[[./assets/preview.png]]

A multi-page fuzzy launcher for your terminal, written in Rust.

Supports theming and multiple keybind schemes, including basic vim keybinds.

[[#Installation][Installation]] - [[#Usage][Usage]] - [[#Integration][Integration]] - [[#Configuration][Configuration]]

** Installation

If you don't have Rust, follow the installation instructions [[https://www.rust-lang.org/tools/install][here]].

Run the following command to install fr33zmenu:

+BEGIN_SRC shell

cargo install fr33zmenu

+END_SRC

** Usage

Run the following command to view help: =fr33zmenu --help=

If the command isn't found, you will need to add =~/.cargo/bin= to your path.

+BEGIN_SRC shell

echo 'export PATH=$PATH:~/.cargo/bin' >> ~/.bashrc source ~/.bashrc

+END_SRC

If you're using zsh, replace =~/.bashrc= with =~/.zshrc=.

** Integration

This guide will demonstrate how to integrate fr33zmenu with your window manager. You'll need to adapt this to your terminal and window manager (obviously), but for this guide I'm using [[https://hyprland.org/][Hyprland]] (wayland compositor) and [[https://sw.kovidgoyal.net/kitty/][Kitty]] (terminal).

* 1. Create a configuration file

See the [[#Configuration][Configuration]] section below. I saved mine as =~/.config/fr33menu/menu.toml=.

* 2. Create a script for your window manager to execute

I saved mine as =~/scripts/launcher=.

+BEGIN_SRC shell :tangle ./examples/launcher.sh

!/bin/sh

fr33zmenu ~/.config/fr33zmenu/menu.toml \ --exec-with "nohup hyprctl dispatch exec" \ --transient

+END_SRC

* 3. Configure window manager / compositor

Through keybinds and window rules, it's possible to make a terminal window behave exactly like a graphical launcher. My goal with these settings is to have the window pop up in the center of the screen at a fixed sized.

The following configuration was added to my =~/.config/hypr/hyprland.conf=.

+BEGIN_SRC conf

$launcher = kitty --class fr33zmenu ~/scripts/launcher bind = $mainMod, SPACE, exec, $launcher

windowrulev2 = float, class:fr33zmenu windowrulev2 = size 600 400, class:fr33zmenu windowrulev2 = center, class:fr33zmenu

+END_SRC

If your terminal doesn't support opening with a provided class, you can use the title of the window instead.

Configuration is supported for theming, keybinds, and menus. There is no preset config directory, as the path to your config file will be passed as a positional argument. Even so, you may want to store your config(s) in =~/.config/fr33zmenu= for the sake of organization.

Note: All configuration options must reside in the one file passed to the program. There is no support for providing or importing multiple config files (yet?)

** Menus

Required

A /menu/ defines the interactive content of the program. Each menu is displayed as a tab on the first line of the interface, and the /entries/ of the current menu are displayed underneath the menu's prompt.

* Example

+BEGIN_SRC toml :tangle ./examples/menu.toml

[menus.programs] # Define a new menu named "programs" order = -1 # Ensure it is the first menu prompt = "launch -> " # Give it a cool prompt

[menus.programs.entries] # Define the menu's entries

↓ Name ↓ Value

emacs = "emacsclient -c -a emacs" librewolf = "librewolf --browser" strawberry = "strawberry" gimp = "gimp --new-instance" gajim = "gajim --show"

[menus.power] # Another menu prompt = "power -> "

[menus.power.entries] shutdown = "shutdown now" reboot = "reboot"

+END_SRC

** Keybinds

Optional - Defaults will be loaded if this section is absent in your config.

Named keys

* Example (default keybinds)

+BEGIN_SRC toml :tangle ./examples/keybinds.toml

[keybinds] exit = [ "escape", "ctrl+c" ] submit = [ "enter" ] clear = [ "shift+del", "ctrl+del" ] deletenext = [ "delete" ] deleteback = [ "backspace" ] inputnext = [ "right" ] inputback = [ "left" ] entrynext = [ "down", "ctrl+down", "ctrl+j", "tab" ] entryback = [ "up", "ctrl+up", "ctrl+k", "shift+tab" ] menunext = [ "ctrl+right", "ctrl+l" ] menuback = [ "ctrl+left", "ctrl+h" ]

+END_SRC

** Theme

Optional - Defaults will be loaded if this section is absent in your config.

All text in the interface can be themed. Every value in the theme accepts the following properties:

Any valid CSS color string is accepted, but alpha values will have no effect.

* Example (default theme)

+BEGIN_SRC toml :tangle ./examples/theme.toml

[theme] prompt = { fg = "#a6e3a1", attrs = "bold" } input = { fg = "#cdd6f4" } entryname = { fg = "#cdd6f4" } entryvalue = { fg = "#6c7086" } entrymatch = { fg = "#74c7ec", attrs = "bold" } entryhidden = { fg = "#45475a" } entrycursor = { fg = "#1e1e2e", bg = "#cdd6f4", attrs = "bold" } entrycursormatch = { fg = "#1e1e2e", bg = "#74c7ec", attrs = "bold" } menuname = { fg = "#f38ba8" } menu_cursor = { fg = "#1e1e2e", bg = "#f38ba8", attrs = "bold" } overflow = { fg = "#f9e2af", attrs = "bold" }

+END_SRC