Skip to content

Commit db13c76

Browse files
committed
Allow all buffer names to be customized
1 parent 3051482 commit db13c76

5 files changed

Lines changed: 68 additions & 72 deletions

File tree

eca-chat.el

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ are not currently selected."
549549

550550
;; Internal
551551

552-
(defvar-local eca-chat--closed nil)
552+
553553
(defvar-local eca-chat--history '())
554554
(defvar-local eca-chat--history-index -1)
555555
(defvar-local eca-chat--id nil)
@@ -637,13 +637,6 @@ A plist with :session :request :question :options :tool-call-id :allow-freeform.
637637
(defvar eca--chat-init-session nil
638638
"Dynamically bound session during `eca-chat-mode' initialization.")
639639

640-
(defun eca-chat-new-buffer-name (session)
641-
"Return the chat buffer name for SESSION."
642-
(format "<eca-chat[%s]:%s:%s>"
643-
(eca--session-project-name session)
644-
(eca--session-id session)
645-
eca-chat--new-chat-id))
646-
647640
(defvar eca-chat-mode-map
648641
(let ((map (make-sparse-keymap)))
649642
(set-keymap-parent map markdown-mode-map)
@@ -700,11 +693,11 @@ A plist with :session :request :question :options :tool-call-id :allow-freeform.
700693
(or (when-let (last-buff (eca--session-last-chat-buffer session))
701694
(when (buffer-live-p last-buff)
702695
last-buff))
703-
(get-buffer (eca-chat-new-buffer-name session))))
696+
(get-buffer (funcall eca-generate-buffer-name-function "eca-chat" :session session :chat-id eca-chat--new-chat-id))))
704697

705698
(defun eca-chat--create-buffer (session)
706699
"Create the eca chat buffer for SESSION."
707-
(get-buffer-create (generate-new-buffer-name (eca-chat-new-buffer-name session))))
700+
(get-buffer-create (generate-new-buffer-name (funcall eca-generate-buffer-name-function "eca-chat" :session session :chat-id eca-chat--new-chat-id))))
708701

