Skip to content
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

Eslint/Prettier Support #5612

Closed
jamesdbruner opened this issue Jul 16, 2022 · 89 comments
Closed

Eslint/Prettier Support #5612

jamesdbruner opened this issue Jul 16, 2022 · 89 comments
Labels
enhancement [core label] eslint ESLint tooling support prettier Prettier tooling support tooling An umbrella label for language tools, linters, formatters, etc

Comments

@jamesdbruner
Copy link

I tried every way I could think of to try to get format_on_save to work with my existing eslint/prettier setup but I can't figure out how to make it work. I have a narwhal monorepo with an eslintrc.json file at the root and one in every project and have it setup to use prettier as the formatter.

In vscode and webstorm they pickup the nearest eslintrc and use those rules to format my file on save since I added these lines to my settings.json

"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
},

Here's an example of what that root eslintrc.json looks like:

{
  "root": true,
  "plugins": ["@nrwl/nx"],
  "overrides": [
    {
      "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
      "rules": {
        "@nrwl/nx/enforce-module-boundaries": [
          "error",
          {
            "enforceBuildableLibDependency": true,
            "allow": [],
            "depConstraints": [
              {
                "sourceTag": "*",
                "onlyDependOnLibsWithTags": ["*"]
              }
            ]
          }
        ]
      }
    },
    {
      "files": ["*.ts", "*.tsx"],
      "extends": [
        "plugin:@nrwl/nx/typescript",
        "plugin:prettier/recommended"
      ],
      "rules": {
        "prettier/prettier": [
          "warn",
          {
            "semi": false,
            "singleQuote": true,
            "tabs": true,
            "useTabs": true,
            "tabWidth": 1,
            "printWidth": 120,
            "endOfLine": "auto"
          }
        ]
      }
    },
    {
      "files": ["*.js", "*.jsx"],
      "extends": ["plugin:@nrwl/nx/javascript"],
      "rules": {}
    }
  ]
}

Can I use the current format_on_save setting to replicate how vscode or webstorm work in this regard? I'm probably just being dumb but would really appreciate some clarification or direction. Awesome work so far, and if I can get this figured out Zed will likely be my editor of choice for the foreseeable future.

@jamesdbruner jamesdbruner added enhancement [core label] triage Maintainer needs to classify the issue labels Jul 16, 2022
@hovsater
Copy link
Contributor

@jamesdbruner have you seen https://zed.dev/docs/javascript? It showcases an example in which you customize format_on_save to use Prettier instead.

@jamesdbruner
Copy link
Author

Yes, I've seen that yes I can get prettier to format my code by doing that. I don't think you should have to install prettier globally when I have it installed at the root of my repository and also I'd prefer to let eslint dictate how and when prettier runs I guess is my point. Is it possible to do something like this?

    "language_overrides": {
        "TypeScript": {
            "format_on_save": {
                "external": {
                    "command": "eslint",
                    "arguments": [
                        "--stdin-filepath",
                        "{buffer_path}",
                        "--fix"
                    ]
                }
            }
        }
    }

@as-cii
Copy link
Member

as-cii commented Jul 18, 2022

Thanks for the feedback, @jamesdbruner! And thanks @kevinsjoberg for providing support on this! ✨

I don't think you should have to install prettier globally when I have it installed at the root of my repository

This should already be possible, as we run the command from the root of the worktree that you opened. So you should be able to run things like npx or specify a command as a relative path node_modules/.bin/prettier. Does something like this work for you?

"language_overrides": {
    "JavaScript": {
        "format_on_save": {
            "external": {
                "command": "npx", // you could also specify "node_modules/.bin/prettier" here
                "arguments": [
                    "prettier",
                    "--stdin-filepath",
                    "{buffer_path}"
                ]
            }
        }
    }
}

also I'd prefer to let eslint dictate how and when prettier runs I guess is my point.

As for eslint, they support reading files from stdin but I am afraid they don't support reporting the fixed output on stdout. I saw they support reporting fixes as JSON to stdout, so you can probably write a simple script that invokes eslint. I was able to make it work using https://github.com/mantoni/eslint_d.js and the following configuration:

"language_overrides": {
    "JavaScript": {
        "format_on_save": {
            "external": {
                "command": "npx",
                "arguments": [
                    "eslint_d",
                    "--stdin",
                    "--stdin-filename",
                    "{buffer_path}",
                    "--fix-to-stdout"
                ]
            }
        }
    }
}

I understand this is suboptimal and we should probably support a more out-of-the-box experience, but would the above work for you?

@jamesdbruner
Copy link
Author

