emacs-lsp / lsp-mode

Emacs client/library for the Language Server Protocol
https://emacs-lsp.github.io/lsp-mode
GNU General Public License v3.0
4.79k stars 889 forks source link

Extra lens are displayed when buffer is narrowed #3228

Open andreyorst opened 2 years ago

andreyorst commented 2 years ago

Thank you for the bug report

Bug description

If the buffer is narrowed all lenses below the narrowed region are displayed at the last line.

Steps to reproduce

Open a buffer, and create some variables, so the server could return the lens, for them. Here's an example in Clojure:

(ns foo)
(def a nil)
(def b nil)
(def c nil)
(def d nil)

Here are the lenses:

image

Then narrow to defun on (def a nil) line:

image

Expected behavior

Only one lens is displayed.

Which Language Server did you use?

clojure-lsp

OS

Linux

Error callstack

No response

Anything else?

No response

ericdallo commented 2 years ago

Hum, we should probably change lsp-mode to hide lens when narrowing c/c @yyoncho

yyoncho commented 2 years ago

does it fix itself after changing the text?

yyoncho commented 2 years ago

I was able to test it - it fixes itself after narrowing and changing the buffer content. So we should refresh the lenses after narowing.

ericdallo commented 2 years ago

@yyoncho do you know what narrow hook we can watch it?

andreyorst commented 2 years ago

I'm afraid there's no such hook. However all narrowing commands should use narrow-to-region, and it is a C function, so it seems to fix the issue it can just be advised:

(define-advice narrow-to-region (:after (&rest _))
  (lsp-lens-refresh t))
(define-advice widen (:after (&rest _))
  (lsp-lens-refresh t))
andreyorst commented 2 years ago

This, however, raises another issue, when using indirect narrowing. When I first narrow to an indirect buffer with the advice from above, I get the correct lens in the indirect buffer and no lens in the original buffer:

image

However, when I focus the original buffer I get this:

image

I'm not sure how this should be handled

andreyorst commented 2 years ago

I'm afraid there's no such hook. However all narrowing commands should use narrow-to-region, and it is a C function, so it seems to fix the issue it can just be advised:

(define-advice narrow-to-region (:after (&rest _))
  (lsp-lens-refresh t))
(define-advice widen (:after (&rest _))
  (lsp-lens-refresh t))

I've tried this for a day and noticed an extreme CPU usage in the clojure-lsp process (about 500%). I've not tried other servers, but removing the advices resolved the CPU usage issue, so I think this method is not very good.

yyoncho commented 2 years ago

it should be (lsp-lens-refresh nil) and also it should check if the buffer has lens mode enabled.