vis: add script fzf.sh and use it with just two keys
fzf.sh is a wrapper around fzf with mode for fd, rg, git and jj which allow to switch between them with keys
This commit is contained in:
215
vis/.config/vis/fzf.sh
Executable file
215
vis/.config/vis/fzf.sh
Executable file
@@ -0,0 +1,215 @@
|
||||
#!/bin/sh
|
||||
|
||||
prompt=${FZF_PROMPT%> }
|
||||
cmd=${prompt%+*}
|
||||
hidden=${prompt#$cmd}
|
||||
|
||||
ripgrep='rg --column --line-number --color=always --smart-case'
|
||||
|
||||
if [ "$1" = list ]; then
|
||||
case "$FZF_HEADER_LABEL" in
|
||||
:?*)
|
||||
path=${FZF_HEADER_LABEL#?}
|
||||
;;
|
||||
*)
|
||||
path=
|
||||
;;
|
||||
esac
|
||||
case "$prompt" in
|
||||
files)
|
||||
exec fd --type f '' $path
|
||||
;;
|
||||
files+hidden)
|
||||
exec fd --type f -H '' $path
|
||||
;;
|
||||
search)
|
||||
exec $ripgrep "$FZF_QUERY" $path
|
||||
;;
|
||||
search+hidden)
|
||||
exec $ripgrep -. "$FZF_QUERY" $path
|
||||
;;
|
||||
git-files*)
|
||||
exec git ls-files $path
|
||||
;;
|
||||
git-search*)
|
||||
exec git grep --column --line-number --color=always "$FZF_QUERY" $path
|
||||
;;
|
||||
jj-files*)
|
||||
exec jj file list --ignore-working-copy $path
|
||||
;;
|
||||
jj-search*)
|
||||
exec $ripgrep "$FZF_QUERY" $(jj file list --ignore-working-copy $path)
|
||||
;;
|
||||
esac
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$1" = preview ]; then
|
||||
if [ -n "$3" ]; then
|
||||
start=$(( $3 - $FZF_PREVIEW_LINES / 2 ))
|
||||
if [ $start -lt 1 ]; then
|
||||
start=1
|
||||
fi
|
||||
end=$(( $start + $FZF_PREVIEW_LINES ))
|
||||
exec bat --style=numbers --color=always --highlight-line $3 --line-range $start:$end $2
|
||||
else
|
||||
exec bat --style=numbers --color=always $2
|
||||
fi
|
||||
fi
|
||||
|
||||
reload="reload(sh $0 list || true)"
|
||||
no_search="rebind(change)+disable-search"
|
||||
search="unbind(change)+enable-search"
|
||||
|
||||
if [ "$1" = key ]; then
|
||||
case "$FZF_KEY" in
|
||||
alt-d)
|
||||
path=${FZF_HEADER_LABEL#?}
|
||||
case "$FZF_HEADER_LABEL" in
|
||||
.?*)
|
||||
echo "change-header(path: $path)+change-header-label(:$path)+$reload"
|
||||
;;
|
||||
*)
|
||||
echo "change-header()+change-header-label(.$path)+$reload"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
alt-f)
|
||||
case "$cmd" in
|
||||
*files)
|
||||
prompt="files$hidden"
|
||||
;;
|
||||
*search)
|
||||
prompt="${cmd%-*}-files$hidden"
|
||||
;;
|
||||
esac
|
||||
echo "change-prompt($prompt> )+$search+$reload"
|
||||
;;
|
||||
alt-g)
|
||||
case "$cmd" in
|
||||
*files)
|
||||
prompt="git-files$hidden"
|
||||
echo "change-prompt($prompt> )+$search+$reload"
|
||||
;;
|
||||
*search)
|
||||
prompt="git-search$hidden"
|
||||
echo "change-prompt($prompt> )+$no_search+$reload"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
alt-h)
|
||||
if [ -z "$hidden" ]; then
|
||||
prompt="$cmd+hidden"
|
||||
else
|
||||
prompt="$cmd"
|
||||
fi
|
||||
echo "change-prompt($prompt> )+$reload"
|
||||
;;
|
||||
alt-j)
|
||||
case "$cmd" in
|
||||
*files)
|
||||
prompt="jj-files$hidden"
|
||||
echo "change-prompt($prompt> )+$search+$reload"
|
||||
;;
|
||||
*search)
|
||||
prompt="jj-search$hidden"
|
||||
echo "change-prompt($prompt> )+$no_search+$reload"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
alt-s)
|
||||
case "$cmd" in
|
||||
*files)
|
||||
prompt="${cmd%-*}-search$hidden"
|
||||
;;
|
||||
*search)
|
||||
prompt="search$hidden"
|
||||
;;
|
||||
esac
|
||||
echo "change-prompt($prompt> )+$no_search+$reload"
|
||||
;;
|
||||
esac
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
label=".$2"
|
||||
else
|
||||
label=".."
|
||||
fi
|
||||
|
||||
case ${1%+hidden} in
|
||||
auto-files)
|
||||
git=$(git rev-parse --show-toplevel 2> /dev/null)
|
||||
jj=$(jj root --ignore-working-copy 2> /dev/null)
|
||||
if [ -n "$jj" ] && [ "${git#$jj}" = "$git" -o "$git" = "$jj" ]; then
|
||||
cmd="jj-files$hidden"
|
||||
elif [ -n "$git" ] && [ "${jj#$git}" = "$jj" ]; then
|
||||
cmd="git-files$hidden"
|
||||
else
|
||||
cmd="files"
|
||||
fi
|
||||
action="$search"
|
||||
prompt="$cmd> "
|
||||
;;
|
||||
auto-search)
|
||||
git=$(git rev-parse --show-toplevel 2> /dev/null)
|
||||
jj=$(jj root --ignore-working-copy 2> /dev/null)
|
||||
if [ -n "$jj" ] && [ "${git#$jj}" = "$git" -o "$git" = "$jj" ]; then
|
||||
cmd="jj-search$hidden"
|
||||
elif [ -n "$git" ] && [ "${jj#$git}" = "$jj" ]; then
|
||||
cmd="git-search$hidden"
|
||||
else
|
||||
cmd="search"
|
||||
fi
|
||||
action="$no_search"
|
||||
prompt="$cmd> "
|
||||
;;
|
||||
files|git-files|jj-files)
|
||||
cmd="$1"
|
||||
action="$search"
|
||||
prompt="$1> "
|
||||
;;
|
||||
search|git-search|jj-search)
|
||||
cmd="$1"
|
||||
action="$no_search"
|
||||
prompt="$1> "
|
||||
;;
|
||||
*)
|
||||
cmd="files"
|
||||
action="$search"
|
||||
prompt="files> "
|
||||
;;
|
||||
esac
|
||||
key="transform(sh $0 key)"
|
||||
|
||||
HELP='Keys:
|
||||
|
||||
alt-? help
|
||||
alt-d toggle alternative directory
|
||||
alt-f switch to files (twice for plain files)
|
||||
alt-g switch to git
|
||||
alt-j switch to jj
|
||||
alt-h toggle hidden
|
||||
alt-p toggle preview (also to turn off help)
|
||||
alt-s switch to search (twice for plain search)
|
||||
alt-u toggle preview window position (right or up)
|
||||
'
|
||||
|
||||
exec fzf --query "$3" \
|
||||
--prompt "$prompt" \
|
||||
--header-label "$label" \
|
||||
--ansi \
|
||||
--delimiter : \
|
||||
--ghost ' (Use alt-? for help)' \
|
||||
--bind "change:$reload" \
|
||||
--bind "start:$reload+$action" \
|
||||
--bind "alt-d:$key" \
|
||||
--bind "alt-f:$key" \
|
||||
--bind "alt-g:$key" \
|
||||
--bind "alt-j:$key" \
|
||||
--bind "alt-h:$key" \
|
||||
--bind "alt-s:$key" \
|
||||
--bind "alt-p:change-preview(sh $0 preview {1} {2})+toggle-preview" \
|
||||
--bind "alt-u:change-preview-window(up|right)" \
|
||||
--bind "alt-?:change-preview(echo '$HELP')+show-preview"
|
||||
@@ -66,6 +66,32 @@ local function escape_and_quoted(s)
|
||||
return "'" .. s:gsub("'", "\\'") .. "'"
|
||||
end
|
||||
|
||||
local function cmd_action(cmd, action)
|
||||
local code, out, err = vis:pipe(cmd, true)
|
||||
if code == 0 then
|
||||
action(out)
|
||||
elseif err ~= nil then
|
||||
vis:info(err)
|
||||
elseif code ~= 0 then
|
||||
vis:info('Program exit code ' .. code)
|
||||
end
|
||||
end
|
||||
|
||||
local function fzf_sh(arg)
|
||||
action = function(out)
|
||||
open_file_pos(out, vis.win.file.modified and 'o' or 'e')
|
||||
end
|
||||
local home = os.getenv('HOME')
|
||||
local path = vis.win.file.path or ''
|
||||
local dir = path:match('^.*/') or ''
|
||||
local reg = ''
|
||||
if reg ~= '"' then
|
||||
reg = string.gsub(vis.registers[vis.register][1], '%z', '')
|
||||
end
|
||||
local cmd = home .. '/.config/vis/fzf.sh ' .. escape_and_quoted(arg) .. ' ' .. escape_and_quoted(dir) .. ' ' .. escape_and_quoted(reg)
|
||||
cmd_action(cmd, action)
|
||||
end
|
||||
|
||||
local function search(cmd, action)
|
||||
if action == nil then
|
||||
action = function(out)
|
||||
@@ -78,14 +104,7 @@ local function search(cmd, action)
|
||||
cmd = cmd .. ' --query=' .. escape_and_quoted(reg)
|
||||
end
|
||||
end
|
||||
local code, out, err = vis:pipe(cmd, true)
|
||||
if code == 0 then
|
||||
action(out)
|
||||
elseif err ~= nil then
|
||||
vis:info(err)
|
||||
elseif code ~= 0 then
|
||||
vis:info('Program exit code ' .. code)
|
||||
end
|
||||
cmd_action(cmd, action)
|
||||
end
|
||||
|
||||
local file_slots = {}
|
||||
@@ -178,56 +197,26 @@ vis.events.subscribe(vis.events.INIT, function()
|
||||
vis:map(vis.modes.NORMAL, ' l=', ':lspc-format<Enter>')
|
||||
|
||||
for num = 1, 9 do
|
||||
vis:map(vis.modes.NORMAL, ' s' .. num, function() set_file_slot(num) end, 'set file slot ' .. num)
|
||||
vis:map(vis.modes.NORMAL, ' r' .. num, function() set_file_slot(num) end, 'set file slot ' .. num)
|
||||
vis:map(vis.modes.NORMAL, ' ' .. num, function() open_file_slot(num, 'e') end, 'open file slot ' .. num)
|
||||
vis:map(vis.modes.NORMAL, ' h' .. num, function() open_file_slot(num, 'o') end, 'open file slot ' .. num)
|
||||
vis:map(vis.modes.NORMAL, ' v' .. num, function() open_file_slot(num, 'vsplit') end,
|
||||
'open file slot ' .. num)
|
||||
end
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' fg', function()
|
||||
search(fzf_reload(ripgrep))
|
||||
end, 'fzf: rg')
|
||||
vis:map(vis.modes.NORMAL, ' s', function()
|
||||
fzf_sh('auto-search')
|
||||
end, 'fzf: search')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' hg', function()
|
||||
search(fzf_reload(ripgrep .. ' -.'))
|
||||
end, 'fzf: rg with hidden files')
|
||||
vis:map(vis.modes.NORMAL, ' f', function()
|
||||
fzf_sh('auto-files')
|
||||
end, 'fzf: files')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' /', function()
|
||||
search(fzf_reload(ripgrep .. ' --with-filename {q} ' .. escape_and_quoted(vis.win.file.path)))
|
||||
end, 'fzf: rg current file')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' ff', function()
|
||||
search('fd --type f | fzf')
|
||||
end, 'fzf: files')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' fh', function()
|
||||
search('fd -H --type f | fzf')
|
||||
end, 'fzf: files with hidden files')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' df', function()
|
||||
local path = vis.win.file.path
|
||||
if path then
|
||||
local dir = path:match('^.*/')
|
||||
local arg = escape_and_quoted(dir)
|
||||
search('fd --type f "" ' .. arg .. ' | fzf')
|
||||
else
|
||||
search('fd --type f | fzf')
|
||||
end
|
||||
end, 'fzf in file directory')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' dh', function()
|
||||
local path = vis.win.file.path
|
||||
if path then
|
||||
local dir = path:match('^.*/')
|
||||
local arg = escape_and_quoted(dir)
|
||||
search('fd -H --type f "" ' .. arg .. ' | fzf')
|
||||
else
|
||||
search('fd -H --type f | fzf')
|
||||
end
|
||||
end, 'fzf in file directory with hidden files')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' sh', function()
|
||||
vis:map(vis.modes.NORMAL, ' .', function()
|
||||
local shell = os.getenv('SHELL')
|
||||
vis:command('!' .. shell)
|
||||
end, 'run shell')
|
||||
@@ -244,29 +233,13 @@ vis.events.subscribe(vis.events.INIT, function()
|
||||
end
|
||||
end, 'run shell in file directory')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' gf', function()
|
||||
search('git ls-files | fzf')
|
||||
end, 'fzf: git files')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' gg', function()
|
||||
search(fzf_reload('git grep --column --line-number --color=always'))
|
||||
end, 'fzf: jj grep')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' gl', function()
|
||||
vis:command('!lazygit')
|
||||
end, 'lazygit')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' jf', function()
|
||||
search('jj file list | fzf')
|
||||
end, 'fzf: jj files')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' jg', function()
|
||||
search(fzf_reload(ripgrep .. ' {q} $(jj file list | xargs)'))
|
||||
end, 'fzf: jj grep')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' jl', function()
|
||||
vis:command('!lazyjj')
|
||||
end, 'fzf open')
|
||||
end, 'lazyjj')
|
||||
|
||||
vis:map(vis.modes.NORMAL, ' ', function()
|
||||
vis:command('fzfmru')
|
||||
|
||||
Reference in New Issue
Block a user