Skip to content

Key actions

rovr lets you inherit from one of three built-in keybinding sets: base, vim, or sane.

If keys.toml is empty or does not exist, rovr will use the older, unsupported keybindings (not the base set, the one defined in config.toml)

Assign an action to a key under a context in keys.toml. A binding may be an action string or an inline table with a required action and optional desc:

[main]
"ctrl+t" = "tab_new"
"?" = { action = "show_keybinds", desc = "Show keybindings" }
# yes function-like syntax is supported, for supported literal values
"1" = "activate_tab(0)"
# check https://docs.python.org/3/library/ast.html#ast.literal_eval
# obviously dont pass anything stupid
[file_list]
"ctrl+c" = "copy.to_rovr"

Both forms dispatch actions identically. desc is shown in the keybindings screen; when it is omitted, the action string is shown instead. Bindings for the same action in one context are grouped together, so only one of them needs a description:

[global]
"q" = { action = "app.quit", desc = "Quit rovr" }
"ctrl+q" = "app.quit"

The name of a Python method such as action_tab_new becomes tab_new in keys.toml. Arguments use Textual’s action syntax: cycle_tab(-1), cursor(1), or sort_order.set("modified", True).

If in this reference, angled brackets (like <bool>) is used, it means that the action does not require that value, but it can be passed. For example, app.quit can be called as app.quit(True) or app.quit(False), but the default is True.

Actions without a prefix run on the owner of the active context. The following namespaces can target another object explicitly:

Namespace Target Example
app The rovr application app.quit
screen The currently active screen screen.exit
Primary context The mounted owner of that context copy.to_rovr

Primary context namespaces include copy and sort_order. Prefer an unqualified action when the action belongs to the context containing the binding.

rovr checks contexts from the focused widget outward. The first matching action wins. Specific contexts are checked before reusable contexts, such as file_list before lists and search_input before inputs.

main is available only while the main screen is unobstructed. global is checked separately for application-wide bindings, including while a modal is open. Set an inherited key to noop to consume it without running an action.

inherit = "vim"
[file_list]
"q" = "noop"
[global]
"ctrl+q" = "app.quit"

Use global sparingly for actions that must work regardless of the active screen.

Action Description Example
app.quit(<bool>) Quit rovr. If True (default) and using cd-on-quit, will switch to the focused directory "ctrl+q" = "app.quit"
app.command_palette Open Textual’s command palette. "ctrl+p" = "app.command_palette"
app.suspend_process Suspend rovr on supported systems. "ctrl+z" = "app.suspend_process"

The application context used while the main screen is active and no modal screen is overlaying it. The app. prefix is optional here.

Action Description Example
activate_tab(index) Activate a tab by zero-based index. "1" = "activate_tab(0)"
cycle_tab(offset) Move relative to the current tab. "ctrl+j" = "cycle_tab(1)"
tab_next Activate the next tab. "ctrl+j" = "tab_next"
tab_previous Activate the previous tab. "ctrl+k" = "tab_previous"
tab_new Create a tab. "ctrl+t" = "tab_new"
tab_close Close the current tab. "ctrl+w" = "tab_close"
focus_file_list Focus the active file list. "escape" = "focus_file_list"
focus_next Focus the next focusable widget. "tab" = "focus_next"
focus_previous Focus the previous focusable widget. "shift+tab" = "focus_previous"
focus_toggle_pinned_sidebar Switch between the pinned sidebar and file list. "s" = "focus_toggle_pinned_sidebar"
focus_toggle_preview_sidebar Switch between the preview and file list. "i" = "focus_toggle_preview_sidebar"
focus_toggle_path_switcher Switch between the path input and file list. "ctrl+l" = "focus_toggle_path_switcher"
focus_toggle_processes Switch between processes and file list. "p" = "focus_toggle_processes"
focus_toggle_clipboard Switch between the clipboard and file list. "c" = "focus_toggle_clipboard"
focus_toggle_metadata Switch between metadata and file list. "m" = "focus_toggle_metadata"
toggle_pinned_sidebar Show or hide the pinned sidebar. "S" = "toggle_pinned_sidebar"
toggle_preview_sidebar Show or hide the preview. "I" = "toggle_preview_sidebar"
toggle_footer Show or hide the footer. "F" = "toggle_footer"
toggle_menu_wrapper Show or hide the menu bar. "M" = "toggle_menu_wrapper"
change_theme Open the theme chooser. "T" = "change_theme"
show_keybinds Open the active keybindings screen. "?" = "show_keybinds"
show_shell_screen Open a shell command screen in this directory. ">" = "show_shell_screen"
print_dom Equivalent of rovr --tree-dom: prints widget tree to stdout "ctrl+shift+d" = "print_dom"
cd_zoxide Open the zoxide directory chooser. "z" = "cd_zoxide"
search_fd Open recursive file search. "f" = "search_fd"
search_rg Open file-content search. "\\" = "search_rg"
open_recycle_bin Open the recycle bin. "T" = "open_recycle_bin"

