├── .gitignore ├── README.md ├── term-toggle.el └── term-toggle.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.elc 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # emacs-term-toggle 2 | 3 | ## About 4 | 5 | ![Screenshot:](term-toggle.png) 6 | 7 | Term-toggle lets you quickly toggle shells that come built-in with Emacs. Currently it can toggle shell, term, ansi-term, eshell, and ielm. You can put each one on a keyboard shortcut and toggle a console off and on as needed. The console will be 8 | opened in the current buffer's default directory. This applicaiton is similar to [shell-pop](https://github.com/kyagi/shell-pop-el), but this one lets you have different terminals open at once, while shell-pop works only on pre-defined 9 | one. I like to be able to work both with ielm/eshell and open a terminal from time to time, so I don't want to have just one pre-defined terminal I can pop back and forth. Term-toggle is also much lighter in resource usage and with somewhat 10 | less features than shell-pop. Most notably you can't easily add your own shell via an API, but it is so small, so you can easily hack it in :). 11 | 12 | It is al about cnvenicence and minimalism. I personally really care only about eshell, term and ielm, and wish to be able to toggle them on and off quickly. When I wish to kill a term, I don't want to answer y-or-no questions, so it has 13 | features to quickly kill buffer or it's process. 14 | 15 | ## Features 16 | 17 | - very minimalistic and light on resources 18 | - multiple shells out of the box 19 | - automatically exit process when console buffer is killed 20 | - automatically kill buffer and its window when shell is exited 21 | 22 | ## Install 23 | 24 | For the moment this is not in any package repository, so you will have to download it from the git and install with package with 25 | 26 | M-x package-install-file 27 | 28 | I will see if they would like to have it in Melpa. 29 | 30 | Alternatively you may install it manually by adding term-toggle.el to your load path and either generating autoloads, or require term-toggle.el when Emacs starts. 31 | 32 | ## Usage 33 | 34 | Bind `term-toggle' and `term-toggle-eshell' to keys of your choice, for example: 35 | 36 | (define-key global-map [S-f2] #'term-toggle-ansi) 37 | (define-key global-map [f2] #'term-toggle-eshell) 38 | 39 | We this setup you can press F2 to toggle eshell, or S-F2 to open anis-term, when you press it again it will go away. 40 | 41 | The term/eshell buffer will not get killed, just burried down so they are not in the way. 42 | 43 | Once you are done with using eshell or term, you can simply kill buffer to get rid of them. As a convenience, you can customize option to no confirm exit, so you don't need to confirm exit from the term because of the live bash process: 44 | 45 | (setq term-toggle-no-confirm-exit t) 46 | 47 | Optionally you can also customize option to kill-buffer and exit terminal window when shell process has exited: 48 | 49 | (setq term-toggle-kill-buffer-on-term-exit t) 50 | 51 | This way, if you press Ctrl+D in you shell window, term buffer and window will be killed too. 52 | 53 | ## History 54 | 55 | Derived from [Joseph's](https://www.emacswiki.org/emacs/term-toggle.el), this plugin brings up a quake-style console with commands term-toggle{,-cd}. The major difference with Joseph's version is that maximized console feature is removed 56 | (in the original version sometimes it gets stuck in maximized state, possibly because the window configuration is corrupted). Also, this plugin determines whether to split a new window for the console, or replace the buffer of current 57 | selected window if height is not enough for a split. Another feature is that this plugin will detect the status of the terminal. When there's no process running in *terminal* buffer, it will fire up another one. 58 | 59 | Added to [Yatao's version](https://github.com/v-yadli/emacs-term-toggle) is ability to open eshell console in current buffers as well as the option `term-toggle-no-confirm-exit' to let Emacs exit term buffer and kill bash process without confirmation. 60 | 61 | ## Licence 62 | 63 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 64 | 65 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 66 | 67 | You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/. 68 | 69 | -------------------------------------------------------------------------------- /term-toggle.el: -------------------------------------------------------------------------------- 1 | ;;; term-toggle.el --- Toggle to and from the *terminal* buffer -*- lexical-binding: t; -*- 2 | 3 | ;; Filename: term-toggle.el 4 | ;; Description: Toggle a dedicated terminal 5 | ;; Author: Joseph , Yatao , Arthur 6 | ;; Created: 2011-03-02 7 | ;; Version: 1.0 8 | ;; URL: https://github.com/v-yadli/emacs-term-toggle 9 | ;; Keywords: term toggle shell 10 | ;; Compatibility: (Test on GNU Emacs 28.0.50). 11 | ;; 12 | ;;; License 13 | ;; 14 | ;; This program 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 3, or (at your option) 17 | ;; any later version. 18 | 19 | ;; This program 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 this program; see the file COPYING. If not, write to 26 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth 27 | ;; Floor, Boston, MA 02110-1301, USA. 28 | ;; 29 | 30 | ;;; Commentary: 31 | ;; Derived from Joseph (URL: 32 | ;; http://www.emacswiki.org/term-toggle.el), this plugin brings up a 33 | ;; quake-style console with commands term-toggle{,-cd} 34 | ;; The major difference with Joseph's version is that maximized 35 | ;; console feature is removed (in the original version sometimes it 36 | ;; gets stuck in maximized state, possibly because the window 37 | ;; configuration is corrupted). Also, this plugin determines whether 38 | ;; to split a new window for the console, or replace the buffer of 39 | ;; current selected window if height is not enough for a 40 | ;; split. Another feature is that this plugin will detect the status 41 | ;; of the terminal. When there's no process running in *terminal* 42 | ;; buffer, it will fire up another one. 43 | 44 | ;;; History: 45 | ;; 2021-09-16 A. Miller simplified and refactored code 46 | ;; 2021-09-13 A. Miller added support for shell, ansi-term and ielm. 47 | ;; 2021-09-04 A. Miller added support to exit term without quering for exit-confirm. 48 | ;; 2019-01-23 A. Miller added eshell toggle 49 | 50 | 51 | ;;; Customizable Options: 52 | (defgroup term-toggle nil 53 | "Quake style console toggle in current working directory. 54 | Support toggle for shell, term, ansi-term, eshell and ielm." 55 | :prefix "term-toggle-" 56 | :group 'applications) 57 | 58 | (defcustom term-toggle-confirm-exit nil 59 | "Ask to confirm exit if there is a running bash process in terminal." 60 | :type 'boolean 61 | :group 'term-toggle) 62 | 63 | (defcustom term-toggle-kill-buffer-on-process-exit t 64 | "Kill buffer when shell process has exited." 65 | :type 'boolean 66 | :group 'term-toggle) 67 | 68 | (defcustom term-toggle-minimum-split-height 10 69 | "The minimum height of a splittable window" 70 | :type 'fixnum 71 | :group 'term-toggle) 72 | 73 | (defcustom term-toggle-default-height 15 74 | "The default height of a splitted window." 75 | :type 'fixnum 76 | :group 'term-toggle) 77 | 78 | ;;; Internal functions and declarations 79 | (defun term-toggle--start (shell name) 80 | (if (or (eq shell 'term) (eq shell 'ansi-term)) 81 | (funcall shell (getenv "SHELL")) 82 | (funcall shell)) 83 | (when-let ((proc (get-buffer-process (get-buffer name)))) 84 | (set-process-query-on-exit-flag proc term-toggle-confirm-exit) 85 | (when term-toggle-kill-buffer-on-process-exit 86 | (set-process-sentinel 87 | proc (lambda (__ evt) 88 | (when (string-match-p "\\(?:exited\\|finished\\)" evt) 89 | (kill-buffer))))))) 90 | 91 | (defun term-toggle--toggle (term-buffer) 92 | (if-let ((term-window (get-buffer-window term-buffer))) 93 | (progn 94 | (bury-buffer term-buffer) 95 | (delete-window term-window)) 96 | (split-window-vertically) 97 | (other-window 1) 98 | (pop-to-buffer-same-window term-buffer t) 99 | (set-window-dedicated-p term-window t) 100 | (when (>= (window-total-height (selected-window)) 101 | term-toggle-minimum-split-height) 102 | (let ((delta (- (window-height (selected-window)) term-toggle-default-height))) 103 | (when (> delta 0) (shrink-window delta)))))) 104 | 105 | (defun term-toggle (shell) 106 | (let ((name (format "*%s*" (if (eq shell 'term) "terminal" shell))) 107 | (original-buffer (current-buffer))) 108 | (unless (get-buffer name) 109 | (term-toggle--start shell name) 110 | (pop-to-buffer-same-window original-buffer)) 111 | (term-toggle--toggle (get-buffer name)))) 112 | 113 | ;;; Commands 114 | ;;;###autoload 115 | (defun term-toggle-term () 116 | "Toggle `term'." 117 | (interactive) (term-toggle 'term)) 118 | 119 | ;;;###autoload 120 | (defun term-toggle-shell () 121 | "Toggle `shell'." 122 | (interactive) (term-toggle 'shell)) 123 | 124 | ;;;###autoload 125 | (defun term-toggle-ansi () 126 | "Toggle `ansi-term'." 127 | (interactive) (term-toggle 'ansi-term)) 128 | 129 | ;;;###autoload 130 | (defun term-toggle-eshell () 131 | "Toggle `eshell'." 132 | (interactive) (term-toggle 'eshell)) 133 | 134 | ;;;###autoload 135 | (defun term-toggle-ielm () 136 | "Toggle `ielm'." 137 | (interactive) (term-toggle 'ielm)) 138 | 139 | (provide 'term-toggle) 140 | 141 | ;;; term-toggle.el ends here 142 | -------------------------------------------------------------------------------- /term-toggle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amno1/emacs-term-toggle/76587d8af4859383da2fa7f72fd8c8b6289ee9d1/term-toggle.png --------------------------------------------------------------------------------