-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat: New command :paste-join
#13600
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
base: master
Are you sure you want to change the base?
Conversation
f156d3f
to
d1893b8
Compare
Looks great, something from kakoune I have missed often. Could you also make a normal command version of this? Whrn mapping these commands a normal command where you can set the register with " would ve more useful. I would like to replicate the kaklune bindings:
(Potentially these three variants can also be flags for the typable command) |
I made normal versions of the 3 commands you mentioned
The typed command now accepts I deviated from Kakoune's And both Deviated from I also added default mapping |
db65c31
to
13b4df5
Compare
:paste-join
:paste-join
, 3 new default keybindings
:paste-join
, 3 new default keybindings:paste-join
+ 3 new default keybindings
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 great thisnwill be very useful
return; | ||
}; | ||
let scrolloff = editor.config().scrolloff; | ||
let (view, doc) = current_ref!(editor); | ||
let yanked = values.map(|value| value.to_string()).collect::<Vec<_>>(); |
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 collect to a vec here instead of accepting impl Iterator<Item=&str>
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.
The issue is that here:
let Some(values) = editor.registers.read(register, editor) else {
return;
};
values
from borrows from the editor
.
We then need to let (view, doc) = current!(editor);
which mutably borrows from Editor
to create &mut View
and &mut Document
To call replace_impl
with something like impl Iterator<Item=&str>
, each &str
would need to borrow from Editor
and the View
/Document
would need to mutably borrow
I also tried accepting impl Iterator<Item = String>
, but it did not work because the lifetime of the iterator is still bound to the editor
, which causes the issues mentioned above
// `values` is asserted to have at least one entry above. | ||
let last = values_rev.peek().unwrap(); | ||
let mut values_rev = values.iter().rev().peekable(); | ||
let Some(last) = values_rev.peek() else { |
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 did you change this from an unwrap? As far as I can see there is still always atleast one value?
And if there isn't I would rather unwrap instead of silently doing nothing (or atleast log an error)
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.
Previously we had registers.read().filter(|values| values.len() > 0)
and would return if it's empty. So unwrap was ok. This all happened in the body of the same function
But now, I've moved registers.read().filter(|values| values.len() > 0)
outside of replace_impl
. Keeping the unwrap means placing an extra constraint on the caller and I think it'd be better to do the validation inside of replace_impl
, so I removed call to .filter
The effect is the same as before: Do nothing if it's empty.
It can be empty when the register contains nothing. E.g., "m<C-R>
would do nothing if m
is empty.
This behaviour (including not logging anything) is consistent with what would happen if you did "mp
, "mP
, "mR
etc if the m
register is empty
:paste-join
+ 3 new default keybindings:paste-join
+ 4 new default keybindings
Running into a bug where it broke the existing commands : [replace_with_yanked, replace_selections_with_keyboard]
same behaviour with space-R |
Thanks for noticing it. The issue was passing 2 |
Since there is a typable command I don't think we need to add default keybindings for these. Or at least I'd prefer to discuss that in a separate PR. The keymap space is limited and this would occupy four spots for commands you can execute in command mode |
:paste-join
+ 4 new default keybindings:paste-join
Ok, I've removed the default mappings |
This is a popular feature :) Imo #4694 would be greatly preferable to this PR because:
With #4694 I can produce this separate lines outcome by doing the paste join, and then leveraging the selections to insert the newlines. With this PR we don't have away of reconstructing the functionality of having multiple selections. |
The benefit of this PR is that it adds typed commands for more granular control The static commands are simply shorthands for the typed commands with newline as the separator I'm not sure what is the benefit of the PR you sent, when the changes you mentioned can be implemented here quite easily ( |
The key feature that is missing here is not static commands to paste without a newline, it is pasting without joining the selections. See how many selections result: https://github.com/helix-editor/helix/pull/13698/files#diff-de6d53c9114aa1dd8644d67767043ed85f30780e0a0197e49501fc9967443da1 This state preserving the selections enables you to do many more things. You can compose other arbitrary edit actions, instead of only being able to do what the typed command flags support. |
Sometimes I have like 10 selections, yank them with
y
only to realize i want them all in a single place. So what I do is usually select everything again and use:yank-join
, which joins all of my selections so I can paste it with just 1 cursorThe above experience would be more pleasant if I could take all of my 10 yanked selections and paste them into 1 place. The
:paste-join
command does exactly that.In this file
If you have the first 3 words selected, as outlined by
[...]
and you pressy
to yank it then place your cursor at[ ]
:using
:paste-join
will join whatever you copied with a newlineWithout having to create multiple cursors, or use
yank-join
!New typed command
New static commands
paste_before_joined_with_newline
paste_after_joined_with_newline
replace_joined_with_newline
Supercedes #4694