@@ -244,6 +244,7 @@ These keys pass through to Emacs instead."
244244 (define-key map (kbd " C-c C-k" ) #'ghostel-copy-mode )
245245 (define-key map (kbd " C-c C-y" ) #'ghostel-paste )
246246 (define-key map (kbd " C-c C-l" ) #'ghostel-clear-scrollback )
247+ (define-key map (kbd " C-c C-q" ) #'ghostel-send-next-key )
247248 ; ; Cursor and navigation keys — raw escape sequences
248249 (define-key map (kbd " <escape>" ) (lambda () (interactive ) (ghostel--send-key " \e " )))
249250 (define-key map (kbd " <up>" ) (lambda () (interactive ) (ghostel--send-key " \e [A" )))
@@ -296,6 +297,30 @@ These keys pass through to Emacs instead."
296297
297298; ;; Key sending
298299
300+ (defun ghostel-send-next-key ()
301+ " Read the next key event and send it to the terminal.
302+ This is an escape hatch for sending keys that are normally
303+ intercepted by Emacs (e.g., C-g, C-x)."
304+ (interactive )
305+ (let* ((key (read-key-sequence " Send key: " ))
306+ (char (aref key 0 )))
307+ (cond
308+ ; ; Control character
309+ ((and (integerp char) (<= char 31 ))
310+ (ghostel--send-key (string char)))
311+ ; ; Regular character
312+ ((and (integerp char) (< char 128 ))
313+ (ghostel--send-key (string char)))
314+ ; ; Multi-byte character
315+ ((integerp char)
316+ (ghostel--send-key (encode-coding-string (string char) 'utf-8 )))
317+ ; ; Function key / special key — look up in keymap
318+ (t
319+ (let* ((binding (key-binding key)))
320+ (if (and binding (commandp binding))
321+ (call-interactively binding)
322+ (message " ghostel: unrecognized key %S " key)))))))
323+
299324(defun ghostel--send-key (key )
300325 " Send KEY string to the terminal process."
301326 (when (and ghostel--process (process-live-p ghostel--process))
0 commit comments