You can run shell/argv commands using the app context. The run_command action runs a command as an argv list, while run_shell runs a command through the shell. Both actions accept an optional run_type arg (not kwarg) that can be one of (“suspend”, “background”, “orphan”) (uses “background” by default.)

  • suspend: hides rovr’s ui and runs the command in the foreground, returning to rovr when it exits
  • background: runs the command in the background, returning to rovr immediately. it will stop process when exiting
  • orphan: runs the command detached, rovr cannot read stdout/stderr/exit code, and will not stop the process on exit
Action Description Example
run_command(list[str], <command-type>) Run an argv command in the current directory. "@" = 'run_command(["echo", "hello world"], "orphan")'
run_shell(str, <command-type>) Run a shell command in the current directory. "ctrl+@" = 'run_shell("echo hello world", "orphan")'

Actions specific to the focused file list. Generic list actions from lists also work here.

Action Description Example
open Open the highlighted or selected items. "enter" = "open"
open_editor Open items in the configured editor. "e" = "open_editor"
open_right_click_menu Open the context menu. "shift+f10" = "open_right_click_menu"
up_tree Go to the parent directory. "left" = "up_tree"
bypass_up_tree Leave single-child directory chains. "H" = "bypass_up_tree"
bypass_down_tree Enter single-child directory chains. "L" = "bypass_down_tree"
hist_previous(bool) Go backward in directory history. If True, will go to parent directory if there is no more history "backspace" = "hist_previous"
hist_next Go forward in directory history. "space" = "hist_next"
toggle_pin Pin or unpin the current directory. "P" = "toggle_pin"
copy Copy selected items to rovr’s clipboard. "y" = "copy"
cut Cut selected items. "x" = "cut"
paste Paste items into the current directory. "p" = "paste"
new Create a file or directory. "a" = "new"
bulk_create Create multiple items using the editor. "A" = "bulk_create"
rename Rename selected items. "r" = "rename"
delete Open the deletion confirmation. "d" = "delete"
zip Create an archive from selected items. "E" = "zip"
unzip Extract the highlighted archive. "ctrl+e" = "unzip"
focus_search Focus the file-list search input. "/" = "focus_search"
toggle_hidden_files Show or hide hidden files. "." = "toggle_hidden_files"
toggle_visual Enter or leave visual selection mode. "v" = "toggle_visual"
toggle_all Select or clear every item. "%" = "toggle_all"
invert_selections Invert selections (unselects selected items, selects unselected items) "ctrl+r" = "invert_selections"
toggle_select_item Toggle the highlighted item. "insert" = "toggle_select_item"
select_cursor(offset, <bool>) Extend selection by an item offset. If True, will wrap on top and bottom "shift+down" = "select_cursor(1, False)"
select_cursor_page(pages) Extend selection by visible pages. "shift+pagedown" = "select_cursor_page(1)"
select_home Extend selection to the first item. "shift+home" = "select_home"
select_end Extend selection to the last item. "shift+end" = "select_end"
copy.open_popup Open the extra copy actions menu. "Y" = "copy.open_popup"
sort_order.open_popup Open the sort menu. "," = "sort_order.open_popup"

Uses all lists actions and adds focus_search, which focuses the pinned-folder search input.

Uses all lists actions. It also supports delete to remove the highlighted clipboard entry, toggle_all to select or clear all entries, and the range-selection actions described below.

Uses all scroll actions. delete clears completed and failed processes.

Both support the scroll actions. preview additionally provides up, down, page_up, page_down, home, and end for navigating rendered content.

The fallback context for option and selection lists. It is shared by file lists, popup menus, search results, archive options, trash entries, and other selectable lists.

