Repository navigation
Questions about copy/kill and paste/yank default keybindings and behavior in char-mode and semi-char-mode #749
Replies: 9 comments
|
Thanks for the issue. First I want to clarify a few things, Ghostty (same as char-mode Ghostel) does NOT support kill/yank, So that's why Ghostty and Ghostel in char-mode are behaving the same, they themself don't do anything and just forward the keys to the terminal. In semi-char we explicitly have our own keybinding for pasting, as when you copy text in another Emacs buffer and have something in your Emacs kill-ring, it feels natural to me that when you paste, this just copied text gets inserted. But I agree that it is confusing. I'll have to think a bit more about it. Do you have an idea/suggestion how it should work in an ideal world? |
You're correct, I should've said something like "the user is able to do X in Ghostty".
Agreed.
My suggestion would be to make Mind you it's still a bit tricky as you'd need to know what text the terminal command is about to kill. E.g. repeatedly pressing |
If the key still also goes to the terminal, then at least the consequences of getting the kill slightly wrong wouldn't be that high at least. But it has to work reliably enough to warrant the added complexity, I think. |
Yeah, while Maybe a better approach would be to send the ^W event to the shell first, and then figure out what it killed.. |
I have this in my config: https://github.com/dakra/dmacs/blob/64ec3e0db6dda591f3f521d10bbd3b03c7be8c9e/init.el#L767-L786 But I feel that stuff should not be in core as it's just not 100% correct. I feel if you "opt-in" with a snippet like above in your config you "acknowledge" that behavior. |
Yeah, you're right, it's better to have this opt-in rather than enabled by default but unreliable.
Ain't that the truth! I made a (defvar ghostel--kill-ring-update-timeout 0.1)
(defvar-local ghostel--kill-ring-update-timer nil)
(defun ghostel-C-w ()
(interactive)
(labels ((%rest-of-input ()
(when-let* ((end ghostel--cursor-char-pos)
(beg (ghostel-input-start-point))
((<= beg end)))
(buffer-substring-no-properties beg end)))
(%kill-handler (input-old appendp)
(lambda ()
(if-let* ((input-new (%rest-of-input))
(to-kill
(if (string-empty-p input-new)
input-old
;; Assume that C-w just removes some suffix from
;; INPUT-OLD.
(when (string-prefix-p input-new input-old)
(substring input-old (length input-new))))))
(if appendp
(kill-append to-kill 'before-p)
(kill-new to-kill))
(message "ghostel-C-w: failed to add text to kill-ring")))))
(let ((input-old (%rest-of-input)))
(ghostel--send-encoded "w" "ctrl")
(when (and (stringp input-old) (not (string-empty-p input-old)))
;; HACK Buffer state isn't updated synchronously, so we schedule a
;; function to update kill-ring. This will fail miserably on tramp
;; connections with basically any amount of latency. I wonder if there
;; is a good way to sync this. Maybe a hook in the redraw function?
(when (timerp ghostel--kill-ring-update-timer)
(cancel-timer ghostel--kill-ring-update-timer))
(setq ghostel--kill-ring-update-timer
(run-with-timer ghostel--kill-ring-update-timeout nil
(%kill-handler input-old
(eq 'ghostel-C-w last-command))))))))
(define-key ghostel-semi-char-mode-map (kbd "C-w") 'ghostel-C-w)
(evil-define-key 'insert ghostel-semi-char-mode-map
(kbd "C-w") 'ghostel-C-w)
Somewhat related to this, what would be a good way to run code after ghostel redraw? E.g. if one wanted to implement something similar to the existing password prompt detection or link handling. |
I don't think there's any good hook for that right now, but but I have been thinking about adding a If you want to hack it, you could advice |
|
Personally... I'd rather ghostel/emacs take over for kill-ring ownership. For others, they might not want that interaction... maybe on customize option is in order for "Who owns kill/yank/etc" ? |
|
jFYI, I converted the issue to a discussion because I think there is no real issue to be solved. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Ghostty
C-k/C-w/C-ukills text inside terminal, C-y yanks it back, M-y cycles kill-ringDragging the mouse while holding
mouse-1selects text (primary selection)mouse-2orS-<insert>pastes primary selectionC-S-ccopies primary selection to clipboardC-S-vpastes from clipboardChar mode
C-k/C-w/C-u/C-y/M-ysame as Ghostty (nice!)Mouse does nothing
S-<insert>inserts '2~'C-S-cgets translated toC-cC-S-vgets translated toC-vSemi-char mode
C-k/C-wkills text inside terminal (but you can only paste it from char-mode)C-y/S-<insert>yanks from emacs kill-ring,M-ycycles emacs kill-ringC-uis used for emacs prefix-argDragging the mouse while holding
mouse-1selects text and enters copy-mode<mouse-2>pastes primary selectionC-S-cgets translated toC-cC-S-vgets translated toC-vSo Ghostty supports
Char mode supports
Semi-char mode supports
Char mode is at least consistent, but semi-char is just bizarre.
C-w/C-kkills stuff but you have to switch to another mode to yank it, whileC-yyanks emacs stuff but you have to switch to another mode to copy.What is the vision/expected workflow here?
All reactions