Hey,
As an avid CLI user, I always aimed to master non-interactive tools to perform most of my work, given that they are easy to use, create, extend, and connect.
However, I found myself dealing with software projects with many files (mostly under the yoke of corporate oppression; an ordeal which I endure to sustain myself, as most of those reading me do, and therefore I will not go further into this topic) and started to hit the limits of non-interactive tools to find and edit files. Indeed, I could go faster if I followed the temptation of monstrous IDEs, as I did in my innocent past.
I did not despair, as naturally I heard of the usefulness of interactive fuzzy finders such as fzf. After spending an afternoon evaluating the tool, I concluded that it indeed increases the complexity of my workflow. Still, this complexity is managed in a sensible way that follows the UNIX tradition.
I now ask you two general questions:
- Did you reach similar conclusions to me and decide to use interactive fuzzy finders to solve working on software projects with many files?
- If you use fzf or similar tools, what can you tell me about your workflow? Any other third-party tools? Do you integrate it into your scripts? Any advice that you can give me out of a long time of experience using the tool that is not easily conveyed by the documentation?
I also ask this very specific question:
- The one part of fzf which I found missing was a way to interact with the results of grep, and to automatically place the selected file(s) in the prompt or an editor. For that, I created the following two commands. Do you have a similar workflow when you want to bring the speed of fuzzy finding to grep?
#! /usr/bin/env bash
# gf: grep + fzf
# basically a wrapper for 'grep <ARGS> | fzf | cut -f 1 -d:'
# print usage on -h/--help
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
echo "Usage: gf <grep-args>"
echo
echo "~~~ that feel when no 'gf' ~~~"
echo
echo "- Basically a wrapper for 'grep <ARGS> | fzf | cut -f 1 -d:'"
echo "- Opens fzf with grep results, and prints the selected filename(s)"
echo "- Note: As this is meant to search files, it already adds the -r flag"
echo
echo "Example:"
echo " $ nvim \`gf foobar\`"
echo " $ gf foobar | xargs nvim"
exit 0
fi
# run grep with arguments, pipe to fzf, and print the filename(s) selected
custom_grep () {
grep -E --color=always --binary-files=without-match --recursive "$@"
}
remove_color () {
sed -E 's/\x1b\[[0-9;]*[mK]//g'
}
custom_fzf () {
fzf --ansi --height ~98%
}
grep_output=$(custom_grep "$@")
if [[ "$?" -ne 0 ]]; then
exit 1
else
echo "$grep_output" | custom_fzf | remove_color | cut -f 1 -d:
fi
#! /usr/bin/env bash
# ge: grep + fzf + editor
# basically a wrapper for 'grep <ARGS> | fzf | cut -f 1 -d: | $EDITOR'
# print usage on -h/--help
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
echo "Usage: ge <grep-args>"
echo
echo "- Basically a wrapper for 'grep <ARGS> | fzf | cut -f 1 -d: | \$EDITOR'"
echo "- Opens fzf with grep results, and edits the selected file(s)"
echo "- Note: As this is meant to search files, it already adds the -r flag"
echo "- Note: Internally, it uses the 'gf' command"
echo
echo "Example:"
echo " $ ge foobar"
exit 0
fi
# takes output from 'gf' and opens it in $EDITOR
grep_fzf_output=$(gf "$@")
if [[ -n "$grep_fzf_output" ]]; then
$EDITOR "$grep_fzf_output"
fi
Have a wonderful day, you CLI cowboys.
I fear M4. The boomers programmed too greedily and too deep, they almost unleashed computational hell upon us.