Package: simple-term-menu
Simple Terminal MenuOverviewsimple-term-menucreates simple menus for interactive command line programs. It can be used to offer a choice of
different options to the user. Menu entries can be selected with the arrow, j/k, or emacs (C-n/C-p) keys. The module
uses the terminfo database to detect terminal features automatically and disables styles that are not available.
Currently, Linux and macOS are supported.Breaking changesFrom version 0.x to 1.xIf you update from version 0.x to 1.x, please consider these breaking changes:TheTerminalMenuconstructor now only takes keyword-only arguments (except for the first parameter which contains
the menu entries). This makes it easier to add new parameters in future releases and allows to keep a well-arranged
parameter list.The command line interface was revised. It now uses-instead of_to separate words consistently and rearranges
short options. Only the most important short options were kept to save free letters for future releases.From version 1.1 to 1.2Themulti_select_keyparameter is now namedmulti_select_keysand takes an iterable of keys and by defaultspaceandtabare now used as multi-select keys. This allows to toggle selected items in search mode.Theshortcut_parentheses_highlight_styleparameter is renamed toshortcut_brackets_highlight_styleto be more
consistent with the newmulti_select_cursor_brackets_styleparameter.Installationsimple-term-menuis available on PyPI for Python 3.5+ and can be installed withpip:python3-mpipinstallsimple-term-menuIf you use Arch Linux or one of its derivatives, you can also installsimple-term-menufrom theAUR:yay-Spython-simple-term-menuYou also find self-contained executables for 64-bit Linux distributions and macOS High Sierra and newer on thereleases page. They are created withPyInstallerand only require glibc >= 2.17 on Linux (should be fine on any recent
Linux system).UsageCreate a menu with the default styleCreate an instance of the classTerminalMenuand pass the menu entries as a list of strings to the constructor. Call
theshowmethod to output the menu and wait for keyboard input:#!/usr/bin/env python3fromsimple_term_menuimportTerminalMenudefmain():options=["entry 1","entry 2","entry 3"]terminal_menu=TerminalMenu(options)menu_entry_index=terminal_menu.show()print(f"You have selected{options[menu_entry_index]}!")if__name__=="__main__":main()You will get an output like:You can now select a menu entry with the arrow keys orj/k(vim motions) and accept your choice by hitting enter or
cancel the menu with escape,qor<Ctrl>-C.showreturns the selected menu entry index orNoneif the menu was
canceled.Long menus can be scrolled quickly with the page up and page down keys (or<Ctrl>-f/<Ctrl-b>for vim users).You can pass an optionaltitleto theTerminalMenuconstructor which will be placed above the menu.titlecan be a
simple string, a multiline string (with\nnewlines) or a list of strings. The same applies to thestatus_barparameter, which places a status bar below the menu. Moreover, you can use a callable asstatus_barparameter which
takes the currently selected entry and returns a status bar string.StylingYou can pass styling arguments to theTerminalMenuconstructor. Each style is a tuple of keyword strings. Currently
the following keywords are accepted:bg_blackbg_bluebg_cyanbg_graybg_greenbg_purplebg_redbg_yellowfg_blackfg_bluefg_cyanfg_grayfg_greenfg_purplefg_redfg_yellowbolditalicsstandoutunderlineYou can alter the following styles:menu_cursor_style: The style of the shown cursor. The default style is("fg_red", "bold").menu_highlight_style: The style of the selected menu entry. The default style is("standout",).search_highlight_style: The style of matched search strings. The default style is("fg_black", "bg_yellow", "bold").shortcut_key_highlight_style: The style of shortcut keys. The default style is("fg_blue",).shortcut_brackets_highlight_style: The style of brackets enclosing shortcut keys. The default style is("fg_gray",).status_bar_style: The style of the status bar below the menu. The default style is("fg_yellow", "bg_black").multi_select_cursor_style: The style of the cursor which pins a selected entry in a multi-selection. The default
style is("fg_yellow", "bold"). This style excludes brackets (see below).multi_select_cursor_brackets_style: The style of brackets in themulti_select_cursor(([{<)]}>). The default
style is("fg_gray",).By settingmenu_cursoryou can define another cursor or disable it (None). The default cursor is"> ".
The parametermulti_select_cursorcustomizes the multi-select cursor (the default is"[*] ").Searchingsimple_term_menuhas a built-in search feature to filter shown menu entries. The default key to activate search mode
is/(like in Vim, less and other terminal programs). If you prefer another search key, pass asearch_keyparameter
to theTerminalMenuconstructor.Nonecan be passed to activate the search on every letter key. Obviously,jandkcannot be used for cursor motions in that mode. Use<Ctrl-j>and<Ctrl-k>instead.The search mode supports Python regex syntax. Visit thePython re documentationfor more details.String parts of the menu entries which match the given search pattern are highlighted. Use thesearch_highlight_styleparameter to adjust the highlight style to your liking.By default, the search is case insensitive. Setsearch_case_sensitivetoTrueif you prefer a case sensitive search
line.Passshow_search_hint=Trueto theTerminalMenuconstructor to activate a search hint in the search line (like(Press "/" to search)).ShortcutsYou can define shortcuts for selected menu entries by prepending a single character enclosed in square brackets (like[a]). Passshortcut_key_highlight_styleand/orshortcut_brackets_highlight_styleto theTerminalMenuconstructor
to change the default highlight style of the shortcuts.By default, theshowmethod returns when a shortcut key is pressed. If you only want the selection to jump the
shortcut target, passexit_on_shortcut=Falseto theTerminalMenuconstructor.If you configured the search to be activated on every letter key, the shortcut feature will be disabled.Passshow_shortcut_hints=Trueto theTerminalMenuconstructor to display shortcut hints in the status bar (useful
for very long menus which need scrolling). Additionally passshow_shortcut_hints_in_status_bar=Falseif you prefer
shortcut hints in the menu title.Shortcuts exampleCreate a menu of some fruits and use the first letter as shortcut key:#!/usr/bin/env python3importosfromsimple_term_menuimportTerminalMenudefmain():fruits=["[a] apple","[b] banana","[o] orange"]terminal_menu=TerminalMenu(fruits,title="Fruits")menu_entry_index=terminal_menu.show()if__name__=="__main__":main()Custom accept keysThe default key to accept a menu item isenter. Pass theaccept_keysparameter with a tuple of keys (as strings) to
theTerminalMenuconstructor to use a different set of accept keys. Custom accept keys can be plain ascii letters or
ascii letters with a modifier key (prependctrl-oralt-to an ascii letter). Use thechosen_accept_keyproperty
of theTerminalMenuinstance to query which accept key was pressed by the user.Be aware that not all combinations of modifier and ascii keys will work depending on your terminal emulator and
graphical user interface. In addition, some combinations generate other existing keys (e.g.ctrl-misenter/
carriage return).Custom accept keys example#!/usr/bin/env python3fromsimple_term_menuimportTerminalMenudefmain():terminal_menu=TerminalMenu(["entry 1","entry 2","entry 3"],accept_keys=("enter","alt-d","ctrl-i"))menu_entry_index=terminal_menu.show()print(terminal_menu.chosen_accept_key)if__name__=="__main__":main()Multi-selectPassmulti_select=Trueto theTerminalMenuconstructor to enable the multi-select mode. Pressspaceortabon an
arbitrary menu item to add it to your selection. Pressenter(or any other configuredaccept_key) to add the
currently selected entry as the last item to the selection and to return from theshowmethod as usual. In
multi-select mode, theshowmethod returns a sorted tuple of all your selected menu indices instead of a single int.
Use thechosen_menu_entriesproperty to get a tuple of the menu entry strings instead. By settingmulti_select_keysyou can define another set of keys to toggle a selected item. By passingshow_multi_select_hint=Truea multi-select
mode hint is shown in the status bar. If you don't want theaccept_keyto also select the last highlighted item you
can passmulti_select_select_on_accept=False. If no menu item is explicitly selected, the last highlighted menu item
will still be added to the selection unless you also passmulti_select_empty_ok=True.An optional list (or any other iterable object)preselected_entriescan also be passed to have items already selected
when the menu is displayed.  This list can be composed of either integers representing indexes of themenu_entrieslist, or strings matching the elements ofmenu_entries. Integers and strings can be mixed.Multi-select example#!/usr/bin/env python3fromsimple_term_menuimportTerminalMenudefmain():terminal_menu=TerminalMenu(["dog","cat","mouse","squirrel"],multi_select=True,show_multi_select_hint=True,)menu_entry_indices=terminal_menu.show()print(menu_entry_indices)print(terminal_menu.chosen_menu_entries)if__name__=="__main__":main()Preview windowsimple-term-menucan show a preview for each menu entry. Pass apreview_commandto theTerminalMenuconstructor to
activate this optional feature.preview_commandeither takes a command string which will be executed as a subprocess
or a Python callable which converts a given menu entry string into the preview output. If a command string is given, the
pattern{}is replaced with the current menu entry string. If a menu entry has an additional data component (separated
by|), it is passed instead to the preview command.\|can be used for a literal|. If you simply append a|(without a data component), the preview window will be disabled for this entry.The additional keyword argumentpreview_sizecan be used to control the height of the preview window. It is given as
fraction of the complete terminal height (default:0.25). The width cannot be set, it is always the complete width of
the terminal window.Passpreview_titlewith a string of your choice to customize the preview window title (default:"preview") orpreview_border=Falseto deactivate the border around the preview window (also deactivates the title string).Preview commands are allowed to generateANSI escape color codes.Preview examplesCreate a menu for all files in the current directory and preview their contents with thebatcommand:#!/usr/bin/env python3importosfromsimple_term_menuimportTerminalMenudeflist_files(directory="."):return(fileforfileinos.listdir(directory)ifos.path.isfile(os.path.join(directory,file)))defmain():terminal_menu=TerminalMenu(list_files(),preview_command="bat --color=always{}",preview_size=0.75)menu_entry_index=terminal_menu.show()if__name__=="__main__":main()Another file preview example using thePygmentsapi:#!/usr/bin/env python3importosfrompygmentsimportformatters,highlight,lexersfrompygments.utilimportClassNotFoundfromsimple_term_menuimportTerminalMenudefhighlight_file(filepath):withopen(filepath,"r")asf:file_content=f.read()try:lexer=lexers.get_lexer_for_filename(filepath,stripnl=False,stripall=False)exceptClassNotFound:lexer=lexers.get_lexer_by_name("text",stripnl=False,stripall=False)formatter=formatters.TerminalFormatter(bg="dark")# dark or lighthighlighted_file_content=highlight(file_content,lexer,formatter)returnhighlighted_file_contentdeflist_files(directory="."):return(fileforfileinos.listdir(directory)ifos.path.isfile(os.path.join(directory,file)))defmain():terminal_menu=TerminalMenu(list_files(),preview_command=highlight_file,preview_size=0.75)menu_entry_index=terminal_menu.show()if__name__=="__main__":main()Preview the active pane of each running tmux session (the session ids are appended to the menu entries with the|separator):#!/usr/bin/env python3importsubprocessfromsimple_term_menuimportTerminalMenudeflist_tmux_sessions():tmux_command_output=subprocess.check_output(["tmux","list-sessions","-F#{session_id}:#{session_name}"],universal_newlines=True)tmux_sessions=[]forlineintmux_command_output.split("\n"):line=line.strip()ifnotline:continuesession_id,session_name=tuple(line.split(":"))tmux_sessions.append((session_name,session_id))returntmux_sessionsdefmain():terminal_menu=TerminalMenu(("|".join(session)forsessioninlist_tmux_sessions()),preview_command="tmux capture-pane -e -p -t{}",preview_size=0.75,)menu_entry_index=terminal_menu.show()if__name__=="__main__":main()Skipping empty entriesUse the constructor parameterskip_empty_entriesor the flag--skip-empty-entriesto interpret an empty string value
in the menu entries as an empty menu entry (will be skipped when iterating over the entries). ANonevalue is always
considered as an empty menu entry independently from theskip_empty_entriesparameter.fromsimple_term_menuimportTerminalMenudefmain():# Or use `None` instead of `""`:options=["entry 1","entry 2","","add","edit"]# ["entry 1", "entry 2", None, "add", "edit"]terminal_menu=TerminalMenu(options,skip_empty_entries=True)# TerminalMenu(options)menu_entry_index=terminal_menu.show()print(f"You have selected{options[menu_entry_index]}!")if__name__=="__main__":main()Localization / Text modificationUse the constructor parametersshow_search_hint_textandshow_multi_select_hint_textto modify the corresponding texts. Use the placeholder{key}for the search key inshow_search_hint_textand both{accept_keys}and{multi_select_keys}inshow_multi_select_hint_textif appropriately.Additional settingsFurthermore, theTerminalMenuconstructor takes these additional parameters to change the menu behavior:clear_menu_on_exit: A bool value which indicates if the menu will be cleared after theshowmethod. Defaults toTrue.clear_screen: A bool value which indicates if the screen will be cleared before the menu is shown. Defaults toFalse.cursor_index: The initially selected item index.cycle_cursor: A bool value which indicates if the menu cursor cycles when the end of the menu is reached. Defaults
toTrue.quit_keys: An iterable of keys which quit the terminal menu. Defaults to("escape", "q").raise_error_on_interrupt: Set this toTrueto reraise Keyboard interrupts (by pressing<Ctrl-c>). Defaults toFalse.status_bar_below_preview: Position the status bar below the preview window (default positioning is above).Command line programsimple-term-menucan be used as a terminal program in shell scripts. The exit code of the script is the 1-based index
of the selected menu entry. The exit code 0 reports the cancel action. The following command line arguments are
supported:usage: simple-term-menu [-h] [-s] [-X] [-l] [--cursor CURSOR]
                        [-i CURSOR_INDEX] [--cursor-style CURSOR_STYLE] [-C]
                        [-E] [--highlight-style HIGHLIGHT_STYLE] [-m]
                        [--multi-select-cursor MULTI_SELECT_CURSOR]
                        [--multi-select-cursor-brackets-style MULTI_SELECT_CURSOR_BRACKETS_STYLE]
                        [--multi-select-cursor-style MULTI_SELECT_CURSOR_STYLE]
                        [--multi-select-keys MULTI_SELECT_KEYS]
                        [--multi-select-no-select-on-accept]
                        [--multi-select-empty-ok] [-p PREVIEW_COMMAND]
                        [--no-preview-border] [--preview-size PREVIEW_SIZE]
                        [--preview-title PREVIEW_TITLE]
                        [--search-highlight-style SEARCH_HIGHLIGHT_STYLE]
                        [--search-key SEARCH_KEY]
                        [--shortcut-brackets-highlight-style SHORTCUT_BRACKETS_HIGHLIGHT_STYLE]
                        [--shortcut-key-highlight-style SHORTCUT_KEY_HIGHLIGHT_STYLE]
                        [--show-multi-select-hint]
                        [--show-multi-select-hint-text SHOW_MULTI_SELECT_HINT_TEXT]
                        [--show-search-hint]
                        [--show-search-hint-text SHOW_SEARCH_HINT_TEXT]
                        [--show-shortcut-hints]
                        [--show-shortcut-hints-in-title]
                        [--skip-empty-entries] [-b STATUS_BAR] [-d]
                        [--status-bar-style STATUS_BAR_STYLE] [--stdout]
                        [-t TITLE] [-V]
                        [-r PRESELECTED_ENTRIES | -R PRESELECTED_INDICES]
                        [entries ...]

