shell: Add support for global, filtered history.

master
Pierre Neidhardt 2020-07-09 12:14:13 +02:00
parent ed1ad20c1a
commit f8552950b2
1 changed files with 42 additions and 4 deletions

View File

@ -1,13 +1,51 @@
(setq helm-ff-preferred-shell-mode 'shell-mode)
;;; Shared global history.
(defvar ambrevar/shell-history-global-ring nil
"The history ring shared across shell sessions.")
(defun ambrevar/shell-use-global-history ()
"Make shell history shared across different sessions."
(unless ambrevar/shell-history-global-ring
(when comint-input-ring-file-name
(comint-read-input-ring))
(setq ambrevar/shell-history-global-ring (or comint-input-ring (make-ring comint-input-ring-size))))
(setq comint-input-ring ambrevar/shell-history-global-ring))
(defun ambrevar/shell-history-remove-duplicates ()
(require 'functions) ; For `ambrevar/ring-delete-first-item-duplicates'.
(ambrevar/ring-delete-first-item-duplicates comint-input-ring))
(defvar ambrevar/comint-input-history-ignore (concat "^" (regexp-opt '("#" " " "cd ")))
"`comint-input-history-ignore' can only be customized globally
because `comint-read-input-ring' uses a temp buffer.")
(defun ambrevar/shell-remove-ignored-inputs-from-ring ()
"Discard last command from history if it matches
`ambrevar/comint-input-history-ignore'."
(unless (ring-empty-p comint-input-ring)
(when (string-match ambrevar/comint-input-history-ignore
(ring-ref comint-input-ring 0))
(ring-remove comint-input-ring 0))))
(defun ambrevar/shell-sync-input-ring (_)
(ambrevar/shell-history-remove-duplicates)
(ambrevar/shell-remove-ignored-inputs-from-ring)
(comint-write-input-ring))
(defun ambrevar/shell-setup ()
(set (make-variable-buffer-local 'comint-input-history-ignore)
(regexp-opt '("^#" "^ " "^cd ")))
(setq comint-input-ring-file-name
(expand-file-name "shell-history" user-emacs-directory))
(ambrevar/shell-use-global-history)
;; Write history on every command, not just on exit.
(add-hook 'comint-input-filter-functions 'ambrevar/shell-sync-input-ring nil t)
;; Only ending with '#' or '$' but seems slower:
;; (setq comint-prompt-regexp "^[^#$]*
;; [^#$]*[#$>] +")
;; [^#$]*[#$>] +")
(setq comint-prompt-regexp "^[^#$%>]*
[^#$%>]*[#$%>] +"))
\[^#$%>]*[#$%>] +"))
(add-hook 'shell-mode-hook 'ambrevar/shell-setup)