[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 ()