Open ngmariusz opened 3 years ago
i just redefine zvm_vi_yank
in zshrc
:
zvm_vi_yank () {
zvm_yank
printf %s "${CUTBUFFER}" | xclip -sel c
zvm_exit_visual_mode
}
similarly for macOS:
function zvm_vi_yank() {
zvm_yank
echo ${CUTBUFFER} | pbcopy
zvm_exit_visual_mode
}
(printf also works)
@tormodatt Thanks for your tips. Hope you have a good day! : )
Also for wayland (need is wl-clipboard)
zvm_vi_yank () {
zvm_yank
printf %s "${CUTBUFFER}" | wl-copy -n
zvm_exit_visual_mode
}
also you can make p/P paste from the windows clipboard by changing zvm_vi_put_after and zvm_vi_put_before as follow:
function zvm_vi_put_after() {
local head= foot=
local content=$(win32yank.exe -o)
...
}
would be great to add one variable which will decide if use custom clipboards, if yes then left the user specify yank/past command
FWIW, here is my solution for getting zsh-vi-mode to play nicely—given my preferences¹—with system clipboards. I have not done any thorough testing but I have not noticed any problems since I started using this solution some weeks ago. (cbread
and cbprint
are custom functions I have for writing and reading to and from the system clipboard, respectively.²)
my_zvm_vi_yank() {
zvm_vi_yank
echo -en "${CUTBUFFER}" | cbread
}
my_zvm_vi_delete() {
zvm_vi_delete
echo -en "${CUTBUFFER}" | cbread
}
my_zvm_vi_change() {
zvm_vi_change
echo -en "${CUTBUFFER}" | cbread
}
my_zvm_vi_change_eol() {
zvm_vi_change_eol
echo -en "${CUTBUFFER}" | cbread
}
my_zvm_vi_put_after() {
CUTBUFFER=$(cbprint)
zvm_vi_put_after
zvm_highlight clear # zvm_vi_put_after introduces weird highlighting for me
}
my_zvm_vi_put_before() {
CUTBUFFER=$(cbprint)
zvm_vi_put_before
zvm_highlight clear # zvm_vi_put_before introduces weird highlighting for me
}
zvm_after_lazy_keybindings() {
zvm_define_widget my_zvm_vi_yank
zvm_define_widget my_zvm_vi_delete
zvm_define_widget my_zvm_vi_change
zvm_define_widget my_zvm_vi_change_eol
zvm_define_widget my_zvm_vi_put_after
zvm_define_widget my_zvm_vi_put_before
zvm_bindkey visual 'y' my_zvm_vi_yank
zvm_bindkey visual 'd' my_zvm_vi_delete
zvm_bindkey visual 'x' my_zvm_vi_delete
zvm_bindkey vicmd 'C' my_zvm_vi_change_eol
zvm_bindkey visual 'c' my_zvm_vi_change
zvm_bindkey vicmd 'p' my_zvm_vi_put_after
zvm_bindkey vicmd 'P' my_zvm_vi_put_before
}
¹ I only work with one clipboard, which is shared between my local system and any (trusted) remote system I am logged on to.
² Here are cbread
and cbprint
:
if [[ $(uname) = "Darwin" ]]; then
on_mac_os=0
else
on_mac_os=1
fi
cbread() {
if [[ $on_mac_os -eq 0 ]]; then
pbcopy
else
xclip -selection primary -i -f | xclip -selection secondary -i -f | xclip -selection clipboard -i
fi
}
cbprint() {
if [[ $on_mac_os -eq 0 ]]; then
pbpaste
else
if x=$(xclip -o -selection clipboard 2> /dev/null); then
echo -n $x
elif x=$(xclip -o -selection primary 2> /dev/null); then
echo -n $x
elif x=$(xclip -o -selection secondary 2> /dev/null); then
echo -n $x
fi
fi
}
For anyone on WSL2 for Windows:
zvm_vi_yank () {
zvm_yank
echo "$CUTBUFFER" | clip.exe
zvm_exit_visual_mode
}
Thanks for your solution @anderslundstedt
Any idea how to stop deleting lines or characters from replacing what is in the clipboard?
Loved idea with cbprint, cpread from @anderslundstedt https://github.com/jeffreytse/zsh-vi-mode/issues/19#issuecomment-1268057812
rewrite it via functions overriding
for f in zvm_backward_kill_region zvm_yank zvm_replace_selection zvm_change_surround_text_object zvm_vi_delete zvm_vi_change zvm_vi_change_eol; do
eval "$(echo "_$f() {"; declare -f $f | tail -n +2)"
eval "$f() { _$f; echo -en \$CUTBUFFER | cbread }"
done
for f in zvm_vi_put_after zvm_vi_put_before; do
eval "$(echo "_$f() {"; declare -f $f | tail -n +2)"
eval "$f() { CUTBUFFER=\$(cbprint); _$f; zvm_highlight clear }"
done
Sharing my version for macOs that covers more commands.
my_zvm_vi_yank() {
zvm_vi_yank
echo -en "${CUTBUFFER}" | pbcopy
}
my_zvm_vi_delete() {
zvm_vi_delete
echo -en "${CUTBUFFER}" | pbcopy
}
my_zvm_vi_change() {
zvm_vi_change
echo -en "${CUTBUFFER}" | pbcopy
}
my_zvm_vi_change_eol() {
zvm_vi_change_eol
echo -en "${CUTBUFFER}" | pbcopy
}
my_zvm_vi_substitute() {
zvm_vi_substitute
echo -en "${CUTBUFFER}" | pbcopy
}
my_zvm_vi_substitute_whole_line() {
zvm_vi_substitute_whole_line
echo -en "${CUTBUFFER}" | pbcopy
}
my_zvm_vi_put_after() {
CUTBUFFER=$(pbpaste)
zvm_vi_put_after
zvm_highlight clear # zvm_vi_put_after introduces weird highlighting
}
my_zvm_vi_put_before() {
CUTBUFFER=$(pbpaste)
zvm_vi_put_before
zvm_highlight clear # zvm_vi_put_before introduces weird highlighting
}
my_zvm_vi_replace_selection() {
CUTBUFFER=$(pbpaste)
zvm_vi_replace_selection
echo -en "${CUTBUFFER}" | pbcopy
}
zvm_after_lazy_keybindings() {
zvm_define_widget my_zvm_vi_yank
zvm_define_widget my_zvm_vi_delete
zvm_define_widget my_zvm_vi_change
zvm_define_widget my_zvm_vi_change_eol
zvm_define_widget my_zvm_vi_put_after
zvm_define_widget my_zvm_vi_put_before
zvm_define_widget my_zvm_vi_substitute
zvm_define_widget my_zvm_vi_substitute_whole_line
zvm_define_widget my_zvm_vi_replace_selection
zvm_bindkey vicmd 'C' my_zvm_vi_change_eol
zvm_bindkey vicmd 'P' my_zvm_vi_put_before
zvm_bindkey vicmd 'S' my_zvm_vi_substitute_whole_line
zvm_bindkey vicmd 'p' my_zvm_vi_put_after
zvm_bindkey visual 'p' my_zvm_vi_replace_selection
zvm_bindkey visual 'c' my_zvm_vi_change
zvm_bindkey visual 'd' my_zvm_vi_delete
zvm_bindkey visual 's' my_zvm_vi_substitute
zvm_bindkey visual 'x' my_zvm_vi_delete
zvm_bindkey visual 'y' my_zvm_vi_yank
}
https://github.com/jeffreytse/zsh-vi-mode/issues/19#issuecomment-1268057812:
in Linux for these cool bindings to work set aliases before:
alias cbread='xclip -selection c'
alias cbprint='xclip -o -selection clipboard'
I applied it on linux.
it works well when I first select the word via visual mode, then y
however
yy
or Y
(copy the whole line) does not workyiw
(copy current word) does not work
any idea ? edit: solved it !
I had to edit the source, https://github.com/jeffreytse/zsh-vi-mode/blob/master/zsh-vi-mode.zsh#L1829
to call my_zvm_vi_yank
instead
@joihn, thanks!
y*) zvm_vi_yank false; cursor=;;
My little bit more accurate patch:
1) at the beginning of .zsh-vi-mode.zsh
:
# see https://unix.stackexchange.com/questions/332005/test-for-functions-existence-that-can-work-on-both-bash-and-zsh
fn_exists()
{
typeset -f $1 >/dev/null 2>&1;
}
2) at that line:
# y*) zvm_vi_yank false; cursor=;;
y*) fn_exists my_zvm_vi_yank && my_zvm_vi_yank false || zvm_vi_yank false; cursor=;;
It fixes yy
but seems Y
still not working :thinking:
While we wait for final solution you can patch zsh-vi-mode plugin if it's deal breaker for you.
For those not very familiar with bash just find plugin file
~/.oh-my-zsh/custom/plugins/zsh-vi-mode/zsh-vi-mode.zsh
and then functionzvm_yank()
; In my case for windows wsl2 ubuntu20 it's like so:brutal, but does the job.