aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/completion.el
diff options
context:
space:
mode:
authorStefan Monnier2014-12-22 12:35:29 -0500
committerStefan Monnier2014-12-22 12:35:29 -0500
commitb366b3bbf5ce0f6b47afec2eff0f7d27291e9a6f (patch)
tree6922917248792d0fc8d2b35c2078948eb6d1682a /lisp/completion.el
parentfafba80d7353f4ab5c359df75798f8130599371a (diff)
downloademacs-b366b3bbf5ce0f6b47afec2eff0f7d27291e9a6f.tar.gz
emacs-b366b3bbf5ce0f6b47afec2eff0f7d27291e9a6f.zip
* lisp/completion.el: Use post-self-insert-hook.
Fixes: debbugs:19400 (completion-separator-self-insert-command) (completion-separator-self-insert-autofilling): Remove. (completion-separator-chars): New var. (completion-c-mode-hook, completion-setup-fortran-mode): Use it instead of changing the keymap. (completion--post-self-insert): New function. (dynamic-completion-mode): Use it instead of rebinding keys. (cmpl--completion-string): Rename from completion-string. (add-completion-to-head, delete-completion): Let-bind it explicitly.
Diffstat (limited to 'lisp/completion.el')
-rw-r--r--lisp/completion.el228
1 files changed, 96 insertions, 132 deletions
diff --git a/lisp/completion.el b/lisp/completion.el
index d2d94e778d5..c2a20056ccc 100644
--- a/lisp/completion.el
+++ b/lisp/completion.el
@@ -373,7 +373,7 @@ Used to decide whether to save completions.")
373 373
374(defvar cmpl-preceding-syntax) 374(defvar cmpl-preceding-syntax)
375 375
376(defvar completion-string) 376(defvar cmpl--completion-string)
377 377
378;;--------------------------------------------------------------------------- 378;;---------------------------------------------------------------------------
379;; Low level tools 379;; Low level tools
@@ -1082,7 +1082,7 @@ Must be called after `find-exact-completion'."
1082 (cmpl-db-debug-p 1082 (cmpl-db-debug-p
1083 ;; not found, error if debug mode 1083 ;; not found, error if debug mode
1084 (error "Completion entry exists but not on prefix list - %s" 1084 (error "Completion entry exists but not on prefix list - %s"
1085 completion-string)) 1085 cmpl--completion-string))
1086 (inside-locate-completion-entry 1086 (inside-locate-completion-entry
1087 ;; recursive error: really scrod 1087 ;; recursive error: really scrod
1088 (locate-completion-db-error)) 1088 (locate-completion-db-error))
@@ -1149,73 +1149,75 @@ COMPLETION-STRING must be longer than `completion-prefix-min-length'.
1149Updates the saved string with the supplied string. 1149Updates the saved string with the supplied string.
1150This must be very fast. 1150This must be very fast.
1151Returns the completion entry." 1151Returns the completion entry."
1152 ;; Handle pending acceptance 1152 (let ((cmpl--completion-string completion-string))
1153 (if completion-to-accept (accept-completion)) 1153 ;; Handle pending acceptance
1154 ;; test if already in database 1154 (if completion-to-accept (accept-completion))
1155 (if (setq cmpl-db-entry (find-exact-completion completion-string)) 1155 ;; test if already in database
1156 ;; found 1156 (if (setq cmpl-db-entry (find-exact-completion completion-string))
1157 (let* ((prefix-entry (find-cmpl-prefix-entry 1157 ;; found
1158 (substring cmpl-db-downcase-string 0 1158 (let* ((prefix-entry (find-cmpl-prefix-entry
1159 completion-prefix-min-length))) 1159 (substring cmpl-db-downcase-string 0
1160 (splice-ptr (locate-completion-entry cmpl-db-entry prefix-entry)) 1160 completion-prefix-min-length)))
1161 (cmpl-ptr (cdr splice-ptr))) 1161 (splice-ptr (locate-completion-entry cmpl-db-entry prefix-entry))
1162 ;; update entry 1162 (cmpl-ptr (cdr splice-ptr)))
1163 (set-completion-string cmpl-db-entry completion-string) 1163 ;; update entry
1164 ;; move to head (if necessary) 1164 (set-completion-string cmpl-db-entry completion-string)
1165 (cond (splice-ptr 1165 ;; move to head (if necessary)
1166 ;; These should all execute atomically but it is not fatal if 1166 (cond (splice-ptr
1167 ;; they don't. 1167 ;; These should all execute atomically but it is not fatal if
1168 ;; splice it out 1168 ;; they don't.
1169 (or (setcdr splice-ptr (cdr cmpl-ptr)) 1169 ;; splice it out
1170 ;; fix up tail if necessary 1170 (or (setcdr splice-ptr (cdr cmpl-ptr))
1171 (set-cmpl-prefix-entry-tail prefix-entry splice-ptr)) 1171 ;; fix up tail if necessary
1172 ;; splice in at head 1172 (set-cmpl-prefix-entry-tail prefix-entry splice-ptr))
1173 (setcdr cmpl-ptr (cmpl-prefix-entry-head prefix-entry)) 1173 ;; splice in at head
1174 (set-cmpl-prefix-entry-head prefix-entry cmpl-ptr))) 1174 (setcdr cmpl-ptr (cmpl-prefix-entry-head prefix-entry))
1175 cmpl-db-entry) 1175 (set-cmpl-prefix-entry-head prefix-entry cmpl-ptr)))
1176 ;; not there 1176 cmpl-db-entry)
1177 (let (;; create an entry 1177 ;; not there
1178 (entry (list (make-completion completion-string))) 1178 (let ( ;; create an entry
1179 ;; setup the prefix 1179 (entry (list (make-completion completion-string)))
1180 (prefix-entry (find-cmpl-prefix-entry 1180 ;; setup the prefix
1181 (substring cmpl-db-downcase-string 0 1181 (prefix-entry (find-cmpl-prefix-entry
1182 completion-prefix-min-length)))) 1182 (substring cmpl-db-downcase-string 0
1183 (cond (prefix-entry 1183 completion-prefix-min-length))))
1184 ;; Splice in at head 1184 (cond (prefix-entry
1185 (setcdr entry (cmpl-prefix-entry-head prefix-entry)) 1185 ;; Splice in at head
1186 (set-cmpl-prefix-entry-head prefix-entry entry)) 1186 (setcdr entry (cmpl-prefix-entry-head prefix-entry))
1187 (t 1187 (set-cmpl-prefix-entry-head prefix-entry entry))
1188 ;; Start new prefix entry 1188 (t
1189 (set cmpl-db-prefix-symbol (make-cmpl-prefix-entry entry)))) 1189 ;; Start new prefix entry
1190 ;; Add it to the symbol 1190 (set cmpl-db-prefix-symbol (make-cmpl-prefix-entry entry))))
1191 (set cmpl-db-symbol (car entry))))) 1191 ;; Add it to the symbol
1192 (set cmpl-db-symbol (car entry))))))
1192 1193
1193(defun delete-completion (completion-string) 1194(defun delete-completion (completion-string)
1194 "Delete the completion from the database. 1195 "Delete the completion from the database.
1195String must be longer than `completion-prefix-min-length'." 1196String must be longer than `completion-prefix-min-length'."
1196 ;; Handle pending acceptance 1197 ;; Handle pending acceptance
1197 (if completion-to-accept (accept-completion)) 1198 (let ((cmpl--completion-string completion-string))
1198 (if (setq cmpl-db-entry (find-exact-completion completion-string)) 1199 (if completion-to-accept (accept-completion))
1199 ;; found 1200 (if (setq cmpl-db-entry (find-exact-completion completion-string))
1200 (let* ((prefix-entry (find-cmpl-prefix-entry 1201 ;; found
1201 (substring cmpl-db-downcase-string 0 1202 (let* ((prefix-entry (find-cmpl-prefix-entry
1202 completion-prefix-min-length))) 1203 (substring cmpl-db-downcase-string 0
1203 (splice-ptr (locate-completion-entry cmpl-db-entry prefix-entry))) 1204 completion-prefix-min-length)))
1204 ;; delete symbol reference 1205 (splice-ptr (locate-completion-entry cmpl-db-entry prefix-entry)))
1205 (set cmpl-db-symbol nil) 1206 ;; delete symbol reference
1206 ;; remove from prefix list 1207 (set cmpl-db-symbol nil)
1207 (cond (splice-ptr 1208 ;; remove from prefix list
1208 ;; not at head 1209 (cond (splice-ptr
1209 (or (setcdr splice-ptr (cdr (cdr splice-ptr))) 1210 ;; not at head
1210 ;; fix up tail if necessary 1211 (or (setcdr splice-ptr (cdr (cdr splice-ptr)))
1211 (set-cmpl-prefix-entry-tail prefix-entry splice-ptr))) 1212 ;; fix up tail if necessary
1212 (t 1213 (set-cmpl-prefix-entry-tail prefix-entry splice-ptr)))
1213 ;; at head 1214 (t
1214 (or (set-cmpl-prefix-entry-head 1215 ;; at head
1216 (or (set-cmpl-prefix-entry-head
1215 prefix-entry (cdr (cmpl-prefix-entry-head prefix-entry))) 1217 prefix-entry (cdr (cmpl-prefix-entry-head prefix-entry)))
1216 ;; List is now empty 1218 ;; List is now empty
1217 (set cmpl-db-prefix-symbol nil))))) 1219 (set cmpl-db-prefix-symbol nil)))))
1218 (error "Unknown completion `%s'" completion-string))) 1220 (error "Unknown completion `%s'" completion-string))))
1219 1221
1220;; Tests -- 1222;; Tests --
1221;; - Add and Find - 1223;; - Add and Find -
@@ -1311,7 +1313,7 @@ are specified."
1311 (delete-completion string)) 1313 (delete-completion string))
1312 1314
1313(defun accept-completion () 1315(defun accept-completion ()
1314 "Accepts the pending completion in `completion-to-accept'. 1316 "Accept the pending completion in `completion-to-accept'.
1315This bumps num-uses. Called by `add-completion-to-head' and 1317This bumps num-uses. Called by `add-completion-to-head' and
1316`completion-search-reset'." 1318`completion-search-reset'."
1317 (let ((string completion-to-accept) 1319 (let ((string completion-to-accept)
@@ -2156,26 +2158,27 @@ Patched to remove the most recent completion."
2156;; to work) 2158;; to work)
2157 2159
2158;; All common separators (eg. space "(" ")" """) characters go through a 2160;; All common separators (eg. space "(" ")" """) characters go through a
2159;; function to add new words to the list of words to complete from: 2161;; function to add new words to the list of words to complete from.
2160;; COMPLETION-SEPARATOR-SELF-INSERT-COMMAND (arg).
2161;; If the character before this was an alpha-numeric then this adds the 2162;; If the character before this was an alpha-numeric then this adds the
2162;; symbol before point to the completion list (using ADD-COMPLETION). 2163;; symbol before point to the completion list (using ADD-COMPLETION).
2163 2164
2164(defun completion-separator-self-insert-command (arg) 2165(defvar completion-separator-chars
2165 (interactive "p") 2166 (append " !%^&()=`|{}[];\\'#,?"
2166 (if (command-remapping 'self-insert-command) 2167 ;; We include period and colon even though they are symbol
2167 (funcall (command-remapping 'self-insert-command) arg) 2168 ;; chars because :
2168 (use-completion-before-separator) 2169 ;; - in text we want to pick up the last word in a sentence.
2169 (self-insert-command arg))) 2170 ;; - in C pointer refs. we want to pick up the first symbol
2170 2171 ;; - it won't make a difference for lisp mode (package names
2171(defun completion-separator-self-insert-autofilling (arg) 2172 ;; are short)
2172 (interactive "p") 2173 ".:" nil))
2173 (if (command-remapping 'self-insert-command) 2174
2174 (funcall (command-remapping 'self-insert-command) arg) 2175(defun completion--post-self-insert ()
2175 (use-completion-before-separator) 2176 (when (memq last-command-event completion-separator-chars)
2176 (self-insert-command arg) 2177 (let ((after-pos (electric--after-char-pos)))
2177 (and auto-fill-function 2178 (when after-pos
2178 (funcall auto-fill-function)))) 2179 (save-excursion
2180 (goto-char (1- after-pos))
2181 (use-completion-before-separator))))))
2179 2182
2180;;----------------------------------------------- 2183;;-----------------------------------------------
2181;; Wrapping Macro 2184;; Wrapping Macro
@@ -2244,9 +2247,8 @@ TYPE is the type of the wrapper to be added. Can be :before or :under."
2244(completion-def-wrapper 'electric-c-semi :separator) 2247(completion-def-wrapper 'electric-c-semi :separator)
2245(defun completion-c-mode-hook () 2248(defun completion-c-mode-hook ()
2246 (setq completion-syntax-table completion-c-syntax-table) 2249 (setq completion-syntax-table completion-c-syntax-table)
2247 (local-set-key "+" 'completion-separator-self-insert-command) 2250 (setq-local completion-separator-chars
2248 (local-set-key "*" 'completion-separator-self-insert-command) 2251 (append "+*/" completion-separator-chars)))
2249 (local-set-key "/" 'completion-separator-self-insert-command))
2250 2252
2251;; FORTRAN mode diffs. (these are defined when fortran is called) 2253;; FORTRAN mode diffs. (these are defined when fortran is called)
2252 2254
@@ -2259,10 +2261,8 @@ TYPE is the type of the wrapper to be added. Can be :before or :under."
2259 2261
2260(defun completion-setup-fortran-mode () 2262(defun completion-setup-fortran-mode ()
2261 (setq completion-syntax-table completion-fortran-syntax-table) 2263 (setq completion-syntax-table completion-fortran-syntax-table)
2262 (local-set-key "+" 'completion-separator-self-insert-command) 2264 (setq-local completion-separator-chars
2263 (local-set-key "-" 'completion-separator-self-insert-command) 2265 (append "+-*/" completion-separator-chars)))
2264 (local-set-key "*" 'completion-separator-self-insert-command)
2265 (local-set-key "/" 'completion-separator-self-insert-command))
2266 2266
2267;; Enable completion mode. 2267;; Enable completion mode.
2268 2268
@@ -2281,15 +2281,16 @@ if ARG is omitted or nil."
2281 ;; This is always good, not specific to dynamic-completion-mode. 2281 ;; This is always good, not specific to dynamic-completion-mode.
2282 (define-key function-key-map [C-return] [?\C-\r]) 2282 (define-key function-key-map [C-return] [?\C-\r])
2283 2283
2284 (dolist (x '((find-file-hook . completion-find-file-hook) 2284 (dolist (x `((find-file-hook . ,#'completion-find-file-hook)
2285 (pre-command-hook . completion-before-command) 2285 (pre-command-hook . ,#'completion-before-command)
2286 ;; Save completions when killing Emacs. 2286 ;; Save completions when killing Emacs.
2287 (kill-emacs-hook . kill-emacs-save-completions) 2287 (kill-emacs-hook . ,#'kill-emacs-save-completions)
2288 (post-self-insert-hook . ,#'completion--post-self-insert)
2288 2289
2289 ;; Install the appropriate mode tables. 2290 ;; Install the appropriate mode tables.
2290 (lisp-mode-hook . completion-lisp-mode-hook) 2291 (lisp-mode-hook . ,#'completion-lisp-mode-hook)
2291 (c-mode-hook . completion-c-mode-hook) 2292 (c-mode-hook . ,#'completion-c-mode-hook)
2292 (fortran-mode-hook . completion-setup-fortran-mode))) 2293 (fortran-mode-hook . ,#'completion-setup-fortran-mode)))
2293 (if dynamic-completion-mode 2294 (if dynamic-completion-mode
2294 (add-hook (car x) (cdr x)) 2295 (add-hook (car x) (cdr x))
2295 (remove-hook (car x) (cdr x)))) 2296 (remove-hook (car x) (cdr x))))
@@ -2315,44 +2316,7 @@ if ARG is omitted or nil."
2315 ;; cumb 2316 ;; cumb
2316 2317
2317 ;; Patches to standard keymaps insert completions 2318 ;; Patches to standard keymaps insert completions
2318 ([remap kill-region] . completion-kill-region) 2319 ([remap kill-region] . completion-kill-region)))
2319
2320 ;; Separators
2321 ;; We've used the completion syntax table given as a guide.
2322 ;;
2323 ;; Global separator chars.
2324 ;; We left out <tab> because there are too many special
2325 ;; cases for it. Also, in normal coding it's rarely typed
2326 ;; after a word.
2327 (" " . completion-separator-self-insert-autofilling)
2328 ("!" . completion-separator-self-insert-command)
2329 ("%" . completion-separator-self-insert-command)
2330 ("^" . completion-separator-self-insert-command)
2331 ("&" . completion-separator-self-insert-command)
2332 ("(" . completion-separator-self-insert-command)
2333 (")" . completion-separator-self-insert-command)
2334 ("=" . completion-separator-self-insert-command)
2335 ("`" . completion-separator-self-insert-command)
2336 ("|" . completion-separator-self-insert-command)
2337 ("{" . completion-separator-self-insert-command)
2338 ("}" . completion-separator-self-insert-command)
2339 ("[" . completion-separator-self-insert-command)
2340 ("]" . completion-separator-self-insert-command)
2341 (";" . completion-separator-self-insert-command)
2342 ("\"". completion-separator-self-insert-command)
2343 ("'" . completion-separator-self-insert-command)
2344 ("#" . completion-separator-self-insert-command)
2345 ("," . completion-separator-self-insert-command)
2346 ("?" . completion-separator-self-insert-command)
2347
2348 ;; We include period and colon even though they are symbol
2349 ;; chars because :
2350 ;; - in text we want to pick up the last word in a sentence.
2351 ;; - in C pointer refs. we want to pick up the first symbol
2352 ;; - it won't make a difference for lisp mode (package names
2353 ;; are short)
2354 ("." . completion-separator-self-insert-command)
2355 (":" . completion-separator-self-insert-command)))
2356 (push (cons (car binding) (lookup-key global-map (car binding))) 2320 (push (cons (car binding) (lookup-key global-map (car binding)))
2357 completion-saved-bindings) 2321 completion-saved-bindings)
2358 (global-set-key (car binding) (cdr binding))) 2322 (global-set-key (car binding) (cdr binding)))