Files
sydnix/users/crumb/programs/emacs/modules/syd-eshell.el
2025-02-11 11:36:55 -07:00

119 lines
3.9 KiB
EmacsLisp

;;; syd-eshell.el -*- lexical-binding: t; -*-
(require 'ring)
(require 'cl-lib)
(defvar eshell-buffer-name "*eshell*")
(defvar syd-eshell-buffers (make-ring 25)
"List of open eshell buffers.")
(defun syd-eshell-buffers ()
"TODO"
(ring-elements syd-eshell-buffers))
;;;###autoload
(defun syd-eshell-run-command (command &optional buffer)
"TODO"
(let ((buffer
(or buffer
(if (eq major-mode 'eshell-mode)
(current-buffer)
(cl-find-if #'buffer-live-p (syd-eshell-buffers))))))
(unless buffer
(user-error "No living eshell buffers available"))
(unless (buffer-live-p buffer)
(user-error "Cannot operate on a dead buffer"))
(with-current-buffer buffer
(goto-char eshell-last-output-end)
(goto-char (line-end-position))
(insert command)
(eshell-send-input nil t))))
;;;###autoload
(defun syd-eshell/toggle (arg &optional command)
"Toggle eshell popup window."
(interactive "P")
(let ((eshell-buffer
(get-buffer-create
(format "*eshell-popup:%s*"
(if (bound-and-true-p persp-mode)
(safe-persp-name (get-current-persp))
"main"))))
confirm-kill-processes
current-prefix-arg)
(when arg
(when-let* ((win (get-buffer-window eshell-buffer)))
(delete-window win))
(when (buffer-live-p eshell-buffer)
(with-current-buffer eshell-buffer
(fundamental-mode)
(erase-buffer))))
(if-let* ((win (get-buffer-window eshell-buffer)))
(let (confirm-kill-processes)
(delete-window win)
(ignore-errors (kill-buffer eshell-buffer)))
(with-current-buffer eshell-buffer
(syd-mark-buffer-as-real)
(if (eq major-mode 'eshell-mode)
(run-hooks 'eshell-mode-hook)
(eshell-mode))
(when command
(syd-eshell-run-command command eshell-buffer)))
(pop-to-buffer eshell-buffer))))
(use-package eshell
:custom
((eshell-banner-message
'(format "🦌 %s %s }:3\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)
(eshell-glob-case-insensitive t)
(eshell-error-if-no-glob t)
(eshell-history-file-name (file-name-concat
syd-data-dir "eshell" "history"))
(eshell-last-dir-ring-file-name (file-name-concat
syd-data-dir "eshell" "lastdir")))
:general
(:keymaps 'syd-leader-open-map
"e" #'syd-eshell/toggle)
(:keymaps 'eshell-mode-map
:states '(normal insert)
"C-j" #'eshell-next-matching-input-from-input
"C-k" #'eshell-previous-matching-input-from-input)
:config
(require 'syd-buffers)
(add-hook 'eshell-mode-hook #'syd-mark-buffer-as-real)
;; UI enhancements.
(defun syd-eshell-remove-fringes-h ()
(set-window-fringes nil 0 0)
(set-window-margins nil 1 nil))
(defun syd-eshell-enable-text-wrapping-h ()
(visual-line-mode +1)
(set-display-table-slot standard-display-table 0 ?\ ))
(add-hook 'eshell-mode-hook #'syd-eshell-remove-fringes-h)
(add-hook 'eshell-mode-hook #'syd-eshell-enable-text-wrapping-h)
(with-eval-after-load 'hide-mode-line
(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.
(defun syd-eshell-disable-hscroll-margin ()
(setq hscroll-margin 0))
(add-hook 'eshell-mode-hook #'syd-eshell-disable-hscroll-margin))
(set-popup-rule! "^\\*eshell-popup"
:vslot -5 :size 0.35 :select t :modeline nil :quit nil :ttl nil)
(provide 'syd-eshell)