···1313;; :session-id "..."
1414;; :project "kms")
1515;;
1616-;; Two opt-in dispatchers ship with this file:
1717-;; - `pm-agent-dispatch-term' (built-in `term-mode')
1818-;; - `pm-agent-dispatch-vterm' (requires the `vterm' package)
1616+;; Three opt-in dispatchers ship with this file:
1717+;; - `pm-agent-dispatch-term' (built-in `term-mode')
1818+;; - `pm-agent-dispatch-vterm' (requires the `vterm' package)
1919+;; - `pm-agent-dispatch-ghostel' (requires the `ghostel' package)
1920;;
2021;; Default behavior (`pm-agent-dispatch-function' = nil) stages the
2122;; command on the kill-ring and prints a hint, so the package is
···4344(declare-function term-mode "term" ())
4445(declare-function term-char-mode "term" ())
45464747+(defvar ghostel-buffer-name) ; declared dynamic so the let-binding takes effect
4848+(declare-function ghostel "ext:ghostel" (&optional arg))
4949+(declare-function ghostel-paste-string "ext:ghostel" (string))
5050+(declare-function ghostel-send-key "ext:ghostel" (key-name &optional mods))
5151+4652;;;; Dispatch defcustom
47534854;;;###autoload
···5460the kill-ring and prints a message instead of launching anything.
55615662Set to one of the built-in dispatchers shipped with this file:
5757- - `pm-agent-dispatch-term' (uses Emacs's built-in `term-mode')
5858- - `pm-agent-dispatch-vterm' (requires the `vterm' package)
6363+ - `pm-agent-dispatch-term' (uses Emacs's built-in `term-mode')
6464+ - `pm-agent-dispatch-vterm' (requires the `vterm' package)
6565+ - `pm-agent-dispatch-ghostel' (requires the `ghostel' package)
5966or write your own — for example, to spawn an external terminal
6067emulator."
6168 :type '(choice (const :tag "Disabled (kill-ring stage)" nil)
···149156 (vterm))
150157 (vterm-send-string (mapconcat #'shell-quote-argument argv " "))
151158 (vterm-send-return)))
159159+160160+;;;###autoload
161161+(defun pm-agent-dispatch-ghostel (plist)
162162+ "Launch PLIST's `:argv' inside a `ghostel' buffer.
163163+164164+Requires the `ghostel' package; raises `user-error' otherwise so
165165+users get a clear hint instead of a void-function backtrace.
166166+167167+The argv is shell-quoted and forwarded via `ghostel-paste-string'
168168+(bracketed paste — the shell treats it as one atomic input even
169169+when it contains spaces or quotes), then a Return key is sent to
170170+execute it. Bracketed paste falls back to a raw write before the
171171+shell has set DECSET 2004; either way the shell receives the
172172+argv as a single command line."
173173+ (unless (require 'ghostel nil t)
174174+ (user-error "ghostel not installed; pick another `pm-agent-dispatch-function'"))
175175+ (let* ((argv (plist-get plist :argv))
176176+ (cwd (plist-get plist :cwd))
177177+ (agent (plist-get plist :agent))
178178+ (project (plist-get plist :project))
179179+ (default-directory cwd)
180180+ (ghostel-buffer-name (format "*pm-agent: %s/%s*" project agent))
181181+ (buf (ghostel)))
182182+ (with-current-buffer buf
183183+ (ghostel-paste-string (mapconcat #'shell-quote-argument argv " "))
184184+ (ghostel-send-key "return"))))
152185153186;;;; Buffer + mode
154187