Skip to content

Commit cd7c043

Browse files
affe-mit-waffeldakra
authored andcommitted
Rework how ghostel buffers are created
- Until now `M-x ghostel` created a new unique buffers every time - Other packages like eshell, eat and vterm switch to an existing buffer if it exits. - Now ghostel behaves like these packages too. - Pass `C-u` (universal argument) to `M-x ghostel` to create new, unique buffer (e.g. *ghostel*<2>). - When provided with a numeric argument create a ghostel buffer with that name or switch to if it already exists (eg. `C-5 M-x ghostel` to switch to buffer *ghostel*<5>).
1 parent c6eb801 commit cd7c043

3 files changed

Lines changed: 57 additions & 28 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ individual faces with `M-x customize-face`.
322322

323323
| Command | Description |
324324
|--------------------------------|----------------------------------------------|
325-
| `M-x ghostel` | Open a new terminal |
326-
| `M-x ghostel-project` | Open a terminal in the current project root |
325+
| `M-x ghostel` | Open a new terminal (create new buffer with prefix arg) |
326+
| `M-x ghostel-project` | Open a terminal in the current project root (create new buffer with prefix arg) |
327327
| `M-x ghostel-other` | Switch to next terminal or create one |
328328
| `M-x ghostel-clear` | Clear screen and scrollback |
329329
| `M-x ghostel-clear-scrollback` | Clear scrollback only |

ghostel.el

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,6 @@ DIR is the module directory."
576576
(defvar-local ghostel--input-timer nil
577577
"Timer for flushing coalesced input.")
578578

579-
580-
581-
582579
(defvar-local ghostel--last-directory nil
583580
"Last known working directory from OSC 7, used for dedup.")
584581

@@ -591,10 +588,6 @@ variable re-enables automatic renaming for the next title update.")
591588
"List of prompt positions as (buffer-line . exit-status) pairs.
592589
Used for prompt navigation and optional re-application after full redraws.")
593590

594-
595-
(defvar ghostel--buffer-counter 0
596-
"Counter for generating unique terminal buffer names.")
597-
598591

599592
;;; Keymap
600593

@@ -1984,9 +1977,14 @@ wheel events reach ghostel's own scroll commands."
19841977
;;; Entry point
19851978

