diff --git a/init.example.el b/init.example.el index 65c7cc9b8..38c9b35a0 100644 --- a/init.example.el +++ b/init.example.el @@ -79,6 +79,7 @@ ;;tmux ; an API for interacting with tmux ;;upload ; map local to remote projects via ssh/ftp ;;wakatime + ;;vterm ; another terminals in Emacs :lang ;;assembly ; assembly for fun or debugging diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 4ddb344b5..e625846b2 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -730,6 +730,9 @@ (:when (featurep! :emacs term) :desc "Terminal" "t" #'+term/open :desc "Terminal in popup" "T" #'+term/open-popup-in-project) + (:when (featurep! :tools 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/tools/vterm/autoload.el b/modules/tools/vterm/autoload.el new file mode 100644 index 000000000..52f663a73 --- /dev/null +++ b/modules/tools/vterm/autoload.el @@ -0,0 +1,29 @@ +;;; tools/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/tools/vterm/config.el b/modules/tools/vterm/config.el new file mode 100644 index 000000000..ab89ee5ee --- /dev/null +++ b/modules/tools/vterm/config.el @@ -0,0 +1,41 @@ +;;; tools/vterm/config.el -*- lexical-binding: t; -*- + +(def-package! vterm + :when (fboundp 'module-load) + :defer t + :init (setq vterm-install t) + :config + (set-env! "SHELL") + (set-popup-rule! "^vterm" :size 0.25 :vslot -4 :select t :quit nil :ttl 0) + + (add-hook 'vterm-mode-hook #'doom|mark-buffer-as-real) + ;; Automatically kill buffer when vterm exits. + (add-to-list 'vterm-exit-functions (lambda (buffer) (if buffer (kill-buffer buffer)))) + + (when (featurep! :feature evil) + (evil-set-initial-state 'vterm-mode '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. + (setq-hook! 'vterm-mode-hook evil-move-cursor-back nil) + ;; Those keys are commonly needed by terminals. + (evil-define-key* 'insert vterm-mode-map + (kbd "C-a") #'vterm--self-insert + (kbd "C-b") #'vterm--self-insert ; Should not be necessary. + (kbd "C-d") #'vterm--self-insert + (kbd "C-e") #'vterm--self-insert + (kbd "C-f") #'vterm--self-insert ; Should not be necessary. + (kbd "C-k") #'vterm--self-insert + (kbd "C-l") #'vterm--self-insert ; Should not be necessary. + (kbd "C-n") #'vterm--self-insert + (kbd "C-o") #'vterm--self-insert + (kbd "C-p") #'vterm--self-insert + (kbd "C-q") #'vterm--self-insert ; Should not be necessary. + (kbd "C-r") #'vterm--self-insert + (kbd "C-s") #'vterm--self-insert ; Should not be necessary. + (kbd "C-t") #'vterm--self-insert + (kbd "C-u") #'vterm--self-insert ; Should not be necessary. + (kbd "C-v") #'vterm--self-insert ; Should not be necessary. + (kbd "C-w") #'vterm--self-insert + (kbd "C-y") #'vterm--self-insert + (kbd "C-z") #'vterm--self-insert))) diff --git a/modules/tools/vterm/doctor.el b/modules/tools/vterm/doctor.el new file mode 100644 index 000000000..866c4b62d --- /dev/null +++ b/modules/tools/vterm/doctor.el @@ -0,0 +1,13 @@ +;;; tools/vterm/doctor.el -*- lexical-binding: t; -*- + +(unless (executable-find "vterm-ctrl") + (warn! "Couldn't find libvterm. Vterm module won't compile.")) + +(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 don't have MODULES support. Vterm module won't work.")) diff --git a/modules/tools/vterm/packages.el b/modules/tools/vterm/packages.el new file mode 100644 index 000000000..c0d33a1d5 --- /dev/null +++ b/modules/tools/vterm/packages.el @@ -0,0 +1,7 @@ +;; -*- no-byte-compile: t; -*- +;;; tools/vterm/packages.el + +(package! vterm :recipe + (:fetcher github + :repo "akermu/emacs-libvterm" + :files ("*"))) diff --git a/modules/tools/vterm/readme.org b/modules/tools/vterm/readme.org new file mode 100644 index 000000000..077e6a668 --- /dev/null +++ b/modules/tools/vterm/readme.org @@ -0,0 +1,94 @@ +#+TITLE: tools/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]] + - [[System requirement][System requirement]] + - [[Module requirement][Module requirement]] + +* Description +An [[https://github.com/akermu/emacs-libvterm][emacs-libvterm]] module. + +* Prerequisites + +** Emacs requirement + +You have to compile emacs with =--with-modules= option. + +Check the =system-configuration-options= variable to see if your emacs has this +option. + +- On Archlinux or Manjaro, if you install emacs with pacman, this option is + enabled. +- On macOS: + - If you use [[https://emacsformacosx.com/][Emacs For Mac OS X]], this option is enabled. + - If you use [[https://github.com/d12frosted/homebrew-emacs-plus][emacs-plus]], this option is enabled by default. + - If you use [[https://github.com/railwaycat/homebrew-emacsmacport][emacs-mac]], this options is *not* enabled by default. You may have + to reinstall emacs with the option: + #+BEGIN_SRC sh + brew install emacs-mac --with-modules + #+END_SRC + +** 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 + + +** Module requirement + +You have to compile and install the requied module =vterm-module.so=. + +In order to compile it you need to have: + +- Compilation tools. This include =make=, =cmake= and a c compiler such as + =gcc=. +- Internet connection, because =cmake= will automatically download some requied + libraries from the internet. + +There are several ways to install the module: + +1. You can use =M-x vterm-module-compile= to let emacs automatically compile and + install the module. + + *WARNING*: Emacs will hang during the compilation. It may take a while. + +2. A fully byte-compile will cause emacs to automatically compile and install + the module if it cannot find an executable =vterm-module.so= file. + +3. You can compile and install the module yourself. Go to the vterm installation + directory, which is usually + =~/.emacs.d/.local/packages/elpa/vterm-=, and run the following: + + #+BEGIN_SRC sh + mkdir -p build + cd build + cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. + make + #+END_SRC + +4. You can also compile the module at other place, and install the compiled + =vterm-module.so= file to your vterm installation folder, which is usually + =~/.emacs.d/.local/packages/elpa/vterm-/=. Also make sure the module + file is executable.