Skip to content

Commit c41c089

Browse files
committed
Add git worktree support
1 parent 05a183c commit c41c089

File tree

4 files changed

+140
-23
lines changed

4 files changed

+140
-23
lines changed

denops/gin/action/branch_delete.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { define, GatherCandidates, Range } from "./core.ts";
44

55
export type Candidate =
66
| { kind: "remote"; branch: string; remote: string }
7-
| { kind?: "alias" | "local"; branch: string };
7+
| { kind?: "alias" | "local"; branch: string; worktree?: string };
88

99
export async function init(
1010
denops: Denops,
@@ -50,11 +50,19 @@ async function doDelete(
5050
]);
5151
break;
5252
default:
53-
await denops.dispatch("gin", "command", "", [
54-
"branch",
55-
force ? "-D" : "-d",
56-
x.branch,
57-
]);
53+
if (x.worktree) {
54+
await denops.dispatch("gin", "command", "", [
55+
"worktree",
56+
"remove",
57+
x.worktree,
58+
]);
59+
} else {
60+
await denops.dispatch("gin", "command", "", [
61+
"branch",
62+
force ? "-D" : "-d",
63+
x.branch,
64+
]);
65+
}
5866
break;
5967
}
6068
}

denops/gin/action/branch_move.ts

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as batch from "jsr:@denops/std@^7.0.0/batch";
33
import * as helper from "jsr:@denops/std@^7.0.0/helper";
44
import { define, GatherCandidates, Range } from "./core.ts";
55

6-
export type Candidate = { branch: string };
6+
export type Candidate = { branch: string; worktree?: string };
77

88
export async function init(
99
denops: Denops,
@@ -40,21 +40,41 @@ async function doMove(
4040
if (!x) {
4141
return;
4242
}
43-
const from = x.branch;
44-
const name = await helper.input(denops, {
45-
prompt: `Rename (from ${from}): `,
46-
text: from,
47-
});
48-
await denops.cmd('redraw | echo ""');
49-
if (!name) {
50-
await helper.echoerr(denops, "Cancelled");
51-
return;
43+
if (x.worktree) {
44+
const from = x.worktree;
45+
const newPath = await helper.input(denops, {
46+
prompt: `New path (from ${from}): `,
47+
text: from,
48+
});
49+
await denops.cmd('redraw | echo ""');
50+
if (!name) {
51+
await helper.echoerr(denops, "Cancelled");
52+
return;
53+
}
54+
await denops.dispatch("gin", "command", "", [
55+
"worktree",
56+
"move",
57+
...(force ? ["--force"] : []),
58+
from,
59+
newPath,
60+
]);
61+
} else {
62+
const from = x.branch;
63+
const newName = await helper.input(denops, {
64+
prompt: `Rename (from ${from}): `,
65+
text: from,
66+
});
67+
await denops.cmd('redraw | echo ""');
68+
if (!newName) {
69+
await helper.echoerr(denops, "Cancelled");
70+
return;
71+
}
72+
await denops.dispatch("gin", "command", "", [
73+
"branch",
74+
...(force ? ["--force"] : []),
75+
"--move",
76+
from,
77+
newName,
78+
]);
5279
}
53-
await denops.dispatch("gin", "command", "", [
54-
"branch",
55-
...(force ? ["--force"] : []),
56-
"--move",
57-
from,
58-
name,
59-
]);
6080
}

denops/gin/action/worktree_new.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import type { Denops } from "jsr:@denops/std@^7.0.0";
2+
import * as batch from "jsr:@denops/std@^7.0.0/batch";
3+
import * as helper from "jsr:@denops/std@^7.0.0/helper";
4+
import { define, GatherCandidates, Range } from "./core.ts";
5+
6+
export type Candidate = { target?: string };
7+
8+
export async function init(
9+
denops: Denops,
10+
bufnr: number,
11+
gatherCandidates: GatherCandidates<Candidate>,
12+
): Promise<void> {
13+
await batch.batch(denops, async (denops) => {
14+
await define(
15+
denops,
16+
bufnr,
17+
"worktree",
18+
(denops, bufnr, range) =>
19+
doNew(denops, bufnr, range, false, gatherCandidates),
20+
);
21+
await define(
22+
denops,
23+
bufnr,
24+
"worktree:force",
25+
(denops, bufnr, range) =>
26+
doNew(denops, bufnr, range, true, gatherCandidates),
27+
);
28+
await define(
29+
denops,
30+
bufnr,
31+
"worktree:orphan",
32+
(denops, bufnr, range) =>
33+
doNewOrphan(denops, bufnr, range, gatherCandidates),
34+
);
35+
});
36+
}
37+
38+
async function doNew(
39+
denops: Denops,
40+
bufnr: number,
41+
range: Range,
42+
force: boolean,
43+
gatherCandidates: GatherCandidates<Candidate>,
44+
): Promise<void> {
45+
const xs = await gatherCandidates(denops, bufnr, range);
46+
const x = xs.at(0);
47+
const target = x?.target ?? "HEAD";
48+
const worktreePath = await helper.input(denops, {
49+
prompt: `Worktree path (for ${target}): `,
50+
text: `.worktrees/${target}`,
51+
});
52+
await denops.cmd('redraw | echo ""');
53+
if (!worktreePath) {
54+
await helper.echoerr(denops, "Cancelled");
55+
return;
56+
}
57+
await denops.dispatch("gin", "command", "", [
58+
"worktree",
59+
"add",
60+
...(force ? ["-f"] : []),
61+
worktreePath,
62+
target,
63+
]);
64+
}
65+
66+
async function doNewOrphan(
67+
denops: Denops,
68+
_bufnr: number,
69+
_range: Range,
70+
_gatherCandidates: GatherCandidates<unknown>,
71+
): Promise<void> {
72+
const worktreePath = await helper.input(denops, {
73+
prompt: "Worktree path (orphan): ",
74+
text: `.worktrees/orphan`,
75+
});
76+
await denops.cmd('redraw | echo ""');
77+
if (!worktreePath) {
78+
await helper.echoerr(denops, "Cancelled");
79+
return;
80+
}
81+
await denops.dispatch("gin", "command", "", [
82+
"worktree",
83+
"add",
84+
"--orphan",
85+
worktreePath,
86+
]);
87+
}

denops/gin/command/branch/edit.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { init as initActionMerge } from "../../action/merge.ts";
1919
import { init as initActionRebase } from "../../action/rebase.ts";
2020
import { init as initActionSwitch } from "../../action/switch.ts";
2121
import { init as initActionYank } from "../../action/yank.ts";
22+
import { init as initActionWorktreeNew } from "../../action/worktree_new.ts";
2223
import { Branch, parse as parseBranch } from "./parser.ts";
2324

2425
export async function edit(
@@ -71,6 +72,7 @@ export async function exec(
7172
await initActionBranchDelete(denops, bufnr, gatherCandidates);
7273
await initActionBranchMove(denops, bufnr, gatherCandidates);
7374
await initActionBranchNew(denops, bufnr, gatherCandidates);
75+
await initActionWorktreeNew(denops, bufnr, gatherCandidates);
7476
await initActionBrowse(denops, bufnr, async (denops, bufnr, range) => {
7577
const xs = await gatherCandidates(denops, bufnr, range);
7678
return xs.map((b) => ({ commit: b.target, ...b }));

0 commit comments

Comments
 (0)