pmenu
pmenu copied to clipboard
A dynamic terminal-based menu inspired by dmenu written in Python without dependencies with an optional MRU ordering which could also be used as an application launcher and CtrlP alternative.
pmenu
A dynamic terminal-based menu inspired by dmenu written in Python without dependencies with an optional MRU ordering which could also be used as an application launcher and CtrlP alternative.
Discussion: https://bbs.archlinux.org/viewtopic.php?id=201674.
Dependencies
Python 3.3+.
Usage examples
Display some menu items:
echo -e "foo\nbar\nbaz" | pmenu
pmenu foo bar baz
echo -e "foo\nbar" | pmenu baz qux

Pick some file from the current directory:
command ls /usr/bin/ | pmenu
find -maxdepth 3 -type f ! -path "./.git/*" ! -path "./.svn/*" -printf '%P\n' | LC_COLLATE=C sort | pmenu

Pick some file from the current directory for editing in VIM using Ctrl-P shortcut (a la the CtrlP plugin):
function! Pmenu()
let item_command = "find -maxdepth 3 -type f -regextype posix-egrep ! -regex '.*/(__pycache__|\.git|\.svn|node_modules)/.*' -printf '%P\\n'"
if isdirectory("./.git")
let item_command = "git ls-files"
endif
let cache_name = fnamemodify(getcwd(), ":t")
let items = sort(systemlist(item_command))
let current_item = expand("%:.")
if !empty(current_item)
let items = filter(copy(items), "v:val != " . shellescape(current_item))
endif
let selected_items = systemlist("pmenu -n " . shellescape(cache_name), items)
if !empty(selected_items)
execute "edit " . fnameescape(selected_items[0])
endif
redraw!
endfunction
nnoremap <silent> <C-P> :call Pmenu()<CR>
vnoremap <silent> <C-P> :call Pmenu()<CR>

Pick a title from the markdown file and jump to it:
function! PmenuMarkdownTitle()
let titles = filter(getline(1, '$'), "v:val =~ '^#\\+\\s'")
let selected_paths = systemlist('pmenu', titles)
if !empty(selected_paths)
call search('^#\+\s' . selected_paths[0])
endif
redraw!
endfunction
nnoremap <silent> <C-T> :call PmenuMarkdownTitle()<CR>
Pick and show a definition from the WordNet dictionary on the dict server (dict.org by default) using either the curl or dict command:
pmenu -c "m={} && curl -s \"dict://dict.org/m:\${m:-a}:wn:prefix\" | awk -F \\\" '! array[tolower(\$2)]++ { print \$2 }'" | xargs -I '{}' curl -s "dict://dict.org/d:{}:wn" | grep -vP "^(\d+ |\.)" | less
pmenu -c "dict -fm -d wn -s prefix -- {} | awk '! array[tolower(\$4)]++ { print \$4 }'" | xargs dict -d wn | less
Pick and start a VirtualBox virtual machine:
vboxmanage startvm "`vboxmanage list vms | sed 's/^"\(.*\)".*/\1/' | pmenu`"
Pick and jump to a subdirectory in ~/Projects:
cd "`cd ~/Projects; pmenu *`"
pmenu-run
The script pmenu-run is an example of an application launcher built with pmenu similar to dmenu_run, gmrun and bashrun. It builds the menu from system *.desktop files and launches the selected item in the current terminal or detached from it depending on the application type.
Bind any shortcut using your desktop preferences to one the following commands depending of what terminal emulator you use:
xterm -e pmenu-run
urxvt -e pmenu-run
pmenu-run passes all provided additional options to pmenu. This could be used to add more items to the launcher menu, like pmenu-run command1 command2 command3.
Installation
Copy pmenu (and optionally pmenu-run) to any location from your $PATH, say /usr/local/bin.
There is the AUR package for Arch Linux: https://aur.archlinux.org/packages/pmenu/.
Command-line interface
usage: pipe newline-separated menu items to stdin and/or pass them as positional arguments
positional arguments:
item the menu item text
optional arguments:
-h, --help show this help message and exit
-c COMMAND, --command COMMAND
the shell command which output will populate the menu
items on every keystroke ({} will be replaced by the
current input text)
-n NAME, --name NAME the cache file name with the most recently used items
-p PROMPT, --prompt PROMPT
the prompt text
-v, --version show program's version number and exit
Keyboard shortcuts
Ctrl-C,Ctrl-G,Ctrl-[,Escape: quit without selecting an itemCtrl-H,Backspace: delete the character before the cursorCtrl-I,Tab: complete the selected itemCtrl-J,Ctrl-M,Enter: quit and output the selected itemCtrl-N, 'Down': select the next itemCtrl-P, 'Up': select the previous itemCtrl-U: delete the entire lineCtrl-W: delete the word before the cursor
Alternatives
dmenu-like menus
- Heatseeker
Rustterminal - Icepick
Rustterminal - PathPicker
Pythonterminal - Selecta
Rubyterminal - bemenu
CWaylandX11terminal - dmenu2
CX11 - dmenu
CX11 - fzf
Goterminal - fzy
Cterminal - gof
Goterminal - gpicker
CX11 - happyfinder
Goterminal - hmenu
Haskellterminal - peco
Goterminal - percol
Pythonterminal - pick
Cterminal - rofi
CX11 - selector
Cterminal - slmenu
Cterminal - smenu
Cterminal - tmenu
Cterminal - tpick
Cterminal - ppick 'C' 'terminal'
- vis-menu
Cterminal
dmenu wrappers
Application launchers
- Albert
C++X11 - Kupfer
PythonX11 - bashrun2
Bashterminal - bashrun
Bashterminal - dmenu_run
ShellX11 - gmrun
CX11 - lighthouse
CX11 - rrun
RustX11 - shellex
CX11 - xboomx
PythonX11 - xlauncher
CX11
Vim menus
License and copyright
The project is released under the General Public License (GPL), version 3.
Copyright © 2015, Danil Semelenov.