Repository management with ghq
I recently encountered ghq, a tool for automatically organising VCS-backed
projects automatically. Give it a repository URL, it will clone a project to
your projects dir (set by $GHQ_ROOT
) like so:
$ ghq get https://github.com/motemen/ghq
# Runs `git clone https://github.com/motemen/ghq ~/.ghq/github.com/motemen/ghq`
I don’t like the idea of having projects hidden away, so I set
$GHQ_ROOT
to $HOME/projects
.
From there, the list
and look
subcommands allow listing
repositories and visiting them in the shell (actually a subshell).
I wanted a nicer way to visit project directories. Since I’m
using fzf as a fuzzy-finder, I thought it would be nice to use it
for this. I created a simple function, fp
(find project) to do that:
fp () {
ghq look $(ghq list | fzf +m)
}
I ran into some issues with the subshell of ghq look
and wondered
whether it might be possible to create a zsh command to remove the
need for a subshell.
I found that fzf
includes a cd-widget function and created
something similar that uses ghq
instead of find
:
cd-project-widget () {
local cmd="ghq list"
setopt localoptions pipefail 2> /dev/null
local dir="$(eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS" fzf +m)"
if [[ -z "$dir" ]]; then
zle redisplay
return 0
fi
cd $(ghq list --full-path | grep "$dir")
local ret=$?
zle reset-prompt
typeset -f zle-line-init >/dev/null && zle zle-line-init
return $ret
}
zle -N cd-project-widget
It should be quite simple to modify it to work with other
fuzzy-finders. The basic idea is to show the output of ghq list
for
selection, and use ghq list --full-path
with the selected candidate
to print the correct directory for cd
.
What’s really nice about this, is that I can bind it to a key sequence:
bindkey '\es' cd-project-widget
Now I can press M-s
in a shell, start typing “nixfiles” and press enter to cd
to my nixfiles project. Pretty neat!