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

flymake-no-change-timeout setting seems to be ignored #508

Closed
InspectorMustache opened this issue Jul 1, 2020 · 10 comments
Closed

flymake-no-change-timeout setting seems to be ignored #508

InspectorMustache opened this issue Jul 1, 2020 · 10 comments

Comments

@InspectorMustache
Copy link

I would like to disable the automatic buffer check that flymake does, so I set flymake-no-change-timeout to nil. This works fine in elisp buffers where I don't use eglot. However, once I turn on eglot in other buffers, the automatic check is back. I tried this with both Go and Python, here's the events transcript for Python:

[client-request] (id:1) Wed Jul  1 12:05:26 2020:
(:jsonrpc "2.0" :id 1 :method "initialize" :params
	  (:processId 36624 :rootPath "/home/anlai/" :rootUri "file:///home/anlai/" :initializationOptions nil :capabilities
		      (:workspace
		       (:applyEdit t :executeCommand
				   (:dynamicRegistration :json-false)
				   :workspaceEdit
				   (:documentChanges :json-false)
				   :didChangeWatchedFiles
				   (:dynamicRegistration t)
				   :symbol
				   (:dynamicRegistration :json-false)
				   :configuration t)
		       :textDocument
		       (:synchronization
			(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t)
			:completion
			(:dynamicRegistration :json-false :completionItem
					      (:snippetSupport :json-false)
					      :contextSupport t)
			:hover
			(:dynamicRegistration :json-false :contentFormat
					      ["markdown" "plaintext"])
			:signatureHelp
			(:dynamicRegistration :json-false :signatureInformation
					      (:parameterInformation
					       (:labelOffsetSupport t)))
			:references
			(:dynamicRegistration :json-false)
			:definition
			(:dynamicRegistration :json-false)
			:declaration
			(:dynamicRegistration :json-false)
			:implementation
			(:dynamicRegistration :json-false)
			:typeDefinition
			(:dynamicRegistration :json-false)
			:documentSymbol
			(:dynamicRegistration :json-false :symbolKind
					      (:valueSet
					       [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]))
			:documentHighlight
			(:dynamicRegistration :json-false)
			:codeAction
			(:dynamicRegistration :json-false :codeActionLiteralSupport
					      (:codeActionKind
					       (:valueSet
						["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"])))
			:formatting
			(:dynamicRegistration :json-false)
			:rangeFormatting
			(:dynamicRegistration :json-false)
			:rename
			(:dynamicRegistration :json-false)
			:publishDiagnostics
			(:relatedInformation :json-false))
		       :experimental nil)))
[stderr] 2020-07-01 12:05:26,701 UTC - WARNING - pyls.config.config - Failed to load pyls entry point 'autopep8': No module named 'autopep8'
[stderr] 2020-07-01 12:05:26,764 UTC - WARNING - pyls.config.config - Failed to load pyls entry point 'pylint': No module named 'pylint'
[server-reply] (id:1) Wed Jul  1 12:05:26 2020:
(:jsonrpc "2.0" :id 1 :result
	  (:capabilities
	   (:codeActionProvider t :codeLensProvider
				(:resolveProvider :json-false)
				:completionProvider
				(:resolveProvider :json-false :triggerCharacters
						  ["."])
				:documentFormattingProvider t :documentHighlightProvider t :documentRangeFormattingProvider t :documentSymbolProvider t :definitionProvider t :executeCommandProvider
				(:commands
				 [])
				:hoverProvider t :referencesProvider t :renameProvider t :foldingRangeProvider t :signatureHelpProvider
				(:triggerCharacters
				 ["(" "," "="])
				:textDocumentSync
				(:change 2 :save
					 (:includeText t)
					 :openClose t)
				:workspace
				(:workspaceFolders
				 (:supported t :changeNotifications t))
				:experimental nil)))
[client-notification] Wed Jul  1 12:05:26 2020:
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data
							    ()))
[client-notification] Wed Jul  1 12:05:26 2020:
(:jsonrpc "2.0" :method "textDocument/didOpen" :params
	  (:textDocument
	   (:uri "file:///home/anlai/pfl.py" :version 0 :languageId "python" :text "i removed this part")))
[client-notification] Wed Jul  1 12:05:26 2020:
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params
	  (:settings nil))
[stderr] 2020-07-01 12:05:26,765 UTC - WARNING - pyls.config.config - Failed to load pyls entry point 'rope_completion': No module named 'rope'
[stderr] 2020-07-01 12:05:26,766 UTC - WARNING - pyls.config.config - Failed to load pyls entry point 'rope_rename': No module named 'rope'
[stderr] 2020-07-01 12:05:26,766 UTC - WARNING - pyls.config.config - Failed to load pyls entry point 'yapf': No module named 'yapf'
[server-notification] Wed Jul  1 12:05:27 2020:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
	  (:uri "file:///home/anlai/pfl.py" :diagnostics
		[(:source "pyflakes" :range
			  (:start
			   (:line 3 :character 0)
			   :end
			   (:line 3 :character 30))
			  :message "'apso_utils.msgbox' imported but unused" :severity 2)
		 (:source "pyflakes" :range
			  (:start
			   (:line 160 :character 4)
			   :end
			   (:line 160 :character 30))
			  :message "local variable 'cols' is assigned to but never used" :severity 2)
		 (:source "pyflakes" :range
			  (:start
			   (:line 304 :character 10)
			   :end
			   (:line 304 :character 39))
			  :message "undefined name 'XSCRIPTCONTEXT'" :severity 1)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 35 :character 79)
			   :end
			   (:line 35 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 168 :character 79)
			   :end
			   (:line 168 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 291 :character 79)
			   :end
			   (:line 291 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)]))
[internal] (id:2) Wed Jul  1 12:05:29 2020:
(:deferring :textDocument/signatureHelp :id 2 :params
	    (:textDocument
	     (:uri "file:///home/anlai/pfl.py")
	     :position
	     (:line 0 :character 1)))
[internal] (id:3) Wed Jul  1 12:05:29 2020:
(:deferring :textDocument/hover :id 3 :params
	    (:textDocument
	     (:uri "file:///home/anlai/pfl.py")
	     :position
	     (:line 0 :character 1)))
[internal] (id:4) Wed Jul  1 12:05:29 2020:
(:deferring :textDocument/documentHighlight :id 4 :params
	    (:textDocument
	     (:uri "file:///home/anlai/pfl.py")
	     :position
	     (:line 0 :character 1)))
[client-notification] Wed Jul  1 12:05:29 2020:
(:jsonrpc "2.0" :method "textDocument/didChange" :params
	  (:textDocument
	   (:uri "file:///home/anlai/pfl.py" :version 1)
	   :contentChanges
	   [(:range
	     (:start
	      (:line 0 :character 0)
	      :end
	      (:line 0 :character 0))
	     :rangeLength 0 :text "i")]))
[internal] Wed Jul  1 12:05:29 2020:
(:maybe-run-deferred
 (2 3 4))
[client-request] (id:2) Wed Jul  1 12:05:29 2020:
(:jsonrpc "2.0" :id 2 :method "textDocument/signatureHelp" :params
	  (:textDocument
	   (:uri "file:///home/anlai/pfl.py")
	   :position
	   (:line 0 :character 1)))
[client-request] (id:3) Wed Jul  1 12:05:29 2020:
(:jsonrpc "2.0" :id 3 :method "textDocument/hover" :params
	  (:textDocument
	   (:uri "file:///home/anlai/pfl.py")
	   :position
	   (:line 0 :character 1)))
[client-request] (id:4) Wed Jul  1 12:05:29 2020:
(:jsonrpc "2.0" :id 4 :method "textDocument/documentHighlight" :params
	  (:textDocument
	   (:uri "file:///home/anlai/pfl.py")
	   :position
	   (:line 0 :character 1)))
[server-reply] (id:2) Wed Jul  1 12:05:29 2020:
(:jsonrpc "2.0" :id 2 :result
	  (:signatures
	   []))
[server-reply] (id:3) Wed Jul  1 12:05:29 2020:
(:jsonrpc "2.0" :id 3 :result
	  (:contents ""))
[server-notification] Wed Jul  1 12:05:29 2020:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
	  (:uri "file:///home/anlai/pfl.py" :diagnostics
		[(:source "pyflakes" :range
			  (:start
			   (:line 0 :character 9)
			   :end
			   (:line 0 :character 24))
			  :message "invalid syntax" :severity 1)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 1 :character 0)
			   :end
			   (:line 1 :character 11))
			  :message "E402 module level import not at top of file" :code "E402" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 2 :character 0)
			   :end
			   (:line 2 :character 36))
			  :message "E402 module level import not at top of file" :code "E402" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 3 :character 0)
			   :end
			   (:line 3 :character 30))
			  :message "E402 module level import not at top of file" :code "E402" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 4 :character 0)
			   :end
			   (:line 4 :character 36))
			  :message "E402 module level import not at top of file" :code "E402" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 5 :character 0)
			   :end
			   (:line 5 :character 34))
			  :message "E402 module level import not at top of file" :code "E402" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 6 :character 0)
			   :end
			   (:line 6 :character 33))
			  :message "E402 module level import not at top of file" :code "E402" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 35 :character 79)
			   :end
			   (:line 35 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 168 :character 79)
			   :end
			   (:line 168 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 291 :character 79)
			   :end
			   (:line 291 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)]))
[server-reply] (id:4) Wed Jul  1 12:05:30 2020:
(:jsonrpc "2.0" :id 4 :result
	  [(:range
	    (:start
	     (:line 0 :character 0)
	     :end
	     (:line 0 :character 7))
	    :kind 2)])
[client-notification] Wed Jul  1 12:05:31 2020:
(:jsonrpc "2.0" :method "textDocument/didChange" :params
	  (:textDocument
	   (:uri "file:///home/anlai/pfl.py" :version 2)
	   :contentChanges
	   [(:range
	     (:start
	      (:line 0 :character 0)
	      :end
	      (:line 0 :character 1))
	     :rangeLength 1 :text "")]))
[server-notification] Wed Jul  1 12:05:31 2020:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
	  (:uri "file:///home/anlai/pfl.py" :diagnostics
		[(:source "pyflakes" :range
			  (:start
			   (:line 3 :character 0)
			   :end
			   (:line 3 :character 30))
			  :message "'apso_utils.msgbox' imported but unused" :severity 2)
		 (:source "pyflakes" :range
			  (:start
			   (:line 160 :character 4)
			   :end
			   (:line 160 :character 30))
			  :message "local variable 'cols' is assigned to but never used" :severity 2)
		 (:source "pyflakes" :range
			  (:start
			   (:line 304 :character 10)
			   :end
			   (:line 304 :character 39))
			  :message "undefined name 'XSCRIPTCONTEXT'" :severity 1)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 35 :character 79)
			   :end
			   (:line 35 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 168 :character 79)
			   :end
			   (:line 168 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)
		 (:source "pycodestyle" :range
			  (:start
			   (:line 291 :character 79)
			   :end
			   (:line 291 :character 88))
			  :message "E501 line too long (87 > 79 characters)" :code "E501" :severity 2)]))
[internal] (id:2) Wed Jul  1 12:05:39 2020:
(:timed-out :textDocument/signatureHelp :id 2 :params
	    (:textDocument
	     (:uri "file:///home/anlai/pfl.py")
	     :position
	     (:line 0 :character 1)))
[internal] (id:3) Wed Jul  1 12:05:39 2020:
(:timed-out :textDocument/hover :id 3 :params
	    (:textDocument
	     (:uri "file:///home/anlai/pfl.py")
	     :position
	     (:line 0 :character 1)))
[internal] (id:4) Wed Jul  1 12:05:39 2020:
(:timed-out :textDocument/documentHighlight :id 4 :params
	    (:textDocument
	     (:uri "file:///home/anlai/pfl.py")
	     :position
	     (:line 0 :character 1)))
@joaotavora
Copy link
Owner

Do you actually see these diagnostics that come in periodically displayed on screen? The reason why I'm asking is that Flymake, or at least that particular Flymake variable, has no control over the amount of information that the LSP server sends to Emacs or vice versa. In normal LSP situations, everytime Emacs communicates a change to a file, the LSP server volunteers information about diagnostics. That seems to be what you're showing me in that transcript.

