about summary refs log tree commit diff stats
path: root/content/post
diff options
context:
space:
mode:
authorAlan Pearce2017-05-07 00:10:06 +0200
committerAlan Pearce2017-05-07 00:10:06 +0200
commit0254c947f04abacdb932d21f7fca5ad0113bc5f3 (patch)
treef59ecd725a83c7f25f291f639757c96344b9801a /content/post
parent1b083b46889df352c1fc09305c39d55aaa1ac553 (diff)
downloadwebsite-0254c947f04abacdb932d21f7fca5ad0113bc5f3.tar.lz
website-0254c947f04abacdb932d21f7fca5ad0113bc5f3.tar.zst
website-0254c947f04abacdb932d21f7fca5ad0113bc5f3.zip
post: Repository management with ghq
Diffstat (limited to 'content/post')
-rw-r--r--content/post/repository-management-with-ghq.md75
1 files changed, 75 insertions, 0 deletions
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 @@
1+++
2Tags = ["development","git"]
3date = "2017-05-06T23:31:51+02:00"
4title = "Repository management with ghq"
5+++
6
7I recently encountered [ghq][], a tool for automatically organising VCS-backed
8projects automatically. Give it a repository URL, it will clone a project to
9your projects dir (set by `$GHQ_ROOT`) like so:
10
11{{< highlight sh >}}
12$ ghq get https://github.com/motemen/ghq
13# Runs `git clone https://github.com/motemen/ghq ~/.ghq/github.com/motemen/ghq`
14{{< /highlight >}}
15
16I don't like the idea of having projects hidden away, so I set
17`$GHQ_ROOT` to `$HOME/projects`.
18
19From there, the `list` and `look` subcommands allow listing
20repositories and visiting them in the shell (actually a subshell).
21
22I wanted a nicer way to visit project directories. Since I'm
23using [fzf][] as a fuzzy-finder, I thought it would be nice to use it
24for this. I created a simple function, `fp` (find project) to do that:
25
26{{< highlight sh >}}
27fp () {
28 ghq look $(ghq list | fzf +m)
29}
30{{< /highlight >}}
31
32I ran into some issues with the subshell of `ghq look` and wondered
33whether it might be possible to create a zsh command to remove the
34need for a subshell.
35
36I found that `fzf` includes a [cd-widget function][fzf-cd-widget] and created
37something similar that uses `ghq` instead of `find`:
38
39{{< highlight sh >}}
40cd-project-widget () {
41 local cmd="ghq list"
42 setopt localoptions pipefail 2> /dev/null
43 local dir="$(eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS" fzf +m)"
44 if [[ -z "$dir" ]]; then
45 zle redisplay
46 return 0
47 fi
48 cd $(ghq list --full-path | grep "$dir")
49 local ret=$?
50 zle reset-prompt
51 typeset -f zle-line-init >/dev/null && zle zle-line-init
52 return $ret
53}
54zle -N cd-project-widget
55{{< /highlight >}}
56
57It should be quite simple to modify it to work with other
58fuzzy-finders. The basic idea is to show the output of `ghq list` for
59selection, and use `ghq list --full-path` with the selected candidate
60to print the correct directory for `cd`.
61
62What's really nice about this, is that I can bind it to a key
63sequence:
64
65{{< highlight sh >}}
66bindkey '\es' cd-project-widget
67{{< /highlight >}}
68
69Now I can press `M-s` in a shell, start typing "dotfiles" and press enter to `cd`
70to my [dotfiles][] project. Pretty neat!
71
72[ghq]:https://github.com/motemen/ghq
73[fzf]:https://github.com/junegunn/fzf
74[fzf-cd-widget]:https://github.com/junegunn/fzf/blob/337cdbb37c1efc49b09b4cacc6e9ee1369c7d76d/shell/key-bindings.zsh#L40-L54
75[dotfiles]:https://git.alanpearce.eu/dotfiles