Skip to content

Latest commit

 

History

History
140 lines (121 loc) · 6.42 KB

README.md

File metadata and controls

140 lines (121 loc) · 6.42 KB

Dynmen Build Status Coverage Status Supported python versions

a python interface to dynamic menus

Introduction

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

General Usage

Using dynmen to drive any dynamic menu can be broken down into two main steps

  1. 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 or asyncio)
    • Menu objects may be created from a few classes
      • The barebones dynmen.Menu
      • Menu-specific classes like dynmen.rofi.Rofi or dynmen.dmenu.DMenu which use property descriptors for all of the menu's options
  2. 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.

Installation

dynmen is supported on python versions 2.7-3.x

Installing from pypi

pip install --user dynmen

Installing development version from github

git clone https://github.com/frostidaho/dynmen.git
cd dynmen
make install-user

Code Reference

Please read General Usage first before reading this section.

Creating and configuring menu objects

Using the dynmen.Menu class

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)

Using a menu in non-blocking mode

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())

Using application-specific classes like dynmen.rofi.Rofi or dynmen.dmenu.DMenu

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)