diff --git a/lisp/shell.el b/lisp/shell.el index 4352811912a..6fb5768c056 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -419,6 +419,21 @@ shell--start-prog "Shell file name started in `shell'.") (put 'shell--start-prog 'permanent-local t) +(defcustom shell-history-file-name nil + "The history file name used in `shell-mode'. +When it is a string, this file name will be used. +When it is nil, the environment variable HISTFILE is used. +When it is t, no history file name is used in `shell-mode'. + +The settings obey whether `shell-mode' is invoked in a remote buffer. +In that case, HISTFILE is taken from the remote host, and the string is +interpreted as local file name on the remote host. + +If `shell-mode' is invoked in a local buffer, and no history file name +can be determined, a default according to the shell type is used." + :type '(choice (const :tag "Default" nil) (const :tag "Suppress" t) file) + :version "30.1") + ;;; Basic Procedures (defun shell--unquote&requote-argument (qstr &optional upos) @@ -721,27 +736,33 @@ shell-mode (setq list-buffers-directory (expand-file-name default-directory)) ;; shell-dependent assignments. (when (ring-empty-p comint-input-ring) - (let ((remote (file-remote-p default-directory)) - (shell (or shell--start-prog "")) - (hsize (getenv "HISTSIZE")) - (hfile (getenv "HISTFILE"))) - (when remote - ;; `shell-snarf-envar' does not work trustworthy. - (setq hsize (shell-command-to-string "echo -n $HISTSIZE") - hfile (shell-command-to-string "echo -n $HISTFILE"))) + (let* ((remote (file-remote-p default-directory)) + (shell (or shell--start-prog "")) + (hfile (cond ((stringp shell-history-file-name) + shell-history-file-name) + ((null shell-history-file-name) + (if remote + (shell-command-to-string "echo -n $HISTFILE") + (getenv "HISTFILE"))))) + hsize) (and (string-equal hfile "") (setq hfile nil)) - (and (stringp hsize) - (integerp (setq hsize (string-to-number hsize))) - (> hsize 0) - (setq-local comint-input-ring-size hsize)) - (setq comint-input-ring-file-name - (concat - remote - (or hfile - (cond ((string-equal shell "bash") "~/.bash_history") - ((string-equal shell "ksh") "~/.sh_history") - ((string-equal shell "zsh") "~/.zsh_history") - (t "~/.history"))))) + (when (and (not remote) (not hfile)) + (setq hfile + (cond ((string-equal shell "bash") "~/.bash_history") + ((string-equal shell "ksh") "~/.sh_history") + ((string-equal shell "zsh") "~/.zsh_history") + (t "~/.history")))) + (when (stringp hfile) + (setq hsize + (if remote + (shell-command-to-string "echo -n $HISTSIZE") + (getenv "HISTSIZE"))) + (and (stringp hsize) + (integerp (setq hsize (string-to-number hsize))) + (> hsize 0) + (setq-local comint-input-ring-size hsize)) + (setq comint-input-ring-file-name + (concat remote hfile))) (if (or (equal comint-input-ring-file-name "") (equal (file-truename comint-input-ring-file-name) (file-truename null-device)))