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

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

[elpa] externals/corfu bfbe9ddf99 3/4: Add corfu-history and corfu-info


From: ELPA Syncer
Subject: [elpa] externals/corfu bfbe9ddf99 3/4: Add corfu-history and corfu-info extensions
Date: Wed, 13 Apr 2022 09:57:25 -0400 (EDT)

branch: externals/corfu
commit bfbe9ddf991ad846f8cabe3a0338919e5b2eb255
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>

    Add corfu-history and corfu-info extensions
---
 corfu.el                    |  56 ++----------------------
 extensions/corfu-history.el | 101 ++++++++++++++++++++++++++++++++++++++++++++
 extensions/corfu-indexed.el |   2 +-
 extensions/corfu-info.el    |  95 +++++++++++++++++++++++++++++++++++++++++
 extensions/corfu-quick.el   |  36 ++++++++--------
 5 files changed, 218 insertions(+), 72 deletions(-)

diff --git a/corfu.el b/corfu.el
index 403efa44e6..5daf7043ba 100644
--- a/corfu.el
+++ b/corfu.el
@@ -240,8 +240,8 @@ The completion backend can override this with
     (define-key map "\C-g" #'corfu-quit)
     (define-key map "\r" #'corfu-insert)
     (define-key map "\t" #'corfu-complete)
-    (define-key map "\eg" #'corfu-show-location)
-    (define-key map "\eh" #'corfu-show-documentation)
+    (define-key map "\eg" 'corfu-info-location)
+    (define-key map "\eh" 'corfu-info-documentation)
     (define-key map (concat "\e" " ") #'corfu-insert-separator) ;; Avoid ugly 
warning
     map)
   "Corfu keymap used when popup is shown.")
@@ -949,56 +949,6 @@ See `corfu-separator' for more details."
   (interactive)
   (corfu--goto (1- corfu--total)))
 
-(defun corfu--restore-on-next-command ()
-  "Restore window configuration before next command."
-  (let ((config (current-window-configuration))
-        (other other-window-scroll-buffer)
-        (restore (make-symbol "corfu--restore")))
-    (fset restore
-          (lambda ()
-            (setq other-window-scroll-buffer other)
-            (unless (memq this-command '(scroll-other-window 
scroll-other-window-down))
-              (when (memq this-command '(corfu-quit corfu-reset))
-                (setq this-command #'ignore))
-              (remove-hook 'pre-command-hook restore)
-              (set-window-configuration config))))
-    (add-hook 'pre-command-hook restore)))
-
-;; Company support, taken from `company.el', see `company-show-doc-buffer'.
-(defun corfu-show-documentation ()
-  "Show documentation of current candidate."
-  (interactive)
-  (when (< corfu--index 0)
-    (user-error "No candidate selected"))
-  (if-let* ((fun (plist-get corfu--extra :company-doc-buffer))
-            (res (funcall fun (nth corfu--index corfu--candidates))))
-      (let ((buf (or (car-safe res) res)))
-        (corfu--restore-on-next-command)
-        (setq other-window-scroll-buffer (get-buffer buf))
-        (set-window-start (display-buffer buf t) (or (cdr-safe res) 
(point-min))))
-    (user-error "No documentation available")))
-
-;; Company support, taken from `company.el', see `company-show-location'.
-(defun corfu-show-location ()
-  "Show location of current candidate."
-  (interactive)
-  (when (< corfu--index 0)
-    (user-error "No candidate selected"))
-  (if-let* ((fun (plist-get corfu--extra :company-location))
-            (loc (funcall fun (nth corfu--index corfu--candidates))))
-      (let ((buf (or (and (bufferp (car loc)) (car loc)) (find-file-noselect 
(car loc) t))))
-        (corfu--restore-on-next-command)
-        (setq other-window-scroll-buffer buf)
-        (with-selected-window (display-buffer buf t)
-          (save-restriction
-            (widen)
-            (if (bufferp (car loc))
-                (goto-char (cdr loc))
-              (goto-char (point-min))
-              (forward-line (1- (cdr loc))))
-            (set-window-start nil (point)))))
-    (user-error "No candidate location available")))
-
 (defun corfu-complete ()
   "Try to complete current input.
 If a candidate is selected, insert it."
@@ -1273,7 +1223,7 @@ The ORIG function takes the FUN and WHICH arguments."
 ;; Emacs 28: Do not show Corfu commands with M-X
 (dolist (sym '(corfu-next corfu-previous corfu-first corfu-last corfu-quit 
corfu-reset
                corfu-complete corfu-insert corfu-scroll-up corfu-scroll-down
-               corfu-show-location corfu-show-documentation 
corfu-insert-separator))
+               corfu-insert-separator))
   (put sym 'completion-predicate #'ignore))
 
 (provide 'corfu)
diff --git a/extensions/corfu-history.el b/extensions/corfu-history.el
new file mode 100644
index 0000000000..ff90779671
--- /dev/null
+++ b/extensions/corfu-history.el
@@ -0,0 +1,101 @@
+;;; corfu-history.el --- Sorting by history for Corfu -*- lexical-binding: t 
-*-
+
+;; Copyright (C) 2022  Free Software Foundation, Inc.
+
+;; Author: Daniel Mendler <mail@daniel-mendler.de>
+;; Maintainer: Daniel Mendler <mail@daniel-mendler.de>
+;; Created: 2021
+;; Version: 0.1
+;; Package-Requires: ((emacs "27.1") (corfu "0.21"))
+;; Homepage: https://github.com/minad/corfu
+
+;; This file is part of GNU Emacs.
+
+;; 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:
+
+;; Sort candidates by their history position. Maintain a list of
+;; recently selected candidates.
+
+;;; Code:
+
+(require 'corfu)
+
+(defcustom corfu-history-length nil
+  "Corfu history length."
+  :type '(choice (const nil) integer)
+  :group 'corfu)
+
+(defvar corfu-history--hash nil
+  "Hash table of Corfu candidates.")
+
+(defvar corfu-history nil
+  "History of Corfu candidates.")
+
+(defun corfu-history--sort-predicate (x y)
+  "Sorting predicate which compares X and Y."
+  (or (< (cdr x) (cdr y))
+      (and (= (cdr x) (cdr y))
+           (string< (car x) (car y)))))
+
+(defun corfu-history--sort (candidates)
+  "Sort CANDIDATES by history."
+  (unless corfu-history--hash
+    (let ((index 0))
+      (setq corfu-history--hash (make-hash-table :test #'equal :size (length 
corfu-history)))
+      (dolist (elt corfu-history)
+        (unless (gethash elt corfu-history--hash)
+          (puthash elt index corfu-history--hash))
+        (setq index (1+ index)))))
+  ;; Decorate each candidate with (index<<13) + length. This way we sort first 
by index and then by
+  ;; length. We assume that the candidates are shorter than 2**13 characters 
and that the history is
+  ;; shorter than 2**16 entries.
+  (let ((cand candidates))
+    (while cand
+      (setcar cand (cons (car cand)
+                         (+ (lsh (gethash (car cand) corfu-history--hash 
#xFFFF) 13)
+                            (length (car cand)))))
+      (pop cand)))
+  (setq candidates (sort candidates #'corfu-history--sort-predicate))
+  ;; Drop decoration from the candidates
+  (let ((cand candidates))
+    (while cand
+      (setcar cand (caar cand))
+      (pop cand)))
+  candidates)
+
+(defun corfu-history--insert (&rest _)
+  "Advice for `corfu--insert'."
+  (when (>= corfu--index 0)
+    (add-to-history 'corfu-history
+                    (nth corfu--index corfu--candidates)
+                    corfu-history-length)
+    (setq corfu-history--hash nil)))
+
+;;;###autoload
+(define-minor-mode corfu-history-mode
+  "Update Corfu history and sort completions by history."
+  :global t
+  :group 'corfu
+  (cond
+   (corfu-history-mode
+    (setq corfu-sort-function #'corfu-history--sort)
+    (advice-add #'corfu--insert :before #'corfu-history--insert))
+   (t
+    (setq corfu-sort-function #'corfu-sort-length-alpha)
+    (advice-remove #'corfu--insert #'corfu-history--insert))))
+
+(provide 'corfu-history)
+;;; corfu-history.el ends here
diff --git a/extensions/corfu-indexed.el b/extensions/corfu-indexed.el
index c88c23486d..19cf876574 100644
--- a/extensions/corfu-indexed.el
+++ b/extensions/corfu-indexed.el
@@ -6,7 +6,7 @@
 ;; Maintainer: Daniel Mendler <mail@daniel-mendler.de>
 ;; Created: 2022
 ;; Version: 0.1
-;; Package-Requires: ((emacs "27.1"))
+;; Package-Requires: ((emacs "27.1") (corfu "0.21"))
 ;; Homepage: https://github.com/minad/corfu
 
 ;; This file is part of GNU Emacs.
diff --git a/extensions/corfu-info.el b/extensions/corfu-info.el
new file mode 100644
index 0000000000..1662a916d7
--- /dev/null
+++ b/extensions/corfu-info.el
@@ -0,0 +1,95 @@
+;;; corfu-info.el --- Show candidate information in separate buffer -*- 
lexical-binding: t -*-
+
+;; Copyright (C) 2022  Free Software Foundation, Inc.
+
+;; Author: Daniel Mendler <mail@daniel-mendler.de>
+;; Maintainer: Daniel Mendler <mail@daniel-mendler.de>
+;; Created: 2021
+;; Version: 0.1
+;; Package-Requires: ((emacs "27.1") (corfu "0.21"))
+;; Homepage: https://github.com/minad/corfu
+
+;; This file is part of GNU Emacs.
+
+;; 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 Corfu extension provides commands to show additional information
+;; to the candidates in a separate buffer.
+
+;;; Code:
+
+(require 'corfu)
+(eval-when-compile
+  (require 'subr-x))
+
+(defun corfu-info--restore-on-next-command ()
+  "Restore window configuration before next command."
+  (let ((config (current-window-configuration))
+        (other other-window-scroll-buffer)
+        (restore (make-symbol "corfu--restore")))
+    (fset restore
+          (lambda ()
+            (setq other-window-scroll-buffer other)
+            (unless (memq this-command '(scroll-other-window 
scroll-other-window-down))
+              (when (memq this-command '(corfu-quit corfu-reset))
+                (setq this-command #'ignore))
+              (remove-hook 'pre-command-hook restore)
+              (set-window-configuration config))))
+    (add-hook 'pre-command-hook restore)))
+
+;;;###autoload
+(defun corfu-info-documentation ()
+  "Show documentation of current candidate."
+  (interactive)
+  ;; Company support, taken from `company.el', see `company-show-doc-buffer'.
+  (when (< corfu--index 0)
+    (user-error "No candidate selected"))
+  (if-let* ((fun (plist-get corfu--extra :company-doc-buffer))
+            (res (funcall fun (nth corfu--index corfu--candidates))))
+      (let ((buf (or (car-safe res) res)))
+        (corfu-info--restore-on-next-command)
+        (setq other-window-scroll-buffer (get-buffer buf))
+        (set-window-start (display-buffer buf t) (or (cdr-safe res) 
(point-min))))
+    (user-error "No documentation available")))
+
+;;;###autoload
+(defun corfu-info-location ()
+  "Show location of current candidate."
+  (interactive)
+  ;; Company support, taken from `company.el', see `company-show-location'.
+  (when (< corfu--index 0)
+    (user-error "No candidate selected"))
+  (if-let* ((fun (plist-get corfu--extra :company-location))
+            (loc (funcall fun (nth corfu--index corfu--candidates))))
+      (let ((buf (or (and (bufferp (car loc)) (car loc)) (find-file-noselect 
(car loc) t))))
+        (corfu-info--restore-on-next-command)
+        (setq other-window-scroll-buffer buf)
+        (with-selected-window (display-buffer buf t)
+          (save-restriction
+            (widen)
+            (if (bufferp (car loc))
+                (goto-char (cdr loc))
+              (goto-char (point-min))
+              (forward-line (1- (cdr loc))))
+            (set-window-start nil (point)))))
+    (user-error "No candidate location available")))
+
+;; Emacs 28: Do not show Corfu commands with M-X
+(put #'corfu-info-location 'completion-predicate #'ignore)
+(put #'corfu-info-documentation 'completion-predicate #'ignore)
+
+(provide 'corfu-info)
+;;; corfu-info.el ends here
diff --git a/extensions/corfu-quick.el b/extensions/corfu-quick.el
index 5dbacd42f2..7c824904ee 100644
--- a/extensions/corfu-quick.el
+++ b/extensions/corfu-quick.el
@@ -2,11 +2,11 @@
 
 ;; Copyright (C) 2021  Free Software Foundation, Inc.
 
-;; Author: Luis Henriquez-Perez <luis@luishp.xyz>
+;; Author: Luis Henriquez-Perez <luis@luishp.xyz>, Daniel Mendler 
<mail@daniel-mendler.de>
 ;; Maintainer: Daniel Mendler <mail@daniel-mendler.de>
 ;; Created: 2022
-;; Version: 0.19
-;; Package-Requires: ((emacs "27.1"))
+;; Version: 0.1
+;; Package-Requires: ((emacs "27.1") (corfu "0.21"))
 ;; Homepage: https://github.com/minad/corfu
 
 ;; This file is part of GNU Emacs.
@@ -72,22 +72,22 @@ the candidate that corresponds to QUICK-KEYS.")
 (defun corfu-quick--keys (index)
   "Return `corfu-quick' keys for candidate at INDEX."
   (let ((length1 (seq-length corfu-quick1))
-       (length2 (seq-length corfu-quick2))
-       (key1 "")
-       (key2 ""))
+        (length2 (seq-length corfu-quick2))
+        (key1 "")
+        (key2 ""))
     (if (< index length1)
-       (setq key1 (char-to-string (seq-elt corfu-quick1 index)))
+        (setq key1 (char-to-string (seq-elt corfu-quick1 index)))
       (setq key1 (char-to-string (seq-elt corfu-quick1 (% (- index length1) 
length1))))
       (setq key2 (char-to-string (seq-elt corfu-quick2 (% (- index length1) 
length2)))))
     (concat (propertize key2 'face 'corfu-quick1)
-           (propertize key1 'face 'corfu-quick2))))
+            (propertize key1 'face 'corfu-quick2))))
 
 (defun corfu-quick--format-candidates (orig candidates)
   "Advice for `corfu--format-candidates' that adds quick keys to candidates.
 See `corfu--format-candidates'."
   (let ((updated-candidates nil)
-       (quick-keys nil)
-       (index 0))
+        (quick-keys nil)
+        (index 0))
     (setq corfu-quick--alist nil)
     (pcase-dolist (`(,candidate ,prefix ,suffix) candidates)
       (setq quick-keys (corfu-quick--keys index))
@@ -100,18 +100,18 @@ See `corfu--format-candidates'."
 (defun corfu-quick--read ()
   "Read quick keys and return index of candidate specified by quick keys."
   (cl-letf* ((old-fn (symbol-function #'corfu--format-candidates))
-            (new-fn (apply-partially #'corfu-quick--format-candidates old-fn))
-            ((symbol-function #'corfu--format-candidates) new-fn))
+             (new-fn (apply-partially #'corfu-quick--format-candidates old-fn))
+             ((symbol-function #'corfu--format-candidates) new-fn))
     (corfu--candidates-popup (point))
     (let* ((key (read-key))
-          (quick-keys (char-to-string key)))
+           (quick-keys (char-to-string key)))
       (when (seq-contains-p corfu-quick2 key)
-       (cl-letf* ((orig-fn (symbol-function #'corfu-quick--keys))
-                  ((symbol-function #'corfu-quick--keys) (lambda (index) 
(seq-rest (funcall orig-fn index)))))
-         (corfu--candidates-popup (point)))
-       (setq quick-keys (char-to-string (read-key))))
+        (cl-letf* ((orig-fn (symbol-function #'corfu-quick--keys))
+                   ((symbol-function #'corfu-quick--keys) (lambda (index) 
(seq-rest (funcall orig-fn index)))))
+          (corfu--candidates-popup (point)))
+        (setq quick-keys (char-to-string (read-key))))
       (or (alist-get quick-keys corfu-quick--alist 0 nil #'string=)
-         (corfu-quick-exit)))))
+          (corfu-quick-exit)))))
 
 ;;;###autoload
 (defun corfu-quick-jump ()



reply via email to

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