tumashu / vertico-posframe

GNU General Public License v3.0
114 stars 16 forks source link

Disable vertico-posframe when Emacs runs in terminal #16

Closed innerout closed 1 year ago

innerout commented 2 years ago

Hello, I am using doom-emacs with vertico-posframe. There is a case where I am using the same configuration via GUI or ssh. In the case of the ssh, posframe cannot be used since posframes are available only in GUI. Could vertico-posframe detect when Emacs starts in TUI and auto-disable itself, or should I check it in my personal configuration? I believe this could benefit all the users of posframe packages.

draxil commented 2 years ago

You can work around this like (in my case using use-package, but however you activate vertico inside the if:

(if (window-system)
      (use-package vertico-posframe
    :init
    (vertico-posframe-mode)))
basaran commented 2 years ago

This wouldn't help when running emacs as a daemon, and launching the client inside the terminal. There appears to be a fix for the ivy-posframe but not sure if it is in vertico-posframe.

https://github.com/tumashu/ivy-posframe/pull/53

llmII commented 1 year ago

I currently use this "hack" to fix it to work in terminal or gui with Doom Emacs. There is likely a better way to do it rather than override internal functions of vertico-posframe but... I'm lazy and it works and might suffice as just enough effort for someone to generate something more appropriate seeing as my elisp-fu is definitely not sufficient to be contributing to packages aside from suggestions:

(after! vertico-posframe
  (when vertico-posframe-mode
    (advice-remove #'vertico--display-candidates #'vertico-posframe--display)
    (advice-add #'vertico--display-candidates :after #'vertico-posframe--display))

  (defun vertico-posframe--display (_lines)
    "Display _LINES in posframe. But only if not terminal."
    (when (display-graphic-p)
      (let ((buffer (current-buffer))
            (point (point)))
        (setq vertico-posframe--buffer buffer)
        (vertico-posframe--handle-minibuffer-window)
        (vertico-posframe--show buffer point)))))

Of course the after! is Doom specific. The point of testing for vertico-posframe-mode and redoing advices is because the advice references the original function prior to it being overridden. The effectual change is wrapping the body of the original function in (when (display-graphics-p) ,@orginal-body).

On a parting note, this works in emacs server mode with frames both in terminal and graphical mode from my really abbreviated testing.

llmII commented 1 year ago

A better way, with advice, again Doom specific (yet easily extrapolated into a workable solution otherwise) below:

(after! vertico-posframe
  (defun drop-vertico-posframe-nongraphical (orig &rest args)
    (when (display-graphic-p)
      (apply orig args)))
  (advice-add  #'vertico-posframe--display
               :around #'drop-vertico-posframe-nongraphical))
llmII commented 1 year ago

Also, considering PR #22, wouldn't it be easier if perhaps there was a pre-display hook that vertico-posframe--display checked that basically allows for cancellation of display in posframe dependent upon the hook's return value. Suggesting a name (I tend to suck at naming), perhaps vertico-posframe-should-display-hook? I could also be possibly shooting in the dark and determining an incorrect location for hook to be checked.

tumashu commented 1 year ago

Maybe we can use vertico-multiform to realisze this feature.

tumashu commented 1 year ago

Update to vertico-posframe git, and try the below code:

(require 'vertico-posframe)
(require 'vertico-multiform)

(setq vertico-multiform-commands
      '((consult-line
         posframe
         (vertico-posframe-poshandler . posframe-poshandler-frame-top-center))
        (t posframe)))

(vertico-multiform-mode 1)
tumashu commented 1 year ago

@innerout you can try new feature, maybe useful :-)

llmII commented 1 year ago

@tumashu : The recent commit would work without dependence on vertico-multiform-mode? (from a quick overview I believe it would but am no certain if that commit is separate to your prior recommendation as to what to do with the code block referring to multiform).

If so, going to look at how to override Doom's package pins to get the latest commit and check if it invalidates my prior hack. I was fairly certain my solution was far from optimal, so am glad you've come up with one that's more appropriate!

tumashu commented 1 year ago

@llmII can work, but, if you use emacs service, it may be not work well without vertico-multiform-mode

llmII commented 1 year ago

@tumashu you mean that the new mode (the one that maps to #'ignore isn't a buffer local mode, that it enables globally? I asks because if that's the case then the way I went about it, albeit invoking a check every time, did permit it to work in server mode with clients that are both graphical and terminal based. I may just have to try it instead of keeping asking questions, just no time tonight sadly. When I do try it I'll update as to how it works for me in the use case I've mentioned here.

tumashu commented 1 year ago

@llmII if so, you need vertico-multiform-mode, for multiform-mode will call vertico-posframe-mode when a command is called, instead of start of emacs.

llmII commented 1 year ago

@tumashu I see it now at L#341. If one visits a buffer in terminal mode first... I'd assume it would mean that posframe is always disabled for that buffer. Kind of need more of a frame local (but I also think those were removed from emacs so no such luck, that and doesn't help when a frame can be moved between clients if my thinking is correct).

The big thing with vertico-multiform-mode is I'm unsure if I need to define things for every thing vertico is tied into or if the one thing concerning posframe is enough to effect everything without throwing anything else off. I'll have to investigate that, then determine if I feel I must again do a work around. I'll update tomorrow when I try.

Thanks for the help and discussion with regard to this matter, I truly appreciate your input.

tumashu commented 1 year ago

@llmII not this mean, if you add vertico-posframe-mode to .emacs, when you start emacs daemon, vertico-posframe-mode will call fallback, for posframe-workable-p will nil when emacs daemon start. in this time you can not use vertico-posframe in emacs gtk.

with the help of vertico-multiform, vertico-posframe-mode will delay enable to command called, in this time posframe-workable-p will t when in emacs-gtk, and nil when emacs tui.

tumashu commented 1 year ago

you can try the below example first, I have testd in emacs daemon, seem to work.

(setq vertico-multiform-commands
      '((consult-line
         posframe
         (vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
         (vertico-posframe-border-width . 10)
         ;; NOTE: This is useful when emacs is used in both in X and
         ;; terminal, for posframe do not work well in terminal, so
         ;; vertico-buffer-mode will be used as fallback at the
         ;; moment.
         (vertico-posframe-fallback-mode . vertico-buffer-mode))
        (t posframe)))

(vertico-multiform-mode 1)
llmII commented 1 year ago

@tumashu I can confirm that that does work in all the situations I care about (outlined below in case it helps others)

It is quite a bit more configuration work with Doom Emacs. Process overview below in case it helps others.

Thanks again @tumashu!

innerout commented 1 year ago

I will unpin the dependency in doom and test if things keep working. I will report back if anything breaks. Thanks for your work @tumashu !