eshell-vterm.el (4098B)
1 ;;; eshell-vterm.el --- Vterm for visual commands in eshell -*- lexical-binding: t; -*- 2 3 ;; Author: Illia Ostapyshyn <ilya.ostapyshyn@gmail.com> 4 ;; Maintainer: Illia Ostapyshyn <ilya.ostapyshyn@gmail.com> 5 ;; Created: 2021-06-29 6 ;; Package-Version: 20240305.1149 7 ;; Package-Revision: 20f4b246fa60 8 ;; Package-Requires: ((emacs "27.1") (vterm "0.0.1")) 9 ;; Keywords: eshell, vterm, terminals, shell, visual, tools, processes 10 ;; URL: https://github.com/iostapyshyn/eshell-vterm 11 12 ;; This file is not part of GNU Emacs. 13 14 ;; This file is free software; you can redistribute it and/or modify 15 ;; it under the terms of the GNU General Public License as published by 16 ;; the Free Software Foundation; either version 2, or (at your option) 17 ;; any later version. 18 19 ;; This file is distributed in the hope that it will be useful, 20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 ;; GNU General Public License for more details. 23 24 ;; You should have received a copy of the GNU General Public License 25 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 26 27 ;;; Commentary: 28 29 ;; This package provides a global minor mode allowing eshell to use 30 ;; vterm for visual commands. 31 32 ;;; Code: 33 34 (require 'vterm) 35 (require 'em-term) 36 (require 'esh-ext) 37 38 (defvar eshell-parent-buffer) 39 40 (defun eshell-vterm-exec-visual (&rest args) 41 "Run the specified PROGRAM in a terminal emulation buffer. 42 ARGS are passed to the program. At the moment, no piping of input is 43 allowed. In case ARGS is nil, a new VTerm session is created." 44 (if args 45 (let* (eshell-interpreter-alist 46 (interp (eshell-find-interpreter (car args) (cdr args))) 47 (program (car interp)) 48 (args (flatten-tree 49 (eshell-stringify-list (append (cdr interp) 50 (cdr args))))) 51 (args (mapconcat #'shell-quote-argument args " ")) 52 (term-buf (generate-new-buffer 53 (concat "*" (file-name-nondirectory program) "*"))) 54 (eshell-buf (current-buffer)) 55 (vterm-shell (concat (shell-quote-argument 56 (file-local-name program)) 57 " " args))) 58 (save-current-buffer 59 (switch-to-buffer term-buf) 60 (cl-letf (((symbol-function 'vterm--get-shell) 61 (lambda () vterm-shell))) 62 (vterm-mode)) 63 (setq-local eshell-parent-buffer eshell-buf) 64 (let ((proc (get-buffer-process term-buf))) 65 (if (and proc (eq 'run (process-status proc))) 66 (set-process-sentinel proc #'eshell-vterm-sentinel) 67 (error "Failed to invoke visual command"))))) 68 (vterm '(4))) ; Start a new session 69 nil) 70 71 (defun eshell-vterm-sentinel (proc msg) 72 "Clean up the buffer visiting PROC with message MSG. 73 If `eshell-destroy-buffer-when-process-dies' is non-nil, destroy 74 the buffer." 75 (let ((vterm-kill-buffer-on-exit nil)) 76 (vterm--sentinel proc msg)) ;; First call the normal term sentinel. 77 (when eshell-destroy-buffer-when-process-dies 78 (let ((proc-buf (process-buffer proc))) 79 (when (and proc-buf (buffer-live-p proc-buf) 80 (not (eq 'run (process-status proc))) 81 (= (process-exit-status proc) 0)) 82 (if (eq (current-buffer) proc-buf) 83 (let ((buf (and (boundp 'eshell-parent-buffer) 84 eshell-parent-buffer 85 (buffer-live-p eshell-parent-buffer) 86 eshell-parent-buffer))) 87 (if buf 88 (switch-to-buffer buf)))) 89 (kill-buffer proc-buf))))) 90 91 ;;;###autoload 92 (define-minor-mode eshell-vterm-mode 93 "Use Vterm for eshell visual commands." 94 :global t 95 :group 'eshell-vterm 96 (if eshell-vterm-mode 97 (advice-add #'eshell-exec-visual :override #'eshell-vterm-exec-visual) 98 (advice-remove #'eshell-exec-visual #'eshell-vterm-exec-visual))) 99 100 (provide 'eshell-vterm) 101 ;;; eshell-vterm.el ends here