From 56b1082525741c62677c4f1fd4ac5dac2d4872e2 Mon Sep 17 00:00:00 2001 From: garaiza-93 <57430880+garaiza-93@users.noreply.github.com> Date: Fri, 26 Jan 2024 07:41:10 -0600 Subject: [PATCH] plugins/typescript-tools: init (#966) --- plugins/default.nix | 1 + plugins/languages/typescript-tools.nix | 178 ++++++++++++++++++ .../plugins/languages/typescript-tools.nix | 30 +++ 3 files changed, 209 insertions(+) create mode 100644 plugins/languages/typescript-tools.nix create mode 100644 tests/test-sources/plugins/languages/typescript-tools.nix diff --git a/plugins/default.nix b/plugins/default.nix index 03157e15..b514ff0c 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -68,6 +68,7 @@ ./languages/treesitter/ts-autotag.nix ./languages/treesitter/ts-context-commentstring.nix ./languages/typst/typst-vim.nix + ./languages/typescript-tools.nix ./languages/vim-slime.nix ./languages/vimtex.nix ./languages/zig.nix diff --git a/plugins/languages/typescript-tools.nix b/plugins/languages/typescript-tools.nix new file mode 100644 index 00000000..671fb4a5 --- /dev/null +++ b/plugins/languages/typescript-tools.nix @@ -0,0 +1,178 @@ +{ + lib, + pkgs, + helpers, + config, + ... +}: +with lib; let + cfg = config.plugins.typescript-tools; +in { + options.plugins.typescript-tools = { + enable = mkEnableOption "typescript-tools"; + package = + helpers.mkPackageOption "typescript-tools" + pkgs.vimPlugins.typescript-tools-nvim; + + onAttach = + helpers.defaultNullOpts.mkLuaFn "__lspOnAttach" + "Lua code to run when tsserver attaches to a buffer."; + handlers = mkOption { + type = with helpers.nixvimTypes; nullOr (attrsOf strLuaFn); + apply = v: helpers.ifNonNull' v (mapAttrs (_: helpers.mkRaw) v); + default = null; + description = "How tsserver should respond to LSP requests"; + example = { + "textDocument/publishDiagnostics" = '' + require("typescript-tools.api").filter_diagnostics( + -- Ignore 'This may be converted to an async function' diagnostics. + { 80006 } + ) + ''; + }; + }; + + settings = { + separateDiagnosticServer = + helpers.defaultNullOpts.mkBool true + "Spawns an additional tsserver instance to calculate diagnostics"; + + publishDiagnosticOn = + helpers.defaultNullOpts.mkEnum ["change" "insert_leave"] + "insert_leave" '' + Either "change" or "insert_leave". Determines when the client asks the server about diagnostics + ''; + + exposeAsCodeAction = mkOption { + type = with types; + either (enum ["all"]) (listOf (enum [ + "fix_all" + "add_missing_imports" + "remove_unused" + "remove_unused_imports" + "organize_imports" + "insert_leave" + ])); + default = []; + description = "Specify what to expose as code actions."; + }; + + tsserverPath = helpers.mkNullOrStr '' + Specify a custom path to `tsserver.js` file, if this is nil or file under path + doesn't exist then standard path resolution strategy is applied + ''; + + tsserverPlugins = with helpers.nixvimTypes; + helpers.mkNullOrOption (listOf (maybeRaw str)) '' + List of plugins for tsserver to load. See this plugins's README + at https://github.com/pmizio/typescript-tools.nvim/#-styled-components-support + ''; + + tsserverMaxMemory = helpers.mkNullOrOption (with helpers.nixvimTypes; + maybeRaw (either ints.unsigned (enum ["auto"]))) '' + This value is passed to: https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-megabytes + Memory limit in megabytes or "auto"(basically no limit) + ''; + + tsserverFormatOptions = mkOption { + type = with types; nullOr (attrsOf anything); + default = null; + description = "Configuration options that well be passed to the tsserver instance. Find available options [here](https://github.com/microsoft/TypeScript/blob/v5.0.4/src/server/protocol.ts#L3418)"; + example = { + "tsserver_file_preferences" = '' + { + includeInlayParameterNameHints = "all", + includeCompletionsForModuleExports = true, + quotePreference = "auto", + ... + } + ''; + }; + }; + + tsserverFilePreferences = mkOption { + type = with types; nullOr (attrsOf anything); + default = null; + description = "Configuration options that well be passed to the tsserver instance. Find available options [here](https://github.com/microsoft/TypeScript/blob/v5.0.4/src/server/protocol.ts#L3439)"; + example = { + "tsserver_format_options" = '' + { + allowIncompleteCompletions = false, + allowRenameOfImportPath = false, + ... + }''; + }; + }; + + tsserverLocale = helpers.defaultNullOpts.mkStr "en" '' + Locale of all tsserver messages. Supported locales here: https://github.com/microsoft/TypeScript/blob/3c221fc086be52b19801f6e8d82596d04607ede6/src/compiler/utilitiesPublic.ts#L620 + ''; + + completeFunctionCalls = helpers.defaultNullOpts.mkBool false '' + Mirror of VSCode's `typescript.suggest.completeFunctionCalls` + ''; + + includeCompletionsWithInsertText = helpers.defaultNullOpts.mkBool true '' + Mirror of VSCode's `typescript.suggest.completeFunctionCalls` + ''; + + codeLens = + helpers.defaultNullOpts.mkEnum [ + "off" + "all" + "implementations_only" + "references_only" + ] "off" + "WARNING: Experimental feature also in VSCode, disabled by default because it might impact server performance."; + + disableMemberCodeLens = helpers.defaultNullOpts.mkBool true '' + By default code lenses are displayed on all referencable values. Display less by removing member references from lenses. + ''; + + jsxCloseTag = { + enable = helpers.defaultNullOpts.mkBool false '' + Functions similarly to `nvim-ts-autotag`. This is disabled by default to avoid conflicts. + ''; + filetypes = + helpers.defaultNullOpts.mkListOf types.str + ''["javascriptreact" "typescriptreact"]'' '' + Filetypes this should apply to. + ''; + }; + }; + }; + config = mkIf cfg.enable { + extraPlugins = with pkgs.vimPlugins; [ + cfg.package + plenary-nvim + nvim-lspconfig + ]; + + plugins.lsp.postConfig = with cfg; let + options = { + inherit handlers; + on_attach = onAttach; + + settings = with settings; { + separate_diagnostic_server = separateDiagnosticServer; + publish_diagnostic_on = publishDiagnosticOn; + expose_as_code_action = exposeAsCodeAction; + tsserver_path = tsserverPath; + tsserver_plugins = tsserverPlugins; + tsserver_max_memory = tsserverMaxMemory; + tsserver_format_options = tsserverFormatOptions; + tsserver_file_preferences = tsserverFilePreferences; + tsserver_locale = tsserverLocale; + complete_function_calls = completeFunctionCalls; + include_completions_with_insert_text = + includeCompletionsWithInsertText; + code_lens = codeLens; + disable_member_code_lens = disableMemberCodeLens; + jsx_close_tag = with jsxCloseTag; {inherit enable filetypes;}; + }; + }; + in '' + require('typescript-tools').setup(${helpers.toLuaObject options}) + ''; + }; +} diff --git a/tests/test-sources/plugins/languages/typescript-tools.nix b/tests/test-sources/plugins/languages/typescript-tools.nix new file mode 100644 index 00000000..4e0fd76c --- /dev/null +++ b/tests/test-sources/plugins/languages/typescript-tools.nix @@ -0,0 +1,30 @@ +{ + empty = {plugins.typescript-tools.enable = true;}; + + # Upstream defaults (couldn't find defaults for on_attach or handlers) + + defaults = { + plugins.typescript-tools = { + enable = true; + settings = { + separateDiagnosticServer = true; + publishDiagnosticOn = "insert_leave"; + exposeAsCodeAction = null; + tsserverPath = null; + tsserverPlugins = null; + tsserverMaxMemory = "auto"; + tsserverFormatOptions = null; + tsserverFilePreferences = null; + tsserverLocale = "en"; + completeFunctionCalls = false; + includeCompletionsWithInsertText = true; + codeLens = "off"; + disableMemberCodeLens = true; + jsxCloseTag = { + enable = false; + filetypes = ["javascriptreact" "typescriptreact"]; + }; + }; + }; + }; +}