New user option 'shell-history-file-name'

* doc/emacs/misc.texi (Shell Ring): Explain shell-history-file-name.

* doc/misc/tramp.texi (Inline methods): Be more specific with containers.
(Remote processes): New subsection "Managing remote shell history".
Explain shell-history-file-name.
(Frequently Asked Questions): Add items to Tramp speedup.  Remove
entry about history file.

* etc/NEWS: New user option 'shell-history-file-name'.

* lisp/shell.el (shell-history-file-name): New defcustom.
(shell-mode): Use it.  (Bug#71049)
This commit is contained in:
Michael Albinus 2024-06-02 19:30:12 +02:00
parent 2849c0cda3
commit bffe73b562
4 changed files with 136 additions and 80 deletions

View file

@ -1331,16 +1331,18 @@ buffer, or even killing large parts of it, does not affect the history
that these commands access.
@vindex comint-input-ring-file-name
@vindex shell-history-file-name
@cindex @env{HISTFILE} environment variable
Some shells store their command histories in files so that you can
refer to commands from previous shell sessions. Emacs reads
the command history file for your chosen shell, to initialize its own
command history. The file name is @file{~/.bash_history} for bash,
@file{~/.sh_history} for ksh, and @file{~/.history} for other shells.
@vindex tramp-histfile-override
If you run the shell on a remote host, this setting might be
overwritten by the variable @code{tramp-histfile-override}. It is
recommended to set this variable to @code{nil}.
refer to commands from previous shell sessions. Emacs reads the command
history file for your chosen shell, to initialize its own command
history. The history file name is the string specified in
@code{shell-history-file-name}. If that user option is @code{t}, the
command history is not read. If the value is @code{nil}, the command
history is read from the file specified in environment variable
@env{HISTFILE}, or from @file{~/.bash_history} for bash,
@file{~/.sh_history} for ksh, @file{~/.zsh_history"} for zsh, or
@file{~/.history} for other shells.
@node Shell History Copying
@subsubsection Shell History Copying

View file

@ -976,7 +976,8 @@ session.
@end table
@noindent
The following methods allow to access containers in different ways:
The following methods allow to access running containers in different
ways:
@table @asis
@item @option{docker}
@ -1017,6 +1018,9 @@ The host name may be either a container's name or ID, as returned by
the default Toolbox container for the host will be used. There is no
such default for Distrobox.
Contrary to the other container-based methods, these two methods start
a created container, if it isn't running yet.
These are optional methods, @pxref{Optional methods}. They do not
support user names.
@ -4080,8 +4084,59 @@ host. Furthermore, set @code{tramp-use-connection-share} to
unwanted side effects.
@anchor{Managing remote shell history}
@subsection Managing remote shell history
@cindex shell history
@vindex tramp-histfile-override
@vindex HISTFILE@r{, environment variable}
@vindex HISTFILESIZE@r{, environment variable}
@vindex HISTSIZE@r{, environment variable}
Due to the remote shell saving tilde expansions triggered by
@value{tramp}, the shell history file is probably growing rapidly.
@value{tramp} can suppress this behavior with the user option
@code{tramp-histfile-override}. When set to @code{t}, environment
variable @env{HISTFILE} is unset, and environment variables
@env{HISTFILESIZE} and @env{HISTSIZE} are set to 0. Don't use this
with @command{bash} 5.0.0. There is a bug in @command{bash} which
lets @command{bash} die.
Alternatively, @code{tramp-histfile-override} could be a string.
Environment variable @env{HISTFILE} is set to this file name then. Be
careful when setting to @file{/dev/null}; this might result in
undesired results when using @command{bash} as remote shell.
Another approach is to disable @value{tramp}'s handling of the
@env{HISTFILE} at all by setting @code{tramp-histfile-override} to
@code{nil}. In this case, saving history could be turned off by
putting this shell code in @file{.bashrc} or @file{.kshrc}:
@example
@group
if [ -f $HOME/.sh_history ] ; then
/bin/rm $HOME/.sh_history
fi
if [ "$@{HISTFILE-unset@}" != "unset" ] ; then
unset HISTFILE
fi
if [ "$@{HISTSIZE-unset@}" != "unset" ] ; then
unset HISTSIZE
fi
@end group
@end example
For @option{ssh}-based method, add the following line to your
@file{~/.ssh/environment}:
@example
HISTFILE=/dev/null
@end example
@subsection Running @code{shell} on a remote host
@cindex @code{shell}
@vindex explicit-shell-file-name
@vindex shell-history-file-name
Set @code{explicit-shell-file-name} to the appropriate shell name
when using @value{tramp} between two hosts with different operating
@ -4126,6 +4181,14 @@ of @code{explicit-shell-file-name} for different remote hosts.
@end group
@end lisp
The command @code{shell} reads the remote history file in order to to
initialize the history input ring. You can set the user option
@code{shell-history-file-name} in order to specify which remote
history file is taken, or whether to suppress this at all. It accepts
the same values as @code{tramp-histfile-override}, see @pxref{Managing
remote shell history}. @code{shell-history-file-name} accepts also
connection-local values in @code{shell} buffers.
@subsection Running @code{shell-command} on a remote host
@cindex @code{shell-command}
@ -5170,6 +5233,13 @@ connections, apply the following code.
@end group
@end lisp
@item
Use direct asynchronous processes if possible.
@item
Suppress reading the remote history file in @code{shell}. Set
@code{shell-history-file-name} to @code{t}.
@item
Disable excessive traces. Set @code{tramp-verbose} to 3 or lower,
default being 3. Increase trace levels temporarily when hunting for
@ -5476,54 +5546,6 @@ as follows:
@end lisp
@item
Why is @file{~/.sh_history} on the remote host growing?
@vindex tramp-histfile-override
@vindex HISTFILE@r{, environment variable}
@vindex HISTFILESIZE@r{, environment variable}
@vindex HISTSIZE@r{, environment variable}
Due to the remote shell saving tilde expansions triggered by
@value{tramp}, the history file is probably growing rapidly.
@value{tramp} can suppress this behavior with the user option
@code{tramp-histfile-override}. When set to @code{t}, environment
variable @env{HISTFILE} is unset, and environment variables
@env{HISTFILESIZE} and @env{HISTSIZE} are set to 0. Don't use this
with @command{bash} 5.0.0. There is a bug in @command{bash} which
lets @command{bash} die.
Alternatively, @code{tramp-histfile-override} could be a string.
Environment variable @env{HISTFILE} is set to this file name then. Be
careful when setting to @file{/dev/null}; this might result in
undesired results when using @command{bash} as remote shell.
Another approach is to disable @value{tramp}'s handling of the
@env{HISTFILE} at all by setting @code{tramp-histfile-override} to
@code{nil}. In this case, saving history could be turned off by
putting this shell code in @file{.bashrc} or @file{.kshrc}:
@example
@group
if [ -f $HOME/.sh_history ] ; then
/bin/rm $HOME/.sh_history
fi
if [ "$@{HISTFILE-unset@}" != "unset" ] ; then
unset HISTFILE
fi
if [ "$@{HISTSIZE-unset@}" != "unset" ] ; then
unset HISTSIZE
fi
@end group
@end example
For @option{ssh}-based method, add the following line to your
@file{~/.ssh/environment}:
@example
HISTFILE=/dev/null
@end example
@item
Where are remote files trashed to?

View file

@ -1047,6 +1047,15 @@ When this user option is non-nil, 'shell-get-old-input' ('C-RET')
includes multiple shell "\" continuation lines from command output.
Default is nil.
+++
*** New user option 'shell-history-file-name'.
When this user option is set to t, 'shell-mode' does not read the shell
history file. Setting this user option to a string specifies the name
of the shell history file to be read. A nil value triggers reading the
environment variable 'HISTFILE'.
In a 'shell' buffer, this user option is connection-local.
** Make mode
*** The Makefile browser is now obsolete.
@ -1182,7 +1191,7 @@ manual "(tramp) Improving performance of asynchronous remote processes".
---
*** Direct asynchronous processes use 'tramp-remote-path'.
When a direct asynchronous process is invoked, it uses 'tramp-remote-path'
for setting the remote PATH environment variable.
for setting the remote 'PATH' environment variable.
** File Notifications
@ -1922,10 +1931,11 @@ grammars. The Info manual "(elisp) Parsing Expression Grammars" has
documentation and examples.
** New major mode 'shell-command-mode'.
This mode is used by default for the output of 'async-shell-command'.
This mode is used by default for the output of asynchronous 'shell-command'.
To revert to the previous behavior, set the (also new) variable
'async-shell-command-mode' to 'shell-mode'. Any hooks or mode-specific
variables used should be adapted appropriately.
* Incompatible Lisp Changes in Emacs 30.1

View file

@ -419,6 +419,22 @@ Useful for shells like zsh that has this feature."
"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")
(put 'shell-history-file-name 'permanent-local t)
;;; Basic Procedures
(defun shell--unquote&requote-argument (qstr &optional upos)
@ -721,27 +737,33 @@ command."
(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)))