From 1f723e8abd6286f1e489fa0c374ee1be95b0157c Mon Sep 17 00:00:00 2001 From: traxys Date: Thu, 5 Jan 2023 15:23:23 +0100 Subject: [PATCH] treesitter: add module for treesitter-refactor (#101) As treesitter-refactor is a treesitter module we need a way to pass extra configuration options to the treesitter setup. This is done through a `moduleConfig` attrset. This set should not be used outside nixvim. --- plugins/default.nix | 1 + plugins/languages/treesitter-refactor.nix | 128 ++++++++++++++++++++++ plugins/languages/treesitter.nix | 8 +- 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 plugins/languages/treesitter-refactor.nix diff --git a/plugins/default.nix b/plugins/default.nix index 01c68e6d..4ca0ac62 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -24,6 +24,7 @@ ./languages/ledger.nix ./languages/nix.nix ./languages/treesitter.nix + ./languages/treesitter-refactor.nix ./languages/zig.nix ./null-ls diff --git a/plugins/languages/treesitter-refactor.nix b/plugins/languages/treesitter-refactor.nix new file mode 100644 index 00000000..56b768a3 --- /dev/null +++ b/plugins/languages/treesitter-refactor.nix @@ -0,0 +1,128 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; { + options.plugins.treesitter-refactor = let + disable = mkOption { + type = types.listOf types.str; + default = []; + description = "List of languages to disable the module on"; + }; + in { + enable = + mkEnableOption + "Enable treesitter-refactor (requires plugins.treesitter.enable to be true)"; + highlightDefinitions = { + inherit disable; + enable = + mkEnableOption + "Highlights definition and usages of the current symbol under the cursor."; + clearOnCursorMove = mkOption { + type = types.bool; + default = true; + description = '' + Controls if highlights should be cleared when the cursor is moved. If your 'updatetime' + is around `100` you can set this to false to have a less laggy experience. + ''; + }; + }; + highlightCurrentScope = { + inherit disable; + enable = mkEnableOption "Highlights the block from the current scope where the cursor is."; + }; + smartRename = { + inherit disable; + enable = + mkEnableOption + "Renames the symbol under the cursor within the current scope (and current file)."; + keymaps = { + smartRename = mkOption { + type = types.nullOr types.str; + default = "grr"; + description = "rename symbol under the cursor"; + }; + }; + }; + navigation = { + inherit disable; + enable = mkEnableOption '' + Provides "go to definition" for the symbol under the cursor, + and lists the definitions from the current file. + ''; + + keymaps = { + gotoDefinition = mkOption { + type = types.nullOr types.str; + default = "gnd"; + description = "go to the definition of the symbol under the cursor"; + }; + gotoDefinitionLspFallback = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + go to the definition of the symbol under the cursor or use vim.lsp.buf.definition if + the symbol can not be resolved. You can use your own fallback function if create a + mapping fo `lua require'nvim-treesitter.refactor.navigation(nil, fallback_function)`. + ''; + }; + listDefinitons = mkOption { + type = types.nullOr types.str; + default = "gnD"; + description = "list all definitions from the current file"; + }; + listDefinitonsToc = mkOption { + type = types.nullOr types.str; + default = "gO"; + description = '' + list all definitions from the current file like a table of contents (similar to the one + you see when pressing |gO| in help files). + ''; + }; + gotoNextUsage = mkOption { + type = types.nullOr types.str; + default = ""; + description = "go to next usage of identifier under the cursor"; + }; + gotoPreviousUsage = mkOption { + type = types.nullOr types.str; + default = ""; + description = "go to previous usage of identifier"; + }; + }; + }; + }; + + config = let + cfg = config.plugins.treesitter-refactor; + in + mkIf cfg.enable { + extraPlugins = with pkgs.vimPlugins; [nvim-treesitter-refactor]; + plugins.treesitter.moduleConfig.refactor = { + highlight_definitions = { + inherit (cfg.highlightDefinitions) enable disable; + clear_on_cursor_move = cfg.highlightDefinitions.clearOnCursorMove; + }; + highlight_current_scope = cfg.highlightCurrentScope; + smart_rename = { + inherit (cfg.smartRename) enable disable; + keymaps = {smart_rename = cfg.smartRename.keymaps.smartRename;}; + }; + navigation = { + inherit (cfg.navigation) enable disable; + keymaps = let + cfgK = cfg.navigation.keymaps; + in { + goto_definition = cfgK.gotoDefinition; + goto_definition_lsp_fallback = cfgK.gotoDefinitionLspFallback; + list_definitions = cfgK.listDefinitons; + list_definitions_toc = cfgK.listDefinitonsToc; + goto_next_usage = cfgK.gotoNextUsage; + goto_previous_usage = cfgK.gotoPreviousUsage; + }; + }; + }; + }; +} diff --git a/plugins/languages/treesitter.nix b/plugins/languages/treesitter.nix index e96a68af..a76b44d8 100644 --- a/plugins/languages/treesitter.nix +++ b/plugins/languages/treesitter.nix @@ -71,6 +71,12 @@ in default = pkgs.tree-sitter.allGrammars; description = "Grammar packages to install"; }; + + moduleConfig = mkOption { + type = types.attrsOf types.anything; + default = {}; + description = "This is the configuration for extra modules. It should not be used directly"; + }; }; }; @@ -103,7 +109,7 @@ in ensure_installed = if cfg.nixGrammars then [ ] else cfg.ensureInstalled; ignore_install = cfg.ignoreInstall; parser_install_dir = cfg.parserInstallDir; - }; + } // cfg.moduleConfig; in mkIf cfg.enable { extraConfigLua = ''