emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master d1de20f 193/348: Display completion-at-point at point


From: Oleh Krehel
Subject: [elpa] master d1de20f 193/348: Display completion-at-point at point
Date: Sat, 8 Apr 2017 11:03:53 -0400 (EDT)

branch: master
commit d1de20f76168504515f9dd632e5234304fb53323
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Display completion-at-point at point
    
    * ivy.el (ivy-display-function): New defcustom, which decides how to
      display the candidates.
    (ivy-completion-in-region):
    1. Bind `ivy-display-function' to `ivy-overlay'.
    2. Bind `ivy--prompts-list' so that the number of candidates
       is not displayed any more (the idea is to have a completely static
       minibuffer and look at point instead of at the minibuffer).
    3. Add `ivy-overlay-cleanup' to :unwind.
    4. Add :caller.
    
    (ivy-flip): Remove, now generalized to `ivy-display-function'.
    
    (ivy--insert-minibuffer): Forward to `ivy-display-function'.
    
    * ivy-display.el (ivy-display-function-lv): New defun. Corresponds to
      the old `ivy-flip'.
    
    (ivy-display-function-popup): New defun. Experiment with `popup-tip'.
    
    * ivy-overlay.el (ivy-overlay-at): New defvar.
    (ivy-left-pad):
    (ivy-overlay-cleanup):
    (ivy-overlay-show-after): New defun.
    
    (ivy-overlay): New defun. Remove all visible updates in the minibuffer.
    1. Ensure the prompt function does nothing, e.g. redisplaying the amount
       of candidates.
    2. Set the minibuffer text foreground to white.
    3. Hide the cursor in the minibuffer.
---
 ivy-display.el | 45 +++++++++++++++++++++++++++++++++++
 ivy-overlay.el | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ivy.el         | 38 ++++++++++++++++-------------
 3 files changed, 142 insertions(+), 16 deletions(-)