@as-cii Thanks so much for getting back to me! I'll try this tonight and let you know how it goes. Honestly so long as it works, I don't really mind adding configuration and considering how npx works, I believe it'll use my local eslint before reaching out to the web to download it. I think that should be a good solution until something out of the box is released.

@fnky
Copy link

fnky commented Jul 29, 2022

I tried this but the experience is not so great. Formatting takes some time since it has to boot up Node each time, and the cursor is moved the the start of the line each time after formatting.

I'm sure this will be solved with user plugins :)

@as-cii as-cii mentioned this issue Aug 1, 2022
46 tasks
@JosephTLyons JosephTLyons removed the triage Maintainer needs to classify the issue label Aug 21, 2022
@morajabi
Copy link

Should we make another issue about inline ESlint error/warning support? Personally, I'm interested in a language-server-like experience for ESLint similar to the extension for VS Code.

On another note, @fnky is right about prettier being slow when used like this.

@uicowboy
Copy link

uicowboy commented Oct 23, 2022

@morajabi Yeah +1, especially when considering how a lot of enterprise apps are built using Prettier and ESLint together. If these technologies work great out of the box, it will help with Zed's adoption.

Edit: have been using Zed for a few hours now running the formatter using Prettier, since that's what we use for all frontend projects at my company. On every save, there's a noticeable ~1s delay from the moment CMD+S is pressed to when the formatting is done. This is unfortunate, particularly because Zed is fairly speedy and this defeats that enough that it's noticeable all the time.

@victororlyk
Copy link

Should we make another issue about inline ESlint error/warning support? Personally, I'm interested in a language-server-like experience for ESLint similar to the extension for VS Code.

On another note, @fnky is right about prettier being slow when used like this.

I have created feature request for that #4901

@func0x
Copy link

func0x commented Mar 21, 2023

Maybe in here is a great person to told me how I can run this prettier on save with tsx files?

"language_overrides": {
        "TypeScript": {
            "format_on_save": {
                "external": {
                    "command": "node_modules/.bin/prettier", // this or npx and "prettier" as a first arguments
                    "arguments": [
                        "--stdin-filepath",
                        "{buffer_path}"
                    ]
                }
            }
        }
    }

When I use in terminal node_modules/.bin/prettier --write PATH_TO_FILE it's work and I assume to add this "--write" as a first argument to arguments array and to be working but it don't.

I test it changing file extension to JSX and change language in override from TypeScript to JavaScript and then everything works.... but why not work with TS?

@gh0stonio
Copy link

Hi everyone,

Thanks to all tips here how I've succeed to format properly my TSX files with both prettier and eslint rules.

Here my eslintrc:

{
    "extends": ["next/core-web-vitals"],
    "plugins": ["arca", "prettier"],
    "rules": {
        "prefer-const": "error",
        "prettier/prettier": "error",
        "arca/import-ordering": [
            "error",
            {
                "sections": [
                    "^~/",
                    "^\\.\\./",
                    "^\\./"
                ]
            }
        ],
        "arca/newline-after-import-section": [
            "error",
            {
                "sections": [
                    "^~/",
                    "^\\.\\./",
                    "^\\./"
                ]
            }
        ]
    }
}

Here my Zed settings:

{
  ...
  "language_overrides": {
        "TypeScript": {
            "format_on_save": {
                "external": {
                    "command": "node_modules/.bin/eslint_d",
                    "arguments": [
                        "--stdin",
                        "--fix",
                        "--fix-to-stdout",
                        "--stdin-filename",
                        "{buffer_path}"
                    ]
                }
            }
        },
        "TSX": {
            "format_on_save": {
                "external": {
                    "command": "node_modules/.bin/eslint_d",
                    "arguments": [
                        "--stdin",
                        "--fix",
                        "--fix-to-stdout",
                        "--stdin-filename",
                        "{buffer_path}"
                    ]
                }
            }
        }
    }
}

I'm using https://github.com/mantoni/eslint_d.js as recommended by @as-cii to be able to handle properly stdin and stdout and an eslint plugin for prettier to apply prettier formatting at the same time.

@msdrigg
Copy link

msdrigg commented Mar 27, 2023

I'm trying out zed and a bit disappointed that my .eslintrc config isn't supported for diagnostics.

My specific use case is that I am developing a next.js project and often rely on eslint warnings to catch react hooks dependency errors. If I run npm run lint to trigger a lint, it correctly detects these errors, but zed does NOT show these warnings in the editor anywhere.

I can even configure the warnings to show up as errors in .eslintrc config and they still don't show up. It appears that .eslintrc is being ignored by zed.

