From 0254c947f04abacdb932d21f7fca5ad0113bc5f3 Mon Sep 17 00:00:00 2001 From: Alan Pearce Date: Sun, 7 May 2017 00:10:06 +0200 Subject: post: Repository management with ghq --- content/post/repository-management-with-ghq.md | 75 ++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 content/post/repository-management-with-ghq.md diff --git a/content/post/repository-management-with-ghq.md b/content/post/repository-management-with-ghq.md new file mode 100644 index 0000000..6006605 --- /dev/null +++ b/content/post/repository-management-with-ghq.md @@ -0,0 +1,75 @@ ++++ +Tags = ["development","git"] +date = "2017-05-06T23:31:51+02:00" +title = "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: + +{{< highlight sh >}} +$ ghq get https://github.com/motemen/ghq +# Runs `git clone https://github.com/motemen/ghq ~/.ghq/github.com/motemen/ghq` +{{< /highlight >}} + +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: + +{{< highlight sh >}} +fp () { + ghq look $(ghq list | fzf +m) +} +{{< /highlight >}} + +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][fzf-cd-widget] and created +something similar that uses `ghq` instead of `find`: + +{{< highlight sh >}} +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 +{{< /highlight >}} + +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: + +{{< highlight sh >}} +bindkey '\es' cd-project-widget +{{< /highlight >}} + +Now I can press `M-s` in a shell, start typing "dotfiles" and press enter to `cd` +to my [dotfiles][] project. Pretty neat! + +[ghq]:https://github.com/motemen/ghq +[fzf]:https://github.com/junegunn/fzf +[fzf-cd-widget]:https://github.com/junegunn/fzf/blob/337cdbb37c1efc49b09b4cacc6e9ee1369c7d76d/shell/key-bindings.zsh#L40-L54 +[dotfiles]:https://git.alanpearce.eu/dotfiles -- cgit 1.4.1