New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow history file name customization #102

Closed
ekoeppen opened this Issue Jun 11, 2012 · 24 comments

Comments

Projects
None yet
10 participants
@ekoeppen

ekoeppen commented Jun 11, 2012

To have separate histories when using e.g. screen or logging in to a machine via multiple sessions, it should be possible to customize the history file name, for example using an environment variable. See ekoeppen@ccfac2c for a possible implementation.

@jaysh

This comment has been minimized.

Show comment
Hide comment
@jaysh

jaysh Feb 5, 2015

I would also very much like this feature 👍

@ridiculousfish - would you consider a pull request for it? This milestone was assigned a while back, so I thought I would double check.

My use case is the same as this one, and I was thinking of the same approach. Rather than making it specifically configurable, you could just set an environment variable to essentially namespace the histories.

With a slightly tweaked implementation, I believe this would also solve #1156 too if it could be set to /dev/null as the environment variable. This would be the approach I'm in favor of, so at least a workaround is available for anyone interested in #1156.

Thanks,
Jay

jaysh commented Feb 5, 2015

I would also very much like this feature 👍

@ridiculousfish - would you consider a pull request for it? This milestone was assigned a while back, so I thought I would double check.

My use case is the same as this one, and I was thinking of the same approach. Rather than making it specifically configurable, you could just set an environment variable to essentially namespace the histories.

With a slightly tweaked implementation, I believe this would also solve #1156 too if it could be set to /dev/null as the environment variable. This would be the approach I'm in favor of, so at least a workaround is available for anyone interested in #1156.

Thanks,
Jay

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Feb 5, 2015

Member

An environment variable is certainly easy to implement on the fish side. Out of curiosity, how do you plan to set the variable? Would you do it manually (set -x ...) or in a config file someplace?

Member

ridiculousfish commented Feb 5, 2015

An environment variable is certainly easy to implement on the fish side. Out of curiosity, how do you plan to set the variable? Would you do it manually (set -x ...) or in a config file someplace?

@jaysh

This comment has been minimized.

Show comment
Hide comment
@jaysh

jaysh Feb 5, 2015

Music to my ears :)

My initial use case is within terminator. I experimented by creating a profile and selected the "Run a custom command instead of my shell" and configured it to have:

fish_history_filename=/some/path/to/the/history fish

Then I'd have that profile as a launcher shortcut somewhere.

jaysh commented Feb 5, 2015

Music to my ears :)

My initial use case is within terminator. I experimented by creating a profile and selected the "Run a custom command instead of my shell" and configured it to have:

fish_history_filename=/some/path/to/the/history fish

Then I'd have that profile as a launcher shortcut somewhere.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Feb 5, 2015

Member

Thanks, that makes sense.

Member

ridiculousfish commented Feb 5, 2015

Thanks, that makes sense.

@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Jan 9, 2016

Contributor

Sorry, but I vote no to this request. Three and a half years after the issue was opened only one person has said "me too". If you really need isolated history files then you should be using Linux containers or a similar technology to create a namespace for the shell.

Contributor

krader1961 commented Jan 9, 2016

Sorry, but I vote no to this request. Three and a half years after the issue was opened only one person has said "me too". If you really need isolated history files then you should be using Linux containers or a similar technology to create a namespace for the shell.

@floam

This comment has been minimized.

Show comment
Hide comment
@floam

floam Feb 16, 2016

Member

I think this may help implement sessions with working suspend/resume for OS X's Terminal.app. (see /etc/bashrc_Apple_Terminal for what Apple does with bash.)

I'm a "Me Too!", I want to try to make local sessions work from within fish by manually managing/abusing the history.

Member

floam commented Feb 16, 2016

I think this may help implement sessions with working suspend/resume for OS X's Terminal.app. (see /etc/bashrc_Apple_Terminal for what Apple does with bash.)

I'm a "Me Too!", I want to try to make local sessions work from within fish by manually managing/abusing the history.

