Skip to content

Support textDocument/diagnostic specification (Pull diagnostics)#11315

Merged
the-mikedavis merged 7 commits intohelix-editor:masterfrom
SofusA:pull-diagnostics
Sep 23, 2025
Merged

Support textDocument/diagnostic specification (Pull diagnostics)#11315
the-mikedavis merged 7 commits intohelix-editor:masterfrom
SofusA:pull-diagnostics

Conversation

@SofusA
Copy link
Contributor

@SofusA SofusA commented Jul 25, 2024

Closes #7757, if workspace diagnostics is not a requirement. I have not yet found a language server which supports this capability.

Handling of response was originally done by @woojiq in #7900. I was not able to include their git history since their branch has been deleted.

Tested with language servers:

  • eslint version >4.10.0
  • csharp-language-sever version >4.12.0
  • ruby-lsp
  • rust-analyzer version >2025-03-03

Diagnostics are pulled when a document is changed for each language server with pull diagnostics feature with an async hook after a debounce period.

Diagnostics are also pulled when a document is opened, when changed to buffer and when a language server is successfully initiated. This is done without debounce.

@SofusA SofusA marked this pull request as ready for review August 3, 2024 20:49
@the-mikedavis the-mikedavis added the A-language-server Area: Language server client label Aug 4, 2024
@archseer archseer requested a review from pascalkuthe August 9, 2024 10:34
@SofusA
Copy link
Contributor Author

SofusA commented Aug 12, 2024

Thanks again for the reviews!
I added your comments and did some refactoring. I closed the conversations, i am sorry if it is usually the reviewer who does this.

The request is currently only being send on document changes, which makes a terrible user experience 😄

Is there a way to send this request when a document is opened, or should a workspace diagnostic event be send when the language server (which supports this feature) is started?

Edit: By the way, i am using this branch daily for C# development, since it allows me to use the same language server as the C# vscode extension. So i am keeping the branch up to date with master branch. Let me know if the merge commits is making too much noise.

@SofusA
Copy link
Contributor Author

SofusA commented Aug 13, 2024

I did some experiments with this on roslyn language server. It might be that this language server just behaves weird (which it does on other stuff), but sending workspace/diagnostic after the server is initiated always resulted in and empty diagnostic list. Also with some seconds delay.

I also noticed that responses can either be a full or an related unchanged document report. At the moment, since we only listening on changes, we only get the full reports. This means that when i eg. rename something, i will not see diagnostics on related documents until i make a change.

I am not sure if the specification suggest to pull diagnostics every time a document is viewed, or if we should pull diagnostics for all open documents on changes to a document.

Edit: Pulling diagnostics for all open documents seems to work fine actually.

@SofusA
Copy link
Contributor Author

SofusA commented Aug 13, 2024

My plan is to send pull diagnostics request:

  1. When current document is edited for all open documents, if possible where other documents has same active language server by id as edited document
  2. When a new document is opened

@SofusA
Copy link
Contributor Author

SofusA commented Aug 15, 2024

Edit: This is no outdated.
I now pull diagnostics when a document has changed for that document for each language server with pull diagnostics feature. This is done with a async hook with a debounce.

I also pull blocking when a document is opened or changed to buffer.

I chose this model because i thought pulling for all open documents on edit was too aggressive.

I have now added two events: *Pull diagnostics for documents* Trigger: When documents are opened Document ids are collected in a hashset After a short debounce all documents pull from all its language servers with pull diagnostics support.

Pull diagnostics for language servers
Trigger: When document are saved
Language server ids with pull diagnostics support from saved document are collected in a hashset.
After a longer debounce all language servers for all open document are pulled

Document ids are being passed around, and i do some cloning of ids.

Overall it appears to work well. At least better than the first implementation with idle timeout.

SofusA

This comment was marked as duplicate.

@lizclipse
Copy link
Contributor

I've been trying this PR to see if it'll solve some issues using the ESLint LS from vscode-langservers-extracted, and I've run into a couple of bugs. Firstly, if you open a file directly using the CLI args, then the diagnostics won't show, and instead you have to close the buffer and re-open via the file picker. Secondly, and most noticable I think, if I then close this buffer and try to re-open it again then I get a crash:

