comparison lisp/progmodes/cc-menus.el @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents 0d8b17d428b5
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 ;;; cc-menus.el --- imenu support for CC Mode 1 ;;; cc-menus.el --- imenu support for CC Mode
2 2
3 ;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc. 3 ;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4 4 ;; Inc.
5 ;; Authors: 2000- Martin Stjernholm 5
6 ;; 1998-1999 Barry A. Warsaw and Martin Stjernholm 6 ;; Authors: 1998- Martin Stjernholm
7 ;; 1992-1997 Barry A. Warsaw 7 ;; 1992-1999 Barry A. Warsaw
8 ;; 1987 Dave Detlefs and Stewart Clamen 8 ;; 1987 Dave Detlefs and Stewart Clamen
9 ;; 1985 Richard M. Stallman 9 ;; 1985 Richard M. Stallman
10 ;; Maintainer: bug-cc-mode@gnu.org 10 ;; Maintainer: bug-cc-mode@gnu.org
11 ;; Created: 22-Apr-1997 (split from cc-mode.el) 11 ;; Created: 22-Apr-1997 (split from cc-mode.el)
12 ;; Version: See cc-mode.el 12 ;; Version: See cc-mode.el
23 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 23 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
24 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 ;; GNU General Public License for more details. 25 ;; GNU General Public License for more details.
26 26
27 ;; You should have received a copy of the GNU General Public License 27 ;; You should have received a copy of the GNU General Public License
28 ;; along with GNU Emacs; see the file COPYING. If not, write to 28 ;; along with this program; see the file COPYING. If not, write to
29 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 29 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
30 ;; Boston, MA 02111-1307, USA. 30 ;; Boston, MA 02110-1301, USA.
31 31
32 ;;; Commentary: 32 ;;; Commentary:
33 33
34 ;;; Code: 34 ;;; Code:
35 35
37 (let ((load-path 37 (let ((load-path
38 (if (and (boundp 'byte-compile-dest-file) 38 (if (and (boundp 'byte-compile-dest-file)
39 (stringp byte-compile-dest-file)) 39 (stringp byte-compile-dest-file))
40 (cons (file-name-directory byte-compile-dest-file) load-path) 40 (cons (file-name-directory byte-compile-dest-file) load-path)
41 load-path))) 41 load-path)))
42 (require 'cc-bytecomp))) 42 (load "cc-bytecomp" nil t)))
43
44 (cc-require 'cc-defs)
43 45
44 ;; The things referenced in imenu, which we don't require. 46 ;; The things referenced in imenu, which we don't require.
45 (cc-bytecomp-defvar imenu-case-fold-search) 47 (cc-bytecomp-defvar imenu-case-fold-search)
46 (cc-bytecomp-defvar imenu-generic-expression) 48 (cc-bytecomp-defvar imenu-generic-expression)
49 (cc-bytecomp-defvar imenu-create-index-function)
47 (cc-bytecomp-defun imenu-progress-message) 50 (cc-bytecomp-defun imenu-progress-message)
48 51
49 52
50 ;; imenu integration 53 ;; imenu integration
51 (defvar cc-imenu-c-prototype-macro-regexp nil 54 (defvar cc-imenu-c-prototype-macro-regexp nil
69 ;; will be incorrectly recognised as function `new ()' because the regexps 72 ;; will be incorrectly recognised as function `new ()' because the regexps
70 ;; work by backtracking from the end of the definition. 73 ;; work by backtracking from the end of the definition.
71 (nil 74 (nil
72 ,(concat 75 ,(concat
73 "^\\<.*" 76 "^\\<.*"
74 "[^a-zA-Z0-9_:<>~]" ; match any non-identifier char 77 "[^" c-alnum "_:<>~]" ; match any non-identifier char
75 ; (note: this can be `\n') 78 ; (note: this can be `\n')
76 "\\(" 79 "\\("
77 "\\([a-zA-Z0-9_:<>~]*::\\)?" ; match an operator 80 "\\([" c-alnum "_:<>~]*::\\)?" ; match an operator
78 "operator\\>[ \t]*" 81 "operator\\>[ \t]*"
79 "\\(()\\|[^(]*\\)" ; special case for `()' operator 82 "\\(()\\|[^(]*\\)" ; special case for `()' operator
80 "\\)" 83 "\\)"
81 84
82 "[ \t]*([^)]*)[ \t]*[^ \t;]" ; followed by ws, arg list, 85 "[ \t]*([^)]*)[ \t]*[^ \t;]" ; followed by ws, arg list,
91 ;; Special case to match a line like `main() {}' 94 ;; Special case to match a line like `main() {}'
92 ;; e.g. no return type, not even on the previous line. 95 ;; e.g. no return type, not even on the previous line.
93 (nil 96 (nil
94 ,(concat 97 ,(concat
95 "^" 98 "^"
96 "\\([a-zA-Z_][a-zA-Z0-9_:<>~]*\\)" ; match function name 99 "\\([" c-alpha "_][" c-alnum "_:<>~]*\\)" ; match function name
97 "[ \t]*(" ; see above, BUT 100 "[ \t]*(" ; see above, BUT
98 "[ \t]*\\([^ \t(*][^)]*\\)?)" ; the arg list must not start 101 "[ \t]*\\([^ \t(*][^)]*\\)?)" ; the arg list must not start
99 "[ \t]*[^ \t;(]" ; with an asterisk or parentheses 102 "[ \t]*[^ \t;(]" ; with an asterisk or parentheses
100 ) 1) 103 ) 1)
101 ;; General function name regexp 104 ;; General function name regexp
102 (nil 105 (nil
103 ,(concat 106 ,(concat
104 "^\\<" ; line MUST start with word char 107 "^\\<" ; line MUST start with word char
105 "[^()]*" ; no parentheses before 108 "[^()]*" ; no parentheses before
106 "[^a-zA-Z0-9_:<>~]" ; match any non-identifier char 109 "[^" c-alnum "_:<>~]" ; match any non-identifier char
107 "\\([a-zA-Z_][a-zA-Z0-9_:<>~]*\\)" ; match function name 110 "\\([" c-alpha "_][" c-alnum "_:<>~]*\\)" ; match function name
108 "\\([ \t\n]\\|\\\\\n\\)*(" ; see above, BUT the arg list 111 "\\([ \t\n]\\|\\\\\n\\)*(" ; see above, BUT the arg list
109 "\\([ \t\n]\\|\\\\\n\\)*\\([^ \t\n(*][^)]*\\)?)" ; must not start 112 "\\([ \t\n]\\|\\\\\n\\)*\\([^ \t\n(*][^)]*\\)?)" ; must not start
110 "\\([ \t\n]\\|\\\\\n\\)*[^ \t\n;(]" ; with an asterisk or parentheses 113 "\\([ \t\n]\\|\\\\\n\\)*[^ \t\n;(]" ; with an asterisk or parentheses
111 ) 1) 114 ) 1)
112 ;; Special case for definitions using phony prototype macros like: 115 ;; Special case for definitions using phony prototype macros like:
115 ;; Only supported in c-code, so no `:<>~' chars in function name! 118 ;; Only supported in c-code, so no `:<>~' chars in function name!
116 ,@(if cc-imenu-c-prototype-macro-regexp 119 ,@(if cc-imenu-c-prototype-macro-regexp
117 `((nil 120 `((nil
118 ,(concat 121 ,(concat
119 "^\\<.*" ; line MUST start with word char 122 "^\\<.*" ; line MUST start with word char
120 "[^a-zA-Z0-9_]" ; match any non-identifier char 123 "[^" c-alnum "_]" ; match any non-identifier char
121 "\\([a-zA-Z_][a-zA-Z0-9_]*\\)" ; match function name 124 "\\([" c-alpha "_][" c-alnum "_]*\\)" ; match function name
122 "[ \t]*" ; whitespace before macro name 125 "[ \t]*" ; whitespace before macro name
123 cc-imenu-c-prototype-macro-regexp 126 cc-imenu-c-prototype-macro-regexp
124 "[ \t]*(" ; ws followed by first paren. 127 "[ \t]*(" ; ws followed by first paren.
125 "[ \t]*([^)]*)[ \t]*)[ \t]*[^ \t;]" ; see above 128 "[ \t]*([^)]*)[ \t]*)[ \t]*[^ \t;]" ; see above
126 ) 1))) 129 ) 1)))
127 ;; Class definitions 130 ;; Class definitions
128 ("Class" 131 ("Class"
129 ,(concat 132 ,(concat
130 "^" ; beginning of line is required 133 "^" ; beginning of line is required
131 "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a `template <...>' 134 "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a `template <...>'
132 "\\(class\\|struct\\)[ \t]+" 135 "\\(class\\|struct\\)[ \t]+"
133 "\\(" ; the string we want to get 136 "\\(" ; the string we want to get
134 "[a-zA-Z0-9_]+" ; class name 137 "[" c-alnum "_]+" ; class name
135 "\\(<[^>]+>\\)?" ; possibly explicitly specialized 138 "\\(<[^>]+>\\)?" ; possibly explicitly specialized
136 "\\)" 139 "\\)"
137 "\\([ \t\n]\\|\\\\\n\\)*[:{]" 140 "\\([ \t\n]\\|\\\\\n\\)*[:{]"
138 ) 3)) 141 ) 3))
139 "Imenu generic expression for C++ mode. See `imenu-generic-expression'.") 142 "Imenu generic expression for C++ mode. See `imenu-generic-expression'.")
140 143
141 (defvar cc-imenu-c-generic-expression 144 (defvar cc-imenu-c-generic-expression
142 cc-imenu-c++-generic-expression 145 cc-imenu-c++-generic-expression
143 "Imenu generic expression for C mode. See `imenu-generic-expression'.") 146 "Imenu generic expression for C mode. See `imenu-generic-expression'.")
144 147
145 (defvar cc-imenu-java-generic-expression 148 (defvar cc-imenu-java-generic-expression
146 `((nil 149 `((nil
147 ,(concat 150 ,(concat
148 "^\\([ \t]\\)*" 151 "[" c-alpha "_][\]\[." c-alnum "_]+[ \t\n\r]+" ; type spec
149 "\\([.A-Za-z0-9_-]+[ \t]+\\)?" ; type specs; there can be 152 "\\([" c-alpha "_][" c-alnum "_]+\\)" ; method name
150 "\\([.A-Za-z0-9_-]+[ \t]+\\)?" ; more than 3 tokens, right? 153 "[ \t\n\r]*"
151 "\\([.A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)" 154 ;; An argument list that is either empty or contains at least
152 "\\([ \t]\\)" 155 ;; two identifiers with only space between them. This avoids
153 "\\([A-Za-z0-9_-]+\\)" ; the string we want to get 156 ;; matching e.g. "else if (foo)".
154 "\\([ \t]*\\)+(" 157 (concat "([ \t\n\r]*"
155 "[][a-zA-Z,_1-9\n \t]*" ; arguments 158 "\\([\]\[.," c-alnum "_]+"
156 ")[ \t]*" 159 "[ \t\n\r]+"
157 ; "[^;(]" 160 "[\]\[.," c-alnum "_]"
158 "[,a-zA-Z_1-9\n \t]*{" 161 "[\]\[.," c-alnum "_ \t\n\r]*"
159 ) 6)) 162 "\\)?)")
163 "[.," c-alnum "_ \t\n\r]*"
164 "{"
165 ) 1))
160 "Imenu generic expression for Java mode. See `imenu-generic-expression'.") 166 "Imenu generic expression for Java mode. See `imenu-generic-expression'.")
161 167
162 ;; *Warning for cc-mode developers* 168 ;; *Warning for cc-mode developers*
163 ;; 169 ;;
164 ;; `cc-imenu-objc-generic-expression' elements depend on 170 ;; `cc-imenu-objc-generic-expression' elements depend on
165 ;; `cc-imenu-c++-generic-expression'. So if you change this 171 ;; `cc-imenu-c++-generic-expression'. So if you change this
166 ;; expression, you need to change following variables, 172 ;; expression, you need to change following variables,
167 ;; `cc-imenu-objc-generic-expression-*-index', 173 ;; `cc-imenu-objc-generic-expression-*-index',
168 ;; too. `cc-imenu-objc-function' uses these *-index variables, in 174 ;; too. `cc-imenu-objc-function' uses these *-index variables, in
169 ;; order to know where the each regexp *group \\(foobar\\)* elements 175 ;; order to know where the each regexp *group \\(foobar\\)* elements
170 ;; are started. 176 ;; are started.
171 ;; 177 ;;
172 ;; *-index variables are initialized during `cc-imenu-objc-generic-expression' 178 ;; *-index variables are initialized during `cc-imenu-objc-generic-expression'
173 ;; being initialized. 179 ;; being initialized.
174 ;; 180 ;;
175 181
176 ;; Internal variables 182 ;; Internal variables
177 (defvar cc-imenu-objc-generic-expression-noreturn-index nil) 183 (defvar cc-imenu-objc-generic-expression-noreturn-index nil)
178 (defvar cc-imenu-objc-generic-expression-general-func-index nil) 184 (defvar cc-imenu-objc-generic-expression-general-func-index nil)
179 (defvar cc-imenu-objc-generic-expression-proto-index nil) 185 (defvar cc-imenu-objc-generic-expression-proto-index nil)
180 (defvar cc-imenu-objc-generic-expression-objc-base-index nil) 186 (defvar cc-imenu-objc-generic-expression-objc-base-index nil)
181 187
182 (defvar cc-imenu-objc-generic-expression 188 (defvar cc-imenu-objc-generic-expression
183 (concat 189 (concat
184 ;; 190 ;;
185 ;; For C 191 ;; For C
186 ;; 192 ;;
187 ;; > Special case to match a line like `main() {}' 193 ;; > Special case to match a line like `main() {}'
188 ;; > e.g. no return type, not even on the previous line. 194 ;; > e.g. no return type, not even on the previous line.
189 ;; Pick a token by (match-string 1) 195 ;; Pick a token by (match-string 1)
190 (car (cdr (nth 1 cc-imenu-c++-generic-expression))) ; -> index += 2 196 (car (cdr (nth 1 cc-imenu-c++-generic-expression))) ; -> index += 2
191 (prog2 (setq cc-imenu-objc-generic-expression-noreturn-index 1) "") 197 (prog2 (setq cc-imenu-objc-generic-expression-noreturn-index 1) "")
192 "\\|" 198 "\\|"
193 ;; > General function name regexp 199 ;; > General function name regexp
194 ;; Pick a token by (match-string 3) 200 ;; Pick a token by (match-string 3)
195 (car (cdr (nth 2 cc-imenu-c++-generic-expression))) ; -> index += 2 201 (car (cdr (nth 2 cc-imenu-c++-generic-expression))) ; -> index += 5
196 (prog2 (setq cc-imenu-objc-generic-expression-general-func-index 3) "") 202 (prog2 (setq cc-imenu-objc-generic-expression-general-func-index 3) "")
197 ;; > Special case for definitions using phony prototype macros like: 203 ;; > Special case for definitions using phony prototype macros like:
198 ;; > `int main _PROTO( (int argc,char *argv[]) )'. 204 ;; > `int main _PROTO( (int argc,char *argv[]) )'.
199 ;; Pick a token by (match-string 5) 205 ;; Pick a token by (match-string 8)
200 (if cc-imenu-c-prototype-macro-regexp 206 (if cc-imenu-c-prototype-macro-regexp
201 (concat 207 (concat
202 "\\|" 208 "\\|"
203 (car (cdr (nth 3 cc-imenu-c++-generic-expression))) ; -> index += 1 209 (car (cdr (nth 3 cc-imenu-c++-generic-expression))) ; -> index += 1
204 (prog2 (setq cc-imenu-objc-generic-expression-objc-base-index 6) "") 210 (prog2 (setq cc-imenu-objc-generic-expression-objc-base-index 9) "")
205 ) 211 )
206 (prog2 (setq cc-imenu-objc-generic-expression-objc-base-index 5) "") 212 (prog2 (setq cc-imenu-objc-generic-expression-objc-base-index 8) "")
207 "") ; -> index += 0 213 "") ; -> index += 0
208 (prog2 (setq cc-imenu-objc-generic-expression-proto-index 5) "") 214 (prog2 (setq cc-imenu-objc-generic-expression-proto-index 8) "")
209 ;; 215 ;;
210 ;; For Objective-C 216 ;; For Objective-C
211 ;; Pick a token by (match-string 5 or 6) 217 ;; Pick a token by (match-string 8 or 9)
212 ;; 218 ;;
213 "\\|\\(" 219 "\\|\\("
214 "^[-+][:a-zA-Z0-9()*_<>\n\t ]*[;{]" ; Methods 220 "^[-+][:" c-alnum "()*_<>\n\t ]*[;{]" ; Methods
215 "\\|" 221 "\\|"
216 "^@interface[\t ]+[a-zA-Z0-9_]+[\t ]*:" 222 "^@interface[\t ]+[" c-alnum "_]+[\t ]*:"
217 "\\|" 223 "\\|"
218 "^@interface[\t ]+[a-zA-Z0-9_]+[\t ]*([a-zA-Z0-9_]+)" 224 "^@interface[\t ]+[" c-alnum "_]+[\t ]*([" c-alnum "_]+)"
219 "\\|" 225 "\\|"
220 ;; For NSObject, NSProxy and Object... They don't have super class. 226 ;; For NSObject, NSProxy and Object... They don't have super class.
221 "^@interface[\t ]+[a-zA-Z0-9_]+[\t ]*.*$" 227 "^@interface[\t ]+[" c-alnum "_]+[\t ]*.*$"
222 "\\|" 228 "\\|"
223 "^@implementation[\t ]+[a-zA-Z0-9_]+[\t ]*([a-zA-Z0-9_]+)" 229 "^@implementation[\t ]+[" c-alnum "_]+[\t ]*([" c-alnum "_]+)"
224 "\\|" 230 "\\|"
225 "^@implementation[\t ]+[a-zA-Z0-9_]+" 231 "^@implementation[\t ]+[" c-alnum "_]+"
226 "\\|" 232 "\\|"
227 "^@protocol[\t ]+[a-zA-Z0-9_]+" "\\)") 233 "^@protocol[\t ]+[" c-alnum "_]+" "\\)")
228 "Imenu generic expression for ObjC mode. See `imenu-generic-expression'.") 234 "Imenu generic expression for ObjC mode. See `imenu-generic-expression'.")
229 235
230 236
231 ;; Imenu support for objective-c uses functions. 237 ;; Imenu support for objective-c uses functions.
232 (defsubst cc-imenu-objc-method-to-selector (method) 238 (defsubst cc-imenu-objc-method-to-selector (method)
233 "Return the objc selector style string of METHOD. 239 "Return the objc selector style string of METHOD.
234 Example: 240 Example:
235 - perform: (SEL)aSelector withObject: object1 withObject: object2; /* METHOD */ 241 - perform: (SEL)aSelector withObject: object1 withObject: object2; /* METHOD */
236 => 242 =>
237 -perform:withObject:withObject:withObject: /* selector */" 243 -perform:withObject:withObject:withObject: /* selector */"
238 (let ((return "") ; String to be returned 244 (let ((return "") ; String to be returned
239 (p 0) ; Current scanning position in METHOD 245 (p 0) ; Current scanning position in METHOD
240 (pmax (length method)) ; 246 (pmax (length method)) ;
241 char ; Current scanning target 247 char ; Current scanning target
242 (betweenparen 0) ; CHAR is in parentheses. 248 (betweenparen 0) ; CHAR is in parentheses.
243 argreq ; An argument is required. 249 argreq ; An argument is required.
244 inargvar) ; position of CHAR is in an argument variable. 250 inargvar) ; position of CHAR is in an argument variable.
245 (while (< p pmax) 251 (while (< p pmax)
251 (eq 0 betweenparen) ; Ignore if CHAR is in parentheses. 257 (eq 0 betweenparen) ; Ignore if CHAR is in parentheses.
252 (or (and (<= ?a char) (<= char ?z)) 258 (or (and (<= ?a char) (<= char ?z))
253 (and (<= ?A char) (<= char ?Z)) 259 (and (<= ?A char) (<= char ?Z))
254 (and (<= ?0 char) (<= char ?9)) 260 (and (<= ?0 char) (<= char ?9))
255 (= ?_ char))) 261 (= ?_ char)))
256 (if argreq 262 (if argreq
257 (setq inargvar t 263 (setq inargvar t
258 argreq nil) 264 argreq nil)
259 (setq return (concat return (char-to-string char))))) 265 (setq return (concat return (char-to-string char)))))
260 ;; Or a white space? 266 ;; Or a white space?
261 ((and inargvar (or (eq ?\ char) (eq ?\n char)) 267 ((and inargvar (or (eq ?\ char) (eq ?\n char))
262 (setq inargvar nil))) 268 (setq inargvar nil)))
263 ;; Or a method separator? 269 ;; Or a method separator?
264 ;; If a method separator, the next token will be an argument variable. 270 ;; If a method separator, the next token will be an argument variable.
265 ((eq ?: char) 271 ((eq ?: char)
266 (setq argreq t 272 (setq argreq t
267 return (concat return (char-to-string char)))) 273 return (concat return (char-to-string char))))
268 ;; Or an open parentheses? 274 ;; Or an open parentheses?
269 ((eq ?\( char) 275 ((eq ?\( char)
270 (setq betweenparen (1+ betweenparen))) 276 (setq betweenparen (1+ betweenparen)))
271 ;; Or a close parentheses? 277 ;; Or a close parentheses?
275 281
276 (defun cc-imenu-objc-remove-white-space (str) 282 (defun cc-imenu-objc-remove-white-space (str)
277 "Remove all spaces and tabs from STR." 283 "Remove all spaces and tabs from STR."
278 (let ((return "") 284 (let ((return "")
279 (p 0) 285 (p 0)
280 (max (length str)) 286 (max (length str))
281 char) 287 char)
282 (while (< p max) 288 (while (< p max)
283 (setq char (aref str p)) 289 (setq char (aref str p))
284 (setq p (1+ p)) 290 (setq p (1+ p))
285 (if (or (= char ?\ ) (= char ?\t)) 291 (if (or (= char ?\ ) (= char ?\t))
292 (let (methodlist 298 (let (methodlist
293 clist 299 clist
294 ;; 300 ;;
295 ;; OBJC, Cnoreturn, Cgeneralfunc, Cproto are constants. 301 ;; OBJC, Cnoreturn, Cgeneralfunc, Cproto are constants.
296 ;; 302 ;;
297 ;; *Warning for developers* 303 ;; *Warning for developers*
298 ;; These constants depend on `cc-imenu-c++-generic-expression'. 304 ;; These constants depend on `cc-imenu-c++-generic-expression'.
299 ;; 305 ;;
300 (OBJC cc-imenu-objc-generic-expression-objc-base-index) 306 (OBJC cc-imenu-objc-generic-expression-objc-base-index)
301 ;; Special case to match a line like `main() {}' 307 ;; Special case to match a line like `main() {}'
302 (Cnoreturn cc-imenu-objc-generic-expression-noreturn-index) 308 (Cnoreturn cc-imenu-objc-generic-expression-noreturn-index)
308 ;; 314 ;;
309 (classcount 0) 315 (classcount 0)
310 toplist 316 toplist
311 stupid 317 stupid
312 str 318 str
313 str2 319 str2
314 (intflen (length "@interface")) 320 (intflen (length "@interface"))
315 (implen (length "@implementation")) 321 (implen (length "@implementation"))
316 (prtlen (length "@protocol")) 322 (prtlen (length "@protocol"))
317 (func 323 (func
318 ;; 324 ;;
319 ;; Does this emacs has buffer-substring-no-properties? 325 ;; Does this emacs has buffer-substring-no-properties?
320 ;; 326 ;;
321 (if (fboundp 'buffer-substring-no-properties) 327 (if (fboundp 'buffer-substring-no-properties)
322 'buffer-substring-no-properties 328 'buffer-substring-no-properties
323 'buffer-substring))) 329 'buffer-substring)))
324 (goto-char (point-max)) 330 (goto-char (point-max))
325 (imenu-progress-message stupid 0) 331 (imenu-progress-message stupid 0)
326 ;; 332 ;;
327 (while (re-search-backward cc-imenu-objc-generic-expression nil t) 333 (while (re-search-backward cc-imenu-objc-generic-expression nil t)
328 (imenu-progress-message stupid) 334 (imenu-progress-message stupid)
329 (setq langnum (if (match-beginning OBJC) 335 (setq langnum (if (match-beginning OBJC)
330 OBJC 336 OBJC
331 (cond 337 (cond
332 ((match-beginning Cproto) Cproto) 338 ((match-beginning Cproto) Cproto)
333 ((match-beginning Cgeneralfunc) Cgeneralfunc) 339 ((match-beginning Cgeneralfunc) Cgeneralfunc)
334 ((match-beginning Cnoreturn) Cnoreturn)))) 340 ((match-beginning Cnoreturn) Cnoreturn))))
335 (setq str (funcall func (match-beginning langnum) (match-end langnum))) 341 (setq str (funcall func (match-beginning langnum) (match-end langnum)))
336 ;; 342 ;;
337 (cond 343 (cond
338 ;; 344 ;;
339 ;; C 345 ;; C
340 ;; 346 ;;
341 ((not (eq langnum OBJC)) 347 ((not (eq langnum OBJC))
342 (setq clist (cons (cons str (match-beginning langnum)) clist))) 348 (setq clist (cons (cons str (match-beginning langnum)) clist)))
343 ;; 349 ;;
344 ;; ObjC 350 ;; ObjC
345 ;; 351 ;;
346 ;; An instance Method 352 ;; An instance Method
347 ((eq (aref str 0) ?-) 353 ((eq (aref str 0) ?-)
348 (setq str (concat "-" (cc-imenu-objc-method-to-selector str))) 354 (setq str (concat "-" (cc-imenu-objc-method-to-selector str)))
349 (setq methodlist (cons (cons str 355 (setq methodlist (cons (cons str
350 (match-beginning langnum)) 356 (match-beginning langnum))
353 ((eq (aref str 0) ?+) 359 ((eq (aref str 0) ?+)
354 (setq str (concat "+" (cc-imenu-objc-method-to-selector str))) 360 (setq str (concat "+" (cc-imenu-objc-method-to-selector str)))
355 (setq methodlist (cons (cons str 361 (setq methodlist (cons (cons str
356 (match-beginning langnum)) 362 (match-beginning langnum))
357 methodlist))) 363 methodlist)))
358 ;; Interface or implementation or protocol 364 ;; Interface or implementation or protocol
359 ((eq (aref str 0) ?@) 365 ((eq (aref str 0) ?@)
360 (setq classcount (1+ classcount)) 366 (setq classcount (1+ classcount))
361 (cond 367 (cond
362 ((and (> (length str) implen) 368 ((and (> (length str) implen)
363 (string= (substring str 0 implen) "@implementation")) 369 (string= (substring str 0 implen) "@implementation"))
364 (setq str (substring str implen) 370 (setq str (substring str implen)
365 str2 "@implementation")) 371 str2 "@implementation"))
366 ((string= (substring str 0 intflen) "@interface") 372 ((string= (substring str 0 intflen) "@interface")
374 (match-beginning langnum)) 380 (match-beginning langnum))
375 methodlist)) 381 methodlist))
376 (setq toplist (cons nil (cons (cons str 382 (setq toplist (cons nil (cons (cons str
377 methodlist) toplist)) 383 methodlist) toplist))
378 methodlist nil)))) 384 methodlist nil))))
379 ;; 385 ;;
380 (imenu-progress-message stupid 100) 386 (imenu-progress-message stupid 100)
381 (if (eq (car toplist) nil) 387 (if (eq (car toplist) nil)
382 (setq toplist (cdr toplist))) 388 (setq toplist (cdr toplist)))
383 389
384 ;; In this buffer, there is only one or zero @{interface|implementation|protocol}. 390 ;; In this buffer, there is only one or zero @{interface|implementation|protocol}.
393 (setq last toplist) 399 (setq last toplist)
394 (while (cdr last) 400 (while (cdr last)
395 (setq last (cdr last))) 401 (setq last (cdr last)))
396 (setcdr last clist)))) 402 (setcdr last clist))))
397 ;; Add C lang tokens as a sub menu 403 ;; Add C lang tokens as a sub menu
398 (setq toplist (cons (cons "C" clist) toplist))) 404 (if clist
405 (setq toplist (cons (cons "C" clist) toplist))))
399 ;; 406 ;;
400 toplist 407 toplist
401 )) 408 ))
402 409
403 ;(defvar cc-imenu-pike-generic-expression 410 ;(defvar cc-imenu-pike-generic-expression
404 ; ()) 411 ; ())
405 ; FIXME: Please contribute one! 412 ; FIXME: Please contribute one!
406 413
407 (defun cc-imenu-init (mode-generic-expression) 414 (defun cc-imenu-init (mode-generic-expression
415 &optional mode-create-index-function)
408 (setq imenu-generic-expression mode-generic-expression 416 (setq imenu-generic-expression mode-generic-expression
409 imenu-case-fold-search nil)) 417 imenu-case-fold-search nil)
418 (when mode-create-index-function
419 (setq imenu-create-index-function mode-create-index-function)))
410 420
411 421
412 (cc-provide 'cc-menus) 422 (cc-provide 'cc-menus)
413 423
424 ;;; arch-tag: f6b60933-91f0-4145-ab44-70ca6d1b919b
414 ;;; cc-menus.el ends here 425 ;;; cc-menus.el ends here