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)
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 atypescript-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 withkak-lsp
? Should I overloadlsp-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:
-
- need to get rid of the "preferences" prefix (in line with the docs)
-
- "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"
- 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 viaworkspace/didChangeConfiguration
, notinitializationOptions
I have also tried to move out all [language.tsx.settings._]
from kak-lsp.toml
to a hook:
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:
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)