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
Add ivy-display-schemes and use it. #1443
Conversation
I want to create a ivy-posframe which is very similar ivy-overlay, so I need this ivy feature :-) |
This is a init version of ivy-posframe: https://github.com/tumashu/ivy-posframe/blob/master/ivy-posframe.el, you can as a test example, |
ivy.el
Outdated
'((ivy-overlay | ||
:display ivy-display-function-overlay | ||
:cleanup ivy-overlay-cleanup)) | ||
"An alist of display schemes.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about providing a bit more information with something like "Map display schemes to their property list."
ivy.el
Outdated
@@ -1661,7 +1667,8 @@ customizations apply to the current completion session." | |||
collection)))) | |||
(ivy-display-function | |||
(unless (window-minibuffer-p) | |||
(cdr (assoc caller ivy-display-functions-alist))))) | |||
(cdr (or (assoc caller ivy-display-functions-alist) | |||
(assoc t ivy-display-functions-alist)))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use assq
instead of assoc
for both of these calls.
ivy.el
Outdated
ivy-display-function)) | ||
(setq func (plist-get plist action))))) | ||
(when (functionp func) | ||
(funcall func)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not
(defun ivy-display-scheme-call (action)
"Call ACTION property associated with `ivy-display-function'."
(when ivy-display-function
(let* ((scheme (cl-rassoc-if (lambda (plist)
(eq (plist-get plist :display)
ivy-display-function))
ivy-display-schemes))
(action (plist-get (cdr scheme) action)))
(when (functionp action)
(funcall action)))))
Guaranteed 100% untested.
Fixed, please check again :-) |
Thanks. Wouldn't the following be slightly simpler and cleaner, without any loss of generality? diff --git a/ivy.el b/ivy.el
index 4e91f7f..1f3e5b2 100644
--- a/ivy.el
+++ b/ivy.el
@@ -1661,7 +1661,8 @@ ivy-read
collection))))
(ivy-display-function
(unless (window-minibuffer-p)
- (cdr (assoc caller ivy-display-functions-alist)))))
+ (cdr (or (assq caller ivy-display-functions-alist)
+ (assq t ivy-display-functions-alist))))))
(setq ivy-last
(make-ivy-state
:prompt prompt
@@ -1721,8 +1722,9 @@ ivy-read
(cdr (symbol-value hist))))))))
(ivy-state-current ivy-last)))
(remove-hook 'post-command-hook #'ivy--queue-exhibit)
- (when (eq ivy-display-function 'ivy-display-function-overlay)
- (ivy-overlay-cleanup))
+ (let ((cleanup (ivy--display-function-prop :cleanup)))
+ (when (functionp cleanup)
+ (funcall cleanup)))
(when (setq unwind (ivy-state-unwind ivy-last))
(funcall unwind))
(unless (eq ivy-exit 'done)
@@ -2398,6 +2400,15 @@ ivy-fixed-height-minibuffer
:type 'boolean)
;;** Rest
+(defvar ivy--display-function-props
+ '((ivy-display-function-overlay :cleanup ivy-overlay-cleanup))
+ "Map `ivy-display-function' values to their property lists.")
+
+(defun ivy--display-function-prop (prop)
+ "Return PROP associated with current `ivy-display-function'."
+ (plist-get (cdr (assq ivy-display-function ivy--display-function-props))
+ prop))
+
(defcustom ivy-truncate-lines t
"Minibuffer setting for `truncate-lines'."
:type 'boolean) |
I like the |
* ivy.el (ivy-read): Using function associated to t of ivy-display-functions-alist as fallback function.
Changed, the different is: |
@@ -196,6 +196,12 @@ See https://github.com/abo-abo/swiper/wiki/ivy-display-function." | |||
(const :tag "Popup" ivy-display-function-popup) | |||
(const :tag "Overlay" ivy-display-function-overlay))) | |||
|
|||
(defvar ivy-display-functions-props |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ivy-display-function-props
(singular) is better grammar than ivy-display-functions-props
here.
ivy.el
Outdated
'((ivy-display-function-overlay :cleanup ivy-overlay-cleanup)) | ||
"Map display functions of ivy to theirs action property lists. | ||
These actions are functions which work closely with display functions, | ||
for example: cleanup action functions.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to write:
"Map Ivy display functions to their property lists.
Examples of properties include associated `:cleanup' functions."
There's no reason to limit this alist to "action" functions.
I prefer to functions is:
|
Right |
ivy.el
Outdated
Note: this variable is used to config global display function, | ||
If user want to set a command's display function, for example: | ||
the display function used by ivy-completion-in-region, please | ||
use `ivy-display-functions-alist' instead." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good opportunity to improve the whole docstring:
"Determine where to display candidates.
When nil (the default), candidates are shown in the minibuffer.
Otherwise, this can be set to a function which takes a string
argument comprising the current matching candidates and displays
it somewhere.
This user option acts as a global default for Ivy-based
completion commands. You can customize the display function on a
per-command basis via `ivy-display-functions-alist', which see.
See also URL
`https://github.com/abo-abo/swiper/wiki/ivy-display-function'."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool
(cdr (assoc caller ivy-display-functions-alist))))) | ||
(or ivy-display-function | ||
(cdr (or (assq caller ivy-display-functions-alist) | ||
(assq t ivy-display-functions-alist))))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't the first operand in (or ivy-display-function ...)
make it impossible to customise ivy-display-function
on a per-command basis?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If user want to config per-command function, they should use ivy-display-functions-alist and set ivy-display-function to nil.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a bad idea for two important reasons:
- It is a breaking change.
- It makes
ivy-display-function
redundant for any setting other thannil
, as the user will have to customiseivy-display-functions-alist
for every single command they use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On further inspection, I'm not quite sure what the intended interplay between ivy-display-function
and ivy-display-functions-alist
is at the moment, so I retract my last comment and defer to @abo-abo for comment.
Some comments/questions/observations:
ivy-display-function
is also used inivy--insert-minibuffer
.- Why do we check for
window-minibuffer-p
beforelet
-bindingivy-display-function
? Could this be simplified as a lookup intoivy-display-functions-alist
, in whichivy-display-function
is mapped to by the fallback keyt
? - If
window-minibuffer-p
is necessary, shouldn't it be(minibuffer-window-active-p (selected-window))
instead, seeing as there can be multiple minibuffer windows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe ivy-display-functions-alist should override ivy-display-function :-)
but this seem to have other problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We check window-minibuffer-p
because the only viable display function (other than nil
) at the time was ivy-display-function-overlay
, which doesn't make sense to use when you press TAB
while in the minibuffer.
Fair enough, I guess it can't be helped (except via varaliases, but that would be overkill).
Sure, but "display function properties" is correct grammar even when talking about more than one display function, whereas "display functions properties" is technically incorrect. Obviously this doesn't matter much in a programming context, I'm just pedantic. :) |
If no the problem I said, function is good too:-), for me, functions or function is no different for my poor English :-) |
No I agree with you that it is more important to be consistent with This is why I said "fair enough, I guess it can't be helped." |
... |
* ivy.el (ivy--display-function-prop): New function. (ivy-display-functions-props): New variable. (ivy-read): Use ivy--display-function-prop to get cleanup function.
* ivy.el (ivy-display-function): Update docstring, ivy-display-function is used set global display function now. (ivy-read): Use ivy-display-function first if it is non-nil.
Thanks god, magit-rebase save me ... |
https://github.com/abo-abo/swiper/wiki/ivy-display-function is incorrect, the fact is that if you want to use a display-function, you should set ivy-display-function and add your commands to ivy-display-functions-alist. :-( It seem to be a bug ... |
Yeah, that's why I'm not so certain about the correct solution, as described here: #1443 (comment). |
Merged, thanks. Refinement PRs are welcome, as usual. |
(ivy-read): Use ivy-dispatching-call to clean up.
(ivy-display-scheme-call): New function.