709702
(defun eca-chat--get-chat-buffer (session chat-id)
710703
"Get chat buffer for SESSION and CHAT-ID, or nil when none registered.
@@ -720,7 +713,7 @@ its real id and there is no `'empty' placeholder to migrate from."
720713
(and (symbolp this-command)
721714
(string-prefix-p "eca-" (symbol-name this-command))))
722715
eca-chat--id
723-
(not eca-chat--closed)
716+
(not eca-chat-closed)
724717
(yes-or-no-p "Delete chat from server side (otherwise it will just kill the buffer) ?"))
725718
(eca-api-request-sync (eca-session)
726719
:method "chat/delete"
@@ -1345,7 +1338,7 @@ Resteps a list of context plists found in the prompt field."
13451338

13461339
(defun eca-chat--send-prompt (session prompt)
13471340
"Send PROMPT to server for SESSION."
1348-
(when eca-chat--closed
1341+
(when eca-chat-closed
13491342
(user-error (eca-error "This chat is closed")))
13501343
(let* ((prompt-contexts (eca-chat--extract-contexts-from-prompt))
13511344
(refined-contexts (-map #'eca-chat--refine-context
@@ -2008,7 +2001,7 @@ are in progress."
20082001

20092002
(defun eca-chat--mode-line-string (session)
20102003
"Build mode-line string for SESSION from `eca-chat-mode-line-format'."
2011-
(if eca-chat--closed
2004+
(if eca-chat-closed
20122005
(propertize "*Closed session*"
20132006
'font-lock-face 'eca-chat-system-messages-face)
20142007
(let* ((fmt eca-chat-mode-line-format)
@@ -3576,15 +3569,15 @@ When ACTIVE is non-nil, show the question prefix; otherwise restore normal."
35763569
(when eca-chat--stopping-safety-timer
35773570
(cancel-timer eca-chat--stopping-safety-timer)
35783571
(setq-local eca-chat--stopping-safety-timer nil))
3579-
(setq eca-chat--closed t)
3572+
(setq-local eca-chat-closed t)
35803573
(force-mode-line-update)
35813574
(goto-char (point-max))
35823575
(rename-buffer (concat (buffer-name) ":closed") t)
35833576
;; Keep only the most recently closed chat buffer; kill older ones.
35843577
(let ((current (current-buffer)))
35853578
(dolist (b (buffer-list))
35863579
(when (and (not (eq b current))
3587-
(string-match-p "^<eca-chat:.*>:closed$" (buffer-name b)))
3580+
(buffer-local-value 'eca-chat-closed b))
35883581
(kill-buffer b))))
35893582
(when-let* ((window (get-buffer-window chat-buffer)))
35903583
(quit-window nil window))))))

eca-process.el

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,6 @@ If current `gc-cons-threshold` is lower use that on filter server messages.'"
114114
:type 'integer
115115
:group 'eca)
116116

117-
(defun eca-process--buffer-name (session)
118-
"Return the process buffer name for SESSION."
119-
(format "<eca[%s]:%s>"
120-
(eca--session-project-name session)
121-
(eca--session-id session)))
122-
123-
(defun eca-process--stderr-buffer-name (session)
124-
"Return the stderr buffer name for SESSION."
125-
(format "<eca:stderr[%s]:%s>"
126-
(eca--session-project-name session)
127-
(eca--session-id session)))
128-
129117
(defcustom eca-server-releases-cache-ttl 3600
130118
"Time-to-live (seconds) for the cached eca server releases list.
131119
Once expired, the next call that needs the releases list will refetch
@@ -544,12 +532,12 @@ Call HANDLE-MSG for new msgs processed."
544532
:connection-type 'pipe
545533
:name "eca"
546534
:command command
547-
:buffer (eca-process--buffer-name session)
548-
:stderr (get-buffer-create (eca-process--stderr-buffer-name session))
535+
:buffer (funcall eca-generate-buffer-name-function "eca" :session session)
536+
:stderr (get-buffer-create (funcall eca-generate-buffer-name-function "eca:stderr" :session session))
549537
:filter (eca-process--make-filter handle-msg)
550538
:sentinel (lambda (process exit-str)
551539
(unless (process-live-p process)
552-
(when-let* ((name (eca-process--stderr-buffer-name session))
540+
(when-let* ((name (funcall eca-generate-buffer-name-function "eca:stderr" :session session))
553541
(buf (get-buffer name)))
554542
(with-current-buffer buf
555543
(rename-buffer (concat (buffer-name) ":closed") t)
@@ -581,12 +569,13 @@ Call HANDLE-MSG for new msgs processed."
581569
"Stop the eca process for SESSION if running."
582570
(when session
583571
(kill-process (eca--session-process session))
584-
(kill-buffer (eca-process--buffer-name session))
572+
(kill-buffer (funcall eca-generate-buffer-name-function "eca" :session session))
585573
;; Rename stderr buffer to closed and clean up older closed ones
586-
(let ((stderr-buffer (get-buffer (eca-process--stderr-buffer-name session))))
574+
(let ((stderr-buffer (get-buffer (funcall eca-generate-buffer-name-function "eca:stderr" :session session))))
587575
(when stderr-buffer
588576
(with-current-buffer stderr-buffer
589577
(rename-buffer (concat (buffer-name) ":closed") t)
578+
(setq-local eca-chat-closed t)
590579
(setq-local mode-line-format '("*Closed session*"))
591580
(when-let ((win (get-buffer-window (current-buffer))))
592581
(quit-window nil win))
@@ -596,12 +585,12 @@ Call HANDLE-MSG for new msgs processed."
596585
(let ((current (current-buffer)))
597586
(dolist (b (buffer-list))
598587
(when (and (not (eq b current))
599-
(string-match-p "^<eca:stderr:.*>:closed" (buffer-name b)))
588+
(buffer-local-value 'eca-chat-closed b))
600589
(kill-buffer b)))))))))
601590

602591
(defun eca-process-show-stderr (session)
603592
"Open the eca process stderr buffer for SESSION."
604-
(if-let ((buf (get-buffer (eca-process--stderr-buffer-name session))))
593+
(if-let ((buf (get-buffer (funcall eca-generate-buffer-name-function "eca:stderr" :session session))))
605594
(if (window-live-p (get-buffer-window buf))
606595
(select-window (get-buffer-window buf))
607596
(display-buffer buf))

eca-settings.el

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,22 +82,15 @@ preserving tab order."
8282
(defvar-local eca-settings--tab-key nil
8383
"The tab key for this settings buffer.")
8484

85-
(defun eca-settings--buffer-name (tab-key session)
86-
"Return buffer name for TAB-KEY in SESSION."
87-
(format "<eca-settings[%s]:%s:%s>"
88-
(eca--session-project-name session)
89-
tab-key
90-
(eca--session-id session)))
91-
9285
(defun eca-settings--get-buffer (tab-key session)
9386
"Get existing settings buffer for TAB-KEY in SESSION."
94-
(get-buffer (eca-settings--buffer-name tab-key session)))
87+
(get-buffer (funcall eca-generate-buffer-name-function "eca-settings" :session session :chat-id tab-key)))
9588

9689
(defun eca-settings--create-buffer (tab-key session)
9790
"Create a new settings buffer for TAB-KEY in SESSION."
9891
(get-buffer-create
9992
(generate-new-buffer-name
100-
(eca-settings--buffer-name tab-key session))))
93+
(funcall eca-generate-buffer-name-function "eca-settings" :session session :chat-id tab-key))))
10194

10295
(defun eca-settings--get-or-create-tab-buffer (tab-key session)
10396
"Get or create settings buffer for TAB-KEY in SESSION.

eca-util.el

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,35 @@ workspace folder. Falls back to \"unknown\"."
320320
"Display eca error message with FORMAT with ARGS."
321321
(message "%s :: %s" (propertize "ECA" 'face 'error) (apply #'format format args)))
322322

323+
(defvar-local eca-chat-closed nil
324+
"Non-nil when the chat buffer belongs to a closed session.")
325+
326+
(cl-defun eca-generate-buffer-name-default-function (mode &key session chat-id)
327+
"Generate a buffer name for optional SESSION and optional CHAT-ID.
328+
MODE is a string describing the buffer type (e.g. eca-chat)."
329+
(cond
330+
((null session)
331+
(format "<%s>" mode))
332+
(chat-id
333+
(format "<%s[%s]:%s:%s>" mode
334+
(eca--session-project-name session)
335+
(eca--session-id session)
336+
chat-id))
337+
(t
338+
(format "<%s[%s]:%s>" mode
339+
(eca--session-project-name session)
340+
(eca--session-id session)))))
341+
342+
(defcustom eca-generate-buffer-name-function
343+
#'eca-generate-buffer-name-default-function
344+
"The function used to generate the name for an ECA buffer.
345+
The function is called with a required MODE (string), followed by
346+
keyword arguments :session and :chat-id. It must return a string
347+
to use as the buffer name."
348+
:type `(radio (function-item ,#'eca-generate-buffer-name-default-function)
349+
(function :tag "Function"))
350+
:group 'eca)
351+
323352
(defun eca-buttonize (base-map text callback)
324353
"Create a actionable TEXT that call CALLBACK when actioned.
325354
Inheirits BASE-MAP."

eca.el

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -121,20 +121,12 @@ with `eca-process-wrapper-function' for a fully sandboxed setup."
121121

122122
;; Internal
123123

124-
(defvar eca-workspaces-buffer-name "*eca-workspaces*")
125-
126-
(defun eca--emacs-errors-buffer-name (session)
127-
"Return the Emacs errors buffer name for SESSION."
128-
(format "<eca:emacs-errors[%s]:%s>"
129-
(eca--session-project-name session)
130-
(eca--session-id session)))
131-
132124
(defun eca--log-error (session err &optional context backtrace)
133125
"Log error ERR to the Emacs errors buffer for SESSION.
134126
Optional CONTEXT is a string describing what was happening
135127
when the error occurred. Optional BACKTRACE is a list of
136128
frames captured via `backtrace-get-frames'."
137-
(let ((buffer (get-buffer-create (eca--emacs-errors-buffer-name session))))
129+
(let ((buffer (get-buffer-create (funcall eca-generate-buffer-name-function "eca:emacs-errors" :session session))))
138130
(with-current-buffer buffer
139131
(goto-char (point-max))
140132
(insert (format "[%s] %s%s\n"
@@ -150,7 +142,7 @@ frames captured via `backtrace-get-frames'."
150142

151143
(defun eca-show-emacs-errors (session)
152144
"Open the Emacs errors buffer for SESSION."
153-
(let ((buffer (get-buffer (eca--emacs-errors-buffer-name session))))
145+
(let ((buffer (get-buffer (funcall eca-generate-buffer-name-function "eca:emacs-errors" :session session))))
154146
(if buffer
155147
(with-current-buffer buffer
156148
(if (window-live-p (get-buffer-window (buffer-name)))
@@ -166,20 +158,19 @@ frames captured via `backtrace-get-frames'."
166158

167159
(defun eca--emacs-errors-exit (session)
168160
"Clean up the Emacs errors buffer for SESSION on stop."
169-
(let ((buffer (get-buffer (eca--emacs-errors-buffer-name session))))
161+
(let ((buffer (get-buffer (funcall eca-generate-buffer-name-function "eca:emacs-errors" :session session))))
170162
(when buffer
171163
(with-current-buffer buffer
172164
(rename-buffer (concat (buffer-name) ":closed") t)
173-
(setq-local mode-line-format '("*Closed session*"))
174-
(when-let ((win (get-buffer-window (current-buffer))))
175-
(quit-window nil win))
176-
;; Keep only the most recently closed errors buffer; kill older ones.
177-
(let ((current (current-buffer)))
178-
(dolist (b (buffer-list))
179-
(when (and (not (eq b current))
180-
(or
181-
(string-match-p "^<eca:emacs-errors:.*>:closed$" (buffer-name b))
182-
(string-match-p "^<eca:emacs-errors:.*>$" (buffer-name b))))
165+
(setq-local eca-chat-closed t)
166+
(setq-local mode-line-format '("*Closed session*"))
167+
(when-let ((win (get-buffer-window (current-buffer))))
168+
(quit-window nil win))
169+
;; Keep only the most recently closed errors buffer; kill older ones.
170+
(let ((current (current-buffer)))
171+
(dolist (b (buffer-list))
172+
(when (and (not (eq b current))
173+
(buffer-local-value 'eca-chat-closed b))
183174
(kill-buffer b))))))))
184175

185176
(defun eca--get-message-type (json-data)
@@ -364,7 +355,7 @@ backtrace. On older Emacs, runs BODY without capture."
364355
"Connect in eca nrepl port for development."
365356
(interactive)
366357
(eca-assert-session-running (eca-session))
367-
(with-current-buffer (eca-process--stderr-buffer-name (eca-session))
358+
(with-current-buffer (funcall eca-generate-buffer-name-function "eca:stderr" :session (eca-session))
368359
(save-excursion
369360
(goto-char (point-min))
370361
(when (re-search-forward "started on port \\([0-9]+\\)" nil t)
@@ -466,13 +457,14 @@ When ARG is current prefix, ask for workspace roots to use."
466457
(seq-doseq (chat-by-id (eca--session-chats session))
467458
(when (buffer-live-p (cdr chat-by-id))
468459
(hierarchy-add-tree h (cdr chat-by-id) parent-fn))))
469-
(let ((b (or (when-let ((b (get-buffer eca-workspaces-buffer-name)))
470-
(when (buffer-live-p b)
471-
(with-current-buffer b
472-
(let ((inhibit-read-only t))
473-
(erase-buffer))))
474-
b)
475-
(generate-new-buffer eca-workspaces-buffer-name))))
460+
(let* ((buffer-name (funcall eca-generate-buffer-name-function "eca-workspaces"))
461+
(b (or (when-let ((b (get-buffer buffer-name)))
462+
(when (buffer-live-p b)
463+
(with-current-buffer b
464+
(let ((inhibit-read-only t))
465+
(erase-buffer))))
466+
b)
467+
(generate-new-buffer buffer-name))))
476468
(with-current-buffer b
477469
(setq-local tree-widget-image-enable nil)
478470
(widget-create (eca--tree-widget-open-all

0 commit comments

Comments
 (0)