@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Feb 23, 2016

Contributor

Okay, I've changed my mind. However, I think this should use the same HISTFILE env var name that bash and zsh use. Thanks for PR#1940, @jaysh, but it has some problems with the code not to mention the lack of unit tests and changes to the documentation. If you don't mind I'll borrow your idea and fix the problems.

Contributor

krader1961 commented Feb 23, 2016

Okay, I've changed my mind. However, I think this should use the same HISTFILE env var name that bash and zsh use. Thanks for PR#1940, @jaysh, but it has some problems with the code not to mention the lack of unit tests and changes to the documentation. If you don't mind I'll borrow your idea and fix the problems.

@krader1961 krader1961 self-assigned this Feb 23, 2016

krader1961 added a commit to krader1961/fish-shell that referenced this issue Feb 26, 2016

allow the history file to be configurable
Introduce a HISTFILE variable in the same vein as bash and zsh to allow the
user to specify where interactive commands are logged. The default file name
is unchanged.

Resolves fish-shell#102.

krader1961 added a commit to krader1961/fish-shell that referenced this issue Feb 26, 2016

allow the history file to be configurable
Introduce a HISTFILE variable in the same vein as bash and zsh to allow the
user to specify where interactive commands are logged. The default file name
is unchanged.

Resolves fish-shell#102.

krader1961 added a commit to krader1961/fish-shell that referenced this issue Feb 26, 2016

allow the history file to be configurable
Introduce a HISTFILE variable in the same vein as bash and zsh to allow the user to specify where interactive commands are logged. The default file name is unchanged.

Resolves fish-shell#102.

krader1961 added a commit to krader1961/fish-shell that referenced this issue Feb 26, 2016

allow the history file to be configurable
Introduce a HISTFILE variable in the same vein as bash and zsh to allow the user to specify where interactive commands are logged. The default file name is unchanged.

Resolves fish-shell#102.

krader1961 added a commit to krader1961/fish-shell that referenced this issue Feb 26, 2016

allow the history file to be configurable
Introduce a HISTFILE variable in the same vein as bash and zsh to allow the user to specify where interactive commands are logged. The default file name is unchanged.

Resolves fish-shell#102.
@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Feb 27, 2016

Contributor

