I'm a recent fish convert (from zsh) and I love it.
The only thing that annoys me is working with Android AOSP requires sourcing a bunch of bash functions that I don't feel like porting to fish so I'm occasionally required to drop into bash whereas with zsh and it's POSIX compatibility I could just source the bash functions and it would work fine. But fish's completions work much better out of the box and they have some useful features like being aware of your history in each directory.
I've been seeing mentions of fzf for some time but this article might make it try it.
Zsh's H-S-MW plugin [1], which provides multi word CTRL+R to search the history + a couple of half-assed tools I wrote [2] seem to cover most of the think I would need fzf for, but maybe fzf would work better or be a useful addition to my toolset. Maybe it could replace those half-assed tools.
So I might aswell ask here: I want to search for a string using ripgrep, select one of the files from the result list using FZF and then open the selected file with VS code.
> rg . | fzf
How do I do this on windows (NOT Linux)??
*Note:* Assume I already have ripgrep, FZF & VS Code installed.
You open Total Commander in that folder, press Alt+F7, put your string into the lower search box and press search. It will give you the list of matching files, with F3 available for quick preview; then you right click the file you need and choose "Open with VS Code" from the context menu.
Sadly, you don't get the "context" (the content of actual matches) out of the box, you'll have to resort to double-tapping F3 while manually going down the file list. That's a downside, I fully admit that.
I appreciate your answer but the whole point is to do everything from the command line. If I need to use another application, I can just open VS Code in the directory and search from there directly.
cut is a part of git for windows. It should be inside "c:\Program Files\Git\usr\bin\" folder. So after adding this folder to your path `rg . | fzf | cut -d ":" -f 1` should work. However I wasn't able to actually use that to open that file in vscode or vim because the application started immediately without waiting to pick a file ...
I use orthodox file managers heavily (mc, FAR, etc). Your approach was my norm for over 20 years. However, fzf is the first tool I've found that far exceeds the file managers in speed of navigation.
Nice. I'm going to dig through these tomorrow. Thanks for posting! The PR review helper looks excellent and I'm excited to try it out. Til about `pandoc` and `glow`.
I whipped up a nice, performant branch picker last night that I'm pretty happy with, hopefully there are some useful tidbits for others. It's similar to your `flog` command but it uses the reflog to find the most recently checked out branches. It filters those which have been deleted using a set structure (well, map of bools), thus requiring BASH 4+. I'll be interested to see the differences in behavior and performance of your approach
Pretty much par for the course, Linux distributions don't do per user configuration of tools beyond appending to PATH or setting some essential environment variables using scripts in in /etc/profile.d/. They will most certainly not mess with login scripts.
Yeah sure, that makes sense. I'm surprised that the .deb doesn't install the stuff from `$upstream/shell` into `/usr/share/fzf` though. That's the sort of thing `/usr/share/$prog` is intended for.
apt install? There's no way I'm integrating a core tool like that with a crude "curl | zsh" hack. How and when would it get updated? Am I expected to stick that in an Ansible playbook?
For an article titled "You've installed fzf. Now what?", I would've expected step 1 to be "how to add the shell hook for your particular shell". Especially since people here are referencing extra integrations that the bundled shell hook doesn't setup.
This is what happens when tooling providers try to do their own packaging. Homebrew, apt, rpm, and other package managers, as well as bash, zsh and other shells, all offer standardized ways to install configuration loader scripts for the user's environment, and to display installer messages that prompt the user to do it - but fzf has a bunch of functionality to go around all that and auto-update itself in place and hack lines into the user's bashrc/zshrc.
Not trying to single out fzf here - there are many other tools that do this - but I find this behavior really sad because it makes me very disinclined to trust the tool with anything. A command-line tool should not be trying to auto-update itself or manipulate dotfiles in the user's home directory. It's dangerous and unexpected.
There’s no real good mechanism for what fzf is trying to do. profile.d might work, but I think that is more intended for environment variables, rather than interactive shell changing scripts.
There’s no standardised way to extend interactive shell configuration without just appending to /etc/bashrc.
The other problem with this is that it is hard to disable. What if you want fzf but without the key bindings? FZF could add a mechanism for this, but it doesn’t fully solve the problem, because the FZF script being added to global configuration will always be run before any user config.
In this specific case, it is a limitation of bash (and probably ZSH as well) that there is no simple package-manger compatible extension mechanism for interactive shell plugins which doesn’t sacrifice user control.
Thanks fore sharing. I was also lost reading this article, because I installed with apt (Debian). After searching for "fzf + Ctrl+R" I found about the keybindings part.
This enables the C-r / M-c / C-t key bindings, but there's also a completion.bash file. This enables the "**" completion trigger, which can contextually complete paths, envvar names or PIDs in commands. (See "Fuzzy completion for bash and zsh" in fzf's readme [1]). Similarly, you can add to your .bashrc:
if [ -e /usr/share/doc/fzf/examples/completion.bash ]; then
source /usr/share/doc/fzf/examples/completion.bash
fi
/usr/share/doc/fzf/README.Debian explains this, as well as the setup for zsh, fish and vim.
You do have to remember to use it, but the thing to keep in mind is that you can pipe a list of ANYTHING into it. Any list of text items you can search through with a text query is fair game.
git log --oneline | fzf
for example is one of my favorite tricks. Instead of scanning by eye or repeatedly grepping to find something, it's a live fuzzy filter. And depending on how deep you want to go you can then add key bindings to check out the selected commit, or preview the full message, or anything really.
3. A command to fuzzily run npm scripts with previews and syntax highlighting. Depends on bat and gojq, but you can sub gojq with jq. It does have a bug where it doesn't handle ":" characters in script keys well, but I'll fix that at some point.
npz() {
local script
script=$(cat package.json | gojq -r '.scripts | keys[] ' | fzf --preview 'cat package.json | gojq -r ".scripts | .$(echo {1})" | bat -l sh --color always --file-name "npm run $(echo {1})" | sed "s/File: /Command: /"') && npm run $(echo "$script")
}
4. A command for rapidly selecting an AWS profile. As a user of AWS SSO with many accounts/roles, this is a life-saver. I combine this with having my prompt show the currently selected role for added value.
alias aws-profile='export AWS_PROFILE=$(sed -n "s/\[profile \(.*\)\]/\1/gp" ~/.aws/config | fzf)'
alias ap="aws-profile"
5. A command for fuzzily finding and tailing an AWS cloudwatch log group. I didn't come up with this one, and I can't remember where I read about it, or I'd attribute it properly.
I just type in a fuzzy match for some of the directories I have visited.
For example, if I know I frequently visit `/users/elahmo/developer/project`, if I type `j pro` I know it will jump there most of the time. If I type `j project`, it will jump 99% of the time. So it is quite good to cycle between things you often open, but of course you can reach things that are in the history it builds.
1. You are running jump for the first time. Have you integrated jump with your
shell? Run the following command for help:
$ jump shell
If you have run the integration, enter a few directories in a new shell to
populate the database.
Are you coming from autojump or z? You can import their existing scoring
databases into jump with:
$ jump import
Doesn't work afaik / Tried all doesn't work how do you set this up @elAhmo
I didn't have to do any manual setup, I used it on ~three machines so far. Maybe something is odd with your shell? Which one do you use?
I have seen other people suggesting https://github.com/wting/autojump too, so it might be worth giving that tool a look, it seems supported a bit better and more actively developed.
Now combine the two: autojump and fzf. Basically look at all the directories in the jump database and pass that to fzf (sorted by frequency). You'll be amazed at what an improvement that is. I've bound it to Alt-j on my shell. I use it a ton more than Alt-c.
We have an IoT command server and connecting to one of the devices (for maintenance, logs or whatever) involved two manual lookups in the output of two commands and then finding your match in both. I was sick of this one day and with some grep, sed, awk and finally fzf, you could just sort of type the device's name and press "enter" to connect.
People's reaction when I showed them was basically WHAT IS THIS MAGIC?!?
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
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 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.
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.
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
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 ?
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).
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
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.
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.
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
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.
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 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.
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?
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.
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?
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.
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.
"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.
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.
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.
> 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.
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.
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.
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.
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!
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.
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.
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.
If anyone who uses i3 needs an fzf application launcher in their lives, adding the following two lines to your config will make $mod+d open it as a floating window in the middle (uses rxvt-unicode):
The default ctrl+r behavior doesn't allow me to scroll up through my history of matches, which is always disappointing. Often it's some random incantation I'm trying to search for that shares a prefix with other more common commands and the default ctrl+r requires me to type out far enough to be unique, which defeats the purpose of history search. Maybe I'm missing some essential behavior that I'm not familiar with.
ctrl+r matches any part of the line, not just the commands / start of the line. I'm often using it on a unique argument I remember last using the command with.
Imagine you have a bunch of different for loops and you want to get the one that ran a specific command. You can use something like "history | grep for | grep command" or you can use fzf. Ctrl-r, type "f o r <space>" then type "c o m m" and you'll quickly narrow down the search results.
It's the fuzziness that really beats ordinary ctrl-r, being able to search on multiple fragments of text is just fantastic.
which will instantly upgrade my search capabilities, if I'm stuck. Which doesn't really happen that much.
I think the main part of my vanilla C-r experience is that I trained myself to remember commands differently. I somehow remember exact char-to-char tokens, like the "/fzf/" substring above. Or for a more extreme example "ose -p d" when I try to find:
docker compose -p devenv exec myservice /bin/sh
Weirdly, I kinda know that if used "se -p d" instead (shorter) it would land me on a wrong command (so, not shorter).
I initially felt the same way and found it cluttered. Though I still left fzf-history around and bound it Ctrl+Alt+R so Ctrl+R could still be the default. In zsh I just did this with `bindkey '^[^R' fzf-history-widget`.
Over time I eventually found myself using Ctrl+Alt+R more and more so I made it the default and now Ctrl+Alt+R is still 'old school' history search for me.
There's a potential well of habit that you have to climb out of before you start getting a benefit. If you don't put in the energy to try it for a while, you'll slide back down into the well.
When I learned what Ctrl-R was originally, by mistake, I was like damn... maybe the majority of shell users just have no idea how to drive bash. No wonder people lose their shit over it, it's like trying to drive a car but you're never told the car can go in reverse and the rear view mirror is just tucked up into the roof!
I don't like the `Ctrl+r` interface. Instead, I use these settings in `.inputrc`. Type the command I want and use arrow keys (I prefer matching from start of the command, but you can match anywhere too).
# use up and down arrow to match search history based on typed starting text
"\e[A": history-search-backward
"\e[B": history-search-forward
# if you prefer to search anywhere in the command
"\e[A":history-substring-search-backward
"\e[B":history-substring-search-forward
Here's a little function that I use pretty often when I want to install a package but I'm not sure what the exact package name is. Give it a keyword and it searches apt-cache and dumps the results into fzf.
function finstall {
PACKAGE_NAME=$(apt-cache search $1 | fzf | cut --delimiter=" " --fields=1)
if [ "$PACKAGE_NAME" ]; then
echo "Installing $PACKAGE_NAME"
sudo apt install $PACKAGE_NAME
fi
}
I have a similar one for Homebrew, with the ability to preview package info and install multiple targets:
# ~/.config/fish/functions/fbi.fish
function fbi -a query -d 'Install Brew package via FZF'
set -f PREVIEW 'HOMEBREW_COLOR=1 brew info {}'
set -f PKGS (brew formulae) (brew casks |sed 's|^|homebrew/cask/|')
set -f INSTALL_PKGS (echo $PKGS \
|sed 's/ /\n/g' \
|fzf --multi --preview=$PREVIEW --query=$query --nth=-1 --with-nth=-2.. --delimiter=/)
if test ! -z "$INSTALL_PKGS"
brew install $INSTALL_PKGS
else
echo "Nothing to install…"
end
end
Obviously only useful for MacOS, but fzf plus spotlight is pretty useful. You can use it to find that lost file that you only remember part of the name!
291 comments
[ 1.3 ms ] story [ 300 ms ] threadIt's one of the few packages that I think genuinely enhance fish versus merely adding a bunch of cruft.
alt+ctrl+f and ctrl+r are indispensable.
The only thing that annoys me is working with Android AOSP requires sourcing a bunch of bash functions that I don't feel like porting to fish so I'm occasionally required to drop into bash whereas with zsh and it's POSIX compatibility I could just source the bash functions and it would work fine. But fish's completions work much better out of the box and they have some useful features like being aware of your history in each directory.
https://github.com/junegunn/fzf/wiki/examples
Zsh's H-S-MW plugin [1], which provides multi word CTRL+R to search the history + a couple of half-assed tools I wrote [2] seem to cover most of the think I would need fzf for, but maybe fzf would work better or be a useful addition to my toolset. Maybe it could replace those half-assed tools.
Of course I intensively use ripgrep.
[1] https://github.com/z-shell/H-S-MW
[2] https://news.ycombinator.com/item?id=34495070
> rg . | fzf
How do I do this on windows (NOT Linux)??
*Note:* Assume I already have ripgrep, FZF & VS Code installed.
In fact, I went and tried the other shortcuts and they worked as well e.g. Alt+C
Didn't know about this all this while and I had fzf installed!
Sadly, you don't get the "context" (the content of actual matches) out of the box, you'll have to resort to double-tapping F3 while manually going down the file list. That's a downside, I fully admit that.
In the article, they provide this:
>rg . | fzf | cut -d ":" -f 1
What would be the easy windows equivalent of
> cut -d ":" -f 1
??
https://xon.sh/
1. flog: go to git branches I had checked out in the past quickly
2. pr: preview and check out PRs I've been assigned to review
I whipped up a nice, performant branch picker last night that I'm pretty happy with, hopefully there are some useful tidbits for others. It's similar to your `flog` command but it uses the reflog to find the most recently checked out branches. It filters those which have been deleted using a set structure (well, map of bools), thus requiring BASH 4+. I'll be interested to see the differences in behavior and performance of your approach
https://gist.github.com/pnovotnak/4dfe9b2867bf6fea60fa94b4c8...
I was exactly in the situation the article describes, I installed it, then, didn't find a use case.
But that's because Ubuntu doesn't come with completion enabled by default.
You have to add in your bashrc:
The fzf and ubuntu docs don't mention you have to.Couldn't find easily how to do it with google, but chatgpt saved the day once again.
Then it would just be (in bash anyway):
https://github.com/dotstrap/ansible-fzf
I don't see why not
Not trying to single out fzf here - there are many other tools that do this - but I find this behavior really sad because it makes me very disinclined to trust the tool with anything. A command-line tool should not be trying to auto-update itself or manipulate dotfiles in the user's home directory. It's dangerous and unexpected.
There’s no standardised way to extend interactive shell configuration without just appending to /etc/bashrc.
The other problem with this is that it is hard to disable. What if you want fzf but without the key bindings? FZF could add a mechanism for this, but it doesn’t fully solve the problem, because the FZF script being added to global configuration will always be run before any user config.
In this specific case, it is a limitation of bash (and probably ZSH as well) that there is no simple package-manger compatible extension mechanism for interactive shell plugins which doesn’t sacrifice user control.
[1]: https://github.com/junegunn/fzf#fuzzy-completion-for-bash-an...
nvim $(rg . --vimgrep | fzf | awk -F: '{print $1, "+" $2+0}')
https://github.com/kbd/setup/blob/master/HOME/.config/git/co...
Perfect example: my "cherry pick" alias:
Those "pick-" aliases pop up fzf to let me choose a branch, then commits to cherry pick. No more copying hashes anywhere.Similarly, my alias for git add lets me fzf-select a list of files to stage based on what "git status" reports.
First, some env variables for setting defaults:
And some neat commands:1. A command for fuzzy jumping between workspaces with tree previews (depends on `tree`):
2. A command to be able to fuzzy search files with previews and syntax highlighting. Depends on bat being installed. 3. A command to fuzzily run npm scripts with previews and syntax highlighting. Depends on bat and gojq, but you can sub gojq with jq. It does have a bug where it doesn't handle ":" characters in script keys well, but I'll fix that at some point. 4. A command for rapidly selecting an AWS profile. As a user of AWS SSO with many accounts/roles, this is a life-saver. I combine this with having my prompt show the currently selected role for added value. 5. A command for fuzzily finding and tailing an AWS cloudwatch log group. I didn't come up with this one, and I can't remember where I read about it, or I'd attribute it properly. I also have a few other commands related using fzf, but they're more bespoke and probably not useful to others.does not do anything useful on my mac m1
j '' '' '' '' ''
For example, if I know I frequently visit `/users/elahmo/developer/project`, if I type `j pro` I know it will jump there most of the time. If I type `j project`, it will jump 99% of the time. So it is quite good to cycle between things you often open, but of course you can reach things that are in the history it builds.
1. You are running jump for the first time. Have you integrated jump with your shell? Run the following command for help:
Doesn't work afaik / Tried all doesn't work how do you set this up @elAhmoI have seen other people suggesting https://github.com/wting/autojump too, so it might be worth giving that tool a look, it seems supported a bit better and more actively developed.
Now combine the two: autojump and fzf. Basically look at all the directories in the jump database and pass that to fzf (sorted by frequency). You'll be amazed at what an improvement that is. I've bound it to Alt-j on my shell. I use it a ton more than Alt-c.
Apparently an option_as_alt option should also be introduced in the next release.
Another possibility is to fix it via eg the terminal emulator - but that doesn't work for global hotkeys like window management with yabai via skhd.
See my comment on lobsters: https://lobste.rs/s/nvoikx/helix_notes#c_m8guuh
People's reaction when I showed them was basically WHAT IS THIS MAGIC?!?
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
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).
[1]: https://atuin.sh/docs/config/#update_check
> 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
It was quite annoying so we're sorry for that
* 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!
Went back to FZF (in Zsh).
I have a seven year zsh history. That may be a contributing factor for the issues ?
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).
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
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.
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.
With the current directory you should be able to get the absolute path from your relative paths
Or maybe I'm just lazy.
Or at least I hope it is. :)
but that isn't sexy somehow. we'll have to settle on 'shag'.
"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."
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:
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.
To wit:
> It says to put those commands in the .bashrc config:
> 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.
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.
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.
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.
https://github.com/oantolin/orderless
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
What do you mean by maintained? There are commits as recent as yesterday on the project: https://github.com/junegunn/fzf
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.
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...
So you don't need to do stuff like
And instead can use fzf from inside the editor.It also supports integrating it with fdfind and ripgrep.
https://github.com/ctrlpvim/ctrlp.vim
I'm perfectly satisfied with the default Ctrl+R functionality, to the point that fzf seemed to add visual clutter without any value.
I guess I was never let down by inverse search.
Context: I'm using Linux and doing SWE and SRE work, and constantly live in the terminal.
So, type: ctrl+r, prefix, and then keep pressing ctrl+r to find everything that matches the prefix.
ctrl+r matches any part of the line, not just the commands / start of the line. I'm often using it on a unique argument I remember last using the command with.
It's the fuzziness that really beats ordinary ctrl-r, being able to search on multiple fragments of text is just fantastic.
But I also remember that I can C-r /fzf/ and it will search back to the command:
which will instantly upgrade my search capabilities, if I'm stuck. Which doesn't really happen that much.I think the main part of my vanilla C-r experience is that I trained myself to remember commands differently. I somehow remember exact char-to-char tokens, like the "/fzf/" substring above. Or for a more extreme example "ose -p d" when I try to find:
Weirdly, I kinda know that if used "se -p d" instead (shorter) it would land me on a wrong command (so, not shorter).Over time I eventually found myself using Ctrl+Alt+R more and more so I made it the default and now Ctrl+Alt+R is still 'old school' history search for me.
https://github.com/Aloxaf/fzf-tab
Install this, get an instant improvement to anything you do on the terminal. It works with any existing program with tab completion.
Something else you can try in your `~/.gitconfig`
I alias `git fza` to `ga` and it gets used a lotOh, and another useful shortcut is this:
Obviously only useful for MacOS, but fzf plus spotlight is pretty useful. You can use it to find that lost file that you only remember part of the name!