v(1) - a modern rewrite of v
v(1) lists vim's recently edited files for quick selection, regardless of where you are in the filesystem.
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##*/}" "$@" |