[HN Gopher] So you've installed `fzf` - now what? ___________________________________________________________________ So you've installed `fzf` - now what? Author : hiAndrewQuinn Score : 561 points Date : 2023-03-21 16:01 UTC (6 hours ago) (HTM) web link (andrew-quinn.me) (TXT) w3m dump (andrew-quinn.me) | jonfw wrote: | FZF is a great ad-hoc UI. Let's say I want to run an operation | against a cluster- it's way better to use fzf to select clusters | from a list than it is to have to copy/paste a particular cluster | name | tetha wrote: | I recently setup something simple, but I've been falling in love | with it - `goto`. Not as in the funny programming thing, with the | even funnier `comefrom` variant in intercal, but as a simple | shell script. | | My issue is that at work, I tend to work with a lot of projects | and repos, and I work a whole lot in a couple repos. And | honestly, even if its short, typing `cd | ~/Pro<tab>/an<tab>/main_<tab>` becomes old after 2000 times or | more. And then there are ~80 - 90 repos in ~/Projects/terraform, | and a couple dozen legacy repos in ~/Projects/chef, a dozen | different config repos in ~/Projects/config, an automatically | rotating scratchpad in ~/Stuff, ... I don't know if it's a messy | workstation, or I'm just dealing with a boatload of stuff. | | That's why I wrote goto. goto works in 2ish phases. The first | phase just uses fzf -1 to give me a selection of the broad | strokes I tend to navigate to. In case there is a prettier way to | make fzf give me a static list of choices, let me know. It's | basically: DESTINATION=$( echo | "ansible\nterraform\nchef\nconfigs\n..." | fzf -1 "$1" ) | | This way I can either launch goto to get a list of 6-7 things I | can select with arrows, by typing, or I can just be like `goto | tf` and it directly selects `terraform`. | | After that, it's a big switch-case selecting where to `cd` to, as | well as possibly doing some normal init things. `ansible` as a | destination for example just CDs and that's it. | | `terraform` on the other hand does a bit more: | case terraform) DESTINATION2=$( ls | ~/Projects/terraform | fzf -1 "$2" ) cd | "$DESTINATION2" git pull --rebase # more | stuff ;; | | This way I can either say `goto`, select `terraform`, select a | project and get moved there. Or I go `goto terraform` and type | `prj2 foo` and usually fzf gives me the right thing, or I can be | like `goto tf 'p2 fo'` and it drops me into the right place. Or | something like `goto config infra-logaggregation` (or rather, | `goto c ilg`). Or `goto stuff ticket-id` to get into some older | scratchpad. | | I'll just have to consider if I want to stick with ohmyzshs alias | of g == git, which I don't really use much. Then I could achieve | the entirely readable `g c ilg` to go where I need to, hah. | | All of this is then wrapped into an alias, which basically | aliases `goto` to be `source ~/goto`. | | IDK, thanks for listening to my TED-talk on how to use fzf to | juggle way too many hats at once. It's just saved me a lot of | keystrokes getting around and mashing incomprehensible spells | into the shell so coworkers are confused is always fun. | bilalq wrote: | I love how people share their fzf scripts whenever a new post | comes along. I'll share some of my own. | | First, some env variables for setting defaults: | export FZF_DEFAULT_COMMAND='fd --type f --hidden --exclude .git' | export FZF_DEFAULT_OPTS='--layout=reverse --inline-info' | export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" | | And some neat commands: | | 1. A command for fuzzy jumping between workspaces with tree | previews (depends on `tree`): export | WORKSPACE_ROOT="$HOME/whatever-your-root-is" ws() { | cd "$WORKSPACE_ROOT/`ls -a $WORKSPACE_ROOT | fgrep -v .DS_Store | | fzf --preview '(cd $WORKSPACE_ROOT/{1}; pwd; tree -C -L 1 -I | node_modules -I .DS_Store)'`" } | | 2. A command to be able to fuzzy search files with previews and | syntax highlighting. Depends on bat being installed. | alias fzp="fzf --preview 'bat --style=numbers --color=always | --line-range :500 {}' --border --height='80%'" | | 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. | awslogs() { export AWS_PROFILE=$(cat ~/.aws/config | | awk '/^\[profile /{print $2}' | tr -d ']' | fzf) local | log_group=$(aws logs describe-log-groups | gojq -r | '.logGroups[].logGroupName' | fzf) aws logs tail | "$log_group" --since 3h --follow --format=short } | | I also have a few other commands related using fzf, but they're | more bespoke and probably not useful to others. | bloopernova wrote: | That AWS logs one is fantastic. | campground wrote: | 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 } | sigmonsays wrote: | I havn't seen it mentioned yet, you can also do fuzzy completion | like cd * <tab> | | After pressing <tab> you get sent into fzf to make the decision | | This works for ssh too | hiAndrewQuinn wrote: | Crap, I forgot to include the whole *<TAB> thing! Man, good | catch. | Grimm665 wrote: | Did not know that worked for ssh, nice! | EamonnMR wrote: | I use fzf for all of my searching needs, especially on Mac where | the default search is hot garbage. | bloopernova wrote: | I have ctrl-r and alt-c assigned to macro keys on my keyboard, | they're so danged useful. | | Something else you can try in your `~/.gitconfig` | [alias] fza = "!git ls-files -m -o --exclude-standard | | fzf -m --print0 | xargs -0 git add" git fza will | quickly let you add files if you've changed a lot. | | I alias `git fza` to `ga` and it gets used _a lot_ | | Oh, and another useful shortcut is this: export | FZF_CTRL_T_COMMAND="mdfind -onlyin . -name ." | | 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! | andelink wrote: | I'm not super familiar with spotlight/mdfind. What are the | benefits it offers over using the default `find` command with | fzf? | pi-rat wrote: | `find` has to traverse the filesystem, which is pretty slow. | `mdfind` looks up in an indexed database, which is very fast. | andelink wrote: | Good to know! Thanks | dandanua wrote: | I've made a simple tagging solution based on fzf and don't know | how to live without it anymore. | | You just name your folders and subfolders by tags. And then | search it via fzf (I prefer the exact search) launched by a | hotkey. | | To exclude a subfolder from the global search I use a trick. You | add the stop symbol " #" at the end of the subfolder name. A | custom fzf configuration (see below) then excludes what's the | inside. Though, you still can cd into the excluded folder and | make fzf search in it. So, in fact it gives you an hierarchy of | tagged folders with stop symbols. This helps to avoid search | pollution and unnecessary disk reads: export | FZF_DEFAULT_COMMAND="fd -E=**/*#/**" | | I also use hotkeys to open items in default programs and to | preview files in fzf UI: export | FZF_DEFAULT_OPTS="--exact \ --bind 'ctrl-/:execute- | silent(xdg-open {} &)' \ --bind 'ctrl-p:toggle-preview'" | | Of course, it still requires a strong discipline to tag | everything appropriately. But the profit is immense - you can | find everything you remember and open it in the default program | in a matter of seconds. | wetpaws wrote: | Just spend entire morning setting fzf and this is lifechanging. | agumonkey wrote: | dont forget ` -m` for multiselect ;) | synergy20 wrote: | with rg I rarely need fzf in practice, I would say for every | 10,000 rg usage I need fzf once | effnorwood wrote: | [dead] | vcdimension wrote: | I wrote a couple of shell tools based on fzf: | | https://github.com/vapniks/fzfrepl: Edit commands/pipelines with | fzf, and view live output while editing. There's a cool example | using ffmpeg, graph2dot & graph-easy for displaying ffmpeg filter | graphs. | | https://github.com/vapniks/fzf-tool-launcher: Browse & preview | contents of files, and launch tools/pipelines to process selected | files. You can use fzfrepl in sequence to process each part of a | dataprocessing pipeline with different tools. | waynesonfire wrote: | have no need for this, plenty fast without it. these two have | been sufficient for all my needs: | | ctrl + r for most things | | history | grep for searching when i forget the exact command or | want to see related commands. | | I don't want pull downs, pull ups, drop downs, expanded hamburger | menu, hot dogs, another set of key strokes to remember how i | started some service last month. | csdvrx wrote: | > I don't want pull downs, pull ups, drop downs, expanded | hamburger menu, hot dogs, another set of key strokes to | remember how i started some service last month | | You seem to be stuck in your ways, so that even when new better | alternatives are created, you dismiss them unceremoniously, | possibly without having taken the time to evaluate them. | | It's something I've noticed with quite a few linux users, and I | find that super interesting! | | May I ask what's your age range? (just curious) | | Do you think the time spend in an exploratory phase for new | tools (ex: getting familiar with fzy) would not be recovered by | time gains in the exploitation phase? Or is it because of a | fear of the unknown, or a belief that old habits may be hard to | change? | | It's a very serious question BTW, I hope it's not too personal | joemi wrote: | Maybe I'm just getting old, but I found most of the animations in | this article to go too fast. I couldn't tell what was happening, | couldn't tell what I was supposed to be looking at. | grimgrin wrote: | okay ignore everything you saw and just conceptualize: | | 1) list of text 2) input to filter the list down. see: list | gets tinier | kbd wrote: | To show off the power of fzf, I should share my fzr ("fzf repl") | script: | | https://github.com/kbd/setup/blob/master/HOME/bin/fzr | | Basically, prefix any jq command (or rg, or anything you can | think of) with fzr and it'll give you an interactive interpreter | for your query. People have written a number of dedicated jq | interactive repls, but not much is needed beyond fzf. | leo-mednet wrote: | If you are like me and cannot get any of these goodies working in | zsh on Mac OS, do this: | | $(brew --prefix)/opt/fzf/install | | assuming you've installed fzf with brew. | shmerl wrote: | fzf lua is a cool plugin for neovim: | https://github.com/ibhagwan/fzf-lua | | So you don't need to do stuff like vi $(find . | '/' | fzf) | | And instead can use fzf from inside the editor. | | It also supports integrating it with fdfind and ripgrep. | elAhmo wrote: | jump (https://github.com/gsamokovarov/jump) is something I use as | I didn't know about Alt-C. Highly recommended | noloblo wrote: | Jump's database is empty. This could mean: | | 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 | BeetleB wrote: | I use autojump (very similar). | | 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. | rocketbop wrote: | I'm exactly in the same boat, after using both programs for | years. Now I wonder if I can or should unlearn my j muscle | memory. | noloblo wrote: | how does it work, where do you use it | | does not do anything useful on my mac m1 | | j '' '' '' '' '' | spearman wrote: | Thanks for this. I didn't know about the built-in-cd. For anyone | on macOS trying to get Alt-C to work see | https://github.com/junegunn/fzf/issues/164. | trufas wrote: | If any other alacritty on macos users were looking for a | workaround: | https://github.com/alacritty/alacritty/issues/93#issuecommen... | | Apparently an option_as_alt option should also be introduced in | the next release. | baq wrote: | TL;DR - Esc+C works (yes you read that right, Esc+C) | ww520 wrote: | Quick question. How do you set up the key bindings for the | command prompt window on Windows? The control-r, alt-c, etc. | BeetleB wrote: | I use xonsh on Windows, and set up the keybindings there. It, | frankly, is messy to do so in xonsh. | thunderbong wrote: | In my PowerShell profile I have the following - | Remove-PSReadlineKeyHandler 'Ctrl+r' Remove- | PSReadlineKeyHandler 'Ctrl+t' Import-Module PSFzf | | All other shortcuts worked out of the box! | endorphine wrote: | Am I the only one that tried fzf as a replacement to the default | Ctrl+R behavior, then switched back? | | 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. | bloopernova wrote: | 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. | andelink wrote: | 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. | babuskov wrote: | I don't know if the version I have is somewhat special, but I | can simply keep pressing ctrl+r to search "up" for the next | match. | | So, type: ctrl+r, prefix, and then keep pressing ctrl+r to | find everything that matches the prefix. | kubanczyk wrote: | Not a hard choice. So far I stick to the vanilla C-r, same as | you. | | But I also remember that I can C-r /fzf/ and it will search | back to the command: source | /usr/share/doc/fzf/examples/key-bindings.bash | | 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). | jnsaff2 wrote: | For me (in a similar role to you) Ctrl+R is the main reason of | having fzf. Quality of Life improvement is immense. | jrm4 wrote: | I don't think this article goes far enough into what a game- | changer fzf can be. | | Combined with some clever "preview" functions, and a pop-up | terminal function (which, that part is admittedly harder than it | ought to be) it can be an across the board a better _general | purpose_ script menu creator than most command line AND GUI | tools, namely due to | | - instant previews AND | | - the ability to either arrow up and down OR fuzzy type what you | want. | | For me, it renders, e.g. "select in" and "case" functions in Bash | completely obsolete. At any time, if I want quick selection of | anything that can be a list, my first thought is, can I do this | with fzf? | rakoo wrote: | I have ~200 lines of scripts that use fzf and mblaze | (https://github.com/leahneukirchen/mblaze) as the ui for my | very own mua. It's all Unixy and lovely. I should write a page | about that | grimgrin wrote: | agreed. preview rips | | i was confused how to adjust the width and figured it out, | here's where i asked, learned, and shared my figlet script | | fzfont | | https://github.com/junegunn/fzf/discussions/3211 | | https://asciinema.org/a/grALSk2M1tkVPiiyrAGCbdX5J (without | width adjustment iirc) | wanderingmind wrote: | The article talks about rg (ripgrep) but not rga (ripgrepall)[1] | which extends rg to other file types like pdf, tar, zip. The rga | website provides a function on integrating it with fzf[2] to | interactively search documents from terminal. | | [1] https://github.com/phiresky/ripgrep-all | | [2] https://github.com/phiresky/ripgrep- | all/blob/master/doc/rga-... | E39M5S62 wrote: | fzf is fantastic. We use it to generate the entire interface of | ZFSBootMenu - | https://docs.zfsbootmenu.org/en/latest/_images/v2.1.0-multi-... . | It's leagues ahead of any other fuzzy finder in terms of | scripting and layout capabilities. | enriquto wrote: | The interface is really cool. But is it possible to globally set | the default "fuzziness" to zero? I'd like to get only exact | matches in all circumstances. | spapas82 wrote: | > And I found myself asking: Where the heck is nginx.conf? | | The author lists some ways but misses the _standard_ Unix way: | simply use locate https://en.m.wikipedia.org/wiki/Locate_(Unix) | | Using locate maybe piped to grep is good enough for all my | finding needs | gregopet wrote: | 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?!? | jon-wood wrote: | This is fantastic - I'm in a similar situation, and just threw | together a quick FZF incantation to look up a device's ID for | use in other commands. | atemerev wrote: | So, just like what fish shell gives out of the box :) | streb-lo wrote: | 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. | wkdneidbwf wrote: | i love and daily-drive fish, but i don't think fish does | everything fzf does. did you stop reading the article at | ctrl-r? | mattgreenrocks wrote: | I like this: https://github.com/PatrickF1/fzf.fish | | It's one of the few packages that I think genuinely enhance | fish versus merely adding a bunch of cruft. | spyremeown wrote: | Alright, you convinced me. Damn great article! | BeetleB wrote: | Other uses for fzf: | | - Combine it with autojump[1] and quickly navigate to any | directory you've navigated to before (sorted by frequency). This | is crazy helpful. | | - Use it for git branch names | | - Use it for ssh locations | | [1] https://github.com/wting/autojump | wetpaws wrote: | how do I use it with autojump? | BeetleB wrote: | autojump -s gets you the entries in the database. | | You have to parse it to extract the directories without all | the metadata it spits out. | | Then you probably need to write a shell function in your | preferred shell to tie the pieces together, as well as assign | it to a keybinding. It's not too hard. | | I use xonsh for my shell, so my config probably won't help. | And doing it in xonsh is probably a lot messier than doing it | in Bash. | jpe90 wrote: | if anyone is interested, here's a blog post about using fzf's | file preview feature to preview grep results: | https://jeskin.net/blog/grep-fzf-clp/ | rjzzleep wrote: | fzf actually has a huge list of functions for the shell to use on | their wiki | | https://github.com/junegunn/fzf/wiki/examples | m47h4r wrote: | I had no idea about alt+c, that's a game changer for me. great | intro. | [deleted] | ursuscamp wrote: | I've been using fzf for a long time, but I didn't even know about | Ctrl-R. Since I use fish, I've been used to just typing some | random part of an old command, then hitting the Up key to cycle | through old commands with that snippet. I'm going to have to give | this a real shot. | jraph wrote: | 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. | | Of course I intensively use ripgrep. | | [1] https://github.com/z-shell/H-S-MW | | [2] https://news.ycombinator.com/item?id=34495070 | ryanbigg wrote: | I also like a Ctrl+T for finding a file in the current directory. | | For example: bundle exec rspec <Ctrl+T> | grimgrin wrote: | i use it a lot but want an accompanying binding just for | directories | | edit: okay done | | http://i.imgur.com/n12DYUu.png | | Two examples in case you have a preference w/ or w/o the | preview: fzf_insert_directory_preview() { | local dir dir=$(find . -type d -not -path '*/\.*' | | fzf --height 40% --reverse --preview 'tree -C {} | head -200') | if [[ -n $dir ]]; then | READLINE_LINE="${READLINE_LINE}${dir}" | READLINE_POINT=$((${#READLINE_LINE})) fi } | fzf_insert_directory() { local dir | dir=$(find . -type d -not -path '*/\.*' | fzf --height 40% | --reverse) if [[ -n $dir ]]; then | READLINE_LINE="${READLINE_LINE}${dir}" | READLINE_POINT=$((${#READLINE_LINE})) fi } | bind -x '"\ey": fzf_insert_directory_preview' # alt-y | bind -x '"\et": fzf_insert_directory' # alt-t | | http://ix.io/4rtn/sh | | Sent from a LLM | 1-more wrote: | Two things I use fuzzy finder for: | | 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 | flog () { branch="$( git branch | --sort=-committerdate --format="%(committerdate:relative)%09%(ref | name:short)%09%(subject)" \ | column -ts $'\t' \ | | fzf \ | sed 's/.*ago \+\([^ ]*\) .*/\1/' | )" git co $branch || ( echo -n "git co | $branch" | pbcopy ) } errcho() { | echo "$@" 1>&2 } jq_query=$(cat <<- EOF | map( { key: "\(.number)" , value: | { line: "\(.number):\(if .isDraft then "" else " " | end):\(.author.login):\(.title):\(.headRefName)" | , body: "# \(.number): \(.title) ## \(.headRefName) | \(.body)" } } ) | | from_entries EOF ) pr () { | local gh_user=${1:-} if [ -z "$gh_user" ]; | then gh_user="@me" fi | tmpFile=$(mktemp /tmp/prs-XXXXXX.json) cleanup | () { rm "$tmpFile" } | trap cleanup EXIT gh pr list -S "review- | requested:${gh_user}" \ --json | number,title,headRefName,body,author,isDraft \ | jq -r | "$jq_query" > "$tmpFile" preview_command="\ | jq -r '.[\"{1}\"].body' $tmpFile \ | pandoc -f gfm -t | markdown \ | glow -s light - " | pr_number=$( jq -r \ 'to_entries | | map(.value.line) | join(" ")' \ "$tmpFile" | \ | column -t -s: \ | fzf | \ --ansi \ | --delimiter=' ' \ | --preview="$preview_command" \ --preview- | window=up:80% \ | grep -o '^[0-9]\+' ) | if [ -n "$pr_number" ]; then errcho "checking out | #$pr_number" gh pr checkout "$pr_number" && gh pr | view --web "$pr_number" && git pull || echo -e "gh pr checkout | $pr_number && gh pr view --web $pr_number && git pull" | else errcho "canceled" fi } | phforms wrote: | I really like the suggested command `<my editor> $(fzf)` to | quickly open files in <my editor> relative to the directory I am | in. However, when I abort the fuzzy find with esc, it still opens | <my editor> without a file input, which is not what I want, so I | wrote a little script for my shell config to prevent this: | fuzz() { file=$(fzf) if [ ${#file} -gt 0 ]; then | nvim "$file" # or any editor you prefer else : | fi } | hiAndrewQuinn wrote: | I hope this article along with this comment serves as a gateway | drug for people to realize fzf is also really useful in | injecting some interactivity into their shell scripts. It | _feels_ different to write scripts which call down fzf from the | heavens for a split second. | phforms wrote: | I am very new to shell scripting and as I wrote the script, I | actually just realized that I can plug anything into fzf that | is split into lines of text and that I can use the selected | output for further processing, since it's just text. | | I just love how simple it is to stick anything together via | the universal plain text interface in the shell and even pipe | this text/dataflow through interactive tools like fzf, as you | just mentioned. | _dain_ wrote: | For me the killer feature is fuzzy tab completion. | | 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. | MayeulC wrote: | Interesting, I'm of the first kind, who uninstalled it quickly. | | I use ctrl-r a lot, though I have no issue remembering exact | portions of the commands, but that may just be me. | | I'll give it another try. | | In the same vein as ripgrep (rg), I recommand the author (and | everybody else) to give fd-find (fd) a try as a replacement to | find. It's much, much faster (multithreaded search), and has | better defaults to use from the shell (doesn't complain about | these permissions issues, and `fd abc` is equivalent to `find. | -iname ' _abc_ '`. | | A few comments here mention it already, but I wanted to recommend | it. | vonseel wrote: | I loveeee fd! About the only time I reach for find is if I need | to do something with printf. | | I've noticed a bunch of CLI tools recently released written in | rust that are along this same line of being snappy and well- | written. Fclones, ripgrep, paru, fd, exa, to name a few. This | probably has more to do with the type of developers the rust | platform attracts, rather than the language itself (many | awesome tools have been written in go recently as well). But | yea, devs who have an interest in Linux and command line tools | tend to be great IMO :) | djcannabiz wrote: | That blew my mind, thanks so much for sharing | lumb63 wrote: | I've never used fzf before and live in a shell all day, but the | capabilities shown in the article doesn't seem very useful to me. | Am I missing something? | | For Ctrl+R, how many times are people running similar variants of | commands that they 1) don't know what they typed and 2) didn't | think to simplify their workflow to not be running duplicated | commands? | | For Alt+C, are peoples' file and directory layouts such a mess | that they need to search entire directory trees to find what | they're looking for? | | I'm confused. | wahnfrieden wrote: | it's simple: search can be a better interface than manual | tagging and organizing | BeetleB wrote: | Regarding Ctrl+R: Forget fzf for a moment and ask if you _ever_ | use it or some similar history command. If you do, then fzf is | automatically a better interface than the default one. | | If you don't, then yes, I use it all the time to find the exact | command I typed in a few weeks ago. I'm not going to memorize | all the options I passed in, etc. | | For Alt+C: Useful even if you organize things very well. I'm in | my home directory. I have | /home/me/media/video/youtube/channel_name. I want to go in | there. That's a lot of typing (even with Tab autocompletion). | When I can just press Alt+C and type perhaps 4 characters of | the channel name and I'm instantly in that directory. Do this | 100 times over for different directories and the benefits | become obvious. In the past I would put convenient symlinks to | get to deeper directories quickly, and I now realize that | approach is just a hack due to a poor navigation interface. | Timpy wrote: | > For Alt+C, are peoples' file and directory layouts such a | mess that they need to search entire directory trees to find | what they're looking for? | | Have you ever joined a new project? Usually they're both messy | and you don't know where anything is. | | Besides, even now with plenty of familiarity in my current | legacy code base I can use fzf to type filenames or directories | without typing the full path. | | Ctrl+R is great for those repeat commands in your shell history | that you want to use right now but don't want to add to your | .bashrc, like repeatedly running a script with some arguments. | I think the value of searching your history is self evident. | mrguyorama wrote: | >Have you ever joined a new project? | | Shouldn't your new team members work to help onboard you | instead? Shouldn't you get ample training in your job? | csdvrx wrote: | You dropped your /s | vlunkr wrote: | For Ctrl+R, suppose you ran 'curl' against a bunch of API | endpoints on a single domain name 2 months ago. I can now | easily find one without knowing too much detail by fuzzy | searching curl+part_of_domain_name+part_of_path. | | For Alt+C, yes files and directories are often a huge mess. It | may be no fault of your own. Maybe you're working with a giant | legacy codebase or digging into node_modules. Now you can type | 'vim Alt+C', to find and immediately open whatever you're | looking for. | | Of course this can all be done other ways, but it's very | convenient and very fast when paired with ripgrep especially. | spapas82 wrote: | I usually do a `history | grep something | grep | somethingelse` to find stuff in my history | Topgamer7 wrote: | I use Ctrl+R profusely. I don't like hitting up to cycle | through recent commands. | | Also sometimes I want to run something I haven't run in several | days. | akira2501 wrote: | Not often, and when that does happen a 'grep .histfile' seems | more than adequate for finding these one off's. | | Likewise, if you get your directory layout rationalized, good | tab completion and disambiguation feels like all you would | need. | agumonkey wrote: | fuzzy matching is honestly vastly superior to any sequential | search, the few times where the match is incorrect still feels | a better time investment as a user | dharmab wrote: | I use Ctrl+R instead of hitting my up arrow key until I find a | command I want to reuse. | gajus wrote: | How is fzf different from hstr? | itchynosedev wrote: | You can also go to the specific line you pick from fzf search | | nvim $(rg . --vimgrep | fzf | awk -F: '{print $1, "+" $2+0}') | mrzool wrote: | I loved this article since I was one of those who installed fzf, | didn't get it, and walked away (at least twice). | conradludgate wrote: | 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 | noroot wrote: | 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). | psYchotic wrote: | 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 | MayeulC wrote: | 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. | conradludgate wrote: | 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 | ellieh wrote: | 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). | conradludgate wrote: | 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 | psYchotic wrote: | 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). | pmarreck wrote: | How would you compare this to, say, McFly? | https://github.com/cantino/mcfly | conradludgate wrote: | 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! | reddit_clone wrote: | 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 ? | conradludgate wrote: | 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 | pmarreck wrote: | I'm a fan of McFly https://github.com/cantino/mcfly | tasuki wrote: | I love fzf because it's so much more than a shell history | explorer! | xxxtentachyon wrote: | 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... | drekipus wrote: | Oh wow thank you for this. | CuteDepravity wrote: | 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? | yesenadam wrote: | 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. | noxvilleza wrote: | 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? | larschdk wrote: | 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. | reddit_clone wrote: | 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. | totetsu wrote: | Fuzzy find would have been great with discworld mud | nathanwh wrote: | 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. | reddit_clone wrote: | 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. | sodapopcan wrote: | So scrappy and simple-I love it! | ryanianian wrote: | 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. | asdff wrote: | 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. | darkwater wrote: | 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. | asdff wrote: | 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). | conradludgate wrote: | 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 | nidnogg wrote: | 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. | VoodooJuJu wrote: | Most useful fzf thing for me is this: history | fzf | elAhmo wrote: | This is basically what CTRL-R does | Topgamer7 wrote: | This is exactly what Ctrl+R does. | Orangeair wrote: | Is there a preceding blog post I could read here? Something like, | "So you've just heard of fzf for the first time, what even is | it?" I was kind of surprised that the author doesn't even make a | passing attempt to define or explain it. | petepete wrote: | There isn't, but this one provides a good overview. | | https://www.redhat.com/sysadmin/fzf-linux-fuzzy-finder | | The tl;dr is that it provides terminal fuzzy finding that can | be plugged into just about any task that involves finding | things. | | I use it many times an hour, it's the main way I navigate files | and buffers in nvim, it's how I find files in my projects, it's | how I select sessions in tmux. | | I'd be lost without it. | Orangeair wrote: | Thanks for the link! | calmoo wrote: | fzf is super useful for navigating and switching git branches I | realised today [1] function gbll(){ | local tags branches target branches=$( git | --no-pager branch --sort=-committerdate \ --format="% | (if)%(HEAD)%(then)%(else)%(if:equals=HEAD)%(refname:strip=3)%(the | n)%(else)%1B[0;34;1mbranch%09%1B[m%(refname:short)%(end)%(end)" \ | | sed '/^$/d') || return tags=$( git --no-pager | tag | awk '{print "\x1b[35;1mtag\x1b[m\t" $1}') || return | target=$( (echo "$branches"; echo "$tags") | | fzf --no-hscroll --no-multi -n 2 \ --ansi | --preview="git --no-pager log -150 --pretty=format:%s '..{2}'") | || return git checkout $(awk '{print $2}' <<<"$target" ) | } | | [1]https://github.com/junegunn/fzf/wiki/Examples#git | kbd wrote: | Agree I use fzf _extensively_ in my git aliases: | | https://github.com/kbd/setup/blob/master/HOME/.config/git/co... | | Perfect example: my "cherry pick" alias: cp = | !git pick-branch | xargs git pick-commits | tac | xargs -t git | cherry-pick | | 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. | agilob wrote: | https://github.com/bigH/git-fuzzy | sva_ wrote: | 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): bindsym $mod+d exec --no-startup-id | urxvt -title "fzf-menu-random123" -e bash -c 'i3-dmenu-desktop | --dmenu=fzf' for_window [title="fzf-menu-random123"] | floating enable | guestbest wrote: | I wish we still had Perl one liners since it is installed | everywhere vi and gawk is installed. I've never seen fzf in the | wild. | roomey wrote: | I know, I am so used to ending up on different servers, I am | worried about installing this on my own workstation, and | getting used to it! | | I find myself getting tripped up even with zsh missing. | [deleted] | kelnos wrote: | I'd never heard of fzf before! It looks like there's a lot of | cool stuff you can do with it, but honestly, I think it's worth | it even just to replace the frustrating ctrl+R search in bash, | which I use a lot, but constantly dislike. | | I feel like with a lot of these kinds of tools, if I have to | actually actively use them, I forget that they exist ('z'[0] | ended up being like this for me) and eventually remove them, but | something that directly replaces something I use regularly (but | hate the UX of) is perfect for me. | | Another bit that helps is that I'm not having to learn/remember | something new that I'll only have on my laptop. I'll continue to | ctrl+R and get a nicer experience, but if I'm ssh'ed into some | random box without fzf, ctrl+R will still work, just with a worse | experience. | | [0] https://github.com/rupa/z | strangelove026 wrote: | I've got a couple git aliases that are nice. | | Use tab to select multiple git branches that are deleted when you | hit enter | | alias gbD="git for-each-ref --format='%(refname:short)' | refs/heads | fzf -m | xargs git branch -D" | | Lists git branches and checkouts the selected | | alias gcof="git for-each-ref --format='%(refname:short)' | refs/heads | fzf | xargs git checkout" | mickeyp wrote: | If you're an Emacs user, then why not use Emacs as your fuzzy | finder on the command line. I wrote about this a while back: | | https://www.masteringemacs.org/article/fuzzy-finding-emacs-i... | Yoofie wrote: | 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. | BeetleB wrote: | Use xonsh in Windows (seriously!) | | https://xon.sh/ | thunderbong wrote: | The exact same command worked for me on Windows in PowerShell! | | 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! | Joker_vD wrote: | 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. | BeetleB wrote: | 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. | Yoofie wrote: | 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. | | In the article, they provide this: | | >rg . | fzf | cut -d ":" -f 1 | | What would be the easy windows equivalent of | | > cut -d ":" -f 1 | | ?? | spapas82 wrote: | 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 ... | pdntspa wrote: | > I reviewed my options. I could > Use my half-remembered | knowledge of the FHS to guess around, with trees and greps, or > | Just know and commit it to memory and feel superior to everyone | else, or > Just pipe find . '/' to fzf and start searching. | | Or you could have just typed find / -name nginx.conf | | Maybe an extra 2>/dev/null if you dont want to do it from sudo | hiAndrewQuinn wrote: | Notice in that section I called it within a subshell. If I ran | `vi $(find / -name nginx.conf)`, and there happened to be | multiple files named nginx.conf lying around my system, my | guess is `vi` would try to open all of them as different | buffers, which is not generally what I want. | renewiltord wrote: | I have `,fv` running `nvim $(fzf)` and it's actually a little | annoying because afterwards I can't find the filename that I had | open. I wish there were some way to expand it into my history. | themadsens wrote: | You can: Help for bash 'history -s args': The args are added to | the end of the history list as a single entry | renewiltord wrote: | Thank you. I must find the equivalent zsh command. | BiteCode_dev wrote: | Fantastic article. | | 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: if [ -e | /usr/share/doc/fzf/examples/key-bindings.bash ]; then | source /usr/share/doc/fzf/examples/key-bindings.bash fi | | 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. | AiAi wrote: | 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. | zokier wrote: | Strictly speaking the ubuntu/debian docs do mention it, but | yeah its not super discoverable: https://salsa.debian.org/go- | team/packages/fzf/-/blob/master/... | triyambakam wrote: | The default install script asks if you want to install key | bindings and adds that to your bashrc. How did you install fzf? | sickmartian wrote: | Not parent but on pop-os, using sudo apt install zfz I got | the same behavior, had to add it myself to .bashrc | acka wrote: | 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. | sophacles wrote: | 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_. | | Then it would just be (in bash anyway): | source /usr/share/fzf/keybindings.bash | Steltek wrote: | 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? | turboponyy wrote: | A shoutout to home-manager, where it's just | programs.fzf.enableBashIntegration = true; | tough wrote: | https://github.com/gantsign/ansible-role-oh-my-zsh | | https://github.com/dotstrap/ansible-fzf | | I don't see why not | stevenhuang wrote: | Yes. It's a shell hook, it's expected for you to add it to | your bash/zsh .rc yourself. How else can it work? | 5e92cb50239222b wrote: | Packages can place init scripts into /etc/profile.d and | those get autoloaded by shells. | Steltek wrote: | 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. ___________________________________________________________________ (page generated 2023-03-21 23:00 UTC)