diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-05 09:55:41 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-05 09:55:41 -0500 |
| commit | 81ececd67b23e42163c970edb4e9a4c0d824612e (patch) | |
| tree | 66c6558000c8675ed63c8b0e2ae9518e383d581c /modules | |
| parent | 854aa53a96476ccaae0c93bd9af0493ef8431e4b (diff) | |
| download | dotemacs-81ececd67b23e42163c970edb4e9a4c0d824612e.tar.gz dotemacs-81ececd67b23e42163c970edb4e9a4c0d824612e.zip | |
fix(term): forward C-SPC and window-nav keys in ghostel buffers
Two keystrokes weren't reaching Emacs inside a ghostel terminal, both because of how ghostel routes keys in semi-char mode.
C-SPC was the worse one. ghostel forwards the `C-@' event but not the distinct `C-SPC' event GUI Emacs produces, so C-Space fell through to the global `set-mark-command' and set an Emacs region in the terminal buffer. That region followed point as output streamed (a stuck "selection" Escape and C-g couldn't clear), and it meant tmux copy-mode's begin-selection never started, so M-w copied nothing. I bind C-SPC to cj/term-send-C-SPC, which forwards NUL like a terminal key.
The C-M-arrows (buffer-move, window swap) were being forwarded to the terminal program the same way the F9 family was. I added the windmove S-arrows and buffer-move C-M-arrows to ghostel-keymap-exceptions and rebuilt the semi-char map. The S-arrows already reached Emacs by keymap precedence, but listing them makes the window-nav contract explicit rather than accidental.
Regression tests cover all three: C-SPC bound to the forwarder, and the window-nav keys in the exceptions with the semi-char map no longer forwarding them.
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/term-config.el | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/modules/term-config.el b/modules/term-config.el index b327777a..5753edde 100644 --- a/modules/term-config.el +++ b/modules/term-config.el @@ -221,14 +221,19 @@ run its own project-named tmux session instead of a bare, auto-named one. :ensure t :commands (ghostel) :init - ;; C-; and F12 must reach Emacs (not the terminal program) inside ghostel + ;; These keys must reach Emacs (not the terminal program) inside ghostel ;; buffers. In semi-char mode ghostel forwards every key NOT in ;; `ghostel-keymap-exceptions' to the pty, and `ghostel-semi-char-mode-map' ;; is rebuilt from that list by `ghostel--rebuild-semi-char-keymap' -- ;; `add-to-list' alone updates the list but not the already-built map, so the - ;; rebuild is what actually lets the key through to `ghostel-mode-map'. + ;; rebuild is what actually lets the key through to `ghostel-mode-map' / the + ;; global map. C-; and F12 are the prefix + toggle; the modified arrows are + ;; windmove (S-arrows, focus) and buffer-move (C-M-arrows, swap), which the + ;; ai-term workflow expects to work from inside an agent buffer. (with-eval-after-load 'ghostel - (dolist (key '("C-;" "<f12>")) + (dolist (key '("C-;" "<f12>" + "S-<up>" "S-<down>" "S-<left>" "S-<right>" + "C-M-<up>" "C-M-<down>" "C-M-<left>" "C-M-<right>")) (add-to-list 'ghostel-keymap-exceptions key)) (ghostel--rebuild-semi-char-keymap)) :hook @@ -377,12 +382,27 @@ Excludes agent-prefixed buffers; those have their own F9 dispatch via (keymap-set cj/term-map "q" #'ghostel-send-next-key) (keymap-set cj/term-map "t" #'cj/term-toggle) +(defun cj/term-send-C-SPC () + "Forward C-SPC (NUL) to the terminal instead of setting an Emacs mark. + +ghostel forwards the `C-@' event but not the distinct `C-SPC' event GUI +Emacs produces, so a bare C-SPC in a ghostel buffer falls through to the +global `set-mark-command'. That sets an Emacs region in the terminal buffer +that follows point as output streams (a stuck \"selection\" C-g / Escape +can't clear) and, worse, never reaches tmux -- so tmux copy-mode's +begin-selection (C-Space) never starts and M-w then copies nothing. +Forwarding NUL makes C-Space behave like a terminal key." + (interactive) + (ghostel-send-string "\C-@")) + (defun cj/term-install-keys () - "Make `C-;' resolve as the personal keymap inside ghostel buffers, and bind -the F-key toggles so they reach Emacs from inside a terminal buffer." + "Make `C-;' resolve as the personal keymap inside ghostel buffers, bind the +F12 toggle, and forward C-SPC so it reaches the terminal (see +`cj/term-send-C-SPC')." (when (boundp 'ghostel-mode-map) (keymap-set ghostel-mode-map "C-;" cj/custom-keymap) - (keymap-set ghostel-mode-map "<f12>" #'cj/term-toggle))) + (keymap-set ghostel-mode-map "<f12>" #'cj/term-toggle) + (keymap-set ghostel-mode-map "C-SPC" #'cj/term-send-C-SPC))) (cj/term-install-keys) (with-eval-after-load 'ghostel |