diff --git a/ivy-display.el b/ivy-display.el
new file mode 100644
index 0000000..18997a9
--- /dev/null
+++ b/ivy-display.el
@@ -0,0 +1,45 @@
+;;; ivy-display.el --- Experimental display functions for Ivy  -*- 
lexical-binding: t; -*-
+
+;; Copyright (C) 2016  Oleh Krehel
+
+;; Author: Oleh Krehel <address@hidden>
+;; Keywords: convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package experiments with using other packages' display
+;; functions for Ivy.
+
+;;; Code:
+(require 'lv nil t)
+(require 'popup nil t)
+
+(defun ivy-display-function-lv (text)
+  (let ((lv-force-update t))
+    (lv-message
+     (if (string-match "\\`\n" text)
+         (substring text 1)
+       text))))
+
+(defun ivy-display-function-popup (text)
+  (with-ivy-window
+    (popup-tip
+     (setq ivy-insert-debug
+           (substring text 1))
+     :nostrip t)))
+
+(provide 'ivy-display)
+;;; ivy-display.el ends here
diff --git a/ivy-overlay.el b/ivy-overlay.el
new file mode 100644
index 0000000..7a45137
--- /dev/null
+++ b/ivy-overlay.el
@@ -0,0 +1,75 @@
+;;; ivy-overlay.el --- Overlay display functions for Ivy  -*- lexical-binding: 
t; -*-
+
+;; Copyright (C) 2016  Oleh Krehel
+
+;; Author: Oleh Krehel <address@hidden>
+;; Keywords: convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package allows to setup Ivy's completion at point to actually
+;; show the candidates and the input at point, instead of in the
+;; minibuffer.
+
+;;; Code:
+(defvar ivy-overlay-at nil
+  "Overlay variable for `ivy-display-function-overlay'.")
+
+(defun ivy-left-pad (str width)
+  "Pad STR from left with WIDTH spaces."
+  (let ((padding (make-string width ?\ )))
+    (mapconcat (lambda (x) (concat padding x))
+               (split-string str "\n")
+               "\n")))
+
+(defun ivy-overlay-cleanup ()
+  "Clean up after `ivy-display-function-overlay'."
+  (when (overlayp ivy-overlay-at)
+    (delete-overlay ivy-overlay-at)
+    (setq ivy-overlay-at nil))
+  (setq cursor-type t))
+
+(defun ivy-overlay-show-after (str)
+  "Display STR in an overlay at point.
+
+First, fill each line of STR with spaces to the current column.
+Then attach the overlay the character before point."
+  (if ivy-overlay-at
+      (progn
+        (move-overlay ivy-overlay-at (1- (point)) (line-end-position))
+        (overlay-put ivy-overlay-at 'invisible nil))
+    (setq ivy-overlay-at (make-overlay (1- (point)) (line-end-position)))
+    (overlay-put ivy-overlay-at 'priority 9999))
+  (overlay-put ivy-overlay-at 'display str)
+  (overlay-put ivy-overlay-at 'after-string ""))
+
+(defun ivy-display-function-overlay (str)
+  "Called from the minibuffer, display STR in an overlay in Ivy window.
+Hide the minibuffer contents and cursor."
+  (add-face-text-property (minibuffer-prompt-end) (point-max)
+                          '(:foreground "white"))
+  (setq cursor-type nil)
+  (with-ivy-window
+    (setq cursor-type nil)
+    (ivy-overlay-show-after
+     (concat
+      (buffer-substring (1- (point)) (point))
+      ivy-text
+      (buffer-substring (point) (line-end-position))
+      (ivy-left-pad str (current-column))))))
+
+(provide 'ivy-overlay)
+;;; ivy-overlay.el ends here
diff --git a/ivy.el b/ivy.el
index e11e8d9..e8c4c8b 100644
--- a/ivy.el
+++ b/ivy.el
@@ -39,6 +39,7 @@
 ;;; Code:
 (require 'cl-lib)
 (require 'ffap)
+(require 'ivy-overlay)
 
 ;;* Customization
 (defgroup ivy nil
@@ -172,6 +173,16 @@ Only \"./\" and \"../\" apply here. They appear in reverse 
order."
   "When non-nil, add `recentf-mode' and bookmarks to `ivy-switch-buffer'."
   :type 'boolean)
 
+(defcustom ivy-display-function nil
+  "Decide where to display the candidates.
+This function takes a string with the current matching candidates
+and has to display it somewhere."
+  :type '(choice
+          (const :tag "Minibuffer" nil)
+          (const :tag "LV" ivy-display-function-lv)
+          (const :tag "Popup" ivy-display-function-popup)
+          (const :tag "Overlay" ivy-display-function-overlay)))
+
 (defvar ivy--actions-list nil
   "A list of extra actions per command.")
 
@@ -1755,7 +1766,12 @@ The previous string is between `ivy-completion-beg' and 
`ivy-completion-end'."
          (str (buffer-substring-no-properties start end))
          (completion-ignore-case case-fold-search)
          (comps
-          (completion-all-completions str collection predicate (- end start))))
+          (completion-all-completions str collection predicate (- end start)))
+         (ivy-display-function (unless (window-minibuffer-p)
+                                 #'ivy-display-function-overlay))
+         (ivy--prompts-list (if (window-minibuffer-p)
+                                ivy--prompts-list
+                              '(ivy-completion-in-region (lambda nil)))))
     (if (null comps)
         (message "No matches")
       (let ((len (min (ivy-completion-common-length (car comps))
@@ -1783,7 +1799,9 @@ The previous string is between `ivy-completion-beg' and 
`ivy-completion-end'."
                        (mapcar #'substring-no-properties comps)
                        :predicate predicate
                        :action #'ivy-completion-in-region-action
-                       :require-match t)
+                       :unwind #'ivy-overlay-cleanup
+                       :require-match t
+                       :caller 'ivy-completion-in-region)
              t)))))))
 
 (defcustom ivy-do-completion-in-region t
@@ -2218,14 +2236,6 @@ Should be run via minibuffer `post-command-hook'."
           (ivy--filter ivy-text ivy--all-candidates))))
       (setq ivy--old-text ivy-text))))
 
-(defvar ivy-flip (and (require 'lv nil t)
-                      nil)
-  "When non-nil, the candidates are above the input, instead of below.
-This depends on `lv' feature provided by the package `hydra'.")
-
-(defvar lv-force-update)
-(declare-function lv-message "ext:lv")
-
 (defun ivy--insert-minibuffer (text)
   "Insert TEXT into minibuffer with appropriate cleanup."
   (let ((resize-mini-windows nil)
@@ -2238,12 +2248,8 @@ This depends on `lv' feature provided by the package 
`hydra'.")
     (ivy--insert-prompt)
     ;; Do nothing if while-no-input was aborted.
     (when (stringp text)
-      (if ivy-flip
-          (let ((lv-force-update t))
-            (lv-message
-             (if (string-match "\\`\n" text)
-                 (substring text 1)
-               text)))
+      (if ivy-display-function
+          (funcall ivy-display-function text)
         (let ((buffer-undo-list t))
           (save-excursion
             (forward-line 1)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]