featurep! will be renamed modulep! in the future, so it's been deprecated. They have identical interfaces, and can be replaced without issue. featurep! was never quite the right name for this macro. It implied that it had some connection to featurep, which it doesn't (only that it was similar in purpose; still, Doom modules are not features). To undo such implications and be consistent with its namespace (and since we're heading into a storm of breaking changes with the v3 release anyway), now was the best opportunity to begin the transition.
205 lines
7.6 KiB
EmacsLisp
205 lines
7.6 KiB
EmacsLisp
;;; term/eshell/config.el -*- lexical-binding: t; -*-
|
|
|
|
;; see:
|
|
;; + `+eshell/here': open eshell in the current window
|
|
;; + `+eshell/toggle': toggles an eshell popup
|
|
;; + `+eshell/frame': converts the current frame into an eshell-dedicated
|
|
;; frame. Once the last eshell process is killed, the old frame configuration
|
|
;; is restored.
|
|
|
|
(defvar +eshell-config-dir
|
|
(expand-file-name "eshell/" doom-private-dir)
|
|
"Where to store eshell configuration files, as opposed to
|
|
`eshell-directory-name', which is where Doom will store temporary/data files.")
|
|
|
|
(defvar eshell-directory-name (concat doom-etc-dir "eshell")
|
|
"Where to store temporary/data files, as opposed to `eshell-config-dir',
|
|
which is where Doom will store eshell configuration files.")
|
|
|
|
(defvar +eshell-enable-new-shell-on-split t
|
|
"If non-nil, spawn a new eshell session after splitting from an eshell
|
|
buffer.")
|
|
|
|
(defvar +eshell-kill-window-on-exit nil
|
|
"If non-nil, eshell will close windows along with its eshell buffers.")
|
|
|
|
(defvar +eshell-aliases
|
|
'(("q" "exit") ; built-in
|
|
("f" "find-file $1")
|
|
("ff" "find-file-other-window $1")
|
|
("d" "dired $1")
|
|
("bd" "eshell-up $1")
|
|
("rg" "rg --color=always $*")
|
|
("l" "ls -lh $*")
|
|
("ll" "ls -lah $*")
|
|
("git" "git --no-pager $*")
|
|
("gg" "magit-status")
|
|
("cdp" "cd-to-project")
|
|
("clear" "clear-scrollback")) ; more sensible than default
|
|
"An alist of default eshell aliases, meant to emulate useful shell utilities,
|
|
like fasd and bd. Note that you may overwrite these in your
|
|
`eshell-aliases-file'. This is here to provide an alternative, elisp-centric way
|
|
to define your aliases.
|
|
|
|
You should use `set-eshell-alias!' to change this.")
|
|
|
|
;; These files are exceptions, because they may contain configuration
|
|
(defvar eshell-aliases-file (concat +eshell-config-dir "aliases"))
|
|
(defvar eshell-rc-script (concat +eshell-config-dir "profile"))
|
|
(defvar eshell-login-script (concat +eshell-config-dir "login"))
|
|
|
|
(defvar +eshell--default-aliases nil)
|
|
|
|
|
|
;;
|
|
;;; Packages
|
|
|
|
(after! eshell ; built-in
|
|
(setq eshell-banner-message
|
|
'(format "%s %s\n"
|
|
(propertize (format " %s " (string-trim (buffer-name)))
|
|
'face 'mode-line-highlight)
|
|
(propertize (current-time-string)
|
|
'face 'font-lock-keyword-face))
|
|
eshell-scroll-to-bottom-on-input 'all
|
|
eshell-scroll-to-bottom-on-output 'all
|
|
eshell-kill-processes-on-exit t
|
|
eshell-hist-ignoredups t
|
|
;; don't record command in history if prefixed with whitespace
|
|
;; TODO Use `eshell-input-filter-initial-space' when Emacs 25 support is dropped
|
|
eshell-input-filter (lambda (input) (not (string-match-p "\\`\\s-+" input)))
|
|
;; em-prompt
|
|
eshell-prompt-regexp "^.* λ "
|
|
eshell-prompt-function #'+eshell-default-prompt-fn
|
|
;; em-glob
|
|
eshell-glob-case-insensitive t
|
|
eshell-error-if-no-glob t)
|
|
|
|
;; Consider eshell buffers real
|
|
(add-hook 'eshell-mode-hook #'doom-mark-buffer-as-real-h)
|
|
|
|
;; Keep track of open eshell buffers
|
|
(add-hook 'eshell-mode-hook #'+eshell-init-h)
|
|
(add-hook 'eshell-exit-hook #'+eshell-cleanup-h)
|
|
|
|
;; Enable autopairing in eshell
|
|
(add-hook 'eshell-mode-hook #'smartparens-mode)
|
|
|
|
;; Persp-mode/workspaces integration
|
|
(when (modulep! :ui workspaces)
|
|
(add-hook 'persp-activated-functions #'+eshell-switch-workspace-fn)
|
|
(add-hook 'persp-before-switch-functions #'+eshell-save-workspace-fn))
|
|
|
|
;; UI enhancements
|
|
(add-hook! 'eshell-mode-hook
|
|
(defun +eshell-remove-fringes-h ()
|
|
(set-window-fringes nil 0 0)
|
|
(set-window-margins nil 1 nil))
|
|
(defun +eshell-enable-text-wrapping-h ()
|
|
(visual-line-mode +1)
|
|
(set-display-table-slot standard-display-table 0 ?\ )))
|
|
|
|
(add-hook 'eshell-mode-hook #'hide-mode-line-mode)
|
|
|
|
;; Remove hscroll-margin in shells, otherwise you get jumpiness when the
|
|
;; cursor comes close to the left/right edges of the window.
|
|
(setq-hook! 'eshell-mode-hook hscroll-margin 0)
|
|
|
|
;; Don't auto-write our aliases! Let us manage our own `eshell-aliases-file'
|
|
;; or configure `+eshell-aliases' via elisp.
|
|
(advice-add #'eshell-write-aliases-list :override #'ignore)
|
|
|
|
;; REVIEW In Emacs 27 and newer, waiting for esh-module is unnecessary.
|
|
(after! esh-module
|
|
(add-to-list 'eshell-modules-list 'eshell-tramp))
|
|
|
|
;; Visual commands require a proper terminal. Eshell can't handle that, so
|
|
;; it delegates these commands to a term buffer.
|
|
(after! em-term
|
|
(pushnew! eshell-visual-commands "tmux" "htop" "vim" "nvim" "ncmpcpp"))
|
|
|
|
(after! em-alias
|
|
(setq +eshell--default-aliases eshell-command-aliases-list
|
|
eshell-command-aliases-list
|
|
(append eshell-command-aliases-list
|
|
+eshell-aliases))))
|
|
|
|
|
|
(after! esh-mode
|
|
(map! :map eshell-mode-map
|
|
:n "RET" #'+eshell/goto-end-of-prompt
|
|
:n [return] #'+eshell/goto-end-of-prompt
|
|
:ni "C-j" #'eshell-next-matching-input-from-input
|
|
:ni "C-k" #'eshell-previous-matching-input-from-input
|
|
:ig "C-d" #'+eshell/quit-or-delete-char
|
|
:i "C-c h" #'evil-window-left
|
|
:i "C-c j" #'evil-window-down
|
|
:i "C-c k" #'evil-window-up
|
|
:i "C-c l" #'evil-window-right
|
|
"C-s" #'+eshell/search-history
|
|
;; Emacs bindings
|
|
"C-e" #'end-of-line
|
|
;; Tmux-esque prefix keybinds
|
|
"C-c s" #'+eshell/split-below
|
|
"C-c v" #'+eshell/split-right
|
|
"C-c x" #'+eshell/kill-and-close
|
|
[remap split-window-below] #'+eshell/split-below
|
|
[remap split-window-right] #'+eshell/split-right
|
|
[remap doom/backward-to-bol-or-indent] #'eshell-bol
|
|
[remap doom/backward-kill-to-bol-and-indent] #'eshell-kill-input
|
|
[remap evil-delete-back-to-indentation] #'eshell-kill-input
|
|
[remap evil-window-split] #'+eshell/split-below
|
|
[remap evil-window-vsplit] #'+eshell/split-right
|
|
;; To emulate terminal keybinds
|
|
"C-l" (cmd! (eshell/clear-scrollback) (eshell-emit-prompt))
|
|
(:localleader
|
|
"b" #'eshell-insert-buffer-name
|
|
"e" #'eshell-insert-envvar
|
|
"s" #'+eshell/search-history)))
|
|
|
|
|
|
(use-package! eshell-up
|
|
:commands eshell-up eshell-up-peek)
|
|
|
|
|
|
(use-package! eshell-z
|
|
:after eshell
|
|
:config
|
|
;; Use zsh's db if it exists, otherwise, store it in `doom-cache-dir'
|
|
(unless (file-exists-p eshell-z-freq-dir-hash-table-file-name)
|
|
(setq eshell-z-freq-dir-hash-table-file-name
|
|
(expand-file-name "z" eshell-directory-name))))
|
|
|
|
|
|
(use-package! esh-help
|
|
:after eshell
|
|
:config (setup-esh-help-eldoc))
|
|
|
|
|
|
(use-package! eshell-did-you-mean
|
|
:after esh-mode ; Specifically esh-mode, not eshell
|
|
:config
|
|
(eshell-did-you-mean-setup)
|
|
;; HACK There is a known issue with `eshell-did-you-mean' where it does not
|
|
;; work on first invocation, so we invoke it once manually by setting the
|
|
;; last command and then calling the output filter.
|
|
(setq eshell-last-command-name "catt")
|
|
(eshell-did-you-mean-output-filter "catt: command not found"))
|
|
|
|
|
|
(use-package eshell-syntax-highlighting
|
|
:hook (eshell-mode . eshell-syntax-highlighting-mode))
|
|
|
|
|
|
(use-package! fish-completion
|
|
:unless IS-WINDOWS
|
|
:hook (eshell-mode . fish-completion-mode)
|
|
:init (setq fish-completion-fallback-on-bash-p t)
|
|
:config
|
|
;; HACK Even with `fish-completion-fallback-on-bash-p' non-nil,
|
|
;; `fish-completion--list-completions-with-desc' will throw an error if
|
|
;; fish isn't installed (and so, will fail to fall back to bash), so we
|
|
;; advise it to fail silently.
|
|
(defadvice! +eshell--fallback-to-bash-a (&rest _)
|
|
:before-until #'fish-completion--list-completions-with-desc
|
|
(unless (executable-find "fish") "")))
|