From 38a5e73e2ef384b9febd3ad923450ab6dcd094cb Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 23 Mar 2018 18:17:59 -0400 Subject: [PATCH] tools/eshell: major refactor & update --- modules/tools/eshell/autoload/eshell.el | 68 +++---------------------- modules/tools/eshell/autoload/evil.el | 39 ++++++++++++++ modules/tools/eshell/config.el | 57 +++++++++------------ 3 files changed, 69 insertions(+), 95 deletions(-) diff --git a/modules/tools/eshell/autoload/eshell.el b/modules/tools/eshell/autoload/eshell.el index 2b2fa81df..2cfe67e5a 100644 --- a/modules/tools/eshell/autoload/eshell.el +++ b/modules/tools/eshell/autoload/eshell.el @@ -85,16 +85,13 @@ module to be loaded." (eshell-life-is-too-much) (delete-char arg))) -(defun +eshell--outside-prompt-p () - (< (point) eshell-last-output-end)) - (defun +eshell--current-git-branch () - (let ((branch (car (loop for match in (split-string (shell-command-to-string "git branch") "\n") - when (string-match "^\*" match) - collect match)))) - (if (not (eq branch nil)) - (concat " [" (substring branch 2) "]") - ""))) + (let ((branch (car (cl-loop for match in (split-string (shell-command-to-string "git branch") "\n") + if (string-match-p "^\*" match) + collect match)))) + (if (not (eq branch nil)) + (concat " [" (substring branch 2) "]") + ""))) ;;;###autoload (defun +eshell/split () @@ -114,56 +111,3 @@ module to be loaded." (propertize (+eshell--current-git-branch) 'face 'font-lock-function-name-face) (propertize " λ " 'face 'font-lock-constant-face))) -;;;###autoload -(defun +eshell/evil-append () - (interactive) - (goto-char eshell-last-output-end) - (call-interactively #'evil-append-line)) - -;;;###autoload -(defun +eshell/evil-append-maybe () - (interactive) - (if (+eshell--outside-prompt-p) - (+eshell/evil-append) - (call-interactively #'evil-append))) - -;;;###autoload -(defun +eshell/evil-prepend () - (interactive) - (goto-char eshell-last-output-end) - (call-interactively #'evil-insert)) - -;;;###autoload -(defun +eshell/evil-prepend-maybe () - (interactive) - (if (+eshell--outside-prompt-p) - (+eshell/evil-prepend) - (call-interactively #'evil-insert))) - -;;;###autoload -(defun +eshell/evil-replace-maybe () - (interactive) - (if (+eshell--outside-prompt-p) - (user-error "Cannot edit read-only region") - (call-interactively #'evil-replace))) - -;;;###autoload -(defun +eshell/evil-replace-state-maybe () - (interactive) - (if (+eshell--outside-prompt-p) - (user-error "Cannot edit read-only region") - (call-interactively #'evil-replace-state))) - -;;;###autoload -(defun +eshell/evil-change () - (interactive) - (when (+eshell--outside-prompt-p) - (goto-char eshell-last-output-end)) - (call-interactively #'evil-change)) - -;;;###autoload -(defun +eshell/evil-change-line () - (interactive) - (when (+eshell--outside-prompt-p) - (goto-char eshell-last-output-end)) - (call-interactively #'evil-change-line)) diff --git a/modules/tools/eshell/autoload/evil.el b/modules/tools/eshell/autoload/evil.el index 0f8d18316..7a0070264 100644 --- a/modules/tools/eshell/autoload/evil.el +++ b/modules/tools/eshell/autoload/evil.el @@ -9,3 +9,42 @@ (+eshell/open command) (+eshell/open-popup command))) +;;;###autoload (autoload '+eshell/evil-change "tools/eshell/autoload/evil" nil t) +(evil-define-operator +eshell/evil-change (beg end type register yank-handler delete-func) + "Like `evil-change' but will not delete/copy the prompt." + (interactive "") + (let ((delete-func (or delete-func #'evil-delete)) + (nlines (1+ (evil-count-lines beg end))) + (opoint (save-excursion + (goto-char beg) + (evil-collection-eshell-next-prompt) + (point)))) + (unless (eq evil-want-fine-undo t) + (evil-start-undo-step)) + (when (get-text-property beg 'read-only) + (save-excursion + (goto-char beg) + (evil-collection-eshell-next-prompt) + (setq beg (point)))) + (funcall delete-func beg end type register yank-handler) + (cond + ((eq type 'line) + (goto-char eshell-last-output-end) + (when (get-text-property (point) 'read-only) + (evil-collection-eshell-next-prompt)) + (evil-append 1)) + ((eq type 'block) (evil-insert 1 nlines)) + (t + (evil-insert 1))))) + +;;;###autoload (autoload '+eshell/evil-change-line "tools/eshell/autoload/evil" nil t) +(evil-define-operator +eshell/evil-change-line (beg end type register yank-handler) + "Change to end of line." + :motion evil-end-of-line + (interactive "") + (when (get-text-property beg 'read-only) + (save-excursion + (goto-char beg) + (evil-collection-eshell-next-prompt) + (setq beg (point)))) + (evil-change beg end type register yank-handler #'evil-delete-line)) diff --git a/modules/tools/eshell/config.el b/modules/tools/eshell/config.el index 8e34c8a50..529e29317 100644 --- a/modules/tools/eshell/config.el +++ b/modules/tools/eshell/config.el @@ -12,65 +12,56 @@ :commands eshell-mode :init (setq eshell-directory-name (concat doom-etc-dir "/eshell") + eshell-rc-script "~/.eshellrc" + eshell-aliases-file "~/.eshell_aliases" + ;; eshell-scroll-to-bottom-on-input 'all eshell-scroll-to-bottom-on-output 'all eshell-buffer-shorthand t eshell-kill-processes-on-exit t + eshell-error-if-no-glob t + eshell-hist-ignoredups t ;; em-prompt eshell-prompt-regexp "^.* λ " eshell-prompt-function #'+eshell-prompt ;; em-glob eshell-glob-case-insensitive t - eshell-error-if-no-glob t - ;; em-alias - eshell-aliases-file (concat doom-local-dir ".eshell-aliases")) + eshell-error-if-no-glob t) :config - (set! :evil-state 'eshell-mode 'insert) - ;; Keep track of open eshell buffers (add-hook 'eshell-mode-hook #'+eshell|init) (add-hook 'eshell-exit-hook #'+eshell|cleanup) + (after! em-alias + (setq eshell-command-aliases-list + (append eshell-command-aliases-list + '(("q" "exit") + ("l" "ls -1") + ("ll" "ls -l") + ("la" "ls -la") + ("g" "hub") + ("gs" "hub status --short ."))))) + (after! em-term ;; Visual commands require a proper terminal. Eshell can't handle that, so it ;; delegates these commands to a term buffer. - (nconc eshell-visual-commands '("tmux" "htop" "bash" "zsh" "fish" "vim" "nvim")) - (setq eshell-visual-subcommands '(("git" "log" "l" "diff" "show")))) + (setq eshell-visual-commands + (append eshell-visual-commands '("tmux" "htop" "bash" "zsh" "fish" "vim" "nvim")) + eshell-visual-subcommands '(("git" "log" "l" "diff" "show")))) (defun +eshell|init-keymap () "Setup eshell keybindings. This must be done in a hook because eshell-mode redefines its keys every time `eshell-mode' is enabled." (map! :map eshell-mode-map - :n "i" #'+eshell/evil-prepend-maybe - :n "I" #'+eshell/evil-prepend - :n "a" #'+eshell/evil-append-maybe - :n "A" #'+eshell/evil-append - :n "r" #'+eshell/evil-replace-maybe - :n "R" #'+eshell/evil-replace-state-maybe :n "c" #'+eshell/evil-change :n "C" #'+eshell/evil-change-line - :i [tab] #'eshell-pcomplete - :i "SPC" #'self-insert-command - :i "C-u" #'eshell-kill-input - :i "C-a" #'eshell-bol :i "C-d" #'+eshell/quit-or-delete-char - :i "C-k" #'kill-line :i "C-p" #'eshell-previous-input - :i "" #'eshell-previous-input :i "C-n" #'eshell-next-input - :i "" #'eshell-next-input - :m "" #'+eshell/evil-append - :n [remap evil-record-macro] #'eshell-life-is-too-much - [remap kill-this-buffer] #'eshell-life-is-too-much)) - (add-hook 'eshell-mode-hook #'+eshell|init-keymap) - - ;; Aliases - (setq eshell-command-aliases-list - '(("q" "exit") - ("l" "ls -1") - ("ll" "ls -l") - ("la" "ls -la") - ("g" "hub") - ("gs" "hub status --short .")))) + [remap doom/backward-to-bol-or-indent] #'eshell-bol + [remap doom/backward-kill-to-bol-and-indent] #'eshell-kill-input + [remap evil-window-split] #'+eshell/split + [remap evil-window-vsplit] #'+eshell/vsplit)) + (add-hook 'eshell-first-time-mode-hook #'+eshell|init-keymap))