;;; 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")) (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 using `spawn-fn' or switch to active vterm using `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 using `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))