If someone sets $FISH_HISTFILE (which I've decided to use rather than $HISTFILE) to a relative path should fish

  1. always expand that path relative to the $PWD at the time a command is logged, or
  2. anchor it (i.e., convert to an absolute path) at the time the variable is set?

This is something of a rhetorical question because I think it's pretty clear option 1 will cause so many problems it's not even worth considering. I only ask because the original pull-request implemented that behavior. As did my first rewrite of that change. Unless someone can explain why option 1 is preferable I'm going to implement option 2.

Contributor

krader1961 commented Feb 27, 2016

If someone sets $FISH_HISTFILE (which I've decided to use rather than $HISTFILE) to a relative path should fish

  1. always expand that path relative to the $PWD at the time a command is logged, or
  2. anchor it (i.e., convert to an absolute path) at the time the variable is set?

This is something of a rhetorical question because I think it's pretty clear option 1 will cause so many problems it's not even worth considering. I only ask because the original pull-request implemented that behavior. As did my first rewrite of that change. Unless someone can explain why option 1 is preferable I'm going to implement option 2.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Feb 27, 2016

Member

That's a pretty funny question. What do bash and zsh do?

Member

ridiculousfish commented Feb 27, 2016

That's a pretty funny question. What do bash and zsh do?

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Feb 27, 2016

Member

Also if I set FISH_HISTFILE, do I lose my history from this session and instead pick up whatever was in that other file?

Member

ridiculousfish commented Feb 27, 2016

Also if I set FISH_HISTFILE, do I lose my history from this session and instead pick up whatever was in that other file?

@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Feb 27, 2016

Contributor

I have no idea what bash/zsh do. Zsh in particular is such a rat maze of behavior I wouldn't even pretend that I knew how it behaves despite using it for 7+ years and you'd have to pay me to figure out what it does.

Your second question is more interesting. It's not clear to me what happens or should happen. Any new commands are logged to the new $FISH_HISTFILE as best I can tell from limited human testing and unit tests. But what does that mean for older history that is unique to the current shell? When does an interactive fish instance decide to rewrite the current fish history file? If fish merely concatenated commands to the history file rather than removing old entries for the same unique command this would presumably be straightforward to answer. But the duplicate elimination complicates things.

Which means I don't really understand when the history file is rewritten and neither did the person who created the original change. It also means the documentation doesn't answer this question unless I have a reading comprehension problem.

Contributor

krader1961 commented Feb 27, 2016

I have no idea what bash/zsh do. Zsh in particular is such a rat maze of behavior I wouldn't even pretend that I knew how it behaves despite using it for 7+ years and you'd have to pay me to figure out what it does.

Your second question is more interesting. It's not clear to me what happens or should happen. Any new commands are logged to the new $FISH_HISTFILE as best I can tell from limited human testing and unit tests. But what does that mean for older history that is unique to the current shell? When does an interactive fish instance decide to rewrite the current fish history file? If fish merely concatenated commands to the history file rather than removing old entries for the same unique command this would presumably be straightforward to answer. But the duplicate elimination complicates things.

Which means I don't really understand when the history file is rewritten and neither did the person who created the original change. It also means the documentation doesn't answer this question unless I have a reading comprehension problem.

@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Feb 27, 2016

Contributor

P.S., for anyone paying attention. The dialog on this issue is a canonical example of why seemingly simple enhancement requests are almost never simple.

Contributor

krader1961 commented Feb 27, 2016

P.S., for anyone paying attention. The dialog on this issue is a canonical example of why seemingly simple enhancement requests are almost never simple.

@ridiculousfish

This comment has been minimized.

Show comment
Hide comment
@ridiculousfish

ridiculousfish Feb 27, 2016

Member

When does an interactive fish instance decide to rewrite the current fish history file?

Every 25 (kVacuumFrequency) items, with an initially randomized counter.

The history is conceptually just a list of commands. Running a command appends to that list, and up-arrow traverses backwards through them. It seems natural that setting FISH_HISTFILE switches over to a different list, so it would not contain any prior commands.

If we believe this (and I do) then the implementation is very straightforward. History is already instanced (see e.g. history_with_name), so setting FISH_HISTFILE should simply set the reader_data_t::history field to a new (or existing) instance. This avoids a bunch of ugly concurrency issues and is definitely my preferred approach.

A minor change required is to replace history_with_name would history_with_path; right now history_filename infers the path from the name, but we would instead want the path to be explicitly settable.

Member

ridiculousfish commented Feb 27, 2016

When does an interactive fish instance decide to rewrite the current fish history file?

Every 25 (kVacuumFrequency) items, with an initially randomized counter.

The history is conceptually just a list of commands. Running a command appends to that list, and up-arrow traverses backwards through them. It seems natural that setting FISH_HISTFILE switches over to a different list, so it would not contain any prior commands.

If we believe this (and I do) then the implementation is very straightforward. History is already instanced (see e.g. history_with_name), so setting FISH_HISTFILE should simply set the reader_data_t::history field to a new (or existing) instance. This avoids a bunch of ugly concurrency issues and is definitely my preferred approach.

A minor change required is to replace history_with_name would history_with_path; right now history_filename infers the path from the name, but we would instead want the path to be explicitly settable.

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Feb 27, 2016

Member

Also if I set FISH_HISTFILE, do I lose my history from this session and instead pick up whatever was in that other file?

One of the usecases that were mentioned for this was screencasting, where you don't want your old commands to show up. So:

It seems natural that setting FISH_HISTFILE switches over to a different list, so it would not contain any prior commands.

Yes. Others were also going for the privacy angle.

Member

faho commented Feb 27, 2016

Also if I set FISH_HISTFILE, do I lose my history from this session and instead pick up whatever was in that other file?

One of the usecases that were mentioned for this was screencasting, where you don't want your old commands to show up. So:

It seems natural that setting FISH_HISTFILE switches over to a different list, so it would not contain any prior commands.

Yes. Others were also going for the privacy angle.

@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Feb 29, 2016

Contributor

I am now leaning towards a hybrid solution. Augment the builtin history command to have an option analogous to read --mode-name. I say analogous because I don't think that option name is something we want to replicate. But there should be a way via the fish builtin history command to change the history file. Including not having any persistent history by setting the value to an empty string or /dev/null. There will need to be another history option to show the file name. We still need a way to set the history file before the shell is started. And an env var like FISH_HISTFILE is the natural way to do so. A private function defined with --on-variable FISH_HISTFILE would handle mapping that var to the history command.

Contributor

krader1961 commented Feb 29, 2016

I am now leaning towards a hybrid solution. Augment the builtin history command to have an option analogous to read --mode-name. I say analogous because I don't think that option name is something we want to replicate. But there should be a way via the fish builtin history command to change the history file. Including not having any persistent history by setting the value to an empty string or /dev/null. There will need to be another history option to show the file name. We still need a way to set the history file before the shell is started. And an env var like FISH_HISTFILE is the natural way to do so. A private function defined with --on-variable FISH_HISTFILE would handle mapping that var to the history command.

@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Mar 3, 2016

Contributor

Below is the text I'm tentatively planning on adding to the doc_src/history.txt file to explain how to change the history file. After this is implemented I intend to add a --read option to make the history command operate on the read history file and deprecate the existing read --mode_name option.

Obviously using the history command to set the history file will be the canonical way to do so. And any user who wants to use an environment variable to set the history file at the time the shell starts is free to do so via appropriate statements in their config.fish. The question is whether we should provide support "out of the box" for setting the file via an env var as described in my previous comments.

\fish{synopsis}
history --file history_file_identifier
...
- `--file` changes the current history file. That option can be used both independent of any
other option and in conjunction with the other options. In both cases the change to the
current history file is persistent and affects subsequent commands. The switch to a new
history file occurs before any other option is acted on and an implicit `history --save`
occurs before the switch.

The "history_file_identifier" can be a simple word or a relative or absolute path name.
A simple word (i.e., one without slashes) is interpreted as a file name relative to
`$XDG_DATA_HOME` (`$HOME/.local/share/fish` by default). If "history_file_identifier"
is the special word "fish" the default history path name will be substituted. The special
word "none" results in no history file being used. A relative path (one that contains a
slash but does not begin with a slash) is interpreted relative to `$PWD` at the time the
command is run.
Contributor

krader1961 commented Mar 3, 2016

Below is the text I'm tentatively planning on adding to the doc_src/history.txt file to explain how to change the history file. After this is implemented I intend to add a --read option to make the history command operate on the read history file and deprecate the existing read --mode_name option.

Obviously using the history command to set the history file will be the canonical way to do so. And any user who wants to use an environment variable to set the history file at the time the shell starts is free to do so via appropriate statements in their config.fish. The question is whether we should provide support "out of the box" for setting the file via an env var as described in my previous comments.

\fish{synopsis}
history --file history_file_identifier
...
- `--file` changes the current history file. That option can be used both independent of any
other option and in conjunction with the other options. In both cases the change to the
current history file is persistent and affects subsequent commands. The switch to a new
history file occurs before any other option is acted on and an implicit `history --save`
occurs before the switch.

The "history_file_identifier" can be a simple word or a relative or absolute path name.
A simple word (i.e., one without slashes) is interpreted as a file name relative to
`$XDG_DATA_HOME` (`$HOME/.local/share/fish` by default). If "history_file_identifier"
is the special word "fish" the default history path name will be substituted. The special
word "none" results in no history file being used. A relative path (one that contains a
slash but does not begin with a slash) is interpreted relative to `$PWD` at the time the
command is run.
@jonhoo

This comment has been minimized.

Show comment
Hide comment
@jonhoo

jonhoo Mar 3, 2016

Contributor

@krader1961 this looks good. I think having standard support for a variable might be useful, but not necessary. It would (probably) primarily be used by scripts that call fish, but given that fish is intended for interactive sessions, that's shouldn't be all that common.

Contributor

jonhoo commented Mar 3, 2016

@krader1961 this looks good. I think having standard support for a variable might be useful, but not necessary. It would (probably) primarily be used by scripts that call fish, but given that fish is intended for interactive sessions, that's shouldn't be all that common.

@zanchey

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey Mar 4, 2016

Member

I think it would be worth noting that using "none" allows you to enter a private/incognito session, ala browsers.

Member

zanchey commented Mar 4, 2016

I think it would be worth noting that using "none" allows you to enter a private/incognito session, ala browsers.

@krader1961

This comment has been minimized.

Show comment
Hide comment
@krader1961

krader1961 Mar 4, 2016

Contributor

@zanchey: Excellent suggestion. Thx. I'm also going to make it clear that only regular files can be used. Attempting to specify a device file like /dev/null will be rejected. I know I suggested using /dev/null in other comments but I now believe that is a bad idea. Not least because it complicates the history rewrite logic.

Contributor

krader1961 commented Mar 4, 2016

@zanchey: Excellent suggestion. Thx. I'm also going to make it clear that only regular files can be used. Attempting to specify a device file like /dev/null will be rejected. I know I suggested using /dev/null in other comments but I now believe that is a bad idea. Not least because it complicates the history rewrite logic.

krader1961 added a commit to krader1961/fish-shell that referenced this issue Mar 29, 2016

allow the history file to be configurable
Introduce a HISTFILE variable in the same vein as bash and zsh to allow the user to specify where interactive commands are logged. The default file name is unchanged.

Resolves fish-shell#102.

krader1961 added a commit to krader1961/fish-shell that referenced this issue Apr 5, 2016

allow the history file to be configurable
Introduce a HISTFILE variable in the same vein as bash and zsh to allow the user to specify where interactive commands are logged. The default file name is unchanged.

Resolves fish-shell#102.
@zx8

This comment has been minimized.

Show comment
Hide comment
@zx8

zx8 Dec 18, 2016

@krader1961 Any plan on picking this back up? Would be really awesome to support this in fish!

zx8 commented Dec 18, 2016

@krader1961 Any plan on picking this back up? Would be really awesome to support this in fish!

tomassedovic added a commit to tomassedovic/fish-shell that referenced this issue May 12, 2017

allow the history file to be configurable
Introduce a HISTFILE variable in the same vein as bash and zsh to allow the user to specify where interactive commands are logged. The default file name is unchanged.

Resolves fish-shell#102.

@tomassedovic tomassedovic referenced this issue May 12, 2017

Closed

Fish histfile #4024

1 of 3 tasks complete
@tomassedovic

This comment has been minimized.

Show comment
Hide comment
@tomassedovic

tomassedovic May 15, 2017

Contributor

If there are no objections, I'm happy to take this on. For a WIP implementation, see #4024 and the associated comments.

Contributor

tomassedovic commented May 15, 2017

If there are no objections, I'm happy to take this on. For a WIP implementation, see #4024 and the associated comments.

@tomassedovic

This comment has been minimized.

Show comment
Hide comment
@tomassedovic

tomassedovic May 17, 2017

Contributor

Based on the comments on the pull request above, here's the proposed implementation:

The history file will be controlled solely by the FISH_HISTFILE environment variable. The variable represents a session ID that the history files will use. It is not a path to a file or directory.

The location of the history file will be:

$XDG_DATA_HOME/fish/<session_id>_history

Couple of examples:

FISH_HISTFILE="fish" -> ~/.local/share/fish/fish_history{,.*}
FISH_HISTFILE="banana" -> ~/.local/share/fish/banana_history{,.*}

As you can see, setting FISH_HISTFILE to fish will result in the current path of the history file, so that's going to be the default value. If FISH_HISTFILE is unset or set to default, we will use the default value (fish).

If FISH_HISTFILE is set to an empty string, no history will be stored (like the private/incognito mode in web browsers).

If the value changes in a single shell session, the location will be updated accordingly.

Contributor

tomassedovic commented May 17, 2017

Based on the comments on the pull request above, here's the proposed implementation:

The history file will be controlled solely by the FISH_HISTFILE environment variable. The variable represents a session ID that the history files will use. It is not a path to a file or directory.

The location of the history file will be:

$XDG_DATA_HOME/fish/<session_id>_history

Couple of examples:

FISH_HISTFILE="fish" -> ~/.local/share/fish/fish_history{,.*}
FISH_HISTFILE="banana" -> ~/.local/share/fish/banana_history{,.*}

As you can see, setting FISH_HISTFILE to fish will result in the current path of the history file, so that's going to be the default value. If FISH_HISTFILE is unset or set to default, we will use the default value (fish).

If FISH_HISTFILE is set to an empty string, no history will be stored (like the private/incognito mode in web browsers).

If the value changes in a single shell session, the location will be updated accordingly.

tomassedovic added a commit to tomassedovic/fish-shell that referenced this issue May 27, 2017

Make the history session configurable
Using the FISH_HISTFILE variable will let people customise the session
to use for the history file. The resulting history file is:

    `$XDG_DATA_HOME/fish/name_history`

Where `name` is the name of the session. The default value is `fish`
which results in the current history file.

If it's set to an empty string, the history will not be stored to a
file.

Fixes fish-shell#102

@krader1961 krader1961 closed this in aec0973 Jul 1, 2017

@faho faho modified the milestones: fish 2.7.0, fish-future Jul 24, 2017

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Feb 4, 2018

Why was a session ID chosen over being able to set a file path?
Would it still be possible/compatible to add setting a file path?

Edit: sorry for thread necro, I missed the reference to #4024, checking that out now.

ghost commented Feb 4, 2018

Why was a session ID chosen over being able to set a file path?
Would it still be possible/compatible to add setting a file path?

Edit: sorry for thread necro, I missed the reference to #4024, checking that out now.

@ghost ghost unassigned krader1961 Feb 4, 2018

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Mar 7, 2018

Member

For posterity: The variable was renamed to fish_history, and it contains a "session ID", not a filename. That means the file ends up being called {$fish_history}_history and {$fish_history}_read_history for things entered via read.

Member

faho commented Mar 7, 2018

For posterity: The variable was renamed to fish_history, and it contains a "session ID", not a filename. That means the file ends up being called {$fish_history}_history and {$fish_history}_read_history for things entered via read.

mqudsi added a commit to mqudsi/fish-shell that referenced this issue Sep 20, 2018

Add a --private option to launch fish in private mode
In private mode, access to previous history is blocked and new history
is directed immediately to /dev/null. Note that in this current
implementation, history is available _within_ the private session, but
cannot (well, should not) leak from it.

This mode can be used when it is not desirable for commandline history
to leak into a session, e.g. via autocomplete or when it is desirable to
test the behavior of fish in the absence of history items without
permanently clearing the history.

I'm sure there are a lot more features that can be incorporated into
private mode, such as restricting access to certain user-specific
configuration files, etc.

This addresses a lot of the concerns raised in fish-shell#1363 (which was later
changed to track mosh-specific problems). See also fish-shell#102.

(Note that $fish_history is not used as that causes data to persist to
disk.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment