diff --git a/lua/ht/plugins/lsp/neodim.lua b/lua/ht/plugins/lsp/neodim.lua index ae546c47..b655e86c 100644 --- a/lua/ht/plugins/lsp/neodim.lua +++ b/lua/ht/plugins/lsp/neodim.lua @@ -1,6 +1,6 @@ return { { - "TwIStOy/neodim", + "zbirenbaum/neodim", lazy = true, event = "LspAttach", config = function() diff --git a/lua/ht/plugins/lsp/null-ls.lua b/lua/ht/plugins/lsp/null-ls.lua deleted file mode 100644 index 5b7c3e71..00000000 --- a/lua/ht/plugins/lsp/null-ls.lua +++ /dev/null @@ -1,34 +0,0 @@ -return { - { - "jose-elias-alvarez/null-ls.nvim", - lazy = true, - enabled = false, - dependencies = { "nvim-lua/plenary.nvim", "williamboman/mason.nvim" }, - config = function() - local null_ls = require("null-ls") - local builtins = null_ls.builtins - local Const = require("ht.core.const") - local lsp_conf = require("ht.conf.lsp.init") - - local sources = {} - - for _, tool in ipairs(lsp_conf.all_tools) do - local opt = {} - if tool.mason_pkg == nil then - opt.command = Const.mason_bin .. "/" .. tool.name - elseif tool.mason_pkg ~= false then - opt.command = Const.mason_bin .. "/" .. tool.mason_pkg - end - if tool.opts ~= nil then - opt = vim.tbl_extend("force", opt, tool.opts) - end - sources[#sources + 1] = builtins[tool.typ][tool.name].with(opt) - end - sources[#sources + 1] = builtins.formatting.dart_format - - null_ls.setup { - sources = sources, - } - end, - }, -} diff --git a/lua/ht/plugins/lsp/nvim-lspconfig.lua b/lua/ht/plugins/lsp/nvim-lspconfig.lua index 691c49ed..81ff4c53 100644 --- a/lua/ht/plugins/lsp/nvim-lspconfig.lua +++ b/lua/ht/plugins/lsp/nvim-lspconfig.lua @@ -15,7 +15,6 @@ return { "hrsh7th/nvim-cmp", "williamboman/mason.nvim", "MunifTanjim/nui.nvim", - "jose-elias-alvarez/null-ls.nvim", }, config = function() --- add menus for specific types diff --git a/lua/ht/plugins/lsp/trouble.lua b/lua/ht/plugins/lsp/trouble.lua deleted file mode 100644 index 1b2b3b25..00000000 --- a/lua/ht/plugins/lsp/trouble.lua +++ /dev/null @@ -1,63 +0,0 @@ -return { - Use { - "folke/trouble.nvim", - lazy = { - dependencies = { "folke/lsp-colors.nvim" }, - lazy = true, - cmd = { "Trouble", "TroubleClose", "TroubleToggle", "TroubleRefresh" }, - }, - functions = { - FuncSpec("Toggle trouble window", "TroubleToggle", { - keys = "xx", - desc = "toggle-trouble-window", - }), - { - filter = { - filter = function() - return require("trouble").is_open() - end, - }, - values = { - FuncSpec("Previous trouble item", function() - require("trouble").previous { skip_groups = true, jump = true } - end, { - keys = "[q", - desc = "previous-trouble-item", - }), - FuncSpec("Next trouble item", function() - require("trouble").next { skip_groups = true, jump = true } - end, { - keys = "]q", - desc = "next-trouble-item", - }), - }, - }, - { - filter = { - ---@param buffer VimBuffer - filter = function(buffer) - return buffer:lsp_attached() - end, - }, - values = { - FuncSpec( - "Open diagnostics in current workspace (Trouble)", - "Trouble workspace_diagnostics", - { - keys = "xw", - desc = "lsp-references", - } - ), - FuncSpec( - "Open diagnostics in current document (Trouble)", - "Trouble document_diagnostics", - { - keys = "xd", - desc = "lsp-references", - } - ), - }, - }, - }, - }, -} diff --git a/src/conf/actions/index.ts b/src/conf/actions/index.ts index 0cae1ca6..067124cf 100644 --- a/src/conf/actions/index.ts +++ b/src/conf/actions/index.ts @@ -1,6 +1,6 @@ import { AllPlugins } from "@conf/plugins"; import { Plugin, PluginActionIds, TraitActionsId } from "@core/model"; -import { TupleToUnion } from "@core/type_traits"; +import { RemoveReadonlyFromTuple, TupleToUnion } from "@core/type_traits"; import { builtinActions } from "./builtin"; export type AvailableActions = TupleToUnion< @@ -25,15 +25,6 @@ type MaybePluginOrPluginList

= P extends Plugin[] ? PluginActionIds

: never; -type RemoveReadonlyFromTuple = T extends readonly [ - infer A, - ...infer Rest, -] - ? A extends readonly any[] - ? [RemoveReadonlyFromTuple, ...RemoveReadonlyFromTuple] - : [A, ...RemoveReadonlyFromTuple] - : T; - type MergePluginsActions[]> = Ps extends [ infer P, ...infer Rest, diff --git a/src/conf/plugins/coding/crates-nvim.ts b/src/conf/plugins/coding/crates-nvim.ts index d1e9b7b8..ad912d29 100644 --- a/src/conf/plugins/coding/crates-nvim.ts +++ b/src/conf/plugins/coding/crates-nvim.ts @@ -73,7 +73,6 @@ const spec: PluginOptsBase = { lazy: true, dependencies: [ "nvim-lua/plenary.nvim", - "jose-elias-alvarez/null-ls.nvim", "MunifTanjim/nui.nvim", ], event: { diff --git a/src/conf/plugins/lsp/index.ts b/src/conf/plugins/lsp/index.ts index 15a2ec73..fdba6683 100644 --- a/src/conf/plugins/lsp/index.ts +++ b/src/conf/plugins/lsp/index.ts @@ -3,6 +3,7 @@ import { plugin as aerial } from "./aerial"; import { plugin as typescriptToolsNvim } from "./typescript-tools-nvim"; import { plugin as glanceNvim } from "./glance-nvim"; import { plugin as lspkindNvim } from "./lspkind-nvim"; +import { plugin as troubleNvim } from "./trouble-nvim"; export const plugins = [ mason, @@ -10,4 +11,5 @@ export const plugins = [ typescriptToolsNvim, glanceNvim, lspkindNvim, + troubleNvim, ] as const; diff --git a/src/conf/plugins/lsp/trouble-nvim.ts b/src/conf/plugins/lsp/trouble-nvim.ts new file mode 100644 index 00000000..120d910a --- /dev/null +++ b/src/conf/plugins/lsp/trouble-nvim.ts @@ -0,0 +1,93 @@ +import { + ActionGroupBuilder, + Plugin, + PluginOptsBase, + andActions, + removeReadonly, +} from "@core/model"; + +const spec: PluginOptsBase = { + shortUrl: "folke/trouble.nvim", + lazy: { + dependencies: ["folke/lsp-colors.nvim"], + lazy: true, + cmd: ["Trouble", "TroubleClose", "TroubleToggle", "TroubleRefresh"], + }, +}; + +function generateActions() { + const lspActions = ActionGroupBuilder.start() + .category("Trouble") + .from("trouble.nvim") + .condition((buf) => { + return buf.lspServers.length > 0; + }) + .addOpts({ + id: "trouble.open-workspace-diagnostic", + title: "Open workspace diagnostic (Trouble)", + callback: "Trouble workspace_diagnostic", + keys: { + [1]: "xw", + desc: "lsp-workspace-diagnostic", + }, + }) + .addOpts({ + id: "trouble.open-document-diagnostic", + title: "Open document diagnostic (Trouble)", + callback: "Trouble document_diagnostic", + keys: { + [1]: "xd", + desc: "lsp-document-diagnostic", + }, + }) + .build(); + const commonActions = ActionGroupBuilder.start() + .category("Trouble") + .from("trouble.nvim") + .addOpts({ + id: "trouble.toggle-indow", + title: "Toggle trouble window", + callback: "TroubleToggle", + keys: { + [1]: "xx", + desc: "trouble-toggle", + }, + }) + .build(); + const actionsInTroubleWindow = ActionGroupBuilder.start() + .category("Trouble") + .from("trouble.nvim") + .condition(() => { + return luaRequire("trouble").is_open(); + }) + .addOpts({ + id: "trouble.previous-trouble", + title: "Previous trouble item", + callback: () => { + luaRequire("trouble").previous({ skip_groups: true, jump: true }); + }, + keys: { + [1]: "[q]", + desc: "previous-trouble", + }, + }) + .addOpts({ + id: "trouble.next-trouble", + title: "Next trouble item", + callback: () => { + luaRequire("trouble").next({ skip_groups: true, jump: true }); + }, + keys: { + [1]: "]q]", + desc: "next-trouble", + }, + }) + .build(); + return removeReadonly([ + ...lspActions, + ...commonActions, + ...actionsInTroubleWindow, + ] as const); +} + +export const plugin = new Plugin(andActions(spec, generateActions)); diff --git a/src/core/model/action.ts b/src/core/model/action.ts index 25f6c75c..97d001ac 100644 --- a/src/core/model/action.ts +++ b/src/core/model/action.ts @@ -1,4 +1,9 @@ -import { GetRequired, Push, TupleToUnion } from "@core/type_traits"; +import { + GetRequired, + Push, + RemoveReadonlyFromTuple, + TupleToUnion, +} from "@core/type_traits"; import { VimBuffer } from "@core/vim"; import { LazyKeySpec } from "types/plugin/lazy"; @@ -275,3 +280,9 @@ export class Action { return ret; } } + +export function removeReadonly( + actions: T +): RemoveReadonlyFromTuple { + return actions as any; +} diff --git a/src/core/type_traits.ts b/src/core/type_traits.ts index a71afd1c..e6bfcdf7 100644 --- a/src/core/type_traits.ts +++ b/src/core/type_traits.ts @@ -54,3 +54,10 @@ export type Writeable = { -readonly [P in keyof T]: T[P] }; export type DeepWriteable = { -readonly [P in keyof T]: DeepWriteable; }; + +export type RemoveReadonlyFromTuple = + T extends readonly [infer A, ...infer Rest] + ? A extends readonly any[] + ? [RemoveReadonlyFromTuple, ...RemoveReadonlyFromTuple] + : [A, ...RemoveReadonlyFromTuple] + : T; diff --git a/src/core/utils/fn.ts b/src/core/utils/fn.ts index 8b137891..e69de29b 100644 --- a/src/core/utils/fn.ts +++ b/src/core/utils/fn.ts @@ -1 +0,0 @@ - diff --git a/src/core/utils/fs.ts b/src/core/utils/fs.ts new file mode 100644 index 00000000..3b3f0840 --- /dev/null +++ b/src/core/utils/fs.ts @@ -0,0 +1,29 @@ +import { VimBuffer, system } from "@core/vim"; + +export async function inGitRepo(buffer?: VimBuffer): Promise { + let cwd: string | undefined; + if (buffer && buffer.fullFileName) { + cwd = vim.fn.fnamemodify(buffer.fullFileName, ":h"); + } + let ret = await system(["git", "rev-parse", "--is-inside-work-tree"], { + cwd, + }); + return ret.code === 0; +} + +export async function getCurrentRepoPath( + buffer?: VimBuffer +): Promise { + let cwd: string | undefined; + if (buffer && buffer.fullFileName) { + cwd = vim.fn.fnamemodify(buffer.fullFileName, ":h"); + } + let ret = await system(["git", "rev-parse", "--show-toplevel"], { + cwd, + }); + if (ret.code !== 0) { + return null; + } + return ret.stdout!.trim(); +} + diff --git a/src/core/vim.ts b/src/core/vim.ts index 5e5aa6fd..475753db 100644 --- a/src/core/vim.ts +++ b/src/core/vim.ts @@ -190,3 +190,19 @@ export function highlightFg(group: string): string { } return ""; } + +export function system( + cmd: string[], + opts?: any +): Promise { + return new Promise((resolve, reject) => { + const onExit = (obj: vim.SystemCompleted) => { + resolve(obj); + }; + try { + vim.system(cmd, opts, onExit); + } catch (e) { + reject(e); + } + }); +} diff --git a/src/types/vim/fn.d.ts b/src/types/vim/fn.d.ts index cd3191ec..f385b05b 100644 --- a/src/types/vim/fn.d.ts +++ b/src/types/vim/fn.d.ts @@ -51,7 +51,11 @@ declare namespace vim { list?: boolean ): string; - export function fnamemodify(fname: string, mods: string): string; + export function fnamemodify( + this: void, + fname: string, + mods: string + ): string; export function setreg(reg: string, val: any, options?: any): void; }