doomemacs/modules/term/vterm/autoload.el
Henrik Lissner a0a4aa81c1
fix(vterm): +vterm/toggle creating duplicates
If vterm-buffer-name-string is set to non-nil, then vterm will rename
the buffer after it is initialized. Since +vterm/toggle looks up buffers
by name, it will lose track of them, causing it to create a new one on
each invocation. With this, it will no longer lose track of them.

Fix: #6651
2022-08-09 17:18:35 +02:00

76 lines
2.7 KiB
EmacsLisp

;;; term/vterm/autoload.el -*- lexical-binding: t; -*-
(defvar +vterm--id nil)
;;;###autoload
(defun +vterm/toggle (arg)
"Toggles a terminal popup window at project root.
If prefix ARG is non-nil, recreate vterm buffer in the current project's root.
Returns the vterm buffer."
(interactive "P")
(+vterm--configure-project-root-and-display
arg
(lambda ()
(let ((buffer-name
(format "*doom:vterm-popup:%s*"
(if (bound-and-true-p persp-mode)
(safe-persp-name (get-current-persp))
"main")))
confirm-kill-processes
current-prefix-arg)
(when arg
(let ((buffer (get-buffer buffer-name))
(window (get-buffer-window buffer-name)))
(when (buffer-live-p buffer)
(kill-buffer buffer))
(when (window-live-p window)
(delete-window window))))
(if-let (win (get-buffer-window buffer-name))
(delete-window win)
(let ((buffer (or (cl-loop for buf in (doom-buffers-in-mode 'vterm-mode)
if (equal (buffer-local-value '+vterm--id buf)
buffer-name)
return buf)
(get-buffer-create buffer-name))))
(with-current-buffer buffer
(setq-local +vterm--id buffer-name)
(unless (eq major-mode 'vterm-mode)
(vterm-mode)))
(pop-to-buffer buffer)))
(get-buffer buffer-name)))))
;;;###autoload
(defun +vterm/here (arg)
"Open a terminal buffer in the current window at project root.
If prefix ARG is non-nil, cd into `default-directory' instead of project root.
Returns the vterm buffer."
(interactive "P")
(+vterm--configure-project-root-and-display
arg
(lambda()
(require 'vterm)
;; HACK forces vterm to redraw, fixing strange artefacting in the tty.
(save-window-excursion
(pop-to-buffer "*scratch*"))
(let (display-buffer-alist)
(vterm vterm-buffer-name)))))
(defun +vterm--configure-project-root-and-display (arg display-fn)
"Sets the environment variable PROOT and displays a terminal using `display-fn`.
If prefix ARG is non-nil, cd into `default-directory' instead of project root.
Returns the vterm buffer."
(unless (fboundp 'module-load)
(user-error "Your build of Emacs lacks dynamic modules support and cannot load vterm"))
(let* ((project-root (or (doom-project-root) default-directory))
(default-directory
(if arg
default-directory
project-root)))
(setenv "PROOT" project-root)
(funcall display-fn)))