natebosch / vim-lsc

A vim plugin for communicating with a language server
BSD 3-Clause "New" or "Revised" License
691 stars 79 forks source link

ALE compatibility, similar to upcoming vim-lsp <--> ALE bridge #337

Open bluz71 opened 3 years ago

bluz71 commented 3 years ago

ALE celebrated it's four year anniversary today as noted in this Reddit post.

Interestingly the author, @w0rp, noted a desire to have LSP clients delegate diagnostics to ALE if users so wish. Well, that's how I read this post.

Coc is already integrated as noted here.

The one that caught my eye is the vim-lsp <--> ALE bridge as discussed in this issue.

As a Neovim + LSC + ALE user myseld I also want in on the action, if possible.

Once the ALE <--> vim-lsp bridge is done it would be nice to see, resources permitting, if the same could happen here. I suggest a holding pattern until the vim-lsp 882 issue is complete.

Background, I use LSC for LSP functionality sans any diagnostics and I use ALE for only linting & fixing. In the case of Dart that means I end up spawning, via LSC and ALE, two Dart Analysis Servers. Ideally I would prefer only one server (spawned by LSC) and to have LSC redirect any and all diagnostics over to ALE. And I would like this bridging to be language dependent, aka I would use the bridge for Dart, but not for Ruby (for example); I don't know if this is possible or not?

Hopefully we can get @w0rp from the ALE project involved here after vim-lsp is done.

Best regards.

w0rp commented 3 years ago

I'm going to try to work on the vim-lsp bridge plugin later myself. For documentation on how to cooperate with ALE, I recommend reading :help ale-lint-other-sources, if you have ALE installed. The documentation should explain everything.

bluz71 commented 3 years ago

@w0rp,

Thanks, I will have a look, but Nate (LSC maintainer) will need to get involved since I suspect LSC will need a new user switch, enable ALE passthrough, that if true should redirect textDocument/publishDiagnostics responses to ALE. I myself only have a brief knowledge of how LSC internals work (I just dabbled a bit with Neovim floating windows).

But I am a big proponent of having LSC forward diagnostics over to ALE since it is a superior linter (with bonus fixing/formatting).

If ALE <--> vim-lsp get done, then ALE <--> LSC should also be doable.

Side note, these would be the (Neo)vim LSP clients that would interop well with ALE:

Which is nearly the same collection of LSP clients that vim-vsnip integrated with.

Best regards.

natebosch commented 3 years ago

@w0rp - is it possible to set diagnostics for files that aren't open yet?

In ale-loclist-format I see that it is possible to have items for files that aren't open by setting the filename key to a full path. https://github.com/dense-analysis/ale/blob/4ddf74264397a0c739b1c6fd5f643505a31e1d11/doc/ale.txt#L3614-L3616

However the ale#other_source#ShowResults looks like it requires a bufnr argument which we might not have yet. https://github.com/dense-analysis/ale/blob/4ddf74264397a0c739b1c6fd5f643505a31e1d11/doc/ale.txt#L268

I could wait until the buffer is opened to send them, but it adds some complexity over calling ale#other_source#ShowResults every time we get diagnostics from the server.

bluz71 commented 3 years ago

I could wait until the buffer is opened to send them, but it adds some complexity over calling ale#other_source#ShowResults every time we get diagnostics from the server.

Maybe LSC could simply drop those results?

If that buffer isn't open then a user likely is not currently interested in those diagnostics.

For example, in ALE these are the on-lint triggers:

* When you modify a buffer.                - |g:ale_lint_on_text_changed|
* On leaving insert mode.                  - |g:ale_lint_on_insert_leave|
* When you open a new or modified buffer.  - |g:ale_lint_on_enter|
* When you save a buffer.                  - |g:ale_lint_on_save|
* When the filetype changes for a buffer.  - |g:ale_lint_on_filetype_changed|

All are predicated on the buffer being visible on screen now; aka I care about linting the buffer that is before me.

bluz71 commented 3 years ago

Hello Nate,

What do we believe the API should be?

Something like this maybe:

let g:lsc_diagnostics_display_by_ale = v:true

Would the behaviour then be that all LSC language servers would pass through textDocument/publishDiagnostics to ALE which would then display lint errors per the users ALE configuration?

Ideally I would really like to control textDocument/publishDiagnostics to ALE on a language server by language server basis, for example:

let g:lsc_server_commands = {
 \  'dart': {
 \    'command': expand('dart $DART_SDK/bin/snapshots/analysis_server.dart.snapshot --lsp'),
 \    'log_level': -1,
 \    'suppress_stderr': v:true,
 \  },
 \  'ruby': {
 \    'command': 'solargraph stdio',
 \    'log_level': -1,
 \    'suppress_stderr': v:true,
 \  },
 \  'javascript': {
 \    'command': 'typescript-language-server --stdio',
 \    'log_level': -1,
 \    'suppress_stderr': v:true,
 \  }
 \}

let g:lsc_diagnostics_display_by_ale = ['dart', 'javascript']

Instead of a global boolean flag for ALE, maybe a list of which languages should have diagnostics enabled and be forwarded to ALE. In the above example I want diagnostics for Dart and JavaScript and for them to be forwarded to ALE, but no diagnostics for Ruby (which I use non-LSP Rubocop directly via ALE).

ALE really is an outstanding linting solution. I am very interested in a solution that can use LSC LSP-smarts married up with ALE's excellent linting presentation.

Cheers.

bluz71 commented 3 years ago

@natebosch and @w0rp ,

In my ALE configuration I explicitly enable let g:ale_lint_on_save = 1 whilst also explicitly disabling let g:ale_lint_on_enter = 0.

In LSC if I set let g:lsc_enable_diagnostics = v:true it appears that diagnostics immediately come into effect. As soon as the server has diagnostics they are delivered on screen.

I think in LSP-land diagnostics are delivered by the language server any old time and maybe are not driven by Vim events such as on-save, on-enter, etc.

In any LSC <--> ALE bridge it would be nice to honor a user's ALE lint/diagnostic display-when preference (if that's possible). Maybe the ALE side of the bridge already handles that? I don't know if there is much LSC can do about that.

Maybe this post should be ignored. Anyway, just thought I'd bring it up.

Cheers.