Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default language server settings for TypeScript/Eslint/Prettier #7079

Closed
cd-a opened this issue May 19, 2023 · 9 comments
Closed

Default language server settings for TypeScript/Eslint/Prettier #7079

cd-a opened this issue May 19, 2023 · 9 comments
Labels
A-language-support Area: Support for programming/text languages C-enhancement Category: Improvements

Comments

@cd-a
Copy link
Contributor

cd-a commented May 19, 2023

First of all, thank you for all involved, especially @Philipp-M for getting #2507 merged. Epic.

Since the multiple language servers are now implemented, we can work with TypeScript/Eslint/Prettier. We do need some config to set it up though.

In the thread of #2507 it was discussed to add some sane defaults to make it work out of the box.

There have been some configs posted in the PR, but do we already have a consensus of what's the best way to set it up?

@cd-a cd-a added the C-enhancement Category: Improvements label May 19, 2023
@LeoniePhiline
Copy link
Contributor

LeoniePhiline commented May 19, 2023

Side note: Using prettier (similarly, eslint --fix) as formatter was already supported:

[[language]]
name = "javascript"
formatter = { command = 'prettier', args = ["--parser", "typescript"] }
# auto-format = true

However, since formatters are an opinionated matter, you would hardly see built-in defaults for that. Users will always need to configure formatters in their languages.toml.

An idea to add some day might be config presets, e.g. packaged configuration which enables prettier for all languages it supports. this feature would be independent of #2507, though.

I believe prettier has no language server capabilities.


TypeScript language server already has default configuration: https://github.com/helix-editor/helix/blob/master/languages.toml#L117-L138

@kirawi kirawi added the A-language-support Area: Support for programming/text languages label May 19, 2023
@cd-a
Copy link
Contributor Author

cd-a commented May 19, 2023

Hmm in that case the least we should do is add a working example for this to the documentation, since those 3 are the staple for JS/TS work.

@Philipp-M
Copy link
Contributor

An idea to add some day might be config presets

Yeah that makes sense I think, though I'm not sure how that would look like in practice...

But it certainly makes sense to add some ready-to-copy-paste examples in the wiki for common configurations like eslint + + tsserver.

FWIW this is what I'm using for eslint currently (maybe I'll add this in the wiki at some time, if no-one else does in the meantime):

[language-server.eslint]
args = ["--stdio"]
command = "vscode-eslint-language-server"

[language-server.eslint.config]
format = true
nodePath = ""
onIgnoredFiles = "off"
packageManager = "yarn"
quiet = false
rulesCustomizations = []
run = "onType"
useESLintClass = false
validate = "on"
codeAction = { disableRuleComment = { enable = true, location = "separateLine" }, showDocumentation = { enable = true } }
codeActionOnSave = { mode = "all" }
experimental = { }
problems = { shortenToSingleLine = false }
workingDirectory = { mode = "auto" }

I'm using prettier via efm-langserver like this:

[language-server.efm-lsp-prettier]
command = "efm-langserver"

[language-server.efm-lsp-prettier.config]
documentFormatting = true

[language-server.efm-lsp-prettier.config.languages]
[[language-server.efm-lsp-prettier.config.languages.javascript]]
formatCommand = "prettier --stdin-filepath ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.javascriptreact]]
formatCommand = "prettier --stdin-filepath ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.json]]
formatCommand = "prettier --stdin-filepath ${INPUT}"
formatStdin = true

#...

Not sure if there's a semantical difference to using it via the formatter option in language but it's working for me well (with project specific prettier configurations).

Here's a project with eslint + eslint-prettier enforced rules, that's working well with the above config: https://github.com/Philipp-M/tree-sitter-yuck/ Might be of interest for some.

@tauseefk
Copy link

@Philipp-M been reading up your comments about eslint integration and the docs on master so appreciate the great work!
I use helix when I write code, but use vscode to actually format before pushing to version control. Today I built hx from source so I can finally use the setup (with multiple language servers) just like you mention here.

I'm wondering if it's possible to use eslint with prettier plugins, more specifically use eslint to fix the linting issues along with formatting.

I do see eslint errors when I write code that doesn't fit my prettier config, but I can't fix it using the format command.
I've tried replacing the prettier command in the efm-lsp config with eslint --fix --stdin --stdin-filename ${INPUT}", but that doesn't do anything AFAIK. My familiarity with efm or LSPs in general is non-existent so I'm not sure which parts are magic and which are configurable.

Config files that I've been using:

.eslintrc.cjs

