tumashu / ivy-posframe

ivy-posframe is a ivy extension, which let ivy use posframe to show its candidate menu, ivy-posframe is a **GNU ELPA** package.
414 stars 26 forks source link

How to avoid automatic width resizing? #105

Open gdindi opened 3 years ago

gdindi commented 3 years ago

Hi, I don't know if this is a desired behaviour, but the posframe width changes as I type (depending on the matches of the selection). Is there a way to ensure that the frame size does not change?

Thanks.

tumashu commented 3 years ago
(defun ivy-posframe-get-size ()
  "The default functon used by `ivy-posframe-size-function'."
  (list
   :height ivy-posframe-height
   :width ivy-posframe-width
   :min-height (or ivy-posframe-min-height
                   (let ((height (+ ivy-height 1)))
                     (min height (or ivy-posframe-height height))))
   :min-width (or ivy-posframe-min-width
                  (let ((width (round (* (frame-width) 0.62))))
                    (min width (or ivy-posframe-width width))))))
tumashu commented 3 years ago

customize ivy-posframe-size-function

gdindi commented 3 years ago

Hi, Thanks for your answer. Do you mean that I have to code a function myself? Or there are several choices already? I am not a lisp programmer, so I don't know how to do it myself. Thanks

tumashu commented 3 years ago

you can also set ivy-posframe-min-width to a big value, maybe useful

thomasheartman commented 3 years ago

@gdindi I came here looking for the exact same thing! Thankfully, the code snippet above was enough for me to figure it out. It seems the trick is to set width and min-width to the same value. I wrote this little bit which makes it behave as I want it to:

  (defun my-ivy-posframe-get-size ()
    "Set the ivy-posframe size according to the current frame."
    (let ((height (or ivy-posframe-height (or ivy-height 10)))
          (width (min (or ivy-posframe-width 200) (round (* .75 (frame-width))))))
      (list :height height :width width :min-height height :min-width width)))

  (setq ivy-posframe-size-function 'my-ivy-posframe-get-size)

This uses the ivy-posframe-height and ivy-posframe-width variables if they're set. Otherwise it uses the default ivy variables or falls back to values I find sensible. In short, it should make the posframe 10 rows tall and 200 columns or 75% of the current frame width (whichever is smaller). From playing around with it, at least, the size of the posframe appears to stay constant.

While the width is great, I'd love for the height to be dynamic based on the number of candidates that are available. I would have thought that setting min-height to something like 0 or 1 would make this work, but it doesn't work exactly as I'd expect. The posframe does change its height but not consistently and it will often leave some blank lines at the end.

For instance, it doesn't seem to resize when there are 6 candidates, but instead leaves 3 empty lines at the end. When filtering out even more candidates, the blank lines seem to remain until I get to about two candidates, after the height is only enough to fit the prompt and the candidates. @tumashu, do you have any insight to offer on this? Is there a better solution?

ellingtonjp commented 3 years ago

It seems like having a fixed width or fixed height might be popular. I personally think it feels a lot better fixed (especially width).

Anyone like exposing variables for this? Something like

(setq ivy-posframe-width-fixed t)  ; forces min-width == width
(setq ivy-posframe-height-fixed t) ; forces min-height == height

Also maybe something like the following, which makes it easy to specify "percentage of screen":

(setq ivy-posframe-width-relative t)
(setq ivy-posframe-height-relative t)
(setq ivy-posframe-width-relative-factor 0.62)
(setq ivy-posframe-height-relative-factor 0.1)
tumashu commented 3 years ago
It seems like having a fixed width or fixed height might be popular

I do not know :-)

ellingtonjp commented 3 years ago

Well, this thread has at least three fixed-width advocates 😛

I can submit a PR if you like the idea.

thomasheartman commented 3 years ago

While I can't speak for anyone else, I personally found it a bit confusing when the prompt was continually resizing and thought I had set something up wrong. I had expected it to stay the same size or at least for there to be a simple toggle for it. So based on that, I think it makes sense to expose some easy configuration options for the end users to tweak this themselves.

However, I have also just started using the project and don't have any stakes in it, so while I think it's a good idea, I also realize I don't have any say in the direction of the project and will not have to maintain any of the code. So it's definitely not up to me, but I do think it's a good idea.