helix
helix copied to clipboard
Use eslint for typescript
Is it possible to change the language server of typescript to eslint?
I tried making a user-level languages.toml to overwrite the typescript language to use eslint but it just acted as though no language server existed.
What does your hx --health typescript
say? And logs?
eslint isn't actually a language server but a linter?
@archseer there is also an eslint language server. It is quite common nowadays to use it along with tsserver
, which is what vscode does.
It allows code actions to fix eslint issues. It even can act as a super fast code formatter by reading your prettier
rules.
It is available on npm: https://github.com/hrsh7th/vscode-langservers-extracted
Health is all good it can find eslint. The logs however are showing helix_lsp::transport [ERROR] err: <- StreamClosed
I think these are related: https://github.com/helix-editor/helix/issues/1396, https://github.com/helix-editor/helix/pull/2507
Neovim is using https://github.com/hrsh7th/vscode-langservers-extracted for their eslint language server. I'm going to try that same binary in helix
Hey I tried this approach with the multiple language servers branch and one roadblock that I had faced was that the vscode-langservers-extracted
lsp required a property that wasn't provided by Helix.
helix_lsp::transport [ERROR] err <- "(node:13560) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'workingDirectory' of null"
@space-shell I think you may want to mention that as a new issue?
Does anyone know if its possible to use eslint just as the linter?
@archseer there is also an eslint language server. It is quite common nowadays to use it along with
tsserver
, which is what vscode does.It allows code actions to fix eslint issues. It even can act as a super fast code formatter by reading your
prettier
rules.It is available on npm: https://github.com/hrsh7th/vscode-langservers-extracted
Hi @jacksonludwig, could you explain how to configure the eslint
language server in the languages.toml
file?
@RilDev I am not sure, I can see there is an issue about it https://github.com/helix-editor/helix/issues/3520, I've not set it up myself with helix.
Not a useful comment, but this is the only one thats preventing me from using this editor. Somehow I could not get prettier also working, but thats may be my fault.
same, are there any updates or a release date for this feature?
Trying to have the same behavior as neovim and vscode for eslint
vscode-eslint-language-server
doesn't seem to work unless someone can point me in the right direction.
https://github.com/helix-editor/helix/pull/2507 will make it happen. It's in the current milestone.
Now that #2507 has been merged, does anyone have an example config of how to setup eslint?
Alright I found a working config, just waiting for code actions on save to have it work on save
# Front-end
[[language]]
name = "typescript"
scope = "source.ts"
injection-regex = "(ts|typescript)"
language-servers = [{except-features = ["format"], name = "typescript-language-server"}, "tailwindcss-react", "eslint"]
roots = ["tailwind.config.js","tailwind.config.cjs", ".prettierrc.json", ""]
file-types = ["ts", "mts", "cts"]
formatter = { command = 'prettier', args = ["--stdin-filepath", "file.ts"] }
auto-format = true
[[language]]
language-servers = [{except-features = ["format"], name = "typescript-language-server"}, "tailwindcss-react", "eslint"]
roots = ["tailwind.config.js","tailwind.config.cjs", ".prettierrc.json"]
name = "javascript"
scope = "source.js"
injection-regex = "(js|javascript)"
file-types = ["js", "mjs", "cjs"]
formatter = { command = 'prettier', args = ["--stdin-filepath", "file.js"] }
auto-format = true
[[language]]
language-servers = [{except-features = ["format"], name = "typescript-language-server"}, "tailwindcss-react", "eslint"]
roots = ["tailwind.config.js","tailwind.config.cjs", ".prettierrc.json"]
name = "jsx"
scope = "source.jsx"
injection-regex = "jsx"
file-types = ["jsx"]
formatter = { command = 'prettier', args = ["--stdin-filepath", "file.jsx"] }
indent = { tab-width = 4, unit = "\t" }
auto-format = true
[[language]]
language-servers = [{except-features = ["format"], name = "typescript-language-server"}, "tailwindcss-react" , "eslint"]
roots = ["tailwind.config.js","tailwind.config.cjs", ".prettierrc.json"]
name = "tsx"
scope = "source.tsx"
injection-regex = "(tsx)" # |typescript
file-types = ["tsx"]
formatter = { command = 'prettier', args = ["--stdin-filepath", "file.tsx"] }
auto-format = true
[[language]]
name = "html"
scope = "text.html.basic"
injection-regex = "html"
file-types = ["html"]
language-servers = ["tailwindcss-react","vscode-html-language-server"]
roots = ["tailwind.config.js","tailwind.config.cjs", ".prettierrc.json"]
auto-format = true
[[language]]
name = "css"
scope = "source.css"
injection-regex = "css"
file-types = ["css"]
language-servers = ["tailwindcss-react", "vscode-css-language-server"]
roots = ["tailwind.config.js","tailwind.config.cjs", ".prettierrc.json"]
auto-format = true
[language-server.tailwindcss-react]
language-id = "javascriptreact"
command = "hx-tw"
config = { }
args = ["--stdio"]
timeout = 3
[language-server.eslint]
args = ["--stdio"]
command = "vscode-eslint-language-server"
[language-server.eslint.config]
validate = "on"
experimental = { useFlatConfig = false }
rulesCustomizations = []
run = "onType"
problems = { shortenToSingleLine = false }
nodePath = ""
[language-server.eslint.config.codeAction]
[language-server.eslint.config.codeAction.disableRuleComment]
enable = true
location = "separateLine"
[language-server.eslint.config.codeAction.showDocumentation]
enable = true
[language-server.eslint.config.codeActionOnSave]
enable = true
mode = "fixAll"
[language-server.eslint.config.workingDirectory]
mode = "location"
[language-server.typescript-language-server]
args = ["--stdio"]
command = "typescript-language-server"
[language-server.typescript-language-server.config]
documentFormatting = false
@amritk, helix has just been a splendid example of how to design a powerful editor like nvim but without nvim's notorious difficulty to configure, which lead to the creation of various nvim distributions (not that I don't like the configurability but only when I need to deviate from the OOB experience which should just work for any language supported that is installed). I just hope that helix won't have distributions created like this in the future.
I think that in order to achieve this, stuff like that configuration you pasted above, should be included by default in helix.
Thanks to your config, I got React/TS/ESLint+Prettier to work just as it does in VSCode. Here's my config. I think the number of deviations from the standard configs of these tools/LSPs should be kept to a minimum, so the standard behavior can become the baseline. For example even helix docs suggests we don't need to set any args for prettier: https://github.com/helix-editor/helix/wiki/External-formatter-configuration#prettier
[language-server.eslint]
args = ["--stdio"] # should come by def with helix
command = "vscode-eslint-language-server"
[language-server.eslint.config]
validate = "on" # I assume this enabled eslit to validate the file, which now shows me counts for errors, warnings, etc in helix
experimental = { useFlatConfig = false } # not sure why this is here
rulesCustomizations = []
run = "onType"
problems = { shortenToSingleLine = false }
nodePath = "" # seems redundant, why do we need to override this, should get detected autom.
[language-server.eslint.config.codeAction]
[language-server.eslint.config.codeAction.disableRuleComment]
enable = true
location = "separateLine"
[language-server.eslint.config.codeAction.showDocumentation]
enable = true # why?
[language-server.eslint.config.codeActionOnSave]
enable = true
mode = "fixAll"
[language-server.eslint.config.workingDirectory]
mode = "location" # do we need to override this?
[language-server.typescript-language-server.config]
documentFormatting = false # use eslint instead, do we have to override this ourselves? I think if eslint LSP is detected and enabled, this should be done automatically for us as generally everyone lets eslint take over linting+prettying, which uses prettier by default if detected by it
[[language]]
name = "typescript"
language-servers = [{ except-features = ["format"], name = "typescript-language-server" }, "eslint"] # shouldn't need to override this
roots = ["package-lock.json", "tsconfig.json", ".prettierrc.json"] # shouldn't need to override this
formatter = { command = "prettier" }
auto-format = true
[[language]]
name = "tsx"
language-servers = [{ except-features = ["format"], name = "typescript-language-server" }, "eslint"] # shouldn't need to override this
roots = ["package-lock.json", "tsconfig.json", ".prettierrc.json"] # shouldn't need to override this!
formatter = { command = "prettier" } # works without any args, the modifications end up in the buffer, unsaved
auto-format = true
When i try to add eslint as language server it complains that it couldn't read the tsconfig.json file. It searched in the wrong folder.
My eslintConfig is part of the package.json.