doom/modules/term/vterm/autoload.el

130 lines
4.2 KiB
EmacsLisp

;;; term/vterm/autoload.el -*- lexical-binding: t; -*-
(defun +vterm--buffer-name ()
"Get the base name for vterm buffers."
(format "*vterm%s*"
(if (bound-and-true-p persp-mode)
(format ":%s" (safe-persp-name (get-current-persp)))
"")))
(defun +vterm--get-existing-buffer ()
"Find an existing buffer in vterm-mode.
Assumes vterm buffers are killed on exit."
(seq-find (lambda (buffer)
(string-prefix-p (+vterm--buffer-name) (buffer-name buffer)))
(buffer-list)))
(defun +vterm--vterm (vterm-buffer-name)
"Create a vterm session with some tty hack."
;; HACK forces vterm to redraw, fixing strange artefacting in the tty.
(save-window-excursion
(pop-to-buffer "*scratch*"))
(vterm vterm-buffer-name))
(defun +vterm--spawn-or-switch (spawn-fn switch-fn)
"Open using `spawn-fn' or switch to active vterm using `switch-fn'.
If current buffer is in vterm-mode:
Open a new vterm using `spawn-fn';
If current buffer is not in vterm-mode:
If a buffer in vterm-mode exists:
Switch to that buffer using `switch-fn';
If it does not exist:
Open a new vterm using `spawn-fn'.
Returns the vterm buffer"
(unless (fboundp 'module-load)
(user-error
"Your build of Emacs lacks dynamic modules support and cannot load vterm"))
(require 'vterm)
(let ((vterm-buffer-name (+vterm--buffer-name)))
(if (string= major-mode "vterm-mode")
(funcall spawn-fn vterm-buffer-name)
(let ((existing-vterm (+vterm--get-existing-buffer)))
(if existing-vterm
(funcall switch-fn existing-vterm)
(funcall spawn-fn vterm-buffer-name)))))
)
(defun +vterm--spawn-or-switch-with-project (spawn-fn switch-fn)
"Open with `spawn-fn' or switch to active vterm with `switch-fn' in a project.
Returns the vterm buffer"
(let ((project-root (doom-project-root)))
(unless project-root
(user-error
"vterm/project cannot find a project, because you are not in a project"))
(let ((default-directory project-root))
(+vterm--spawn-or-switch spawn-fn switch-fn))))
(defun +vterm--other-window (other-window-fn current-window-fn)
"Open or switch with `other-window-fn'.
Unless current buffer is doom-dashboard.
Returns the vterm buffer."
(if (equal major-mode #'+doom-dashboard-mode)
(funcall current-window-fn)
(funcall other-window-fn)))
;;;###autoload
(defun +vterm/other-window ()
"Open or switch to active vterm in other window.
If invoked from a vterm window a new vterm session is created.
An exception is made for the doom-dashboard. If the current
buffer is the doom-dashboard, vterm opens in the current window.
Returns the vterm buffer."
(interactive)
(+vterm--other-window
(lambda ()
(+vterm--spawn-or-switch #'vterm-other-window
#'switch-to-buffer-other-window))
(lambda ()
(+vterm--spawn-or-switch #'+vterm--vterm
#'switch-to-buffer))))
;;;###autoload
(defun +vterm/project/other-window ()
"Open or switch to active vterm in other window in current project.
If invoked from a vterm window a new vterm session is created.
An exception is made for the doom-dashboard. If the current
buffer is the doom-dashboard, vterm opens in the current window.
Returns the vterm buffer."
(interactive)
(+vterm--other-window
(lambda ()
(+vterm--spawn-or-switch-with-project #'vterm-other-window
#'switch-to-buffer-other-window))
(lambda ()
(+vterm--spawn-or-switch-with-project #'+vterm--window
#'switch-to-buffer))))
;;;###autoload
(defun +vterm/here ()
"Open or switch to active vterm in the current window.
If invoked from a vterm window a new vterm session is created.
Returns the vterm buffer."
(interactive)
(+vterm--spawn-or-switch #'+vterm--vterm
#'switch-to-buffer))
;;;###autoload
(defun +vterm/project/here ()
"Open or switch to active vterm in the current window.
If invoked from a vterm window a new vterm session is created.
Returns the vterm buffer."
(interactive)
(+vterm--spawn-or-switch-with-project #'+vterm--vterm
#'switch-to-buffer))