diff --git a/init.example.el b/init.example.el index 8789117f9..aecc8e67c 100644 --- a/init.example.el +++ b/init.example.el @@ -60,6 +60,7 @@ hideshow ; basic code-folding support imenu ; an imenu sidebar and searchable code index ;;term ; terminals in Emacs + ;;vterm ; another terminals in Emacs vc ; version-control and Emacs, sitting in a tree :tools diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index de2ccf508..b072979d3 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -689,6 +689,9 @@ (:when (featurep! :emacs term) :desc "Terminal" "t" #'+term/open :desc "Terminal in popup" "T" #'+term/open-popup-in-project) + (:when (featurep! :emacs vterm) + :desc "Terminal" "t" #'+vterm/open + :desc "Terminal in popup" "T" #'+vterm/open-popup-in-project) (:when (featurep! :emacs eshell) :desc "Eshell" "e" #'+eshell/open :desc "Eshell in popup" "E" #'+eshell/open-popup) diff --git a/modules/emacs/vterm/autoload.el b/modules/emacs/vterm/autoload.el new file mode 100644 index 000000000..4d3f7311d --- /dev/null +++ b/modules/emacs/vterm/autoload.el @@ -0,0 +1,29 @@ +;;; emacs/vterm/autoload.el -*- lexical-binding: t; -*- + +;;;###autoload +(defun +vterm/open (arg) + "Open a terminal buffer in the current window. If ARG (universal argument) is +non-nil, cd into the current project's root." + (interactive "P") + (let ((default-directory + (if arg + (or (doom-project-root) default-directory) + default-directory))) + (switch-to-buffer (save-window-excursion (vterm))))) + +;;;###autoload +(defun +vterm/open-popup (arg) + "Open a terminal popup window. If ARG (universal argument) is +non-nil, cd into the current project's root." + (interactive "P") + (let ((default-directory + (if arg + (or (doom-project-root) default-directory) + default-directory))) + (pop-to-buffer (save-window-excursion (vterm))))) + +;;;###autoload +(defun +vterm/open-popup-in-project () + "Open a terminal popup window in the root of the current project." + (interactive) + (+vterm/open-popup t)) diff --git a/modules/emacs/vterm/config.el b/modules/emacs/vterm/config.el new file mode 100644 index 000000000..32bc953ba --- /dev/null +++ b/modules/emacs/vterm/config.el @@ -0,0 +1,27 @@ +;;; emacs/vterm/config.el -*- lexical-binding: t; -*- + +(def-package! vterm + :load-path (lambda () (list (concat doom-packages-dir "/quelpa/build/vterm"))) + :init + (unless (file-executable-p (concat + (file-name-directory (locate-library "vterm")) + "vterm-module.so")) + ;; let vterm compile `vterm-modules.so' + (setq-default vterm-install t)) + :when (and (string-match-p "MODULES" system-configuration-features) + (display-graphic-p)) + :config + (set-env! "SHELL") + (add-hook 'vterm-mode-hook #'doom|mark-buffer-as-real) + ;; Automatically kill buffer when vterm exits. + (setq-default vterm-exit-functions #'kill-buffer) + (when (featurep! :feature evil) + (evil-set-initial-state 'vterm-mode 'insert) + ;; Those keys are commonly needed by terminals. + (evil-define-key 'insert vterm-mode-map + (kbd "C-d") #'vterm--self-insert) + ;; Go back to normal state but don't move cursor backwards. + ;; Moving cursor backwards is the default Vim behavior but + ;; it is not appropriate in some cases like terminals. + (add-hook 'vterm-mode-hook #'(lambda () + (setq-local evil-move-cursor-back nil))))) diff --git a/modules/emacs/vterm/doctor.el b/modules/emacs/vterm/doctor.el new file mode 100644 index 000000000..8f8837fc8 --- /dev/null +++ b/modules/emacs/vterm/doctor.el @@ -0,0 +1,13 @@ +;;; emacs/vterm/doctor.el -*- lexical-binding: t; -*- + +(unless (executable-find "vterm-ctrl") + (warn! "Couldn't find libvterm library. Please install it on your system")) + +(unless (executable-find "make") + (warn! "Couldn't find make command. Please install it on your system")) + +(unless (executable-find "cmake") + (warn! "Couldn't find cmake command. Please install it on your system")) + +(unless (string-match-p "MODULES" system-configuration-features) + (error! "You have to compile emacs with MODULES support")) diff --git a/modules/emacs/vterm/packages.el b/modules/emacs/vterm/packages.el new file mode 100644 index 000000000..f584b6c74 --- /dev/null +++ b/modules/emacs/vterm/packages.el @@ -0,0 +1,4 @@ +;; -*- no-byte-compile: t; -*- +;;; emacs/vterm/packages.el + +(package! vterm :recipe (:fetcher github :repo "akermu/emacs-libvterm")) diff --git a/modules/emacs/vterm/readme.org b/modules/emacs/vterm/readme.org new file mode 100644 index 000000000..3a8b13ba8 --- /dev/null +++ b/modules/emacs/vterm/readme.org @@ -0,0 +1,55 @@ +#+TITLE: emacs/vterm +#+DATE: January 16, 2019 +#+SINCE: {replace with next tagged release version} +#+STARTUP: inlineimages + +* Table of Contents :TOC_3:noexport: +- [[Description][Description]] +- [[Prerequisites][Prerequisites]] + - [[Emacs requirement][Emacs requirement]] + - [[Compiler requirement][Compiler requirement]] + - [[System requirement][System requirement]] + +* Description +An [[https://github.com/akermu/emacs-libvterm][emacs-libvterm]] module. + +* Prerequisites + +** Emacs requirement + +You have to compile emacs with =--with-modules= option. + +Lookat the =system-configuration-options= variable to see if your emacs has this option. + +** Compiler requirement + +Your system need to have =make= =cmake= and a c compiler to compile +=libvterm-module=, Emacs will automatically compile the module for you. + +You can also put your pre-compiled =vterm-module.so= to your vterm installation +folder, which is usually =~/.emacs.d/.local/packages/quelpa/build/vterm/=, +and make sure =vterm-module.so= file is executable, instead of let emacs compile +it for you. + +** System requirement + +You need to have =libvterm= installed in your system. + +On Ubuntu or Debian: + +#+BEGIN_SRC sh +sudo apt install libvterm-dev +#+END_SRC + +On ArchLinux or Manjaro: + +#+BEGIN_SRC sh +sudo pacman -S libvterm +#+END_SRC + +On macOS: + +#+BEGIN_SRC sh +brew install libvterm +#+END_SRC + diff --git a/modules/ui/popup/config.el b/modules/ui/popup/config.el index cb49d1e8d..088912b1c 100644 --- a/modules/ui/popup/config.el +++ b/modules/ui/popup/config.el @@ -144,6 +144,8 @@ prevent the popup(s) from messing up the UI (or vice versa)." :size 0.45 :vslot -3 :ttl 0 :quit t :select t) ("^\\*doom \\(?:term\\|eshell\\)" :size 0.25 :vslot -4 :select t :quit nil :ttl 0) + ("^vterm" + :size 0.25 :vslot -4 :select t :quit nil :ttl 0) ("^\\*doom:" :vslot -5 :size 0.35 :size bottom :autosave t :select t :modeline t :quit nil) ("^\\*\\(?:\\(?:Pp E\\|doom e\\)val\\)"