vde-worktree 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,287 @@
1
+ #compdef vw vde-worktree
2
+
3
+ _vw_worktree_branches_raw() {
4
+ command git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
5
+ command git worktree list --porcelain 2>/dev/null \
6
+ | command sed -n 's/^branch refs\/heads\///p' \
7
+ | command sort -u
8
+ }
9
+
10
+ _vw_worktree_candidate_rows_raw() {
11
+ command git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
12
+ local vw_bin="${words[1]:-vw}"
13
+ command -v "$vw_bin" >/dev/null 2>&1 || return 0
14
+
15
+ command "$vw_bin" list --json 2>/dev/null | command node -e '
16
+ const fs = require("fs")
17
+ const home = process.env.HOME || ""
18
+ const toDisplayPath = (path) => {
19
+ if (typeof path !== "string" || path.length === 0) return ""
20
+ if (home.length === 0) return path
21
+ if (path === home) return "~"
22
+ if (path.startsWith(`${home}/`)) return `~${path.slice(home.length)}`
23
+ return path
24
+ }
25
+ const toFlag = (value) => {
26
+ if (value === true) return "yes"
27
+ if (value === false) return "no"
28
+ return "unknown"
29
+ }
30
+ let payload
31
+ try {
32
+ payload = JSON.parse(fs.readFileSync(0, "utf8"))
33
+ } catch {
34
+ process.exit(0)
35
+ }
36
+ const worktrees = Array.isArray(payload.worktrees) ? payload.worktrees : []
37
+ for (const worktree of worktrees) {
38
+ if (typeof worktree?.branch !== "string" || worktree.branch.length === 0) continue
39
+ const merged = toFlag(worktree?.merged?.overall)
40
+ const dirty = worktree?.dirty === true ? "yes" : "no"
41
+ const locked = worktree?.locked?.value === true ? "yes" : "no"
42
+ const path = toDisplayPath(worktree?.path)
43
+ const summary = `merged=${merged} dirty=${dirty} locked=${locked}${path ? ` path=${path}` : ""}`
44
+ const sanitized = summary.replace(/[\t\r\n]+/g, " ").trim()
45
+ process.stdout.write(`${worktree.branch}\t${sanitized}\n`)
46
+ }
47
+ ' 2>/dev/null
48
+ }
49
+
50
+ _vw_local_branches_raw() {
51
+ command git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
52
+ command git for-each-ref --format='%(refname:short)' refs/heads 2>/dev/null | command sort -u
53
+ }
54
+
55
+ _vw_remote_branches_raw() {
56
+ command git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
57
+ command git for-each-ref --format='%(refname:short)' refs/remotes 2>/dev/null \
58
+ | command sed '/\/HEAD$/d' \
59
+ | command sort -u
60
+ }
61
+
62
+ _vw_hook_names_raw() {
63
+ command git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
64
+ local repo_root
65
+ repo_root="$(command git rev-parse --show-toplevel 2>/dev/null)" || return 0
66
+ command ls -1 "$repo_root/.vde/worktree/hooks" 2>/dev/null \
67
+ | command grep -E '^(pre|post)-' \
68
+ | command sort -u
69
+ }
70
+
71
+ _vw_describe_values() {
72
+ local label="$1"
73
+ shift
74
+ local -a values
75
+ values=("$@")
76
+ if (( ${#values} == 0 )); then
77
+ _message "no ${label} candidates"
78
+ return 0
79
+ fi
80
+ _describe -t "${label}" "${label}" values
81
+ }
82
+
83
+ _vw_complete_worktree_branches() {
84
+ local -a values
85
+ values=("${(@f)$(_vw_worktree_branches_raw)}")
86
+ _vw_describe_values "worktree-branch" "${values[@]}"
87
+ }
88
+
89
+ _vw_complete_worktree_branches_with_meta() {
90
+ local -a rows branches descriptions
91
+ local row branch summary
92
+ rows=("${(@f)$(_vw_worktree_candidate_rows_raw)}")
93
+
94
+ for row in "${rows[@]}"; do
95
+ branch="${row%%$'\t'*}"
96
+ summary="${row#*$'\t'}"
97
+ if [[ -z "${branch}" ]]; then
98
+ continue
99
+ fi
100
+
101
+ branches+=("${branch}")
102
+ descriptions+=("${summary}")
103
+ done
104
+
105
+ if (( ${#branches} > 0 )); then
106
+ compadd -Ql -d descriptions -a branches
107
+ return 0
108
+ fi
109
+
110
+ _vw_complete_worktree_branches
111
+ }
112
+
113
+ _vw_complete_local_branches() {
114
+ local -a values
115
+ values=("${(@f)$(_vw_local_branches_raw)}")
116
+ _vw_describe_values "local-branch" "${values[@]}"
117
+ }
118
+
119
+ _vw_complete_switch_branches() {
120
+ local -a values
121
+ values=("${(@u)${(@f)$(_vw_worktree_branches_raw)} ${(@f)$(_vw_local_branches_raw)}}")
122
+ _vw_describe_values "branch" "${values[@]}"
123
+ }
124
+
125
+ _vw_complete_remote_branches() {
126
+ local -a values
127
+ values=("${(@f)$(_vw_remote_branches_raw)}")
128
+ _vw_describe_values "remote-branch" "${values[@]}"
129
+ }
130
+
131
+ _vw_complete_hooks() {
132
+ local -a values
133
+ values=("${(@f)$(_vw_hook_names_raw)}")
134
+ _vw_describe_values "hook" "${values[@]}"
135
+ }
136
+
137
+ _vw() {
138
+ local curcontext="$curcontext" state
139
+ local -a line
140
+ typeset -a commands
141
+ typeset -a global_options
142
+
143
+ commands=(
144
+ "init:Initialize directories, hooks, and managed exclude entries"
145
+ "list:List worktrees with status metadata"
146
+ "status:Show a single worktree status"
147
+ "path:Print absolute worktree path for branch"
148
+ "new:Create branch + worktree under .worktree"
149
+ "switch:Idempotent branch entrypoint"
150
+ "mv:Rename current non-primary worktree branch and move its directory"
151
+ "del:Delete worktree + branch with safety checks"
152
+ "gone:Bulk cleanup by safety-filtered candidate selection"
153
+ "get:Fetch remote branch and attach worktree"
154
+ "extract:Extract current primary branch into .worktree"
155
+ "use:Checkout target branch in primary worktree"
156
+ "exec:Run command in target branch worktree"
157
+ "invoke:Manually run hook script"
158
+ "copy:Copy repo-root files/dirs to target worktree"
159
+ "link:Create symlink from target worktree to repo-root file"
160
+ "lock:Create or update lock metadata"
161
+ "unlock:Remove lock metadata"
162
+ "cd:Interactive fzf picker that prints selected worktree path"
163
+ "completion:Print or install shell completion scripts"
164
+ "help:Show help"
165
+ )
166
+
167
+ global_options=(
168
+ "--json[Output machine-readable JSON]"
169
+ "--verbose[Enable verbose logs]"
170
+ "--no-hooks[Disable hooks for this run]"
171
+ "--allow-unsafe[Allow unsafe behavior in non-TTY mode]"
172
+ "--strict-post-hooks[Fail when post hooks fail]"
173
+ "--hook-timeout-ms[Override hook timeout]:ms:"
174
+ "--lock-timeout-ms[Override repository lock timeout]:ms:"
175
+ "--help[Show help]"
176
+ "--version[Show version]"
177
+ )
178
+
179
+ _arguments -C \
180
+ $global_options \
181
+ "1:command:->command" \
182
+ "*:: :->arguments"
183
+
184
+ case $state in
185
+ command)
186
+ _describe -t commands "vw command" commands
187
+ return
188
+ ;;
189
+ arguments)
190
+ local current_command="${line[1]:-${words[2]}}"
191
+ case "${current_command}" in
192
+ status)
193
+ _arguments \
194
+ "1:branch:_vw_complete_worktree_branches_with_meta"
195
+ ;;
196
+ path)
197
+ _arguments \
198
+ "1:branch:_vw_complete_worktree_branches_with_meta"
199
+ ;;
200
+ switch)
201
+ _arguments \
202
+ "1:branch:_vw_complete_switch_branches"
203
+ ;;
204
+ mv)
205
+ _arguments \
206
+ "1:new-branch:_vw_complete_local_branches"
207
+ ;;
208
+ del)
209
+ _arguments \
210
+ "1:branch:_vw_complete_worktree_branches_with_meta" \
211
+ "--force-dirty[Allow dirty worktree for del]" \
212
+ "--allow-unpushed[Allow unpushed commits for del]" \
213
+ "--force-unmerged[Allow unmerged worktree for del]" \
214
+ "--force-locked[Allow deleting locked worktree]" \
215
+ "--force[Enable all del force flags]"
216
+ ;;
217
+ gone)
218
+ _arguments \
219
+ "--apply[Apply deletion]" \
220
+ "--dry-run[Dry-run mode]"
221
+ ;;
222
+ get)
223
+ _arguments \
224
+ "1:remote-branch:_vw_complete_remote_branches"
225
+ ;;
226
+ extract)
227
+ _arguments \
228
+ "--current[Extract current worktree branch]" \
229
+ "--from[Path used by extract --from]:path:_files" \
230
+ "--stash[Allow stash when dirty]"
231
+ ;;
232
+ use)
233
+ _arguments \
234
+ "1:branch:_vw_complete_switch_branches" \
235
+ "--allow-agent[Allow non-TTY execution for use]" \
236
+ "--allow-unsafe[Allow unsafe behavior in non-TTY mode]"
237
+ ;;
238
+ exec)
239
+ _arguments \
240
+ "1:branch:_vw_complete_worktree_branches_with_meta"
241
+ ;;
242
+ invoke)
243
+ _arguments \
244
+ "1:hook:_vw_complete_hooks"
245
+ ;;
246
+ copy)
247
+ _arguments \
248
+ "*:repo-relative-path:_files"
249
+ ;;
250
+ link)
251
+ _arguments \
252
+ "*:repo-relative-path:_files" \
253
+ "--no-fallback[Disable copy fallback when symlink fails]"
254
+ ;;
255
+ lock)
256
+ _arguments \
257
+ "1:branch:_vw_complete_worktree_branches_with_meta" \
258
+ "--owner[Lock owner]:owner:" \
259
+ "--reason[Lock reason]:reason:"
260
+ ;;
261
+ unlock)
262
+ _arguments \
263
+ "1:branch:_vw_complete_worktree_branches_with_meta" \
264
+ "--owner[Unlock owner]:owner:" \
265
+ "--force[Force unlock]"
266
+ ;;
267
+ cd)
268
+ _arguments \
269
+ "--prompt[Custom fzf prompt]:prompt:" \
270
+ "--fzf-arg[Extra argument passed to fzf]:arg:"
271
+ ;;
272
+ completion)
273
+ _arguments \
274
+ "1:shell:(zsh fish)" \
275
+ "--install[Install completion file to default or --path]" \
276
+ "--path[Install destination file path]:path:_files"
277
+ ;;
278
+ help)
279
+ _arguments \
280
+ "1:command:(${(j: :)${commands%%:*}})"
281
+ ;;
282
+ esac
283
+ ;;
284
+ esac
285
+ }
286
+
287
+ compdef _vw vw vde-worktree
@@ -0,0 +1 @@
1
+ export { };