Skip to content
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

Killing lines does not add to the kill ring #304

Open
plattfot opened this issue Apr 22, 2020 · 9 comments
Open

Killing lines does not add to the kill ring #304

plattfot opened this issue Apr 22, 2020 · 9 comments

Comments

@plattfot
Copy link

Having an issue when killing text in the vterm mode (not the VTermCopy), that it's not adding it to the kill ring.

To reproduce the issue:
Run emacs -Q
Then in the scratch buffer evaluate these two lines to load vterm

(add-to-list 'load-path "~/.emacs.d/elpa/vterm-20200418.1610")
(require 'vterm)

Type in foo in the scratch buffer then killed that.
Open a vterm using M-x vterm and type cd

$ cd|

then C-a

$ |cd

C-k

$ |

C-y

$ foo|

Expected behavior:
Should yank cd to the prompt not foo.

@Sbozzolo
Copy link
Collaborator

Thanks for the report. A possible workaround is this:

(defun vterm-send-C-k ()
  "Send `C-k' to libvterm."
  (interactive)
  (kill-ring-save (point) (vterm-end-of-line))
  (vterm-send-key "k" nil nil t))

The problem with this workaround is that all the times C-k is sent, the text is copied, even if C-k was not supposed to kill/copy (eg, you are in a TUI that captures C-k).

At the moment, I don't know how to do better.

@plattfot
Copy link
Author

Thanks for the workaround. I'm not using programs with TUI that much so that shouldn't be a problem for me.

@may
Copy link

may commented Nov 30, 2021

I ended up wrapping this in a eval-after-load, otherwise it would stop working after I restarted emacs (because I had previously C-x C-e'd it to get it working when I first installed it.)

(eval-after-load "vterm"
  '(defun vterm-send-C-k ()
     "Send `C-k' to libvterm."
     (interactive)
     (kill-ring-save (point) (vterm-end-of-line))
     (vterm-send-key "k" nil nil t)))

@e-hoarder
Copy link

e-hoarder commented Jun 16, 2023

wouldn't it make more sense to handle that sort of thing in the shell itself?
I have this in my .zshrc for example:

_kill_line_to_clip(){
    zle .set-mark-command
    zle .end-of-line
    zle .exchange-point-and-mark
    zle .copy-region-as-kill
    echo -n "${CUTBUFFER}" | pbcopy
    zle .kill-line
}
zle -N kill-line-to-clip _kill_line_to_clip
bindkey '^k' kill-line-to-clip

_backward_kill_word_to_clip() {
  zle .set-mark-command
  zle .backward-word
  zle .exchange-point-and-mark
  zle .copy-region-as-kill
  echo -n "${CUTBUFFER}" | pbcopy
  zle .backward-kill-word
}
zle -N backward-kill-word-to-clip _backward_kill_word_to_clip
bindkey '^w' backward-kill-word-to-clip

@eswierk
Copy link

eswierk commented Jan 27, 2024

I use @e-hoarder 's solution with one tweak: instead of pbcopy, which works only on the local machine, use the magic ANSI OSC 52 sequence, which writes to the clipboard from anywhere.

  • Replace the two echo commands with printf "\033]52;c;$(printf "%s" "${CUTBUFFER}" | base64)\a"
  • Enable OSC 52 by setting (setq vterm-enable-manipulate-selection-data-by-osc52 t)

@e-hoarder
Copy link

* Replace the two `echo` commands with `printf "\033]52;c;$(printf "%s" "${CUTBUFFER}" | base64)\a"`

* Enable OSC 52 by setting `(setq vterm-enable-manipulate-selection-data-by-osc52 t)`

That is awesome, I wish I had known about this earlier, thanks. I spend most of my work day in ssh sessions.

@e-hoarder
Copy link

e-hoarder commented Jan 29, 2024

I implemented @eswierk 's suggestion like so

 osc-copy(){
  if test "$#" -gt 0 ; then
    printf "\033]52;c;%s\a" "$( printf "$*" | base64 )"
  elif test ! -t 0 ; then
    printf "\033]52;c;%s\a" "$( </dev/stdin base64 )"
  fi
}

Which should be a drop-in replacement at least for the most basic uses of wl-copy/pbcopy or whatever

@eswierk
Copy link

eswierk commented Jan 29, 2024

@e-hoarder Good idea... but I think that inner printf needs to be printf "%s" "$*". Passing "$*" straight to printf will do strange things if the argument itself happens to contain a format sequence like %s.

@e-hoarder
Copy link

I just started using tmux more and I finally got around to updating this function

escape-if-tmux(){
  if test -n "$TMUX" -o -z "${TERM##screen*}" ; then
    printf "\033Ptmux;\033%s\a" "${1}"
  else
    printf "%s" "${1}"
  fi
}

osc-52-printf(){
  printf "\033]52;c;%s\a" "${1}"
}

osc-copy(){
  if test "$#" -gt 0 ; then
    input="$( printf "%s" "$*" | base64 --wrap=0 )"
  elif test ! -t 0 ; then
    input="$( </dev/stdin base64 --wrap=0 )"
  fi
  escape-if-tmux "$( osc-52-printf ${input} )"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants