Mercurial > emacs
annotate lisp/progmodes/sym-comp.el @ 105077:927f49ae259a
(nxml-end-of-heading): Fix typo in condition-case handler.
author | Glenn Morris <rgm@gnu.org> |
---|---|
date | Fri, 18 Sep 2009 07:25:14 +0000 |
parents | 1d5c75e6a226 |
children | aef9a4af6024 |
rev | line source |
---|---|
92054 | 1 ;;; sym-comp.el --- mode-dependent symbol completion |
2 | |
100908 | 3 ;; Copyright (C) 2004, 2008, 2009 Free Software Foundation, Inc. |
92054 | 4 |
5 ;; Author: Dave Love <fx@gnu.org> | |
6 ;; Keywords: extensions | |
7 ;; URL: http://www.loveshack.ukfsn.org/emacs | |
8 | |
92256 | 9 ;; This file is part of GNU Emacs. |
10 | |
94673
52b7a8c22af5
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
92256
diff
changeset
|
11 ;; GNU Emacs is free software: you can redistribute it and/or modify |
92054 | 12 ;; it under the terms of the GNU General Public License as published by |
94673
52b7a8c22af5
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
92256
diff
changeset
|
13 ;; the Free Software Foundation, either version 3 of the License, or |
52b7a8c22af5
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
92256
diff
changeset
|
14 ;; (at your option) any later version. |
92054 | 15 |
92256 | 16 ;; GNU Emacs is distributed in the hope that it will be useful, |
92054 | 17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 ;; GNU General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
94673
52b7a8c22af5
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
92256
diff
changeset
|
22 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
92054 | 23 |
24 ;;; Commentary: | |
25 | |
26 ;; This defines `symbol-complete', which is a generalization of the | |
27 ;; old `lisp-complete-symbol'. It provides the following hooks to | |
28 ;; allow major modes to set up completion appropriate for the mode: | |
29 ;; `symbol-completion-symbol-function', | |
30 ;; `symbol-completion-completions-function', | |
31 ;; `symbol-completion-predicate-function', | |
32 ;; `symbol-completion-transform-function'. Typically it is only | |
33 ;; necessary for a mode to set | |
34 ;; `symbol-completion-completions-function' locally and to bind | |
35 ;; `symbol-complete' appropriately. | |
36 | |
37 ;; It's unfortunate that there doesn't seem to be a good way of | |
38 ;; combining this with `complete-symbol'. | |
39 | |
40 ;; There is also `symbol-completion-try-complete', for use with | |
41 ;; Hippie-exp. | |
42 | |
43 ;;; Code: | |
44 | |
45 ;;;; Mode-dependent symbol completion. | |
46 | |
47 (defun symbol-completion-symbol () | |
48 "Default `symbol-completion-symbol-function'. | |
49 Uses `current-word' with the buffer narrowed to the part before | |
50 point." | |
51 (save-restriction | |
52 ;; Narrow in case point is in the middle of a symbol -- we want | |
53 ;; just the preceeding part. | |
54 (narrow-to-region (point-min) (point)) | |
55 (current-word))) | |
56 | |
57 (defvar symbol-completion-symbol-function 'symbol-completion-symbol | |
58 "Function to return a partial symbol before point for completion. | |
59 The value it returns should be a string (or nil). | |
104760
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
60 Major modes may set this locally if the default isn't appropriate. |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
61 |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
62 Beware: the length of the string STR returned need to be equal to the length |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
63 of text before point that's subject to completion. Typically, this amounts |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
64 to saying that STR is equal to |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
65 \(buffer-substring (- (point) (length STR)) (point)).") |
92054 | 66 |
67 (defvar symbol-completion-completions-function nil | |
68 "Function to return possible symbol completions. | |
69 It takes an argument which is the string to be completed and | |
70 returns a value suitable for the second argument of | |
71 `try-completion'. This value need not use the argument, i.e. it | |
72 may be all possible completions, such as `obarray' in the case of | |
73 Emacs Lisp. | |
74 | |
75 Major modes may set this locally to allow them to support | |
76 `symbol-complete'. See also `symbol-completion-symbol-function', | |
77 `symbol-completion-predicate-function' and | |
78 `symbol-completion-transform-function'.") | |
79 | |
80 (defvar symbol-completion-predicate-function nil | |
81 "If non-nil, function to return a predicate for selecting symbol completions. | |
82 The function gets two args, the positions of the beginning and | |
83 end of the symbol to be completed. | |
84 | |
85 Major modes may set this locally if the default isn't | |
86 appropriate. This is a function returning a predicate so that | |
87 the predicate can be context-dependent, e.g. to select only | |
88 function names if point is at a function call position. The | |
89 function's args may be useful for determining the context.") | |
90 | |
91 (defvar symbol-completion-transform-function nil | |
92 "If non-nil, function to transform symbols in the symbol-completion buffer. | |
93 E.g., for Lisp, it may annotate the symbol as being a function, | |
94 not a variable. | |
95 | |
96 The function takes the symbol name as argument. If it needs to | |
97 annotate this, it should return a value suitable as an element of | |
98 the list passed to `display-completion-list'. | |
99 | |
100 The predicate being used for selecting completions (from | |
101 `symbol-completion-predicate-function') is available | |
102 dynamically-bound as `symbol-completion-predicate' in case the | |
103 transform needs it.") | |
104 | |
104760
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
105 (defvar symbol-completion-predicate) |
92054 | 106 |
107 ;;;###autoload | |
108 (defun symbol-complete (&optional predicate) | |
109 "Perform completion of the symbol preceding point. | |
110 This is done in a way appropriate to the current major mode, | |
111 perhaps by interrogating an inferior interpreter. Compare | |
112 `complete-symbol'. | |
113 If no characters can be completed, display a list of possible completions. | |
114 Repeating the command at that point scrolls the list. | |
115 | |
116 When called from a program, optional arg PREDICATE is a predicate | |
117 determining which symbols are considered. | |
118 | |
119 This function requires `symbol-completion-completions-function' | |
120 to be set buffer-locally. Variables `symbol-completion-symbol-function', | |
121 `symbol-completion-predicate-function' and | |
122 `symbol-completion-transform-function' are also consulted." | |
123 (interactive) | |
124 ;; Fixme: Punt to `complete-symbol' in this case? | |
125 (unless (functionp symbol-completion-completions-function) | |
126 (error "symbol-completion-completions-function not defined")) | |
104760
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
127 (let* ((pattern (or (funcall symbol-completion-symbol-function) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
128 (error "No preceding symbol to complete"))) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
129 ;; FIXME: We assume below that `pattern' holds the text just |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
130 ;; before point. This is a problem in the way |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
131 ;; symbol-completion-symbol-function was defined. |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
132 (predicate (or predicate |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
133 (if symbol-completion-predicate-function |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
134 (funcall symbol-completion-predicate-function |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
135 (- (point) (length pattern)) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
136 (point))))) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
137 (completions (funcall symbol-completion-completions-function |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
138 pattern)) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
139 ;; In case the transform needs to access it. |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
140 (symbol-completion-predicate predicate) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
141 (completion-annotate-function |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
142 (if (functionp symbol-completion-transform-function) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
143 (lambda (str) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
144 (car-safe (cdr-safe |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
145 (funcall symbol-completion-transform-function |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
146 str)))))) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
147 (minibuffer-completion-table completions) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
148 (minibuffer-completion-predicate predicate) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
149 (ol (make-overlay (- (point) (length pattern)) (point) nil nil t))) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
150 (overlay-put ol 'field 'sym-comp) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
151 (unwind-protect |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
152 (call-interactively 'minibuffer-complete) |
1d5c75e6a226
(displayed-completions): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
100908
diff
changeset
|
153 (delete-overlay ol)))) |
92054 | 154 |
155 (eval-when-compile (require 'hippie-exp)) | |
156 | |
157 ;;;###autoload | |
158 (defun symbol-completion-try-complete (old) | |
159 "Completion function for use with `hippie-expand'. | |
160 Uses `symbol-completion-symbol-function' and | |
161 `symbol-completion-completions-function'. It is intended to be | |
162 used something like this in a major mode which provides symbol | |
163 completion: | |
164 | |
165 (if (featurep 'hippie-exp) | |
166 (set (make-local-variable 'hippie-expand-try-functions-list) | |
167 (cons 'symbol-completion-try-complete | |
168 hippie-expand-try-functions-list)))" | |
169 (when (and symbol-completion-symbol-function | |
170 symbol-completion-completions-function) | |
171 (unless old | |
172 (let ((symbol (funcall symbol-completion-symbol-function))) | |
173 (he-init-string (- (point) (length symbol)) (point)) | |
174 (if (not (he-string-member he-search-string he-tried-table)) | |
175 (push he-search-string he-tried-table)) | |
176 (setq he-expand-list | |
177 (and symbol | |
178 (funcall symbol-completion-completions-function symbol))))) | |
179 (while (and he-expand-list | |
180 (he-string-member (car he-expand-list) he-tried-table)) | |
181 (pop he-expand-list)) | |
182 (if he-expand-list | |
183 (progn | |
184 (he-substitute-string (pop he-expand-list)) | |
185 t) | |
186 (if old (he-reset-string)) | |
187 nil))) | |
188 | |
189 ;;; Emacs Lisp symbol completion. | |
190 | |
191 (defun lisp-completion-symbol () | |
192 "`symbol-completion-symbol-function' for Lisp." | |
193 (let ((end (point)) | |
194 (beg (with-syntax-table emacs-lisp-mode-syntax-table | |
195 (save-excursion | |
196 (backward-sexp 1) | |
197 (while (= (char-syntax (following-char)) ?\') | |
198 (forward-char 1)) | |
199 (point))))) | |
200 (buffer-substring-no-properties beg end))) | |
201 | |
202 (defun lisp-completion-predicate (beg end) | |
203 "`symbol-completion-predicate-function' for Lisp." | |
204 (save-excursion | |
205 (goto-char beg) | |
206 (if (not (eq (char-before) ?\()) | |
207 (lambda (sym) ;why not just nil ? -sm | |
208 ;To avoid interned symbols with | |
209 ;no slots. -- fx | |
210 (or (boundp sym) (fboundp sym) | |
211 (symbol-plist sym))) | |
212 ;; Looks like a funcall position. Let's double check. | |
213 (if (condition-case nil | |
214 (progn (up-list -2) (forward-char 1) | |
215 (eq (char-after) ?\()) | |
216 (error nil)) | |
217 ;; If the first element of the parent list is an open | |
218 ;; parenthesis we are probably not in a funcall position. | |
219 ;; Maybe a `let' varlist or something. | |
220 nil | |
221 ;; Else, we assume that a function name is expected. | |
222 'fboundp)))) | |
223 | |
224 (defun lisp-symbol-completion-transform () | |
225 "`symbol-completion-transform-function' for Lisp." | |
226 (lambda (elt) | |
227 (if (and (not (eq 'fboundp symbol-completion-predicate)) | |
228 (fboundp (intern elt))) | |
229 (list elt " <f>") | |
230 elt))) | |
231 | |
232 (provide 'sym-comp) | |
92123 | 233 |
234 ;; arch-tag: 6fcce616-f3c4-4751-94b4-710e83144124 | |
92054 | 235 ;;; sym-comp.el ends here |