@iamnbutler
Copy link
Member

ESLint is very on our radar, and should be tackled soon!

@msdrigg
Copy link

msdrigg commented Mar 27, 2023

I believe eslint is already integrated into typescript-language-server, so in theory my use case should be covered by zed.dev as long as typescript-language-server supports this. I have submitted an issue there as well that may resolve this. I'll update here if anything comes from it typescript-language-server/typescript-language-server#708

@msdrigg
Copy link

msdrigg commented Mar 27, 2023

Wait — I was confused eslint Isnt integration into typescript language server at all

@tinchoz49
Copy link

tinchoz49 commented Mar 27, 2023

Wait — I was confused eslint Isnt integration into typescript language server at all

But is integrated here: https://github.com/microsoft/vscode-eslint/tree/main/server so your idea still makes sense. I mean using eslint as a LSP.

@janmonschke
Copy link

ESLint is very on our radar, and should be tackled soon!

@iamnbutler Great to hear that it's on your radar 🎉 Is there a way to track progress on planned features?

@Rados51
Copy link

Rados51 commented Apr 10, 2023

@iamnbutler Would it also be possible to group language_overrides like JavaScript|TypeScript|TSX|JSON instead of writing same config for each lang? Thanks :)

@iamnbutler
Copy link
Member

@iamnbutler Would it also be possible to group language_overrides like JavaScript|TypeScript|TSX|JSON instead of writing same config for each lang? Thanks :)

Sounds like a good idea if we can make it work. If there isn't already an issue it would be great if you could create one!

@rruzicka-inno
Copy link

Hi everyone,

Thanks to all tips here how I've succeed to format properly my TSX files with both prettier and eslint rules.

Here my eslintrc:

{
    "extends": ["next/core-web-vitals"],
    "plugins": ["arca", "prettier"],
    "rules": {
        "prefer-const": "error",
        "prettier/prettier": "error",
        "arca/import-ordering": [
            "error",
            {
                "sections": [
                    "^~/",
                    "^\\.\\./",
                    "^\\./"
                ]
            }
        ],
        "arca/newline-after-import-section": [
            "error",
            {
                "sections": [
                    "^~/",
                    "^\\.\\./",
                    "^\\./"
                ]
            }
        ]
    }
}

Here my Zed settings:

{
  ...
  "language_overrides": {
        "TypeScript": {
            "format_on_save": {
                "external": {
                    "command": "node_modules/.bin/eslint_d",
                    "arguments": [
                        "--stdin",
                        "--fix",
                        "--fix-to-stdout",
                        "--stdin-filename",
                        "{buffer_path}"
                    ]
                }
            }
        },
        "TSX": {
            "format_on_save": {
                "external": {
                    "command": "node_modules/.bin/eslint_d",
                    "arguments": [
                        "--stdin",
                        "--fix",
                        "--fix-to-stdout",
                        "--stdin-filename",
                        "{buffer_path}"
                    ]
                }
            }
        }
    }
}

I'm using https://github.com/mantoni/eslint_d.js as recommended by @as-cii to be able to handle properly stdin and stdout and an eslint plugin for prettier to apply prettier formatting at the same time.

I used this setup but prettier is not working properly. I have eslint_d installed locally in the project. When I had it globally it didn't work at all. When I changed e.g. quotes to double it didn't do anything.

"format_on_save": {
  "external": {
    "command": "node_modules/.bin/eslint_d",
    "arguments": [
      "--stdin",
      "--fix",
      "--fix-to-stdout",
      "--stdin-filename",
      "{buffer_path}"
    ]
  }
}

When I use this setup it works properly, but eslint --fix doesn't work.

"format_on_save": {
  "external": {
    "command": "node_modules/.bin/prettier",
    "arguments": [
      "--stdin-filepath",
      "{buffer_path}"
    ]
  }
}

And I don't see a way to have both configured, since I can't use an array on command.

@slingercode
Copy link

Looking forward for this integration. ATM this is my most anticipated feature and would be awesome when we can have the same interaction as in vscode 👍

@vaidotasp
Copy link

this is really needed for any dev work involving web dev, eslint language server support is definitely needed

@darcher-
Copy link

darcher- commented Jun 24, 2023

Is this really necessary?

The ability to explicitly fine-tune formatting is nice; however, a specific property name to target formatting, linting, etc. seems too granular here. Perhaps a generic approach can grant greater flexibility in this case?

As an aside

I have used the JetBrains Suite, Visual Studios Suite, Notepad/++, Brackets, All the Sublime Text editors, and currently use VSCode as my primary.

