Program Launcher using fzf and compgen

Ever since I transitoned to wayland (sway),I was searching for a good program launcher (I know about dmenu, but I wanted something native to wayland). Then I got this idea from a random reddit comment, why not use fzf and a terminal emulator as the program launcher. Thought it was cool and efficient since I already have fzf installed for neovim and don’t have to add another dependency to my system.

For those who don’t know what fzf is here is a quick info from it’s repo.

  • FZF is an interactive Unix filter for command-line that can be used with any list; files, command history, processes, hostnames, bookmarks, git commits, etc.

In simple terms it is a command-line general-purpose fuzzy finder tool, and it is somewhat like grep but more awesome. So here is how I did it ;). fzf usually filters through whatever list we give and give as interactive prompt to search with, we can use this cool feature for our program launcher. So if we pipe list command through fzf, It will allow us search all the sub directories in a directory interactively.

image: ls|fzf

image: ls|fzf

So the next problem to tackle how we should give the executable programs, for that we need a list of all the binaries present in our system, compgen can help as on that. What is compgen then ;), If you are using bash you have heard of this since its a bash command. (Fish users can use another command called complete for the same purpose) Compgen is a Bash builtin that shows all possible completions, by completions I mean is command names, paths, and so on, that might be completed when given a part of a string.

For example, if we type “mk” and press tab we could see completions like mkdir, mkfs these are completions , so we can access the commands in our system using compgen, more specifically compgen with a ‘-c’ flag. Example:

    $compgen -c
    img2txt
    lavpipe
    unix_chkpwd
	pw-loopback
	.........

compgen -c generates a list of commands that can be completed. By piping the list to fzf, we can create a menu system to search and execute any command we want.

    $ compgen -c| fzf

image: compgen -c| fzf

So here we have menu system that works, all that left is to make show our menu system based on a key shortcut. Since I am using sway (window manager similar to i3wm but for wayland), the steps include some sway utilities, but you can change it according to the window manager of your choice.

Here goes our full script which I have saved as separate file which can be called from the window manager config.

    #!/bin/bash
    # filename: fzf_menu.sh

    # if the script is already then exit 
    pidof -o %PPID -x $0 >/dev/null && exit 1
    
    # else run the script
    foot -w 640x240 -T "fzf_menu" -- /bin/sh -c 'compgen -c | fzf | xargs swaymsg exec'

Since I am using an awesome terminal emulator know as foot, using command line arguments I am spawning a new terminal each time we are running the script.

Then all that left is to keep a key shortcut in sway for (ctrl + p) for launching the program.

    # using ctrl + p to launch our menu
    bindsym $mod+p exec '/home/rijo/.config/sway/fzf_menu.sh'
    # set the terminal as floating, so it will appear in center
    for_window [title="^fzf_menu$"] floating enable, border pixel

The final result will be like the below screenshot

image: final

So now we have a cool looking menu at our disposal ;).

<