Override doom's default vterm module
This commit is contained in:
parent
6f9fadaea8
commit
1b4eda2cbb
60
modules/term/vterm/README.org
Normal file
60
modules/term/vterm/README.org
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#+TITLE: term/vterm
|
||||||
|
#+DATE: April 4, 2022
|
||||||
|
#+SINCE: 3.0
|
||||||
|
#+STARTUP: inlineimages
|
||||||
|
|
||||||
|
* Table of Contents :TOC_3:noexport:
|
||||||
|
- [[#description][Description]]
|
||||||
|
- [[#module-flags][Module Flags]]
|
||||||
|
- [[#plugins][Plugins]]
|
||||||
|
- [[#prerequisites][Prerequisites]]
|
||||||
|
- [[#dynamic-module-support][Dynamic Module support]]
|
||||||
|
- [[#libvterm][libvterm]]
|
||||||
|
- [[#compilation-tools-for-vterm-moduleso][Compilation tools for vterm-module.so]]
|
||||||
|
|
||||||
|
* Description
|
||||||
|
This module provides a terminal emulator powered by libvterm.
|
||||||
|
|
||||||
|
The following commands are available to open it:
|
||||||
|
|
||||||
|
+ ~+vterm/other-window~ (=C-c o t=): Opens vterm in other window
|
||||||
|
+ ~+vterm/project/other-window~ (=C-c o p=): Opens vterm in the current project in other window
|
||||||
|
+ ~+vterm/here~ (=C-c o T=): Opens vterm in the current window
|
||||||
|
+ ~+vterm/project/here~ (=C-c o P=): Opens vterm in the current project in the current window
|
||||||
|
|
||||||
|
These commands will first try to find an existing suitable vterm buffer and open
|
||||||
|
it. If one does not exist, they will create a new one. If the current buffer is
|
||||||
|
such a vterm buffer, a new vterm session will be created.
|
||||||
|
|
||||||
|
** Module Flags
|
||||||
|
This module provides no flags.
|
||||||
|
|
||||||
|
** Plugins
|
||||||
|
+ [[https://github.com/akermu/emacs-libvterm][vterm]]
|
||||||
|
|
||||||
|
* Prerequisites
|
||||||
|
+ Emacs must be built with dynamic module support, i.e. compiled with the
|
||||||
|
=--with-modules= option.
|
||||||
|
+ You need =libvterm= installed on your system.
|
||||||
|
+ You need =make=, =cmake= and a C compiler such as =gcc= so that vterm can
|
||||||
|
build =vterm-module.so=.
|
||||||
|
|
||||||
|
** Dynamic Module support
|
||||||
|
To check if your build of Emacs was built with dynamic module support, check
|
||||||
|
~bin/doom info~ for ~MODULES~ next to "System features". If it's there, you're
|
||||||
|
good to go.
|
||||||
|
|
||||||
|
You can also check for =--with-modules= in the ~system-configuration-options~
|
||||||
|
variable (=C-c h v system-configuration-options=).
|
||||||
|
|
||||||
|
** libvterm
|
||||||
|
+ Ubuntu or Debian users: ~apt-get install libvterm-dev~
|
||||||
|
|
||||||
|
** Compilation tools for vterm-module.so
|
||||||
|
When you first load vterm, it will compile =vterm-module.so= for you. For this
|
||||||
|
to succeed, you need the following:
|
||||||
|
|
||||||
|
+ =make=
|
||||||
|
+ =cmake=
|
||||||
|
+ A C compiler like =gcc=
|
||||||
|
+ An internet connection (=cmake= will download needed libraries)
|
121
modules/term/vterm/autoload.el
Normal file
121
modules/term/vterm/autoload.el
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
;;; 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))
|
25
modules/term/vterm/config.el
Normal file
25
modules/term/vterm/config.el
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
;;; term/vterm/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(use-package! vterm
|
||||||
|
:when (bound-and-true-p module-file-suffix)
|
||||||
|
:commands (vterm vterm-other-window)
|
||||||
|
:hook (vterm-mode . doom-mark-buffer-as-real-h)
|
||||||
|
:init
|
||||||
|
;; HACK Because vterm clusmily forces vterm-module.so's compilation on us when
|
||||||
|
;; the package is loaded, this is necessary to prevent it when
|
||||||
|
;; byte-compiling this file (`use-package' blocks eagerly loads packages
|
||||||
|
;; when compiled).
|
||||||
|
(when noninteractive
|
||||||
|
(advice-add #'vterm-module-compile :override #'ignore)
|
||||||
|
(provide 'vterm-module))
|
||||||
|
|
||||||
|
:config
|
||||||
|
(set-popup-rule! "^\\*vterm" :ignore t)
|
||||||
|
|
||||||
|
;; Once vterm is dead, the vterm buffer is useless. Why keep it around? We can
|
||||||
|
;; spawn another if we want one.
|
||||||
|
(setq vterm-kill-buffer-on-exit t)
|
||||||
|
|
||||||
|
(setq-hook! 'vterm-mode-hook
|
||||||
|
;; Prevent premature horizontal scrolling
|
||||||
|
hscroll-margin 0))
|
10
modules/term/vterm/doctor.el
Normal file
10
modules/term/vterm/doctor.el
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
;;; term/vterm/doctor.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(unless (executable-find "make")
|
||||||
|
(warn! "Couldn't find make command. Vterm module won't compile"))
|
||||||
|
|
||||||
|
(unless (executable-find "cmake")
|
||||||
|
(warn! "Couldn't find cmake command. Vterm module won't compile"))
|
||||||
|
|
||||||
|
(unless (fboundp 'module-load)
|
||||||
|
(warn! "Your emacs wasn't built with dynamic modules support. The vterm module won't build"))
|
6
modules/term/vterm/packages.el
Normal file
6
modules/term/vterm/packages.el
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
;; -*- no-byte-compile: t; -*-
|
||||||
|
;;; term/vterm/packages.el
|
||||||
|
|
||||||
|
(package! vterm
|
||||||
|
:built-in 'prefer
|
||||||
|
:pin "a940dd2ee8a82684860e320c0f6d5e15d31d916f")
|
Loading…
Reference in New Issue
Block a user