diff options
| author | Jack Jamison <jackqjamison@gmail.com> | 2026-07-05 01:19:30 -0400 |
|---|---|---|
| committer | Jack Jamison <jackqjamison@gmail.com> | 2026-07-05 01:19:30 -0400 |
| commit | bdf9a71ab7baa2b1de9abcfd5df1a9107a55d141 (patch) | |
| tree | c4524e6c41aa5107211103401dabfaefc81aa882 /.config/emacs/lisp/evil-collection/modes/eshell | |
| parent | fe3984f541bd32bdfa418afb305b614176b55ca0 (diff) | |
add a bunch of emacs packages HELP
Diffstat (limited to '.config/emacs/lisp/evil-collection/modes/eshell')
| -rw-r--r-- | .config/emacs/lisp/evil-collection/modes/eshell/README.org | 36 | ||||
| -rw-r--r-- | .config/emacs/lisp/evil-collection/modes/eshell/evil-collection-eshell.el | 168 |
2 files changed, 204 insertions, 0 deletions
diff --git a/.config/emacs/lisp/evil-collection/modes/eshell/README.org b/.config/emacs/lisp/evil-collection/modes/eshell/README.org new file mode 100644 index 0000000..0d4ab5f --- /dev/null +++ b/.config/emacs/lisp/evil-collection/modes/eshell/README.org @@ -0,0 +1,36 @@ +* eshell + + Evil bindings for [[https://www.gnu.org/software/emacs/manual/html_node/eshell/index.html][Eshell]]. + +** Key bindings + + Normal-state bindings added to =eshell-mode-map=. + + | Command | Original | Evil | + |---------------------------------------------------+-----------+-------------------| + | =eshell-previous-prompt= | =C-c C-p= | =[[=, =gk=, =C-k= | + | =eshell-next-prompt= | =C-c C-n= | =]]=, =gj=, =C-j= | + | =eshell-backward-argument= | =C-c C-b= | =M-h= | + | =eshell-forward-argument= | =C-c C-f= | =M-l= | + | =eshell-previous-matching-input-from-input= | =C-c M-p= | =C-p= | + | =eshell-next-matching-input-from-input= | =C-c M-n= | =C-n= | + | =eshell-bol= (Emacs < 30) | =C-a= | =0=, =^= | + | =eshell-kill-input= (when =evil-want-C-u-delete=) | =C-c C-u= | =C-u= (insert) | + + =RET= sends input in the state named by =evil-collection-repl-submit-state=, + and inserts a newline in the complementary state. + +** New commands + + | Command | Key | | + |--------------------------------------------+-----------+-----------------------------------------| + | =evil-collection-eshell-interrupt-process= | =C-c C-c= | interrupt process, then enter insert | + | =evil-collection-eshell-evil-change= | =c= | change, never touches prompt or history | + | =evil-collection-eshell-evil-change-line= | =C= | change to end-of-line | + | =evil-collection-eshell-evil-delete= | =d= | delete, never touches prompt or history | + | =evil-collection-eshell-evil-delete-line= | =D= | delete to end-of-line | + +** Notes + + - On entering insert/replace state, point jumps to the next prompt. + - On entering normal state, point stays put (no Vim-style backward step). diff --git a/.config/emacs/lisp/evil-collection/modes/eshell/evil-collection-eshell.el b/.config/emacs/lisp/evil-collection/modes/eshell/evil-collection-eshell.el new file mode 100644 index 0000000..30580d2 --- /dev/null +++ b/.config/emacs/lisp/evil-collection/modes/eshell/evil-collection-eshell.el @@ -0,0 +1,168 @@ +;;; evil-collection-eshell.el --- Evil bindings for Eshell -*- lexical-binding: t -*- + +;; Copyright (C) 2017, 2021 Pierre Neidhardt + +;; Author: Pierre Neidhardt <mail@ambrevar.xyz> +;; Maintainer: James Nguyen <james@jojojames.com> +;; Pierre Neidhardt <mail@ambrevar.xyz> +;; URL: https://github.com/emacs-evil/evil-collection +;; Version: 0.0.1 +;; Package-Requires: ((emacs "26.3")) +;; Keywords: evil, eshell, tools + +;; This file 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, or (at your +;; option) any later version. +;; +;; This file 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. +;; +;; For a full copy of the GNU General Public License +;; see <http://www.gnu.org/licenses/>. + +;;; Commentary: +;; Evil bindings for Eshell. + +;;; Code: +(require 'em-prompt) +(require 'eshell) +(require 'evil-collection) + +(defconst evil-collection-eshell-maps '(eshell-mode-map)) + +(defun evil-collection-eshell-next-prompt () + "`evil' wrapper around `eshell-next-prompt'." + (when (get-text-property (point) 'read-only) + ;; If at end of prompt, `eshell-next-prompt' will not move, so go backward. + (beginning-of-line) + (eshell-next-prompt 1))) + +(defun evil-collection-eshell-next-prompt-on-insert () + "Go to next prompt on `evil' replace/insert enter." + (dolist (hook '(evil-replace-state-entry-hook evil-insert-state-entry-hook)) + (add-hook hook 'evil-collection-eshell-next-prompt nil t))) + +(defun evil-collection-eshell-interrupt-process () + "Interupt `eshell' process and enter insert state." + (interactive) + (eshell-interrupt-process) + (evil-insert 1)) + +(defun evil-collection-eshell-escape-stay () + "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-local evil-move-cursor-back nil)) + +;; Taken from Doom Emacs +(evil-define-operator evil-collection-eshell-evil-change (beg end type register yank-handler delete-func) + "Like `evil-change' but will not delete/copy the prompt." + (interactive "<R><x><y>") + (save-restriction + (narrow-to-region eshell-last-output-end (point-max)) + (evil-change (max beg (point-min)) + (if (eq type 'line) (point-max) (min (or end (point-max)) (point-max))) + type register yank-handler delete-func))) + +;; Taken from Doom Emacs +(evil-define-operator evil-collection-eshell-evil-change-line (beg end type register yank-handler) + "Change to end of line." + :motion evil-end-of-line + (interactive "<R><x><y>") + (evil-collection-eshell-evil-change beg end type register yank-handler #'evil-delete-line)) + +;; Taken from Doom Emacs +(evil-define-operator evil-collection-eshell-evil-delete (beg end type register yank-handler) + "Like `evil-delete' but will not delete/copy the prompt." + (interactive "<R><x><y>") + (save-restriction + (narrow-to-region eshell-last-output-end (point-max)) + (evil-delete (if beg (max beg (point-min)) (point-min)) + (if (eq type 'line) (point-max) (min (or end (point-max)) (point-max))) + type register yank-handler))) + +;; Taken from Doom Emacs +;; +;; Although the BEG argument doesn't get used in any meaningful way, +;; `evil-define-operator' must access it nonetheless, so putting an underscore +;; in front will make the CI fail. +(evil-define-operator evil-collection-eshell-evil-delete-line (beg end type register yank-handler) + "Change to end of line." + :motion nil + :keep-visual t + (interactive "<R><x>") + (evil-collection-eshell-evil-delete (point) end type register yank-handler)) + +;; `eshell-mode-map' is reset when Eshell is initialized in `eshell-mode'. We +;; need to add bindings to `eshell-first-time-mode-hook'. +(defun evil-collection-eshell-setup-keys () + "Set up `evil' bindings for `eshell'." + (evil-collection-define-key 'normal 'eshell-mode-map + ;; motion + "[[" 'eshell-previous-prompt + "]]" 'eshell-next-prompt + (kbd "C-k") 'eshell-previous-prompt + (kbd "C-j") 'eshell-next-prompt + "gk" 'eshell-previous-prompt + "gj" 'eshell-next-prompt + (kbd "M-h") 'eshell-backward-argument + (kbd "M-l") 'eshell-forward-argument + + (kbd "C-n") 'eshell-next-matching-input-from-input + (kbd "C-p") 'eshell-previous-matching-input-from-input + + (kbd "C-c C-c") 'evil-collection-eshell-interrupt-process + "c" 'evil-collection-eshell-evil-change + "C" 'evil-collection-eshell-evil-change-line + "d" 'evil-collection-eshell-evil-delete + "D" 'evil-collection-eshell-evil-delete-line) + + (let* ((submit evil-collection-repl-submit-state) + (newline-state (if (eq submit 'normal) 'insert 'normal))) + (evil-collection-define-key submit 'eshell-mode-map + (kbd "RET") 'eshell-send-input) + (evil-collection-define-key newline-state 'eshell-mode-map + (kbd "RET") 'newline)) + + (when (< emacs-major-version 30) + (evil-collection-define-key 'normal 'eshell-mode-map + "0" 'eshell-bol + "^" 'eshell-bol)) + + (when evil-want-C-u-delete + (evil-collection-define-key 'insert 'eshell-mode-map + (kbd "C-u") 'eshell-kill-input)) + + (evil-collection-define-key 'visual 'eshell-mode-map + ;; motion + ;; TODO: This does not work with `evil-visual-line'. + "[[" 'eshell-previous-prompt + "]]" 'eshell-next-prompt + (kbd "C-k") 'eshell-previous-prompt + (kbd "C-j") 'eshell-next-prompt + "gk" 'eshell-previous-prompt + "gj" 'eshell-next-prompt) + + (when (< emacs-major-version 30) + (evil-collection-define-key 'visual 'eshell-mode-map + "0" 'eshell-bol + "^" 'eshell-bol)) + + (evil-normalize-keymaps) + (unless evil-collection-always-run-setup-hook-after-load + (run-hook-with-args + 'evil-collection-setup-hook 'eshell evil-collection-eshell-maps))) + +;; TODO: Compare this setup procedure with evil-ediff. +;;;###autoload +(defun evil-collection-eshell-setup () + "Set up `evil' bindings for `eshell'." + (add-hook 'eshell-mode-hook 'evil-collection-eshell-escape-stay) + (add-hook 'eshell-mode-hook 'evil-collection-eshell-next-prompt-on-insert) + (add-hook 'eshell-first-time-mode-hook 'evil-collection-eshell-setup-keys)) + +(provide 'evil-collection-eshell) +;;; evil-collection-eshell.el ends here |