Action Description Example
cursor(offset, <bool>) Move by a number of enabled items. If True (default), will wrap on top and bottom "j" = "cursor(1)"
cursor_page(pages) Move by a number of visible pages. "pagedown" = "cursor_page(1)"
first Move to the first item. "home" = "first"
last Move to the last item. "end" = "last"
select Activate or toggle the highlighted item. "enter" = "select"

Selection-list contexts also provide select_cursor(offset, bool) and select_cursor_page(pages) for extending a selection. These include file_list, clipboard, file_search_filters, content_search_filters, archive_types, archive_compression, and trash_list.

The following primary contexts inherit lists: file_list, pinned_sidebar, clipboard, popup_list, file_list_menu, file_list_submenu, search_results, special_option_list, file_search_filters, content_search_filters, keybind_list, archive_types, archive_compression, paste_drop_list, and trash_list.

The fallback context for text inputs, including path_input, search_input, filter_input, and modal_input_field.

Action Description Example
cursor_left Move left by one character. "left" = "cursor_left"
cursor_right Move right by one character. "right" = "cursor_right"
cursor_left_word Move left by one word. "ctrl+left" = "cursor_left_word"
cursor_right_word Move right by one word. "ctrl+right" = "cursor_right_word"
home Move to the start of the input. "home" = "home"
end Move to the end of the input. "end" = "end"
delete_left Delete the character to the left. "backspace" = "delete_left"
delete_right Delete the character to the right. "delete" = "delete_right"
delete_left_word Delete the word to the left. "ctrl+backspace" = "delete_left_word"
delete_right_word Delete the word to the right. "ctrl+delete" = "delete_right_word"
delete_left_all Delete everything to the left. "ctrl+u" = "delete_left_all"
delete_right_all Delete everything to the right. "ctrl+k" = "delete_right_all"
select_all Select the entire value. "ctrl+a" = "select_all"
copy Copy selected text. "ctrl+c" = "copy"
cut Cut selected text. "ctrl+x" = "cut"
paste Paste text. "ctrl+v" = "paste"
submit Submit the current value. "enter" = "submit"

The fallback context for scrollable panels, including preview, metadata, and processes.

Action Description Example
scroll_up Scroll up one step. "up" = "scroll_up"
scroll_down Scroll down one step. "down" = "scroll_down"
scroll_left Scroll left one step. "left" = "scroll_left"
scroll_right Scroll right one step. "right" = "scroll_right"
scroll_page_up Scroll up one page. "pageup" = "scroll_page_up"
scroll_page_down Scroll down one page. "pagedown" = "scroll_page_down"
scroll_page_left Scroll left one page. "shift+pageup" = "scroll_page_left"
scroll_page_right Scroll right one page. "shift+pagedown" = "scroll_page_right"
scroll_home Scroll to the beginning. "home" = "scroll_home"
scroll_end Scroll to the end. "end" = "scroll_end"
Action Description
copy.to_rovr Copy selected files to rovr’s clipboard.
copy.highlighted Copy the highlighted path.
copy.to_system_clip Copy selected paths to the system clipboard.
copy.current_directory Copy the current directory path.
Action Description
sort_order.name(<bool>) Sort by name
sort_order.extension(<bool>) Sort by file extension
sort_order.natural(<bool>) Sort by natural numbers
sort_order.size(<bool>) Sort by size
sort_order.created(<bool>) Sort by created time
sort_order.modified(<bool>) Sort by modified time

all of the above actions accept a boolean argument to indicate ascending (False) or descending (True) order. If unspecified or None, the order will remain ascending/descending as it was before.

The lower-level action sort_order.set(method, <descending>) accepts a method name and a Boolean:

[file_list]
"alt+m" = "sort_order.set('modified', True)"

Shared by file_search, content_search, directory_jump, theme_chooser, and keybinds.

Action Description Example
exit Close the modal. "escape" = "exit"
cursor(offset, <bool>) Move through results. Wraps if True (default) "down" = "cursor(1, False)"
cursor_page(pages) Move through results by pages. "pagedown" = "cursor_page(1)"

The keybinds context also supports focus_search. shell_exec supports cycle_mode.

