kakoune-lsp / kakoune-lsp

Kakoune Language Server Protocol Client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't set options for `typescript-language-server`

rosingrind opened this issue · comments

Summary

I'm trying to pass options according to initializationOptions reference, and lsp-formatting doesn't seem to respect these.

At first, I was trying to pass convertTabsToSpaces and tabSize and I found that these type of settings are handled in a formatting request (I've mistakenly thought that this may be the reason I can't get tabSize respected when formatting): https://github.com/kak-lsp/kak-lsp/blob/12bad0b5e4e6eb0dd567701fcd02a7247f6f3ef7/rc/lsp.kak#L1179

Then I have tried to set other options such as quotePreference or format.semicolons, and this also didn't work for me. Am I doing something wrong, or is this a kak-lsp issue?

Sample kakrc config

eval %sh{ kak-lsp --kakoune --session $kak_session }

hook global WinSetOption filetype=(c|rust|javascript|typescript) %{
	lsp-enable-window

	# set-option global lsp_insert_spaces false
	try %{ lsp-inline-diagnostics-enable window }
	try %{ lsp-inlay-hints-enable window }
	try %{ lsp-inlay-code-lenses-enable window }
}

Sample kak-lsp.toml config

[language.tsx] # works for typescript as well
filetypes = ["typescript"]
roots = ["package.json", "tsconfig.json", ".git", ".hg"]
command = "typescript-language-server"
args = ["--stdio"]
settings_section = "_"
[language.tsx.settings._]
preferences.quotePreference = "double"
preferences.typescript.format.semicolons = "insert"

Sample App.tsx file

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  )
}

export default App

Info

  • typescript-language-server@3.3.2
  • typescript@5.2.2
  • kak-lsp v14.2.0
  • Kakoune v2023.08.05
  • macOS 13.5.1 (22G90)

By the way, setting language.tsx.settings._.preferences.includeInlayParameterNameHints = "all" and other inlay hints settings seems to work for me:

image

Ok, as far as I understand, all formatting with the lang-server is configured right at the request phase: https://github.com/typescript-language-server/typescript-language-server/blob/9f3e578792161095aab0eccb4c3e394dd9a4e697/src/lsp-server.ts#L800-L827

Passing all additional options (such as [key: string]: boolean | integer | string; according to spec) seems to be a job of the next piece:
https://github.com/kak-lsp/kak-lsp/blob/12bad0b5e4e6eb0dd567701fcd02a7247f6f3ef7/rc/lsp.kak#L1170-L1180

As other config options seems working to me (except the formatting ones) and logs that I've checked proof that all options are passed, it seems that this is not a kak-lsp issue. But, it's still unclear for me:

  • if setting initializationOptions should be performed under language.tsx.settings._.preferences, then it's a typescript-language-server bug (am I right?)
  • if initializationOptions for formatting are meant to pass via [key: string]: boolean | integer | string; when calling a formatting function as it's said in spec, how do I do this with kak-lsp? Should I overload lsp-formatting-request then?

https://github.com/typescript-language-server/typescript-language-server#workspacedidchangeconfiguration says that options like format.convertTabsToSpaces are controlled via workspace/didChangeConfiguration, not initializationOptions.

With your configuration, kak-lsp will send

{
  "jsonrpc": "2.0",
  "method": "workspace/didChangeConfiguration",
  "params": {
    "settings": {
      "preferences": {
        "quotePreference": "double",
        "typescript": {
          "format": {
            "semicolons": "insert"
          }
        }
      }
    }
  }
}

maybe that's different from what they expect? It looks correct to me though

One way to find out (since the docs seems ambiguous) is to check how it looks like in VSCode's settings.json (or check vscode logs).

There's a chance it's not nested objects but just a flat one; if you use this:

"preferences.quotePreference" = "double"
"preferences.typescript.format.semicolons" = "insert"

then kak-lsp will send

{
  "jsonrpc": "2.0",
  "method": "workspace/didChangeConfiguration",
  "params": {
    "settings": {
      "preferences.quotePreference": "double",
      "preferences.typescript.format.semicolons": "insert"
    }
  }
}

I don't see anything in the typescript-language-server documentation that lists options to pass to the individual formatting request (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#formattingOptions).
kak-lsp currently only supports two of those.

Ok, as far as I understand, all formatting with the lang-server is configured right at the request phase: https://github.com/typescript-language-server/typescript-language-server/blob/9f3e578792161095aab0eccb4c3e394dd9a4e697/src/lsp-server.ts#L800-L827

things like format.convertTabsToSpaces could also be applied elsewhere in the code.

ok I found out how to make format.semicolons work. Two issues:

    1. need to get rid of the "preferences" prefix (in line with the docs)
    1. "tsx" needs to be "typescript" else it won't match with the "typescript" in the config key

This works for me:

[language.typescript] # works for typescript as well
filetypes = ["typescript"]
roots = ["package.json", "tsconfig.json", ".git", ".hg"]
command = "typescript-language-server"
settings_section = "_"
args = ["--stdio"]
[language.typescript.settings._]
quotePreference = "double"
typescript.format.semicolons = "insert"
  1. means that we might need to adapt our default config. It's a shame there isn't more standardization in LSP

options like format.convertTabsToSpaces are controlled via workspace/didChangeConfiguration, not initializationOptions

I have also tried to move out all [language.tsx.settings._] from kak-lsp.toml to a hook:

https://github.com/kak-lsp/kak-lsp/blob/12bad0b5e4e6eb0dd567701fcd02a7247f6f3ef7/README.asciidoc?plain=1#L339-L347

set-option global lsp_config %{
	[language.tsx.settings._]
	preferences.quotePreference = "double"
	preferences.typescript.format.semicolons = "insert"
}

And this meant to work, but it doesnt. If I add any inlay hints related settings, they work either from kak-lsp.toml or a hook:

https://github.com/kak-lsp/kak-lsp/blob/12bad0b5e4e6eb0dd567701fcd02a7247f6f3ef7/README.asciidoc?plain=1#L319-L322

Your config sample from #693 (comment) did work for me too! But it seems that all <JSX \> tags are highlighted as errors. Is there any workaround for this now?

Edit: seems like #686 might bring a proper solution for these kind of issues

preferences.typescript.format.semicolons = "insert"

lose the "preferences.". Otherwise this should work.

But it seems that all <JSX > tags are highlighted as errors. Is there any workaround for this now?

Right, that's because the language ID is no longer tsx but typescript.
In this case we probably want to write

[language.tsx] # works for typescript as well
filetypes = ["typescript"]
roots = ["package.json", "tsconfig.json", ".git", ".hg"]
command = "typescript-language-server"
settings_section = "_"
args = ["--stdio"]
[language.tsx.settings._]
quotePreference = "double"
tsx.format.semicolons = "insert"

And ask the server vendor to support options like tsx.format.semicolons.
Maybe that will reveal a simpler solution because other LSP clients probably support this somehow.

Edit: seems like #686 might bring a proper solution for these kind of issues

Your scenario should work without that, we're only talking to a single language server here right?
Talking to the same one with two identities would be quite hacky.

Ok, thanks! I'm closing this as it's not a bug or a kak-lsp issue

The tsx files should have a typescriptreact language ID. Then the typescript.* configuration options will also apply to those.

(this should be most likely documented in typescript-language-server - PRs welcome)