module.exports = {
  env: { browser: true, es2020: true },
  extends: [
    'eslint:recommended',
    'plugin:prettier/recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:react-hooks/recommended',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
  plugins: ['react-refresh'],
  rules: {
    'react-refresh/only-export-components': 'warn',
  },
  ignorePatterns: ['.eslintrc.cjs'],
}

languages.toml

...
# the above part is similar to yours

[[language]]
name = "typescript"
language-servers = [ { name = "eslint" , except-features = [ "format" ] }, "efm-lsp-prettier" ]


[[language]]
name = "tsx"
language-servers = [ { name = "eslint" , except-features = [ "format" ] }, "efm-lsp-prettier" ]

@cd-a
Copy link
Contributor Author

cd-a commented Jun 21, 2023

@tauseefk code actions on save, what is needed to run eslint auto fix, is being handled in #6486

@dextermb
Copy link

Hey gang, is there any progress here?

I'm trying to get eslint and prettier picking up project configuration files but I'm having a hard time. I'm fairly new to configuring these sorts of things.

I'm trying to use efm-langserver to trigger both:

  • eslint
  • prettierd

Here's the languages.toml:

#####
#
# efm-lsp-eslint
#
#####

[language-server.efm-lsp-eslint]
command = "efm-langserver"

[language-server.efm-lsp-eslint.config]
documentFormatting = true

[[language-server.efm-lsp-prettier.config.languages.javascript]]
formatCommand ="eslint --stdin-filename ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.react]]
formatCommand ="eslint --stdin-filename ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.typescript]]
formatCommand ="eslint --stdin-filename ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.typescriptreact]]
formatCommand ="eslint --stdin-filename ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.css]]
formatCommand ="eslint --stdin-filename ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.scss]]
formatCommand ="eslint --stdin-filename ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.html]]
formatCommand ="eslint --stdin-filename ${INPUT}"
formatStdin = true

#####
#
# efm-lsp-prettier
#
#####

[language-server.efm-lsp-prettier]
command = "efm-langserver"

[language-server.efm-lsp-prettier.config]
documentFormatting = true

[[language-server.efm-lsp-prettier.config.languages.javascript]]
formatCommand ="prettierd --stdin-filepath ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.react]]
formatCommand ="prettierd --stdin-filepath ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.typescript]]
formatCommand ="prettierd --stdin-filepath ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.typescriptreact]]
formatCommand ="prettierd --stdin-filepath ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.css]]
formatCommand ="prettierd --stdin-filepath ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.scss]]
formatCommand ="prettierd --stdin-filepath ${INPUT}"
formatStdin = true

[[language-server.efm-lsp-prettier.config.languages.html]]
formatCommand ="prettierd --stdin-filepath ${INPUT}"
formatStdin = true

#####
#
# languages
#
#####

[[language]]
name = "javascript"
auto-format = true
language-servers = [
  { name = "efm-lsp-prettier", only-features = [ "format" ] },
  { name = "efm-lsp-eslint", only-features = [ "format" ] },
  { name = "typescript-language-server", except-features = [ "format" ] }
]

[[language]]
name = "jsx"
auto-format = true
language-servers = [
  { name = "efm-lsp-prettier", only-features = [ "format" ] },
  { name = "efm-lsp-eslint", only-features = [ "format" ] },
  { name = "typescript-language-server", except-features = [ "format" ] }
]

[[language]]
name = "typescript"
auto-format = true
language-servers = [
  { name = "efm-lsp-prettier", only-features = [ "format" ] },
  { name = "efm-lsp-eslint", only-features = [ "format" ] },
  { name = "typescript-language-server", except-features = [ "format" ] }
]

[[language]]
name = "tsx"
auto-format = true
language-servers = [
  { name = "efm-lsp-prettier", only-features = [ "format" ] },
  { name = "efm-lsp-eslint", only-features = [ "format" ] },
  { name = "typescript-language-server", except-features = [ "format" ] }
]

[[language]]
name = "css"
auto-format = true
language-servers = [
  { name = "efm-lsp-prettier", only-features = [ "format" ] },
  { name = "vscode-css-language-server", except-features = [ "format" ] }
]

[[language]]
name = "scss"
auto-format = true
language-servers = [
  { name = "efm-lsp-prettier", only-features = [ "format" ] },
  { name = "vscode-css-language-server", except-features = [ "format" ] }
]

[[language]]
name = "html"
auto-format = true
language-servers = [
  { name = "efm-lsp-prettier", only-features = [ "format" ] },
  { name = "vscode-css-language-server", except-features = [ "format" ] }
]

But I can't seem to figure out what's going wrong. Happy to help provide debugging information.

@Philipp-M
Copy link
Contributor

You probably don't want to use efm-langserver at least for eslint.
I'm not sure about formatting, but since there's a dedicated language.formatter key you may try this.

There were a few configurations regarding eslint (e.g. in my other comment here).
I also wouldn't disable all other features than format in eslint (i.e. only-features = [ "format" ]), I haven't disabled any features for eslint.
At least right now, formatting uses the first language-server that supports it, prioritized in the order of the language-servers array (which may change in the future), so your eslint configuration has no effect, since it will never be used.

@SalmanEsketchers
Copy link

[language-server.eslint.config]
format = true
nodePath = ""
onIgnoredFiles = "off"
packageManager = "yarn"
quiet = false
rulesCustomizations = []
run = "onType"
useESLintClass = false
validate = "on"
codeAction = { disableRuleComment = { enable = true, location = "separateLine" }, showDocumentation = { enable = true } }
codeActionOnSave = { mode = "all" }
experimental = { }
problems = { shortenToSingleLine = false }
workingDirectory = { mode = "auto" }

Can you tell us the source of these config options? Thanks.

@Philipp-M

@Philipp-M
Copy link
Contributor

Mostly from neovims lsp-config, but I've also digged a little bit in the source code of the vscode-eslint-language-server itself.

@helix-editor helix-editor locked and limited conversation to collaborators Apr 30, 2024
@pascalkuthe pascalkuthe converted this issue into discussion #10645 Apr 30, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
A-language-support Area: Support for programming/text languages C-enhancement Category: Improvements
Projects
None yet
Development

No branches or pull requests

7 participants