Context Actions
delete_files trash, delete, cancel
trash restore, purge, empty, cancel
filename_conflict overwrite, rename, skip, cancel, dont_ask_again
file_in_use retry, skip, cancel, toggle_dont_ask_again
yes_or_no yes, no, dont_ask_again
paste_drop copy, move, cancel

These actions apply only while their corresponding modal is open.

Certain actions support expansions based on their state.

  • %state: returns “enable” if the sort order set is for that folder only. “disable” otherwise
  • %nextstate: opposite of %state
  • %State and %Nextstate: same as above, but capitalized

Run rovr --show-keys to display the key name that will be used.

Mouse buttons 4-7 are supported as keys. If your mouse has extra keys and the terminal emulator supports SGR Extended Mouse Mode, you can bind them to actions. The key names are mouse4, mouse5, mouse6, and mouse7.

Supported terminals based on testing:

  • kitty
  • Foot
  • XTerm
  • Tilix
  • Gnome Terminal
  • Ghostty

these conflicts are from terminal emulators themselves, existing due to backwards compatibility. if your terminal emulator supports kitty keyboard protocol, it should not cause issues.

original key sent as
ctrl+m enter
ctrl+i tab
ctrl+h backspace
ctrl+[ escape
alt+b ctrl+left
alt+f ctrl+right

alt keybinds are also handled a bit weirdly, there is an internal timer that checks for the escape key, and if another printable key is sent within 0.25 seconds, it will be counted as a alt+ keybind, obviously dont push it

but it exists if you want it

obviously please use kitty keyboard protocol.

as of 0.10.2, this system is not forced, you can continue using the old system, but it will be removed in 0.11.0.

how to migrate:

old syntax will not be migrated automatically
if you chose the default options in setup, you can relaunch setup with rovr --force-first-launch and regenerate your config and keybinds

for those who customised their keybinds, you need to look carefully

old keybinds are defined under [keybinds] in config.toml, and the new system is defined in keys.toml. old keybinds are based of a single preset, so to keep using that preset as base, add this to keys.toml

inherit = "base"

the new system uses <key> = <action>, not <action> = [<key>], so you need to change the syntax. for example, this:

[keybinds]
"tab_new" = ["n"]
"tab_close" = ["w"]

would be

[main]
"n" = "tab_new"
"w" = "tab_close"

for navigation, you can change it from

[keybinds]
up = ["up", "k"]
down = ["down", "j"]
up_tree = ["left", "h"]
down_tree = ["right", "l", "enter"]
bypass_up_tree = ["H"]
bypass_down_tree = ["L"]
page_up = ["pageup", "ctrl+b"]
page_down = ["pagedown", "ctrl+f"]
home = ["home", "g"]
end = ["end", "G"]

to

[lists]
# you can choose to use cursor(-1)
"up" = { action = "cursor(-1)", desc = "Move up" }
# or alternatively
# "up" = { action = "cursor_down" }
# but cursor(-1) is more consistent with the other actions
# and recommended for flexibility
"k" = "cursor(-1)"
"down" = { action = "cursor(1)", desc = "Move down" }
"j" = "cursor(1)"
"right" = { action = "select", desc = "Select" }
"l" = "select"
"enter" = "select"
"pageup" = { action = "cursor_page(-1)", desc = "Move up one page" }
"ctrl+b" = "cursor_page(-1)"
"pagedown" = { action = "cursor_page(1)", desc = "Move down one page" }
"ctrl+f" = "cursor_page(1)"
"home" = { action = "first", desc = "Move to the first item" }
"g" = "first"
"end" = { action = "last", desc = "Move to the last item" }
"G" = "last"
[scroll]
"up" = "scroll_up"
"k" = "scroll_up"
"down" = "scroll_down"
"j" = "scroll_down"
"pageup" = "scroll_page_up"
"ctrl+b" = "scroll_page_up"
"pagedown" = "scroll_page_down"
"ctrl+f" = "scroll_page_down"
"home" = "scroll_home"
"g" = "scroll_home"
"end" = "scroll_end"
"G" = "scroll_end"

for certain screens, for instance DeleteFiles, it is simpler

[keybinds.delete_files]
trash = ["d"]
delete = ["x"]
cancel = ["c", "escape"]

to

[delete_files]
"d" = "trash"
"x" = "delete"
"c" = "cancel"
"escape" = "cancel"

this may seem overly verbose, but it allows me to add more flexible actions without needing to change much of the core