2026-03-22 23:57:48 +11:00
|
|
|
;; -*- lexical-binding: t; -*-
|
|
|
|
|
|
|
|
|
|
(use-package shell
|
2026-03-30 11:49:18 +11:00
|
|
|
:straight nil
|
2026-03-30 16:37:02 +11:00
|
|
|
:hook ((comint-output-filter-functions . comint-strip-ctrl-m))
|
2026-03-22 23:57:48 +11:00
|
|
|
:init
|
2026-03-30 16:37:02 +11:00
|
|
|
(setq system-uses-terminfo nil))
|
|
|
|
|
|
|
|
|
|
;; Emacs command shell
|
|
|
|
|
(use-package eshell
|
|
|
|
|
:ensure nil
|
|
|
|
|
:defines eshell-prompt-function
|
|
|
|
|
:bind (:map eshell-mode-map
|
|
|
|
|
([remap recenter-top-bottom] . eshell/clear))
|
|
|
|
|
:config
|
2026-03-22 23:57:48 +11:00
|
|
|
(with-no-warnings
|
2026-03-30 16:37:02 +11:00
|
|
|
(defun eshell/clear ()
|
|
|
|
|
"Clear the eshell buffer."
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(eshell-send-input)))
|
|
|
|
|
(defun eshell/emacs (&rest args)
|
|
|
|
|
"Open a file (ARGS) in Emacs. Some habits die hard."
|
|
|
|
|
(if (null args)
|
|
|
|
|
;; If I just ran "emacs", I probably expect to be launching
|
|
|
|
|
;; Emacs, which is rather silly since I'm already in Emacs.
|
|
|
|
|
;; So just pretend to do what I ask.
|
|
|
|
|
(bury-buffer)
|
|
|
|
|
;; We have to expand the file names or else naming a directory in an
|
|
|
|
|
;; argument causes later arguments to be looked for in that directory,
|
|
|
|
|
;; not the starting directory
|
|
|
|
|
(mapc #'find-file (mapcar #'expand-file-name (flatten-tree (reverse args))))))
|
|
|
|
|
(defalias 'eshell/e #'eshell/emacs)
|
|
|
|
|
(defalias 'eshell/ec #'eshell/emacs)
|
|
|
|
|
(defun eshell/ebc (&rest args)
|
|
|
|
|
"Compile a file (ARGS) in Emacs. Use `compile' to do background make."
|
|
|
|
|
(if (eshell-interactive-output-p)
|
|
|
|
|
(let ((compilation-process-setup-function
|
|
|
|
|
(list 'lambda nil
|
|
|
|
|
(list 'setq 'process-environment
|
|
|
|
|
(list 'quote (eshell-copy-environment))))))
|
|
|
|
|
(compile (eshell-flatten-and-stringify args))
|
|
|
|
|
(pop-to-buffer compilation-last-buffer))
|
|
|
|
|
(throw 'eshell-replace-command
|
|
|
|
|
(let ((l (eshell-stringify-list (flatten-tree args))))
|
|
|
|
|
(eshell-parse-command (car l) (cdr l))))))
|
|
|
|
|
(put 'eshell/ebc 'eshell-no-numeric-conversions t)
|
|
|
|
|
(defun eshell-view-file (file)
|
|
|
|
|
"View FILE. A version of `view-file' which properly rets the eshell prompt."
|
|
|
|
|
(interactive "fView file: ")
|
|
|
|
|
(unless (file-exists-p file) (error "%s does not exist" file))
|
|
|
|
|
(let ((buffer (find-file-noselect file)))
|
|
|
|
|
(if (eq (get (buffer-local-value 'major-mode buffer) 'mode-class)
|
|
|
|
|
'special)
|
|
|
|
|
(progn
|
|
|
|
|
(switch-to-buffer buffer)
|
|
|
|
|
(message "Not using View mode because the major mode is special"))
|
|
|
|
|
(let ((undo-window (list (window-buffer) (window-start)
|
|
|
|
|
(+ (window-point)
|
|
|
|
|
(length (funcall eshell-prompt-function))))))
|
|
|
|
|
(switch-to-buffer buffer)
|
|
|
|
|
(view-mode-enter (cons (selected-window) (cons nil undo-window))
|
|
|
|
|
'kill-buffer)))))
|
|
|
|
|
|
|
|
|
|
(defun eshell/less (&rest args)
|
|
|
|
|
"Invoke `view-file' on a file (ARGS).
|
|
|
|
|
|
|
|
|
|
\"less +42 foo\" will go to line 42 in the buffer for foo."
|
|
|
|
|
(while args
|
|
|
|
|
(if (string-match "\\`\\+\\([0-9]+\\)\\'" (car args))
|
|
|
|
|
(let* ((line (string-to-number (match-string 1 (pop args))))
|
|
|
|
|
(file (pop args)))
|
|
|
|
|
(eshell-view-file file)
|
|
|
|
|
(forward-line line))
|
|
|
|
|
(eshell-view-file (pop args)))))
|
|
|
|
|
(defalias 'eshell/more #'eshell/less)))
|
2026-03-22 23:57:48 +11:00
|
|
|
|
|
|
|
|
(use-package xterm-color
|
|
|
|
|
:defines (compilation-environment
|
|
|
|
|
eshell-preoutput-filter-functions
|
|
|
|
|
eshell-output-filter-functions)
|
|
|
|
|
:init
|
|
|
|
|
;; For shell and interpreters
|
|
|
|
|
(setenv "TERM" "xterm-256color")
|
|
|
|
|
|
2026-03-30 16:37:02 +11:00
|
|
|
(setq comint-output-filter-functions
|
|
|
|
|
(remove 'ansi-color-process-output comint-output-filter-functions))
|
|
|
|
|
(add-hook 'comint-preoutput-filter-functions 'xterm-color-filter)
|
|
|
|
|
(add-hook 'shell-mode-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
;; Disable font-locking to improve performance
|
|
|
|
|
(font-lock-mode -1)
|
|
|
|
|
;; Prevent font-locking from being re-enabled
|
|
|
|
|
(make-local-variable 'font-lock-function)
|
|
|
|
|
(setq font-lock-function #'ignore)))
|
|
|
|
|
|
|
|
|
|
;; For eshell
|
2026-03-22 23:57:48 +11:00
|
|
|
(with-eval-after-load 'esh-mode
|
|
|
|
|
(add-hook 'eshell-before-prompt-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(setq xterm-color-preserve-properties t)))
|
|
|
|
|
(add-to-list 'eshell-preoutput-filter-functions 'xterm-color-filter)
|
|
|
|
|
(setq eshell-output-filter-functions
|
|
|
|
|
(remove 'eshell-handle-ansi-color eshell-output-filter-functions)))
|
2026-03-30 16:37:02 +11:00
|
|
|
|
2026-03-22 23:57:48 +11:00
|
|
|
(setq compilation-environment '("TERM=xterm-256color"))
|
2026-03-30 16:37:02 +11:00
|
|
|
(defun my/advice-compilation-filter (fn proc string)
|
|
|
|
|
(funcall fn proc
|
|
|
|
|
(if (eq major-mode 'rg-mode) ; compatible with `rg'
|
|
|
|
|
string
|
|
|
|
|
(xterm-color-filter string))))
|
|
|
|
|
(advice-add 'compilation-filter :around #'my/advice-compilation-filter)
|
|
|
|
|
(advice-add 'gud-filter :around #'my/advice-compilation-filter)
|
2026-03-22 23:57:48 +11:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
(setq eshell-banner-message "")
|
|
|
|
|
|
|
|
|
|
(use-package eat
|
2026-03-30 16:37:02 +11:00
|
|
|
:bind ("C-`" . eat-toggle)
|
|
|
|
|
:bind ("C-<escape>" . eshell-toggle)
|
2026-03-22 23:57:48 +11:00
|
|
|
:hook ((eshell-load . eat-eshell-mode)
|
|
|
|
|
(eshell-load . eat-eshell-visual-command-mode))
|
2026-03-29 19:12:45 +11:00
|
|
|
:straight `(eat :repo "https://codeberg.org/akib/emacs-eat"
|
|
|
|
|
:files ("*.el" ("term" "term/*.el") "*.texi"
|
|
|
|
|
"*.ti" ("terminfo/e" "terminfo/e/*")
|
|
|
|
|
("terminfo/65" "terminfo/65/*")
|
|
|
|
|
("integration" "integration/*")
|
|
|
|
|
(:exclude ".dir-locals.el" "*-tests.el")))
|
2026-03-22 23:57:48 +11:00
|
|
|
:custom
|
|
|
|
|
(eat-term-name "xterm-256color")
|
|
|
|
|
(eat-kill-buffer-on-exit t)
|
|
|
|
|
;; (eat-shell )
|
|
|
|
|
:config
|
2026-03-29 19:12:45 +11:00
|
|
|
(defun eshell-toggle () (interactive)
|
|
|
|
|
(if (string= (buffer-name) "*eshell*")
|
|
|
|
|
(delete-window)
|
|
|
|
|
(eshell)))
|
2026-03-22 23:57:48 +11:00
|
|
|
(defun eat-toggle () (interactive)
|
2026-03-29 19:12:45 +11:00
|
|
|
(if (string= (buffer-name) "*eat*")
|
|
|
|
|
(delete-window)
|
|
|
|
|
(eat)))
|
|
|
|
|
|
|
|
|
|
;; Improve latency
|
|
|
|
|
(setq process-adaptive-read-buffering t)
|
2026-03-22 23:57:48 +11:00
|
|
|
|
|
|
|
|
(setq tramp-remote-process-environment '("TERM=xterm-256color" "TERMINFO=''" "ENV=''" "TMOUT=0" "LC_CTYPE=''" "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat" "autocorrect=" "correct="))
|
|
|
|
|
(when (eq system-type 'darwin)
|
|
|
|
|
(define-key eat-semi-char-mode-map (kbd "C-h") #'eat-self-input)
|
|
|
|
|
(define-key eat-semi-char-mode-map (kbd "<backspace>") (kbd "C-h"))))
|
|
|
|
|
|
|
|
|
|
(use-package eshell-prompt-extras
|
|
|
|
|
:after esh-opt
|
|
|
|
|
:defines eshell-highlight-prompt
|
|
|
|
|
:autoload (epe-theme-lambda epe-theme-dakrone epe-theme-pipeline)
|
|
|
|
|
:init
|
2026-03-30 16:37:02 +11:00
|
|
|
(setq eshell-highlight-prompt t)
|
|
|
|
|
(setq eshell-prompt-function #'epe-theme-lambda))
|
2026-03-22 23:57:48 +11:00
|
|
|
|
|
|
|
|
;; (use-package eshell-z
|
|
|
|
|
;; :hook (eshell-mode . (lambda () (require 'eshell-z))))
|
|
|
|
|
|
|
|
|
|
;; (use-package esh-help
|
|
|
|
|
;; :commands setup-esh-help-eldoc
|
|
|
|
|
;; :init (setup-esh-help-eldoc))
|
|
|
|
|
|
|
|
|
|
(use-package eshell-syntax-highlighting
|
|
|
|
|
:after eshell-mode
|
2026-03-29 19:12:45 +11:00
|
|
|
:hook (after-init . eshell-syntax-highlighting-global-mode))
|
2026-03-22 23:57:48 +11:00
|
|
|
|
|
|
|
|
|
|
|
|
|
(provide 'init-shell)
|