casouri / eldoc-box

childframe doc for eglot and anything that uses eldoc
361 stars 26 forks source link

Utilize the posframe package #11

Open terlar opened 5 years ago

terlar commented 5 years ago

I am running Linux and are seeing some display issues with this, perhaps an idea could be to use this library for display logic: https://github.com/tumashu/posframe

I have found that to be quite stable. Also found this https://github.com/gexplorer/eldoc-posframe, but that one has not been published to MELPA, perhaps efforts could be joined as they both seem to solve the same problem.

Thanks for the package, I've been meaning to do this myself for a while, but haven't gotten around to it.

casouri commented 5 years ago

One reason I don't want to use posframe is that I try to keep the dependency to a minimum and the current mechanism seems worked well (on my machine). But since multiple people have told me that it has problems on Linux, it might be time.

However, I need to look into posframe to decide to either switch to it. And if the problem is trivial, I can just try to fix it without introducing posframe into eldoc-box. So could you describe the problem with some more detail? Thanks.

terlar commented 5 years ago

Understandable, thank you for the response, here is the issue that I am experiencing:

Sometimes a childframe gets created like this, seemingly without some of the properties it should have (name?, size, position, etc): image

It is only during the first display operation and then you can not get rid of it. As you can see when I navigate I get a new child frame displaying correctly in the other corner. If I run eldoc-box-quit-frame it closes this new one, but not the big one (I assume this might be to not being targeted as all the properties were not set.

I have only experienced this in Emacs-Lisp files, I have not seen this in files with Eldoc provided by eglot for example. Perhaps it is a race condition? Causing the properties not to be applied.

terlar commented 5 years ago

Another one seems to be that it cuts off part of the text (in the very end). I wonder if it is due to leading space: image

I think it might be related to me having things such as:

(setq-default fringes-outside-margins t
                  left-margin-width 1
                  right-margin-width 1)

But I tried setting those in eldoc-box-frame-parameters but didn't seem to have any effect. I remember having the same issue with posframe (before it was renamed, and remvoed, hence the history is lost). But there should be some frame parameter that is possible to set to fix that.

terlar commented 5 years ago

I wonder if it is due to this: https://github.com/tumashu/posframe/blob/master/posframe.el#L200

If some parameters is not possible to set via child-frame-parameters, but need to be set at a later time.

casouri commented 5 years ago

Thanks for your info, the cause of this particular problem is hard to reason about just by looking it, I'll get a Linux VM then. While I'm doing that, could you reproduce it with minimum configuration and give me the version of Emacs and eldoc-box that you are using?

casouri commented 5 years ago

I've set up an Arch Linux and tried eldoc-box on Emacs 26.1. I can see the big childframe you are describing, but it disappeared after being set to the right position and size. So I'm not sure why yours stays there. I didn't observe the margin issue that you are describing, any idea?

casouri commented 5 years ago

Oops, didn't mean to close it.

terlar commented 5 years ago

It seems your latest commit fixed that issue with the big box. The error was reproducible when running Emacs 27.0.5, and you just:

emacs -Q
C-x C-f path/to/eldoc-box/eldoc-box.el
M-x load-file path/to/eldoc-box/eldoc-box.el
M-x eldoc-box-hover-mode
... Navigate to any definition that triggers eldoc ...

Looking at this I also found out that the extra space in the beginning is the left-fringe, so removing that would fix that.

I think many of these display issues might be introduced by Emacs 27. It is usable now however. Only thing I notice now is:

When using eldoc-box-hover-at-point-mode:

image

image

image

casouri commented 5 years ago

Thank you for your time :)

  • Width is wrong sometimes off a little bit, e.g. missing last part of a description of a variable. However next time you move your cursor it will fix itself. And it is not all the time.

I'll try to reproduce it and figure out why.

  • Position ends up in the wrong place sometimes (mainly on the y axis). It seems the navigation affects this, if I move from above it gets one line too high, if I move from below it gets one line too low. Also toolbar seems to play a role, as seen from the first and second screenshots. When using Emacs 26, removing the toolbar seems to fix this issue.

IIRC Linux window management system is different from Mac regarding tool box, etc. I think the difference between the position in your example is due to the toolbox (first on, then off). It should be easy to fix.

  • The box is blinking on every move, character input as opposed to the mode at the top which feels very natural 👍.

That's sort of a design complement based on the design of eldoc. At-point documentation blocks the code and I want it to disappear as soon as I move the cursor to other places, that's why you have the blink: it disappears immediately and eldoc displays a new one. But even I make the childframe stay, it will be moved to the new cursor position, which isn't much better than disappearing and reappear at the new position. Is that what you want?

In a word, 1) needs time 2) fix now 3) need more discussion

