mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-03 01:50:12 +00:00
feat(shell): improve fish completion system (#494)
this pr adds the possibility of starting television from a different directory and it gives the option of complete a partial match. For example ```fish cd ~/.config/<ctrl-t> # opens television at '~/.config/' with an empty search bar cd ~/.config/fi<ctrl-t> # opens television at '~/.config/' with 'fi' in the search bar ``` solves (for fish shell) https://github.com/alexpasmantier/television/issues/438
This commit is contained in:
parent
cc27b5ec6b
commit
be8008e97d
@ -1,15 +1,118 @@
|
||||
function tv_smart_autocomplete
|
||||
# prefix (lhs of cursor)
|
||||
set -l current_prompt (commandline -cp)
|
||||
function __tv_parse_commandline --description 'Parse the current command line token and return split of existing filepath, and tv query'
|
||||
# credits to the junegunn/fzf project
|
||||
# https://github.com/junegunn/fzf/blob/9c1a47acf7453f9dad5905b7f23ad06e5195d51f/shell/key-bindings.fish#L53-L131
|
||||
|
||||
set -l output (tv --autocomplete-prompt "$current_prompt")
|
||||
set -l tv_query ''
|
||||
set -l prefix ''
|
||||
set -l dir '.'
|
||||
|
||||
if test -n "$output"
|
||||
# add a space if the prompt does not end with one (unless the prompt is an implicit cd, e.g. '\.')
|
||||
string match -q -r '.*( |./)$' -- "$current_prompt" || set output " $output"
|
||||
commandline -i "$output"
|
||||
commandline -f repaint
|
||||
# Set variables containing the major and minor fish version numbers, using
|
||||
# a method compatible with all supported fish versions.
|
||||
set -l -- fish_major (string match -r -- '^\d+' $version)
|
||||
set -l -- fish_minor (string match -r -- '^\d+\.(\d+)' $version)[2]
|
||||
|
||||
# fish v3.3.0 and newer: Don't use option prefix if " -- " is preceded.
|
||||
set -l -- match_regex '(?<tv_query>[\s\S]*?(?=\n?$)$)'
|
||||
set -l -- prefix_regex '^-[^\s=]+=|^-(?!-)\S'
|
||||
if test "$fish_major" -eq 3 -a "$fish_minor" -lt 3
|
||||
or string match -q -v -- '* -- *' (string sub -l (commandline -Cp) -- (commandline -p))
|
||||
set -- match_regex "(?<prefix>$prefix_regex)?$match_regex"
|
||||
end
|
||||
|
||||
# Set $prefix and expanded $tv_query with preserved trailing newlines.
|
||||
if test "$fish_major" -ge 4
|
||||
# fish v4.0.0 and newer
|
||||
string match -q -r -- $match_regex (commandline --current-token --tokens-expanded | string collect -N)
|
||||
else if test "$fish_major" -eq 3 -a "$fish_minor" -ge 2
|
||||
# fish v3.2.0 - v3.7.1 (last v3)
|
||||
string match -q -r -- $match_regex (commandline --current-token --tokenize | string collect -N)
|
||||
eval set -- tv_query (string escape -n -- $tv_query | string replace -r -a '^\\\(?=~)|\\\(?=\$\w)' '')
|
||||
else
|
||||
# fish older than v3.2.0 (v3.1b1 - v3.1.2)
|
||||
set -l -- cl_token (commandline --current-token --tokenize | string collect -N)
|
||||
set -- prefix (string match -r -- $prefix_regex $cl_token)
|
||||
set -- tv_query (string replace -- "$prefix" '' $cl_token | string collect -N)
|
||||
eval set -- tv_query (string escape -n -- $tv_query | string replace -r -a '^\\\(?=~)|\\\(?=\$\w)|\\\n\\\n$' '')
|
||||
end
|
||||
|
||||
if test -n "$tv_query"
|
||||
# Normalize path in $tv_query, set $dir to the longest existing directory.
|
||||
if test \( "$fish_major" -ge 4 \) -o \( "$fish_major" -eq 3 -a "$fish_minor" -ge 5 \)
|
||||
# fish v3.5.0 and newer
|
||||
set -- tv_query (path normalize -- $tv_query)
|
||||
set -- dir $tv_query
|
||||
while not path is -d $dir
|
||||
set -- dir (path dirname $dir)
|
||||
end
|
||||
else
|
||||
# fish older than v3.5.0 (v3.1b1 - v3.4.1)
|
||||
if test "$fish_major" -eq 3 -a "$fish_minor" -ge 2
|
||||
# fish v3.2.0 - v3.4.1
|
||||
string match -q -r -- '(?<tv_query>^[\s\S]*?(?=\n?$)$)' \
|
||||
(string replace -r -a -- '(?<=/)/|(?<!^)/+(?!\n)$' '' $tv_query | string collect -N)
|
||||
else
|
||||
# fish v3.1b1 - v3.1.2
|
||||
set -- tv_query (string replace -r -a -- '(?<=/)/|(?<!^)/+(?!\n)$' '' $tv_query | string collect -N)
|
||||
eval set -- tv_query (string escape -n -- $tv_query | string replace -r '\\\n$' '')
|
||||
end
|
||||
set -- dir $tv_query
|
||||
while not test -d "$dir"
|
||||
set -- dir (dirname -z -- "$dir" | string split0)
|
||||
end
|
||||
end
|
||||
|
||||
if not string match -q -- '.' $dir; or string match -q -r -- '^\./|^\.$' $tv_query
|
||||
# Strip $dir from $tv_query - preserve trailing newlines.
|
||||
if test "$fish_major" -ge 4
|
||||
# fish v4.0.0 and newer
|
||||
string match -q -r -- '^'(string escape --style=regex -- $dir)'/?(?<tv_query>[\s\S]*)' $tv_query
|
||||
else if test "$fish_major" -eq 3 -a "$fish_minor" -ge 2
|
||||
# fish v3.2.0 - v3.7.1 (last v3)
|
||||
string match -q -r -- '^/?(?<tv_query>[\s\S]*?(?=\n?$)$)' \
|
||||
(string replace -- "$dir" '' $tv_query | string collect -N)
|
||||
else
|
||||
# fish older than v3.2.0 (v3.1b1 - v3.1.2)
|
||||
set -- tv_query (string replace -- "$dir" '' $tv_query | string collect -N)
|
||||
eval set -- tv_query (string escape -n -- $tv_query | string replace -r -a '^/?|\\\n$' '')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure $dir ends with a slash if it's a directory
|
||||
if test -d "$dir"; and not string match -q '*/$' -- $dir
|
||||
set dir "$dir/"
|
||||
end
|
||||
|
||||
string escape -n -- "$dir" "$tv_query" "$prefix"
|
||||
|
||||
end
|
||||
|
||||
function tv_smart_autocomplete
|
||||
set -l commandline (__tv_parse_commandline)
|
||||
set -lx dir $commandline[1]
|
||||
set -l tv_query $commandline[2]
|
||||
|
||||
# prefix (lhs of cursor)
|
||||
set -l current_prompt (commandline --current-process)
|
||||
|
||||
if set -l result (tv $dir --autocomplete-prompt "$current_prompt" --input $tv_query)
|
||||
# Remove last token from commandline.
|
||||
commandline -t ''
|
||||
|
||||
# If dir is the current directory, i.e. './' , clear it.
|
||||
# If the pattern './foo' './bar' instead of 'foo' 'bar' is desired then comment out the check below
|
||||
if test "$dir" = "./"
|
||||
set dir ""
|
||||
end
|
||||
|
||||
for i in $result
|
||||
commandline -it -- $dir(string escape -- $i)' '
|
||||
# optional, if you want to replace '/home/foo/' with '~/', comment out above and uncomment below
|
||||
# commandline -it -- (string replace --all $HOME '~' $dir(string escape -- $i))' '
|
||||
end
|
||||
end
|
||||
|
||||
commandline -f repaint
|
||||
end
|
||||
|
||||
function tv_shell_history
|
||||
|
Loading…
x
Reference in New Issue
Block a user