-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathai-code-backends-infra-ghostel.el
More file actions
123 lines (104 loc) · 5.27 KB
/
ai-code-backends-infra-ghostel.el
File metadata and controls
123 lines (104 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
;;; ai-code-backends-infra-ghostel.el --- Ghostel support for AI Code terminals -*- lexical-binding: t; -*-
;; Author: Kang Tu, AI Agent
;; SPDX-License-Identifier: Apache-2.0
;;; Commentary:
;; Ghostel-specific support for `ai-code-backends-infra'.
;;; Code:
(require 'ai-code-session-link)
;; Prefer `ghostel-exec' for Ghostel backend startup when available, as
;; it simplifies process startup integration.
(declare-function ai-code-backends-infra--configure-session-input-shortcuts
"ai-code-backends-infra" ())
(declare-function ai-code-backends-infra--install-navigation-cursor-sync
"ai-code-backends-infra" ())
(declare-function ai-code-backends-infra--note-meaningful-output
"ai-code-backends-infra" ())
(declare-function ai-code-backends-infra--output-meaningful-p
"ai-code-backends-infra" (output))
(declare-function ai-code-backends-infra--set-session-directory
"ai-code-backends-infra" (buffer directory))
(declare-function ai-code-backends-infra--sync-terminal-cursor
"ai-code-backends-infra" ())
(declare-function ghostel-exec "ghostel" (buffer program &optional args))
(declare-function ghostel--window-adjust-process-window-size
"ghostel" (process windows))
(defvar ai-code-backends-infra--session-terminal-backend)
(defvar ghostel--copy-mode-active nil)
(defvar ghostel--process nil)
(defvar ghostel-enable-title-tracking t)
(defun ai-code-backends-infra-ghostel-ensure-backend ()
"Ensure the Ghostel backend is available."
(unless (featurep 'ghostel) (require 'ghostel nil t))
(unless (featurep 'ghostel)
(user-error "The package ghostel is not installed")))
(defun ai-code-backends-infra-ghostel-navigation-mode-p ()
"Return non-nil when the current Ghostel buffer is in copy mode."
(bound-and-true-p ghostel--copy-mode-active))
(defun ai-code-backends-infra-ghostel-install-navigation-cursor-sync ()
"Install cursor synchronization for Ghostel navigation mode."
(add-hook 'post-command-hook
#'ai-code-backends-infra--sync-terminal-cursor nil t))
(defun ai-code-backends-infra-ghostel-send-string (string)
"Send STRING to the current Ghostel process."
(when (and (bound-and-true-p ghostel--process)
(process-live-p ghostel--process))
(process-send-string ghostel--process string)))
(defun ai-code-backends-infra-ghostel-send-escape ()
"Send escape to the current Ghostel process."
(ai-code-backends-infra-ghostel-send-string "\e"))
(defun ai-code-backends-infra-ghostel-send-return ()
"Send return to the current Ghostel process."
(ai-code-backends-infra-ghostel-send-string "\r"))
(defun ai-code-backends-infra-ghostel-send-backspace ()
"Send backspace to the current Ghostel process."
(ai-code-backends-infra-ghostel-send-string "\177"))
(defun ai-code-backends-infra-ghostel-resize-handler ()
"Return the Ghostel resize handler."
#'ghostel--window-adjust-process-window-size)
(defun ai-code-backends-infra--configure-ghostel-buffer ()
"Configure the current Ghostel buffer for AI Code sessions."
(setq-local ghostel-enable-title-tracking nil)
(ai-code-backends-infra--configure-session-input-shortcuts)
(ai-code-backends-infra--install-navigation-cursor-sync))
(defun ai-code-backends-infra--start-ghostel-process (buffer command)
"Start a Ghostel session in BUFFER for COMMAND."
(with-current-buffer buffer
(ai-code-backends-infra--configure-ghostel-buffer)
(let* ((argv (split-string-shell-command command))
(program (car argv))
(args (cdr argv)))
(cond
((not program) nil)
((fboundp 'ghostel-exec)
(ghostel-exec buffer program args))
(t
(user-error
"Ghostel backend requires a Ghostel version that provides `ghostel-exec`"))))))
(defun ai-code-backends-infra-ghostel-create-session (buffer-name working-dir command env-vars)
"Create a Ghostel session named BUFFER-NAME in WORKING-DIR.
COMMAND is the shell command to run and ENV-VARS are extra environment
variables for the terminal process."
(let* ((working-dir (file-name-as-directory (expand-file-name working-dir)))
(buffer (get-buffer-create buffer-name))
(process-environment (append env-vars process-environment)))
(ai-code-backends-infra--set-session-directory buffer working-dir)
(with-current-buffer buffer
(setq-local default-directory working-dir)
(setq-local ai-code-backends-infra--session-terminal-backend 'ghostel)
(let ((default-directory working-dir)
(proc (ai-code-backends-infra--start-ghostel-process buffer command)))
(when (processp proc)
(set-process-query-on-exit-flag proc nil)
(let ((orig-filter (process-filter proc)))
(set-process-filter
proc
(lambda (process output)
(when orig-filter
(funcall orig-filter process output))
(with-current-buffer (process-buffer process)
(when (ai-code-backends-infra--output-meaningful-p output)
(ai-code-backends-infra--note-meaningful-output))
(ai-code-session-link--linkify-recent-output output))))))
(cons buffer proc)))))
(provide 'ai-code-backends-infra-ghostel)
;;; ai-code-backends-infra-ghostel.el ends here