terlar commented 5 years ago

Thank you. Regarding, the disappearing and reappearing. That is partly true, as the election will be shown in the message area will stay until another message is displayed, and when it is the same message it doesn't redisplay but is kept there constantly.

Usually I want to see the documentation while I type something as arguments to a function. But when it guides and shows again I have to wait for it to appear again.

Especially in elisp where it highlights the current argument, I use that as a guide to which part of the function I am currently writing.

I have not come up with the perfect solution yet. I tried to not hide if the last command was a self-insert and that made sense. But sometimes I do a movement or kill command and would still not like to lose the eldoc.

One option is to whitelist such operations, but perhaps more appropriate to not hide if you are still in the same line, inside the same sexp or perhaps still working with the same symbol.

What do you think?

The non-cursor one is kind of working like this already. I didn't see it flicker there.

casouri commented 5 years ago

I deliberately make the at-point docs disappear ASAP because they are constantly blocking the code underneath. But your point totally makes sense and I agree with you.

The non-cursor one is kind of working like this already. I didn't see it flicker there.

It's easy to make at-point docs behave like non-cursor ones. If you want to try it, you can go to

https://github.com/casouri/eldoc-box/blob/b9a235b61c85d4ecf31b84c4d007c22e2fab0b7c/eldoc-box.el#L153

And remove all the hook configurations in that minor mode definition, then you have it. You will see what I mean by "blocking the code underneath" : (

I have not come up with the perfect solution yet. I tried to not hide if the last command was a self-insert and that made sense. But sometimes I do a movement or kill command and would still not like to lose the eldoc. One option is to whitelist such operations, but perhaps more appropriate to not hide if you are still in the same line, inside the same sexp or perhaps still working with the same symbol.

Yeah I can see a bunch of annoying edge cases that it cannot handle.

I guess the desired behavior is that the doc shows and stays in position as long as you are on a valid symbol (or in a function signature) and disappears as soon as the point leaves.

For that to work eldoc-box has to know whether it's in a doc-able place immediately after each user action. For normal eldoc backends, it's no problem, but eglot is async, which means it calls eldoc to display the doc when it is ready, instead of the other way around. So it is impossible for eldoc-box (being called by eldoc) to know whether it should show the doc on time. That's why eldoc-box uses a timer to clean up in the first place.

The only way I can see that solves this is to write different routines for eglot and other eldoc backends. That's not very health regarding the complexity and stuff, but since eglot has hacked on eldoc, I guess it's ok for eldoc-box to hack on eglot's hack on eldoc ; ) I'll work on it this weekend and see if I can cook out something that works well.

andreyorst commented 5 years ago

It seems that I'm experiencing the same issues with eldoc-box size and eglot.

First, when the mode is just started the box is extremely tiny (single letter) and no information is shown inside it (probably because it can't fit inside): image (you can see that in the line below cursor, eldoc-box is covering l letter)

It seems that eldoc-box uses size of previous box for a new box. E.g. if I hover on the flag variable: image And after that hover on the function, displayed box has exactly the same size as previous box: image

I can get correct size if I hover over the same symbol again: image

But now if I hover back on flag I get the bigger box size that could fit the function documentation: image

This issue can cause annoying problem with line wraps, if previous box was small enough, and new eldoc info has long lines they will be wrapped, and some text will be hidden below the box, because previous box size is used: image

Another problem is that in Org Src mode eldoc-box is displayed not under cursor, but one line lower the cursor: image It doesn't happen in normal emacs-lisp buffers, only when editing Org source block.

I'm using Arch Linux, with GNU Emacs 26.2 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.8) of 2019-04-12 The same happens on Fedora 30, with GNU Emacs 26.2 (build 1, x86_64-redhat-linux-gnu, GTK+ Version 3.24.8) of 2019-04-30

casouri commented 5 years ago

Thanks for your feedback.

First, when the mode is just started the box is extremely tiny (single letter) and no information is shown inside it (probably because it can't fit inside):

That's most possibly because the message function of eldoc-box is called with an empty string. I forgot the reason why I make eldoc-box display the childframe when the docstring is empty. Let me change that and see what happens (c97fe86).

It seems that eldoc-box uses size of previous box for a new box. E.g. if I hover on the flag variable:

That's not the case here. Eldoc-box uses window-text-pixel-size to determine the size of the childframe. When everything works well, that function gives a proper size. In the case of emacs-lisp-mode, I don't see the problem you are describing. Could you tell me the major mode and maybe the eglot backend that you are using?

andreyorst commented 5 years ago

In the case of emacs-lisp-mode, I don't see the problem you are describing.

I'm not using lsp-mode currently, but when I was using it I had no problems with lsp-ui which kinda does the same thing indeed. I find eglot more straightforward and lighweight.

Could you tell me the major mode and maybe the eglot backend that you are using?

On screenshots in my previous comment I'm using eglot with clangd for C major mode.

Exactly the same problems appear when I'm using RLS for Rust major mode:

image image

andreyorst commented 5 years ago

Another problem is that eldoc-box covers company:

image

casouri commented 5 years ago

Sorry for the delay. For company I can add a hook. But I still can't reproduce the first issue.

andreyorst commented 5 years ago

Can an issue being introducing by using certain window manager? I'm using Gnome, maybe in other DE, like KDE, or in another WM, like xfwm the issue isn't reproducible?

Edit: Yes, the popup quickly resizes in xfce4 always showing correctly, but in gnome it doesn't resize itself and displays truncated text as shown in screenshots in my previous comments.

casouri commented 5 years ago

What? I never thought windows managers have an influence on childframe resize, given they all use X11. In this case, it might be an Emacs-related bug. Are you interested in investigating more and report it?

andreyorst commented 5 years ago

What? I never thought windows managers have an influence on childframe resize, given they all use X11.

GNOME uses Wayland by defalut, but the issue can be reproduced under X11 session of GNOME too. Though, I don't know if XWayland is related, since I believe that Emacs is running under it in Wayland session.

Are you interested in investigating more and report it?

Not sure if I can provide full details if they ask. I'm pretty low on time lately. I believe I've already heard something related to different window managers and Emacs, that's why I thought about trying xfce in the first place.

casouri commented 5 years ago

GNOME uses Wayland by defalut, but the issue can be reproduced under X11 session of GNOME too. Though, I don't know if XWayland is related, since I believe that Emacs is running under it in Wayland session.

That makes sense. I don't know much about Linux so I assumed they all use X11. Emacs supports Wayland, IIRC.

Not sure if I can provide full details if they ask. I'm pretty low on time lately. I believe I've already heard something related to different window managers and Emacs, that's why I thought about trying xfce in the first place.

Just a suggestion. As I said, I don't know much about Linux. :smile:

andreyorst commented 5 years ago

I've remembered where I saw same issue which mentions GNOME and posframe: https://github.com/tumashu/company-posframe/issues/2

Can this issue be migrated by extra call to resize of the child frame?

casouri commented 5 years ago

You can reference this issue under that one, and maybe +1 on the original post. 😄

Update: I see this reference is shown in that issue, I guess that would work?

andreyorst commented 5 years ago

Update: I see this reference is shown in that issue, I guess that would work?

I dunno. I guess that this won't help to fix much, because that issue is about posframe, and you're not using it. I'm not sure if you need to use it though, but maybe if that issue will ever get closed by some fix, you could look if this fix could be applied for your implementation.

Also, what about doing extra redisplay in order to get correct size? Can I somehow patch your code in order to test if it solves my particular problem with childframe size?

casouri commented 5 years ago

I dunno. I guess that this won't help to fix much, because that issue is about posframe, and you're not using it. I'm not sure if you need to use it though, but maybe if that issue will ever get closed by some fix, you could look if this fix could be applied for your implementation.

That's a bit of miscommunication. 😄 But yeah, if that issue got solved, this one can definitely learn from it.

Also, what about doing extra redisplay in order to get correct size? Can I somehow patch your code in order to test if it solves my particular problem with childframe size?

Do you mean to hide the childframe and show it back very quickly? If you want to play with the source. Here's some information that might help:

andreyorst commented 5 years ago

Do you mean to hide the childframe and show it back very quickly?

Yes, since on the second call to childframe it appears to be correctly sized. I guess I can add second call to set-frame-size as a first possible workaround.

Upd. Nope, that doesn't help :D

Seems that this ugly hack solves the size problem for me: (advice-add 'eldoc-box--display :after 'eldoc-box-eglot-help-at-point)

casouri commented 5 years ago

Try add another call to make-frame-visible or even make-frame-invisible followed by make-frame-visible and see what happens.

casouri commented 5 years ago

@terlar I come up with a way to get what you want. There are still small annoyances, e.g., the childfame takes a timeout before disappearing when you move to a place that doesn't have a doc to show.

eldoc-box-at-point

You can try it here: https://github.com/casouri/eldoc-box/tree/follow-cursor

andreyorst commented 5 years ago

Also, I've noticed, that company-quickhelp, that uses pos-tip package doesn't have problem with changing size of a popup in GNOME Shell.

andreyorst commented 4 years ago

@casouri FYI there's a work been done to migrate the resize issue on Gnome and there's a patch linked in the thread in company-posframe issue I've mentioned before. The patch works for me, and I think it will be included to Emacs 27

casouri commented 4 years ago

Cool!