diff --git a/ranger/.config/ranger/rc.conf b/ranger/.config/ranger/rc.conf deleted file mode 100644 index 4edf835..0000000 --- a/ranger/.config/ranger/rc.conf +++ /dev/null @@ -1,762 +0,0 @@ -# =================================================================== -# This file contains the default startup commands for ranger. -# To change them, it is recommended to create either /etc/ranger/rc.conf -# (system-wide) or ~/.config/ranger/rc.conf (per user) and add your custom -# commands there. -# -# If you copy this whole file there, you may want to set the environment -# variable RANGER_LOAD_DEFAULT_RC to FALSE to avoid loading it twice. -# -# The purpose of this file is mainly to define keybindings and settings. -# For running more complex python code, please create a plugin in "plugins/" or -# a command in "commands.py". -# -# Each line is a command that will be run before the user interface -# is initialized. As a result, you can not use commands which rely -# on the UI such as :delete or :mark. -# =================================================================== - -# =================================================================== -# == Options -# =================================================================== - -# Which viewmode should be used? Possible values are: -# miller: Use miller columns which show multiple levels of the hierarchy -# multipane: Midnight-commander like multipane view showing all tabs next -# to each other -set viewmode miller - -# How many columns are there, and what are their relative widths? -set column_ratios 1,3,4 - -# Which files should be hidden? (regular expression) -set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$ - -# Show hidden files? You can toggle this by typing 'zh' -set show_hidden true - -# Ask for a confirmation when running the "delete" command? -# Valid values are "always", "never", "multiple" (default) -# With "multiple", ranger will ask only if you delete multiple files at once. -set confirm_on_delete multiple - -# Use non-default path for file preview script? -# ranger ships with scope.sh, a script that calls external programs (see -# README.md for dependencies) to preview images, archives, etc. -#set preview_script ~/.config/ranger/scope.sh - -# Use the external preview script or display simple plain text or image previews? -set use_preview_script true - -# Automatically count files in the directory, even before entering them? -set automatically_count_files true - -# Open all images in this directory when running certain image viewers -# like feh or sxiv? You can still open selected files by marking them. -set open_all_images true - -# Be aware of version control systems and display information. -set vcs_aware false - -# State of the four backends git, hg, bzr, svn. The possible states are -# disabled, local (only show local info), enabled (show local and remote -# information). -set vcs_backend_git enabled -set vcs_backend_hg disabled -set vcs_backend_bzr disabled -set vcs_backend_svn disabled - -# Truncate the long commit messages to this length when shown in the statusbar. -set vcs_msg_length 50 - -# Use one of the supported image preview protocols -set preview_images false - -# Set the preview image method. Supported methods: -# -# * w3m (default): -# Preview images in full color with the external command "w3mimgpreview"? -# This requires the console web browser "w3m" and a supported terminal. -# It has been successfully tested with "xterm" and "urxvt" without tmux. -# -# * iterm2: -# Preview images in full color using iTerm2 image previews -# (http://iterm2.com/images.html). This requires using iTerm2 compiled -# with image preview support. -# -# This feature relies on the dimensions of the terminal's font. By default, a -# width of 8 and height of 11 are used. To use other values, set the options -# iterm2_font_width and iterm2_font_height to the desired values. -# -# * terminology: -# Previews images in full color in the terminology terminal emulator. -# Supports a wide variety of formats, even vector graphics like svg. -# -# * urxvt: -# Preview images in full color using urxvt image backgrounds. This -# requires using urxvt compiled with pixbuf support. -# -# * urxvt-full: -# The same as urxvt but utilizing not only the preview pane but the -# whole terminal window. -# -# * kitty: -# Preview images in full color using kitty image protocol. -# Requires python PIL or pillow library. -# If ranger does not share the local filesystem with kitty -# the transfer method is changed to encode the whole image; -# while slower, this allows remote previews, -# for example during an ssh session. -# Tmux is unsupported. -# -# * ueberzug: -# Preview images in full color with the external command "ueberzug". -# Images are shown by using a child window. -# Only for users who run X11 in GNU/Linux. -set preview_images_method w3m - -# Delay in seconds before displaying an image with the w3m method. -# Increase it in case of experiencing display corruption. -set w3m_delay 0.02 - -# Manually adjust the w3mimg offset when using a terminal which needs this -set w3m_offset 0 - -# Default iTerm2 font size (see: preview_images_method: iterm2) -set iterm2_font_width 8 -set iterm2_font_height 11 - -# Use a unicode "..." character to mark cut-off filenames? -set unicode_ellipsis false - -# BIDI support - try to properly display file names in RTL languages (Hebrew, Arabic). -# Requires the python-bidi pip package -set bidi_support false - -# Show dotfiles in the bookmark preview box? -set show_hidden_bookmarks true - -# Which colorscheme to use? These colorschemes are available by default: -# default, jungle, snow, solarized -set colorscheme default - -# Preview files on the rightmost column? -# And collapse (shrink) the last column if there is nothing to preview? -set preview_files true -set preview_directories true -set collapse_preview true - -# Wrap long lines in plain text previews? -set wrap_plaintext_previews false - -# Save the console history on exit? -set save_console_history true - -# Draw the status bar on top of the browser window (default: bottom) -set status_bar_on_top false - -# Draw a progress bar in the status bar which displays the average state of all -# currently running tasks which support progress bars? -set draw_progress_bar_in_status_bar true - -# Draw borders around columns? (separators, outline, both, or none) -# Separators are vertical lines between columns. -# Outline draws a box around all the columns. -# Both combines the two. -set draw_borders none - -# Display the directory name in tabs? -set dirname_in_tabs false - -# Enable the mouse support? -set mouse_enabled true - -# Display the file size in the main column or status bar? -set display_size_in_main_column true -set display_size_in_status_bar true - -# Display the free disk space in the status bar? -set display_free_space_in_status_bar true - -# Display files tags in all columns or only in main column? -set display_tags_in_all_columns true - -# Set a title for the window? Updates both `WM_NAME` and `WM_ICON_NAME` -set update_title false - -# Set the tmux/screen window-name to "ranger"? -set update_tmux_title true - -# Shorten the title if it gets long? The number defines how many -# directories are displayed at once, 0 turns off this feature. -set shorten_title 3 - -# Show hostname in titlebar? -set hostname_in_titlebar true - -# Abbreviate $HOME with ~ in the titlebar (first line) of ranger? -set tilde_in_titlebar false - -# How many directory-changes or console-commands should be kept in history? -set max_history_size 20 -set max_console_history_size 50 - -# Try to keep so much space between the top/bottom border when scrolling: -set scroll_offset 8 - -# Flush the input after each key hit? (Noticeable when ranger lags) -set flushinput true - -# Padding on the right when there's no preview? -# This allows you to click into the space to run the file. -set padding_right true - -# Save bookmarks (used with mX and `X) instantly? -# This helps to synchronize bookmarks between multiple ranger -# instances but leads to *slight* performance loss. -# When false, bookmarks are saved when ranger is exited. -set autosave_bookmarks true - -# Save the "`" bookmark to disk. This can be used to switch to the last -# directory by typing "``". -set save_backtick_bookmark true - -# You can display the "real" cumulative size of directories by using the -# command :get_cumulative_size or typing "dc". The size is expensive to -# calculate and will not be updated automatically. You can choose -# to update it automatically though by turning on this option: -set autoupdate_cumulative_size false - -# Turning this on makes sense for screen readers: -set show_cursor false - -# One of: size, natural, basename, atime, ctime, mtime, type, random -set sort natural - -# Additional sorting options -set sort_reverse false -set sort_case_insensitive true -set sort_directories_first true -set sort_unicode false - -# Enable this if key combinations with the Alt Key don't work for you. -# (Especially on xterm) -set xterm_alt_key false - -# Whether to include bookmarks in cd command -set cd_bookmarks true - -# Changes case sensitivity for the cd command tab completion -set cd_tab_case sensitive - -# Use fuzzy tab completion with the "cd" command. For example, -# ":cd /u/lo/b" expands to ":cd /usr/local/bin". -set cd_tab_fuzzy false - -# Avoid previewing files larger than this size, in bytes. Use a value of 0 to -# disable this feature. -set preview_max_size 0 - -# The key hint lists up to this size have their sublists expanded. -# Otherwise the submaps are replaced with "...". -set hint_collapse_threshold 10 - -# Add the highlighted file to the path in the titlebar -set show_selection_in_titlebar true - -# The delay that ranger idly waits for user input, in milliseconds, with a -# resolution of 100ms. Lower delay reduces lag between directory updates but -# increases CPU load. -set idle_delay 2000 - -# When the metadata manager module looks for metadata, should it only look for -# a ".metadata.json" file in the current directory, or do a deep search and -# check all directories above the current one as well? -set metadata_deep_search false - -# Clear all existing filters when leaving a directory -set clear_filters_on_dir_change false - -# Disable displaying line numbers in main column. -# Possible values: false, absolute, relative. -set line_numbers false - -# When line_numbers=relative show the absolute line number in the -# current line. -set relative_current_zero false - -# Start line numbers from 1 instead of 0 -set one_indexed false - -# Save tabs on exit -set save_tabs_on_exit false - -# Enable scroll wrapping - moving down while on the last item will wrap around to -# the top and vice versa. -set wrap_scroll false - -# Set the global_inode_type_filter to nothing. Possible options: d, f and l for -# directories, files and symlinks respectively. -set global_inode_type_filter - -# This setting allows to freeze the list of files to save I/O bandwidth. It -# should be 'false' during start-up, but you can toggle it by pressing F. -set freeze_files false - -# Print file sizes in bytes instead of the default human-readable format. -set size_in_bytes false - -# Warn at startup if RANGER_LEVEL env var is greater than 0, in other words -# give a warning when you nest ranger in a subshell started by ranger. -# Special value "error" makes the warning more visible. -set nested_ranger_warning true - -# =================================================================== -# == Local Options -# =================================================================== -# You can set local options that only affect a single directory. - -# Examples: -# setlocal path=~/downloads sort mtime - -# =================================================================== -# == Command Aliases in the Console -# =================================================================== - -alias e edit -alias q quit -alias q! quit! -alias qa quitall -alias qa! quitall! -alias qall quitall -alias qall! quitall! -alias setl setlocal - -alias filter scout -prts -alias hide scout -prtsv -alias find scout -aets -alias mark scout -mr -alias unmark scout -Mr -alias search scout -rs -alias search_inc scout -rts -alias travel scout -aefklst - -# =================================================================== -# == Define keys for the browser -# =================================================================== - -# Basic -map Q quitall -map q quit -copymap q ZZ ZQ - -map R reload_cwd -map F set freeze_files! -map reset -map redraw_window -map abort -map change_mode normal -map ~ set viewmode! - -map i display_file -map scroll_preview 1 -map scroll_preview -1 -map ? help -map W display_log -map w taskview_open -map S shell $SHELL - -map : console -map ; console -map ! console shell%space -map @ console -p6 shell %%s -map # console shell -p%space -map s console shell%space -map r chain draw_possible_programs; console open_with%space -map f console find%space -map cd console cd%space - -map chain console; eval fm.ui.console.history_move(-1) - -# Change the line mode -map Mf linemode filename -map Mi linemode fileinfo -map Mm linemode mtime -map Mh linemode humanreadablemtime -map Mp linemode permissions -map Ms linemode sizemtime -map MH linemode sizehumanreadablemtime -map Mt linemode metatitle - -# Tagging / Marking -map t tag_toggle -map ut tag_remove -map " tag_toggle tag=%any -map mark_files toggle=True -map v mark_files all=True toggle=True -map uv mark_files all=True val=False -map V toggle_visual_mode -map uV toggle_visual_mode reverse=True - -# For the nostalgics: Midnight Commander bindings -map help -map rename_append -map display_file -map edit -map copy -map cut -map console mkdir%space -map console delete -#map console trash -map exit - -# In case you work on a keyboard with dvorak layout -map move up=1 -map move down=1 -map move left=1 -map move right=1 -map move to=0 -map move to=-1 -map move down=1 pages=True -map move up=1 pages=True -map move right=1 -#map console delete -map console touch%space - -# VIM-like -copymap k -copymap j -copymap h -copymap l -copymap gg -copymap G -copymap -copymap - -map J move down=0.5 pages=True -map K move up=0.5 pages=True -copymap J -copymap K - -# Jumping around -map H history_go -1 -map L history_go 1 -map ] move_parent 1 -map [ move_parent -1 -map } traverse -map { traverse_backwards -map ) jump_non - -map gh cd ~ -map ge cd /etc -map gu cd /usr -map gd cd /dev -map gl cd -r . -map gL cd -r %f -map go cd /opt -map gv cd /var -map gm cd /media -map gi eval fm.cd('/run/media/' + os.getenv('USER')) -map gM cd /mnt -map gs cd /srv -map gp cd /tmp -map gr cd / -map gR eval fm.cd(ranger.RANGERDIR) -map g/ cd / -map g? cd /usr/share/doc/ranger - -# External Programs -map E edit -map du shell -p du -d 1 -h "$(2>/dev/null >&2 du --apparent-size /dev/null && printf '%s\n' --apparent-size || printf '%s\n' --)" -map dU shell -p du -d 1 -h "$(2>/dev/null >&2 du --apparent-size /dev/null && printf '%s\n' --apparent-size || printf '%s\n' --)" | sort -rh -map yp yank path -map yd yank dir -map yn yank name -map y. yank name_without_extension - -# Filesystem Operations -map = chmod - -map cw console rename%space -map a rename_append -map A eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%")) -map I eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%"), position=7) - -map pp paste -map po paste overwrite=True -map pP paste append=True -map pO paste overwrite=True append=True -map pl paste_symlink relative=False -map pL paste_symlink relative=True -map phl paste_hardlink -map pht paste_hardlinked_subtree -map pd console paste dest= -map p` paste dest=%any_path -map p' paste dest=%any_path - -map dD console delete -map dT console trash - -map dd cut -map ud uncut -map da cut mode=add -map dr cut mode=remove -map dt cut mode=toggle - -map yy copy -map uy uncut -map ya copy mode=add -map yr copy mode=remove -map yt copy mode=toggle - -# Temporary workarounds -map dgg eval fm.cut(dirarg=dict(to=0), narg=quantifier) -map dG eval fm.cut(dirarg=dict(to=-1), narg=quantifier) -map dj eval fm.cut(dirarg=dict(down=1), narg=quantifier) -map dk eval fm.cut(dirarg=dict(up=1), narg=quantifier) -map ygg eval fm.copy(dirarg=dict(to=0), narg=quantifier) -map yG eval fm.copy(dirarg=dict(to=-1), narg=quantifier) -map yj eval fm.copy(dirarg=dict(down=1), narg=quantifier) -map yk eval fm.copy(dirarg=dict(up=1), narg=quantifier) - -# Searching -map / console search%space -map n search_next -map N search_next forward=False -map ct search_next order=tag -map cs search_next order=size -map ci search_next order=mimetype -map cc search_next order=ctime -map cm search_next order=mtime -map ca search_next order=atime - -# Tabs -map tab_new -map tab_close -map tab_move 1 -map tab_move -1 -map tab_move 1 -map tab_move -1 -map gt tab_move 1 -map gT tab_move -1 -map gn tab_new -map gc tab_close -map uq tab_restore -map tab_open 1 -map tab_open 2 -map tab_open 3 -map tab_open 4 -map tab_open 5 -map tab_open 6 -map tab_open 7 -map tab_open 8 -map tab_open 9 -map tab_shift 1 -map tab_shift -1 - -# Sorting -map or set sort_reverse! -map oz set sort=random -map os chain set sort=size; set sort_reverse=False -map ob chain set sort=basename; set sort_reverse=False -map on chain set sort=natural; set sort_reverse=False -map om chain set sort=mtime; set sort_reverse=False -map oc chain set sort=ctime; set sort_reverse=False -map oa chain set sort=atime; set sort_reverse=False -map ot chain set sort=type; set sort_reverse=False -map oe chain set sort=extension; set sort_reverse=False - -map oS chain set sort=size; set sort_reverse=True -map oB chain set sort=basename; set sort_reverse=True -map oN chain set sort=natural; set sort_reverse=True -map oM chain set sort=mtime; set sort_reverse=True -map oC chain set sort=ctime; set sort_reverse=True -map oA chain set sort=atime; set sort_reverse=True -map oT chain set sort=type; set sort_reverse=True -map oE chain set sort=extension; set sort_reverse=True - -map dc get_cumulative_size - -# Settings -map zc set collapse_preview! -map zd set sort_directories_first! -map zh set show_hidden! -map set show_hidden! -copymap -copymap -map zI set flushinput! -map zi set preview_images! -map zm set mouse_enabled! -map zp set preview_files! -map zP set preview_directories! -map zs set sort_case_insensitive! -map zu set autoupdate_cumulative_size! -map zv set use_preview_script! -map zf console filter%space -copymap zf zz - -# Filter stack -map .d filter_stack add type d -map .f filter_stack add type f -map .l filter_stack add type l -map .m console filter_stack add mime%space -map .n console filter_stack add name%space -map .# console filter_stack add hash%space -map ." filter_stack add duplicate -map .' filter_stack add unique -map .| filter_stack add or -map .& filter_stack add and -map .! filter_stack add not -map .r filter_stack rotate -map .c filter_stack clear -map .* filter_stack decompose -map .p filter_stack pop -map .. filter_stack show - -# Bookmarks -map ` enter_bookmark %any -map ' enter_bookmark %any -map m set_bookmark %any -map um unset_bookmark %any - -map m draw_bookmarks -copymap m um ` ' p` p' - -# Generate all the chmod bindings with some python help: -eval for arg in "rwxXst": cmd("map +u{0} shell -f chmod u+{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map +g{0} shell -f chmod g+{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map +o{0} shell -f chmod o+{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map +a{0} shell -f chmod a+{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map +{0} shell -f chmod +{0} %s".format(arg)) - -eval for arg in "rwxXst": cmd("map -u{0} shell -f chmod u-{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map -g{0} shell -f chmod g-{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map -o{0} shell -f chmod o-{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map -a{0} shell -f chmod a-{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map -{0} shell -f chmod -{0} %s".format(arg)) - -# =================================================================== -# == Define keys for the console -# =================================================================== -# Note: Unmapped keys are passed directly to the console. - -# Basic -cmap eval fm.ui.console.tab() -cmap eval fm.ui.console.tab(-1) -cmap eval fm.ui.console.close() -cmap eval fm.ui.console.execute() -cmap redraw_window - -copycmap -copycmap - -# Move around -cmap eval fm.ui.console.history_move(-1) -cmap eval fm.ui.console.history_move(1) -cmap eval fm.ui.console.move(left=1) -cmap eval fm.ui.console.move(right=1) -cmap eval fm.ui.console.move(right=0, absolute=True) -cmap eval fm.ui.console.move(right=-1, absolute=True) -cmap eval fm.ui.console.move_word(left=1) -cmap eval fm.ui.console.move_word(right=1) - -copycmap -copycmap - -# Line Editing -cmap eval fm.ui.console.delete(-1) -cmap eval fm.ui.console.delete(0) -cmap eval fm.ui.console.delete_word() -cmap eval fm.ui.console.delete_word(backward=False) -cmap eval fm.ui.console.delete_rest(1) -cmap eval fm.ui.console.delete_rest(-1) -cmap eval fm.ui.console.paste() -cmap eval fm.ui.console.transpose_chars() -cmap eval fm.ui.console.transpose_words() - -# And of course the emacs way -copycmap -copycmap -copycmap -copycmap -copycmap -copycmap -copycmap -copycmap -copycmap - -# Note: There are multiple ways to express backspaces. (code 263) -# and (code 127). To be sure, use both. -copycmap - -# This special expression allows typing in numerals: -cmap false - -# =================================================================== -# == Pager Keybindings -# =================================================================== - -# Movement -pmap pager_move down=1 -pmap pager_move up=1 -pmap pager_move left=4 -pmap pager_move right=4 -pmap pager_move to=0 -pmap pager_move to=-1 -pmap pager_move down=1.0 pages=True -pmap pager_move up=1.0 pages=True -pmap pager_move down=0.5 pages=True -pmap pager_move up=0.5 pages=True - -copypmap k -copypmap j -copypmap h -copypmap l -copypmap g -copypmap G -copypmap d -copypmap u -copypmap n f -copypmap p b - -# Basic -pmap redraw_window -pmap pager_close -copypmap q Q i -pmap E edit_file - -# =================================================================== -# == Taskview Keybindings -# =================================================================== - -# Movement -tmap taskview_move up=1 -tmap taskview_move down=1 -tmap taskview_move to=0 -tmap taskview_move to=-1 -tmap taskview_move down=1.0 pages=True -tmap taskview_move up=1.0 pages=True -tmap taskview_move down=0.5 pages=True -tmap taskview_move up=0.5 pages=True - -copytmap k -copytmap j -copytmap g -copytmap G -copytmap u -copytmap n f -copytmap p b - -# Changing priority and deleting tasks -tmap J eval -q fm.ui.taskview.task_move(-1) -tmap K eval -q fm.ui.taskview.task_move(0) -tmap dd eval -q fm.ui.taskview.task_remove() -tmap eval -q fm.ui.taskview.task_move(-1) -tmap eval -q fm.ui.taskview.task_move(0) -tmap eval -q fm.ui.taskview.task_remove() - -# Basic -tmap redraw_window -tmap taskview_close -copytmap q Q w - diff --git a/starship/.config/starship.toml b/starship/.config/starship.toml index 0e57701..72ab4d9 100644 --- a/starship/.config/starship.toml +++ b/starship/.config/starship.toml @@ -1,5 +1,5 @@ format = """ -[░▒▓](#f5c2e7)\ +[ ░▒▓](#f5c2e7)\ $username\ [](bg:#f38ba8 fg:#f5c2e7)\ $directory\ diff --git a/xplr/.config/xplr/init.lua b/xplr/.config/xplr/init.lua new file mode 100644 index 0000000..0710f10 --- /dev/null +++ b/xplr/.config/xplr/init.lua @@ -0,0 +1,2714 @@ +---@diagnostic disable +local xplr = xplr -- The globally exposed configuration to be overridden. +---@diagnostic enable + +-- This is the built-in configuration file that gets loaded and sets the +-- default values when xplr loads, before loading any other custom +-- configuration file. +-- +-- You can use this file as a reference to create a your custom config file. +-- +-- To create a custom configuration file, you need to define the script version +-- for compatibility checks. +-- +-- See https://xplr.dev/en/upgrade-guide +-- +-- ```lua + version = "0.20.1" +-- ``` + +-- # Configuration ------------------------------------------------------------ +-- +-- xplr can be configured using [Lua][1] via a special file named `init.lua`, +-- which can be placed in `~/.config/xplr/` (local to user) or `/etc/xplr/` +-- (global) depending on the use case. +-- +-- When xplr loads, it first executes the [built-in init.lua][2] to set the +-- default values, which is then overwritten by another config file, if found +-- using the following lookup order: +-- +-- 1. `--config /path/to/init.lua` +-- 2. `~/.config/xplr/init.lua` +-- 3. `/etc/xplr/init.lua` +-- +-- The first one found will be loaded by xplr and the lookup will stop. +-- +-- The loaded config can be further extended using the `-C` or `--extra-config` +-- command-line option. +-- +-- +-- [1]: https://www.lua.org +-- [2]: https://github.com/sayanarijit/xplr/blob/main/src/init.lua +-- [3]: https://xplr.dev/en/upgrade-guide + +-- ## Config ------------------------------------------------------------------ +-- +-- The xplr configuration, exposed via `xplr.config` Lua API contains the +-- following sections. +-- +-- See: +-- +-- * [xplr.config.general](https://xplr.dev/en/general-config) +-- * [xplr.config.node_types](https://xplr.dev/en/node_types) +-- * [xplr.config.layouts](https://xplr.dev/en/layouts) +-- * [xplr.config.modes](https://xplr.dev/en/modes) + +-- ### General Configuration -------------------------------------------------- +-- +-- The general configuration properties are grouped together in +-- `xplr.config.general`. + +-- Set it to `true` if you want to ignore the startup errors. You can still see +-- the errors in the logs. +-- +-- Type: boolean +xplr.config.general.disable_debug_error_mode = false + +-- Set it to `true` if you want to enable mouse scrolling. +-- +-- Type: boolean +xplr.config.general.enable_mouse = false + +-- Set it to `true` to show hidden files by default. +-- +-- Type: boolean +xplr.config.general.show_hidden = true + +-- Set it to `true` to use only a subset of selected operations that forbids +-- executing commands or performing write operations on the file-system. +-- +-- Type: boolean +xplr.config.general.read_only = false + +-- Set it to `true` if you want to enable a safety feature that will save you +-- from yourself when you type recklessly. +-- +-- Type: boolean +xplr.config.general.enable_recover_mode = false + +-- Set it to `true` if you want to hide all remaps in the help menu. +-- +-- Type: boolean +xplr.config.general.hide_remaps_in_help_menu = false + +-- Set it to `true` if you want the cursor to stay in the same position when +-- the focus is on the first path and you navigate to the previous path +-- (by pressing `up`/`k`), or when the focus is on the last path and you +-- navigate to the next path (by pressing `down`/`j`). +-- The default behavior is to rotate from the last/first path. +-- +-- Type: boolean +xplr.config.general.enforce_bounded_index_navigation = false + +-- This is the shape of the prompt for the input buffer. +-- +-- Type: nullable string +xplr.config.general.prompt.format = "❯ " + +-- This is the style of the prompt for the input buffer. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.prompt.style = {} + +-- The string to indicate an information in logs. +-- +-- Type: nullable string +xplr.config.general.logs.info.format = "INFO" + +-- The style for the informations logs. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.logs.info.style = { fg = "LightBlue" } + +-- The string to indicate an success in logs. +-- +-- Type: nullable string +xplr.config.general.logs.success.format = "SUCCESS" + +-- The style for the success logs. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.logs.success.style = { fg = "Green" } + +-- The string to indicate an warnings in logs. +-- +-- Type: nullable string +xplr.config.general.logs.warning.format = "WARNING" + +-- The style for the warnings logs. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.logs.warning.style = { fg = "Yellow" } + +-- The string to indicate an error in logs. +-- +-- Type: nullable string +xplr.config.general.logs.error.format = "ERROR" + +-- The style for the error logs. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.logs.error.style = { fg = "Red" } + +-- Columns to display in the table header. +-- +-- Type: nullable list of tables with the following fields: +-- +-- * format: nullable string +-- * style: [Style](https://xplr.dev/en/style) +xplr.config.general.table.header.cols = { + { format = " index", style = {} }, + { format = "╭─── path", style = {} }, + { format = "permissions", style = {} }, + { format = "size", style = {} }, + { format = "modified", style = {} }, +} + +-- Style of the table header. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.table.header.style = {} + +-- Height of the table header. +-- +-- Type: nullable integer +xplr.config.general.table.header.height = 1 + +-- Columns to display in each row in the table. +-- +-- Type: nullable list of tables with the following fields: +-- +-- * format: nullable string +-- * style: [Style](https://xplr.dev/en/style) +xplr.config.general.table.row.cols = { + { + format = "builtin.fmt_general_table_row_cols_0", + style = {}, + }, + { + format = "builtin.fmt_general_table_row_cols_1", + style = {}, + }, + { + format = "builtin.fmt_general_table_row_cols_2", + style = {}, + }, + { + format = "builtin.fmt_general_table_row_cols_3", + style = {}, + }, + { + format = "builtin.fmt_general_table_row_cols_4", + style = {}, + }, +} + +-- Default style of the table. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.table.row.style = {} + +-- Height of the table rows. +-- +-- Type: nullable integer +xplr.config.general.table.row.height = 0 + +-- Default style of the table. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.table.style = {} + +-- Tree to display in the table. +-- +-- Type: nullable list of tables with the following fields: +-- +-- * format: nullable string +-- * style: [Style](https://xplr.dev/en/style) +xplr.config.general.table.tree = { + { format = "├", style = {} }, + { format = "├", style = {} }, + { format = "╰", style = {} }, +} + +-- Spacing between the columns in the table. +-- +-- Type: nullable integer +xplr.config.general.table.col_spacing = 1 + +-- Constraint for the column widths. +-- +-- Type: nullable list of [Constraint](https://xplr.dev/en/layouts#constraint) +xplr.config.general.table.col_widths = { + { Percentage = 10 }, + { Percentage = 50 }, + { Percentage = 10 }, + { Percentage = 10 }, + { Percentage = 20 }, +} + +-- The content that is placed before the item name for each row by default. +-- +-- Type: nullable string +xplr.config.general.default_ui.prefix = "─ " + +-- The content which is appended to each item name for each row by default. +-- +-- Type: nullable string +xplr.config.general.default_ui.suffix = "" + +-- The default style of each item for each row. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.default_ui.style = {} + +-- The string placed before the item name for a focused row. +-- +-- Type: nullable string +xplr.config.general.focus_ui.prefix = "▸[" + +-- The string placed after the item name for a focused row. +-- +-- Type: nullable string +xplr.config.general.focus_ui.suffix = "]" + +-- Style for focused item. +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.focus_ui.style = { add_modifiers = { "Bold" } } + +-- The string placed before the item name for a selected row. +-- +-- Type: nullable string +xplr.config.general.selection_ui.prefix = "─{" + +-- The string placed after the item name for a selected row. +-- +-- Type: nullable string +xplr.config.general.selection_ui.suffix = "}" + +-- Style for selected rows. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.selection_ui.style = { + fg = "LightGreen", + add_modifiers = { "Bold" }, +} + +-- The string placed before item name for a selected row that gets the focus. +-- +-- Type: nullable string +xplr.config.general.focus_selection_ui.prefix = "▸[" + +-- The string placed after the item name for a selected row that gets the focus. +-- +-- Type: nullable string +xplr.config.general.focus_selection_ui.suffix = "]" + +-- Style for a selected row that gets the focus. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.focus_selection_ui.style = { + fg = "LightGreen", + add_modifiers = { "Bold" }, +} + +-- The shape of the separator for the Sort & filter panel. +-- +-- Type: nullable string +xplr.config.general.sort_and_filter_ui.separator.format = " › " + +-- The style of the separator for the Sort & filter panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.sort_and_filter_ui.separator.style = { + add_modifiers = { "Dim" }, +} + +-- The content of the default identifier in Sort & filter panel. +-- +-- Type: nullable string +xplr.config.general.sort_and_filter_ui.default_identifier.format = nil + +-- Style for the default identifier in Sort & filter panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.sort_and_filter_ui.default_identifier.style = {} + +-- The shape of the forward direction indicator for sort identifiers in Sort & filter panel. +-- +-- Type: nullable string +xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.format = "↓" + +-- Style of forward direction indicator in Sort & filter panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.style = nil + +-- The shape of the reverse direction indicator for sort identifiers in Sort & filter panel. +-- +-- Type: nullable string +xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.format = "↑" + +-- Style of reverse direction indicator in Sort & filter panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.style = nil + +-- The identifiers used to denote applied sorters in the Sort & filter panel. +-- +-- Type: nullable mapping of the following key-value pairs: +-- +-- * key: [Sorter](https://xplr.dev/en/sorting#sorter) +-- * value: +-- * format: nullable string +-- * style: [Style](https://xplr.dev/en/style) +xplr.config.general.sort_and_filter_ui.sorter_identifiers = { + ByExtension = { format = "ext", style = {} }, + ByICanonicalAbsolutePath = { format = "[ci]abs", style = {} }, + ByIRelativePath = { format = "[i]rel", style = {} }, + ByISymlinkAbsolutePath = { format = "[si]abs", style = {} }, + ByIsBroken = { format = "⨯", style = {} }, + ByIsDir = { format = "dir", style = {} }, + ByIsFile = { format = "file", style = {} }, + ByIsReadonly = { format = "ro", style = {} }, + ByIsSymlink = { format = "sym", style = {} }, + ByMimeEssence = { format = "mime", style = {} }, + ByRelativePath = { format = "rel", style = {} }, + BySize = { format = "size", style = {} }, + ByCreated = { format = "created", style = {} }, + ByLastModified = { format = "modified", style = {} }, + ByCanonicalAbsolutePath = { format = "[c]abs", style = {} }, + ByCanonicalExtension = { format = "[c]ext", style = {} }, + ByCanonicalIsDir = { format = "[c]dir", style = {} }, + ByCanonicalIsFile = { format = "[c]file", style = {} }, + ByCanonicalIsReadonly = { format = "[c]ro", style = {} }, + ByCanonicalMimeEssence = { format = "[c]mime", style = {} }, + ByCanonicalSize = { format = "[c]size", style = {} }, + ByCanonicalCreated = { format = "[c]created", style = {} }, + ByCanonicalLastModified = { format = "[c]modified", style = {} }, + BySymlinkAbsolutePath = { format = "[s]abs", style = {} }, + BySymlinkExtension = { format = "[s]ext", style = {} }, + BySymlinkIsDir = { format = "[s]dir", style = {} }, + BySymlinkIsFile = { format = "[s]file", style = {} }, + BySymlinkIsReadonly = { format = "[s]ro", style = {} }, + BySymlinkMimeEssence = { format = "[s]mime", style = {} }, + BySymlinkSize = { format = "[s]size", style = {} }, + BySymlinkCreated = { format = "[s]created", style = {} }, + BySymlinkLastModified = { format = "[s]modified", style = {} }, +} + +-- The identifiers used to denote applied filters in the Sort & filter panel. +-- +-- Type: nullable mapping of the following key-value pairs: +-- +-- * key: [Filter](https://xplr.dev/en/filtering#filter) +-- * value: +-- * format: nullable string +-- * style: [Style](https://xplr.dev/en/style) +xplr.config.general.sort_and_filter_ui.filter_identifiers = { + RelativePathDoesContain = { format = "rel=~", style = {} }, + RelativePathDoesEndWith = { format = "rel=$", style = {} }, + RelativePathDoesNotContain = { format = "rel!~", style = {} }, + RelativePathDoesNotEndWith = { format = "rel!$", style = {} }, + RelativePathDoesNotStartWith = { format = "rel!^", style = {} }, + RelativePathDoesStartWith = { format = "rel=^", style = {} }, + RelativePathIs = { format = "rel==", style = {} }, + RelativePathIsNot = { format = "rel!=", style = {} }, + RelativePathDoesMatchRegex = { format = "rel=/", style = {} }, + RelativePathDoesNotMatchRegex = { format = "rel!/", style = {} }, + + IRelativePathDoesContain = { format = "[i]rel=~", style = {} }, + IRelativePathDoesEndWith = { format = "[i]rel=$", style = {} }, + IRelativePathDoesNotContain = { format = "[i]rel!~", style = {} }, + IRelativePathDoesNotEndWith = { format = "[i]rel!$", style = {} }, + IRelativePathDoesNotStartWith = { format = "[i]rel!^", style = {} }, + IRelativePathDoesStartWith = { format = "[i]rel=^", style = {} }, + IRelativePathIs = { format = "[i]rel==", style = {} }, + IRelativePathIsNot = { format = "[i]rel!=", style = {} }, + IRelativePathDoesMatchRegex = { format = "[i]rel=/", style = {} }, + IRelativePathDoesNotMatchRegex = { format = "[i]rel!/", style = {} }, + + AbsolutePathDoesContain = { format = "abs=~", style = {} }, + AbsolutePathDoesEndWith = { format = "abs=$", style = {} }, + AbsolutePathDoesNotContain = { format = "abs!~", style = {} }, + AbsolutePathDoesNotEndWith = { format = "abs!$", style = {} }, + AbsolutePathDoesNotStartWith = { format = "abs!^", style = {} }, + AbsolutePathDoesStartWith = { format = "abs=^", style = {} }, + AbsolutePathIs = { format = "abs==", style = {} }, + AbsolutePathIsNot = { format = "abs!=", style = {} }, + AbsolutePathDoesMatchRegex = { format = "abs=/", style = {} }, + AbsolutePathDoesNotMatchRegex = { format = "abs!/", style = {} }, + + IAbsolutePathDoesContain = { format = "[i]abs=~", style = {} }, + IAbsolutePathDoesEndWith = { format = "[i]abs=$", style = {} }, + IAbsolutePathDoesNotContain = { format = "[i]abs!~", style = {} }, + IAbsolutePathDoesNotEndWith = { format = "[i]abs!$", style = {} }, + IAbsolutePathDoesNotStartWith = { format = "[i]abs!^", style = {} }, + IAbsolutePathDoesStartWith = { format = "[i]abs=^", style = {} }, + IAbsolutePathIs = { format = "[i]abs==", style = {} }, + IAbsolutePathIsNot = { format = "[i]abs!=", style = {} }, + IAbsolutePathDoesMatchRegex = { format = "[i]abs=/", style = {} }, + IAbsolutePathDoesNotMatchRegex = { format = "[i]abs!/", style = {} }, +} + +-- The identifiers used to denote applied search input. +-- +-- Type: { format = nullable string, style = [Style](https://xplr.dev/en/style) } +xplr.config.general.sort_and_filter_ui.search_identifier = { + format = "search:", + style = {}, +} + +-- The content for panel title by default. +-- +-- Type: nullable string +xplr.config.general.panel_ui.default.title.format = nil + +-- The style for panel title by default. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.default.title.style = { + fg = "Reset", + add_modifiers = { "Bold" }, +} + +-- Style of the panels by default. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.default.style = {} + +-- Defines where to show borders for the panels by default. +-- +-- Type: nullable list of [Border](https://xplr.dev/en/borders#border) +xplr.config.general.panel_ui.default.borders = { + "Top", + "Right", + "Bottom", + "Left", +} + +-- Type of the borders by default. +-- +-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type) +xplr.config.general.panel_ui.default.border_type = "Rounded" + +-- Style of the panel borders by default. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.default.border_style = { fg = "DarkGray" } + +-- The content for the table panel title. +-- +-- Type: nullable string +xplr.config.general.panel_ui.table.title.format = nil + +-- Style of the table panel title. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.table.title.style = {} + +-- Style of the table panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.table.style = {} + +-- Defines where to show borders for the table panel. +-- +-- Type: nullable list of [Border](https://xplr.dev/en/borders#border) +xplr.config.general.panel_ui.table.borders = nil + +-- Type of the borders for table panel. +-- +-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type) +xplr.config.general.panel_ui.table.border_type = nil + +-- Style of the table panel borders. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.table.border_style = {} + +-- The content for the help menu panel title. +-- +-- Type: nullable string +xplr.config.general.panel_ui.help_menu.title.format = nil + +-- Style of the help menu panel title. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.help_menu.title.style = {} + +-- Style of the help menu panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.help_menu.style = {} + +-- Defines where to show borders for the help menu panel. +-- +-- Type: nullable list of [Border](https://xplr.dev/en/borders#border) +xplr.config.general.panel_ui.help_menu.borders = nil + +-- Type of the borders for help menu panel. +-- +-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type) +xplr.config.general.panel_ui.help_menu.border_type = nil + +-- Style of the help menu panel borders. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.help_menu.border_style = {} + +-- The content for the input & logs panel title. +-- +-- Type: nullable string +xplr.config.general.panel_ui.input_and_logs.title.format = nil + +-- Style of the input & logs panel title. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.input_and_logs.title.style = {} + +-- Style of the input & logs panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.input_and_logs.style = {} +-- Defines where to show borders for the input & logs panel. +-- +-- Type: nullable list of [Border](https://xplr.dev/en/borders#border) +xplr.config.general.panel_ui.input_and_logs.borders = nil + +-- Type of the borders for input & logs panel. +-- +-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type) +xplr.config.general.panel_ui.input_and_logs.border_type = nil + +-- Style of the input & logs panel borders. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.input_and_logs.border_style = {} + +-- The content for the selection panel title. +-- +-- Type: nullable string +xplr.config.general.panel_ui.selection.title.format = nil + +-- Style of the selection panel title. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.selection.title.style = {} + +-- Style of the selection panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.selection.style = {} +-- Defines where to show borders for the selection panel. +-- +-- Type: nullable list of [Border](https://xplr.dev/en/borders#border) +xplr.config.general.panel_ui.selection.borders = nil + +-- Type of the borders for selection panel. +-- +-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type) +xplr.config.general.panel_ui.selection.border_type = nil + +-- Style of the selection panel borders. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.selection.border_style = {} + +-- The content for the sort & filter panel title. +-- +-- Type: nullable string +xplr.config.general.panel_ui.sort_and_filter.title.format = nil + +-- Style of the sort & filter panel title. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.sort_and_filter.title.style = {} + +-- Style of the sort & filter panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.sort_and_filter.style = {} + +-- Defines where to show borders for the sort & filter panel. +-- +-- Type: nullable list of [Border](https://xplr.dev/en/borders#border) +xplr.config.general.panel_ui.sort_and_filter.borders = nil + +-- Type of the borders for sort & filter panel. +-- +-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type) +xplr.config.general.panel_ui.sort_and_filter.border_type = nil + +-- Style of the sort & filter panel borders. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.sort_and_filter.border_style = {} + +-- Initial group if sorters applied to the nodes list in the table. +-- +-- Type: nullable list of [Node Sorter](https://xplr.dev/en/sorting#node-sorter-applicable) +xplr.config.general.initial_sorting = { + { sorter = "ByCanonicalIsDir", reverse = true }, + { sorter = "ByIRelativePath", reverse = false }, +} + +-- The name of one of the modes to use when xplr loads. +-- +-- Type: nullable string +xplr.config.general.initial_mode = "default" + +-- The name of one of the layouts to use when xplr loads. +-- +-- Type: nullable string +xplr.config.general.initial_layout = "default" + +-- Set it to a file path to start fifo when xplr loads. +-- Generally it is used to integrate with external tools like previewers. +-- +-- Type: nullable string +xplr.config.general.start_fifo = nil + +-- Use it to define a set of key bindings that are available by default in +-- every [mode](https://xplr.dev/en/mode). They can be overwritten. +-- +-- Type: [Key Bindings](https://xplr.dev/en/configure-key-bindings#key-bindings) +xplr.config.general.global_key_bindings = { + on_key = { + ["esc"] = { + messages = { + "PopMode", + }, + }, + ["ctrl-c"] = { + messages = { + "Terminate", + }, + }, + }, +} + +-- ### Node Types ------------------------------------------------------------- +-- +-- This section defines how to deal with different kinds of nodes (files, +-- directories, symlinks etc.) based on their properties. +-- +-- One node can fall into multiple categories. For example, a node can have the +-- *extension* `md`, and also be a *file*. In that case, the properties from +-- the more specific category i.e. *extension* will be used. +-- +-- This can be configured using the `xplr.config.node_types` Lua API. + +-- The style for the directory nodes +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.node_types.directory.style = { + fg = "Cyan", + add_modifiers = { "Bold" }, +} + +-- Metadata for the directory nodes. +-- You can set as many metadata as you want. +-- +-- Type: nullable string +-- +-- Example: +-- +-- ```lua +-- xplr.config.node_types.directory.meta.foo = "foo" +-- xplr.config.node_types.directory.meta.bar = "bar" +-- ``` +xplr.config.node_types.directory.meta.icon = "ð" + +-- The style for the file nodes. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.node_types.file.style = {} + +-- Metadata for the file nodes. +-- You can set as many metadata as you want. +-- +-- Type: nullable string +-- +-- Example: +-- +-- ```lua +-- xplr.config.node_types.file.meta.foo = "foo" +-- xplr.config.node_types.file.meta.bar = "bar" +-- ``` +xplr.config.node_types.file.meta.icon = "ƒ" + +-- The style for the symlink nodes. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.node_types.symlink.style = { + fg = "Magenta", + add_modifiers = { "Italic" }, +} + +-- Metadata for the symlink nodes. +-- You can set as many metadata as you want. +-- +-- Type: nullable string +-- +-- Example: +-- +-- ```lua +-- xplr.config.node_types.symlink.meta.foo = "foo" +-- xplr.config.node_types.symlink.meta.bar = "bar" +-- ``` +xplr.config.node_types.symlink.meta.icon = "§" + +-- Metadata and style based on mime types. +-- It is possible to use the wildcard `*` to match all mime sub types. It will +-- be overwritten by the more specific sub types that are defined. +-- +-- Type: mapping of the following key-value pairs: +-- +-- * key: string +-- * value: +-- * key: string +-- * value: [Node Type](https://xplr.dev/en/node-type) +-- +-- Example: +-- +-- ```lua +-- xplr.config.node_types.mime_essence = { +-- application = { +-- -- application/* +-- ["*"] = { meta = { icon = "a" } } +-- +-- -- application/pdf +-- pdf = { meta = { icon = "" }, style = { fg = "Blue" } }, +-- +-- -- application/zip +-- zip = { meta = { icon = ""} }, +-- }, +-- } +-- ``` +xplr.config.node_types.mime_essence = {} + +-- Metadata and style based on extension. +-- +-- Type: mapping of the following key-value pairs: +-- +-- * key: string +-- * value: [Node Type](https://xplr.dev/en/node-type) +-- +-- Example: +-- +-- ```lua +-- xplr.config.node_types.extension.md = { meta = { icon = "" }, style = { fg = "Blue" } } +-- xplr.config.node_types.extension.rs = { meta = { icon = "🦀" } } +-- ``` +xplr.config.node_types.extension = {} + +-- Metadata and style based on special file names. +-- +-- Type: mapping of the following key-value pairs: +-- +-- * key: string +-- * value: [Node Type](https://xplr.dev/en/node-type) +-- +-- Example: +-- +-- ```lua +-- xplr.config.node_types.special["Cargo.toml"] = { meta = { icon = "" } } +-- xplr.config.node_types.special["Downloads"] = { meta = { icon = "" }, style = { fg = "Blue" } } +-- ``` +xplr.config.node_types.special = {} + +-- ### Layouts ---------------------------------------------------------------- +-- +-- xplr layouts define the structure of the UI, i.e. how many panel we see, +-- placement and size of the panels, how they look etc. +-- +-- This is configuration exposed via the `xplr.config.layouts` API. +-- +-- `xplr.config.layouts.builtin` contain some built-in panels which can be +-- overridden, but you can't add or remove panels in it. +-- +-- You can add new panels in `xplr.config.layouts.custom`. +-- +-- ##### Example: Defining Custom Layout +-- +-- ![demo](https://s6.gifyu.com/images/layout.png) +-- +-- ```lua +-- xplr.config.layouts.builtin.default = { +-- Horizontal = { +-- config = { +-- margin = 1, +-- horizontal_margin = 2, +-- vertical_margin = 3, +-- constraints = { +-- { Percentage = 50 }, +-- { Percentage = 50 }, +-- } +-- }, +-- splits = { +-- "Table", +-- "HelpMenu", +-- } +-- } +-- } +-- ``` + +-- The default layout +-- +-- Type: [Layout](https://xplr.dev/en/layout) +xplr.config.layouts.builtin.default = { + Horizontal = { + config = { + constraints = { + { Percentage = 70 }, + { Percentage = 30 }, + }, + }, + splits = { + { + Vertical = { + config = { + constraints = { + { Length = 3 }, + { Min = 1 }, + { Length = 3 }, + }, + }, + splits = { + "SortAndFilter", + "Table", + "InputAndLogs", + }, + }, + }, + { + Vertical = { + config = { + constraints = { + { Percentage = 30 }, + { Percentage = 70 }, + }, + }, + splits = { + "Selection", + "HelpMenu", + }, + }, + }, + }, + }, +} + +-- The layout without help menu +-- +-- Type: [Layout](https://xplr.dev/en/layout) +xplr.config.layouts.builtin.no_help = { + Horizontal = { + config = { + constraints = { + { Percentage = 70 }, + { Percentage = 30 }, + }, + }, + splits = { + { + Vertical = { + config = { + constraints = { + { Length = 3 }, + { Min = 1 }, + { Length = 3 }, + }, + }, + splits = { + "SortAndFilter", + "Table", + "InputAndLogs", + }, + }, + }, + "Selection", + }, + }, +} + +-- The layout without selection panel +-- +-- Type: [Layout](https://xplr.dev/en/layout) +xplr.config.layouts.builtin.no_selection = { + Horizontal = { + config = { + constraints = { + { Percentage = 70 }, + { Percentage = 30 }, + }, + }, + splits = { + { + Vertical = { + config = { + constraints = { + { Length = 3 }, + { Min = 1 }, + { Length = 3 }, + }, + }, + splits = { + "SortAndFilter", + "Table", + "InputAndLogs", + }, + }, + }, + "HelpMenu", + }, + }, +} + +-- The layout without help menu and selection panel +-- +-- Type: [Layout](https://xplr.dev/en/layout) +xplr.config.layouts.builtin.no_help_no_selection = { + Vertical = { + config = { + constraints = { + { Length = 3 }, + { Min = 1 }, + { Length = 3 }, + }, + }, + splits = { + "SortAndFilter", + "Table", + "InputAndLogs", + }, + }, +} + +-- This is where you can define custom layouts +-- +-- Type: mapping of the following key-value pairs: +-- +-- * key: string +-- * value: [Layout](https://xplr.dev/en/layout) +-- +-- Example: +-- +-- ```lua +-- xplr.config.layouts.custom.example = "Nothing" -- Show a blank screen +-- xplr.config.general.initial_layout = "example" -- Load the example layout +-- ``` +xplr.config.layouts.custom = {} + +-- ### Modes ------------------------------------------------------------------ +-- +-- xplr is a modal file explorer. That means the users switch between different +-- modes, each containing a different set of key bindings to avoid clashes. +-- Users can switch between these modes at run-time. +-- +-- The modes can be configured using the `xplr.config.modes` Lua API. +-- +-- `xplr.config.modes.builtin` contain some built-in modes which can be +-- overridden, but you can't add or remove modes in it. + +-- The builtin default mode. +-- Visit the [Default Key Bindings](https://xplr.dev/en/default-key-bindings) +-- to see what each mode does. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.default = { + name = "default", + key_bindings = { + on_key = { + ["#"] = { + messages = { + "PrintAppStateAndQuit", + }, + }, + ["."] = { + help = "show hidden", + messages = { + { + ToggleNodeFilter = { filter = "RelativePathDoesNotStartWith", input = "." }, + }, + "ExplorePwdAsync", + }, + }, + [":"] = { + help = "action", + messages = { + "PopMode", + { SwitchModeBuiltin = "action" }, + }, + }, + ["?"] = { + help = "global help menu", + messages = { + { + BashExec = [===[ + [ -z "$PAGER" ] && PAGER="less -+F" + cat -- "${XPLR_PIPE_GLOBAL_HELP_MENU_OUT}" | ${PAGER:?} + ]===], + }, + }, + }, + ["G"] = { + help = "go to bottom", + messages = { + "PopMode", + "FocusLast", + }, + }, + ["ctrl-a"] = { + help = "select/unselect all", + messages = { + "ToggleSelectAll", + }, + }, + ["ctrl-f"] = { + help = "search", + messages = { + "PopMode", + { SwitchModeBuiltin = "search" }, + { SetInputBuffer = "" }, + }, + }, + ["ctrl-i"] = { + help = "next visited path", + messages = { + "NextVisitedPath", + }, + }, + ["ctrl-o"] = { + help = "last visited path", + messages = { + "LastVisitedPath", + }, + }, + ["ctrl-r"] = { + help = "refresh screen", + messages = { + "ClearScreen", + }, + }, + ["ctrl-u"] = { + help = "clear selection", + messages = { + "ClearSelection", + }, + }, + ["ctrl-w"] = { + help = "switch layout", + messages = { + { SwitchModeBuiltin = "switch_layout" }, + }, + }, + ["d"] = { + help = "delete", + messages = { + "PopMode", + { SwitchModeBuiltin = "delete" }, + }, + }, + ["down"] = { + help = "down", + messages = { + "FocusNext", + }, + }, + ["enter"] = { + help = "quit with result", + messages = { + "PrintResultAndQuit", + }, + }, + ["f"] = { + help = "filter", + messages = { + "PopMode", + { SwitchModeBuiltin = "filter" }, + }, + }, + ["g"] = { + help = "go to", + messages = { + "PopMode", + { SwitchModeBuiltin = "go_to" }, + }, + }, + ["left"] = { + help = "back", + messages = { + "Back", + }, + }, + ["q"] = { + help = "quit", + messages = { + "Quit", + }, + }, + ["r"] = { + help = "rename", + messages = { + "PopMode", + { SwitchModeBuiltin = "rename" }, + { + BashExecSilently0 = [===[ + NAME=$(basename "${XPLR_FOCUS_PATH:?}") + "$XPLR" -m 'SetInputBuffer: %q' "${NAME:?}" + ]===], + }, + }, + }, + ["ctrl-d"] = { + help = "duplicate as", + messages = { + "PopMode", + { SwitchModeBuiltin = "duplicate_as" }, + { + BashExecSilently0 = [===[ + NAME=$(basename "${XPLR_FOCUS_PATH:?}") + "$XPLR" -m 'SetInputBuffer: %q' "${NAME:?}" + ]===], + }, + }, + }, + ["right"] = { + help = "enter", + messages = { + "Enter", + }, + }, + ["s"] = { + help = "sort", + messages = { + "PopMode", + { SwitchModeBuiltin = "sort" }, + }, + }, + ["space"] = { + help = "toggle selection", + messages = { + "ToggleSelection", + "FocusNext", + }, + }, + ["up"] = { + help = "up", + messages = { + "FocusPrevious", + }, + }, + ["~"] = { + help = "go home", + messages = { + { + BashExecSilently0 = [===[ + "$XPLR" -m 'ChangeDirectory: %q' "${HOME:?}" + ]===], + }, + }, + }, + ["page-up"] = { + help = "scroll up", + messages = { + "ScrollUp", + }, + }, + ["page-down"] = { + help = "scroll down", + messages = { + "ScrollDown", + }, + }, + ["{"] = { + help = "scroll up half", + messages = { + "ScrollUpHalf", + }, + }, + ["}"] = { + help = "scroll down half", + messages = { + "ScrollDownHalf", + }, + }, + }, + on_number = { + help = "input", + messages = { + "PopMode", + { SwitchModeBuiltin = "number" }, + "BufferInputFromKey", + }, + }, + }, +} + +xplr.config.modes.builtin.default.key_bindings.on_key["tab"] = + xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-i"] +xplr.config.modes.builtin.default.key_bindings.on_key["v"] = + xplr.config.modes.builtin.default.key_bindings.on_key["space"] +xplr.config.modes.builtin.default.key_bindings.on_key["V"] = + xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-a"] +xplr.config.modes.builtin.default.key_bindings.on_key["/"] = + xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-f"] +xplr.config.modes.builtin.default.key_bindings.on_key["h"] = + xplr.config.modes.builtin.default.key_bindings.on_key["left"] +xplr.config.modes.builtin.default.key_bindings.on_key["j"] = + xplr.config.modes.builtin.default.key_bindings.on_key["down"] +xplr.config.modes.builtin.default.key_bindings.on_key["k"] = + xplr.config.modes.builtin.default.key_bindings.on_key["up"] +xplr.config.modes.builtin.default.key_bindings.on_key["l"] = + xplr.config.modes.builtin.default.key_bindings.on_key["right"] + +-- The builtin debug error mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.debug_error = { + name = "debug error", + layout = { + Vertical = { + config = { + constraints = { + { Min = 14 }, + { MinLessThanScreenHeight = 14 }, + }, + }, + splits = { + { + CustomContent = { + title = "debug error", + body = { + StaticParagraph = { + render = [[ + + Some errors occurred during startup. + If you think this is a bug, please report it at: + + https://github.com/sayanarijit/xplr/issues/new + + Press `enter` to open the logs in your $EDITOR. + Press `escape` to ignore the errors and continue with the default config. + + To disable this mode, set `xplr.config.general.disable_debug_error_mode` + to `true` in your config file. + ]], + }, + }, + }, + }, + "InputAndLogs", + }, + }, + }, + key_bindings = { + on_key = { + ["enter"] = { + help = "open logs in editor", + messages = { + { + BashExec = [===[ + cat "${XPLR_PIPE_LOGS_OUT:?}" | ${EDITOR:-vi} - + ]===], + }, + }, + }, + ["q"] = { + help = "quit", + messages = { + "Quit", + }, + }, + }, + default = { + messages = {}, + }, + }, +} + +-- The builtin recover mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.recover = { + name = "recover", + layout = { + CustomContent = { + title = " recover ", + body = { + StaticParagraph = { + render = [[ + + You pressed an invalid key and went into "recover" mode. + This mode saves you from performing unwanted actions. + + Let's calm down, press `escape`, and try again. + + To disable this mode, set `xplr.config.general.enable_recover_mode` + to `false` in your config file. + ]], + }, + }, + }, + }, + key_bindings = { + default = { + messages = {}, + }, + }, +} + +-- The builtin go to path mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.go_to_path = { + name = "go to path", + key_bindings = { + on_key = { + ["enter"] = { + help = "submit", + messages = { + { + BashExecSilently0 = [===[ + PTH=${XPLR_INPUT_BUFFER} + PTH_ESC=$(printf %q "$PTH") + if [ -d "$PTH" ]; then + "$XPLR" -m 'ChangeDirectory: %q' "$PTH" + elif [ -e "$PTH" ]; then + "$XPLR" -m 'FocusPath: %q' "$PTH" + else + "$XPLR" -m 'LogError: %q' "could not find $PTH_ESC" + fi + ]===], + }, + "PopMode", + }, + }, + ["tab"] = { + help = "try complete", + messages = { + { CallLuaSilently = "builtin.try_complete_path" }, + }, + }, + }, + default = { + messages = { + "UpdateInputBufferFromKey", + }, + }, + }, +} + +-- The builtin selection ops mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.selection_ops = { + name = "selection ops", + layout = "HelpMenu", + key_bindings = { + on_key = { + ["c"] = { + help = "copy here", + messages = { + { + BashExec0 = [===[ + (while IFS= read -r -d '' PTH; do + PTH_ESC=$(printf %q "$PTH") + if cp -vr -- "${PTH:?}" ./; then + "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC copied to ." + else + "$XPLR" -m 'LogError: %q' "Failed to copy $PTH_ESC to ." + fi + done < "${XPLR_PIPE_SELECTION_OUT:?}") + "$XPLR" -m ExplorePwdAsync + "$XPLR" -m ClearSelection + read -p "[enter to continue]" + ]===], + }, + "PopMode", + }, + }, + ["m"] = { + help = "move here", + messages = { + { + BashExec0 = [===[ + (while IFS= read -r -d '' PTH; do + PTH_ESC=$(printf %q "$PTH") + if mv -v -- "${PTH:?}" ./; then + "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC moved to ." + else + "$XPLR" -m 'LogError: %q' "Failed to move $PTH_ESC to ." + fi + done < "${XPLR_PIPE_SELECTION_OUT:?}") + "$XPLR" -m ExplorePwdAsync + read -p "[enter to continue]" + ]===], + }, + "PopMode", + }, + }, + ["u"] = { + help = "clear selection", + messages = { + "ClearSelection", + "PopMode", + }, + }, + }, + }, +} + +-- The builtin create mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.create = { + name = "create", + layout = "HelpMenu", + key_bindings = { + on_key = { + ["d"] = { + help = "create directory", + messages = { + "PopMode", + { SwitchModeBuiltin = "create_directory" }, + { SetInputBuffer = "" }, + }, + }, + ["f"] = { + help = "create file", + messages = { + "PopMode", + { SwitchModeBuiltin = "create_file" }, + { SetInputBuffer = "" }, + }, + }, + }, + }, +} + +-- The builtin create directory mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.create_directory = { + name = "create directory", + prompt = "ð ❯ ", + key_bindings = { + on_key = { + ["tab"] = { + help = "try complete", + messages = { + { CallLuaSilently = "builtin.try_complete_path" }, + }, + }, + ["enter"] = { + help = "submit", + messages = { + { + BashExecSilently0 = [===[ + PTH="$XPLR_INPUT_BUFFER" + PTH_ESC=$(printf %q "$PTH") + if [ "$PTH" ]; then + mkdir -p -- "$PTH" \ + && "$XPLR" -m 'SetInputBuffer: ""' \ + && "$XPLR" -m ExplorePwd \ + && "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC created" \ + && "$XPLR" -m 'FocusPath: %q' "$PTH" + else + "$XPLR" -m PopMode + fi + ]===], + }, + }, + }, + }, + default = { + messages = { + "UpdateInputBufferFromKey", + }, + }, + }, +} + +-- The builtin create file mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.create_file = { + name = "create file", + prompt = "ƒ ❯ ", + key_bindings = { + on_key = { + ["tab"] = { + help = "try complete", + messages = { + { CallLuaSilently = "builtin.try_complete_path" }, + }, + }, + ["enter"] = { + help = "submit", + messages = { + { + BashExecSilently0 = [===[ + PTH="$XPLR_INPUT_BUFFER" + PTH_ESC=$(printf %q "$PTH") + if [ "$PTH" ]; then + mkdir -p -- "$(dirname $(realpath $PTH))" \ + && touch -- "$PTH" \ + && "$XPLR" -m 'SetInputBuffer: ""' \ + && "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC created" \ + && "$XPLR" -m 'ExplorePwd' \ + && "$XPLR" -m 'FocusPath: %q' "$PTH" + else + "$XPLR" -m PopMode + fi + ]===], + }, + }, + }, + }, + default = { + messages = { + "UpdateInputBufferFromKey", + }, + }, + }, +} + +-- The builtin number mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.number = { + name = "number", + prompt = ":", + key_bindings = { + on_key = { + ["down"] = { + help = "to down", + messages = { + "FocusNextByRelativeIndexFromInput", + "PopMode", + }, + }, + ["enter"] = { + help = "to index", + messages = { + "FocusByIndexFromInput", + "PopMode", + }, + }, + ["up"] = { + help = "to up", + messages = { + "FocusPreviousByRelativeIndexFromInput", + "PopMode", + }, + }, + }, + on_navigation = { + messages = { + "UpdateInputBufferFromKey", + }, + }, + on_number = { + help = "input", + messages = { + "UpdateInputBufferFromKey", + }, + }, + }, +} + +xplr.config.modes.builtin.number.key_bindings.on_key["j"] = + xplr.config.modes.builtin.number.key_bindings.on_key["down"] +xplr.config.modes.builtin.number.key_bindings.on_key["k"] = + xplr.config.modes.builtin.number.key_bindings.on_key["up"] + +-- The builtin go to mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.go_to = { + name = "go to", + layout = "HelpMenu", + key_bindings = { + on_key = { + ["f"] = { + help = "follow symlink", + messages = { + "FollowSymlink", + "PopMode", + }, + }, + ["g"] = { + help = "top", + messages = { + "FocusFirst", + "PopMode", + }, + }, + ["p"] = { + help = "path", + messages = { + "PopMode", + { SwitchModeBuiltin = "go_to_path" }, + { SetInputBuffer = "" }, + }, + }, + ["i"] = { + help = "initial $PWD", + messages = { + "PopMode", + { + BashExecSilently0 = [===[ + "$XPLR" -m 'ChangeDirectory: %q' "${XPLR_INITIAL_PWD:?}" + ]===], + }, + }, + }, + ["x"] = { + help = "open in gui", + messages = { + { + BashExecSilently0 = [===[ + if [ -z "$OPENER" ]; then + if command -v xdg-open; then + OPENER=xdg-open + elif command -v open; then + OPENER=open + else + "$XPLR" -m 'LogError: "$OPENER not found"' + exit 1 + fi + fi + (while IFS= read -r -d '' PTH; do + $OPENER "${PTH:?}" > /dev/null 2>&1 + done < "${XPLR_PIPE_RESULT_OUT:?}") + ]===], + }, + "ClearScreen", + "PopMode", + }, + }, + }, + }, +} + +-- The builtin rename mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.rename = { + name = "rename", + key_bindings = { + on_key = { + ["tab"] = { + help = "try complete", + messages = { + { CallLuaSilently = "builtin.try_complete_path" }, + }, + }, + ["enter"] = { + help = "submit", + messages = { + { + BashExecSilently0 = [===[ + SRC="${XPLR_FOCUS_PATH:?}" + SRC_ESC=$(printf %q "$SRC") + TARGET="${XPLR_INPUT_BUFFER:?}" + TARGET_ESC=$(printf %q "$TARGET") + if [ -e "${TARGET:?}" ]; then + "$XPLR" -m 'LogError: %q' "$TARGET_ESC already exists" + else + mv -- "${SRC:?}" "${TARGET:?}" \ + && "$XPLR" -m ExplorePwd \ + && "$XPLR" -m 'FocusPath: %q' "$TARGET" \ + && "$XPLR" -m 'LogSuccess: %q' "$SRC_ESC renamed to $TARGET_ESC" + fi + ]===], + }, + "PopMode", + }, + }, + }, + default = { + messages = { + "UpdateInputBufferFromKey", + }, + }, + }, +} + +-- The builtin duplicate as mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.duplicate_as = { + name = "duplicate as", + key_bindings = { + on_key = { + ["tab"] = { + help = "try complete", + messages = { + { CallLuaSilently = "builtin.try_complete_path" }, + }, + }, + ["enter"] = { + help = "submit", + messages = { + { + BashExecSilently0 = [===[ + SRC="${XPLR_FOCUS_PATH:?}" + SRC_ESC=$(printf %q "$SRC") + TARGET="${XPLR_INPUT_BUFFER:?}" + TARGET_ESC=$(printf %q "$TARGET") + if [ -e "${TARGET:?}" ]; then + "$XPLR" -m 'LogError: %q' "$TARGET_ESC already exists" + else + cp -r -- "${SRC:?}" "${TARGET:?}" \ + && "$XPLR" -m ExplorePwd \ + && "$XPLR" -m 'FocusPath: %q' "$TARGET_ESC" \ + && "$XPLR" -m 'LogSuccess: %q' "$SRC_ESC duplicated as $TARGET_ESC" + fi + ]===], + }, + "PopMode", + }, + }, + }, + default = { + messages = { + "UpdateInputBufferFromKey", + }, + }, + }, +} + +-- The builtin delete mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.delete = { + name = "delete", + layout = "HelpMenu", + key_bindings = { + on_key = { + ["D"] = { + help = "force delete", + messages = { + { + BashExec0 = [===[ + (while IFS= read -r -d '' PTH; do + PTH_ESC=$(printf %q "$PTH") + if rm -rfv -- "${PTH:?}"; then + "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC deleted" + else + "$XPLR" -m 'LogError: %q' "Failed to delete $PTH_ESC" + fi + done < "${XPLR_PIPE_RESULT_OUT:?}") + "$XPLR" -m ExplorePwdAsync + read -p "[enter to continue]" + ]===], + }, + "PopMode", + }, + }, + ["d"] = { + help = "delete", + messages = { + { + BashExec0 = [===[ + (while IFS= read -r -d '' PTH; do + PTH_ESC=$(printf %q "$PTH") + if [ -d "$PTH" ] && [ ! -L "$PTH" ]; then + if rmdir -v -- "${PTH:?}"; then + "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC deleted" + else + "$XPLR" -m 'LogError: %q' "Failed to delete $PTH_ESC" + fi + else + if rm -v -- "${PTH:?}"; then + "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC deleted" + else + "$XPLR" -m 'LogError: %q' "Failed to delete $PTH_ESC" + fi + fi + done < "${XPLR_PIPE_RESULT_OUT:?}") + "$XPLR" -m ExplorePwdAsync + read -p "[enter to continue]" + ]===], + }, + "PopMode", + }, + }, + }, + }, +} + +-- The builtin action mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.action = { + name = "action to", + layout = "HelpMenu", + key_bindings = { + on_key = { + ["!"] = { + help = "shell", + messages = { + "PopMode", + { Call0 = { command = os.getenv("SHELL") or "bash", args = { "-i" } } }, + "ExplorePwdAsync", + }, + }, + ["c"] = { + help = "create", + messages = { + "PopMode", + { SwitchModeBuiltin = "create" }, + }, + }, + ["e"] = { + help = "open in editor", + messages = { + { + BashExec0 = [===[ + ${EDITOR:-vi} "${XPLR_FOCUS_PATH:?}" + ]===], + }, + "PopMode", + }, + }, + ["l"] = { + help = "logs", + messages = { + { + BashExec = [===[ + [ -z "$PAGER" ] && PAGER="less -+F" + cat -- "${XPLR_PIPE_LOGS_OUT}" | ${PAGER:?} + ]===], + }, + "PopMode", + }, + }, + ["s"] = { + help = "selection operations", + messages = { + "PopMode", + { SwitchModeBuiltin = "selection_ops" }, + }, + }, + ["m"] = { + help = "toggle mouse", + messages = { + "PopMode", + "ToggleMouse", + }, + }, + ["v"] = { + help = "vroot", + messages = { + "PopMode", + { SwitchModeBuiltin = "vroot" }, + }, + }, + ["q"] = { + help = "quit options", + messages = { + "PopMode", + { SwitchModeBuiltin = "quit" }, + }, + }, + }, + on_number = { + help = "go to index", + messages = { + "PopMode", + { SwitchModeBuiltin = "number" }, + "BufferInputFromKey", + }, + }, + }, +} + +-- The builtin quit mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.quit = { + name = "quit", + layout = "HelpMenu", + key_bindings = { + on_key = { + ["enter"] = { + help = "just quit", + messages = { + "Quit", + }, + }, + ["p"] = { + help = "quit printing pwd", + messages = { + "PrintPwdAndQuit", + }, + }, + ["f"] = { + help = "quit printing focus", + messages = { + "PrintFocusPathAndQuit", + }, + }, + ["s"] = { + help = "quit printing selection", + messages = { + "PrintSelectionAndQuit", + }, + }, + ["r"] = { + help = "quit printing result", + messages = { + "PrintResultAndQuit", + }, + }, + }, + }, +} + +-- The builtin search mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.search = { + name = "search", + prompt = "/", + key_bindings = { + on_key = { + ["up"] = { + help = "up", + messages = { + "FocusPrevious", + }, + }, + ["down"] = { + help = "down", + messages = { + "FocusNext", + }, + }, + ["right"] = { + help = "enter", + messages = { + "Enter", + { SetInputBuffer = "" }, + }, + }, + ["left"] = { + help = "back", + messages = { + "Back", + { SetInputBuffer = "" }, + }, + }, + ["tab"] = { + help = "toggle selection", + messages = { + "ToggleSelection", + "FocusNext", + }, + }, + ["enter"] = { + help = "submit", + messages = { + "AcceptSearch", + "PopMode", + }, + }, + ["esc"] = { + help = "cancel", + messages = { + "CancelSearch", + "PopMode", + }, + }, + }, + default = { + messages = { + "UpdateInputBufferFromKey", + "SearchFuzzyFromInput", + "ExplorePwdAsync", + }, + }, + }, +} + +xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-n"] = + xplr.config.modes.builtin.search.key_bindings.on_key["down"] +xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-p"] = + xplr.config.modes.builtin.search.key_bindings.on_key["up"] + +-- The builtin filter mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.filter = { + name = "filter", + key_bindings = { + on_key = { + ["r"] = { + help = "relative path does match regex", + messages = { + { SwitchModeBuiltin = "relative_path_does_match_regex" }, + { SetInputBuffer = "" }, + { AddNodeFilterFromInput = "RelativePathDoesMatchRegex" }, + "ExplorePwdAsync", + }, + }, + ["R"] = { + help = "relative path does not match regex", + messages = { + { SwitchModeBuiltin = "relative_path_does_not_match_regex" }, + { SetInputBuffer = "" }, + { AddNodeFilterFromInput = "RelativePathDoesNotMatchRegex" }, + "ExplorePwdAsync", + }, + }, + ["backspace"] = { + help = "remove last filter", + messages = { + "RemoveLastNodeFilter", + "ExplorePwdAsync", + }, + }, + ["ctrl-r"] = { + help = "reset filters", + messages = { + "ResetNodeFilters", + "ExplorePwdAsync", + }, + }, + ["ctrl-u"] = { + help = "clear filters", + messages = { + "ClearNodeFilters", + "ExplorePwdAsync", + }, + }, + }, + }, +} + +-- The builtin relative_path_does_match_regex mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.relative_path_does_match_regex = { + name = "relative path does match regex", + prompt = xplr.config.general.sort_and_filter_ui.filter_identifiers.RelativePathDoesMatchRegex.format, + key_bindings = { + on_key = { + ["enter"] = { + help = "submit", + messages = { + "PopMode", + }, + }, + ["esc"] = { + messages = { + { RemoveNodeFilterFromInput = "RelativePathDoesMatchRegex" }, + "PopMode", + "ExplorePwdAsync", + }, + }, + }, + default = { + messages = { + { RemoveNodeFilterFromInput = "RelativePathDoesMatchRegex" }, + "UpdateInputBufferFromKey", + { AddNodeFilterFromInput = "RelativePathDoesMatchRegex" }, + "ExplorePwdAsync", + }, + }, + }, +} + +-- The builtin relative_path_does_not_match_regex mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.relative_path_does_not_match_regex = { + name = "relative path does not match regex", + prompt = xplr.config.general.sort_and_filter_ui.filter_identifiers.RelativePathDoesNotMatchRegex.format, + key_bindings = { + on_key = { + ["enter"] = { + help = "submit", + messages = { + "PopMode", + }, + }, + ["esc"] = { + messages = { + { RemoveNodeFilterFromInput = "RelativePathDoesNotMatchRegex" }, + "PopMode", + "ExplorePwdAsync", + }, + }, + }, + default = { + messages = { + { RemoveNodeFilterFromInput = "RelativePathDoesNotMatchRegex" }, + "UpdateInputBufferFromKey", + { AddNodeFilterFromInput = "RelativePathDoesNotMatchRegex" }, + "ExplorePwdAsync", + }, + }, + }, +} + +-- The builtin sort mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.sort = { + name = "sort", + key_bindings = { + on_key = { + ["!"] = { + help = "reverse sorters", + messages = { + "ReverseNodeSorters", + "ExplorePwdAsync", + }, + }, + ["E"] = { + help = "by canonical extension reverse", + messages = { + { AddNodeSorter = { sorter = "ByCanonicalExtension", reverse = true } }, + "ExplorePwdAsync", + }, + }, + ["M"] = { + help = "by canonical mime essence reverse", + messages = { + { AddNodeSorter = { sorter = "ByCanonicalMimeEssence", reverse = true } }, + "ExplorePwdAsync", + }, + }, + ["N"] = { + help = "by node type reverse", + messages = { + { AddNodeSorter = { sorter = "ByCanonicalIsDir", reverse = true } }, + { AddNodeSorter = { sorter = "ByCanonicalIsFile", reverse = true } }, + { AddNodeSorter = { sorter = "ByIsSymlink", reverse = true } }, + "ExplorePwdAsync", + }, + }, + ["R"] = { + help = "by relative path reverse", + messages = { + { AddNodeSorter = { sorter = "ByIRelativePath", reverse = true } }, + "ExplorePwdAsync", + }, + }, + ["S"] = { + help = "by size reverse", + messages = { + { AddNodeSorter = { sorter = "BySize", reverse = true } }, + "ExplorePwdAsync", + }, + }, + ["backspace"] = { + help = "remove last sorter", + messages = { + "RemoveLastNodeSorter", + "ExplorePwdAsync", + }, + }, + ["ctrl-r"] = { + help = "reset sorters", + messages = { + "ResetNodeSorters", + "ExplorePwdAsync", + }, + }, + ["ctrl-u"] = { + help = "clear sorters", + messages = { + "ClearNodeSorters", + "ExplorePwdAsync", + }, + }, + ["e"] = { + help = "by canonical extension", + messages = { + { AddNodeSorter = { sorter = "ByCanonicalExtension", reverse = false } }, + "ExplorePwdAsync", + }, + }, + ["enter"] = { + help = "submit", + messages = { + "PopMode", + }, + }, + ["m"] = { + help = "by canonical mime essence", + messages = { + { AddNodeSorter = { sorter = "ByCanonicalMimeEssence", reverse = false } }, + "ExplorePwdAsync", + }, + }, + ["n"] = { + help = "by node type", + messages = { + { AddNodeSorter = { sorter = "ByCanonicalIsDir", reverse = false } }, + { AddNodeSorter = { sorter = "ByCanonicalIsFile", reverse = false } }, + { AddNodeSorter = { sorter = "ByIsSymlink", reverse = false } }, + "ExplorePwdAsync", + }, + }, + ["r"] = { + help = "by relative path", + messages = { + { AddNodeSorter = { sorter = "ByIRelativePath", reverse = false } }, + "ExplorePwdAsync", + }, + }, + ["s"] = { + help = "by size", + messages = { + { AddNodeSorter = { sorter = "BySize", reverse = false } }, + "ExplorePwdAsync", + }, + }, + + ["c"] = { + help = "by created", + messages = { + { AddNodeSorter = { sorter = "ByCreated", reverse = false } }, + "ExplorePwdAsync", + }, + }, + + ["C"] = { + help = "by created reverse", + messages = { + { AddNodeSorter = { sorter = "ByCreated", reverse = true } }, + "ExplorePwdAsync", + }, + }, + + ["l"] = { + help = "by last modified", + messages = { + { AddNodeSorter = { sorter = "ByLastModified", reverse = false } }, + "ExplorePwdAsync", + }, + }, + + ["L"] = { + help = "by last modified reverse", + messages = { + { AddNodeSorter = { sorter = "ByLastModified", reverse = true } }, + "ExplorePwdAsync", + }, + }, + }, + }, +} + +-- The builtin switch layout mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.switch_layout = { + name = "switch layout", + layout = "HelpMenu", + key_bindings = { + on_key = { + ["1"] = { + help = "default", + messages = { + { SwitchLayoutBuiltin = "default" }, + "PopMode", + }, + }, + ["2"] = { + help = "no help menu", + messages = { + { SwitchLayoutBuiltin = "no_help" }, + "PopMode", + }, + }, + ["3"] = { + help = "no selection panel", + messages = { + { SwitchLayoutBuiltin = "no_selection" }, + "PopMode", + }, + }, + ["4"] = { + help = "no help or selection", + messages = { + { SwitchLayoutBuiltin = "no_help_no_selection" }, + "PopMode", + }, + }, + }, + }, +} + +-- The builtin vroot mode. +-- +-- Type: [Mode](https://xplr.dev/en/mode) +xplr.config.modes.builtin.vroot = { + name = "vroot", + layout = "HelpMenu", + key_bindings = { + on_key = { + ["v"] = { + help = "toggle vroot", + messages = { + "PopMode", + "ToggleVroot", + }, + }, + ["."] = { + help = "vroot $PWD", + messages = { + "PopMode", + { + BashExecSilently0 = [===[ + "$XPLR" -m 'SetVroot: %q' "${PWD:?}" + ]===], + }, + }, + }, + ["/"] = { + help = "vroot /", + messages = { + "PopMode", + { SetVroot = "/" }, + }, + }, + ["~"] = { + help = "vroot $HOME", + messages = { + "PopMode", + { + BashExecSilently0 = [===[ + "$XPLR" -m 'SetVroot: %q' "${HOME:?}" + ]===], + }, + }, + }, + ["ctrl-r"] = { + help = "reset vroot", + messages = { + "PopMode", + "ResetVroot", + }, + }, + ["ctrl-u"] = { + help = "unset vroot", + messages = { + "PopMode", + "UnsetVroot", + }, + }, + }, + }, +} + +-- This is where you define custom modes. +-- +-- Type: mapping of the following key-value pairs: +-- +-- * key: string +-- * value: [Mode](https://xplr.dev/en/mode) +-- +-- Example: +-- +-- ```lua +-- xplr.config.modes.custom.example = { +-- name = "example", +-- key_bindings = { +-- on_key = { +-- enter = { +-- help = "default mode", +-- messages = { +-- "PopMode", +-- { SwitchModeBuiltin = "default" }, +-- }, +-- }, +-- }, +-- }, +-- } +-- +-- xplr.config.general.initial_mode = "example" +-- ``` +xplr.config.modes.custom = {} + +-- ## Function ---------------------------------------------------------------- +-- +-- While `xplr.config` defines all the static parts of the configuration, +-- `xplr.fn` defines all the dynamic parts using functions. +-- +-- See: [Lua Function Calls](https://xplr.dev/en/lua-function-calls) +-- +-- As always, `xplr.fn.builtin` is where the built-in functions are defined +-- that can be overwritten. + +-- Tries to auto complete the path in the input buffer +xplr.fn.builtin.try_complete_path = function(m) + if not m.input_buffer then + return + end + + local function matches_all(str, paths) + for _, path in ipairs(paths) do + if string.sub(path, 1, #str) ~= str then + return false + end + end + return true + end + + local path = m.input_buffer + local explorer_config = { + filters = { + { filter = "RelativePathDoesStartWith", input = xplr.util.basename(path) }, + }, + } + local parent = xplr.util.dirname(path) + if not parent or parent == "" then + parent = "./" + elseif parent ~= "/" then + parent = parent .. "/" + end + + local nodes = xplr.util.explore(parent, explorer_config) + local found = {} + for _, node in ipairs(nodes) do + table.insert(found, parent .. node.relative_path) + end + local count = #found + + if count == 0 then + return + elseif count == 1 then + return { + { SetInputBuffer = found[1] }, + } + else + local first = found[1] + while #first > #path and matches_all(path, found) do + path = string.sub(first, 1, #path + 1) + end + + if matches_all(path, found) then + return { + { SetInputBuffer = path }, + } + end + + return { + { SetInputBuffer = string.sub(path, 1, #path - 1) }, + } + end +end + +-- Renders the first column in the table +xplr.fn.builtin.fmt_general_table_row_cols_0 = function(m) + local r = "" + if m.is_before_focus then + r = r .. " -" + else + r = r .. " " + end + + r = r .. m.relative_index .. "│" .. m.index + + return r +end + +-- Renders the second column in the table +xplr.fn.builtin.fmt_general_table_row_cols_1 = function(m) + local r = m.tree .. m.prefix + + local function path_escape(path) + return string.gsub(string.gsub(path, "\\", "\\\\"), "\n", "\\n") + end + + if m.meta.icon == nil then + r = r .. "" + else + r = r .. m.meta.icon .. " " + end + + r = r .. path_escape(m.relative_path) + + if m.is_dir then + r = r .. "/" + end + + r = r .. m.suffix .. " " + + if m.is_symlink then + r = r .. "-> " + + if m.is_broken then + r = r .. "×" + else + r = r .. path_escape(m.symlink.absolute_path) + + if m.symlink.is_dir then + r = r .. "/" + end + end + end + + return r +end + +-- Renders the third column in the table +xplr.fn.builtin.fmt_general_table_row_cols_2 = function(m) + local no_color = os.getenv("NO_COLOR") + + local function green(x) + if no_color == nil then + return "\x1b[32m" .. x .. "\x1b[0m" + else + return x + end + end + + local function yellow(x) + if no_color == nil then + return "\x1b[33m" .. x .. "\x1b[0m" + else + return x + end + end + + local function red(x) + if no_color == nil then + return "\x1b[31m" .. x .. "\x1b[0m" + else + return x + end + end + + local function bit(x, color, cond) + if cond then + return color(x) + else + return color("-") + end + end + + local p = m.permissions + + local r = "" + + r = r .. bit("r", green, p.user_read) + r = r .. bit("w", yellow, p.user_write) + + if p.user_execute == false and p.setuid == false then + r = r .. bit("-", red, p.user_execute) + elseif p.user_execute == true and p.setuid == false then + r = r .. bit("x", red, p.user_execute) + elseif p.user_execute == false and p.setuid == true then + r = r .. bit("S", red, p.user_execute) + else + r = r .. bit("s", red, p.user_execute) + end + + r = r .. bit("r", green, p.group_read) + r = r .. bit("w", yellow, p.group_write) + + if p.group_execute == false and p.setuid == false then + r = r .. bit("-", red, p.group_execute) + elseif p.group_execute == true and p.setuid == false then + r = r .. bit("x", red, p.group_execute) + elseif p.group_execute == false and p.setuid == true then + r = r .. bit("S", red, p.group_execute) + else + r = r .. bit("s", red, p.group_execute) + end + + r = r .. bit("r", green, p.other_read) + r = r .. bit("w", yellow, p.other_write) + + if p.other_execute == false and p.setuid == false then + r = r .. bit("-", red, p.other_execute) + elseif p.other_execute == true and p.setuid == false then + r = r .. bit("x", red, p.other_execute) + elseif p.other_execute == false and p.setuid == true then + r = r .. bit("T", red, p.other_execute) + else + r = r .. bit("t", red, p.other_execute) + end + + return r +end + +-- Renders the fourth column in the table +xplr.fn.builtin.fmt_general_table_row_cols_3 = function(m) + if not m.is_dir then + return m.human_size + else + return "" + end +end + +-- Renders the fifth column in the table +xplr.fn.builtin.fmt_general_table_row_cols_4 = function(m) + return tostring(os.date("%a %b %d %H:%M:%S %Y", m.last_modified / 1000000000)) +end + +-- This is where the custom functions can be added. +-- +-- There is currently no restriction on what kind of functions can be defined +-- in `xplr.fn.custom`. +-- +-- You can also use nested tables such as +-- `xplr.fn.custom.my_plugin.my_function` to define custom functions. +xplr.fn.custom = {} + +-- ## Hooks ------------------------------------------------------------------- +-- +-- This section of the configuration cannot be overwritten by another config +-- file or plugin, since this is an optional lua return statement specific to +-- each config file. It can be used to define things that should be explicit +-- for reasons like performance concerns, such as hooks. +-- +-- Plugins should expose the hooks, and require users to subscribe to them +-- explicitly. +-- +-- Example: +-- +-- ```lua +-- return { +-- -- Add messages to send when the xplr loads. +-- -- This is similar to the `--on-load` command-line option. +-- -- +-- -- Type: list of [Message](https://xplr.dev/en/message#message)s +-- on_load = { +-- { LogSuccess = "Configuration successfully loaded!" }, +-- { CallLuaSilently = "custom.some_plugin_with_hooks.on_load" }, +-- }, +-- +-- -- Add messages to send when the directory changes. +-- -- +-- -- Type: list of [Message](https://xplr.dev/en/message#message)s +-- on_directory_change = { +-- { LogSuccess = "Changed directory" }, +-- { CallLuaSilently = "custom.some_plugin_with_hooks.on_directory_change" }, +-- }, +-- +-- -- Add messages to send when the focus changes. +-- -- +-- -- Type: list of [Message](https://xplr.dev/en/message#message)s +-- on_focus_change = { +-- { LogSuccess = "Changed focus" }, +-- { CallLuaSilently = "custom.some_plugin_with_hooks.on_focus_change" }, +-- } +-- } +-- ``` + +return { + on_load = {}, + on_directory_change = {}, + on_focus_change = {}, +} +