I'm not trying to troll you or be annoying or get off my lawn kinda thing right, but seriously, what the fuck is the point of oh-my-zsh?
I still use ksh these days (actually, the openbsd version, even on linux) and it behaves EXACTLY the same way as a bash shell to the uninitiated (ctrl+r, fc -l, etc etc etc)..
I have some little shell functions that I use for things, like 'git_branch()' which I use with some aliases (I have >200 shell aliases)..
ZSH has a fucking ftp client in it right? And it still just behaves like bash? What does it do on top? Am I missing something? :}
> I have some little shell functions that I use for things, like 'git_branch()' which I use with some aliases (I have >200 shell aliases)..
I think you may have just answered your own question -- it includes ready-made shell themes and plugins. Not everyone wants to work that hard (including me!).
For me, the few plugins I use have really good/sane defaults so any configuration is minimal (can't even remember configuring any of them, tbh, lol). Mostly I use oh-my-zsh not to improve zsh itself [besides the aussiegeek theme :^)], but to make zsh work more harmoniously with other programs - tmux, git, rg, etc.
Have started using kubectl lately, and would be interested to know how you use fzf. I’m finding I have to do a lot to copying and pasting of pod names in between commands.
You can do a fair amount of stuff with k9s, which is a nice tool.
But if you need to to do something more specialized you can pipe the output of a kubectl command into fzf and then use the ‘describe’ sub command on the selected item returned by fzf. Basically when you need to interact in someway then run a command on the output fzf can be great.
I think you have to really love the idea of creating an app/script or hot key for a work flow to really start to enjoy using 'fzf'. And for most, I get it, it's "Where to start? Ugh, looks like work."
For those that haven't tried yet, and want an entry point, I'd highly recommend you play around with the 'fzf' key bindings and completion scripts for zsh[0] to see what's possible. A little app of mine[1] also has an example of what one might call the minimal viable hot key script for you (note: for skim or 'sk', a 'fzf' Rust clone).
For me the key to using fzf has been remembering that you can pipe ANYTHING into it. For example, grovelling though a git repo with grep might take multiple tries and careful refinement of search patterns. Or you can
git log --oneline | fzf
and interactively fuzz your way to the commit you're looking for. Having the ability to just update live with backspace when the search isn't matching makes a tremendous difference.
Once I installed fzf.fish[0], my command line experience was radically changed for the better. The goodness of fish’s command line with search ability from fzf and seeing context from bat. Great for searching your history, commit hashes, variable names, and just about everything else.
I have been really inspired by 'fzf' recently. Wrote a fun little ZFS utility[0] which I intended to just script with 'fzf', but have since found skim[1], or 'sk', and now use it both as my sole fuzzy finder app (because it's supposed to be interactive and it's faster!), and as a library for my little utility.
I like them both for making fun zsh key bindings, so, so easy.
That's a good question. I'd be interested in any benchmark you saw. And although it seems like sk has come a long way since 2020[0], it may still be slower reading in a larger file. I really don't know.
But I suppose I'd ask -- faster how?
The linked benchmark really doesn't mean much to me. As an interactive app I judged it on how it felt latency-wise at the CLI. So, I would just try to scroll page-up while find was feeding in the files in my home directory. fzf would sometimes stall on my system (again not scientific) and would occasionally junk up the terminal when it got fed something strange. This could be a problem with fzf or it could have been a problem with how I was using it.
On the other hand, sk at the CLI has been rock solid and very fast. skim as a library needs better docs and has a few other teething issues, but I'm using skim right now, because it feels faster, and because I use it as a library, there is some mental continuity between the two. Recognize and respect fzf in this space, it's just sk is doing it better for me, for now.
Skim is effectively dead. fzf continues to receive new features and improvements. One of the stated goals of skim is that it will be option-compatible with fzf.
Unfortunately that's only superficially true at this point. I recently removed sk support from a project because I was tired of special-casing for it. (ZFSBootMenu).
An awesome use case for fzf is to use it as a selector for a bunch of lines of text. So we have a script that gets the latest docker images and then we pipe it to fzf allowing you to select which one of them you want to use.
Just a small thing to add on to the awesomeness that is fzf!
I wrote a small "selector" script to use fzf or dmenu depending on whether a TTY is available. So if I am running a script involving selection outside of a terminal I get the dmenu GUI, but inside a terminal I get fzf.
This tool isn't "news", it's been a staple of my environment for years, but it's trending so upvoted. I use fzf everywhere, it's greatly enhanced my workflow. Recommend fzf-tab to use fzf for zsh autocompletion.
Try installing it from the source into eg. ~/.fzf and run ~/.fzf/install (if I remember correctly). It will offer to add bindings for ctrl-r etc. to the shell's rc file. Easy to update, just run git pull in ~/.fzf and install again.
Try using it with the -e flag, it gives exact matches for each space-separated word you type, ignoring order and case. This is usually the most useful way to search in my experience. For example, if I'm searching through my filesystem I can give it "pdf pascal", it will give me all the Pascal-related PDF files. But it won't match paths like this just because the letters appear throughout the string:
Diff so fancy is great too! I go back and forth between it and delta at times by leaving delta as the default diff tool and adding a git alias for the following:
I failed a bunch of times to find a terminal differ that could display diffs and especially merges with convenience comparable to graphical tools like Meld, KDiff of Idea's built-in merger. So far the best I could dig up is `icdiff` for side-by-side diffs, and some Emacs mode that Magit uses, for three-way merges (the latter is not a terminal util really, just faster sometimes than going to Meld).
Another wonderful tool is "entr". It just runs a program when files change.
It's incredible.
I use it 20-40 times an hour to do very fast Dev/DevOps development:
- "run Pytest when Python files change"
- "I forgot how to use ps, run my-ps.sh when it changes and show me the output"
- "rebuild all these Kubernetes resources when I edit the YAML files"
- "run fast lint, then unit test Python files, then invoke one and show me the results"
I am inclined to use watchexec next time I need one, because like go, I can read it more easily than c, but also because I looked at the web page and GitHub repo and it seems worth trying. For instance, it shows how to use it as a library instead of just as a command-line tool. https://watchexec.github.io/
Do you have to be very careful when you save files if you're using that? I can imagine having it start a build that then spews tons of errors just because you saved a file that's only one of many changes you wanted to make, could become irritating more than anything else. Also, what happens when you change a file in the middle of a build that it started?
I can see how it could be helpful, but with the way I write software, that scares me. I save habitually, and not only when I'm actually ready to build the result.
I just use inotifywait for that. What does entr do differently?
This will run a binary when any file on the directory tree changes:
#!/usr/bin/env sh
set -e
while true; do
inotifywait -e modify,create,delete,move -r $1 $2
done
and then just call it: run_on_modify path/to/dir path/to/bin
If someone thinks this is magic or wizardy, instead of teaching them that fire exists (entr), teach them how to make fire first (inotify, linux inodes, etc.). Knowing what kind of events inodes support and how to do something when they happen is pretty powerful.
If you then want to use "entr" or similar instead of just calling inotifywait yourself, that's fair game. But TBH I have a hard time justifying a C or Rust program that's not going to be available / installed everywhere when a 3 LOC POSIX shell script can solve the same problem (and many many more).
inotifywait does a decent job of exposing the inotify primitive from the Linux kernel to userspace, but it's, well, primitive. Using that loop, if you change a file twice in quick succession, what happens? It'll trigger off the first change, but potentially ignore the second change if $2 takes longer to run than you can edit a file.
You can improve the basic loop somewhat, but a more thoroughly written program (whatever the language) rather than a 3 LOC loop is going to have more features and be more ergonomic. In particular, to truly be useful, it should be able to kill the command and restart it every time the file is saved.
I can totally see why fzf is a great utility and is indeed very cool but I don't see real value other than as a Vim plugin for Ctrl-P.
For a Ctrl-R replacement in the terminal, it never sticked with me, because getting more than 1 results was distracting.
Also, if I'm in a directory and want to open a file in vim that I'm not sure of its location, I do `vim` and then Ctrl-P.
I tried to incorporate it a few times in my workflow, but I couldn't see the value that would justify the overhead of having to learn a different tool.
Oh jeez, those are great examples. Thanks. I only use it in neovim (telescope), this post and your comment have inspired me to start trying it on the command line.
Because it's a two-dimensional ctrl-R; therefore far superior. You can look through variations of the same command. If you do a lot of CLI that's important, at least to some of us.
It has replaced vim’s “open file” and “switch to buffer” for me. I occasionally use it in the command line, by expanding *. Not that often as in Vim, but very useful.
I still need to find a satisfactory way to do “find in files” with vim. I use a custom script to call ag and it’s enough, but a bit clunky at times.
If you're using fzf.vim (https://github.com/junegunn/fzf.vim) then you can use :Rg or :Ag. This will run ripgrep or silver-searcher and present the results in a fuzzy finder window.
Wait. What. Just tried that. It worked. I must have missed it when I installed the plugin. Thanks a lot! I can now remove a bunch of stuff from my config file :)
If you're using neovim I suggest checking out telescope.nvim. In addition to searching for files, it comes with a Live Grep mode for searching the current buffer (or all files in a given directory).
Fzf is brilliant. Recently I found fzrepl (https://github.com/danielfgray/fzf-scripts/blob/master/fzrep...), which blew my mind. It uses fzf and its preview window to create a repl for other programs, such as jq. That's great for figuring out a query for jq since I use it so rarely.
92 comments
[ 2.6 ms ] story [ 159 ms ] threadI still use ksh these days (actually, the openbsd version, even on linux) and it behaves EXACTLY the same way as a bash shell to the uninitiated (ctrl+r, fc -l, etc etc etc)..
I have some little shell functions that I use for things, like 'git_branch()' which I use with some aliases (I have >200 shell aliases)..
ZSH has a fucking ftp client in it right? And it still just behaves like bash? What does it do on top? Am I missing something? :}
omz is a tool for zsh users, that is its purpose in life
Zsh has a lot more features than ksh, the functionality ksh has is the lower bound if it works for you great
If you enjoy DIY writing 200 aliases great, zsh like bash is more than path autocomplete and aliases it’s a lot more
I look at zsh alias features and my head explodes a bit. The glob patterns can get so complex, they look like Perl or sendmail config strings.
I think you may have just answered your own question -- it includes ready-made shell themes and plugins. Not everyone wants to work that hard (including me!).
Any command where you might be generating a long list of items you then want to select from can probably benefit from being piped into fzf.
But if you need to to do something more specialized you can pipe the output of a kubectl command into fzf and then use the ‘describe’ sub command on the selected item returned by fzf. Basically when you need to interact in someway then run a command on the output fzf can be great.
[1] https://github.com/BurntSushi/ripgrep
For those that haven't tried yet, and want an entry point, I'd highly recommend you play around with the 'fzf' key bindings and completion scripts for zsh[0] to see what's possible. A little app of mine[1] also has an example of what one might call the minimal viable hot key script for you (note: for skim or 'sk', a 'fzf' Rust clone).
[0]: https://github.com/junegunn/fzf/tree/master/shell [1]: https://github.com/kimono-koans/httm
[0] https://github.com/PatrickF1/fzf.fish
another resource I found valuable early on: https://www.youtube.com/watch?v=qgG5Jhi_Els
EDIT: just realised this is the repo README by the fzf creator. he mentions Samoshkin's video also but it's worth repeating
I like them both for making fun zsh key bindings, so, so easy.
[0]: https://github.com/kimono-koans/httm [1]: https://github.com/lotabout/skim
But I suppose I'd ask -- faster how?
The linked benchmark really doesn't mean much to me. As an interactive app I judged it on how it felt latency-wise at the CLI. So, I would just try to scroll page-up while find was feeding in the files in my home directory. fzf would sometimes stall on my system (again not scientific) and would occasionally junk up the terminal when it got fed something strange. This could be a problem with fzf or it could have been a problem with how I was using it.
On the other hand, sk at the CLI has been rock solid and very fast. skim as a library needs better docs and has a few other teething issues, but I'm using skim right now, because it feels faster, and because I use it as a library, there is some mental continuity between the two. Recognize and respect fzf in this space, it's just sk is doing it better for me, for now.
[0]: https://github.com/lotabout/skim/issues/317
Unfortunately that's only superficially true at this point. I recently removed sk support from a project because I was tired of special-casing for it. (ZFSBootMenu).
Just a small thing to add on to the awesomeness that is fzf!
I think I installed it differently on other systems previously, and those installs took care of the integration for me.
https://github.com/peteryates/dotfiles/blob/master/zsh/.zshr...
In my experience it's too fuzzy, and makes it impossible to find anything.
That first exposure to fzf brought the biggest change to my workflow in years.
I don’t understand what it does. Is it like an alternative diff or is it a patching utility based on a specifically formatted file?
It formats that output, and then might typically be chained into `less` for actual paging.
[I co-maintain, just issue triage really, a similar alternative called `diff-so-fancy`.]
It's incredible.
I use it 20-40 times an hour to do very fast Dev/DevOps development:
- "run Pytest when Python files change" - "I forgot how to use ps, run my-ps.sh when it changes and show me the output" - "rebuild all these Kubernetes resources when I edit the YAML files" - "run fast lint, then unit test Python files, then invoke one and show me the results"
Link: https://jvns.ca/blog/2020/06/28/entr/
There's another one that I've used that is written in go: https://github.com/cespare/reflex
I am inclined to use watchexec next time I need one, because like go, I can read it more easily than c, but also because I looked at the web page and GitHub repo and it seems worth trying. For instance, it shows how to use it as a library instead of just as a command-line tool. https://watchexec.github.io/
I can see how it could be helpful, but with the way I write software, that scares me. I save habitually, and not only when I'm actually ready to build the result.
This is called "debounce" in `watchexec` a similar program to `entr`
I think there’s something I don’t understand about GP:s workflow and needs.
This will run a binary when any file on the directory tree changes:
and then just call it: run_on_modify path/to/dir path/to/binIf someone thinks this is magic or wizardy, instead of teaching them that fire exists (entr), teach them how to make fire first (inotify, linux inodes, etc.). Knowing what kind of events inodes support and how to do something when they happen is pretty powerful.
If you then want to use "entr" or similar instead of just calling inotifywait yourself, that's fair game. But TBH I have a hard time justifying a C or Rust program that's not going to be available / installed everywhere when a 3 LOC POSIX shell script can solve the same problem (and many many more).
You can improve the basic loop somewhat, but a more thoroughly written program (whatever the language) rather than a 3 LOC loop is going to have more features and be more ergonomic. In particular, to truly be useful, it should be able to kill the command and restart it every time the file is saved.
https://pypi.org/project/iterfzf/
The python package also includes the fzf binary.
I would to like to use it for my web-history. And maybe for webpages I have visited too.
For a Ctrl-R replacement in the terminal, it never sticked with me, because getting more than 1 results was distracting.
Also, if I'm in a directory and want to open a file in vim that I'm not sure of its location, I do `vim` and then Ctrl-P.
I tried to incorporate it a few times in my workflow, but I couldn't see the value that would justify the overhead of having to learn a different tool.
I use it to interact with git, i.e.:
- checkout local git branch from curated list of branches fed through fzf
- cherry pick commits from the previous (@{-1}) branch, using fzf + preview showing each commit's "diff"
- pick recent SHA to git revert
- pick files changed from {master,main,blead}
- pick files currently uncommitted
I still need to find a satisfactory way to do “find in files” with vim. I use a custom script to call ag and it’s enough, but a bit clunky at times.
I imagine you have a similar approach, what's clunky about it for you?
I also use vim-grepper (mapped to leader-g) for finding in files and populating the quickfix list.
https://github.com/mhinz/vim-grepper
Does that work for you? I thought that's what a fuzzy finder is
If I wanted all occurrences of lines that match a pattern I'd use vim-grepper (which uses Ag or ripgrep under the hood) and search with a regex.
If you're using Telescope you can use your fuzzy search to find the lines you want then use <C-q> to send them to your quickfix list.
For find and replace, I use spectre.
Does that work for you? I thought that's what a fuzzy finder is
You can use zsh's fzf-tab as a supercharged tab-completion. e.g. you can just do
and it will put a fzf interface where the tab-completions would usually be, and you can pick whatever files you want. And if you instead do it will instead show you all the possible flags and their descriptions, which you can also pick from.I use this all the time on the terminal now. It cuts out so much pointless flow-breaking invocations of ls and man and --help.
https://github.com/zbm-dev/zfsbootmenu/blob/master/media/v1....
https://github.com/zbm-dev/zfsbootmenu/blob/master/zfsbootme...