Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I love fuzzy shell history. Game changer in terms of shell productivity.

I use atuin[0] instead of fzf as I find the experience a bit nicer and it has history backups built in (disclaimer, I am a maintainer)

Some of our users still prefer fzf because they are used to how it fuzzy finds, but we're running an experiment with skim[1] which allows us to embed the fuzzy engine without much overhead - hopefully giving them back that fzf-like experience

[0]: https://github.com/ellie/atuin [1]: https://github.com/lotabout/skim



If that's your use case, here's another game changer (one line bashrc change to make bash_history changes immediately, rather than upon shell exit, e.g. when you end your tmux session): https://web.archive.org/web/20090815205011/http://www.cuberi...


Thank you!! Why on earth isn't that the default. It always seemed weird that with multiple bash windows open, the commands from most of them weren't added to the history.


I often have three or more terminals open, doing different tasks in each; I also often have cycles of work where I'll repeat the last three commands again (three up-arrows and a return). This breaks if one terminal's commands get inserted into another terminal's history.


Comment from the author:

"Ted, the change I suggest doesn't affect the independence of your sessions as you suggest. Each shell maintains a unique history in memory so modifying the history file has no affect on running terminals. The only time the history file is read is when you start a new terminal. I recommend you try my suggestion. Really, all I am doing is eliminating the race condition that causes the bash history file to have inconsistent data.

Thanks for the feedback."


Exactly this.

If you do want to load the history persisted from other shells into the current one, all you have to do (if memory serves) is:

    $ history -r


My solution is I immediately record the commands, but do not load them. That way new terminals get all the history, but old terminals keep their flow.


But if you go back later, the chains of commands from different terminals are interlaced right?


To some degree; it depends on the amount of multitasking. I mainly care about which commands in which order when I'm looking at recent commands from that terminal; otherwise I use C-r.


My guesses are that it's on-close so you can follow the per-shell history slightly easier (rather than it being interleaved from multiple shells?), or reducing disk writes?


They don’t interlace which can be nice


It is very useful just be careful when switching between shells and hitting the up arrow to get the previous command, as you may get something from another shell.


That will only happen if PROMPT_COMMAND also contains "history -c; history -r", right? "history -a" just saves it, but "history -c; history -r" clears memory history and reloads from disk.


Yes, that's correct. I overlooked that detail while reading the link on a phone, where the text is quite small.


Meta question : do you keep the archive.org link of the article in your favorite or did you manually look up the link before posting? Or maybe an extension that does that automatically?


for zsh

    setopt inc_append_history


I have used that for years, but there are downsides to the approach as well.

So, you revisit a window, and you want to start from where you left, but now, you might maybe wade through 100's of commands before you get back to that point in time. There are fixes for this too of course, my point is, that it doesn't come without side effects, and that is maybe why it isn't set as default behaviour. At least in a pre 'fzf/atuin/smenu' world.

I prefer smenu's history search, even if I consider myself a heavy fzf user.


FWIW I get a 503 on that URL. Any chance someone can give me that magic one-liner?


Looks like it is still down - but see eg: https://askubuntu.com/questions/67283/is-it-possible-to-make...

To wit:

> It says to put those commands in the .bashrc config:

    shopt -s histappend
    PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
> The first command changes the history file mode to append and the second configures the history -a command to be run at each shell prompt. The -a option makes history immediately write the current/new lines to the history file.

I used to have something like this set up on my Linux laptop - the downside is that seperate shell/terminals/windows/tabs don't keep seperate history - so if you eg start a server in shell one (rails s), start editor in two - then go back to one and ctrl-c out - up arrow will now give you "vim" not "rails s".

The problem compounds if you ping, or curl in another shell etc.


Not sure what that link had as it's dead for me as well but...

PROMPT_COMMAND='history -a'

Has always worked for me. Goes in your .bashrc from the FM

PROMPT_COMMAND ¶ If this variable is set, and is an array, the value of each set element is interpreted as a command to execute before printing the primary prompt ($PS1). If this is set but not an array variable, its value is used as a command to execute instead.


I did that once (or it might have been something similar with the same effect, don't remember) and after a while it made my terminals super slow.


Oh wow thank you for this.


This is literally going to change my life! T_T


FYI, speaking as a skim library user/lover, two things -- 1) it's really not maintained, and 2) once you dig into the code it gets a little gnarly.

I have a branch[0] where I'm trying to do things like reduce the user perceptible lag in search, the initial time of ingest, and add small features I need, etc (all done). I've tried to create PRs where I can, and they go unnoticed and unused.

One other thing I was trying to get a handle on is memory usage. The issue is -- you're implicitly creating objects with static lifetimes everywhere. Now try to refactor that, and there is a trait object held in a struct which depends on another trait object, so good luck figuring out the lifetimes. This is totally fine for a fuzzy finder tool, probably, but less fine when you drop a fuzzy find feature it into an app.

