1. 26

We already know the $EDITOR, the $VISUAL, the $PAGER, and all of the usual UNIX commands.

It seems that the interactive filter fits well in this ecosystem of commands.

You can think of it as an interactive grep. It takes lines from stdin, display them on screen, and prompt user for input to match against these lines, and filter only the lines that matches. The user can select the input candidates somehow, and while selection is made, the result is sent to stdout, to be exploited by the next command.

This is a feature that has often been integrated to softwares, such as a web browser for the URL bar, start menus to find applications, and even web pages such as search engines…

It seems that there are also a lot available for the terminal as well. I am presenting those that I know, in the order they come to my mind.

I will try to update this list according to the comments.

Fuzzy matching

They match any string with the character of the input in the same order. Just like if we put a wildchar between every character of the input.

This often comes with re-ordering the lines to put the shortest one at the top of the list.

fzf - Go
  • Prompt at bottom by default;
  • Integration with bash and zsh, tmux, vim, ps…
  • Binaries for Linux, Mac, Windows, Android (probably for termux and chroots).
  • Not the fastest, but is totally asynchronous: Butter smooth interface.
  • Uses “alternate screen”: fullscreen only
  • Fancy interface.
  • head -n 10000 /dev/urandom | fzf perfect! Just like plain lines!

Many features, pretty popular. Still not perfect for me, I like tools written in C for command line interactions, and I do not want something that big. It is not bloated, just bigger than what I want.

fzy - C
  • Accurate fuzzy matching by calculating scores for each match;
  • Very fast, the fastest I have found for this accuracy;
  • Simple interface;
  • Integration with vim;
  • head -n 10000 /dev/urandom | fzy not bad, did not segfault.
  • Valgrind said: No error, no leak possible \o/
gof - Go

Strangely looking similar to fzf, maybe the two projects are related. This version is much smaller.

Simple tool that does fuzzy filtering efficiently.

pick - C

Simple and works well.

tmenu - C

Simple tool that works well, with a great effort on making it reliable (only C99 source code) with no dependency. It still supports line editing, with emacs-like keybindings.

pmenu - python
  • No dependency other than python;
  • Most Recently Used feature;
  • Has a large list of alternative, for both terminal and GUI.
selecta - ruby

With a ranking algorithm.

icepick - rust

Re-write of selecta in rust for performance.

heatseeker - rust

Re-write of selecta in rust for performance.

gpicker - C
  • Scoring to order most relevant matches
  • Uses caching of the find command.
hf - Go
  • Propose you to run a command after you selected a match, with $FILE holding the name of the file.
  • Integration with git, vim…
hmenu - haskell

Simple, in haskell, oriented to pick files.

Plain string matching

The input string is filtered as is.

percol - python
  • Feature rich
  • Can select multiple lines at once
  • Lots of customization, through a python-based configuration file.
peco - Go

Made after percol, re-write in Go to make in faster and do not require python.

tpick - C

Using ncurses, but very small, about 300 lines

PathPicker - Python
  • Multiple selections;
  • Oriented to select files and open them with a command;
  • Integration with tmux.
Word matching

Input is splitted at every space, and each word is matched independently like in a search engine.

slmenu - C

For single-line menu: really an equivalent of dmenu for the command line:

  • supports horizontal and vertical interface;
  • share some code with dmenu;
  • support top/bottom of the terminal;

A more maintained version is present in the vis repo: vis-menu.

selector - C

Supports regexp, and ‘;’ as separator for words

iomenu - C

The one I made, so that I could has these two things:

  • Comments at the right of lines that does not get matched by the input and not printed out
  • Headers that are always displayed organize input in multiple categories.

It is not better than the others, it just has a different approach.

Specific

Those that are not exactly filters, but that are still convenient and useful.

smenu - C

Horizontal selection dialogues using arrow keys for selection.

  1.  

  2. 8

    $EDITOR, $VISUAL and $PAGER are useful because there’s some minimal standard interface all those things conform to: editors will take a file on the command-line and not exit until editing is complete, pagers will read from standard input.

    Filters are a bit more flexible: some take items from the command-line, some take items from standard input. If you take items from standard input, they’re probably newline-delimited, but if they’re filenames maybe you want NUL-delimiting like xargs -0.

    Should the filter allow the user to select multiple items? Probably yes if you’re using it with git add, probably no if you’re asking for an output directory.

    Should the filter allow the user to select items that weren’t in the input? Probably yes if you’re asking for a filename to save-to, or looking for a replacement word in a spell-checker. Probably no if you’re asking for a filename to open.

    If there were solid conventions around those questions (like “-m allows multiple selection”, etc.) then I’d love for this to become as widely-used as $EDITOR.

    1. 2

      Sure there can be more features, but I think the essence is given a list of lines, choose one. With something like “$FILTER”, the user can customize that input. For example blind developers might want a different interface.

      1. 1

        We could still contact every dev to put a notice “Follows the $FILTER convention” in their page. with a link to a web page explaining the convention.

        The filters without some features could ignore the missing flags for compatibility.

      2. 1

        That would explain that there are so many out there. Each developer has its priorities in the features he wants.

        But it would not but that hard to set a minimal set of standard behavior. There is already one common behavior as etc said.

        For the most common extra options, we can ask the devs to set the same flag.

      3. 2

        Let me commit a classic bikeshedding response here: I think your terminology is off. While the context of your post makes it clear what you are talking about, the term “filter” by itself would not be descriptive of what you‘re referring. But as a variable name, $FILTER would be especially bad because of ambiguity – my first thought at the term goes to something like grep and ilk. So I’d use $PICKER for this.

        Sorry. ?

        1. 1

          “Interactively filtering lines” is something I have seen on projects description, but $FILTER on its own is a bit confusing, yes.

          There is no confusion with EDITOR, PAGER, PICKER…

        2. 2

          I’ve been using pick for a few monthes now, coupled with ssh, in order to quickly connect to one of the ~1000 hosts I administrate. These interactives filters are indeed extremely useful, and the fact they deal with STDIN and STDOUT makes them really easy to accomodate to different needs.

          1. 1

            As pointed out by its author, smenu is much more than only an horizontal menu for choices.

            In example, it can have a full grid layout. Check the README and man page for more.