-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add auto pairs for same-char pairs #1219
Conversation
) | ||
} | ||
|
||
// [TODO] broken until it works with selections |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is sort of addressed bybmsa"
(match surrounding add (
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, just to be clear, are you saying we shouldn't worry about adding surround functionality with selections? Or just that this particular case should just be inserting a ( before the word, but if the whole word was selected, do the surround?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I've fixed this test, although it's still broken until I add the changes for selections.
Great work! I need to give this a full read later but it's especially great to see test coverage being added :) |
0621b85
to
bc4c38d
Compare
helix-core/src/auto_pairs.rs
Outdated
fn next_char(doc: &Rope, pos: usize) -> Option<char> { | ||
if pos >= doc.len_chars() { | ||
return None; | ||
} | ||
Some(doc.char(pos)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be replaced by doc.get_char(pos)
now, ropey
added a non-panicking variant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, done.
fn handle_open( | ||
doc: &Rope, | ||
selection: &Selection, | ||
open: char, | ||
close: char, | ||
close_before: &str, | ||
) -> Transaction { | ||
let mut ranges = SmallVec::with_capacity(selection.len()); | ||
let mut end_ranges = SmallVec::with_capacity(selection.len()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the rename? It looks like all the variables in _open
and _close
were renamed but nothing else was changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, sorry, this was mostly for my own benefit to better understand the code. When building the final range, in the anchor position, it's offset inline, but the head is in a variable that was defined above. And to me pos
(i.e. position) and head
are kind of synonymous, and it was hard to follow that one is what we started with and the other is what we want it to be after the text transformation. Are you okay with the changes?
helix-core/src/auto_pairs.rs
Outdated
start_range.anchor + offs | ||
}; | ||
|
||
// if selection, retain anchor, if cursor, move over |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment would be better suited above the let end_anchor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Also, it's worth noting that the if
expression is currently a tautology because the selection is transformed into cursors before this code is hit. I kept it because something like it will be necessary when I get to fixing selections (which I'm pretty close to now).
helix-core/src/auto_pairs.rs
Outdated
// return transaction that moves past close | ||
(start_head, start_head, None) // no-op | ||
} else { | ||
let mut pair = Tendril::with_capacity(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This uses bytes as the capacity, you probably want 2 * token.len_utf8()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me but I'd like to get one more reviewer
/cc @sudormrfbin
* Add unit tests for all existing functionality * Add auto pairs for same-char pairs (quotes, etc). Account for apostrophe in prose by requiring both sides of the cursor to be non-pair chars or whitespace. This also incidentally will work for avoiding a double single quote in lifetime annotations, at least until <> is added * Slight factor of moving the cursor transform of the selection to inside the hooks. This will enable doing auto pairing with selections, and fixing the bug where auto pairs destroy the selection. Fixes helix-editor#1014
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor nitpicks, other than that LGTM :)
helix-core/src/auto_pairs.rs
Outdated
start_range.anchor + offs | ||
}; | ||
|
||
end_ranges.push(Range::new(end_anchor, end_head)); | ||
|
||
match next { | ||
Some(ch) if !close_before.contains(ch) => { | ||
offs += 1; | ||
// TODO: else return (use default handler that inserts open) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this TODO still relevant @archseer ? All the handle_
functions would have to return an Option that gets passed through the hook.
Changes
I will still be working on other things, but I thought it would be a good idea to make an incremental smaller PR for the sake of ease of review, and for providing opportunity for feedback with the approach to testing and implementation details before I build further on them.
Fixes #1014
Things I'd still like to do:
{% %}
In particular about the auto pairing with selections, I think when we have a case like (where
[]
is the selection)and we enter insert mode and type
"
, we could either unconditionally surround the selection and makeso it behaves exactly like surround, or we could choose only to surround when both sides of the selection are non-pair chars or whitespace, extending the current behavior to selections, so
I'm on the fence about it, so any guidance there would be helpful.