Love to have others interested in skim, and eager to work with anyone with big ideas about how to make it better. I'll have to try out atuin!

[0]: https://github.com/kimono-koans/two_percent


Was really trying to figure out why you would name a fork of a project that skims the filesystem two_percent. "What, is it invoked using %% or something? That seems unw... oh. Nice." Well done.


> it's really not maintained

What do you mean by maintained? There are commits as recent as yesterday on the project: https://github.com/junegunn/fzf


They are clearly not talking about fzf


Fuzzy history is nice, but the real game changer for me was the ability to pretty much stop remembering paths in big projects. The default keybindings provide the Ctrl-T shortcut to insert a path/filename on the command line using fuzzy search and Alt-C to fuzzy-cd. No more tedious completion - just search + enter.


Same thing with Emacs with Projectile.

I can't believe people still using a tree view of a deeply nested project and clicking though directories and finally finding a file.

I am not willing to type more than a few characters for any file in the project. Fuzzy finding with quick narrowing FTW.


What I really want is orderless[1] searching of my vterm shell history. That would be a game changer.

https://github.com/oantolin/orderless


I've seen a number of projects with hundreds of "index.js" files.


fzf includes the path in your match. So, unless the directories also have unpractical names, this typically won’t be a problem.

Learning for me: Brew suggests to install the shortcuts but doesn’t automatically do this. Just activated this and Ctrl-R is a big improvement this way.


So you type a few more characters and narrow it down. Space separated snippets will match any part of the path.


I've got this in my profile:

  export CDPATH="$HOME:$HOME/code/:$(ls -d $HOME/work/*/| tr \\n :)"
so regardless of my cwd I can cd into pretty much any project I'd want to.


In my environment:

  ~/project% find -type d | wc -l
  13946
I access files in a dozen or so folders in this hierarchy regularly, so fuzzy find is an extreme boost for me.


I just use fzf-marks. Then I can fuzzy cd the only directories that ever matter to me.


Something I've always wanted from my shell history is to be able to record relative filepaths as their absolute equivalent in the history, is that supported in atuin?. If you do a lot of data munging on the CLI, you end up with a lot of commands like `jq 'complicated_selector' data.json`, which if I want to remember the selector is good, but if I want to remember which data I ran it on is not so good. I could do it with better filenames but that would involve thinking ahead. I also run into this a lot trying to remember exactly which local file has been uploaded to s3 by looking at shell history.


I sometime use a #a-text-comment at the end of long/complex command line incantation. Easy to find using fzf at a later date. Also can provide you with a quick context.


This is commonly referred to as a 'bashtag'

Or at least I hope it is. :)


it works in other shells, so 'shetag'.

but that isn't sexy somehow. we'll have to settle on 'shag'.


So scrappy and simple-I love it!


Technically. For every command you run, atuin stores the current directory, the time, the duration, the exit code, a session id and your user/host name.

With the current directory you should be able to get the absolute path from your relative paths


File paths are just strings from the shell, though, and each tool can handle relative paths differently. So `./` can mean relative to your shell's cwd or the program could interpret it as relative to something else. Moreover something like `go test -v ./...` is...ambiguous.

I think what would be more useful is to record `env` or some similar context along with the time and command. That would probably get weird pretty fast, though. Maybe just a thing that could insert some useful bookmarking/state into the history record on-demand? `history-set-checkpoint` or something would save your pwd and local vars or something.


Issues like this are why I write everything into scripts and pipelines, even the munging. This way everything is documented: the environment, the input, the output, the log file, what ran, and longform comments with why I was doing it.


Good choice but that for me breaks the "carpe Diem" part of the inspiration that can go away in a whim, that it's what I have when I'm writing (complex) one liners in the shell.

Or maybe I'm just lazy.


Just have two windows open, your console and your editor. If you ran a command that worked just copy and paste it into the editor. There's your script if you didn't want to get fancy. If you copied your initial cd command or whatever you'd know what the relative paths were referring too as well (although this issue is why I have gotten into the habit of using a path variable instead of relative or anything hardcoded).


I wanted to like atuin. The idea is great. But it just could not match the instant search that ctrl-r with fzf offers sadly. There is always a noticeable delay that annoyed me and made me revert back to fzf for search.

For me another issue was that I needed to do more keystrokes for the same behaviour (search a previously ran command and execute it).

Fuzzy shell history search is just one of those mind-blowing things. I love my history, it's such a trove and I can trust it to work as some kind of external memory (it's enough to vaguely know the kubectl command, or that I want to "du -h | sort" to see what is using disk space, etc).