There's been quite a few others I've sampled in my career but never got into the "die hard" command line options; My input caters to editors with more interactable interfaces.

So far, I really have enjoyed using Zed and will continue to do so, which is why I'm here today!

Improve the shortcomings in other tools

I see potentially greater gains with an option to enable project-level inheritance, particularly over automatable tasks such as formatting, as a more desirable enhancement. Much of these mundane tasks are being automated with tools like Git Actions or libraries such as lint-staged or husky. This helps abstract non-prod items but it feels short-sighted and hacky, certainly does not resolve the bloat or decouple/abstract tools not required at runtime. I know I have certainly spent entirely too much of my life trying to improve .vscode/settings.json to reduce the footprint of non-prod libraries.

Bridging the gaps

Implementing something that makes those tools obsolete feels like the right goal of an IDE. Taking that a step further, if an IDE can replace any need for devDependencies or peerDependencies in package managers purely by granting the ability to relatively configure these tools you would certainly make a sizable impact on workflows. Perhaps even fully configuring these tools inside of the local .zed/settings.json.

Although everything below contradicts what I just mentioned, I have a few ideas to contribute that may help move toward what I mentioned above in a more succinct and iterative way, maybe...


Root directory assignment

An option to designate root_dir to override/dictate highest level of inheritance... could help narrow the scope for users.

NOTE: perhaps automate reference assignment to a degree?

  1. local "zedings"
    • for configs from .zed/settings.json
    • can likely reference ../node_modules/.bin or ../package.json
  2. default "zedings"
    • for configs from ~/config/zed/settings.json
    • could reference dependencies installed at the "global scope" (e.g. /usr/local)
  3. offer something similar to VSCode's Workspaces or a way to set the root and extend settings into other sub-directories (Something to accommodate monorepo with libraries, apps, & webapp code that may require different options.)
{
  "root_dir": "~/dev/web/%PROJECT_NAME%", // can reach `node_modules` and `package.json`
  "extends": "~/dev/lib/%PROJECT_NAME%" // can reach `.zed/settings.json` to use as default
}

A more generic way to augment on_save events

An option for on_save or additional options for common tasks...

NOTE: I am inept in "all things" pertaining to naming convention.

  • keyname: possibly... "run_on_save" | "on_save_hooks" | "on_save_event" | "on_save"
  • presets: perhaps...
    1. namespace:
      • e.g. "prettier" | "eslint" | "rome" | "stylelint" | "axe-linter" | "markdownlint" | "sonarlint"
        • This list will forever evolve, which is why referencing project level dependencies would be ideal.
        • Too much effort goes into reapplying configs to IDE's, projects, random tools like github, etc.
          • The ability to define "namespace" to enable options for calling a collection of plugins that already have configurations setup at the project root level would be a game changer.
          • you could then synchronously call them with ["rome", "sonarlint", "...etc"] somewhere.
      • Can use any of the following to reference deps or confgs:
        • <root_dir>/node_modules/.bin/%PACKAGE_NAME%
        • <root_dir>/package.json to find "dependencies" key-name
        • <root_dir>/%PACKAGE_NAME%/.*\\.(config\\.)?(ya?ml|[cm]?js(on)?|tsx?)
        • ../*.{js,ts,cjs,jsx,mjs,tsx,yml,json,yaml} relative/glob look-ups?
    2. reference:
      • "github" - .github/actions
      • "project" - package.json dependencies/scripts
      • "language" - file type extension specific defaults, basically automagically apply based on type of file.
      • "none" - or just null for generic default
    3. overrides: an object with necessary entries to override each setting...

NOTE: I use Rome as an example as its various use-cases better demonstrate my intentions. The three examples below encapsulate a variety of input formats. All of which, in my eyes, add value.

"on_save": {
  "scope": "project", // local reference
  "plugin": "rome", // runs "node_modules/.bin/rome"
  "command": "check", // runs "rome lint"
  "before": {
    "command": "start", // "rome start"
  },
  "arguments": [
    "--apply", // references "<root_dir>/rome.json"?
    "app", // dir
    "--use-server" // requires "rome start" to execute before, with that in mind, offering the ability to setup callahead/back hooks somehow: `before` & `after` maybe?
  ],
  "after": {
    "command": "stop", // stops server
    "delay": 200
  }
},

Offer various formats to applying configs (and things like arguments)

I'd love to see an IDE with the ability to consume .ya?ml files as configs.

Also, I think for arguments there are a few formats that could grant greater flexibility. Common approaches I've seen in the wild:

  • array: ["--write .*\\.[jt]sx?", "--config-path='config/rome.json'"]
  • string: "--apply src app --configPath \"config/rome.json\""
  • object: { "applyUnsafe": "**/*.{js,ts}", "useServer": true }
    • Boolean args may feel odd in object-style.