simple-term-menu creates simple interactive menus in the terminal and returns the selected entry as exit code.

positional arguments:
  entries               the menu entries to show

options:
  -h, --help            show this help message and exit
  -s, --case-sensitive  searches are case sensitive
  -X, --no-clear-menu-on-exit
                        do not clear the menu on exit
  -l, --clear-screen    clear the screen before the menu is shown
  --cursor CURSOR       menu cursor (default: "> ")
  -i CURSOR_INDEX, --cursor-index CURSOR_INDEX
                        initially selected item index
  --cursor-style CURSOR_STYLE
                        style for the menu cursor as comma separated list
                        (default: "fg_red,bold")
  -C, --no-cycle        do not cycle the menu selection
  -E, --no-exit-on-shortcut
                        do not exit on shortcut keys
  --highlight-style HIGHLIGHT_STYLE
                        style for the selected menu entry as comma separated
                        list (default: "standout")
  -m, --multi-select    Allow the selection of multiple entries (implies
                        `--stdout`)
  --multi-select-cursor MULTI_SELECT_CURSOR
                        multi-select menu cursor (default: "[*] ")
  --multi-select-cursor-brackets-style MULTI_SELECT_CURSOR_BRACKETS_STYLE
                        style for brackets of the multi-select menu cursor as
                        comma separated list (default: "fg_gray")
  --multi-select-cursor-style MULTI_SELECT_CURSOR_STYLE
                        style for the multi-select menu cursor as comma
                        separated list (default: "fg_yellow,bold")
  --multi-select-keys MULTI_SELECT_KEYS
                        key for toggling a selected item in a multi-selection
                        (default: " ,tab",
  --multi-select-no-select-on-accept
                        do not select the currently highlighted menu item when
                        the accept key is pressed (it is still selected if no
                        other item was selected before)
  --multi-select-empty-ok
                        when used together with --multi-select-no-select-on-
                        accept allows returning no selection at all
  -p PREVIEW_COMMAND, --preview PREVIEW_COMMAND
                        Command to generate a preview for the selected menu
                        entry. "{}" can be used as placeholder for the menu
                        text. If the menu entry has a data component
                        (separated by "|"), this is used instead.
  --no-preview-border   do not draw a border around the preview window
  --preview-size PREVIEW_SIZE
                        maximum height of the preview window in fractions of
                        the terminal height (default: "0.25")
  --preview-title PREVIEW_TITLE
                        title of the preview window (default: "preview")
  --search-highlight-style SEARCH_HIGHLIGHT_STYLE
                        style of matched search patterns (default:
                        "fg_black,bg_yellow,bold")
  --search-key SEARCH_KEY
                        key to start a search (default: "/", "none" is treated
                        a special value which activates the search on any
                        letter key)
  --shortcut-brackets-highlight-style SHORTCUT_BRACKETS_HIGHLIGHT_STYLE
                        style of brackets enclosing shortcut keys (default:
                        "fg_gray")
  --shortcut-key-highlight-style SHORTCUT_KEY_HIGHLIGHT_STYLE
                        style of shortcut keys (default: "fg_blue")
  --show-multi-select-hint
                        show a multi-select hint in the status bar
  --show-multi-select-hint-text SHOW_MULTI_SELECT_HINT_TEXT
                        Custom text which will be shown as multi-select hint.
                        Use the placeholders {multi_select_keys} and
                        {accept_keys} if appropriately.
  --show-search-hint    show a search hint in the search line
  --show-search-hint-text SHOW_SEARCH_HINT_TEXT
                        Custom text which will be shown as search hint. Use
                        the placeholders {key} for the search key if
                        appropriately.
  --show-shortcut-hints
                        show shortcut hints in the status bar
  --show-shortcut-hints-in-title
                        show shortcut hints in the menu title
  --skip-empty-entries  Interpret an empty string in menu entries as an empty
                        menu entry
  -b STATUS_BAR, --status-bar STATUS_BAR
                        status bar text
  -d, --status-bar-below-preview
                        show the status bar below the preview window if any
  --status-bar-style STATUS_BAR_STYLE
                        style of the status bar lines (default:
                        "fg_yellow,bg_black")
  --stdout              Print the selected menu index or indices to stdout (in
                        addition to the exit status). Multiple indices are
                        separated by ";".
  -t TITLE, --title TITLE
                        menu title
  -V, --version         print the version number and exit
  -r PRESELECTED_ENTRIES, --preselected_entries PRESELECTED_ENTRIES
                        Comma separated list of strings matching menu items to
                        start pre-selected in a multi-select menu.
  -R PRESELECTED_INDICES, --preselected_indices PRESELECTED_INDICES
                        Comma separated list of numeric indexes of menu items
                        to start pre-selected in a multi-select menu.Example with preview optionInstead of using the Python api as in theprevious examples, a file menu withbatpreview can
also be created from the command line:simple-term-menu-p"bat --color=always {}"\--preview-size0.75\$(find.-maxdepth1-typef|awk'{ print substr($0, 3) }')More advanced exampleA more advanced example with sub menus (thanks topageauc):#!/usr/bin/env python3"""Demonstration example for GitHub Project athttps://github.com/IngoMeyer441/simple-term-menuThis code only works in python3. Install persudo pip3 install simple-term-menu"""importtimefromsimple_term_menuimportTerminalMenudefmain():main_menu_title="  Main Menu.\nPress Q or Esc to quit.\n"main_menu_items=["Edit Menu","Second Item","Third Item","Quit"]main_menu_cursor="> "main_menu_cursor_style=("fg_red","bold")main_menu_style=("bg_red","fg_yellow")main_menu_exit=Falsemain_menu=TerminalMenu(menu_entries=main_menu_items,title=main_menu_title,menu_cursor=main_menu_cursor,menu_cursor_style=main_menu_cursor_style,menu_highlight_style=main_menu_style,cycle_cursor=True,clear_screen=True,)edit_menu_title="  Edit Menu.\nPress Q or Esc to back to main menu.\n"edit_menu_items=["Edit Config","Save Settings","Back to Main Menu"]edit_menu_back=Falseedit_menu=TerminalMenu(edit_menu_items,title=edit_menu_title,menu_cursor=main_menu_cursor,menu_cursor_style=main_menu_cursor_style,menu_highlight_style=main_menu_style,cycle_cursor=True,clear_screen=True,)whilenotmain_menu_exit:main_sel=main_menu.show()ifmain_sel==0:whilenotedit_menu_back:edit_sel=edit_menu.show()ifedit_sel==0:print("Edit Config Selected")time.sleep(5)elifedit_sel==1:print("Save Selected")time.sleep(5)elifedit_sel==2oredit_sel==None:edit_menu_back=Trueprint("Back Selected")edit_menu_back=Falseelifmain_sel==1:print("option 2 selected")time.sleep(5)elifmain_sel==2:print("option 3 selected")time.sleep(5)elifmain_sel==3ormain_sel==None:main_menu_exit=Trueprint("Quit Selected")if__name__=="__main__":main()Similar projectsbullet: Creates bullet-lists with multi-selection support.ContributingPlease openan issue on GitHubif you experience bugs or
miss features. Please consider to send a pull request if you can spend time on fixing the issue yourself. This project
usespre-committo ensure code quality and a consistent code style. Runmakegit-hooks-installto install all linters as Git hooks in your local clone ofsimple-term-menu.