I also had a rather noticeable delay when launching atuin. As it turns out, this was because it checked for an update every time it launched! You can disable that update check: add a ` update_check = false` to your `~/.config/atuin/config.toml` [1]. That made the delay pretty much disappear for me.

[1]: https://atuin.sh/docs/config/#update_check


What? I don't expect any tool to interact with the network if it's not made specifically for this (curl, netcat, etc). This would betray my expectations, I find it unacceptable.


It's one of our key features

> backup and sync encrypted shell history

But it's up to you. You can disable any sync features by installing with `--no-default-features --features client` set. Your application won't have any networking features built into the binary then


We actually fixed the delay issue, but since you disabled update checking you wouldn't have known to update!

It was quite annoying so we're sorry for that


Oh, it's nice you fixed it, thanks! And don't worry, I updated atuin, as it's in my distro's repository (which is why I wasn't worried about disabling the update check).


How would you compare this to, say, McFly? https://github.com/cantino/mcfly


Intrigued by local-directory-first feature of McFly (It brings up commands you previously executed in that folder first). I tried it for a bit. But there was noticeable lag compared to FZF and also the UI was a bit shaky.

Went back to FZF (in Zsh).

I have a seven year zsh history. That may be a contributing factor for the issues ?


Not too different.

* We use heuristic based searches whereas mcfly trains a neural network * We offer a sync functionality to share history on multiple machines

mcfly is a great project, although they are looking for new maintainers apparently!


I noticed that before and am glad to see it fixed. My current issue is that typing to search is noticeably slow on a 150,000 entry history, especially for the first few characters. fzf is instant for me.


Yeah we accidentally had this blocking :/ It does only check once an hour though, and can totally be disabled!

We introduced this as we found a lot of people reporting bugs that had already been fixed + they just needed to update, or users on the sync server that were >1yr behind on updates (making improvements really difficult to introduce).


Same, I enjoyed atuin but found myself missing fzf's fuzzy search experience so I ported fzf's own ctrl-r zsh widget to read from atuin instead of the shell's history to solve this. Best of both worlds imo, you get fzf's fuzzy search experience and speed with atuin's shell history management and syncing functionality.

Zsh snippet below in case it's helpful to anybody. With this in your .zshrc ctrl-r will search your shell history with fzf+atuin and ctrl-e will bring up atuin's own fuzzy finder in case you still want it.

It only searches the last 5000 entries of your atuin history for speed, but you can tweak ATUIN_LIMIT to your desired value if that's not optimal.

    atuin-setup() {
        if ! which atuin &> /dev/null; then return 1; fi
        bindkey '^E' _atuin_search_widget

        export ATUIN_NOBIND="true"
        eval "$(atuin init "$CUR_SHELL")"
        fzf-atuin-history-widget() {
            local selected num
            setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2>/dev/null

            # local atuin_opts="--cmd-only --limit ${ATUIN_LIMIT:-5000}"
            local atuin_opts="--cmd-only"
            local fzf_opts=(
                --height=${FZF_TMUX_HEIGHT:-80%}
                --tac
                "-n2..,.."
                --tiebreak=index
                "--query=${LBUFFER}"
                "+m"
                "--bind=ctrl-d:reload(atuin search $atuin_opts -c $PWD),ctrl-r:reload(atuin search $atuin_opts)"
            )

            selected=$(
                eval "atuin search ${atuin_opts}" |
                    fzf "${fzf_opts[@]}"
            )
            local ret=$?
            if [ -n "$selected" ]; then
                # the += lets it insert at current pos instead of replacing
                LBUFFER+="${selected}"
            fi
            zle reset-prompt
            return $ret
        }
        zle -N fzf-atuin-history-widget
        bindkey '^R' fzf-atuin-history-widget
    }
    atuin-setup


Thanks, just needed to set `CUR_SHELL=zsh` to make it work. Also `brew install atuin fzf`


As I put in a child reply, that delay should be fixed.

But if you can't get past the double-enter, then I understand.

I think there was some work to fix that, I'll check up on it. Thanks for the reminder


Thanks Conrad! That's really a huge game changer.

I'm now using atuin for shell history and fzf for fuzzy completion[0], works awesome! As Shell I use zsh with some plugins managed via antigen on my Linux Mint default terminal.

[0]: https://github.com/junegunn/fzf#fuzzy-completion-for-bash-an...


Thanks for the atuin reminder, I knew fzf reminded me of a crate I had on my backlog to try out but I completely forgot the name. I should probably just get to it now.



I love fzf because it's so much more than a shell history explorer!


Fuzzy find would have been great with discworld mud


It's not only a zsh thing, works in bash too.

I liked the way he covered just one function though, which at least might be starters for such operations, and are fully operational, and probably caters for better workflows for most, than without fzf.

Funny thing: I try to stop using Ctrl-R from fzf at the moment, and rather use the one that ships with smenu.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: