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##*/}" "$@" |