This project aims to create a contextual command palette for any X program. It should be easy to configure (without coding), and flexible.
- Rofi
- JSON file for configuration
-
I’m using myrmidon
as inspiration, though rewriting everything in python for readability and extensibility.
mkdir -p ~/.config/rofi-contextual-palette/
{
"version": "0.1"
}
[
{
"name": "desk switch",
"command": "rofi -show window",
"tags": "desktop"
},
{
"name": "win switch",
"command": "rofi -show windowcd",
"tags": "desktop"
},
{
"name": "bookmarks",
"command": "/home/charlie/.local/bin/rofi-buku",
"tags": "web,buku,firefox"
},
{
"name": "emoji",
"command": "rofimoji",
"tags": "writing,desktop"
},
{
"name": "systemd",
"command": "/home/charlie/.local/bin/rofi-systemd",
"tags": "system,desktop"
},
{
"name": "playlist",
"command": "/home/charlie/.local/bin/rofi-mpd -p",
"tags": "music,desktop"
},
{
"name": "archivos",
"command": "pcmanfm",
"tags": "files"
},
{
"name": "mpc",
"command": "/home/charlie/.local/bin/rofi-mpc",
"tags": "music"
},
{
"name": "temas",
"command": "/home/charlie/.local/bin/rofi-mpd -t",
"tags": "music"
}
]
"""
DO NOT edit this file! Tangled from `Projects/rofi-command-palette/README.org`
Carlos Jose Barroso <[email protected]> Feb 2023
"""
# Now, if we recognize one of the windows we filter the commands for that context.
# I may add a "general" instance of the launcher with all the commands, or maybe
# just prioritize some commands. Other alternative (with can be mixed really) is to
# have several instances.
# The idea of having a contextual one maybe has more value with seldom used apps, or
# heavily specialized environments.
import os
import sys
import json
import subprocess
CONFIG=os.path.expanduser("~/.config/rofi-contextual-palette/config")
TASKS=os.path.expanduser("~/.config/rofi-contextual-palette/task-list.json")
try:
configfile = open(CONFIG)
except FileNotFoundError:
print(f"No config file found at {CONFIG}")
sys.exit()
try:
tasksfile = open(TASKS)
except FileNotFoundError:
print(f"No tasks file found at {TASKS}")
sys.exit()
try:
raw_tasks = json.loads(tasksfile.read())
except json.decoder.JSONDecodeError as e:
print("Error reading tasks file - Corrupt?")
print(str(e))
res=subprocess.run(["xdotool", "getwindowfocus", "getwindowclassname"], capture_output=True)
# remove carriage return and normalize to lower case
focused_window_class=res.stdout.decode("utf-8").strip().lower()
print(focused_window_class)
The column is called “tags”
print("-"*80)
print("raw:", raw_tasks)
class_tasks = [e['label'] for e in raw_tasks if focused_window_class in e['app']]
print("class: ", class_tasks)
# es un objeto que se comporta como str()
selected_task_obj = subprocess.run(
["rofi", "-dmenu","-matching","fuzzy","-i","-p",f"[{focused_window_class}] Search tasks"],
input=merged_tasks, capture_output=True
)
if selected_task_obj.returncode:
print("something's wrong")
sys.exit()
selected_task = selected_task_obj.stdout.decode().strip()
command = filter(lambda _: selected_task in _['label'], raw_tasks)
# verify if it exists, etc
# try, etc,
to_run = list(command).pop()['command']
subprocess.run(to_run.split(" ")) # split required
copyq tab pass read $(seq 0 50) | sed '/^$/d' | rofi -dmenu -i -p "Secure password"