NOTE: Regardless of format, ensure RegExp and/or Glob pattern matching works!

Should also, perhaps, allow multiple hooks to execute on_save

"on_save": [
  {
    "scope": "global", // maybe... "global" (e.g. npx) | "project" (e.g. node_modules/.bin/) | "workspace" (e.g. think "monorepo")
    "plugin": "rome", // runs "node_modules/.bin/rome ci"
    "command": "ci", // runs format & lint
    "arguments": {
      "ci": true,
      "configPath": "./config/rome.json", // separate config file
      "applyUnsafe": "**/*.{js,ts}" // glob
    }
  },
  {
    "scope": "project", // local reference
    "plugin": "rome", // runs "node_modules/.bin/rome"
    "command": "check", // runs "rome lint"
    "before": {
      "command": "start", // "rome start"
    },
    "arguments": [
      "--apply", // references "<root_dir>/rome.json"?
      "src", // dir
      "--use-server" // requires "rome start" to execute before, setup a prerquisite hook somehow?
    ],
    "after": {
      "command": "stop", // stops server
      "delay": 200
    }
  },
  {
    "scope": null, // references "generic rome default config" or a CDN?
    "plugin": "rome", // perhaps, with no scope, it attempts "rome" & "npx rome" & "node_modules/.bin/rome"?
    "command": "format", // runs "rome format"
    "arguments": "--write . --colors=off" // regex
  }
],

Closing notes

DISCLAIMER: I do not generally do this... In-fact, this may be my first comment on a public repo, ever.

If by chance, I have done anything that violates any rules or guidelines that I conveniently failed to look for, please leave a note. I will make the necessary adjustments or whatever is required to correct the error.

Lastly, I wrote this sporadically across my work day and only lightly proofed; there may be areas that cause confusion or are repetitive. Feel free to raise anything and I'll add clarity where able if desired.

 

@ebg1223
Copy link

ebg1223 commented Jul 28, 2023

Been following this thread for a while, and am using eslint_d with prettier integration on save. Wanted to share a little trick that someone might find useful:

Use a separate eslint config file for your format on save action, so you still get the benefit of useful errors and warnings while editing, while maintaining integrated prettier on save!

Why / how / if you need details:

prettier advises to keep prettier and eslint separate, primarily because every prettier correction is interpreted as a warning / error while writing code, which can slow things down, and takes away a huge benefit of eslint: to see actual errors and warnings while you are writing. If every line is an error, they are meaningless.

To get around this, while still running eslint fix and prettier on save, use eslint_d, and create a separate .eslintrc.json files(for example, .eslintrc.json, and .eslintrc.withprettier.json).

.eslintrc is detected by zed, so should just have your lint rules you want to see in the editor.

.eslintrc.withprettier.json has all those rules, but also includes prettier:

  "plugins": [
...otherplugins,
    "prettier"
  ],
  "rules": {
    "prettier/prettier": "warn",
    "arrow-body-style": "off",
    "prefer-arrow-callback": "off",
    ...otherRules
}

Then, your formatOnSave settings will call eslint_d using the withprettier config.

  "language_overrides": {
    "TypeScript": {
      "format_on_save": "on",
      "formatter": {
        "external": {
          "command": "node_modules/.bin/eslint_d",
          "arguments": [
            "--config",
            ".eslintrc.withprettier.json",
            "--stdin",
            "--stdin-filename",
            "{buffer_path}",
            "--fix-to-stdout"
          ]
        }
      }
    },
    "JavaScript": {
      "format_on_save": "on",
      "formatter": {
        "external": {
          "command": "node_modules/.bin/eslint_d",
          "arguments": [
            "--config",
            ".eslintrc.withprettier.json",
            "--stdin",
            "--stdin-filename",
            "{buffer_path}",
            "--fix-to-stdout"
          ]
        }
      }
    },
    "TSX": {
      "format_on_save": "on",
      "formatter": {
        "external": {
          "command": "node_modules/.bin/eslint_d",
          "arguments": [
            "--config",
            ".eslintrc.withprettier.json",
            "--stdin",
            "--stdin-filename",
            "{buffer_path}",
            "--fix-to-stdout"
          ]
        }
      }
    }
  }

Just remember, when changing eslint rules, you need to make your changes to both configs. An improvement would probably be to use .eslintrc js files, then the .prettier version would import the standard, add the prettier stuff, and return a new config with prettier included. But for those of us not constantly updating our eslint rules, this works fine!

In practice, only real errors warnings are visible while editing, running a fix on one of them works well without editing formatting, and on each save, everything is fixed and formatted almost instantly!!

@LinusU
Copy link

LinusU commented Feb 1, 2024

For anyone looking to get TypeScript formatting via dprint:

{
  "language_overrides": {
    "TypeScript": {
      "format_on_save": "on",
      "formatter": {
        "external": {
          "command": "node_modules/.bin/dprint",
          "arguments": [
            "fmt",
            "--stdin",
            "{buffer_path}"
          ]
        }
      }
    }
  }
}

It's fast, but in VS Code using the dprint plugin it's instant, so this is definitively a slightly worse experience...

@shinebayar-g
Copy link

shinebayar-g commented Feb 8, 2024

It looks like Zed has some support of Prettier? While there is a prettier as a formatter option, it didn't work for me. (Did nothing)

image

Until Zed supports Prettier through native extension, external command invocation seems like a great alternative!
However, calling node or npx is too slow for me. It takes almost 1 second every time I save my file.
I found out that bun is a great alternative in this use case! It's almost instant and as fast as native VSCode extension.

  "formatter": {
    "external": {
      "command": "bunx",
      "arguments": ["prettier", "--stdin-filepath", "{buffer_path}", "--write"]
    }
  }

@stabildev
Copy link

stabildev commented Feb 23, 2024

please reopen and fix this.

    "external": {
      "command": "bunx",
      "arguments": ["prettier", "--stdin-filepath", "{buffer_path}", "--write"]
    }
  }

This is working as a workaround for now @shinebayar-g

@TudorEsan
Copy link

TudorEsan commented Feb 24, 2024

this seems to work for me

"lsp": {
"typescript-language-server": {
"initialization_options": {
"checkOnSave": {
"command": "eslint_d",
"arguments": [
"--stdin",
"--stdin-filename",
"{buffer_path}",
"--fix-to-stdout"
]
}
}
}
}

however warnings are not fixed for example:
Screenshot 2024-02-24 at 21 31 36

only errors are fixed when i save

if i run eslint_d src/app/\(login\)/login/components/UserAuthForm.tsx --fix the warnings in the screenshot are fixed

@hungify2022
Copy link

hungify2022 commented Feb 27, 2024

@stabildev @shinebayar-g
It Seems Zed supported the format by Prettier with this "formatter": "auto" config, but your discovery looks so nice.

CleanShot 2024-02-27 at 09 14 38@2x

@weskor
Copy link

weskor commented Feb 28, 2024

"language_overrides": {
    "TypeScript": {
      "format_on_save": "on",
      "formatter": {
        "external": {
          "command": "node_modules/.bin/dprint",
          "arguments": [
            "fmt",
            "--stdin",
            "{buffer_path}"
          ]
        }
      }
    }
  }

Also wondering this. I tried some different things, but could not get it work in zed. It only removes error.

@throrin19
Copy link

throrin19 commented Feb 28, 2024

Any news about that ? I wan't to use my eslint config to format, not prettier or other default formatting. It works fine in VSCode but it seems really complicated to do that in Zed. I think I have to wait before use this IDE.

I made this config :

{
  "formatter": "language_server",
  "language_overrides": {
    "TypeScript": {
      "format_on_save": {
        "external": {
          "command": "node_modules/.bin/eslint",
          "arguments": [
            "--stdin",
            "--fix",
            "--fix-to-stdout",
            "--stdin-filename",
            "{buffer_path}"
          ]
        }
      }
    },
    "JavaScript": {
      "format_on_save": {
        "external": {
          "command": "node_modules/.bin/eslint",
          "arguments": [
            "--stdin",
            "--fix",
            "--fix-to-stdout",
            "--stdin-filename",
            "{buffer_path}"
          ]
        }
      }
    }
  }
}

But when I save non correct formatted file, nothing change now

@korywka
Copy link

korywka commented Feb 28, 2024

@throrin19 I moved eslint to the new issue #4325 cause this one is closed only with prettier support despite the title 🫠

@mrnugget
Copy link
Member

Just to follow-up here: I closed #4325 because I merged changes that allow eslint fix-all to work on save.

Also see this comment on how to "turn off" prettier: #4325 (comment)

@patrykk21
Copy link

I have the same issue with eslint where it doesn't fix imports

@Moshyfawn
Copy link
Contributor

Honestly, I don't know why everyone is calling this the "VSCode killer" when it's barely on par with other editors in terms of functionality. It's a cool idea, but I'm not going to use this app until it's finished and not half-baked.

Because it's the internet, everyone is overly dramatic and you shouldn't believe everything they write 😉

There are currently 2 channels for Zed: Stable and Preview. Preview gets most of the updates at the moment, but it is a bit unstable as things can change and things are being ironed out. A bit of patience and potential contributions can help speed up the process of Zed "training to be The Killer of VSCode" lol

@ijsnow
Copy link

ijsnow commented Mar 8, 2024

I'd like to reiterate my solution above for anyone coming here still. The solution solved eslint support, including formatting with prettier, using the eslint_d daemon.

{
  "lsp": {
    "typescript-language-server": {
      "initialization_options": {
        "checkOnSave": {
          "command": "eslint_d",
          "arguments": [
            "--stdin",
            "--stdin-filename",
            "{buffer_path}",
            "--fix-to-stdout"
          ]
        }
      }
    }
  }
}

@zzzej
Copy link

zzzej commented Mar 9, 2024

I'd like to reiterate my solution above for anyone coming here still. The solution solved eslint support, including formatting with prettier, using the eslint_d daemon.

{
  "lsp": {
    "typescript-language-server": {
      "initialization_options": {
        "checkOnSave": {
          "command": "eslint_d",
          "arguments": [
            "--stdin",
            "--stdin-filename",
            "{buffer_path}",
            "--fix-to-stdout"
          ]
        }
      }
    }
  }
}

Thank you for sharing! How did you manage to make zed "respect" rules in .eslintrc.json of the local project?

@zzzej
Copy link

zzzej commented Mar 9, 2024

Update, this worked for me:

{
"languages": {
    "TypeScript": {
      "formatter": {
        "external": {
          "command": "eslint_d",
          "arguments": [
            "--stdin",
            "--stdin-filename",
            "{buffer_path}",
            "--fix-to-stdout"
          ]
        }
      }
    },
    "TSX": {
      "formatter": {
        "external": {
          "command": "eslint_d",
          "arguments": [
            "--stdin",
            "--stdin-filename",
            "{buffer_path}",
            "--fix-to-stdout"
          ]
        }
      },
      "preferred_line_length": 100
    }
}

@mrnugget
Copy link
Member

@demeralde can you expand a bit on this here?

I haven't been able to get ESLint working at all with Zed.

What have you tried? What's your setup? Do you have any steps to reproduce?

I wish it were as easy as merging one PR and it's fixed for everyone, but sadly it's not. There are a lot of different configurations that people use and VS Code (and its extensions!) have many fallbacks and different combinations that are hard to reproduce from the start. So we have to iterate and improve this bit by bit.

For others and myself ESLint works: it shows diagnostics, it fixes everything when saved. The video here isn't fake: #8496 But that doesn't mean it works with every project yet! So I need all of your help by giving me some information on how to make it work for you :)

@diegofontenelle
Copy link

diegofontenelle commented Mar 21, 2024

For anyone looking for a pure Eslint solution, without prettier or eslint_d, this did the trick for me:

"languages": {
    "JavaScript": {
      "code_actions_on_format": {
        "source.fixAll.eslint": true
      }
    },
    "TypeScript": {
      "code_actions_on_format": {
        "source.fixAll.eslint": true
      }
    }
  },
  "formatter": {
    "external": {
      "command": "eslint --fix",
      "arguments": ["fmt", "--stdin", "{buffer_path}"]
    }
  }

Another option is to use this solution #8992 (comment):

Credits to @klaframboise

"languages": {
  "JavaScript": {
    "formatter": {
      "external": {
        "command": "cat << EOF",
        "arguments": []
      }
    },
    "code_actions_on_format": {
      "source.fixAll.eslint": true
    }
  }
}

@mrnugget
Copy link
Member

@diegofontenelle that would do the same thing twice, right? What happens when you only use code_actions_on_format? What does it say in the language server logs for ESLint? (debug: open language server logs)

@diegofontenelle
Copy link

diegofontenelle commented Mar 21, 2024

@mrnugget I tried using both individually, but only combined I got eslint to properly format.

With only the languages configuration I got it to format, but it was overwritten by the LSP formatter. After adding the formatter configuration it stopped being overwritten and worked as expected.

Here is the output of the eslint server logs:

ESLint library loaded from: /Users/diegofontenelle/code/my-project/node_modules/.pnpm/eslint@8.57.0/node_modules/eslint/lib/api.js

@korywka
Copy link

korywka commented Mar 21, 2024

@diegofontenelle haven't tried but this solution looks like should work too and do not format twice the same code: #8992 (comment)

