30e516a3aa47d90b5f507d5ddacb1b9b69567975

Author
nasso <11479594+nasso@users.noreply.github.com>
Committer
GitHub <noreply@github.com>
Date

Message

feat(jj): add jujutsu plugin (#12292)

Diff

  1diff --git a/plugins/jj/README.md b/plugins/jj/README.md
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..cd43ed11b6709e1cca967656e02d92c80c5703eb
  4--- /dev/null
  5+++ b/plugins/jj/README.md
  6@@ -0,0 +1,89 @@
  7+# jj - Jujutsu CLI
  8+
  9+This plugin provides autocompletion for [jj](https://martinvonz.github.io/jj).
 10+
 11+To use it, add `jj` to the plugins array of your zshrc file:
 12+
 13+```zsh
 14+plugins=(... jj)
 15+```
 16+
 17+## Aliases
 18+
 19+| Alias  | Command                       |
 20+| ------ | ----------------------------- |
 21+| jjc    | `jj commit`                   |
 22+| jjcmsg | `jj commit --message`         |
 23+| jjd    | `jj diff`                     |
 24+| jjdmsg | `jj desc --message`           |
 25+| jjds   | `jj desc`                     |
 26+| jje    | `jj edit`                     |
 27+| jjgcl  | `jj git clone`                |
 28+| jjgf   | `jj git fetch`                |
 29+| jjgp   | `jj git push`                 |
 30+| jjl    | `jj log`                      |
 31+| jjla   | `jj log -r "all()"`           |
 32+| jjn    | `jj new`                      |
 33+| jjrb   | `jj rebase`                   |
 34+| jjrs   | `jj restore`                  |
 35+| jjrt   | `cd "$(jj root \|\| echo .)"` |
 36+| jjsp   | `jj split`                    |
 37+| jjsq   | `jj squash`                   |
 38+
 39+## Prompt usage
 40+
 41+Because `jj` has a very powerful [template syntax](https://martinvonz.github.io/jj/latest/templates/), this
 42+plugin only exposes a convenience function `jj_prompt_template` to read information from the current change.
 43+It is basically the same as `jj log --no-graph -r @ -T $1`:
 44+
 45+```sh
 46+_my_theme_jj_info() {
 47+  jj_prompt_template 'self.change_id().shortest(3)'
 48+}
 49+
 50+PROMPT='$(_my_theme_jj_info) $'
 51+```
 52+
 53+`jj_prompt_template` escapes `%` signs in the output. Use `jj_prompt_template_raw` if you don't want that
 54+(e.g. to colorize the output).
 55+
 56+However, because `jj` can be used inside a Git repository, some themes might clash with it. Generally, you can
 57+fix it with a wrapper function that tries `jj` first and then falls back to `git` if it didn't work:
 58+
 59+```sh
 60+_my_theme_vcs_info() {
 61+  jj_prompt_template 'self.change_id().shortest(3)' \
 62+  || git_prompt_info
 63+}
 64+
 65+PROMPT='$(_my_theme_vcs_info) $'
 66+```
 67+
 68+You can find an example
 69+[here](https://github.com/nasso/omzsh/blob/e439e494f22f4fd4ef1b6cb64626255f4b341c1b/themes/sunakayu.zsh-theme).
 70+
 71+### Performance
 72+
 73+Sometimes `jj` can be slower than `git`.
 74+
 75+If you feel slowdowns, consider using the following:
 76+
 77+```
 78+zstyle :omz:plugins:jj ignore-working-copy yes
 79+```
 80+
 81+This will add `--ignore-working-copy` to all `jj` commands executed by your prompt. The downside here is that
 82+your prompt might be out-of-sync until the next time `jj` gets a chance to _not_ ignore the working copy (i.e.
 83+you manually run a `jj` command).
 84+
 85+If you prefer to keep your prompt always up-to-date but still don't want to _feel_ the slowdown, you can make
 86+your prompt asynchronous. This plugin doesn't do this automatically so you'd have to hack your theme a bit for
 87+that.
 88+
 89+## See Also
 90+
 91+- [martinvonz/jj](https://github.com/martinvonz/jj)
 92+
 93+## Contributors
 94+
 95+- [nasso](https://github.com/nasso) - Plugin Author
 96diff --git a/plugins/jj/jj.plugin.zsh b/plugins/jj/jj.plugin.zsh
 97new file mode 100644
 98index 0000000000000000000000000000000000000000..9f683923d4f438b29eea6a66dc5ee6d691b81819
 99--- /dev/null
100+++ b/plugins/jj/jj.plugin.zsh
101@@ -0,0 +1,53 @@
102+# if jj is not found, don't do the rest of the script
103+if (( ! $+commands[jj] )); then
104+  return
105+fi
106+
107+# If the completion file doesn't exist yet, we need to autoload it and
108+# bind it to `jj`. Otherwise, compinit will have already done that.
109+if [[ ! -f "$ZSH_CACHE_DIR/completions/_jj" ]]; then
110+  typeset -g -A _comps
111+  autoload -Uz _jj
112+  _comps[jj]=_jj
113+fi
114+
115+jj util completion zsh >| "$ZSH_CACHE_DIR/completions/_jj" &|
116+
117+function __jj_prompt_jj() {
118+  local -a flags
119+  flags=("--no-pager")
120+  if zstyle -t ':omz:plugins:jj' ignore-working-copy; then
121+    flags+=("--ignore-working-copy")
122+  fi
123+  command jj $flags "$@"
124+}
125+
126+# convenience functions for themes
127+function jj_prompt_template_raw() {
128+  __jj_prompt_jj log --no-graph -r @ -T "$@" 2> /dev/null
129+}
130+
131+function jj_prompt_template() {
132+  local out
133+  out=$(jj_prompt_template_raw "$@") || return 1
134+  echo "${out:gs/%/%%}"
135+}
136+
137+# Aliases (sorted alphabetically)
138+alias jjc='jj commit'
139+alias jjcmsg='jj commit --message'
140+alias jjd='jj diff'
141+alias jjdmsg='jj desc --message'
142+alias jjds='jj desc'
143+alias jje='jj edit'
144+alias jjgcl='jj git clone'
145+alias jjgf='jj git fetch'
146+alias jjgp='jj git push'
147+alias jjl='jj log'
148+alias jjla='jj log -r "all()"'
149+alias jjn='jj new'
150+alias jjrb='jj rebase'
151+alias jjrs='jj restore'
152+alias jjrt='cd "$(jj root || echo .)"'
153+alias jjsp='jj split'
154+alias jjsq='jj squash'