sk(1)
๐ sk(1) โ Fuzzy Finder in rust! ๐ฆ
okay so like, welcome to the sk page, bestie โ it's from the General Commands Manual and honestly it's giving main character energy from the very first line. โจ We're gonna walk through the whole thing together, no cap, every single flag included. Buckle up. ๐
๐ธ NAME ๐ธ
sk โ Fuzzy Finder in rust! ๐ฆโจ
๐ SYNOPSIS ๐
okay so this is the big vibe-check wall of options. Don't panic, it's literally just every flag the thing accepts, laid out exactly like this:
sk [--tac] [--min-query-length] [--no-sort] [-t|--tiebreak] [-n|--nth]
[--with-nth] [--hide-nth] [-d|--delimiter] [-e|--exact] [--regex]
[--algo] [--case] [--typos] [--no-typos] [--normalize] [--split-match]
[--last-match] [--scheme] [-b|--bind] [-m|--multi] [--no-multi]
[--no-mouse] [-c|--cmd] [-i|--interactive] [-I ] [--color]
[--highlight-line] [--no-hscroll] [--keep-right] [--skip-to-pattern]
[--no-clear-if-empty] [--no-clear-start] [--no-clear] [--show-cmd-error]
[--cycle] [--disabled] [--disable-pattern] [--layout] [--reverse]
[--height] [--no-height] [--min-height] [--margin] [-p|--prompt]
[--cmd-prompt] [--selector] [--multi-selector] [--ansi] [--tabstop]
[--info] [--no-info] [--inline-info] [--header] [--header-lines]
[--separator] [--no-separator] [--border] [--border-no-collapse]
[--no-border] [--wrap] [--multiline] [--scrollbar] [--no-scrollbar]
[--history] [--history-size] [--cmd-history] [--cmd-history-size]
[--preview] [--preview-window] [--image] [-q|--query] [--cmd-query]
[--read0] [--print0] [--print-query] [--print-cmd] [--print-score]
[--print-header] [--print-current] [--output-format] [--no-strip-ansi]
[-1|--select-1] [-0|--exit-0] [--sync] [--pre-select-n]
[--pre-select-pat] [--pre-select-items] [--pre-select-file]
[-f|--filter] [--shell] [--shell-bindings] [--man] [--listen] [--remote]
[--popup] [--popup-name] [--log-level] [--log-file] [--expect]
[-h|--help] [-V|--version]
(yes, [-I ] really does have a space in it, that's not a typo, that's just how it is ๐)
โจ OPTIONS โจ
these are the base-level, everyone-gets-them options. short and sweet, like a good coffee order. โ
-h,--helpโ prints the help text. and heads up: it goes "see a summary with-h", so if you want the short version you already know where to look ๐-V,--versionโ prints the version. that's it. that's the whole job. iconic behavior. ๐
๐ SEARCH ๐
the part where sk actually finds stuff. this is the whole reason we're here, bestie. let's get into it. ๐
--tacโ shows results in reverse order. ๐
ngl this one is often used in combination with --no-sort. they're like a package deal.
--min-query-length <MIN_QUERY_LENGTH>โ the minimum query length before it starts showing results. โณ
so like, it only shows results when your query is at least this many characters long. and in interactive mode with --cmd, it also waits before running the command. under --disabled it has no effect at all โ literally does nothing there, so don't bother. ๐
--no-sortโ does not sort the results. chaotic, but valid. ๐
often used in combination with --tac. example time, keep this exactly:
history | sk --tac --no-sort
-t,--tiebreak <TIEBREAK>[default:score,begin,end] โ a comma-separated list of sort criteria to apply when the scores are tied. ๐ค
think of it as the tiebreaker round in a beauty pageant. here's the criteria:
score: the score from the fuzzy match algorithm.- each criterion could be negated, e.g.
(-index) - each criterion should appear only once in the list โ no duplicates, that's not the vibe ๐ซ
- each criterion could be negated, e.g.
possible values:
score-scorebegin-beginend-endlength-lengthindex-indexpathname-pathname
-n,--nth <NTH>[default:] โ which fields get matched. ๐ฏ
a field index expression can be a non-zero integer or a range expression ([BEGIN]..[END]). and --nth and --with-nth both take a comma-separated list of field index expressions. slay, very flexible.
examples:
1 The 1st field
2 The 2nd field
-1 The last field
-2 The 2nd to last field
3..5 From the 3rd field to the 5th field
2.. From the 2nd field to the last field
..-3 From the 1st field to the 3rd to the last field
.. All the fields
--with-nth <WITH_NTH>[default:] โ fields to be transformed. ๐ช
see nth for the details, it's the same energy, just for transforming.
--hide-nth <HIDE_NTH>[default:] โ fields to hide from the display while keeping them searchable. ๐ซฃ
it takes the same comma-separated field index expressions as nth. the listed fields get removed from the displayed line but they remain part of the text used for matching โ so a query can still match them. characters in the hidden fields are ignored for match highlighting and horizontal scrolling. sneaky AND useful, we love that.
see nth for the field index expression syntax.
-d,--delimiter <DELIMITER>[default:[\t\n ]+] โ the delimiter between fields. โ๏ธ
it's in regex format, and it defaults to AWK-style. escape sequences like \x00, \t, \n are supported. fancy. ๐
-e,--exactโ runs in exact mode. no fuzzy, no vibes, just exact. ๐ฏ--regexโ starts in regex mode instead of fuzzy-match. for the regex girlies. ๐ธ--algo <ALGORITHM>[default:arinae] โ which fuzzy matching algorithm to use. ๐งarinae(ari): latest algorithmskim_v2: legacy skim algorithmclangd: used in clangd for keyword completionfzy: algorithm from fzy (<https://github.com/jhawthorn/fzy>)frizbee: algorithm used in the blink.cmp neovim plugin
possible values:
arinae: Arinae: typo-resistant & natural algorithm, defaultclangd: Clangd fuzzy matching algorithmfzy: Fzy matching algorithm (https://github.com/jhawthorn/fzy)frizbee: Frizbee matching algorithm, typo resistantskim_v2: Previous skim fuzzy matching algorithm (v2)
--case <CASE>[default:smart] โ case sensitivity. ๐
determines whether or not to ignore case while matching. note: this is not used for the Frizbee matcher, which uses a penalty system to favor case-sensitivity without enforcing it. so like, frizbee plays by its own rules, respect it.
possible values:
respect: case-sensitive matchingignore: case-insensitive matchingsmart: smart case: case-insensitive unless query contains uppercase
--typos [<TYPOS>][default:disabled] โ enables typo-tolerant matching. ๐ซถ
when passed without a value (--typos), it uses the adaptive formula (pattern_length / 4). when passed with a value (e.g. --typos=2), it uses that exact number as the maximum allowed typos. and --typos=0 explicitly disables typo tolerance. applies to both the fzy and frizbee matchers. we love a forgiving queen. ๐
--no-typosโ disables typo-tolerant matching. back to strict mode, bestie. ๐ซ--normalizeโ normalizes unicode characters. ๐
when set, it normalizes accents and other unicode diacritics/others. so รฉ and e can finally be friends.
--split-match [<SPLIT_MATCH>...]โ enables split matching and sets the delimiter. โ๏ธ
split matching runs the matcher in splits: foo:bar will match all items matching foo, then :, then bar if the delimiter is present โ or match normally if it's not. lowkey genius.
--last-matchโ highlights the last match found, not the first one. ๐
this makes tiebreak more pertinent on path items where we want to prioritize a match on the last parts. path girlies, this one's for you. ๐ค๏ธ
--scheme <SCHEME>[default:default] โ the search scheme. ๐จ
possible values:
default: default scheme, no modifications to the optionspath: path scheme: will find the furthest match in the item and setpathnameas the maintiebreakhistory: history scheme: will forceindexas the firsttiebreak
๐ a few more things about --bind ๐
Multiple actions can be chained using + separator.
Example: sk --bind 'ctrl-a:select-all+accept'
Special behaviors โจ
With the execute(...) and reload(...) actions, you can execute arbitrary commands without leaving sk. For example, you can turn sk into a simple file browser by binding the enter key to the less command like this:
sk --bind "enter:execute(less {})"
Note: if no argument is supplied to reload, the default command is run.
You can use the same placeholder expressions as in --preview.
sk switches to the alternate screen when executing a command. However, if the command is expected to complete quickly, and you aren't interested in its output, you might want to use execute-silent instead โ it silently executes the command without the switching. Note that sk will not be responsive until the command is complete. For asynchronous execution, start your command as a background process (i.e. appending &). ๐
With the if-query-empty and if-query-not-empty actions, you can specify which action to execute depending on the query condition. For example:
sk --bind 'ctrl-d:if-query-empty(abort)+delete-char'
If the query is empty, skim will execute abort, otherwise it executes delete-char. It's equal to 'delete-char/eof'. slay ๐
-m,--multiโ turn on multiple selection, bestie. Uses Tab and S-Tab for selection by default.--no-multiโ nope, no multiple selection, we're doing one thing at a time ๐ซถ--no-mouseโ mouse? off. gone. not invited to the party ๐-c,--cmd <CMD>โ the command to invoke dynamically in interactive mode. It gets invoked usingsh -con Unix-like systems andcmd /con Windows.-i,--interactiveโ startskimin interactive mode. In interactive mode,skwill run the command specified by the--cmdoption and display the results. ๐ฅ-I <REPLSTR>โ replace replstr with the selected item in commands.[default: {}]--color <COLOR>โ set the color theme, aesthetic queen ๐ Format:[BASE][,COLOR:ANSI[:ATTR1:ATTR2:..]]โ see the [THEME] section for details. Repeated--coloroptions are merged in order, so a later value overrides an earlier one for the same element.--highlight-lineโ highlight the entire current line, not just the text. the whole vibe, not just the words โจ--no-hscrollโ disable horizontal scroll--keep-rightโ keep the right end of the line visible on overflow. Effective only when the query string is empty.--skip-to-pattern <SKIP_TO_PATTERN>โ show the matched pattern at the line start. The line will start with the start of the matched pattern. Effective only when the query string is empty. Was designed to skip showing starts of paths ofrg/grepresults. e.g.sk -i -c "rg {q} --color=always" --skip-to-pattern '[^/]*:' --ansi--no-clear-if-emptyโ don't clear the previous line if the command returns an empty result. Don't clear previous items if a new command returns an empty result. This might be useful to reduce flickering when you're typing new commands and the half-complete commands aren't valid. It's not the default behavior because similar use cases forgrepandrghave already been optimized, where empty query results actually mean "empty" and previous results should be cleared.--no-clear-startโ don't clear items on start--no-clearโ don't clear the screen on exit. Don't clear the finder interface on exit either. Ifskimwas started in full screen mode, it will not switch back to the original screen, so you'll have to manually runtput rmcupto return. This option can be used to avoid flickering of the screen when your application needs to startskimmultiple times in order. ๐ญ careful with this one--show-cmd-errorโ show an error message if the command fails ๐--cycleโ cycle the results by wrapping around when scrolling ๐--disabledโ disable matching entirely--disable-pattern <DISABLE_PATTERN>โ disable items based on this regex pattern
๐ฆ LAYOUT ๐ฆ
--layout <LAYOUT>โ set the layout.[default: default]Possible values:default: display from the bottom of the screenreverse: display from the top of the screenreverse-list: display from the top of the screen, prompt at the bottom
--reverseโ shorthand forreverselayout, iykyk--height <HEIGHT>โ height of skim's window.[default: 100%]Can either be a row count or a percentage. A negative row count will useterm height - valueas the height.--no-heightโ disable height (force full screen), main character energy ๐--min-height <MIN_HEIGHT>โ minimum height of skim's window as a non-negative row count.[default: 10]Must be a non-negative row count, not a percentage. Useful when the height is set as a percentage. Ignored when--heightis not specified.--margin <MARGIN>โ screen margin.[default: 0]For each side, it can be either a row count or a percentage of the terminal size. Format can be one of:TRBLTB,RLT,RL,BT,R,B,L
Example: 1,10%
-p,--prompt <PROMPT>โ set the prompt.[default: > ]๐--cmd-prompt <CMD_PROMPT>โ set the prompt in command mode.[default: c> ]--selector <SELECTOR_ICON>โ set the selected item icon.[default: >]--multi-selector <MULTI_SELECT_ICON>โ set the multi-selected item icon.[default: >]๐ซถ
โจ DISPLAY โจ
--ansiโ bestie, this one parses the ANSI color codes straight out of your input strings ๐
Ok but heads up โ when you're using skim as a library, this flag does literally nothing ๐ญ you gotta enable ansi parsing manually by injecting a cmd_collector like this:
use skim::prelude::*;
let _options = SkimOptionsBuilder::default()
.cmd("ls --color")
.cmd_collector(Rc::new(RefCell::new(SkimItemReader::new(
SkimItemReaderOption::default().ansi(true),
))) as Rc<RefCell<dyn CommandCollector>>)
.build()
.unwrap();
--tabstop <TABSTOP>[default:8] โ how many spaces make up one tab ๐ซถ--info <INFO>[default:default] โ where the matching-result count shows up ๐hiddenโ do not display info at all, gone, invisibleinline[:SEP]โ display info in the same row as the input, with an optional non-default separatordefaultโ display info in a dedicated row above the inputleftโ display all info left-aligned in a dedicated row above the inputrightโ display all info right-aligned in a dedicated row above the inputinline-right[:SEP]โ display info right-aligned in the same row as the input, with an optional non-default separator
--no-infoโ alias for--info=hidden๐--inline-infoโ alias for--info=inlineโจ--header <HEADER>โ set the header, displayed next to the info ๐
The string you give gets printed as the sticky header. The lines show up in the order you gave them, top to bottom, no matter what the --layout option says, and they're not affected by --with-nth. Also, ANSI color codes get processed here even when --ansi is not set โ periodt.
--header-lines <HEADER_LINES>[default:0] โ how many lines of the input get treated as header ๐
The first N lines of your input become the sticky header. And when --with-nth is set, those lines get transformed exactly like all the other lines that follow.
--separator <SEPARATOR>โ draw a repeating horizontal separator on the status line ๐ฆ
With inline info, it follows the status on the prompt line. With inline-right or hidden info, it occupies a separate line. Disabled by default, and an empty string also disables it. An enabled border row gets reused where possible.
--no-separatorโ disable the horizontal separator, bye ๐--border [<BORDER>...][default:none] โ draw borders around the UI components, it's giving framed ๐ผ๏ธ
Possible values:
force-off:ForceOffdisables borders around popups too, set withno_bordernoneplainroundeddoublethicklight-double-dashedheavy-double-dashedlight-triple-dashedheavy-triple-dashedlight-quadruple-dashedheavy-quadruple-dashedquadrant-insidequadrant-outside
--border-no-collapseโ do not collapse adjacent borders into a shared row or column ๐ซ--no-borderโ disables all borders, including in tmux/zellij popups ๐--wrapโ wrap items in the item list ๐--multiline [<MULTILINE>]โ split item text into multiple display lines at the given separator character; defaults to\nifread0is set, and\\nif not (matching literal\nin text) ๐ง
Each item's text gets split on the separator, and each part is displayed as its own separate line within that item's row. It's giving multi-line main character energy.
--scrollbar <THUMB>[default:โ] โ set the scrollbar style for the item list ๐ธ
The optional value is what's used as the indicator.
--no-scrollbarโ disable the scrollbar in the item list, minimalism slay โจ--popup [<POPUP>...]โ run in a tmux or zellij popup, pop off queen ๐
Format: sk --popup <center|top|bottom|left|right>[,SIZE[%]][,SIZE[%]]
Note: this will try to detect a Zellij session, then a Tmux session. Which means that in nested sessions, skim prioritizes Zellij over Tmux.
The popup pane is named after --popup-name (default: skim).
--popup-name <POPUP_NAME>โ name of the popup pane (Zellij) / title of the popup (tmux) ๐ท๏ธ
Only used with --popup. Defaults to skim in Zellij; tmux popups get no title unless this is set. Oh and --border-label is accepted as an fzf-compatible alias, iykyk.
๐ฐ๏ธ HISTORY ๐ฐ๏ธ
--history <HISTORY_FILE>โ history file, bestie ๐
Loads search history from the specified file and updates that file on completion.
When enabled, CTRL+N and CTRL+P are automatically remapped to next-history and previous-history.
--history-size <HISTORY_SIZE>[default:1000] โ maximum number of query history entries to keep ๐--cmd-history <CMD_HISTORY_FILE>โ command history file ๐
Loads command query history from the specified file and updates that file on completion.
When enabled, CTRL+N and CTRL+P are automatically remapped to next-history and previous-history (yes, same deal as above, it's that iconic).
--cmd-history-size <CMD_HISTORY_SIZE>[default:1000] โ maximum number of query history entries to keep ๐
๐ PREVIEW ๐
--preview <PREVIEW>โ preview command, the moment you've all been waiting for ๐ฌ
Executes the given command with sh -c on linux and cmd /c on windows for the current line, and displays the result on the preview window. {} in the command is the placeholder that gets replaced with the single-quoted string of the current line. To transform the replacement string, specify field index expressions between the braces (see FIELD INDEX EXPRESSION for the deets).
Examples:
sk --preview='head -$LINES {}'
ls -l | sk --preview="echo user={3} when={-4..-2}; cat {-1}" --header-lines=1
--preview-window <PREVIEW_WINDOW>[default:right:50%] โ preview window layout ๐ช
Format: [up|down|left|right][:SIZE][:hidden][:[no]wrap][:[no]pty][:+SCROLL[-OFFSET]]
Determines the layout of the preview window. If the argument ends with :hidden, the preview window will be hidden by default until the toggle-preview action is triggered. Long lines are truncated by default. Line wrap can be enabled with the :wrap flag. For more interactive commands, or previews that draw complex interfaces, the preview can use a PTY with the :pty flag.
Note: the preview will run in a PTY (interactive session) on Linux and when wrap is unset.
SIZE can be either:
0, which will hide the preview window- A positive size (eg
20) - A percentage of the total size (eg
50%) - A negative size, which will set the size of everything but the preview to that value
+SCROLL[-OFFSET] determines the initial scroll offset of the preview window. SCROLL can be either a numeric integer or a single-field index expression that refers to a numeric integer. The optional -OFFSET part is for adjusting the base offset so you can see the text above it. It should be given as a numeric integer (-INTEGER), or as a denominator form (-/INTEGER) for specifying a fraction of the preview window height.
Examples:
# Non-default scroll window positions and sizes
sk --preview="head {}" --preview-window=up:30%
sk --preview="file {}" --preview-window=down:2
# Initial scroll offset is set to the line number of each line of
# git grep output *minus* 5 lines (-5)
git grep --line-number '' |
sk --delimiter: --preview 'nl {1}' --preview-window +{2}-5
# Preview with bat, matching line in the middle of the window (-/2)
git grep --line-number '' |
sk --delimiter : \
--preview 'bat --style=numbers --color=always --highlight-line {2} {1}' \
--preview-window +{2}-/2
--image [<IMAGE>...]โ enable image preview, we're visual now ๐ผ๏ธโจ
This renders the preview argument as an image instead of running it as a command.
If set to detect, or if no value is passed, it will try to detect the available image backends at startup โ which adds a small delay before the first render. If set to halfblocks, it will always use the halfblocks rendering method.
Note: the backend detection will not work when piping data into skim. UseSKIM_DEFAULT_COMMAND="find . -type f" sk --imageinstead offind . -type f | sk --imageโ no cap, that's the move.
Possible values:
detect: Default โ automatically detect the available backend at startuphalfblocks: Force halfblocks if you want blurry previews but a faster startup, or if the detection fails
๐ SCRIPTING โจ
okay so this is the stash of flags you reach for when you're scripting sk instead of just vibing in the TUI ๐ซถ
-q,--query <QUERY>โ the initial query, bestie. the thing that's already typed in when sk opens ๐--cmd-query <CMD_QUERY>โ the initial query, but for interactive mode specifically ๐ซ--read0โ read the input delimited by ASCII NUL(\0) characters ๐ซง--print0โ print the output delimited by ASCII NUL(\0) characters ๐--print-queryโ print the query as the first line ๐--print-cmdโ print the command as the first line (after print-query) ๐--print-scoreโ print the score after each item ๐ฅ--print-headerโ print the header as the first line (after print-score) ๐ธ--print-currentโ print the current (highlighted) item as the first line (after print-header) โญ--output-format <OUTPUT_FORMAT>โ set the output format. If set, it overrides allprint_options. It gets expanded the same way as preview or commands โจ--no-strip-ansiโ print the ANSI codes, making the output exactly match the input even when--ansiis on ๐-1,--select-1โ do NOT enter the TUI if the query passed in-qmatches only one item, just return it ๐ฏ-0,--exit-0โ do NOT enter the TUI if the query passed in-qdoesn't match any item ๐--syncโ synchronous search for multi-staged filtering. If you specify it, skim will launch the TUI finder only after the input stream is complete. e.g.sk --multi | sk --sync๐ฆ--pre-select-n <PRE_SELECT_N>[default: 0]โ pre-select the first n items in multi-selection mode ๐--pre-select-pat <PRE_SELECT_PAT>[default: ]โ pre-select the matched items in multi-selection mode. check the doc for the detailed syntax:https://docs.rs/regex/1.4.1/regex/๐ง--pre-select-items <PRE_SELECT_ITEMS>[default: ]โ pre-select the items separated by newline character. Example:'item1\nitem2'๐--pre-select-file <PRE_SELECT_FILE>โ pre-select the items read from this file ๐-f,--filter <FILTER>โ the query for filter mode ๐--shell <SHELL>โ generate a shell completion script. Generates the completion script for the specified shell: bash, zsh, fish, etc. The output can be directly sourced or saved to a file for automatic loading. Examples:source <(sk --shell bash)(immediate use),sk --shell bash >> ~/.bash_completion(persistent use). Supported shells:bash,zsh,fish,powershell,elvish. Possible values are:bashโ Bourne Again SHellelvishโ Elvish shellfishโ Friendly Interactive SHellnushellโ Nushell (nu)power-shellโ PowerShellzshโ Zsh
--shell-bindingsโ generate shell key bindings โ only for bash, zsh and fish. Generates the key bindings script after the shell completions. see the--shelloption for more details ๐ซ--manโ generate the man page and output it to stdout ๐ (yes, sk can print its own man page, main character energy fr)--listen [<LISTEN>...]โ run an IPC socket with an optional name (defaults tosk). The socket expects Actions in Ron format (similar to Rust code), see./src/tui/event.rsfor all possible Actions. To write to it, see the--remoteoption or the man page ๐ฐ๏ธ--remote [<REMOTE>...]โ send commands to an IPC socket with an optional name (defaults tosk). The commands are read from stdin, one per line, in the same format as the actions in thebindflag. They can also be chained using+as a separator. All other arguments will be ignored ๐ก--log-level <LOG_LEVEL>โ set the log level ๐๏ธ--log-file <LOG_FILE>โ pipe log output to a file ๐๏ธ
๐ DEPRECATED ๐ซ
--expect <EXPECT>[default: ]โ deprecated, kept for compatibility purposes. Seeaccept()bind instead โจ
lowkey do not use this one for new stuff, it's literally just vibing here so old configs don't break ๐
๐ MODES ๐
Normal mode
In normal mode, sk reads the input from stdin and displays the results interactively, and the query is then used to fuzzily filter among the input lines. classic. iconic. the standard ๐
Interactive mode
Interactive mode is a special mode that lets you run a command interactively and display the results. It's enabled by the --interactive (or -i) option, or by binding the toggle-interactive action (default: Ctrl+q). The command is specified with the --cmd option ๐ฆ
Example: sk --cmd 'rg {} --color=always' --interactive will use rg to search for the query in the current directory and display the results interactively โจ
๐ SEARCH ๐ธ
By default, skim will start in extended search, giving some characters meaning. Example: ^test rs$ | sh$ will match items starting with test and ending with rs or sh ๐
AND (space)
A space between terms acts as an 'and' operator and filters for items matching all the terms ๐ค
OR (|)
A vertical bar between terms acts as an 'or' operator and filters for items matching one of the terms ๐
Exact match (')
If a term is prefixed by a ', sk will search for exact occurrences of that term. Exact search can be enabled by default with the --exact command-line flag. In exact mode, ' will disable exact matching for that term ๐ฏ
Anchored match (^|$)
If a term is prefixed by a ^ (resp. suffixed by a $), sk will search for matches starting (resp. ending) with that exact term โ
Negation (!)
If a term is prefixed by !, sk will exclude the items that match this term ๐ซ
โจ KEYBINDS โจ
okay bestie, this is where skim becomes yours. You set bindings with the --bind option, which takes a comma-separated list of <trigger>:<action>[+action2] expressions. A trigger can be a key, a finder event, or an action name. Actions can take arguments, and you can write those either between parentheses like reload(ls) or after a colon like reload:ls. Both are valid, no cap. ๐
๐ Available keys (aliases in parentheses)
hereโs the whole key roster, literally every one:
ctrl-[a-z]ctrl-spacectrl-alt-[a-z]alt-[a-zA-Z]alt-[0-9]f[1-12]enterspacebspace(bs)alt-upalt-downalt-leftalt-rightalt-enteralt-spacealt-bspace(alt-bs)alt-/tabbtab(shift-tab)escdelupdownleftrighthomeendpguppgdnshift-upshift-downshift-leftshift-rightalt-shift-upalt-shift-downalt-shift-leftalt-shift-rightdouble-click- any single character
๐๏ธ Bindable finder events
these are the finder moments skim can react to, and yes they all slap:
change: the query changesstart: skim enters its event loop; fired onceload: the reader and matcher finish consuming the current input; fired once per read, including reloadsresult: filtering for the current query completesfocus: the focused item changes because of cursor movement or a result updatezero: the input stream is complete and the final search has no matchesone: the input stream is complete and the final search has exactly one match
๐ฌ Actions as binding triggers
Actions can also be used as binding triggers. A follow-up chain bound to an action name runs immediately after that action. Use the act- prefix for action triggers; it is recommended to avoid ambiguity and required when the action name is also a key, for example act-up:last.
Follow-up chains use non-recursive (noremap) semantics: their actions do not trigger further action bindings. Add suppress to skip the triggering action's default behavior, for example act-up:suppress+down. that little detail is lowkey important, so donโt skip it. ๐ซถ
๐ซ Actions
hereโs the action buffet โ every single one, no skips:
abortโ Abort and exit with erroraccept(...)โ Accept selection and exit with optional key. The argument is printed when the binding is triggered.add-char(...)โ Add a character to the queryappend-and-selectโ Append to selection and selectbackward-charโ Move cursor backward one characterbackward-delete-charโ Delete character before cursorbackward-delete-char/eofโ Delete character before cursor or exit if the query is emptybackward-kill-wordโ Delete word before cursorbackward-wordโ Move cursor backward one wordbeginning-of-lineโ Move cursor to beginning of linebind(...)โ Bind one or more keys to action chains. The argument is a comma-separated list oftrigger:action[+action]bindings to add, using the same syntax as--bind, including action triggers such asact-up:last.cancelโ Cancel current operationclear-screenโ Clear the screendelete-charโ Delete character under cursordelete-char/eofโ Delete character or exit if emptydeselect-allโ Deselect all itemsdown(...)โ Move selection down by N itemsend-of-lineโ Move cursor to end of lineexecute(...)โ Execute a command. The argument is a command, see COMMAND EXPANSION for details.execute-silent(...)โ Execute a command silently. The argument is a command, see COMMAND EXPANSION for details.firstโ Jump to first item in listforward-charโ Move cursor forward one characterforward-wordโ Move cursor forward one wordif-query-empty(...)โ Execute action if query is emptyif-query-not-empty(...)โ Execute action if query is not emptyif-non-matched(...)โ Execute action if no items matchignoreโ Ignore the actionkill-lineโ Delete from cursor to end of linekill-wordโ Delete word after cursorlastโ Jump to last item in listnext-historyโ Move to next history entry (requires--historyor--cmd-history)half-page-down(...)โ Scroll down by half a pagehalf-page-up(...)โ Scroll up by half a pagepage-down(...)โ Scroll down by a pagepage-up(...)โ Scroll up by a pagepreview-up(...)โ Scroll preview uppreview-down(...)โ Scroll preview downpreview-left(...)โ Scroll preview leftpreview-right(...)โ Scroll preview rightpreview-page-up(...)โ Scroll preview up by a pagepreview-page-down(...)โ Scroll preview down by a pageprevious-historyโ Move to previous history entry (requires--historyor--cmd-history)redrawโ Redraw the screenrefresh-cmdโ Refresh the commandrefresh-previewโ Refresh the previewrestart-matcherโ Restart the matcherreload(...)โ Reload with optional new commandrotate-modeโ Rotate through matching modesscroll-left(...)โ Scroll item list leftscroll-right(...)โ Scroll item list rightselect-allโ Select all itemsselect-row(...)โ Select a specific rowselectโ Select current itemsuppressโ Suppress the default behaviour of the action this is bound to. Only meaningful as a follow-up bound to an action (e.g.act-up:suppress): it cancels that action's own effect, so the remaining follow-up chain runs in its place. On its own it is a no-op (equivalent toignore).set-cmd(...)โ Set the interactive-mode command and rerun it. The argument is an expanded expression, see COMMAND EXPANSION for details.set-header(...)โ Set the header (or disable it on an empty value)set-preview-cmd(...)โ Set the preview cmd and rerun preview. The argument is an expanded expression, see COMMAND EXPANSION for details.set-query(...)โ Set the query to the expanded value. The argument is an expanded expression, see COMMAND EXPANSION for details.toggleโ Toggle selection of current itemtoggle-allโ Toggle selection of all itemstoggle-inโ Toggle and move intoggle-interactiveโ Toggle interactive modetoggle-outโ Toggle and move outtoggle-previewโ Toggle preview visibilitytoggle-preview-wrapโ Toggle preview line wrappingtoggle-sortโ Toggle sortingtopโ Jump to first item in list (alias for First)unbind(...)โ Unbind one or more keys. The argument is a comma-separated list of keys or action triggers (e.g.act-up) to unbind.unix-line-discardโ Discard line (unix-style)unix-word-ruboutโ Delete word backward (unix-style)up(...)โ Move selection up by N itemsyankโ Yank (paste)
๐ Default key bindings
out of the box, these are already wired up bestie:
alt-bโbackward-wordalt-bspaceโbackward-kill-wordalt-dโkill-wordalt-fโforward-wordalt-hโscroll-leftalt-lโscroll-rightbspaceโbackward-delete-charbtabโtoggle+upctrl-aโbeginning-of-linectrl-bโbackward-charctrl-cโabortctrl-dโabortctrl-eโend-of-linectrl-fโforward-charctrl-gโabortctrl-hโbackward-delete-charctrl-jโdownctrl-kโupctrl-lโclear-screenctrl-leftโbackward-wordctrl-nโdownctrl-pโupctrl-qโtoggle-interactivectrl-rโrotate-modectrl-rightโforward-wordctrl-uโunix-line-discardctrl-wโunix-word-ruboutctrl-yโyankdelโdelete-chardouble-clickโacceptdownโdownendโend-of-lineenterโacceptescโaborthomeโbeginning-of-lineleftโbackward-charpgdnโpage-downpgupโpage-uprightโforward-charshift-btabโtoggle+upshift-downโpreview-downshift-homeโbeginning-of-lineshift-leftโbackward-wordshift-rightโforward-wordshift-tabโtoggle+upshift-upโpreview-uptabโtoggle+downupโup
๐ COMMAND EXPANSION
In the preview flag, execute, reload, set-query... binds, sk will expand placeholders. this is the secret sauce, bestie:
{}(or--replstrif used) will be expanded to the current item.{q}(or{cq}for legacy reasons) will be expanded to the current query input.{+}will be expanded to either the currently selected items in multi-select mode, or the current item in single-select.{n}will be expanded to the index of the current item.{+n}will be expanded to the index(es) of the corresponding{+}item(s).{FIELD_INDEX_EXPRESSION}will be expanded to the field index expression run against the current item.{+FIELD_INDEX_EXPRESSION}will be expanded to the field index expression run against the{+}item(s).
๐งฎ Field index expression
skim will expand some expressions between {..}. It will expand to the corresponding fields, separated by the --delimiter|-d option (see there for details). yes, this is giving โtiny language inside your pickerโ:
{n}will be the n-th field.{n..m}will be the fields from n to m, inclusive, separated by a space{-n}will be the n-th, starting from the end, -1 will be the last field etc.
๐ฑ ENVIRONMENT VARIABLES
๐ SKIM_DEFAULT_COMMAND
If set, skim will collect items with this command if no input is piped in. If not set, defaults to find . on unix-like systems and dir /s /b /A:-D on Windows. noted, bestie โ those defaults are exact. โจ
๐ธ SKIM_DEFAULT_OPTIONS
Will be parsed and used as default options. Example: --reverse --multi
๐ SKIM_OPTIONS_FILE
If the variable is set to the path of an existing file, the contents of this file will be parsed and used as default options. It supports # as a comment start, which can be escaped using ##. Example:
# Preview
--preview 'echo {}'
--preview-window 'left:30%' # Preview window
--reverse
--prompt '## '
๐ฆ NO_COLOR
If set to a non-empty value, will disable coloring. no color, no problem ๐
๐จ THEME ๐จ
ok so you can ~theme~ this whole thing, and here's the whole menu, bestie:
noneโ the base color scheme, plain and simplemolokaiโ molokai 256colorlightโ light 256color16โ dark base16 themebwโ black & white theme, for the minimalists ๐dark|defaultโ dark 256color, and yes this is the default value- all 4 catppuccin variants โ the whole collection, we love a theme family:
catppuccin-lattecatppuccin-macchiatocatppuccin-frappecatppuccin-mocha
๐ the color names you can use
these are the little keywords that say what you're coloring:
normal(or an empty string) โ normal textmatched(orhl) โ matched text, the stuff you searched forcurrent(orfg+) โ current line foregroundbg+โ current line background (special case: it always sets background, no notes)current_match(orhl+) โ matched text in the current linequeryโ query textspinnerโ spinner characterinfoโ info text (the match count)promptโ prompt textcursor(orpointer) โ cursor/pointer, main character energyselected(ormarker) โ selected item markerheaderโ header textborderโ border linesseparatorโ the horizontal separator (independent of borders and headers, she does her own thing)scrollbarโ item list scrollbar thumb
๐๏ธ picking the part
adding -fg, _fg, -bg, _bg, -underline, _underline sets the corresponding part of the color. for instance, normal-fg (or simply fg) will set the foreground normal color. easy.
๐ฏ color formats
0-255โ ANSI terminal color#rrggbbโ 24-bit color, fancy
โจ attrs
x|regularโ resets the modifiers, use it before the others (order matters bestie, do it first)b|boldu|underlinec|crossed-outd|dimi|italicr|reverse
๐ the example, look at her go
--color '16,normal-fg:0+bold,matched-fg:#ffffff+u,cursor-bg:#deadbe'
this will start with the base 16 theme and override it with a bold ANSI color 0 foreground (black), a hex ffffff (full white) underlined foreground for matched parts and a #deadbe (pale rose, apparently ๐) cursor background. iconic behavior, no notes.
๐ก LISTEN/REMOTE ๐ก
skim can be controlled from other processes, using the --listen (and optionally --remote) flags. yes she's remote-controllable, she's that girl.
to achieve this, run the server instance using sk --listen optional_address (the address defaults to sk). it will then start listening on a named socket for instructions.
to send instructions, you can use sk --remote optional_address or any other tool that allows us to interact with such sockets, such as socat on linux:
echo 'ToggleIn' | socat -u STDIN ABSTRACT-CONNECT:optional_address
instructions correspond to skim's Actions and need to be sent in Ron format. when using sk --remote, pipe in action chains (see the KEYBINDS section), for instance:
echo 'up+select-row' | sk --remote optional_address
๐ช EXIT CODES ๐ช
0โ success slay ๐1โ no match130โ interrupt (ctrl-c or esc)- others โ error ๐ญ
๐ท๏ธ VERSION ๐ท๏ธ
v5.9.0
and that's the whole page babes ๐ซถ โ this was sk 5.9.0, page sk(1), delivered fresh from that exact source and version. go forth and fuzzy-find something gorgeous โจ๐
๐ฆ where this page comes from
- arch rolling: skim 5.9.0-1 ยท MIT
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms