Open savetheclocktower opened 5 months ago
I think that it probably would be worth it to add eslint as a language server, but I think it'd be better to have a language server base package, instead of a linter.
That in turn would resolve most of the issues which this entire repo tried to solve 🤔
I haven’t forgotten about this package; just haven’t had time to think about the best way to go forward. But after recent experiments with language servers/clients in other projects, I got the idea a few days ago to see whether this package could eventually graduate to a package that consumes ESLint as a language server.
Since that’s how VSCode’s ESLint support is delivered, I wondered if we could just use the server they wrote for VSCode, then write our own client by wrapping
atom-languageclient
. That’s how pulsar-ide-typescript-alpha was implemented and it’s been a joy to use.Here are some notes for posterity:
I spent a few hours trying to “extract” the server from this package, then finally realized I could’ve just installed this package as a dependency and run the server as a binary, completely ignoring the client side.
There were several places where I needed to make additions to
@savetheclocktower/atom-languageclient
to reflect additions to the LSP spec. That’s fine; I’m sure there are other methods that have been added since that package saw regular maintenance.Infuriatingly, there are major aspects of the language server contract — as implemented by the
vscode-languageserver
package — that are undocumented in the spec, presumably because they’re “proposed” additions to the spec. One of them is calledDiagnosticPullMode
, and it describes the frequency with which the client will request diagnostic (linting) messages from the server. Possible values areonType
andonSave
.This is an inversion of how diagnostics work in all other language servers which which I’m familiar. They assume that the server will send the client diagnostic events when they’re appropriate; indeed, that’s how
atom-languageclient
has been set up.The
textDocument/diagnostic
method is new in spec version 3.17 and is how the client asks for diagnostics from the server, but the ESLint language server expects the client to send these options governing how often the client will ask for diagnostics. If the client is in charge of this, why does the server care about it? What was wrong with the old approach?At any rate, there's a piece of magic that I haven't been able to sniff out: exactly where the client makes the
textDocument/diagnostic
request, and how it knows how often to do so. I can find where the controlling settings are defined, but not where they're actually used yet. If it's as simple as sending that method from the client every time an editor stops changing, that's fine; but I suspect it's a bit more complicated than that.Otherwise, things went somewhat smoothly. Code actions worked well once I fixed another bug in
@savetheclocktower/atom-languageclient
:Conclusion
Here’s what would have to happen if we wanted this package’s successor to be one that consumes VSCode’s ESLint language server.
In order to deliver a package that can lint on save, plus deliver suggested fixes and links to rule documentation:
atom-languageclient
to support some methods that, honestly, should be supported anyway, since they’re in the spec.pulsar-ide-eslint
that abides by the configuration options expected by the VSCode language server — which would be a bit annoying, but not hard, since the package’s main job would be to translate between our settings and the settings format VSCode uses.In order to go further and deliver a package that can lint on every change:
DiagnosticPullMode
stuff, and that feels icky.What should happen instead?
Whether they realize it or not, ESLint needs to write their own language server. That’s the direction that this discussion drifted toward (though it’s 14 months old).
The pain points with ESLint are especially acute considering how easy it was to write a Pulsar package for for Biome — a project that aims to supplant both ESLint and Prettier. The Biome folks correctly surmised that they’d need to implement their own language server in order to enjoy wide editor support. And their diagnostics — like those of all other language servers I’ve used — are initiated by the server and Just Work.
ESLint, on the other hand, is a tool that originally expected to be run against one file at a time in a terminal session, but is now mainly used in interactive fashion by developers in IDEs. One theory of mine is that this “pull” style of diagnostic retrieval only exists because the client needed to work around ESLint’s limitations (whether performance or single-file awareness) by telling the server which files needed to be linted, rather than vice-versa.
Since that won’t happen, what should we do?
I think it’s still worth trying to
stealborrowuse (it’s MIT-licensed!) some of VSCode’s ESLint code, since they’ve got support for both kinds of config files now. There might at least be some tricks or approaches we could learn from.