thread 'main' panicked at helix-term/src/handlers/diagnostics.rs:144:19:
no entry found for key
stack backtrace:
   0: rust_begin_unwind
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_display
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/core/src/panicking.rs:168:5
   3: core::panicking::panic_str
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/core/src/panicking.rs:152:5
   4: core::option::expect_failed
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/core/src/option.rs:1988:5
   5: helix_term::handlers::diagnostics::pull_diagnostics_for_documents
   6: helix_term::job::Jobs::handle_callback
   7: helix_term::application::Application::run::{{closure}}
   8: tokio::runtime::park::CachedParkThread::block_on
   9: tokio::runtime::runtime::Runtime::block_on
  10: hx::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Of note, you do have to be using vscode-langservers-extracted@>=4.9.0 (I'm testing on 4.10.0), as that's when they changed something to stop the LS working originally, and is why I'm trying this.

@SofusA
Copy link
Contributor Author

SofusA commented Aug 17, 2024

Thanks for testing!

Firstly, if you open a file directly using the CLI args, then the diagnostics won't show, and instead you have to close the buffer and re-open via the file picker.

I see the same behaviour with roslyn language server. I think this is because we are requesting diagnostics before the language server is ready. I was hoping that this would be the language servers responsibility. I am not sure what to do about this.
Diagnostics will be requested if you make a change to the document

Secondly, and most noticable I think, if I then close this buffer and try to re-open it again then I get a crash

I fixed this by skipping the diagnostics request if the document id is not in the editor.
I am not sure if this is the best solution.

Edit:

Of note, you do have to be using vscode-langservers-extracted@>=4.9.0 (I'm testing on 4.10.0), as that's when they changed something to stop the LS working originally, and is why I'm trying this.

I am actually (without knowing) been using vscode-eslint-language-server version 4.10.0 on this branch. It is working for me with pull diagnostics. @lizclipse Can you check if it work with my latest changes?

@lizclipse
Copy link
Contributor

It looks like the crash is fixed now, thank you. I'd be curious on why the diagnostic request is trying to happen on a missing document ID (is there a memory leak somewhere?), but a little defensive programming didn't hurt anyone.

I've been testing this PR against v4.10.0 and so far it's been working (unlike the master branch, since eslint needs this now I think), although I am still getting the issue where it doesn't pick up the first open file. With my testing just now, it seems that it also doesn't pick up if you open helix blank and then open a file via the picker, you then have to re-open the file (or make an edit) before it starts showing anything. IMO I think functionally it's fine for this PR, but it may be worth opening an issue afterwards as a follow-up to at least document that this is known dodgey behaviour.

@SofusA
Copy link
Contributor Author

SofusA commented Aug 18, 2024

I looked into it, and i am not sending the pull diagnostics request, because of a race between the event, and the launching the language server (and registering capabilities). The event wins 😄
In sequent events (open or edit) the language server will be initiated and capabilities are registered.

I have not found a good solution for this, which i find very annoying.
I have found a somewhat hacky solution, where i dispatch the DocumentDidOpen again after a language sever is initialized.

It looks like the crash is fixed now, thank you. I'd be curious on why the diagnostic request is trying to happen on a missing document ID (is there a memory leak somewhere?), but a little defensive programming didn't hurt anyone.

I am not completely sure why. I think part of it was because i was doing this asynchronous, where i collected all document_ids in a hashset, and then send all notifications after a debounce. I changed this to a synchronous hook instead.

@SofusA SofusA marked this pull request as draft August 19, 2024 05:34
@SofusA SofusA marked this pull request as ready for review August 19, 2024 19:26
@SofusA
Copy link
Contributor Author

SofusA commented Aug 19, 2024

I did some experiments with diagnostics refresh, but it does not look like the language servers that I use send this notification. I was hoping this would be sent when the language server is ready to receive pull diagnostic requests.

@SofusA
Copy link
Contributor Author

SofusA commented Aug 22, 2024

I started to implement workspace diagnostics, but the language servers that i use don't responds to this request. Eslint returns an error and roslyn returns an empty array. So not much to work with here.

I also think that this will be difficult to get to work in helix, because we would need the diagnostics picker to await the async request before displaying, or we would need a way to refresh diagnostics in the picker when the request has finished.
So i am leaving this feature, at least unless someone can guide me in the right direction.

I got refresh diagnostics working though

jming422 added a commit to jming422/mac-config that referenced this pull request Aug 22, 2024
See helix-editor/helix#11506, until
helix-editor/helix#11315 lands I have to stay on
vscode-langservers-extracted 4.8.0 or older
@ssiltanen
Copy link
Contributor

eslint version 4.10.0
Eslint returns an error

Have you tried building a newer version of Microsoft/vscode-eslint? Since you referred to version 4.10.0, I imagine you are using the build from hrsh7th/vscode-langservers-extracted, which took a non-release commit from main at its build time.

@SofusA
Copy link
Contributor Author

SofusA commented Sep 1, 2024

eslint version 4.10.0
Eslint returns an error

Have you tried building a newer version of Microsoft/vscode-eslint? Since you referred to version 4.10.0, I imagine you are using the build from hrsh7th/vscode-langservers-extracted, which took a non-release commit from main at its build time.

No i have only tried vscode-langservers-extracted from nixpkgs.

But this would require some refactoring of the diagnostics picker, and i think it should be in a separate pull request

@the-mikedavis
Copy link
Member

See the symbol picker for an example of a picker that waits on an LSP request. The workspace symbol picker is maybe also a good example but it's a sort of "dynamic picker" that re-requests symbols as you type with follow-up requests to the language server.

@SofusA
Copy link
Contributor Author

SofusA commented Sep 1, 2024

See the symbol picker for an example of a picker that waits on an LSP request. The workspace symbol picker is maybe also a good example but it's a sort of "dynamic picker" that re-requests symbols as you type with follow-up requests to the language server.

Okay it does not look that difficult. I have however not been able to get response from roslyn language server. I will try again with a newer version of eslint language server next week.

Edit: Okay i gave it a very low effort shot using this fork which has a nix flake i could use.

I looked at the capability responses from the 3 language servers i know of that supports pull diagnostics: ruby-lsp, vscode-eslint´ and Microsoft.CodeAnalysis.LanguageServer(akaroslyn-ls`. Unfortunately only the roslyn language server supports this at the time of writing, and it does not give me a reliable response.

A workaround could be to request diagnostics for all open buffers, for all language servers which support pull diagnostics, before opening workspace diagnostics.
Edit again: I did give this a try and i am not sure if i will be able to get it working. There will be a double for looping which will gives me issues. That would be the case for workspace diagnostics since it is just one request to the server. A better rust developer might be able to pull it off 😄

I suggest to wait for language servers to support this capability, and maybe handle pulling diagnostics for all documents for workspace diagnostics picker in a separate pull request.

@kirawi kirawi added the S-waiting-on-review Status: Awaiting review from a maintainer. label Sep 3, 2024
editor.document(document_id),
editor.language_server_by_id(language_server_id),
) {
pull_diagnostics_for_document(doc, language_server);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can lead to runaway requests. We should not be making a new request right away since the cancellation is usually caused by a new edit for which we also make a new request anyways.

We should instead send an even to the handler here (which needs to track for which revision we already made a request and only rerequest if it makes sense)

job::dispatch_blocking(move |editor, _| {
let documents = editor.documents.values();

for document in documents {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the server supports it we should use a workspace diagnostic request when pulling all documents.

@SofusA
Copy link
Contributor Author

SofusA commented May 5, 2025

@pascalkuthe Thanks for the review. It sounds like this needs some more features:

  1. Ability to cancel ongoing requests
  2. Implementation of workspace diagnostics
  3. Tracking of dispatched revisions

While i do agree that this would be great features to have, i am personally only invested in basic pull diagnostic support. I absolutely understand why this should be implemented, i just do not have the time (or skills 😄 ).

I have been updating this branch for quite some time and will continue to do so, but i don't think i will be able to implement these features in the near future.

@the-mikedavis
Copy link
Member

Pascal and I can take the branch forward as we find time to work on it. I have some changes locally I was working on to track the ongoing requests anyways. We wouldn't mind getting something relatively simple in as a first step but there are some changes we'll want to make to ensure we don't spam the language server or allow duplicate in-flight requests

@SofusA
Copy link
Contributor Author

SofusA commented May 7, 2025

Pascal and I can take the branch forward as we find time to work on it. I have some changes locally I was working on to track the ongoing requests anyways. We wouldn't mind getting something relatively simple in as a first step but there are some changes we'll want to make to ensure we don't spam the language server or allow duplicate in-flight requests

Thanks. I appreciate your work 😃

I did play around with the cancel request. The result is great. I was able to reduce the debounce to 125 ms without issues, but I am not sure if the code holding ongoing requests is ideal.

edit: Fat fingered the close with comment button.

@SofusA SofusA closed this May 7, 2025
@SofusA SofusA reopened this May 7, 2025
@SofusA
Copy link
Contributor Author

SofusA commented Jul 7, 2025

I will have some time to work on this again. But i could need some guidance for what need to be done before this is ready for review (or merge 😄 ).

My current solution for cancelling on-going requests has been working very well, at least in C#. But it requires the consumer to mark the requests as done, which i don't find ideal.
I am curious for your implementation for tracking requests.

I do understand if you are busy or other pull requests has higher priority.

@the-mikedavis
Copy link
Member

There's some prior art in the LSP document colors code that should be a good reference. We want the pull request to be cancellable in case a document changes before the response arrives:

// NOTE: ideally this would live on the handler for color swatches. This is blocked on a
// large refactor that would make `&mut Editor` available on the `DocumentDidChange` event.
pub color_swatch_controller: TaskController,

let cancel = doc.color_swatch_controller.restart();
let mut seen_language_servers = HashSet::new();
let mut futures: FuturesOrdered<_> = doc
.language_servers_with_feature(LanguageServerFeature::DocumentColors)
.filter(|ls| seen_language_servers.insert(ls.id()))
.map(|language_server| {
let text = doc.text().clone();
let offset_encoding = language_server.offset_encoding();
let future = language_server
.text_document_document_color(doc.identifier(), None)
.unwrap();
async move {
let colors: Vec<_> = future
.await?
.into_iter()
.filter_map(|color_info| {
let pos = helix_lsp::util::lsp_pos_to_pos(
&text,
color_info.range.start,
offset_encoding,
)?;
Some((pos, color_info.color))
})
.collect();
anyhow::Ok(colors)
}
})
.collect();
if futures.is_empty() {
return;
}
tokio::spawn(async move {
let mut all_colors = Vec::new();
loop {
match cancelable_future(futures.next(), &cancel).await {

// Cancel the ongoing request, if present.
event.doc.color_swatch_controller.cancel();

@SofusA
Copy link
Contributor Author

SofusA commented Jul 8, 2025

Nice! I have tried to have similar function signature close to request_document_colors.
I have copied some of the comments which is also applicable in diagnostics. I don't know if this is something that you want.

@SofusA
Copy link
Contributor Author

SofusA commented Jul 23, 2025

The request cancellation has been working great.
I see this as being ready for review as a basic implementation of textDocument/diagnostics.

It leaves some additional tasks which i think should be in followup in separate pull requests:

  • Handle diagnostics for related documents. I was not able to find a language server that supports this.
  • Workspace diagnostics
  • More precise retry logic for failed diagnostics requests.

This change is a very relevant for all developers who writes ruby or csharp, or uses eslint.

@kdestin
Copy link

kdestin commented Sep 18, 2025

I've been running this PR for a couple weeks, and it's been really nice to be able to use https://github.com/SofusA/csharp-language-server/ for C#.

But I've been sometimes running into a bug when I try to open multiple files at once from the commandline.


Description

When opening two or more files from the commandline (hx file1 file2), helix will sometimes hang and the editor will never display the files.

Screencast.from.09-18-2025.06.19.57.PM.mp4

Environment

Steps to Reproduce

  1. Install helix from SofusA/helix-pull-diagnostics

  2. Prepare files

    .
    ├── file1.py
    └── file2.py
    
file1.py (empty file)
file2.py
class Foo:
    def bar(self):
        pass

    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
    # _______________________________________________________________________________________________________________
  1. Install a language server (either is fine)

    • ty (If uv is installed, this can be done with uv tool install ty)
    • ruff (If uv is installed, this can be done with uv tool install ruff)
  2. Open both files

    hx file1.py file2.py

Expected Result

hx should open both buffers, setting file1.py as the active buffer.

Observed Result

hx hangs, never showing the editor, only exiting after sending SIGINT (ctrl-c).

Miscellaneous

I wasn't able to root cause this, but here's a couple things I noticed while making a minimal-ish repro + using this PR:

  • Invocation needs atleast 2 files (hx file1 file2 file3)
    • I've never run into this issue just trying to open 1 file
  • Only reproducible when there's a language server available for the files
  • File contents (when opening 2 files):
    • The contents of the first file seems to be irrelevant (can be empty).
    • The second file needs to be "sufficiently large" to trigger the hang
      • I couldn't determine a consistent size threshold, since this seemed to change based on the actual contents of the file.
      • This might be the reason why the hang isn't 100% reproducible when trying to open two or more files.

@SofusA
Copy link
Contributor Author

SofusA commented Sep 21, 2025

I've been running this PR for a couple weeks, and it's been really nice to be able to use https://github.com/SofusA/csharp-language-server/ for C#.

But I've been sometimes running into a bug when I try to open multiple files at once from the commandline.

Description

When opening two or more files from the commandline (hx file1 file2), helix will sometimes hang and the editor will never display the files.
Screencast.from.09-18-2025.06.19.57.PM.mp4

Environment

* Helix: ([SofusA/helix-pull-diagnostics branch: pull-diagnostics (cabced63)](https://github.com/SofusA/helix-pull-diagnostics/tree/pull-diagnostics))

* OS: Ubuntu 22.04

Steps to Reproduce

1. Install helix from SofusA/helix-pull-diagnostics

2. Prepare files
   ```
   .
   ├── file1.py
   └── file2.py
   ```

file1.py (empty file)

file2.py

3. Install a language server (either is fine)
   
   * [ty](https://github.com/astral-sh/ty) (If uv is installed, this can be done with `uv tool install ty`)
   * [ruff](https://github.com/astral-sh/ruff) (If uv is installed, this can be done with `uv tool install ruff`)

4. Open both files
   ```shell
   hx file1.py file2.py
   ```

Expected Result

hx should open both buffers, setting file1.py as the active buffer.

Observed Result

hx hangs, never showing the editor, only exiting after sending SIGINT (ctrl-c).

Miscellaneous

I wasn't able to root cause this, but here's a couple things I noticed while making a minimal-ish repro + using this PR:

* Invocation needs atleast 2 files (`hx file1 file2 file3`)
  
  * I've never run into this issue just trying to open 1 file

* Only reproducible when there's a language server available for the files
  
  * If you run through the repro without installing a language server, `hx` won't hang
  * As far as I can tell, this isn't just limited to `ty` and `hx`. I've run into this
    with C# while using https://github.com/SofusA/csharp-language-server/.

* File contents (when opening 2 files):
  
  * The contents of the first file seems to be irrelevant (can be empty).
  * The second file needs to be "sufficiently large" to trigger the hang
    
    * I couldn't determine a consistent size threshold, since this seemed to change based on the actual contents of the file.
    * This might be the reason why the hang isn't 100% reproducible when trying to open two or more files.

Thanks for the detailed report. It sounds frustrating.
I am not able to reproduce this with C# and SofusA/csharp-language-server on fedora 42 with this branch merged with master.

Does the hang also occur on master?

Can you add information about your OS, and try again on the rebased branch?

@the-mikedavis
Copy link
Member

This sounds possibly like something I had seen for LSP documentColors: ba54b6a. I didn't spend much time debugging that so I'm not sure it's related, but maybe it's a useful pointer.

Copy link
Member

@the-mikedavis the-mikedavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is looking good, I only have some minor comments. At this point I'd be inclined to just merge this as-is and we can iterate on the hooks in follow-ups if needed

SofusA and others added 6 commits September 22, 2025 09:33
The job::dispatch_blocking attempted to run a job on the main thread,
but the request_document_diagnostics_for_language_severs is already run
on the main thread. We can restart the task controller for the document
directly without the blocking job.
The HashSet doesn't have a defined order so we can equivalently use
FuturesUnordered.
Otherwise changing a document once will cause it to be requested when
the debounce finishes for another document's change for example. The
HashSets would only grow. `std::mem::take` swaps the HashSets with new
empty ones, effectively resetting them, and gives us the owned ones to
pass into job::dispatch_blocking.
We can eagerly handle all successful responses, then wait 500ms and
retry requests to all failed language servers which responded with the
`retrigger_request` option.
@the-mikedavis
Copy link
Member

I could reproduce the deadlock, fixed in 1184bc0 - looks like the main thread was blocking trying to acquire a lock already held by the main thread

Copy link
Member

@the-mikedavis the-mikedavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this!

I think the hooks could be a bit fancier in the long run:

  • We could empty out the HashSets in the AsyncHooks for any language servers that request workspace/diagnostic/refresh. Looks like rust-analyzer requests that when it sees textDocument/didChange in my testing. When it does that we end up with multiple requests for the same document
  • Similarly in the PullAllDocumentsDiagnosticHandler we could avoid requesting diagnostics for any documents that were passed to the PullDiagnosticHandler - just tracking them in another HashSet

These can be done as follow-ups if necessary though. This is already working well in my testing so I will merge it down now 🚀

@the-mikedavis the-mikedavis merged commit a5d0a0e into helix-editor:master Sep 23, 2025
7 checks passed
littleblack111 pushed a commit to littleblack111/helix that referenced this pull request Sep 29, 2025
alschena pushed a commit to alschena/helix that referenced this pull request Nov 13, 2025
kfatyuip pushed a commit to kfatyuip/helix that referenced this pull request Nov 21, 2025
tomgroenwoldt pushed a commit to tomgroenwoldt/helix that referenced this pull request Jan 15, 2026
Eucladia pushed a commit to Eucladia/helix that referenced this pull request Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-language-server Area: Language server client S-waiting-on-review Status: Awaiting review from a maintainer.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add pullDiagnostics lsp feature

10 participants