@muffinmad
Copy link
Collaborator

It is server responsibility to send textDocument/publishDiagnostics. E.g. here was made the attempt to disable linting on change for pyls: palantir/python-language-server#511

@joaotavora
Copy link
Owner

Yeah, I guess there's something in Eglot that can suggest to the LSP server that they shouldn't do that. Some capability . Maybe tweaking eglot-ignored-server-capabilities works.

@InspectorMustache
Copy link
Author

Do you actually see these diagnostics that come in periodically displayed on screen?

Nope, scrolled right past them to be honest. I guess my understanding of how LSP works is rather limited which is why I thought this could be easily configured client-side. Well, maybe I can figure something out tinkering with that variable you mentioned (eglot-ignored-server-capabilities).

@JimDBh
Copy link

JimDBh commented May 17, 2022

Hello, I'd also like to add to this issue.

From the discussion I can understand that the server will volunteer to check diagnostics on change. However, is there a way for eglot to "hold on" to them, and only displays them when flymake asks for it (e.g. via the timeout timer, or manual activation)?

@JimDBh
Copy link

JimDBh commented May 17, 2022

This pull request (#957) seems to add the functionality.

@joaotavora
Copy link
Owner

From the discussion I can understand that the server will volunteer to check diagnostics on change. However, is there a way for eglot to "hold on" to them, and only displays them when flymake asks for it (e.g. via the timeout timer, or manual activation)?

I think this is what happens currently. If it isn't and you have all necessary elements to elaborate an issue (this includes a way for me to witness), please do so.

@joaotavora
Copy link
Owner

See my reply on #957. f-n-c-t is being respected, but servers volunteers information when they please. Though mostly when clients send them changes, the timing of which is controlled by eglot-send-changes-idle-time.

The Flymake diagnostic update you're seeing are for the same "ongoing" check that you have started (presumably manually, if you set it f-n-c-t to zero).

If you'd like to completely disable Flymake diagnostics, eglot-ignored-server-capabilities is a good starting point.

if you'd like to get diagnostics only on request, I don't think LSP has a good model for that.

@JimDBh
Copy link

JimDBh commented May 17, 2022

Thanks for the prompt reply! I'll try to describe what I experienced:

With clangd in a c project, I set company-idle-delay to 0.1 for fast completion prompts. This works fine, except that even when I'm only writing part of the symbol, or when I'm in a yasnippet completion session, eglot would still report the errors.

I've set eglot-send-changes-idle-time to 0.8, and flymake-no-change-timeout to 1.8, however as soon as company tries to obtain completion (which happens in 0.1 secs), the diagnostic also shows up. Please see the screenshot. Note the diagnostics shows almost immediately as I type myFun, but shows after a while after I type a.

eglot-screenshot

I suspect that company asking for completion would manually send changes to the LSP server, so eglot-send-changes-idle-time is not effective here. And because of that, clangd would send back the completions and the diagnostics shortly. I'm not certain of this, so please correct me if I'm wrong.

I agree it seems LSP does not have a good model for that. Just wondering, as a client, can eglot do something about this? For example, with the option to only show the diagnostics once and suppress the following notifications, until flymake asks again?

Thanks a lot for your help!

From the discussion I can understand that the server will volunteer to check diagnostics on change. However, is there a way for eglot to "hold on" to them, and only displays them when flymake asks for it (e.g. via the timeout timer, or manual activation)?

I think this is what happens currently. If it isn't and you have all necessary elements to elaborate an issue (this includes a way for me to witness), please do so.

@joaotavora
Copy link
Owner

See the commit message for rationale and details.

bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 18, 2022
Also per joaotavora/eglot#957.

Only actually and eagerly report LSP diagnotics if the user has
Flymake starting automatically on a timer (flymake-no-changes-timeout
is a number).

By contrast, if flymake-no-changes-timeout is nil, the user starts the
diagnostic collection process on-demand via 'M-x flymake-start'.

Since the control of such collection is impossible with LSP, we should
just hold on to whatever diagnostics we have (which are presumably
up-to-date) until the next invocation of 'eglot-flymake-backend'.

For now, this doesn't affect Flymake "list-only" diagnostics.  Those
are reported via the 'flymake-list-only-diagonstics' variable and
are always communicated immediately to it.

* eglot.el: (eglot-handle-notification
textDocument/publishDiagnostics): Consult flymake-no-changes-timeout.

Suggested-by: Jim Davis <jim.jd.davis@gmail.com>
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 19, 2022
Also per joaotavora/eglot#957.

Only actually and eagerly report LSP diagnotics if the user has
Flymake starting automatically on a timer (flymake-no-changes-timeout
is a number).

By contrast, if flymake-no-changes-timeout is nil, the user starts the
diagnostic collection process on-demand via 'M-x flymake-start'.

Since the control of such collection is impossible with LSP, we should
just hold on to whatever diagnostics we have (which are presumably
up-to-date) until the next invocation of 'eglot-flymake-backend'.

For now, this doesn't affect Flymake "list-only" diagnostics.  Those
are reported via the 'flymake-list-only-diagonstics' variable and
are always communicated immediately to it.

* eglot.el: (eglot-handle-notification
textDocument/publishDiagnostics): Consult flymake-no-changes-timeout.

Suggested-by: Jim Davis <jim.jd.davis@gmail.com>
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 19, 2022
Also per #957.

Only actually and eagerly report LSP diagnotics if the user has
Flymake starting automatically on a timer (flymake-no-changes-timeout
is a number).

By contrast, if flymake-no-changes-timeout is nil, the user starts the
diagnostic collection process on-demand via 'M-x flymake-start'.

Since the control of such collection is impossible with LSP, we should
just hold on to whatever diagnostics we have (which are presumably
up-to-date) until the next invocation of 'eglot-flymake-backend'.

For now, this doesn't affect Flymake "list-only" diagnostics.  Those
are reported via the 'flymake-list-only-diagonstics' variable and
are always communicated immediately to it.

* eglot.el: (eglot-handle-notification
textDocument/publishDiagnostics): Consult flymake-no-changes-timeout.

Suggested-by: Jim Davis <jim.jd.davis@gmail.com>

#508: joaotavora/eglot#508
#957: joaotavora/eglot#957
jollaitbot pushed a commit to sailfishos-mirror/emacs that referenced this issue Oct 12, 2022
Also per joaotavora/eglot#957.

Only actually and eagerly report LSP diagnotics if the user has
Flymake starting automatically on a timer (flymake-no-changes-timeout
is a number).

By contrast, if flymake-no-changes-timeout is nil, the user starts the
diagnostic collection process on-demand via 'M-x flymake-start'.

Since the control of such collection is impossible with LSP, we should
just hold on to whatever diagnostics we have (which are presumably
up-to-date) until the next invocation of 'eglot-flymake-backend'.

For now, this doesn't affect Flymake "list-only" diagnostics.  Those
are reported via the 'flymake-list-only-diagonstics' variable and
are always communicated immediately to it.

* eglot.el: (eglot-handle-notification
textDocument/publishDiagnostics): Consult flymake-no-changes-timeout.

Suggested-by: Jim Davis <jim.jd.davis@gmail.com>
GitHub-reference: fix joaotavora/eglot#508
jollaitbot pushed a commit to sailfishos-mirror/emacs that referenced this issue Oct 20, 2022
Also per joaotavora/eglot#957.

Only actually and eagerly report LSP diagnotics if the user has
Flymake starting automatically on a timer (flymake-no-changes-timeout
is a number).

By contrast, if flymake-no-changes-timeout is nil, the user starts the
diagnostic collection process on-demand via 'M-x flymake-start'.

Since the control of such collection is impossible with LSP, we should
just hold on to whatever diagnostics we have (which are presumably
up-to-date) until the next invocation of 'eglot-flymake-backend'.

For now, this doesn't affect Flymake "list-only" diagnostics.  Those
are reported via the 'flymake-list-only-diagonstics' variable and
are always communicated immediately to it.

* eglot.el: (eglot-handle-notification
textDocument/publishDiagnostics): Consult flymake-no-changes-timeout.

Suggested-by: Jim Davis <jim.jd.davis@gmail.com>
GitHub-reference: fix joaotavora/eglot#508
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

No branches or pull requests

4 participants