Skip to content

Commit 2c6e5de

Browse files
committed
feat(init): add ctrl-n keybinding to create new worktree from fzf picker
1 parent 584c17a commit 2c6e5de

2 files changed

Lines changed: 114 additions & 9 deletions

File tree

lib/commands/init.sh

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,27 @@ __FUNC__() {
9797
--layout=reverse \
9898
--border \
9999
--prompt='Worktree> ' \
100-
--header='enter:cd │ ctrl-e:editor │ ctrl-a:ai │ ctrl-d:delete │ ctrl-y:copy │ ctrl-r:refresh' \
100+
--header='enter:cd │ ctrl-n:new │ ctrl-e:editor │ ctrl-a:ai │ ctrl-d:delete │ ctrl-y:copy │ ctrl-r:refresh' \
101+
--expect=ctrl-n \
101102
--preview='git -C {1} log --oneline --graph --color=always -15 2>/dev/null; echo "---"; git -C {1} status --short 2>/dev/null' \
102103
--preview-window=right:50% \
103104
--bind='ctrl-e:execute(git gtr editor {2})' \
104105
--bind='ctrl-a:execute(git gtr ai {2})' \
105106
--bind='ctrl-d:execute(git gtr rm {2})+reload(git gtr list --porcelain)' \
106107
--bind='ctrl-y:execute(git gtr copy {2})' \
107108
--bind='ctrl-r:reload(git gtr list --porcelain)')" || return 0
108-
[ -z "$_gtr_selection" ] && return 0
109-
dir="$(printf '%s' "$_gtr_selection" | cut -f1)"
109+
local _gtr_key _gtr_line _gtr_branch
110+
_gtr_key="$(head -1 <<< "$_gtr_selection")"
111+
_gtr_line="$(sed -n '2p' <<< "$_gtr_selection")"
112+
if [ "$_gtr_key" = "ctrl-n" ]; then
113+
printf "Branch name: " >&2
114+
read -r _gtr_branch
115+
[ -z "$_gtr_branch" ] && return 0
116+
command git gtr new "$_gtr_branch"
117+
return $?
118+
fi
119+
[ -z "$_gtr_line" ] && return 0
120+
dir="$(printf '%s' "$_gtr_line" | cut -f1)"
110121
elif [ "$#" -eq 0 ]; then
111122
echo "Usage: __FUNC__ cd <branch>" >&2
112123
echo "Tip: Install fzf for an interactive picker (https://github.com/junegunn/fzf)" >&2
@@ -203,16 +214,27 @@ __FUNC__() {
203214
--layout=reverse \
204215
--border \
205216
--prompt='Worktree> ' \
206-
--header='enter:cd │ ctrl-e:editor │ ctrl-a:ai │ ctrl-d:delete │ ctrl-y:copy │ ctrl-r:refresh' \
217+
--header='enter:cd │ ctrl-n:new │ ctrl-e:editor │ ctrl-a:ai │ ctrl-d:delete │ ctrl-y:copy │ ctrl-r:refresh' \
218+
--expect=ctrl-n \
207219
--preview='git -C {1} log --oneline --graph --color=always -15 2>/dev/null; echo "---"; git -C {1} status --short 2>/dev/null' \
208220
--preview-window=right:50% \
209221
--bind='ctrl-e:execute(git gtr editor {2})' \
210222
--bind='ctrl-a:execute(git gtr ai {2})' \
211223
--bind='ctrl-d:execute(git gtr rm {2})+reload(git gtr list --porcelain)' \
212224
--bind='ctrl-y:execute(git gtr copy {2})' \
213225
--bind='ctrl-r:reload(git gtr list --porcelain)')" || return 0
214-
[ -z "$_gtr_selection" ] && return 0
215-
dir="$(printf '%s' "$_gtr_selection" | cut -f1)"
226+
local _gtr_key _gtr_line _gtr_branch
227+
_gtr_key="$(head -1 <<< "$_gtr_selection")"
228+
_gtr_line="$(sed -n '2p' <<< "$_gtr_selection")"
229+
if [ "$_gtr_key" = "ctrl-n" ]; then
230+
printf "Branch name: " >&2
231+
read -r _gtr_branch
232+
[ -z "$_gtr_branch" ] && return 0
233+
command git gtr new "$_gtr_branch"
234+
return $?
235+
fi
236+
[ -z "$_gtr_line" ] && return 0
237+
dir="$(printf '%s' "$_gtr_line" | cut -f1)"
216238
elif [ "$#" -eq 0 ]; then
217239
echo "Usage: __FUNC__ cd <branch>" >&2
218240
echo "Tip: Install fzf for an interactive picker (https://github.com/junegunn/fzf)" >&2
@@ -311,7 +333,8 @@ function __FUNC__
311333
--layout=reverse \
312334
--border \
313335
--prompt='Worktree> ' \
314-
--header='enter:cd │ ctrl-e:editor │ ctrl-a:ai │ ctrl-d:delete │ ctrl-y:copy │ ctrl-r:refresh' \
336+
--header='enter:cd │ ctrl-n:new │ ctrl-e:editor │ ctrl-a:ai │ ctrl-d:delete │ ctrl-y:copy │ ctrl-r:refresh' \
337+
--expect=ctrl-n \
315338
--preview='git -C {1} log --oneline --graph --color=always -15 2>/dev/null; echo "---"; git -C {1} status --short 2>/dev/null' \
316339
--preview-window=right:50% \
317340
--bind='ctrl-e:execute(git gtr editor {2})' \
@@ -320,8 +343,16 @@ function __FUNC__
320343
--bind='ctrl-y:execute(git gtr copy {2})' \
321344
--bind='ctrl-r:reload(git gtr list --porcelain)')
322345
or return 0
323-
test -z "$_gtr_selection"; and return 0
324-
set dir (string split \t -- "$_gtr_selection")[1]
346+
set -l _gtr_key "$_gtr_selection[1]"
347+
set -l _gtr_line "$_gtr_selection[2]"
348+
if test "$_gtr_key" = "ctrl-n"
349+
read -P "Branch name: " _gtr_branch
350+
test -z "$_gtr_branch"; and return 0
351+
command git gtr new "$_gtr_branch"
352+
return $status
353+
end
354+
test -z "$_gtr_line"; and return 0
355+
set dir (string split \t -- "$_gtr_line")[1]
325356
else if test (count $argv) -eq 1
326357
echo "Usage: __FUNC__ cd <branch>" >&2
327358
echo "Tip: Install fzf for an interactive picker (https://github.com/junegunn/fzf)" >&2

