import { ActionFlags, BaseConfig, ConfigArguments, DduOptions, } from "../../../denops/deps/ddu.ts"; import { cmd, map } from "../../../denops/@vimrc/lib/lambda/map.ts"; import { dduHelper } from "./lib/helper.ts"; import { Denops } from "../../../denops/deps/denops_std.ts"; import { is, maybe } from "../../../denops/deps/unknownutil.ts"; import { KindGitStatusActionData } from "../../../denops/deps/ddu-kinds.ts"; import { stdpath } from "../../../denops/deps/deno_std.ts"; import * as sourceList from "../../../denops/@ddu-sources/list.ts"; /* main section */ function setupGitStatus(args: ConfigArguments) { const ddu = dduHelper(args.denops); args.contextBuilder.patchGlobal({ actionOptions: { narrow: { quit: false, }, }, filterParams: { // X converter_hl_dir: { hlGroup: "String", }, // X matcher_fzf: { highlightMatched: "DduMatch", }, }, sourceOptions: { // X git_status: { converters: [ "converter_hl_dir", "converter_git_status", ], }, }, kindOptions: { callback: { defaultAction: "call" }, git_status: { actions: { commit: async () => { await args.denops.call("funnygit#commit"); // await args.denops.cmd("Gin commit"); return ActionFlags.None; }, diff: (args) => { const action = args.items[0].action as KindGitStatusActionData; const path = stdpath.join(action.worktree, action.path); ddu.start({ name: "git_diff", sources: [{ name: "git_diff", options: { path, }, params: { ...maybe(args.actionParams, is.Record) ?? {}, onlyFile: true, }, }], }); return Promise.resolve(ActionFlags.None); }, patch: async (args) => { for (const item of args.items) { const action = item.action as KindGitStatusActionData; await args.denops.cmd("tabnew"); await args.denops.cmd("tcd " + action.worktree); await args.denops.cmd("GinPatch ++no-head " + action.path); } return ActionFlags.None; }, }, defaultAction: "open", }, }, }); args.contextBuilder.patchLocal("git_status", { actionOptions: { add: { quit: false }, reset: { quit: false }, restore: { quit: false }, }, sources: ["git_status"], }); } // X // L も直す function setupLocals(args: ConfigArguments) { // X for (const type of ["mru", "mrw", "mrr"]) { args.contextBuilder.patchLocal(type, { sources: [{ name: "mr", params: { kind: type, }, }], }); } // X args.contextBuilder.patchLocal("dpp", { sources: ["dpp"], }); args.contextBuilder.patchLocal("file_ext_mrw", { sources: [{ name: "file_external", options: { matchers: ["matcher_substring"], sorters: ["sorter_mtime"], converters: [], }, }], }); args.contextBuilder.patchLocal("file_rec_mrw", { sources: [{ name: "file_rec", options: { matchers: ["matcher_substring"], sorters: ["sorter_mtime"], converters: [], }, }], }); // X args.contextBuilder.patchLocal("help", { sources: ["help"], }); // X args.contextBuilder.patchLocal("line", { sources: ["line"], }); } function mainConfig(args: ConfigArguments) { // default options const defaultMatchers = ["matcher_fzf"]; const defaultSorters = ["sorter_fzf"]; // X args.contextBuilder.patchGlobal({ kindOptions: { // X file: { defaultAction: "open", }, lsp: { defaultAction: "open" }, lsp_codeAction: { defaultAction: "apply" }, }, sourceOptions: { _: { ignoreCase: true, matchers: defaultMatchers, sorters: defaultSorters, }, }, sourceParams: { file_external: { cmd: ["fd", ".", "-H", "-I", "-E", ".git", "-t", "f"], }, }, }); setupGitStatus(args); setupLocals(args); } /* selector section */ type Promisify = T | Promise; // 環境から情報を収集してオプションに変える感じで type POptions = Promisify>; type Collector = (denops: Denops) => POptions; async function ripgrepLive( denops: Denops, findPath: (denops: Denops) => Promise, ): Promise> { // ddu-source-rg is set to lazy, load it. await denops.call("dpp#source", "ddu-source-rg"); return { name: "file:rg", sources: [{ name: "rg", options: { matchers: ["matcher_limit"], sorters: ["sorter_alpha_path"], converters: [], path: await findPath(denops), volatile: true, }, }], uiParams: { ff: { ignoreEmpty: false, autoResize: false, }, }, }; } // X const definition: Record = { file: async (denops) => ({ name: "file", sources: [{ name: "file", options: { path: String(await denops.call("expand", "%:p:h")), matchers: [], sorters: ["sorter_alpha"], converters: [], }, }], }), filer: async (denops) => { await denops.dispatcher.loadConfig( await denops.call("expand", "$VIMDIR/conf/plug/ddu/filer.ts"), ); return { name: "filer", sources: [{ name: "file", options: { columns: ["filename"], path: String(await denops.call("expand", "%:p:h")), }, }], // syncとsearchPathによりrevealできるらしい searchPath: String(await denops.call("expand", "%:p")), sync: true, ui: "filer", }; }, git_branch: async (denops) => ({ name: "git_branch", sources: [{ name: "git_branch", options: { path: String(await denops.call("expand", "%:p:h")), }, params: { remote: true, }, }], }), github_repo_pull: async (denops) => { // L await denops.call("dpp#source", "ddu-source-github"); return { name: "github_repo_pull", sources: [{ name: "github_repo_pull", params: { path: await denops.call("expand", "%:p:h"), }, }], }; }, live_grep: (denops) => ripgrepLive( denops, async (denops) => String(await denops.call("expand", "%:p:h")), ), live_grep_git: (denops) => ripgrepLive( denops, async (denops) => String(await denops.call("gin#util#worktree")), ), // X lsp_codeAction: () => ({ name: "lsp", sources: [{ name: "lsp_codeAction", }], }), lsp_definition: () => ({ name: "lsp", sources: ["lsp_definition"], }), lsp_references: () => ({ name: "lsp", sources: ["lsp_references"], }), quickfix: () => ({ name: "file", sources: ["qf"], }), }; async function selectorConfig(args: ConfigArguments) { const { denops } = args; const ddu = dduHelper(denops); await map(denops, ";s", () => { // コレクターを選んで実行しdduに渡す ddu.start( sourceList.buildOptions( Object.keys(definition).sort(), async (items) => { if (items[0] != null) { await denops.call( "histadd", ":", "DduSelectorCall " + items[0].word, ); ddu.start(await definition[items[0].word](denops)); } return ActionFlags.None; }, ), ); }, { noremap: true, }); await cmd(denops, "DduSelectorCall", async (args) => { const def = await definition[args.arg]?.(denops); if (def == null) { throw Error(`DduSelectorCall failed: ${args.arg}`); } ddu.start(def); }); } export class Config extends BaseConfig { async config(args: ConfigArguments) { mainConfig(args); await selectorConfig(args); } }