vim: Fix :g/pattern/norm commands applying on all matches#43352
vim: Fix :g/pattern/norm commands applying on all matches#43352dinocosta merged 6 commits intozed-industries:mainfrom
:g/pattern/norm commands applying on all matches#43352Conversation
|
Thank you for attempting to fix this @AidanV ! I suspect we might want to look for a simpler solution that does not involve the use of channels but can't suggest a different approach right now, as I'm not too familiar with how we're currently handling these. Will review the code and keep you updated 🙂 |
|
Hey @AidanV 👋 I spent some time getting more familiar with how we currently handle both It looks like this pull request is tackling two issues at once, first, that On the former, your solution to replace As for the
Conrad has briefly mentioned that it would be good to introduce a way to track when an action has finished, but that’s not currently in progress. Unfortunately, I believe the suggested changes don’t solve this either, since they rely on the state of the For now, I’d suggest two alternatives:
Personally, I’d probably go with the range fix for |
|
Thank you for the detailed response @dinocosta! I agree with Conrad that we should introduce a way to track action completion. I think that that is the "correct" solution for this problem, but since we don't have that, here is what I did: I tried out your suggested implementation with In the most recent commit, when running |
Interesting, do you remember why? If you do eventually chose to go the
Thank you for tackling this! This approach seems more deterministic to me but I'm unsure if it makes sense for I wonder if it would be better to leverage |
|
Sorry for the slow progress on this. I haven't forgotten about it, just busy at the moment. I should be able to finish this up next week. |
After some investigating it looks like the
I do think that this would work and would not be a huge undertaking, but I think that the
This is true. We are splitting the responsibility; however, someone stumbling on this code later on would not struggle to see the connection between the two since let (action, skip_fix_selections) = match action.as_any().downcast_ref::<VimNorm>() {
Some(vim_norm) => {
let mut vim_norm = vim_norm.clone();
vim_norm.collapse_multicursor = true;
(vim_norm.boxed_clone(), true)
}
None => (action, false),
};Curious to hear your thoughts! |
|
After giving it some more thought I went with something similar to the second solution you suggested:
Now, we can give the Implementing this uncovered a bug in From: old.0 = first_sel;To: old.0 = old.0.get(..1).unwrap_or(&[]).into();I added regression tests for this behavior. Since I ran into this on the path to fixing the bug this PR addresses (and it is so small) I think it is fair to include it in the PR, but if you think it is out of scope, I am happy to move this to a new PR. I hope you are enjoying the break, and I look forward to hearing your thoughts in January! |
dinocosta
left a comment
There was a problem hiding this comment.
Hey @AidanV ! 👋
Thank you so much for your patience and for updating these changes! It's looking promising so far, getting very close to shipping this. I've left a couple minor comments comments of things I believe we can remove/improve and I believe it would also be helpful to comment the override_selections field so future devs are aware of what the field is meant to be used for 🙂
Implementing this uncovered a bug in VimNorm where typing :norm I123` followed by undo would put the cursor at the end of the line instead of the beginning.
Nice catch! I think undo would actually move the cursor back to the position it was at before :norm I123 was run, but I just checked what NeoVim does and it appears to put it at the beginning of the line too, so the updated behavior looks good to me.
Lastly, this is definitely non-blocking but I believe we could even update VimNorm.override_selections to be Option<Vec<u32>> instead, renaming to something like override_rows too, seeing as OnMatchingLines.run always sets the column to 0 (Point::new(row, 0)) so we can get away with simply passing the rows and then, on MutableSelectionsCollection.replace_cursors_with, we can convert it back to DisplayPoint ▼
s.replace_cursors_with(|map| {
override_rows
.iter()
.map(|row| Point::new(*row, 0).to_display_point(map))
.collect()
});Let me know if you want me to push these changes, as I was testing this locally before commenting.
Thanks! 🙂
Closes #36359 Release Notes: - Fixes bug where `:g/pattern/norm commands` would only apply on the last match --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
|
Thank you for your help! |
…stries#43352) Closes zed-industries#36359 Release Notes: - Fixes bug where `:g/pattern/norm commands` would only apply on the last match --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
…stries#43352) Closes zed-industries#36359 Release Notes: - Fixes bug where `:g/pattern/norm commands` would only apply on the last match --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
…stries#43352) Closes zed-industries#36359 Release Notes: - Fixes bug where `:g/pattern/norm commands` would only apply on the last match --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
Closes #36359
Development Notes:
OnMatchingLineshappen before the:normaction completes. This causes there to only be one cursor when:normmakes its edits. My current solution is a little hacky and relies on waiting one cycle to get a task that depends on the keystrokes. Then, we can wait for those keystrokes to finish before updating the cursor positions.OnMatchingLinesgenerates because the action should believe that it is only running on one line, sinceOnMatchingLinesdoes the cursor set-up and tear-down.If this solution is not up to par, I am happy to pair to figure out a better way :)
Release Notes:
:g/pattern/norm commandswould only apply on the last match