diff options
| -rw-r--r-- | lisp/ChangeLog | 13 | ||||
| -rw-r--r-- | lisp/completion.el | 228 |
2 files changed, 109 insertions, 132 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 484ac1afada..d8bb1c89f1f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2014-12-22 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * completion.el: Use post-self-insert-hook (bug#19400). | ||
| 4 | (completion-separator-self-insert-command) | ||
| 5 | (completion-separator-self-insert-autofilling): Remove. | ||
| 6 | (completion-separator-chars): New var. | ||
| 7 | (completion-c-mode-hook, completion-setup-fortran-mode): Use it instead | ||
| 8 | of changing the keymap. | ||
| 9 | (completion--post-self-insert): New function. | ||
| 10 | (dynamic-completion-mode): Use it instead of rebinding keys. | ||
| 11 | (cmpl--completion-string): Rename from completion-string. | ||
| 12 | (add-completion-to-head, delete-completion): Let-bind it explicitly. | ||
| 13 | |||
| 1 | 2014-12-22 Bozhidar Batsov <bozhidar@batsov.com> | 14 | 2014-12-22 Bozhidar Batsov <bozhidar@batsov.com> |
| 2 | 15 | ||
| 3 | * progmodes/ruby-mode.el (ruby--string-region): Simplify code | 16 | * progmodes/ruby-mode.el (ruby--string-region): Simplify code |
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'. | |||
| 1149 | Updates the saved string with the supplied string. | 1149 | Updates the saved string with the supplied string. |
| 1150 | This must be very fast. | 1150 | This must be very fast. |
| 1151 | Returns the completion entry." | 1151 | Returns 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. |
| 1195 | String must be longer than `completion-prefix-min-length'." | 1196 | String 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'. |
| 1315 | This bumps num-uses. Called by `add-completion-to-head' and | 1317 | This 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))) |