Skip to content

WIP: Lint on FocusGained/VimResume#2494

Closed
andreypopp wants to merge 1 commit intodense-analysis:masterfrom
andreypopp:andreypopp/lint-on-focus-gained
Closed

WIP: Lint on FocusGained/VimResume#2494
andreypopp wants to merge 1 commit intodense-analysis:masterfrom
andreypopp:andreypopp/lint-on-focus-gained

Conversation

@andreypopp
Copy link
Contributor

@andreypopp andreypopp commented May 12, 2019

This PR allows to configure ALE to lint when vim gains focus or is resumed after
being suspended (C-z and then fg command).

The motivation for this is that some linters do not watch all needed resources
(build artifacts) and thus they require to be nudged after those are changed.
The good way I found is to do that when you switch back to an editor.

Example workflow:

  1. Work in vim, do some edits
  2. Switch to terminal and run build process so it does some updates to build
    artifacts
  3. Switch back to an editor. This is the point where I want to see updated
    diagnostics for the buffer but right now I have to save buffer manually so it
    triggers the lint (and didSave event for an LSP). With with PR vim sends
    didChange event to LSP / requests lints automatically when I switch to back
    to it.

Not that for this to work with tmux one must set

set -g focus-events on

in their tmux.conf.

Note also that I've added b:force_changedtick which forces to send LSP didChange event even if there were no changes.

This commits allow to configure ALE to lint when vim gains focus or is
resumed after being suspended (C-z and then `fg` command).

Not that for this to work with tmux one must set
```
set -g focus-events on
```
in their `tmux.conf`.
Copy link
Member

@w0rp w0rp left a comment

Choose a reason for hiding this comment

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

Add tests for the new event, and update the tests that check which autocmd commands are set.

endfunction

function! ale#events#FocusGained(buffer) abort
call setbufvar(a:buffer, 'force_changedtick', 1)
Copy link
Member

@w0rp w0rp May 12, 2019

Choose a reason for hiding this comment

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

We shouldn't force updates to be sent to language servers here and below. We should only send updates if the buffer has actually changed. If b:changedtick isn't updated because some other process updated the buffer and Vim didn't increment b:changedtick, we can do something that causes b:changedtick to increment in response to the buffer being changed, maybe comparing the text before and after Vim lost focus. If the buffer hasn't been changed, no messages should be sent to the language servers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done so we can request server to recompute diagnostics. Unfortunate LSP lacks such method and I see you’ve also noted that — microsoft/language-server-protocol#737

Copy link
Member

Choose a reason for hiding this comment

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

I understand. I think we shouldn't request diagnostics again if the buffer hasn't changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you think we can add such feature (requesting diagnostics via sending didChange events) configurable for specific LSP linters? In my case I'm working on ocamlmerlin-lsp which only works per-file — and if I run a build system — I want to re-request diagnostics from the linter no matter if buffer was changed or not (there could be new/no errors just because of the build process finished).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Btw such behaviour can be also useful for non-LSP linters — they don't work with "push" model (I think LSP is designed around this) also, instead you ask / "pull" diagnostics from them.

Copy link
Member

Choose a reason for hiding this comment

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

It won't work for all language servers. Languages servers don't always respond to textDocument/didChange with diagnostics. The Language Server Protocol needs to be changed to support explicitly requesting diagnostics for such a thing to work. The protocol doesn't offer any guarantees about what will trigger diagnostics being sent, when they will arrive, or if they will ever be sent. I think it's one of the flaws of the protocol.

tsserver does have an explicit command for requesting diagnostics and pretty much guarantees a response, so we could add a command to request for diagnostics for tsserver.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I understand that.

That's why I'm asking if we can make this configurable per-linter so it works with ocamlmerlin-lsp (either via textDocument/didChange or I can add some new type of request to query for diagnostics as a protocol extension).

Copy link
Member

Choose a reason for hiding this comment

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

I think we should follow the protocol and only send a message for a document being changed when it has changed, and push for the protocol to be extended to allow user to request diagnostics explicitly, like you can with tsserver.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately I don't think I can wait till it's standardised in LSP — standard bodies move slowly. I prefer standards instead be informed by real world usage. I think I'll be able to patch it up on top of ALE, not optimal but doable.


function! ale#events#FocusGained(buffer) abort
call setbufvar(a:buffer, 'force_changedtick', 1)
call ale#Queue(0, 'lint_file', a:buffer)
Copy link
Member

Choose a reason for hiding this comment

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

Check g:ale_lint_on_focus_gained here again, and probably ale_enabled like we do above. Otherwise it will be difficult to turn this event off after the autocmd command has been set.

let g:ale_lint_on_filetype_changed = get(g:, 'ale_lint_on_filetype_changed', 1)

" This flag can be set to 1 to enable linting when vim gains focus.
let g:ale_lint_on_focus_gained = get(g:, 'ale_lint_on_focus_gained', 1)
Copy link
Member

Choose a reason for hiding this comment

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

Document the option and turn it off by default. There are thousands of people using ALE, and many of them will have told ALE not to lint their buffers when they enter a file. They will be surprised if it starts linting their buffers when Vim regains focus after they update ALE.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm... maybe we should use an existent check g:ale_lint_on_enter, what do you think? Not sure adding an extra option is worth it considering the semantics of "entering" is so poorly defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also — maybe we can make such behaviour configurable per-linter?

Copy link
Member

Choose a reason for hiding this comment

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

I think a new option is appropriate, but it should be off by default.

@andreypopp andreypopp closed this May 12, 2019
@w0rp
Copy link
Member

w0rp commented May 12, 2019

You can get support for linting buffers on VimResume or FocusGained in without the changes to the LSP code. You can take that part out and add support for just the new events.

@andreypopp
Copy link
Contributor Author

Yeah, good point.

@andreypopp andreypopp reopened this May 13, 2019
@w0rp
Copy link
Member

w0rp commented Apr 17, 2020

I'm closing old pull requests that didn't go anywhere, or I didn't have time to look at. Re-open the pull request or submit a new one if you have something you think can be merged.

@w0rp w0rp closed this Apr 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants