Skip to content

Instantly share code, notes, and snippets.

@shalomb
Last active April 19, 2021 21:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shalomb/8a3e266f81a675c1f80cfd6cebdab9aa to your computer and use it in GitHub Desktop.
Save shalomb/8a3e266f81a675c1f80cfd6cebdab9aa to your computer and use it in GitHub Desktop.
v - A modern rewrite of https://github.com/rupa/v using fzf/bat

v(1) - a modern rewrite of v

Description

v(1) lists vim's recently edited files for quick selection, regardless of where you are in the filesystem.

Dependencies

Installation

make install

Provides

  • v(1)
  • vi(1) - wrapper around v/vi/vim
install:
chmod +x ./v
install -m550 $$PWD/v ~/.local/bin/
install -m550 $$PWD/v ~/.local/bin/
#!/bin/bash
#! vi - launch last related-in-flow files in vi
function vi {
if [[ -n $@ ]]; then
command vi "$@"
else
if [[ -n ${_git_args[@]} ]]; then
command vi "${_git_args[@]}"
else
v
fi
fi
}
#! locate-viminfo - return the path of viminfo that we cached
function locate-viminfo {
local tmpfile=$(mktemp)
local v_viminfo="${XDG_CACHE_HOME:-~/.cache}/v.viminfo"
# our file is a symlink to the real viminfo
if [[ -e $v_viminfo ]]; then
echo "$v_viminfo"
return 0
fi
# ask vim to tell us where the viminfo is
for line in "redir! > $tmpfile" "set viminfo" "redir END" "quit"; do
echo ":$line"
done > "$tmpfile"
command "${EDITOR:-vi}" \
-v -R -m -M -n --noplugin -i NONE \
-s "$tmpfile" /dev/null &>/dev/null
# parse the viminfo part
local viminfo=$(grep -oiP '(?<=,n).+' "$tmpfile")
viminfo="${viminfo/~\//$HOME/}"
rm -f "$tmpfile"
if [[ ! -f $viminfo ]]; then
echo >&2 "viminfo '$viminfo' missing or inaccessible?"
return 1
fi
# cache the viminfo location
ln -sf "$viminfo" "$v_viminfo"
echo "$v_viminfo"
return 0
}
#! v - select one of the recently edited files in vim
# A modern rewrite of https://github.com/rupa/v
function v {
local viminfo=$(locate-viminfo)
local files=()
local v_hist_file=~/.cache/v.history
local file
local in_cwd=0
local deleted=0
local usage="$(basename ${FUNCNAME[0]}) [-a|-c] [terms]"
while getopts achv opt; do
case "$opt" in
a) deleted=1;;
c) in_cwd=1;;
h) echo >&2 "$usage"; return 0;;
esac
done
shift "$((OPTIND-1))" # Discard the options and sentinel --
# parse the viminfo for file locations
while IFS=" " read -r line; do
[[ ${line:0:1} = ">" ]] || continue
file=${line:2}
file="${file/~\//$HOME/}"
if (( in_cwd == 1 )) && [[ $file != ${PWD}* ]]; then
continue
fi
[[ $file = *@(COMMIT_EDITMSG|/dev/null)* ]] && continue
if (( deleted == 1 )) || [[ -e $file ]]; then
files+=( "$file" )
fi
done < "$viminfo"
# display the fzf/bat selection/preview
[[ ! -e $v_hist_file ]] && touch "$v_hist_file"
file=$(
printf '%s\n' "${files[@]}" |
fzf --ansi --cycle --border=rounded --prompt='$ ' \
--inline-info --header='Select file to edit, ctrl-e to select normally' --color=dark \
--history=$v_hist_file --preview='bat -f {}'
)
if [[ -e $file ]]; then
echo "$file" >> "$v_hist_file"
command "${EDITOR:-vi}" "$file"
fi
}
# delegate execution to our functions
"${0##*/}" "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment