Rofi is a window switcher, application launcher and dmenu replacement.
I’ve been using rofi
with i3-gaps
since early 2019. I had played with it before, but I’ve been using it daily the last couple of years.
I use it to launch applications, open ssh sessions, with pass and with a set of useful custom scripts.
Installation
You need to install the rofi
package. I also installed rofi-dmenu
for dmenu compatibility, rofi-pass
to use with pass and the extra rofi-emoji
and rofi-calc
.
paru -S rofi rofi-dmenu rofi-pass rofi-emoji rofi-calc
Executing
You can run Rofi in different modes depending if you want to launch an application, open a ssh session, change windows or executing a command in the terminal.
Check Rofi at github and man rofi
for more details.
In my setup, and using i3-gaps
(learn more here) I use it to accomplish a series of tasks:
- As an application launcher (both desktop apps and terminal commands)
bindsym $mod+d exec --no-startup-id "rofi -modi combi -show combi -combi-modi drun,run"
- To explore my password store, allowing me to auto-type password anywhere or copy to the clipboard a username or password
bindsym $mod+p exec --no-startup-id rofi-pass
- Open ssh sessions
bindsym $mod+s exec --no-startup-id rofi -show ssh
- Running custom scripts (as an example a web search script)
bindsym $mod+f exec --no-startup-id websearch
Here’s my websearch
script, inspired by ditrotube.
cat .local/bin/websearch
#!/usr/bin/env bash
DMBROWSER="/usr/bin/librewolf"
declare -a options=(
"searx - https://searx.tuxcloud.net/?q="
"amazon - https://www.amazon.com/s?k="
"kindlebooks - https://www.amazon.com/s?rh=n%3A154606011&ref=nb_sb_noss&k="
"youtube - https://www.youtube.com/results?search_query="
"goodreads - https://www.goodreads.com/search?q="
"archaur - https://aur.archlinux.org/packages/?O=0&K="
"archpkg - https://archlinux.org/packages/?sort=&q="
"archwiki - https://wiki.archlinux.org/index.php?search="
"audible - https://audible.com/search?keywords="
"duckduckgo - https://duckduckgo.com/lite/?q="
"github - https://github.com/search?q="
"gitlab - https://gitlab.com/search?search="
"google - https://www.google.com/search?q="
"reddit - https://www.reddit.com/search/?q="
"quit"
)
while [ -z "$engine" ]; do
enginelist=$(printf '%s\n' "${options[@]}" | rofi -dmenu -p 'Choose search engine:') || exit
engineurl=$(echo "$enginelist" | awk '{print $NF}')
engine=$(echo "$enginelist" | awk '{print $1}')
done
while [ -z "$query" ]; do
if [[ "$engine" == "quit" ]]; then
echo "Program terminated." && exit 0
else
query=$(echo "$engine" | rofi -dmenu -p 'Enter search query:') || exit
fi
done
$DMBROWSER "$engineurl""$query"
#eof
Configuration
The rofi
configuration file is located at .config/rofi/config.rasi
.
cat .config/rofi/config.rasi
configuration {
modi: "run,ssh,window,combi,drun,windowcd";
matching: "fuzzy";
show-icons: true;
theme: "~/.config/rofi/themes/dmenu.rasi";
font: "Cantarell Regular 11";
icon-theme: "oomox-gruvbox-dark";
lines: 7;
separator-style: "solid";
hide-scrollbar: true;
kb-row-down: "Control+j";
kb-row-up: "Control+k";
kb-accept-entry: "Return,KP_Enter";
kb-remove-to-eol: "";
display-drun: "Open";
display-run: "❯ sh";
display-combi: "";
display-window: "Change window";
display-windowcd: "Change window (same workspace)";
terminal: "/usr/bin/alacritty";
ssh-command: "{terminal} -e {ssh-client} {host}";
}
I’m using a theme to emulate dmenu, but I used a gruvbox inspired on until recently.
cat .config/rofi/themes/dmenu.rasi
* {
background-color: Black;
border-color: White;
text-color: White;
font: "Cantarell Regular 12";
}
#window {
anchor: north;
location: north;
width: 100%;
padding: 4px;
children: [ horibox ];
}
#horibox {
orientation: horizontal;
children: [ prompt, entry, listview ];
}
#listview {
layout: horizontal;
spacing: 5px;
lines: 100;
}
#entry {
expand: false;
width: 10em;
}
#element {
padding: 0px 2px;
}
#element selected {
background-color: SteelBlue;
}
cat .config/rofi/themes/gruvbox-common.inc.rasi
window {
background-color: @background;
border: 2;
padding: 2;
}
mainbox {
border: 0;
padding: 0;
}
message {
border: 2px 0 0;
border-color: @separatorcolor;
padding: 1px;
}
textbox {
highlight: @highlight;
text-color: @foreground;
}
listview {
border: 2px solid 0 0;
padding: 2px 0 0;
border-color: @separatorcolor;
spacing: 2px;
scrollbar: @scrollbar;
}
element {
border: 0;
padding: 2px;
}
element.normal.normal {
background-color: @normal-background;
text-color: @normal-foreground;
}
element.normal.urgent {
background-color: @urgent-background;
text-color: @urgent-foreground;
}
element.normal.active {
background-color: @active-background;
text-color: @active-foreground;
}
element.selected.normal {
background-color: @selected-normal-background;
text-color: @selected-normal-foreground;
}
element.selected.urgent {
background-color: @selected-urgent-background;
text-color: @selected-urgent-foreground;
}
element.selected.active {
background-color: @selected-active-background;
text-color: @selected-active-foreground;
}
element.alternate.normal {
background-color: @alternate-normal-background;
text-color: @alternate-normal-foreground;
}
element.alternate.urgent {
background-color: @alternate-urgent-background;
text-color: @alternate-urgent-foreground;
}
element.alternate.active {
background-color: @alternate-active-background;
text-color: @alternate-active-foreground;
}
scrollbar {
width: 4px;
border: 0;
handle-color: @scrollbar-handle;
handle-width: 8px;
padding: 0;
}
sidebar {
border: 2px 0 0;
border-color: @separatorcolor;
}
inputbar {
spacing: 0;
text-color: @normal-foreground;
padding: 2px;
children: [ prompt, textbox-prompt-sep, entry, case-indicator ];
}
case-indicator,
entry,
prompt,
button {
spacing: 0;
text-color: @normal-foreground;
}
button.selected {
background-color: @selected-normal-background;
text-color: @selected-normal-foreground;
}
textbox-prompt-sep {
expand: false;
str: ":";
text-color: @normal-foreground;
margin: 0 0.3em 0 0;
}
cat .config/rofi/themes/gruvbox-dark.rasi
* {
/* Theme settings */
highlight: bold italic;
scrollbar: true;
/* Gruvbox dark colors */
gruvbox-dark-bg0: #282828;
gruvbox-dark-bg0-soft: #32302f;
gruvbox-dark-bg3: #665c54;
gruvbox-dark-fg0: #fbf1c7;
gruvbox-dark-fg1: #ebdbb2;
gruvbox-dark-red-dark: #cc241d;
gruvbox-dark-red-light: #fb4934;
gruvbox-dark-yellow-dark: #d79921;
gruvbox-dark-yellow-light: #fabd2f;
gruvbox-dark-gray: #a89984;
/* Theme colors */
background: @gruvbox-dark-bg0;
background-color: @background;
foreground: @gruvbox-dark-fg1;
border-color: @gruvbox-dark-gray;
separatorcolor: @border-color;
scrollbar-handle: @border-color;
normal-background: @background;
normal-foreground: @foreground;
alternate-normal-background: @gruvbox-dark-bg0-soft;
alternate-normal-foreground: @foreground;
selected-normal-background: @gruvbox-dark-bg3;
selected-normal-foreground: @gruvbox-dark-fg0;
active-background: @gruvbox-dark-yellow-dark;
active-foreground: @background;
alternate-active-background: @active-background;
alternate-active-foreground: @active-foreground;
selected-active-background: @gruvbox-dark-yellow-light;
selected-active-foreground: @active-foreground;
urgent-background: @gruvbox-dark-red-dark;
urgent-foreground: @background;
alternate-urgent-background: @urgent-background;
alternate-urgent-foreground: @urgent-foreground;
selected-urgent-background: @gruvbox-dark-red-light;
selected-urgent-foreground: @urgent-foreground;
}
@import "gruvbox-common.inc"