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("'", "\\'") .. "'"
|
return "'" .. s:gsub("'", "\\'") .. "'"
|
||||||
end
|
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)
|
local function search(cmd, action)
|
||||||
if action == nil then
|
if action == nil then
|
||||||
action = function(out)
|
action = function(out)
|
||||||
@@ -78,14 +104,7 @@ local function search(cmd, action)
|
|||||||
cmd = cmd .. ' --query=' .. escape_and_quoted(reg)
|
cmd = cmd .. ' --query=' .. escape_and_quoted(reg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local code, out, err = vis:pipe(cmd, true)
|
cmd_action(cmd, action)
|
||||||
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
|
end
|
||||||
|
|
||||||
local file_slots = {}
|
local file_slots = {}
|
||||||
@@ -178,56 +197,26 @@ vis.events.subscribe(vis.events.INIT, function()
|
|||||||
vis:map(vis.modes.NORMAL, ' l=', ':lspc-format<Enter>')
|
vis:map(vis.modes.NORMAL, ' l=', ':lspc-format<Enter>')
|
||||||
|
|
||||||
for num = 1, 9 do
|
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, ' ' .. 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, ' 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,
|
vis:map(vis.modes.NORMAL, ' v' .. num, function() open_file_slot(num, 'vsplit') end,
|
||||||
'open file slot ' .. num)
|
'open file slot ' .. num)
|
||||||
end
|
end
|
||||||
|
|
||||||
vis:map(vis.modes.NORMAL, ' fg', function()
|
vis:map(vis.modes.NORMAL, ' s', function()
|
||||||
search(fzf_reload(ripgrep))
|
fzf_sh('auto-search')
|
||||||
end, 'fzf: rg')
|
end, 'fzf: search')
|
||||||
|
|
||||||
vis:map(vis.modes.NORMAL, ' hg', function()
|
vis:map(vis.modes.NORMAL, ' f', function()
|
||||||
search(fzf_reload(ripgrep .. ' -.'))
|
fzf_sh('auto-files')
|
||||||
end, 'fzf: rg with hidden files')
|
end, 'fzf: files')
|
||||||
|
|
||||||
vis:map(vis.modes.NORMAL, ' /', function()
|
vis:map(vis.modes.NORMAL, ' /', function()
|
||||||
search(fzf_reload(ripgrep .. ' --with-filename {q} ' .. escape_and_quoted(vis.win.file.path)))
|
search(fzf_reload(ripgrep .. ' --with-filename {q} ' .. escape_and_quoted(vis.win.file.path)))
|
||||||
end, 'fzf: rg current file')
|
end, 'fzf: rg current file')
|
||||||
|
|
||||||
vis:map(vis.modes.NORMAL, ' ff', function()
|
vis:map(vis.modes.NORMAL, ' .', 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()
|
|
||||||
local shell = os.getenv('SHELL')
|
local shell = os.getenv('SHELL')
|
||||||
vis:command('!' .. shell)
|
vis:command('!' .. shell)
|
||||||
end, 'run shell')
|
end, 'run shell')
|
||||||
@@ -244,29 +233,13 @@ vis.events.subscribe(vis.events.INIT, function()
|
|||||||
end
|
end
|
||||||
end, 'run shell in file directory')
|
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:map(vis.modes.NORMAL, ' gl', function()
|
||||||
vis:command('!lazygit')
|
vis:command('!lazygit')
|
||||||
end, '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:map(vis.modes.NORMAL, ' jl', function()
|
||||||
vis:command('!lazyjj')
|
vis:command('!lazyjj')
|
||||||
end, 'fzf open')
|
end, 'lazyjj')
|
||||||
|
|
||||||
vis:map(vis.modes.NORMAL, ' ', function()
|
vis:map(vis.modes.NORMAL, ' ', function()
|
||||||
vis:command('fzfmru')
|
vis:command('fzfmru')
|
||||||
|
|||||||
Reference in New Issue
Block a user