@diegofontenelle
Copy link

diegofontenelle commented Mar 21, 2024

@diegofontenelle haven't tried but this solution looks like should work too and do not format twice the same code: #8992 (comment)

Indeed it does work as well, thanks! I will add it to my original answer

@mrnugget
Copy link
Member

Got it thanks! Yes, we need a way to only format with code actions.

@dev-abota
Copy link

dev-abota commented Mar 22, 2024

Is there a way to support stylelint formatting on a vue file, when saving?

@mrnugget
Copy link
Member

@dev-abota you can always shell out to a formatter: https://zed.dev/docs/javascript#code-formatting Would that help? Sorry, not super familiar with stylelint or vue.

@throrin19
Copy link

throrin19 commented Mar 29, 2024

I have already problem in latest main zed version.

Eslint format correctly file but directly after that, prettier launch it as you can see in this capture :

Kapture 2024-03-29 at 13 18 18

In log I can't seend eslint do something but I saw pretier do formatting :

stderr: Resolved config: {}, will format file 'repo/stacks/alerts/tests/handlers/alerts-cleanup-api.test.ts' with options: {"printWidth":80,"tabWidth":4,"plugins":[],"parser":"typescript","filepath":"repo/stacks/alerts/tests/handlers/alerts-cleanup-api.test.ts"}

This is my config :

// Zed settings
//
// For information on how to configure Zed, see the Zed
// documentation: https://zed.dev/docs/configuring-zed
//
// To see all of Zed's default settings without changing your
// custom settings, run the `open default settings` command
// from the command palette or from `Zed` application menu.
{
    "features": {
        "copilot": false
    },
    "tab_size": 4,
    "ui_font_size": 16,
    "buffer_font_size": 16,
    "terminal": {
        "font_size": 11
    },
    "languages": {
        "JavaScript": {
            "code_actions_on_format": {
                "source.fixAll.eslint": true
            }
        },
        "TypeScript": {
            "code_actions_on_format": {
                "source.fixAll.eslint": true
            }
        }
    },
    "show_whitespaces": "all",
    "show_wrap_guides": true,
    "show_completion_documentation": true
}

But, If I save file twice, the second time only eslint formatting is made 😨 :

Kapture 2024-03-29 at 13 22 10

There's really no way to just say, I don't want to prettier at all, disable it?

Edit :

I change my config and set formatter to language_server, but after that, I have already the problem if I save file twice with no reason. All my logs are empty, I don't know how to find information about it :

Kapture 2024-03-29 at 13 28 25

Edit 2 :

I found how to fix that. I have to set formatter to :

"formatter": {
        "external": {
            "command": "cat << EOF",
            "arguments": []
        }
    }

But after that I have an error in zed footer :

image

@joshkent94
Copy link

I have the same issue on the below version:

Zed: v0.128.3 (Zed)
OS: macOS 14.3.1
Memory: 8 GiB
Architecture: aarch64

It seems prettier is clashing with ESLint, there's a flicker when saving.

In the prettier LSP logs I have:

stderr: Resolved config: {"tabWidth":4,"singleQuote":true,"arrowParens":"always","bracketSpacing":true,"printWidth":120,"jsxBracketSameLine":true,"semi":true,"trailingComma":"none","quoteProps":"consistent"}

and in my settings.json I have:

"languages": {
"JavaScript": {
"code_actions_on_format": {
"source.fixAll.eslint": true
}
},
"TypeScript": {
"code_actions_on_format": {
"source.fixAll.eslint": true
}
},
"Vue.js": {
"code_actions_on_format": {
"source.fixAll.eslint": true
}
}
}

When saving, it seems my ESLint config is applied, but then the prettier config is applied afterwards, leaving me with ESLint errors.

@mrnugget
Copy link
Member

mrnugget commented Apr 2, 2024

Yeah, there's no way to only format via code actions. I'll try to add something this week.

@hungify2022
Copy link

I want to use Zed and VS Code interchangeably because some features in Zed don't exist. How can I configure Zed to get similar results to VS Code?

@raoulkent
Copy link

@hungify2022 I think you will need to wait quite a bit longer. There are a lot of features present in VSCode that will take some time to develop. And there is a massive number of plugins to VSCode that it is unrealistic to expect the same level of customisability within the near future.

Hang tight and if you want try to contribute?

@mrnugget
Copy link
Member

Just to record this here: I merged #10121 which adds ability to only format via code actions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement [core label] eslint ESLint tooling support prettier Prettier tooling support tooling An umbrella label for language tools, linters, formatters, etc
Projects
None yet
Development

No branches or pull requests