19861979
;;;###autoload
1987-
(defun ghostel ()
1988-
"Create a new Ghostel terminal buffer."
1989-
(interactive)
1980+
(defun ghostel (&optional arg)
1981+
"Start a new Ghostel terminal. If the buffer already exists, switch to it.
1982+
With a non-numeric prefix arg, create a new buffer.
1983+
With a numeric prefix ARG, switch to the buffer with that number or
1984+
create it if it doesn't exist yet.
1985+
The name of the buffer is determined by the value of `ghostel-buffer-name'."
1986+
(interactive "P")
1987+
(cl-assert ghostel-buffer-name)
19901988
(unless (fboundp 'ghostel--new)
19911989
(let ((dir (file-name-directory (locate-library "ghostel"))))
19921990
(ghostel--ensure-module dir)
@@ -1995,33 +1993,41 @@ wheel events reach ghostel's own scroll commands."
19951993
(if (file-exists-p mod)
19961994
(module-load mod)
19971995
(user-error "Ghostel native module not available")))))
1998-
(let* ((index (cl-incf ghostel--buffer-counter))
1999-
(buf-name (if (= index 1)
2000-
ghostel-buffer-name
2001-
(format "%s<%d>" ghostel-buffer-name index)))
2002-
(buffer (generate-new-buffer buf-name)))
1996+
(let ((buffer (cond ((numberp arg)
1997+
(get-buffer-create (format "%s<%d>"
1998+
ghostel-buffer-name
1999+
arg)))
2000+
(arg
2001+
(generate-new-buffer ghostel-buffer-name))
2002+
(t
2003+
(get-buffer-create ghostel-buffer-name)))))
2004+
(cl-assert (and buffer (buffer-live-p buffer)))
20032005
(with-current-buffer buffer
2004-
(ghostel-mode)
2005-
(setq ghostel--managed-buffer-name (buffer-name))
2006-
(let* ((height (window-body-height))
2007-
(width (window-max-chars-per-line)))
2008-
(setq ghostel--term
2009-
(ghostel--new height width ghostel-max-scrollback))
2010-
(ghostel--apply-palette ghostel--term))
2011-
(ghostel--start-process))
2006+
(unless (derived-mode-p 'ghostel-mode)
2007+
(ghostel-mode)
2008+
(setq ghostel--managed-buffer-name (buffer-name))
2009+
(let* ((height (window-body-height))
2010+
(width (window-max-chars-per-line)))
2011+
(setq ghostel--term
2012+
(ghostel--new height width ghostel-max-scrollback))
2013+
(ghostel--apply-palette ghostel--term))
2014+
(ghostel--start-process)))
20122015
(switch-to-buffer buffer)))
20132016

20142017
;;;###autoload
20152018
(defun ghostel-project ()
2016-
"Create a new Ghostel terminal in the current project's root.
2019+
"Start a new Ghostel terminal in the current project's root.
20172020
The buffer name is prefixed with the project name.
2021+
If a buffer already exists for this project switch to it.
2022+
Otherwise create a new Ghostel buffer. This function accepts the same
2023+
universal arguments that `ghostel' does.
20182024
To add this to `project-switch-commands':
20192025
(add-to-list \\='project-switch-commands \\='(ghostel-project \"Ghostel\") t)"
20202026
(interactive)
20212027
(let ((default-directory (project-root (project-current t)))
20222028
(ghostel-buffer-name (project-prefixed-buffer-name
20232029
(string-trim ghostel-buffer-name "*" "*"))))
2024-
(ghostel)))
2030+
(ghostel current-prefix-arg)))
20252031

20262032
(defun ghostel-other ()
20272033
"Switch to the next ghostel terminal buffer, or create one."

test/ghostel-test.el

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,7 @@ cell, so the visual line width must equal the terminal column count."
11991199
((symbol-function 'project-root)
12001200
(lambda (proj) (cdr proj)))
12011201
((symbol-function 'ghostel)
1202-
(lambda ()
1202+
(lambda (&optional _)
12031203
(setq result (cons default-directory ghostel-buffer-name)))))
12041204
(ghostel-project)
12051205
;; default-directory should be the project root
@@ -1208,6 +1208,28 @@ cell, so the visual line width must equal the terminal column count."
12081208
(should (string-match-p "ghostel" (cdr result)))
12091209
(should-not (string-match-p "\\*\\*" (cdr result))))))
12101210

1211+
;; -----------------------------------------------------------------------
1212+
;; Test: ghostel-project passes universal args to ghostel
1213+
;; -----------------------------------------------------------------------
1214+
1215+
(ert-deftest ghostel-test-project-universal-arg ()
1216+
"Test that `ghostel-project' passes the universal arg to `ghostel'."
1217+
(require 'project)
1218+
(let ((ghostel-buffer-name "*ghostel*")
1219+
(current-prefix-arg '4)
1220+
result)
1221+
;; Stub project-current, project-root, and ghostel to capture args
1222+
(cl-letf (((symbol-function 'project-current)
1223+
(lambda (_maybe-prompt) '(transient . "/tmp/myproj/")))
1224+
((symbol-function 'project-root)
1225+
(lambda (proj) (cdr proj)))
1226+
((symbol-function 'ghostel)
1227+
(lambda (&optional arg)
1228+
(setq result arg))))
1229+
(ghostel-project)
1230+
;; Pass the prefix argument to `ghostel'
1231+
(should (equal '4 result)))))
1232+
12111233
;; -----------------------------------------------------------------------
12121234
;; Runner
12131235
;; -----------------------------------------------------------------------
@@ -1536,6 +1558,7 @@ cell, so the visual line width must equal the terminal column count."
15361558
ghostel-test-copy-mode-cursor
15371559
ghostel-test-copy-mode-hl-line
15381560
ghostel-test-project-buffer-name
1561+
ghostel-test-project-universal-arg
15391562
ghostel-test-package-version
15401563
ghostel-test-module-version-match
15411564
ghostel-test-module-version-mismatch

0 commit comments

Comments
 (0)