diff options
| author | Simon Marshall | 1997-07-25 11:36:34 +0000 |
|---|---|---|
| committer | Simon Marshall | 1997-07-25 11:36:34 +0000 |
| commit | 92677e25c1f4bf54cc99c9707018a409e66f0a8b (patch) | |
| tree | 2bcf5ab1af857766d5cd8c51ebbcbcd3e2416cb4 /lisp | |
| parent | 86c87ebc8c430e0419ff7a3bed6fe3fc1c5d2f08 (diff) | |
| download | emacs-92677e25c1f4bf54cc99c9707018a409e66f0a8b.tar.gz emacs-92677e25c1f4bf54cc99c9707018a409e66f0a8b.zip | |
customise & make installation/deinstallation happen on mode command not file load.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/complete.el | 298 |
1 files changed, 193 insertions, 105 deletions
diff --git a/lisp/complete.el b/lisp/complete.el index c12e2ce95cb..a20fb7d6516 100644 --- a/lisp/complete.el +++ b/lisp/complete.el | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | ;; Author: Dave Gillespie <daveg@synaptics.com> | 5 | ;; Author: Dave Gillespie <daveg@synaptics.com> |
| 6 | ;; Keywords: abbrev | 6 | ;; Keywords: abbrev |
| 7 | ;; Version: 2.02 | 7 | ;; Version: 2.03 |
| 8 | ;; Special thanks to Hallvard Furuseth for his many ideas and contributions. | 8 | ;; Special thanks to Hallvard Furuseth for his many ideas and contributions. |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -47,7 +47,7 @@ | |||
| 47 | ;; and the partial completer will use the Meta versions of the keys. | 47 | ;; and the partial completer will use the Meta versions of the keys. |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | ;; Usage: Load this file. Now, during completable minibuffer entry, | 50 | ;; Usage: M-x PC-mode. Now, during completable minibuffer entry, |
| 51 | ;; | 51 | ;; |
| 52 | ;; TAB means to do a partial completion; | 52 | ;; TAB means to do a partial completion; |
| 53 | ;; SPC means to do a partial complete-word; | 53 | ;; SPC means to do a partial complete-word; |
| @@ -62,7 +62,7 @@ | |||
| 62 | ;; | 62 | ;; |
| 63 | ;; in your .emacs file. To load partial completion automatically, put | 63 | ;; in your .emacs file. To load partial completion automatically, put |
| 64 | ;; | 64 | ;; |
| 65 | ;; (load "complete") | 65 | ;; (PC-mode t) |
| 66 | ;; | 66 | ;; |
| 67 | ;; in your .emacs file, too. Things will be faster if you byte-compile | 67 | ;; in your .emacs file, too. Things will be faster if you byte-compile |
| 68 | ;; this file when you install it. | 68 | ;; this file when you install it. |
| @@ -98,71 +98,180 @@ | |||
| 98 | 98 | ||
| 99 | ;;; Code: | 99 | ;;; Code: |
| 100 | 100 | ||
| 101 | (defvar PC-meta-flag t | 101 | (defgroup partial-completion nil |
| 102 | "*If nil, TAB does normal Emacs completion and M-TAB does Partial Completion. | 102 | "Partial Completion of items." |
| 103 | If t, TAB does Partial Completion and M-TAB does normal completion.") | 103 | :prefix "pc-" |
| 104 | 104 | :group 'minibuffer) | |
| 105 | 105 | ||
| 106 | (defvar PC-word-delimiters "-_. " | 106 | (defcustom partial-completion-mode nil |
| 107 | "*A string of characters which are to be treated as word delimiters | 107 | "Toggle Partial Completion mode. |
| 108 | by the Partial Completion system. | 108 | When Partial Completion mode is enabled, TAB (or M-TAB if `PC-meta-flag' is |
| 109 | 109 | nil) is enhanced so that if some string is divided into words and each word is | |
| 110 | Some arcane rules: If `]' is in this string it must come first. | 110 | delimited by a character in `PC-word-delimiters', partial words are completed |
| 111 | If `^' is in this string it must NOT come first. If `-' is in this | 111 | as much as possible and `*' characters are treated likewise in file names. |
| 112 | string, it must come first or right after `]'. In other words, if | 112 | You must modify via \\[customize] for this variable to have an effect." |
| 113 | S is this string, then `[S]' must be a legal Emacs regular expression | 113 | :set (lambda (symbol value) |
| 114 | \(not containing character ranges like `a-z').") | 114 | (partial-completion-mode (or value 0))) |
| 115 | 115 | :initialize 'custom-initialize-default | |
| 116 | 116 | :type 'boolean | |
| 117 | (defvar PC-first-char 'x | 117 | :group 'partial-completion |
| 118 | "*If t, first character of a string to be completed is always taken literally. | 118 | :require 'complete) |
| 119 | If nil, word delimiters are handled even if they appear as first character. | 119 | |
| 120 | This controls whether \".e\" matches \".e*\" (t) or \"*.e*\" (nil). | 120 | (defcustom PC-first-char 'find-file |
| 121 | If neither nil nor t, first char is literal only for filename completion.") | 121 | "*Control how the first character of a string is to be interpreted. |
| 122 | 122 | If nil, the first character of a string is not taken literally if it is a word | |
| 123 | 123 | delimiter, so that \".e\" matches \"*.e*\". | |
| 124 | (defvar PC-include-file-path '("/usr/include") | 124 | If t, the first character of a string is always taken literally even if it is a |
| 125 | "*List of directories in which to look for include files. | 125 | word delimiter, so that \".e\" matches \".e*\". |
| 126 | If this is nil, uses the colon-separated path in $INCPATH instead.") | 126 | If non-nil and non-t, the first character is taken literally only for file name |
| 127 | 127 | completion." | |
| 128 | 128 | :type '(choice (const :tag "delimiter" nil) | |
| 129 | (defvar PC-disable-wildcards nil | 129 | (const :tag "literal" t) |
| 130 | "Set this to non-nil to disable wildcard support in \\[find-file].") | 130 | (sexp :tag "find-file" :format "%t\n" find-file)) |
| 131 | 131 | :group 'partial-completion) | |
| 132 | (defvar PC-disable-includes nil | 132 | |
| 133 | "Set this to non-nil to disable include-file support in \\[find-file].") | 133 | (defcustom PC-meta-flag t |
| 134 | 134 | "*If non-nil, TAB means PC completion and M-TAB means normal completion. | |
| 135 | Otherwise, TAB means normal completion and M-TAB means Partial Completion." | ||
| 136 | :type 'boolean | ||
| 137 | :group 'partial-completion) | ||
| 138 | |||
| 139 | (defcustom PC-word-delimiters "-_. " | ||
| 140 | "*A string of characters treated as word delimiters for completion. | ||
| 141 | Some arcane rules: | ||
| 142 | If `]' is in this string, it must come first. | ||
| 143 | If `^' is in this string, it must not come first. | ||
| 144 | If `-' is in this string, it must come first or right after `]'. | ||
| 145 | In other words, if S is this string, then `[S]' must be a legal Emacs regular | ||
| 146 | expression (not containing character ranges like `a-z')." | ||
| 147 | :type 'string | ||
| 148 | :group 'partial-completion) | ||
| 149 | |||
| 150 | (defcustom PC-include-file-path '("/usr/include" "/usr/local/include") | ||
| 151 | "*A list of directories in which to look for include files. | ||
| 152 | If nil, means use the colon-separated path in the variable $INCPATH instead." | ||
| 153 | :type '(repeat directory) | ||
| 154 | :group 'partial-completion) | ||
| 155 | |||
| 156 | (defcustom PC-disable-wildcards nil | ||
| 157 | "*If non-nil, wildcard support in \\[find-file] is disabled." | ||
| 158 | :type 'boolean | ||
| 159 | :group 'partial-completion) | ||
| 160 | |||
| 161 | (defcustom PC-disable-includes nil | ||
| 162 | "*If non-nil, include-file support in \\[find-file] is disabled." | ||
| 163 | :type 'boolean | ||
| 164 | :group 'partial-completion) | ||
| 135 | 165 | ||
| 136 | (defvar PC-default-bindings t | 166 | (defvar PC-default-bindings t |
| 137 | "Set this to nil to suppress the default partial completion key bindings.") | 167 | "If non-nil, default partial completion key bindings are suppressed.") |
| 138 | 168 | ||
| 139 | (if PC-default-bindings (progn | 169 | (defvar PC-old-read-file-name-internal nil) |
| 140 | (define-key minibuffer-local-completion-map "\t" 'PC-complete) | ||
| 141 | (define-key minibuffer-local-completion-map " " 'PC-complete-word) | ||
| 142 | (define-key minibuffer-local-completion-map "?" 'PC-completion-help) | ||
| 143 | |||
| 144 | (define-key minibuffer-local-completion-map "\e\t" 'PC-complete) | ||
| 145 | (define-key minibuffer-local-completion-map "\e " 'PC-complete-word) | ||
| 146 | (define-key minibuffer-local-completion-map "\e\r" 'PC-force-complete-and-exit) | ||
| 147 | (define-key minibuffer-local-completion-map "\e\n" 'PC-force-complete-and-exit) | ||
| 148 | (define-key minibuffer-local-completion-map "\e?" 'PC-completion-help) | ||
| 149 | |||
| 150 | (define-key minibuffer-local-must-match-map "\t" 'PC-complete) | ||
| 151 | (define-key minibuffer-local-must-match-map " " 'PC-complete-word) | ||
| 152 | (define-key minibuffer-local-must-match-map "\r" 'PC-complete-and-exit) | ||
| 153 | (define-key minibuffer-local-must-match-map "\n" 'PC-complete-and-exit) | ||
| 154 | (define-key minibuffer-local-must-match-map "?" 'PC-completion-help) | ||
| 155 | |||
| 156 | (define-key minibuffer-local-must-match-map "\e\t" 'PC-complete) | ||
| 157 | (define-key minibuffer-local-must-match-map "\e " 'PC-complete-word) | ||
| 158 | (define-key minibuffer-local-must-match-map "\e\r" 'PC-complete-and-exit) | ||
| 159 | (define-key minibuffer-local-must-match-map "\e\n" 'PC-complete-and-exit) | ||
| 160 | (define-key minibuffer-local-must-match-map "\e?" 'PC-completion-help) | ||
| 161 | |||
| 162 | (define-key global-map "\e\t" 'PC-lisp-complete-symbol) | ||
| 163 | )) | ||
| 164 | |||
| 165 | 170 | ||
| 171 | ;;;###autoload | ||
| 172 | (defun partial-completion-mode (&optional arg) | ||
| 173 | "Toggle Partial Completion mode. | ||
| 174 | With prefix ARG, turn Partial Completion mode on if ARG is positive. | ||
| 175 | |||
| 176 | When Partial Completion mode is enabled, TAB (or M-TAB if `PC-meta-flag' is | ||
| 177 | nil) is enhanced so that if some string is divided into words and each word is | ||
| 178 | delimited by a character in `PC-word-delimiters', partial words are completed | ||
| 179 | as much as possible. | ||
| 180 | |||
| 181 | For example, M-x p-c-b expands to M-x partial-completion-mode since no other | ||
| 182 | command begins with that sequence of characters, and | ||
| 183 | \\[find-file] f_b.c TAB might complete to foo_bar.c if that file existed and no | ||
| 184 | other file in that directory begin with that sequence of characters. | ||
| 185 | |||
| 186 | Unless `PC-disable-wildcards' is non-nil, the \"*\" wildcard is interpreted | ||
| 187 | specially when entering file or directory names. For example, | ||
| 188 | \\[find-file] *.c RET finds each C file in the currenty directory, and | ||
| 189 | \\[find-file] */foo_bar.c TAB completes the directory name as far as possible. | ||
| 190 | |||
| 191 | Unless `PC-disable-includes' is non-nil, the \"<...>\" sequence is interpreted | ||
| 192 | specially in \\[find-file]. For example, | ||
| 193 | \\[find-file] <sys/time.h> RET finds the file /usr/include/sys/time.h. | ||
| 194 | See also the variable `PC-include-file-path'." | ||
| 195 | (interactive "P") | ||
| 196 | (let ((on-p (if arg | ||
| 197 | (> (prefix-numeric-value arg) 0) | ||
| 198 | (not partial-completion-mode)))) | ||
| 199 | ;; Deal with key bindings... | ||
| 200 | (PC-bindings on-p) | ||
| 201 | ;; Deal with wildcard file feature... | ||
| 202 | (cond ((not on-p) | ||
| 203 | (remove-hook 'find-file-not-found-hooks 'PC-try-load-many-files)) | ||
| 204 | ((not PC-disable-wildcards) | ||
| 205 | (add-hook 'find-file-not-found-hooks 'PC-try-load-many-files))) | ||
| 206 | ;; Deal with include file feature... | ||
| 207 | (cond ((not on-p) | ||
| 208 | (remove-hook 'find-file-not-found-hooks 'PC-look-for-include-file)) | ||
| 209 | ((not PC-disable-includes) | ||
| 210 | (add-hook 'find-file-not-found-hooks 'PC-look-for-include-file))) | ||
| 211 | ;; ... with some underhand redefining. | ||
| 212 | (cond ((and (not on-p) (functionp PC-old-read-file-name-internal)) | ||
| 213 | (fset 'read-file-name-internal PC-old-read-file-name-internal)) | ||
| 214 | ((and (not PC-disable-includes) (not PC-old-read-file-name-internal)) | ||
| 215 | (setq PC-old-read-file-name-internal | ||
| 216 | (symbol-function 'read-file-name-internal)) | ||
| 217 | (fset 'read-file-name-internal | ||
| 218 | 'PC-read-include-file-name-internal))) | ||
| 219 | ;; Finally set the mode variable. | ||
| 220 | (setq partial-completion-mode on-p))) | ||
| 221 | |||
| 222 | (defun PC-bindings (bind) | ||
| 223 | (let ((completion-map minibuffer-local-completion-map) | ||
| 224 | (must-match-map minibuffer-local-must-match-map)) | ||
| 225 | (cond ((not bind) | ||
| 226 | ;; These bindings are the default bindings. It would be better to | ||
| 227 | ;; restore the previous bindings. | ||
| 228 | (define-key completion-map "\t" 'minibuffer-complete) | ||
| 229 | (define-key completion-map " " 'minibuffer-complete-word) | ||
| 230 | (define-key completion-map "?" 'minibuffer-completion-help) | ||
| 231 | |||
| 232 | (define-key must-match-map "\t" 'minibuffer-complete) | ||
| 233 | (define-key must-match-map " " 'minibuffer-complete-word) | ||
| 234 | (define-key must-match-map "\r" 'minibuffer-complete-and-exit) | ||
| 235 | (define-key must-match-map "\n" 'minibuffer-complete-and-exit) | ||
| 236 | (define-key must-match-map "?" 'minibuffer-completion-help) | ||
| 237 | |||
| 238 | (define-key global-map "\e\t" 'complete-symbol)) | ||
| 239 | (PC-default-bindings | ||
| 240 | (define-key completion-map "\t" 'PC-complete) | ||
| 241 | (define-key completion-map " " 'PC-complete-word) | ||
| 242 | (define-key completion-map "?" 'PC-completion-help) | ||
| 243 | |||
| 244 | (define-key completion-map "\e\t" 'PC-complete) | ||
| 245 | (define-key completion-map "\e " 'PC-complete-word) | ||
| 246 | (define-key completion-map "\e\r" 'PC-force-complete-and-exit) | ||
| 247 | (define-key completion-map "\e\n" 'PC-force-complete-and-exit) | ||
| 248 | (define-key completion-map "\e?" 'PC-completion-help) | ||
| 249 | |||
| 250 | (define-key must-match-map "\t" 'PC-complete) | ||
| 251 | (define-key must-match-map " " 'PC-complete-word) | ||
| 252 | (define-key must-match-map "\r" 'PC-complete-and-exit) | ||
| 253 | (define-key must-match-map "\n" 'PC-complete-and-exit) | ||
| 254 | (define-key must-match-map "?" 'PC-completion-help) | ||
| 255 | |||
| 256 | (define-key must-match-map "\e\t" 'PC-complete) | ||
| 257 | (define-key must-match-map "\e " 'PC-complete-word) | ||
| 258 | (define-key must-match-map "\e\r" 'PC-complete-and-exit) | ||
| 259 | (define-key must-match-map "\e\n" 'PC-complete-and-exit) | ||
| 260 | (define-key must-match-map "\e?" 'PC-completion-help) | ||
| 261 | |||
| 262 | (define-key global-map "\e\t" 'PC-lisp-complete-symbol))))) | ||
| 263 | |||
| 264 | ;; Because the `partial-completion-mode' option is defined before the | ||
| 265 | ;; `partial-completion-mode' command and its callee, we give the former a | ||
| 266 | ;; default `:initialize' keyword value. Otherwise, the `:set' keyword value | ||
| 267 | ;; would be called to initialise the variable value, and that would call the | ||
| 268 | ;; as-yet undefined `partial-completion-mode' function. | ||
| 269 | ;; Since the default `:initialize' keyword value (obviously) does not turn on | ||
| 270 | ;; Partial Completion Mode, we do that here, once the `partial-completion-mode' | ||
| 271 | ;; function and its callee are defined. | ||
| 272 | (when partial-completion-mode | ||
| 273 | (partial-completion-mode t)) | ||
| 274 | |||
| 166 | (defun PC-complete () | 275 | (defun PC-complete () |
| 167 | "Like minibuffer-complete, but allows \"b--di\"-style abbreviations. | 276 | "Like minibuffer-complete, but allows \"b--di\"-style abbreviations. |
| 168 | For example, \"M-x b--di\" would match `byte-recompile-directory', or any | 277 | For example, \"M-x b--di\" would match `byte-recompile-directory', or any |
| @@ -606,25 +715,25 @@ of `minibuffer-completion-table' and the minibuffer contents.") | |||
| 606 | 715 | ||
| 607 | (defvar PC-not-minibuffer nil) | 716 | (defvar PC-not-minibuffer nil) |
| 608 | 717 | ||
| 609 | (defun PC-temp-minibuffer-message (m) | 718 | (defun PC-temp-minibuffer-message (message) |
| 610 | "A Lisp version of `temp_minibuffer_message' from minibuf.c." | 719 | "A Lisp version of `temp_minibuffer_message' from minibuf.c." |
| 611 | (if PC-not-minibuffer | 720 | (cond (PC-not-minibuffer |
| 612 | (progn | 721 | (message message) |
| 613 | (message m) | 722 | (sit-for 2) |
| 614 | (sit-for 2) | 723 | (message "")) |
| 615 | (message "")) | 724 | ((fboundp 'temp-minibuffer-message) |
| 616 | (if (fboundp 'temp-minibuffer-message) | 725 | (temp-minibuffer-message message)) |
| 617 | (temp-minibuffer-message m) | 726 | (t |
| 618 | (let ((savemax (point-max))) | 727 | (let ((point-max (point-max))) |
| 619 | (save-excursion | 728 | (save-excursion |
| 620 | (goto-char (point-max)) | 729 | (goto-char point-max) |
| 621 | (insert m)) | 730 | (insert message)) |
| 622 | (let ((inhibit-quit t)) | 731 | (let ((inhibit-quit t)) |
| 623 | (sit-for 2) | 732 | (sit-for 2) |
| 624 | (delete-region savemax (point-max)) | 733 | (delete-region point-max (point-max)) |
| 625 | (if quit-flag | 734 | (when quit-flag |
| 626 | (setq quit-flag nil | 735 | (setq quit-flag nil |
| 627 | unread-command-char 7))))))) | 736 | unread-command-events '(7)))))))) |
| 628 | 737 | ||
| 629 | 738 | ||
| 630 | (defun PC-lisp-complete-symbol () | 739 | (defun PC-lisp-complete-symbol () |
| @@ -730,13 +839,6 @@ or properties are considered." | |||
| 730 | (kill-buffer (current-buffer)) | 839 | (kill-buffer (current-buffer)) |
| 731 | files)))) | 840 | files)))) |
| 732 | 841 | ||
| 733 | (or PC-disable-wildcards | ||
| 734 | (memq 'PC-try-load-many-files find-file-not-found-hooks) | ||
| 735 | (setq find-file-not-found-hooks (cons 'PC-try-load-many-files | ||
| 736 | find-file-not-found-hooks))) | ||
| 737 | |||
| 738 | |||
| 739 | |||
| 740 | ;;; Facilities for loading C header files. This is independent from the | 842 | ;;; Facilities for loading C header files. This is independent from the |
| 741 | ;;; main completion code. See also the variable `PC-include-file-path' | 843 | ;;; main completion code. See also the variable `PC-include-file-path' |
| 742 | ;;; at top of this file. | 844 | ;;; at top of this file. |
| @@ -866,8 +968,6 @@ absolute rather than relative to some directory on the SEARCH-PATH." | |||
| 866 | (setq sorted (cdr sorted))) | 968 | (setq sorted (cdr sorted))) |
| 867 | compressed)))) | 969 | compressed)))) |
| 868 | 970 | ||
| 869 | (defvar PC-old-read-file-name-internal nil) | ||
| 870 | |||
| 871 | (defun PC-read-include-file-name-internal (string dir action) | 971 | (defun PC-read-include-file-name-internal (string dir action) |
| 872 | (if (string-match "<\\([^\"<>]*\\)>?$" string) | 972 | (if (string-match "<\\([^\"<>]*\\)>?$" string) |
| 873 | (let* ((name (substring string (match-beginning 1) (match-end 1))) | 973 | (let* ((name (substring string (match-beginning 1) (match-end 1))) |
| @@ -883,20 +983,8 @@ absolute rather than relative to some directory on the SEARCH-PATH." | |||
| 883 | ((eq action 'lambda) | 983 | ((eq action 'lambda) |
| 884 | (eq (try-completion str2 completion-table nil) t)))) | 984 | (eq (try-completion str2 completion-table nil) t)))) |
| 885 | (funcall PC-old-read-file-name-internal string dir action))) | 985 | (funcall PC-old-read-file-name-internal string dir action))) |
| 886 | |||
| 887 | (or PC-disable-includes | ||
| 888 | (memq 'PC-look-for-include-file find-file-not-found-hooks) | ||
| 889 | (setq find-file-not-found-hooks (cons 'PC-look-for-include-file | ||
| 890 | find-file-not-found-hooks))) | ||
| 891 | |||
| 892 | (or PC-disable-includes | ||
| 893 | PC-old-read-file-name-internal | ||
| 894 | (progn | ||
| 895 | (setq PC-old-read-file-name-internal | ||
| 896 | (symbol-function 'read-file-name-internal)) | ||
| 897 | (fset 'read-file-name-internal 'PC-read-include-file-name-internal))) | ||
| 898 | |||
| 899 | 986 | ||
| 987 | |||
| 900 | (provide 'complete) | 988 | (provide 'complete) |
| 901 | 989 | ||
| 902 | ;;; End. | 990 | ;;; End. |