diff --git a/modules/defuns/defuns-eshell.el b/modules/defuns/defuns-eshell.el index 1e27ae56a..eca96d3ae 100644 --- a/modules/defuns/defuns-eshell.el +++ b/modules/defuns/defuns-eshell.el @@ -2,8 +2,12 @@ (require 'eshell) -(defun doom--eshell-in-prompt-p (&optional offset) - (>= (- (point) (or offset 0)) (save-excursion (eshell-bol) (point)))) +(defvar doom-eshell-buffers '() "") +(defvar doom-eshell-height 16 "") +(defvar-local doom-eshell-direction nil "") + +(defun doom--eshell-outside-prompt-p (&optional offset) + (< (point) eshell-last-output-end)) (defun doom--eshell-current-git-branch () (let ((branch (car (loop for match in (split-string (shell-command-to-string "git branch") "\n") @@ -13,61 +17,88 @@ (concat " [" (substring branch 2) "]") ""))) +;;;###autoload +(defun doom/eshell-split () + (interactive) + (select-window (split-window-vertically doom-eshell-height)) + (setq-local doom-eshell-direction 'below) + (doom--eshell-init t)) + +;;;###autoload +(defun doom/eshell-vsplit () + (interactive) + (select-window (split-window-horizontally)) + (setq-local doom-eshell-direction 'right) + (doom--eshell-init t)) + ;;;###autoload (defun doom/eshell (&optional same &rest _) (interactive) - (let ((buf (get-buffer-create eshell-buffer-name))) - (cl-assert (and buf (buffer-live-p buf))) - (doom/popup-buffer buf) - (with-current-buffer buf - (unless (derived-mode-p 'eshell-mode) - (eshell-mode))))) + (doom--eshell-init same) + ;; (if doom-eshell-buffers + ;; (let* ((buf (car (reverse doom-eshell-buffers))) + ;; (win (get-buffer-window buf))) + ;; (if (and win (window-live-p win)) + ;; (select-window win) + ;; (select-window (split-window-vertically doom-eshell-height)) + ;; (evil-window-move-very-bottom) + ;; (switch-to-buffer buf t t))) + ;; (doom--eshell-init same)) + ) + +(defun doom--eshell-init (&optional same) + (unless same (select-window (split-window))) + (eshell (max 0 (1- (length doom-eshell-buffers)))) + (unless same + (evil-window-move-very-bottom) + (evil-window-set-height doom-eshell-height)) + (set-window-dedicated-p (selected-window) t)) ;;;###autoload (defun doom/eshell-prompt () (concat (propertize (abbreviate-file-name (eshell/pwd)) 'face 'eshell-prompt) (propertize (doom--eshell-current-git-branch) 'face 'font-lock-function-name-face) - (propertize " $ " 'face 'font-lock-constant-face))) + (propertize " λ " 'face 'font-lock-constant-face))) ;;;###autoload (defun doom/eshell-evil-append () (interactive) - (goto-char (point-max)) - (call-interactively 'evil-append)) + (goto-char eshell-last-output-end) + (call-interactively 'evil-append-line)) ;;;###autoload (defun doom/eshell-evil-append-maybe () (interactive) - (if (doom--eshell-in-prompt-p) - (call-interactively 'evil-insert) - (doom/eshell-append))) + (if (doom--eshell-outside-prompt-p) + (doom/eshell-evil-append) + (call-interactively 'evil-append))) ;;;###autoload (defun doom/eshell-evil-prepend () (interactive) - (eshell-bol) + (goto-char eshell-last-output-end) (call-interactively 'evil-insert)) ;;;###autoload (defun doom/eshell-evil-prepend-maybe () (interactive) - (if (doom--eshell-in-prompt-p) - (call-interactively 'evil-insert) - (doom/eshell-prepend))) + (if (doom--eshell-outside-prompt-p) + (doom/eshell-evil-prepend) + (call-interactively 'evil-insert))) ;;;###autoload (defun doom/eshell-evil-replace-maybe () (interactive) - (if (doom--eshell-in-prompt-p) - (call-interactively 'evil-replace) - (user-error "Cannot edit read-only region"))) + (if (doom--eshell-outside-prompt-p) + (user-error "Cannot edit read-only region") + (call-interactively 'evil-replace))) ;;;###autoload (defun doom/eshell-evil-replace-state-maybe () (interactive) - (if (doom--eshell-in-prompt-p) - (call-interactively 'evil-replace-state) - (user-error "Cannot edit read-only region"))) + (if (doom--eshell-outside-prompt-p) + (user-error "Cannot edit read-only region") + (call-interactively 'evil-replace-state))) (provide 'defuns-eshell) ;;; defuns-eshell.el ends here diff --git a/modules/module-eshell.el b/modules/module-eshell.el index a289e5924..3d045ad04 100644 --- a/modules/module-eshell.el +++ b/modules/module-eshell.el @@ -1,37 +1,52 @@ ;;; module-eshell.el --- -*- no-byte-compile: t; -*- (use-package eshell - :when IS-WINDOWS :init - (evil-set-initial-state 'eshell-mode 'emacs) (setq eshell-directory-name (concat doom-temp-dir "/eshell") eshell-scroll-to-bottom-on-input 'all + eshell-scroll-to-bottom-on-output 'all eshell-buffer-shorthand t + ;; em-prompt + eshell-prompt-function 'doom/eshell-prompt ;; em-glob eshell-glob-case-insensitive t eshell-error-if-no-glob t - eshell-where-to-jump 'end ;; em-alias eshell-aliases-file (concat doom-temp-dir "/.eshell-aliases")) :config - (def-popup! eshell-mode :frame t :select t) + (evil-set-initial-state 'eshell-mode 'insert) - ;; plan 9 smart shell - (require 'em-smart) - (push 'eshell-smart eshell-modules-list) - (setq eshell-where-to-jump 'begin) - (setq eshell-review-quick-commands nil) - (setq eshell-smart-space-goes-to-end t) - ;; em-prompt - (setq eshell-prompt-function 'doom/eshell-prompt) - (map! :map eshell-mode-map - :n "i" 'doom/eshell-evil-prepend-maybe - :n "I" 'doom/eshell-evil-prepend - :n "a" 'doom/eshell-evil-append-maybe - :n "A" 'doom/eshell-evil-append - :n "r" 'doom/eshell-evil-replace-maybe - :n "R" 'doom/eshell-evil-replace-state-maybe)) + (defun doom|eshell-keymap-setup () + (map! :map eshell-mode-map + :n "i" 'doom/eshell-evil-prepend-maybe + :n "I" 'doom/eshell-evil-prepend + :n "a" 'doom/eshell-evil-append-maybe + :n "A" 'doom/eshell-evil-append + :n "r" 'doom/eshell-evil-replace-maybe + :n "R" 'doom/eshell-evil-replace-state-maybe + :i "C-u" 'eshell-kill-input + :i "SPC" 'self-insert-command + :m "" 'doom/eshell-evil-append + :n [remap doom/evil-window-split] 'doom/eshell-split + :n [remap doom/evil-window-vsplit] 'doom/eshell-vsplit)) + + (defun doom|eshell-init () + (when (eq major-mode 'eshell-mode) + (add-to-list 'doom-eshell-buffers (current-buffer)))) + + (defun doom|eshell-cleanup () + (when (eq major-mode 'eshell-mode) + (setq doom-eshell-buffers (delete (current-buffer) doom-eshell-buffers)) + (delete-window))) + + ;; Close window on exit + (add-hook 'eshell-exit-hook 'doom|eshell-cleanup) + (add-hook 'eshell-mode-hook 'doom|eshell-init) + + (add-hook 'eshell-mode-hook 'doom|eshell-keymap-setup) + (add-hook 'eshell-mode-hook 'doom-hide-mode-line-mode) + (add-hook 'eshell-mode-hook 'hl-line-mode)) (provide 'module-eshell) ;;; module-eshell.el ends here