tests/init.bats

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,80 @@ setup() {
205205
[[ "$output" == *'Usage: gwtr cd <branch>'* ]]
206206
}
207207
208+
# ── ctrl-n (new worktree) in fzf picker ────────────────────────────────────
209+
210+
@test "bash output includes --expect=ctrl-n in fzf args" {
211+
run cmd_init bash
212+
[ "$status" -eq 0 ]
213+
[[ "$output" == *"--expect=ctrl-n"* ]]
214+
}
215+
216+
@test "zsh output includes --expect=ctrl-n in fzf args" {
217+
run cmd_init zsh
218+
[ "$status" -eq 0 ]
219+
[[ "$output" == *"--expect=ctrl-n"* ]]
220+
}
221+
222+
@test "fish output includes --expect=ctrl-n in fzf args" {
223+
run cmd_init fish
224+
[ "$status" -eq 0 ]
225+
[[ "$output" == *"--expect=ctrl-n"* ]]
226+
}
227+
228+
@test "bash output includes ctrl-n:new in fzf header" {
229+
run cmd_init bash
230+
[ "$status" -eq 0 ]
231+
[[ "$output" == *"ctrl-n:new"* ]]
232+
}
233+
234+
@test "zsh output includes ctrl-n:new in fzf header" {
235+
run cmd_init zsh
236+
[ "$status" -eq 0 ]
237+
[[ "$output" == *"ctrl-n:new"* ]]
238+
}
239+
240+
@test "fish output includes ctrl-n:new in fzf header" {
241+
run cmd_init fish
242+
[ "$status" -eq 0 ]
243+
[[ "$output" == *"ctrl-n:new"* ]]
244+
}
245+
246+
@test "bash output includes git gtr new in ctrl-n handler" {
247+
run cmd_init bash
248+
[ "$status" -eq 0 ]
249+
[[ "$output" == *'git gtr new "$_gtr_branch"'* ]]
250+
}
251+
252+
@test "zsh output includes git gtr new in ctrl-n handler" {
253+
run cmd_init zsh
254+
[ "$status" -eq 0 ]
255+
[[ "$output" == *'git gtr new "$_gtr_branch"'* ]]
256+
}
257+
258+
@test "fish output includes git gtr new in ctrl-n handler" {
259+
run cmd_init fish
260+
[ "$status" -eq 0 ]
261+
[[ "$output" == *'git gtr new "$_gtr_branch"'* ]]
262+
}
263+
264+
@test "bash output prompts for branch name on ctrl-n" {
265+
run cmd_init bash
266+
[ "$status" -eq 0 ]
267+
[[ "$output" == *'Branch name: '* ]]
268+
}
269+
270+
@test "zsh output prompts for branch name on ctrl-n" {
271+
run cmd_init zsh
272+
[ "$status" -eq 0 ]
273+
[[ "$output" == *'Branch name: '* ]]
274+
}
275+
276+
@test "fish output prompts for branch name on ctrl-n" {
277+
run cmd_init fish
278+
[ "$status" -eq 0 ]
279+
[[ "$output" == *'Branch name: '* ]]
280+
}
281+
208282
# ── git gtr passthrough preserved ────────────────────────────────────────────
209283
210284
@test "bash output passes non-cd commands to git gtr" {

0 commit comments

Comments
 (0)