mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-22 12:04:39 +08:00
Allow deciding if a command should be saved to history (#10302)
Call fish_should_add_to_history to see if a command should be saved If it returns 0, it will be saved, if it returns anything else, it will be ephemeral. It gets the right-trimmed text as the argument. If it doesn't exist, we do the historical behavior of checking for a leading space. That means you can now turn that off by defining a `fish_should_add_to_history` that just doesn't check it. documentation based on #9298
This commit is contained in:
parent
d91ad2976c
commit
f7cc1743c6
57
doc_src/cmds/fish_should_add_to_history.rst
Normal file
57
doc_src/cmds/fish_should_add_to_history.rst
Normal file
|
@ -0,0 +1,57 @@
|
|||
.. _cmd-fish_should_add_to_history:
|
||||
|
||||
fish_should_add_to_history - decide whether a command should be added to the history
|
||||
=================================================================================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
|
||||
fish_should_add_to_history
|
||||
|
||||
::
|
||||
|
||||
function fish_should_add_to_history
|
||||
...
|
||||
end
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The ``fish_should_add_to_history`` function is executed before fish adds a command to history, and its return status decides whether that is done.
|
||||
|
||||
If it returns 0, the command is stored in history, when it returns anything else, it is not. In the latter case the command can still be recalled for one command.
|
||||
|
||||
The first argument to ``fish_should_add_to_history`` is the commandline. History is added *before* a command is run, so e.g. :envvar:`status` can't be checked. This is so commands that don't finish like :doc:`exec` and long-running commands are available in new sessions immediately.
|
||||
|
||||
If ``fish_should_add_to_history`` doesn't exist, fish will save a command to history unless it starts with a space. If it does exist, this function takes over all of the duties, so commands starting with space are saved unless ``fish_should_add_to_history`` says otherwise.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
A simple example:
|
||||
|
||||
::
|
||||
|
||||
function fish_should_add_to_history
|
||||
for cmd in vault mysql ls
|
||||
string match -qr "^$cmd" -- $argv; and return 1
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
This refuses to store any immediate "vault", "mysql" or "ls" calls. Commands starting with space would be stored.
|
||||
|
||||
::
|
||||
|
||||
function fish_should_add_to_history
|
||||
# I don't want `git pull`s in my history when I'm in a specific repository
|
||||
if string match -qr '^git pull'
|
||||
and string match -qr "^/home/me/my-secret-project/" -- (pwd -P)
|
||||
return 1
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
|
@ -4674,6 +4674,25 @@ impl ReaderData {
|
|||
}
|
||||
}
|
||||
|
||||
fn should_add_to_history(&mut self, text: &wstr) -> bool {
|
||||
let parser = self.parser();
|
||||
if !function::exists(L!("fish_should_add_to_history"), parser) {
|
||||
// Historical behavior, if the command starts with a space we don't save it.
|
||||
return text.as_char_slice()[0] != ' ';
|
||||
}
|
||||
|
||||
let mut cmd: WString = L!("fish_should_add_to_history ").into();
|
||||
cmd.push_utfstr(&escape(text));
|
||||
let _not_interactive = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_interactive, new_value),
|
||||
false,
|
||||
);
|
||||
|
||||
let ret = exec_subshell(&cmd, parser, None, /*apply_exit_status=*/ false);
|
||||
|
||||
ret == STATUS_CMD_OK.unwrap()
|
||||
}
|
||||
|
||||
// Add the current command line contents to history.
|
||||
fn add_to_history(&mut self) {
|
||||
if self.conf.in_silent_mode {
|
||||
|
@ -4692,9 +4711,8 @@ impl ReaderData {
|
|||
self.history.remove_ephemeral_items();
|
||||
|
||||
if !text.is_empty() {
|
||||
// Mark this item as ephemeral if there is a leading space (#615).
|
||||
let mode = if text.as_char_slice()[0] == ' ' {
|
||||
// Leading spaces are ephemeral (#615).
|
||||
// Mark this item as ephemeral if should_add_to_history says no (#615).
|
||||
let mode = if !self.should_add_to_history(&text) {
|
||||
PersistenceMode::Ephemeral
|
||||
} else if in_private_mode(self.vars()) {
|
||||
PersistenceMode::Memory
|
||||
|
|
|
@ -178,3 +178,27 @@ sendline("history clear-session")
|
|||
expect_prompt()
|
||||
sendline("history search --exact 'echo after' | cat")
|
||||
expect_prompt("\r\n")
|
||||
|
||||
# Check history filtering
|
||||
# We store anything that starts with "echo ephemeral".
|
||||
sendline("function fish_should_add_to_history; string match -q 'echo ephemeral*' -- $argv; and return 2; return 0; end")
|
||||
expect_prompt("")
|
||||
# Check that matching the line works
|
||||
# (fish_should_add_to_history is itself stored in history so we match "ephemeral!" to avoid it)
|
||||
sendline("echo ephemeral! line")
|
||||
expect_prompt("ephemeral! line")
|
||||
sendline("echo nonephemeral! line")
|
||||
expect_prompt("nonephemeral! line")
|
||||
sendline("true")
|
||||
expect_prompt()
|
||||
sendline("echo a; history search '*ephemeral!*' | cat; echo b")
|
||||
expect_prompt("a\r\necho nonephemeral! line\r\nb\r\n")
|
||||
|
||||
# If fish_should_add_to_history exists, it will completely take over,
|
||||
# so even lines with spaces are stored
|
||||
sendline(" echo spaced")
|
||||
expect_prompt("spaced")
|
||||
sendline("true")
|
||||
expect_prompt()
|
||||
sendline("echo a; history search '*spaced*' | cat; echo b")
|
||||
expect_prompt("a\r\n echo spaced\r\nb\r\n")
|
||||
|
|
Loading…
Reference in New Issue
Block a user