a python interface to dynamic menus
Dynmen is a python library for controlling dynamic menus like dmenu, rofi, fzf, and percol. A primary use for dynamic menus is to prompt users to filter and select an entry from a list. They typically read entries from STDIN and write the selection to STDOUT.
Dynmen simplifies working with dynamic menus by having:
- Input entries to menus as any iterable python object (dict, list, etc)
- Menu run in blocking or non-blocking modes
- Structured results with error checking
- Introspectable classes which expose all of a menu's options
Using dynmen to drive any dynamic menu can be broken down into two main steps
- Create and configure a menu instance (e.g.,
menu = dynmen.Menu(['fzf', '--prompt=Name of person:'])
)- Optionally set menu options like font, color, or sorting
- Optionally set process mode to blocking or non-blocking (
concurrent.futures
orasyncio
) - Menu objects may be created from a few classes
- The barebones
dynmen.Menu
- Menu-specific classes like
dynmen.rofi.Rofi
ordynmen.dmenu.DMenu
which use property descriptors for all of the menu's options
- The barebones
- Call the instance with some data (e.g.,
result = menu({'a':1, 'b':2, 'c':3})
)
To get a feel for how this is used refer to the examples directory which contains a number of self-contained example scripts using dynmen. The following gif records using one of those examples fzf_example.py.
exdict = {
'Alyssa Boyd': ('Brownmouth', '09044'),
'Candice Huber': ('New Kimberly', '11698'),
'Dr. Kelli Sharp MD': ('North Rhondashire', '71761'),
'Gary Hernandez': ('Burnshaven', '62267'),
'Hannah Williams': ('North Stacy', '50983'),
'Monique Mccoy': ('Katherinemouth', '42023'),
'Trevor Kelly': ('South Jenniferport', '73366'),
}
from dynmen import Menu
menu = Menu(['fzf', '--prompt=Name of person:'])
out = menu(exdict)
print('Output from fzf:', out)
Please see the examples folder for more examples. I've also used it in other a number of other projects like dynmen_scripts and python-vpnmenu.
dynmen is supported on python versions 2.7-3.x
pip install --user dynmen
git clone https://github.com/frostidaho/dynmen.git
cd dynmen
make install-user
Please read General Usage first before reading this section.
The dynmen.Menu
class is the foundational menu class in the package. The application specific menu classes
DMenu
and Rofi
are built on top of it. If you want to use some dynamic menu which doesn't have a dynmen
specific class, you can launch the menu through dynmen.Menu
.
from dynmen import Menu
rofi = Menu(['rofi', '-dmenu'])
result = rofi({'first': 1, 'second': 2, 'third': 3})
print(result)
The menu.process_mode
attribute can be set to blocking
, futures
, or asyncio
.
from dynmen import Menu
rofi = Menu(['rofi', '-dmenu'], process_mode='futures')
future = rofi(list('abcdefghijklmnopqrstuvwxyz'))
print(future.result())
This example uses the Rofi()
class which is generated from
the rofi man page, and whose attributes correspond to rofi
command-line flags. For example, rofi ... -font 'monospace 20'
is
equivalent to menu = Rofi(); menu.font = 'monospace 20'
. You can
also set attributes through the constructor Rofi(font='monospace 20')
.
exdict = {
'Alyssa Boyd': ('Brownmouth', '09044'),
'Amy Martin': ('Mikechester', '33477'),
'Angela Mcdonald': ('North Gwendolynberg', '29053'),
'Bradley Santos': ('Andrewsmouth', '72513'),
'Brittany Manning': ('South Danielmouth', '44482'),
'Candice Huber': ('New Kimberly', '11698'),
'Cheyenne Thornton': ('New Anthony', '88618'),
'Dr. Kelli Sharp MD': ('North Rhondashire', '71761'),
'Evan Osborne': ('Andrewsside', '14378'),
'Gary Hernandez': ('Burnshaven', '62267'),
'George Elliott': ('Calebton', '55053'),
'Hannah Williams': ('North Stacy', '50983'),
'James Taylor': ('Gallegoshaven', '95677'),
'John White': ('Hansenhaven', '44559'),
'Monique Mccoy': ('Katherinemouth', '42023'),
'Randy Campos': ('South Scotthaven', '47692'),
'Rebecca Wolfe': ('Torresburgh', '37979'),
'Ronald Parks': ('Turnerland', '96367'),
'Russell Schroeder': ('Smithfurt', '39696'),
'Trevor Kelly': ('South Jenniferport', '73366'),
}
from dynmen.rofi import Rofi
menu = Rofi(lines=10, hide_scrollbar=True)
menu.prompt = "Name of person: "
menu.font = 'DejaVu Sans 30'
menu.case_insensitive = True
out = menu(exdict)
print(out)