which + vim = wvim

Over the years I’ve collected an array of one-off scripts, shell aliases, git subcommands, etc., and I often find myself wanting to reference or edit of one of them. Sometimes I know where to look, but not always, and when in doubt I rely on the which command to point me in the right direction.

wvim is a script that I’ve built to streamline these sort of edits. It started as a simple wrapper around whichfunction wvim() { vim "$(which $1)" } — but over time I’ve added support for shell functions & aliases, as well as git aliases and scripts. The thing that tipped this into the “oh wow, that’s pretty cool” space for me was the addition of tab completion by leveraging the existing tab completion for which via compdef wvim=which.

Using it looks something like this:

Show Me The Code!

You can check out my current version of this script in my dotfiles repo, but for completeness, I’ve included the contents of the file below. You can use it by including the code in your ~/.zshrc file (or by splitting it out into its own file for organization purposes if you share my penchant for clean config files).

Note - the compdef completion line is zsh-specific, but I believe the rest should be reasonably portable to bash or other similar shells.

# top-level command. Determines the type of the requested command and then
# attempts to open it in vim
wvim() {
  command_name="$1"
  case "$(_definition_type "$command_name")" in
    "alias") _edit_shell_alias "$command_name";;
    "function") _edit_shell_function "$command_name";;
    "script") _edit_script "$command_name";;
    "git-alias") _edit_git_alias "$command_name";;
    "not found") _handle_unknown_command "$command_name"
  esac
}

# This line configures zsh tab completion for `wvim` by reusing the tab completion
# for `which`
compdef wvim=which

# Use the `type` command to determine the type of the provided command
_definition_type() {
  arg_type_string=$(type -a "$1")
  if [[ "$arg_type_string" == *"is an alias"* ]]; then
    echo "alias"
  elif [[ "$arg_type_string" == *"is a shell function"* ]]; then
    echo "function"
  elif which "$1" > /dev/null 2>&1; then
    echo "script"
  elif _is_git_alias "$1"; then
    echo "git-alias"
  else
    echo "not found"
  fi
}

# Special handling for git aliases since `type` doesn't know about them
_is_git_alias() {
  echo "$1" | grep -q 'git-.*' && _git_aliases | grep -qF $(_git_alias_name "$1")
}

_handle_unknown_command() {
  echo "\"$1\" is not recognized as a script, function, or alias" >&2
  return 1
}

_git_alias_name() {
  echo "$1" | sed 's/^git-//'
}

_git_aliases() {
  git config --get-regexp ^alias\. |\
    sed -e s/^alias\.// -e s/\ /\ =\ / |\
    awk '{print $1}'
}

_edit_git_alias() {
  line=$(grep -En "^\s+$(_git_alias_name "$1") =" ~/.gitconfig | cut -d ":" -f 1)
  vim ~/.gitconfig "+$line"
}

_edit_script() {
  vim "$(which "$1")"
}

_definition_field_for_pattern() {
  definition=$(grep -En "$2" ~/.zshrc ~/.zshenv ~/.zsh/**/*.zsh 2>/dev/null)
  echo "$definition" | cut -d ":" -f "$1"
}

_edit_based_on_pattern() {
  file=$(_definition_field_for_pattern 1 "$1")
  line=$(_definition_field_for_pattern 2 "$1")
  vim "$file" "+$line"
}

_edit_shell_function() {
  _edit_based_on_pattern "(^function $1)|(^$1\(\))"
}

_edit_shell_alias() {
  _edit_based_on_pattern "alias $1="
}

Caveats and Limitations

Given that wvim is built out of various regex checks and heuristic searching logic, I’ve been impressed by how well wvim has worked for me.

That said, there are a few assumptions baked into this script, most notably that I have it configured to look in both ~/.zshenv and ~/.zshrc. If you don’t have both those files, you’ll want to update that to only reference the file you have.

Solid code, the right features, and a strong team

I would love to help you build your platform, empower your team, and tackle everything in between. Let's talk!