gabriel / muse public
_muse
176 lines 5.8 KB
838d4a3e feat(omzsh-plugin): strip to minimal, secure shell integration Gabriel Cardona <gabriel@tellurstori.com> 3d ago
1 #compdef muse
2 # _muse — ZSH completion for the muse CLI
3 # ==============================================================================
4 # Relies on MUSE_REPO_ROOT exported by muse.plugin.zsh. All file reads are
5 # pure ZSH globbing — no subprocesses, no ls, no eval.
6 # ==============================================================================
7
8 # List branch names from .muse/refs/heads/ using ZSH globbing (no subprocess).
9 function _muse_branches() {
10 local refs_dir="${MUSE_REPO_ROOT}/.muse/refs/heads"
11 [[ -d "$refs_dir" ]] || return
12 local -a branches
13 branches=("${refs_dir}"/*(N:t)) # (N) = nullglob, :t = tail (basename)
14 (( ${#branches} )) && _describe 'branch' branches
15 }
16
17 # List tag names from .muse/refs/tags/.
18 function _muse_tags() {
19 local tags_dir="${MUSE_REPO_ROOT}/.muse/refs/tags"
20 [[ -d "$tags_dir" ]] || return
21 local -a tags
22 tags=("${tags_dir}"/*(N:t))
23 (( ${#tags} )) && _describe 'tag' tags
24 }
25
26 # List remote names from .muse/remotes/.
27 function _muse_remotes() {
28 local remotes_dir="${MUSE_REPO_ROOT}/.muse/remotes"
29 [[ -d "$remotes_dir" ]] || return
30 local -a remotes
31 remotes=("${remotes_dir}"/*(N:t))
32 (( ${#remotes} )) && _describe 'remote' remotes
33 }
34
35 # Main completion function.
36 function _muse() {
37 local state line
38 typeset -A opt_args
39
40 _arguments -C \
41 '(-h --help)'{-h,--help}'[show help]' \
42 '(-V --version)'{-V,--version}'[show version]' \
43 '1: :->command' \
44 '*:: :->args'
45
46 case "$state" in
47 command)
48 local -a cmds
49 cmds=(
50 'init:initialise a new muse repository'
51 'status:show working-tree status'
52 'log:show commit history'
53 'diff:show changes between commits or working tree'
54 'show:show a commit or object'
55 'commit:record changes to the repository'
56 'branch:list, create, or delete branches'
57 'checkout:switch branches or restore files'
58 'merge:join two branches'
59 'reset:reset HEAD to a given state'
60 'revert:create a new commit that undoes a prior commit'
61 'cherry-pick:apply a commit onto the current branch'
62 'stash:stash uncommitted changes'
63 'tag:create, list, or delete tags'
64 'blame:annotate lines with commit info'
65 'reflog:show reference log'
66 'gc:run repository maintenance'
67 'remote:manage remote repositories'
68 'fetch:download objects and refs from a remote'
69 'pull:fetch and integrate from a remote'
70 'push:update remote refs and send objects'
71 'clone:clone a repository'
72 'config:read or write repository config'
73 'domains:list registered domain plugins'
74 'workspace:manage multi-domain workspaces'
75 'worktree:manage linked working trees'
76 'archive:create an archive of repository contents'
77 'annotate:add structured annotations to commits'
78 'attributes:manage path attribute rules'
79 'check:run repository integrity checks'
80 'hub:interact with Muse Hub repositories'
81 'auth:manage authentication credentials'
82 'midi:MIDI domain subcommands'
83 'code:code domain subcommands'
84 'plumbing:low-level plumbing commands'
85 )
86 _describe 'muse command' cmds
87 ;;
88
89 args)
90 case "${line[1]}" in
91 checkout|merge|cherry-pick|branch|revert|reset)
92 _muse_branches
93 ;;
94 push|pull|fetch)
95 local -a remote_args
96 remote_args=()
97 _muse_remotes
98 ;;
99 tag)
100 case "${line[2]}" in
101 -d|--delete) _muse_tags ;;
102 *) _muse_tags ;;
103 esac
104 ;;
105 blame|show|diff)
106 _muse_branches
107 ;;
108 config)
109 if (( ${#line} == 2 )); then
110 local -a keys
111 keys=(
112 'core.domain:active domain plugin'
113 'core.user:commit author name'
114 'core.email:commit author email'
115 'core.editor:preferred editor'
116 'core.pager:preferred pager'
117 'core.autocrlf:line-ending conversion'
118 'core.filemode:track execute permission'
119 'push.default:default push behaviour'
120 'merge.conflictstyle:conflict marker style'
121 'log.oneline:default log format'
122 )
123 _describe 'config key' keys
124 fi
125 ;;
126 stash)
127 local -a stash_cmds
128 stash_cmds=(
129 'push:stash the working tree'
130 'pop:apply and drop the latest stash'
131 'apply:apply a stash without dropping it'
132 'list:list stash entries'
133 'drop:discard a stash entry'
134 'show:inspect a stash entry'
135 )
136 _describe 'stash subcommand' stash_cmds
137 ;;
138 remote)
139 local -a remote_cmds
140 remote_cmds=(
141 'add:add a remote'
142 'remove:remove a remote'
143 'rename:rename a remote'
144 'list:list configured remotes'
145 'show:show remote info'
146 'set-url:change a remote URL'
147 )
148 _describe 'remote subcommand' remote_cmds
149 ;;
150 plumbing)
151 local -a plumbing_cmds
152 plumbing_cmds=(
153 'ls-files:list tracked files'
154 'cat-file:show raw object content'
155 'hash-object:compute object hash'
156 'merge-base:find common ancestor'
157 'rev-parse:resolve a ref to a SHA'
158 )
159 _describe 'plumbing subcommand' plumbing_cmds
160 ;;
161 commit)
162 _arguments \
163 '(-m --message)'{-m,--message}'[commit message]:message' \
164 '(-a --all)'{-a,--all}'[stage all changes before committing]' \
165 '--amend[amend the previous commit]' \
166 '--no-edit[reuse previous commit message]'
167 ;;
168 *)
169 _files
170 ;;
171 esac
172 ;;
173 esac
174 }
175
176 _muse "$@"