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.
- package/README.ja.md +395 -0
- package/README.md +376 -28
- package/bin/vde-worktree +38 -0
- package/bin/vw +38 -0
- package/completions/fish/vw.fish +170 -0
- package/completions/zsh/_vw +287 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +3355 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +78 -6
|
@@ -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
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|