Skip to content

Instantly share code, notes, and snippets.

@minad
Created February 2, 2021 19:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save minad/81cfb7c8b060a587c6ee6763afd87012 to your computer and use it in GitHub Desktop.
Save minad/81cfb7c8b060a587c6ee6763afd87012 to your computer and use it in GitHub Desktop.
;; -*- lexical-binding: t -*-
;; Completion Overlay in Region FUnction
(defun corfu--show (pos lines)
(let* ((width (if lines (apply #'max (mapcar #'string-width lines)) 0))
(beg (line-beginning-position))
(col (- pos beg))
(overlays))
(save-excursion
(dolist (line lines overlays)
(forward-line)
(let* ((beg (line-beginning-position))
(end (line-end-position))
(prefix (and (> col (- end beg)) (make-string (- col (- end beg)) 32)))
(ov
(if prefix
(make-overlay end end)
(make-overlay (min (+ beg col) end) (min (+ beg col width) end))))
(str (concat
line
(make-string (- width (string-width line)) 32))))
(add-face-text-property 0 (length str) '(:background "#f0f0f0" :foreground "#2288ff") t str)
(overlay-put ov 'priority 200)
(overlay-put ov 'window (selected-window))
(overlay-put ov 'invisible t)
(overlay-put ov 'after-string (if prefix (concat prefix str) str))
(push ov overlays))))))
(defun corfu--hide (popup)
(mapc #'delete-overlay popup))
(defun corfu-completion-in-region (start end collection &optional predicate)
(catch 'quit
(let* ((initial (buffer-substring-no-properties start end))
(limit (car (completion-boundaries initial collection predicate "")))
(metadata (completion-metadata initial collection predicate))
(all (completion-all-completions initial collection predicate
(length initial)))
(exit-status 'finished)
(completion
(cond
((atom all) nil)
((and (consp all) (atom (cdr all)))
(setq exit-status 'sole)
(concat (substring initial 0 limit) (car all)))
(t
(let ((popup)
(key)
(selected (car all))
(input-overlay (make-overlay start end))
(input initial)
(all (nconc all nil)))
(unwind-protect
(catch 'okay
(while t
(overlay-put input-overlay 'display input)
(corfu--hide popup)
(setq popup (corfu--show start (seq-take all 10)))
(setq key (read-key nil))
(when (eq key ?\C-g) (throw 'quit nil))
(when (eq key ?\C-m) (throw 'okay selected))
(when (eq key ?\t) (throw 'okay selected))
(when (or (not (characterp key)) (< key 32) (= key 127))
(run-at-time 0 nil (lambda () (setq unread-command-events (append unread-command-events (list key)))))
(throw 'quit t))
(setq input (concat input (char-to-string key)))
(setq limit (car (completion-boundaries input collection predicate "")))
(setq metadata (completion-metadata input collection predicate))
(setq all (nconc (completion-all-completions input collection predicate
(length input))
nil))
(setq selected (if (member selected all) selected (car all)))))
(corfu--hide popup)
(delete-overlay input-overlay)))))))
(if (null completion)
(progn (message "No completion") nil)
(delete-region start end)
(insert (substring-no-properties completion))
(when-let (exit (plist-get completion-extra-properties :exit-function))
(funcall exit completion exit-status))
t))))
(setq completion-in-region-function #'corfu-completion-in-region)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment