diff --git a/denops/gin/action/tag.ts b/denops/gin/action/tag.ts index 39326320..b92044e1 100644 --- a/denops/gin/action/tag.ts +++ b/denops/gin/action/tag.ts @@ -16,42 +16,74 @@ export async function init( bufnr, "tag:lightweight", (denops, bufnr, range) => - doTag(denops, bufnr, range, false, false, false, gatherCandidates), + doTag(denops, bufnr, range, false, gatherCandidates), ); await define( denops, bufnr, "tag:annotate", (denops, bufnr, range) => - doTag(denops, bufnr, range, true, false, false, gatherCandidates), + doTagInteractive( + denops, + bufnr, + range, + true, + false, + false, + gatherCandidates, + ), ); await define( denops, bufnr, "tag:sign", (denops, bufnr, range) => - doTag(denops, bufnr, range, false, true, false, gatherCandidates), + doTagInteractive( + denops, + bufnr, + range, + false, + true, + false, + gatherCandidates, + ), ); await define( denops, bufnr, "tag:lightweight:force", (denops, bufnr, range) => - doTag(denops, bufnr, range, false, false, true, gatherCandidates), + doTag(denops, bufnr, range, true, gatherCandidates), ); await define( denops, bufnr, "tag:annotate:force", (denops, bufnr, range) => - doTag(denops, bufnr, range, true, false, true, gatherCandidates), + doTagInteractive( + denops, + bufnr, + range, + true, + false, + true, + gatherCandidates, + ), ); await define( denops, bufnr, "tag:sign:force", (denops, bufnr, range) => - doTag(denops, bufnr, range, false, true, true, gatherCandidates), + doTagInteractive( + denops, + bufnr, + range, + false, + true, + true, + gatherCandidates, + ), ); await alias( denops, @@ -63,6 +95,33 @@ export async function init( } async function doTag( + denops: Denops, + bufnr: number, + range: Range, + force: boolean, + gatherCandidates: GatherCandidates, +): Promise { + const xs = await gatherCandidates(denops, bufnr, range); + const x = xs.at(0); + if (!x) { + return; + } + const name = await helper.input(denops, { + prompt: `Name: `, + }); + if (!name) { + await helper.echo(denops, "Cancelled"); + return; + } + await denops.dispatch("gin", "command", "", [ + "tag", + ...(force ? ["--force"] : []), + name, + x.commit, + ]); +} + +async function doTagInteractive( denops: Denops, bufnr: number, range: Range, @@ -72,21 +131,32 @@ async function doTag( gatherCandidates: GatherCandidates, ): Promise { const xs = await gatherCandidates(denops, bufnr, range); - for (const x of xs) { - const name = await helper.input(denops, { - prompt: `Name: `, - }); - if (!name) { - await helper.echo(denops, "Cancelled"); - return; - } - await denops.dispatch("gin", "command", "", [ - "tag", - ...(annotate ? ["--annotate"] : []), - ...(sign ? ["--sign"] : []), - ...(force ? ["--force"] : []), - name, - x.commit, - ]); + const x = xs.at(0); + if (!x) { + return; + } + const name = await helper.input(denops, { + prompt: `Name: `, + }); + if (!name) { + await helper.echo(denops, "Cancelled"); + return; } + // NOTE: + // We must NOT await the command otherwise Vim would freeze + // because command proxy could not work if we await here. + denops.dispatch("gin", "command", "", [ + "tag", + ...(annotate ? ["--annotate"] : []), + ...(sign ? ["--sign"] : []), + ...(force ? ["--force"] : []), + name, + x.commit, + ]).catch(async (e) => { + await helper.echoerr(denops, e.toString()); + }).then( + // suppress false-positive detection of file changes + // NOTE: must be done on resolve because the tag is not awaited + () => denops.cmd("silent checktime"), + ); }