-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhippie-completing-read.el
118 lines (101 loc) · 4.98 KB
/
hippie-completing-read.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
;;; hippie-completing-read.el --- Peace love complete -*- lexical-binding: t; -*-
;; Copyright (C) 2021--2022 Case Duckworth
;; Author: Case Duckworth <[email protected]>
;; License: Fair
;; URL: https://codeberg.org/acdw/hippie-completing-read.el
;; Package-Version: 0.3
;; Package-Requires: ((emacs "24.3"))
;;; Commentary:
;; Adapted from https://www.emacswiki.org/emacs/HippieExpand#h5o-11, this
;; allows completing with `hippie-expand' using `completing-read'.
;;; Code:
(require 'cl-lib)
(require 'hippie-exp)
(defgroup hippie-completing-read nil
"Use Hippie Expansion from a Completing Read interface."
:group 'hippie-expand
:group 'completion
:prefix "hippie-completing-read-")
(defcustom hippie-completing-read-prompt "Hippie: "
"The prompt to display with `hippie-completing-read-expand-with'."
:type 'string)
(defcustom hippie-completing-read-function 'completing-read
"Function to use to display and select from `hippie-expand' selections.
Should be compatible with `completing-read'."
:type 'function)
(defcustom hippie-completing-read-function-parameters '(nil ; predicate
nil ; require-match
;; initial-input
he-search-string)
"Further parameters to pass to `hippie-completing-read-function'.
By default, add `he-search-string' (the thing we're completing)
as initial input.
This variable is risky, since its values are evaluated when passed to `hippie-completing-read'."
:type 'list
:risky t)
(defcustom hippie-completing-read-threshold 0
"Number of expansion candidates needed before using `completing-read'.
The more traditional \"cycling\" behavior for hippie-complete
will be used so long as there are not more completion candidates
than in this number."
:type '(integer :tag "Threshold"))
(define-obsolete-variable-alias 'hippie-completing-read-cycle-threshold
'hippie-completing-read-threshold
"0.3"
"Number of expansion candidates needed before using `completing-read'.")
(defun hippie-completing-read-expand-completions
(&optional hippie-expand-function)
"Return the full list of possible completions generated by `hippie-expand'.
The optional HIPPIE-EXPAND-FUNCTION argument can be generated
with `make-hippie-expand-function'."
(let ((this-command 'hippie-completing-read-expand-completions)
(last-command last-command)
(buffer-modified (buffer-modified-p))
(hippie-expand-function (or hippie-expand-function 'hippie-expand)))
(cl-letf (((symbol-function 'ding) #'ignore))
;; inhibit ding when `hippie-expand' exhausts completions
(while (progn
(funcall hippie-expand-function nil)
(setq last-command 'hippie-completing-read-expand-completions)
(not (equal he-num -1)))))
;; Evaluating the completions modifies the buffer, however we will finish
;; up in the same state that we began.
(set-buffer-modified-p buffer-modified)
;; Provide the options in the order in which they are normally generated.
(delete he-search-string (reverse he-tried-table))))
(defun hippie-completing-read-expand-with (hippie-expand-function)
"Offer `completing-read' based completion using `hippie-expand'.
The supplied HIPPIE-EXPAND-FUNCTION will provide completion items."
(let ((collection (hippie-completing-read-expand-completions
hippie-expand-function)))
(if collection
(if (> (length collection)
;; This test is necessary for full backward-compatibility;
;; originally the variable was
;; `hippie-completing-read-cycle-threshold' and could also take
;; values t, nil, and `inherit' (where it would inherit from
;; `completing-read-cycle-threshold' --- which turns out to be
;; nonexistent, at least in Emacs 28. So this code checks if
;; `hippie-completing-read-threshold' is a number, and if not,
;; uses 0 --- effectively enabling the completing-read UI in all
;; cases. (CD 2022-07-26)
(if (numberp hippie-completing-read-threshold)
hippie-completing-read-threshold
0))
(let ((selection
(apply hippie-completing-read-function
hippie-completing-read-prompt
collection
(mapcar 'eval ; is this safe??? hmmmm
hippie-completing-read-function-parameters))))
(when selection
(he-substitute-string selection t)))
(hippie-expand nil))
(user-error "No expansion found for %s" he-search-string))))
;;;###autoload
(defun hippie-completing-read ()
"Offer `completing-read' based completion for word at point."
(interactive)
(hippie-completing-read-expand-with 'hippie-expand))
(provide 'hippie-completing-read)
;;; hippie-completing-read.el ends here