CC-IDE: Add comment hide/show to IDE menu
[emacsstuff.git] / cc-ide / cc-ide.el
1 ;;; cc-ide.el --- C++ IDE
2 ;;
3 ;; $Id$
4 ;;
5 ;; Copyright (C) 2000 Stefan Bund
6
7 ;; cc-ide.el is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 2, or (at your
10 ;; option) any later version.
11
12 ;; cc-ide.el is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
16
17 ;;; Commentary:
18
19 ;;; Change-Log:
20
21 ;; $Log$
22 ;;
23
24 ;;; Variables:
25
26 (defvar ccide-compile-opts "DEBUG=1"
27   "*Additional options to make command")
28
29 (defvar ccide-file-vars nil)
30
31 (defvar ccide-default-author "")
32 (defvar ccide-default-copyright "")
33
34 (defvar ccide-corba-skel-dir "")
35 (defvar ccide-corba-idl-dir "")
36 (defvar ccide-corba-idl-command "omniidl2 -w")
37
38 (defvar c-user-prefixes '("inline" "static" "prefix_")
39   "*List of possible prefixes for function definitions.")
40
41 (defvar ccide-default-prefix "prefix_"
42   "*Prefix added to every implementation header. Probably eiter empty or 'prefix_'")
43
44 (defvar ccide-gen-throw nil
45   "*If non-nil, generate throw_ specs")
46
47 (defconst c-user-prefix-re (regexp-opt c-user-prefixes t))
48
49 (defconst ccide-doxy-tag-re 
50   (concat "\\\\\\(group\\|defgroup\\|see\\|author\\|version\\|id\\|since"
51           "\\|returns?\\|throws?\\|exception\\|raises\\|param\\|li\\|brief"
52           "\\|internal\\|bug\\|fixme\\|todo\\|idea\\|implementation\\)\\b"))
53
54 (defconst ccide-special-extensions
55   '(".h" ".hh" ".mpp" ".ih" ".cc" ".cpp" ".ct" ".cti" ".cci"))
56
57 (defconst ccide-implementation-extensions
58   '(".h" ".hh" ".ih" ".cc" ".cpp" ".ct" ".cti" ".cci"))
59
60 (defconst ccide-class-defaults-word 
61   "// \\(default\\|no\\|protected\\|private\\|disabled\\|my\\)")
62
63 (defconst  ccide-bindings
64   '(
65     ;; file level
66     ("fc"  ccide-file-comment                 "File comment")
67     ("fs"  ccide-syncronize-includes          "Sync includes")
68     (nil   nil                                separator)
69                                           
70     ;; class level                        
71     ("cc"  ccide-class-comment                "Class comment")
72     ("cg"  ccide-gen-class                    "Generate class")
73     ("cd"  ccide-gen-class-defaults           "Generate class defaults")
74     ("cD"  ccide-gen-class-defaults-impl      "Generate class defaults impl")
75
76     ("csd" ccide-set-class-defaults-default   "Set class defaults comment" "Default")
77     ("csn" ccide-set-class-defaults-no        "Set class defaults comment" "No")
78     ("csp" ccide-set-class-defaults-protected "Set class defaults comment" "Protected")
79     ("csr" ccide-set-class-defaults-private   "Set class defaults comment" "Private")
80     ("csx" ccide-set-class-defaults-disabled  "Set class defaults comment" "Disabled")
81     ("csm" ccide-set-class-defaults-my        "Set class defaults comment" "My")
82
83     ("cS"  ccide-gen-struct-constructors      "Generate structure constructors")
84
85     ("ci"  ccide-class-impl-comment           "Generate class implemenation comment")
86
87     (nil   nil                                separator)
88                                           
89     ;; method level                       
90     ("mc"  ccide-function-comment             "Method comment")
91     ("mp"  ccide-grab-prototype               "Grab prototype")
92     ("mr"  ccide-reformat-defun               "Reformat defun")
93     ("mx"  ccide-replace-defun                "Replace defun")
94     ("mt"  ccide-prefix-defun-type-with-class "Prefix defun type with class")
95     ("mn"  ccide-prefix-defun-type-with-namespace "Prefix defun type with namespace")
96     ("mi"  ccide-grab-inline-decl             "Grab inline decl")
97     ("mA"  ccide-grab-all-inlines             "Grab ALL inline decls")
98     ("mC"  ccide-grab-create-constructor      "Grab CREATE constructor")
99     ("mI"  ccide-grab-create-constructor-impl "Build CREATE cosntructor")
100     ("mf"  ccide-find-implementation          "Find method implementation")
101     ("mT"  ccide-insert-defun-prefix          "Insert current defun prefix at point")
102     (nil   nil                                separator)
103                                           
104     ;; variable level                     
105     ("vc"  ccide-variable-comment             "Variable comment")
106     ("vf"  ccide-grab-acces-fn                "Grab access methods")
107     (nil   nil                                separator)
108
109     ;; documentation
110     ("h"  ccide-hide-all-doxy-comments        "Hide all Doxygen comments")
111     ("s"  ccide-show-all-comments             "Show all Doxygen comments")
112                                           
113 ;    ;; CORBA                             
114 ;    ("Cg"  ccide-gen-corba-impl                      "Generate CORBA impl")
115 ;    ("Cm"  ccide-gen-corba-impl-methods       "Generate CORBA impl methods")
116 ;    (nil   nil                               separator)
117                                           
118     ;; templates                          
119 ;    ("ts"  ccide-scan-mantemps               "Scan mantemps")
120 ;    (nil   nil                                separator)
121
122 ;    ;; other
123 ;    ("of"  ccide-open-compilation-frame       "Open *compilation* frame")
124 ;    ("oc"  ccide-compile-compile              "Make -> Compile")
125 ;    ("ox"  ccide-compile-clean                "Make -> Clean")
126 ;    ("od"  ccide-compile-cleandepends         "Make -> Clean depends")
127 ;    ("ok"  ccide-compile-kill                 "Kill compilation")
128 ;    ("oh"  ccide-hide-compilation             "Hide *compilation* buffer")
129
130     ))
131
132 ;;; Code:
133
134 (require 'cc-engine-2)
135 (require 'cc-helper)
136 (require 'c++)
137 (require 'cl)
138 (require 'hideshow)
139 ;(require 'mantemp)
140 (require 'locate)
141 (require 'lucid)
142 (require 'varcmd)
143 (require 'misc-local)
144
145 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
146 ;; utils
147
148 (defsubst ccide-match-string (n)
149   (buffer-substring-no-properties (match-beginning n) (match-end n)))
150
151 (defun ccide-file-macro-name (&optional file-name)
152   (concat (upcase (file-name-extension (or file-name (buffer-file-name))))
153           "_" 
154           (string-replace "\\." "_" (file-name-sans-extension 
155                                      (file-name-nondirectory 
156                                       (or file-name (buffer-file-name))))
157                           t nil t t)
158           "_"))
159
160 (defun ccide-file-name (&optional extension file-name directory)
161   (concat (if directory (file-name-as-directory directory) "")
162           (file-name-sans-extension
163            (file-name-nondirectory 
164             (or file-name (buffer-file-name))))
165           extension))
166
167 (defun ccide-in-doxy-comment ()
168   (save-excursion
169     (back-to-indentation)
170     (if (eq (c-in-literal) 'c)
171         (progn
172           (goto-char (car (c-literal-limits)))
173           (and (looking-at "/\\*\\*[ \t\n\r@]")
174                (current-column))))))
175
176 (defun ccide-shell-command (command)
177   (let ((obuf (get-buffer-create "*ccide shell command*"))
178         exit-status)
179     (save-excursion
180       (set-buffer obuf)
181       (erase-buffer)
182       (insert command "\n"))
183     (setq exit-status (call-process shell-file-name nil "*ccide shell command*" nil
184                                     shell-command-switch command))
185     (and exit-status (equal exit-status 0))))
186
187 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
188 ;; file level
189
190 (defun ccide-file-comment ()
191   "Add a comment to this source file."
192   (interactive)
193   (let ((mode "c++")
194         point)
195     (push-mark)
196     (goto-char (point-min))
197     (insert "// $Id$\n"
198             "//\n"
199             "// Copyright (C) " (number-to-string (nth 5 (decode-time)))
200             " " ccide-default-author "\n"
201             ccide-default-copyright
202             "\n")
203     (cond ((string-match "\\.hh?$" (buffer-file-name))
204            (insert "#ifndef " (ccide-file-macro-name) "\n"
205                    "#define " (ccide-file-macro-name) " 1\n\n"
206                    "// Custom includes\n\n"
207                    "//#include \"" (ccide-file-name ".mpp") "\"\n"
208                    "///////////////////////////////hh.p////////////////////////////////////////\n\n")
209            (setq point (point))
210            (goto-char (point-max))
211            (insert "\n\n///////////////////////////////hh.e////////////////////////////////////////\n"
212                    "//#include \"" (ccide-file-name ".cci") "\"\n"
213                    "//#include \"" (ccide-file-name ".ct") "\"\n"
214                    "//#include \"" (ccide-file-name ".cti") "\"\n"
215                    "//#include \"" (ccide-file-name ".mpp") "\"\n"
216                    "#endif"))
217           ((string-match "\\.mpp$" (buffer-file-name))
218            (insert "#if !BOOST_PP_IS_ITERATING\n"
219                    "#ifndef " (ccide-file-macro-name) "\n\n"
220                    "// Custom includes\n\n"
221                    "//////////////////////////////mpp.p////////////////////////////////////////\n"
222                    "// Local Macros\n\n"
223                    "//////\n"
224                    "#endif\n"
225                    "#else\n"
226                    "///////////////////////////////////////////////////////////////////////////\n\n"
227                    "//////\n"
228                    "#if BOOST_PP_ITERATION_FLAGS()==1\n"
229                    "///////////////////////////////////////////////////////////////////////////\n\n")
230            (setq point (point))
231            (goto-char (point-max))
232            (insert "\n\n//////\n"
233                    "#endif\n"
234                    "#endif\n"
235                    "#if !BOOST_PP_IS_ITERATING\n"
236                    "#ifdef " (ccide-file-macro-name) "\n"
237                    "///////////////////////////////////////////////////////////////////////////\n"
238                    "// Undefine local Macros\n\n"
239                    "//////////////////////////////mpp.e////////////////////////////////////////\n"
240                    "#else\n"
241                    "#define " (ccide-file-macro-name) " 1\n"
242                    "#endif\n"
243                    "#endif"))
244           ((string-match "\\.ih$" (buffer-file-name))
245            (insert "#ifndef " (ccide-file-macro-name) "\n"
246                    "#define " (ccide-file-macro-name) " 1\n\n"
247                    "// Custom includes\n\n"
248                    "///////////////////////////////ih.p////////////////////////////////////////\n\n")
249            (setq point (point))
250            (goto-char (point-max))
251            (insert "\n\n///////////////////////////////ih.e////////////////////////////////////////\n"
252                    "#endif"))
253           ((or (string-match "\\.test\\.cc$" (buffer-file-name))
254                (string-match "\\.test\\.cpp$" (buffer-file-name)))
255            (insert "// Unit tests\n\n"
256                    "//#include \"" (ccide-file-name ".hh") "\"\n"
257                    "//#include \"" (ccide-file-name ".ih") "\"\n\n"
258                    "// Custom includes\n"
259                    "#include \"" (ccide-file-name ".hh" (ccide-file-name)) "\"\n\n"
260                    "#include <boost/test/auto_unit_test.hpp>\n"
261                    "#include <boost/test/test_tools.hpp>\n\n"
262                    "#define prefix_\n"
263                    "///////////////////////////////cc.p////////////////////////////////////////\n\n")
264            (setq point (point))
265            (goto-char (point-max))
266            (insert "\n\n///////////////////////////////cc.e////////////////////////////////////////\n"
267                    "#undef prefix_"))
268           ((or (string-match "\\.cc$" (buffer-file-name))
269                (string-match "\\.cpp$" (buffer-file-name)))
270            (insert "// Definition of non-inline non-template functions\n\n"
271                    "//#include \"" (ccide-file-name ".hh") "\"\n"
272                    "//#include \"" (ccide-file-name ".ih") "\"\n\n"
273                    "// Custom includes\n\n"
274                    "//#include \"" (ccide-file-name ".mpp") "\"\n"
275                    "#define prefix_\n"
276                    "///////////////////////////////cc.p////////////////////////////////////////\n\n")
277            (setq point (point))
278            (goto-char (point-max))
279            (insert "\n\n///////////////////////////////cc.e////////////////////////////////////////\n"
280                    "#undef prefix_\n"
281                    "//#include \"" (ccide-file-name ".mpp") "\""))
282           ((string-match "\\.cci$" (buffer-file-name))
283            (insert "// Definition of inline non-template functions\n\n"
284                    "// Custom includes\n\n"
285                    "#define prefix_ inline\n"
286                    "///////////////////////////////cci.p///////////////////////////////////////\n\n")
287            (setq point (point))
288            (goto-char (point-max))
289            (insert "\n\n///////////////////////////////cci.e///////////////////////////////////////\n"
290                    "#undef prefix_"))
291           ((string-match "\\.ct$" (buffer-file-name))
292            (insert "// Definition of non-inline template functions\n\n"
293                    "//#include \"" (ccide-file-name ".ih") "\"\n\n"
294                    "// Custom includes\n\n"
295                    "#define prefix_\n"
296                    "///////////////////////////////ct.p////////////////////////////////////////\n\n")
297            (setq point (point))
298            (goto-char (point-max))
299            (insert "\n\n///////////////////////////////ct.e////////////////////////////////////////\n"
300                    "#undef prefix_"))
301           ((string-match "\\.cti$" (buffer-file-name))
302            (insert "// Definition of inline template functions\n\n"
303                    "//#include \"" (ccide-file-name ".ih") "\"\n\n"
304                    "// Custom includes\n\n"
305                    "#define prefix_ inline\n"
306                    "///////////////////////////////cti.p///////////////////////////////////////\n\n")
307            (setq point (point))
308            (goto-char (point-max))
309            (insert "\n\n///////////////////////////////cti.e///////////////////////////////////////\n"
310                    "#undef prefix_"))
311           ((string-match "\\.java$" (buffer-file-name))
312            (setq mode "jde")
313            (setq point (point))
314            (goto-char (point-max)))
315           (t
316            (setq point (point))
317            (goto-char (point-max))))
318     (insert "\n\n\f\n"
319             "// Local Variables:\n"
320             "// mode: " mode "\n")
321     (loop for (var . value) in ccide-file-vars
322           do (insert "// " (symbol-name var) ": " (prin1-to-string value) "\n"))
323     (insert "// End:\n")
324     (if point
325         (goto-char point))
326     (if (equal mode "jde")
327         (let ((package (file-name-directory (buffer-file-name))))
328           (jdeap-initialize-setup)
329           (if (not (equal jdeap-current-source-directory "."))
330               (if (string-match 
331                    (concat "^" (regexp-quote jdeap-current-source-directory))
332                    package)
333                   (progn
334                     (setq package (substring package 
335                                              (match-end 0)
336                                              (1- (length package))))
337                     (insert "package "
338                             (string-replace "/" "." package t)
339                             ";\n\n"))))
340           (insert "class " (file-name-sans-extension
341                             (file-name-nondirectory 
342                              (buffer-file-name))) "\n{}")
343           (beginning-of-line)))))
344
345 (defun ccide-syncronize-includes ()
346   "Syncronize include's in all other files"
347   (interactive)
348   (let (buffer-map)
349     (loop for extension in ccide-special-extensions
350           for file-name = (ccide-file-name extension)
351           do (setq buffer-map
352                    (cons (cons file-name
353                                (or (find-buffer-visiting file-name)
354                                    (and (file-readable-p file-name)
355                                         (find-file-noselect file-name))))
356                          buffer-map)))
357     (save-excursion
358       (loop for buffer in buffer-map
359             if (cdr buffer)
360               do (progn 
361                    (set-buffer (cdr buffer))
362                    (save-excursion
363                      (loop for include in buffer-map
364                            do (progn 
365                                 (goto-char (point-min))
366                                 (while (re-search-forward 
367                                         (concat "^\\(//\\)?#\\s-*include \""
368                                                 (regexp-quote (car include))
369                                                 "\"\\s-*$")
370                                         nil t)
371                                   (goto-char (match-beginning 0))
372                                   (if (looking-at "//")
373                                       (if (cdr include)
374                                           (delete-char 2))
375                                     (if (not (cdr include))
376                                         (insert "//")))
377                                   (forward-line 1))))))))))
378
379 (defun ccide-auto-decorate-new-files ()
380   (if (= (point-min) (point-max))
381       (let ((status (buffer-modified-p)))
382         (ccide-file-comment)
383         (set-buffer-modified-p status))))
384
385 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
386 ;; class level
387
388 (defun ccide-class-comment ()
389   "Add comment to start of current class definition"
390   (interactive)
391   (let ((class (c-get-class-at-point)))
392     (if (not class)
393         (error "No class found")
394       (goto-char (or (aref (car class) 3)
395                      (aref (car class) 1)))
396       (if (save-excursion 
397             (forward-line -1)
398             (ccide-in-doxy-comment))
399           (progn
400             (search-backward "/**" nil t)
401             (forward-char 4))
402         (let ((indent (make-string (current-indentation) ? )))
403           (insert "/** ")
404           (save-excursion
405             (insert "\n"
406                     indent "    @short \n"
407                     indent " */\n"
408                     indent)))))))
409
410 (defun ccide-gen-class (name &optional defns)
411   "Generate class declaration template"
412   (interactive (list (read-string (concat "Class name (default "
413                                           (ccide-file-name)
414                                           "): ")
415                                   nil nil (ccide-file-name))))
416   (insert "class " name)
417   (indent-according-to-mode)
418   (let ((in (make-string c-basic-offset ? ))
419         (ofs (make-string (current-indentation) ? )))
420     (save-excursion
421       (beginning-of-line)
422       (open-line 1)
423       (insert ofs "/** \\brief\n"
424               ofs "  */"))
425     (insert "\n" ofs)
426     (save-excursion
427       (insert "{\n"
428               ofs "public:\n"
429               ofs in "///////////////////////////////////////////////////////////////////////////\n"
430               ofs in "// Types\n\n"
431               ofs in "///////////////////////////////////////////////////////////////////////////\n"
432               ofs in "///\\name Structors and default members\n"
433               ofs in "///@{\n\n"
434               ofs in "// default default constructor\n"
435               ofs in "// default copy constructor\n"
436               ofs in "// default copy assignment\n"
437               ofs in "// default destructor\n\n"
438               ofs in "// no conversion constructors\n\n"
439               ofs in "///@}\n"
440               ofs in "///////////////////////////////////////////////////////////////////////////\n"
441               ofs in "///\\name Accessors\n"
442               ofs in "///@{\n\n"
443               ofs in "///@}\n"
444               ofs in "///////////////////////////////////////////////////////////////////////////\n"
445               ofs in "///\\name Mutators\n"
446               ofs in "///@{\n\n"
447               ofs in "///@}\n\n")
448       (loop for defn in defns
449             do (insert ofs in defn ";\n"))
450       (if defns
451           (insert "\n"))
452       (insert ofs "protected:\n\n"
453               ofs "private:\n\n"
454               ofs "};\n"))))
455
456 (defun ccide-gen-class-defaults ()
457   "Generate signatures of the default functions: default constructor,
458 copy constructor, assignment operator and destructor."
459   (indent-according-to-mode)
460   (let* ((name (c-scope-name (aref (car (c-get-class-at-point)) 1)))
461          (in (make-string c-basic-offset ? ))
462          (ofs (make-string (current-indentation) ? ))
463          (tspec (if ccide-gen-throw (concat "\n" ofs in "throw_(());\n") ";\n"))
464          (colon 0))
465     (while (string-match "::" name colon)
466       (setq colon (match-end 0)))
467     (setq name (substring name colon))
468     (beginning-of-line)
469     (delete-horizontal-space)
470     (loop with exit = nil
471           do (message (concat "1-dflt constr, 2-destr, "
472                               "3-copy constr, 4-copy assmnt, "
473                               "c-all copy, d-all dflt, RET-all/done: "))
474           for ch = (read-event)
475           for first = t then nil
476           do (cond ((eq ch 'return)
477                     (if first
478                         (insert ofs name "()" 
479                                 tspec
480                                 ofs name "(const " name "& other)" 
481                                 tspec
482                                 ofs "~" name "();\n"
483                                 ofs name "& operator=(const " name "& other)"
484                                 tspec))
485                     (setq exit t))
486                    ((eq ch ?1)
487                     (insert ofs name "()" 
488                             tspec))
489                    ((eq ch ?2)
490                     (insert ofs "~" name "();\n"))
491                    ((eq ch ?3)
492                     (insert ofs name "(const " name "& other)" 
493                             tspec))
494                    ((eq ch ?4)
495                     (insert ofs name "& operator=(const " name "& other)"
496                             tspec))
497                    ((eq ch ?c)
498                     (insert ofs name "(const " name "& other)" 
499                             tspec
500                             ofs name "& operator=(const " name "& other)"
501                             tspec))
502                    ((eq ch ?d)
503                     (insert ofs name "()" 
504                             tspec
505                             ofs "~" name "();\n"))
506                    (t (setq unread-command-events (cons ch unread-command-events))
507                       (setq exit t)))
508           while (not exit))))
509
510 (defun ccide-gen-class-defaults-impl ()
511   "Generate default implementations for class default functions"
512   (interactive)
513   (let ((defn (c-build-default-funcions-impl)))
514     (kill-new (cadr defn))
515     (message (concat (car defn) " default members"))))
516
517 (defun ccide-set-class-defaults-comment (word)
518   (save-excursion
519     (back-to-indentation)
520     (if (not (looking-at ccide-class-defaults-word))
521         (message "Not at class defaults commnet")
522       (replace-match word t t nil 1))))
523
524 (defmacro ccide-build-class-defaults-f (sym)
525   (let ((fn (intern (concat "ccide-set-class-defaults-" 
526                             (symbol-name sym)))))
527     `(defun ,fn ()
528        (interactive)
529        (ccide-set-class-defaults-comment ,(symbol-name sym)))))
530
531 (ccide-build-class-defaults-f no)
532 (ccide-build-class-defaults-f default)
533 (ccide-build-class-defaults-f my)
534 (ccide-build-class-defaults-f protected)
535 (ccide-build-class-defaults-f private)
536 (ccide-build-class-defaults-f disabled)
537
538 (defun ccide-gen-struct-constructors ()
539   (save-excursion
540     (beginning-of-line)
541     (open-line 1)
542     (indent-according-to-mode)
543     (let* ((scope (c-get-block-scope))
544            (class (c-parse-class scope))
545            (variables (c-get-variable-members-with-type class))
546            (name (c-scope-name (aref (car (last scope)) 1)))
547            (in (make-string (current-indentation) ? ))
548            (inin (make-string (+ (current-indentation) c-basic-offset) ? )))
549       (insert name "()\n" inin ": ")
550       (indent-according-to-mode)
551       (loop for var in variables
552             for first = t then nil
553             if (not first) do (insert ", ")
554             do (insert (car var) "()"))
555       (insert "\n" in "{}\n"
556               in name "(")
557       (loop for var in variables
558             for first = t then nil
559             if (not first) do (insert ", ")
560             do (insert (cdr var) " " (car var) "_"))
561       (insert ")\n" inin ": ")
562       (loop for var in variables
563             for first = t then nil
564             if (not first) do (insert ", ")
565             do (insert (car var) "(" (car var) "_)"))
566       (insert "\n" in "{}"))))
567
568 (defun ccide-class-impl-comment ()
569   "Get implementation comment for current class"
570   (interactive)
571   (let* ((scope (c-get-block-scope))
572          (name (c-get-full-prefix scope)))
573     (kill-new (concat (make-string 75 ?/) "\n"
574                       "// " name "\n\n"
575                       "// protected\n\n"
576                       "// private\n\n"))
577     (message name)))
578
579 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
580 ;; function/method level
581
582 (defun ccide-function-comment ()
583   "Add comment to start of current function"
584   (interactive)
585   (c-forward-out-of-comment)
586   (let ((defun (c-get-defun-state))
587         place indent)
588     (c-goto-beginning-of-defun defun)
589     (setq indent (make-string (current-indentation) ? ))
590     (if (save-excursion
591           (forward-line -1)
592           (ccide-in-doxy-comment))
593         ()
594       (insert "/** ")
595       (setq place (point))
596       (insert "\n\n" 
597               indent "    @li @em PRE : \n"
598               indent "    @li @em POST : \n\n"
599               indent "    @short \n"
600               indent " */\n" indent)
601       (setq defun (c-get-defun-state)))
602     (ccide-function-comment-adjust defun indent)
603     (if place (goto-char place))))
604
605 (defun ccide-function-comment-grab-args ()
606   (let ((limit (save-excursion
607                  (search-backward "/**" nil t)
608                  (point)))
609         (end (progn (forward-line -1) (point)))
610         begin start args argend)
611     (if (search-backward "@throws" limit t)
612         (setq argend (progn (beginning-of-line) (point)))
613       (setq argend end))
614     (while (or (search-backward "@param" limit t)
615                (search-backward "@return" limit t)))
616     (beginning-of-line)
617     (setq start (point))
618     (setq begin start)
619     (while (search-forward "@param" argend t)
620       (or (search-forward "@param" argend t)
621           (search-forward "@return" argend t)
622           (search-forward "@throws" argend t)
623           (goto-char argend))
624       (beginning-of-line)
625       (setq args (cons (ccide-function-comment-parse-arg start (point))
626                        args))
627       (setq start (point)))
628     (prog1
629         (if (not (search-forward "@return" argend t))
630             (cons nil args)
631           (beginning-of-line)
632           (cons (buffer-substring (point) argend) args))
633       (delete-region begin end))))
634
635 (defun ccide-function-comment-parse-arg (start end)
636   (save-excursion
637     (goto-char start)
638     (re-search-forward "@param\\s-*\\(\\S-*\\)" end t)
639     (cons (match-string 1) 
640           (cons (buffer-substring start (match-beginning 1))
641                 (buffer-substring (match-end 1) end)))))
642   
643 (defun ccide-function-comment-get-throws (defun)
644   (if (aref defun 4)
645       (save-excursion
646         (goto-char (car (aref defun 4)))
647         (if (re-search-forward "\\(throw_\\|throw\\)((?\\s-*\\([^()]*\\))?)" 
648                                (cdr (aref defun 4)) t)
649             (let ((spec (match-string 2)))
650               (if (> (length spec) 0)
651                   spec))))))
652
653 (defun ccide-function-comment-adjust (defun indent)
654   (let* ((defargs (mapcar (function (lambda (x)
655                                       (c-get-template-argument-name (car x) (cdr x))))
656                           (aref defun 3)))
657          (defret (and (aref defun 1)
658                       (not (string-match (concat "^\\("
659                                                  c-special-key 
660                                                  "\\s-*\\)*\\s-*void$")
661                                          (buffer-substring (car (aref defun 1))
662                                                            (cdr (aref defun 1)))))))
663          (throws (ccide-function-comment-get-throws defun))
664          (xargs (ccide-function-comment-grab-args))
665          (docargs (cdr xargs))
666          (docret (car xargs))
667          (def-in-doc (loop for defarg in defargs always (assoc defarg docargs)))
668          (doc-in-def (loop for docarg in docargs always (member (car docarg) defargs)))
669          (size-eq (= (length defargs) (length docargs))))
670     (if (or defargs defret throws)
671         (if (not (save-excursion 
672                    (forward-line -1)
673                    (looking-at "\\s-*$")))
674             (insert "\n")))
675     ;; We differentiate four types changes
676     ;;  - new arguments
677     ;;  - removed arguments
678     ;;  - reordered arguments
679     ;;  - renamed arguments
680     ;; 
681     ;; If the change cannot be described by one of the above, it has
682     ;; to be resolved manually
683     (save-excursion
684       (cond (doc-in-def
685              ;; reordered arguments or new arguments (or no change)
686              (loop for defarg in defargs
687                    for docarg = (assoc defarg docargs)
688                    do (if docarg
689                           (insert (cadr docarg) (car docarg) (cddr docarg))
690                         (insert indent "    @param " defarg " \n"))))
691             (size-eq ; and (not doc-in-def)
692              ;; renamed arguments
693              (loop for defarg in defargs
694                    for docarg in docargs
695                    do (insert (cadr docarg) defarg (cddr docarg))))
696             (def-in-doc
697               ;; removed arguments
698               (loop for defarg in defargs
699                     for docarg = (assoc defarg docargs)
700                     do (insert (cadr docarg) (car docarg) (cddr docarg))))
701             (t (error "Arg change too complex. Resolve manualy.")))
702       ;; return value is simple
703       (if defret
704           (if docret
705               (insert docret)
706             (insert indent "    @return \n")))
707       (if throws
708           (insert indent "    @throws " throws "\n")))
709     (back-to-indentation)))
710
711 (defun ccide-grab-prototype (&optional prefix)
712   "Grab prototype of function defined or declared at point. Prefix
713 arg, if given, specifies the kind of prefix (inline, static, ...) to use."
714   (interactive "P")
715   (let* ((prfx (or (and prefix (nth (prefix-numeric-value prefix) c-user-prefixes))
716                    ccide-default-prefix))
717          (defn (c-build-defun prfx)))
718     (kill-new (concat (cadr defn) "\n{}\n"))
719     (message (concat (or prfx "")
720                      (if prfx " " "")
721                      (car defn)))))
722
723 (defun ccide-reformat-defun ()
724   "Reformat the defn of the current defun."
725   (interactive)
726   (save-excursion
727     (c-beginning-of-defun-or-decl)
728     (let ((defn (c-build-defun nil t)))
729       (delete-region (or (caar (aref (caddr defn) 0))
730                          (car (aref (caddr defn) 1))
731                          (car (aref (caddr defn) 2)))
732                      (or (car (aref (caddr defn) 6))
733                          (aref (caddr defn) 7)))
734       (insert (cadr defn) "\n"))))
735
736 (defun ccide-replace-defun ()
737   "Replace the function header with the one on the top of the kill
738 ring (presumably placed there using c++-grab-prototype)."
739   (interactive)
740   (save-excursion
741     (c-beginning-of-defun-or-decl)
742     (let ((parse (c-parse-defun)))
743       (delete-region (or (aref parse 0)
744                          (aref parse 1)
745                          (aref parse 2))
746                      (or (aref parse 5)
747                          (aref parse 6)))
748       (yank)
749       (delete-char -3))))
750
751 (defun ccide-prefix-defun-type-with-class (&optional strip)
752   "If a non-keyword type symbol is found prefixing the current defun,
753 it will be prefixed with the current class prefix."
754   (interactive "p")
755   (save-excursion
756     (c-beginning-of-defun-or-decl)
757     (let* ((parse (c-parse-defun))
758            (prefix (c-scope-name (aref parse 2) (+ (or strip 0) 0))))
759       (goto-char (aref parse 1))
760       (while (and (or (looking-at c-any-key)
761                       (looking-at c-user-prefix-re)
762                       (not (c-at-symbol-p)))
763                   (< (point) (aref parse 2))
764                   (not (eobp)))
765         (c-forward-token-1)
766         (c-forward-syntactic-ws))
767       (if (and (c-at-symbol-p)
768                (< (point) (aref parse 2))
769                (not (looking-at (regexp-quote prefix))))
770           (let ((pos (string-match "<" prefix)))
771             (if (and pos (looking-at (concat (substring prefix 0 pos)
772                                              "\\b[^_]")))
773                 (progn
774                   (goto-char (match-end 0))
775                   (c-backward-syntactic-ws)
776                   (insert (substring prefix pos)))
777               (insert prefix "::"))
778             (ccide-reformat-defun))))))
779
780 (defun ccide-prefix-defun-type-with-namespace (&optional strip)
781   (interactive "p")
782   (ccide-prefix-defun-type-with-class (+ (or strip 0) 1)))
783
784 (defun ccide-insert-defun-prefix (&optional strip)
785   "Insert the current defun prefix at point."
786   (interactive "p")
787   (let* ((parse (c-parse-defun))
788          (prefix (c-scope-name (aref parse 2) (+ (or strip 0) 0))))
789     (insert prefix "::")))
790
791 (defun ccide-kill-inline-decl (defn)
792   (save-excursion
793     (if (aref (caddr defn) 6)
794         (progn
795           (goto-char (cdr (aref (caddr defn) 6)))
796           (let ((end-mark (point-marker)))
797             (goto-char (car (aref (caddr defn) 6)))
798             (indent-rigidly (point) end-mark
799                             (- (current-column)))
800             (prog1
801                 (concat (cadr defn)
802                         "\n"
803                         (buffer-substring-no-properties (point) end-mark)
804                         "\n")
805               (when (aref (caddr defn) 5)
806                 (goto-char (caar (aref (caddr defn) 5)))
807                 (c-backward-syntactic-ws)
808                 (skip-chars-backward ":"))
809               (c-backward-syntactic-ws)
810               (delete-region (point) end-mark)
811               (insert ";"))))
812       (concat (cadr defn) "\n{}\n"))))
813
814 (defun ccide-grab-inline-decl ()
815   "Grab the inline decl at point at turn it into an out-of-line inline
816 declaration at the top of the kill ring."
817   (interactive)
818   (let ((defn (c-build-defun (or ccide-default-prefix "inline"))))
819     (kill-new (ccide-kill-inline-decl defn))
820     (message (concat (or ccide-default-prefix "indline") 
821                      " " 
822                      (car defn)))))
823
824 (defun ccide-grab-all-inlines ()
825   "Grab all inline decls in the current class"
826   (interactive)
827   (let ((class (c-parse-class (c-get-block-scope)))
828         defns)
829     (when class
830       (loop for method in (nreverse (aref class 4))
831             do (when (eq (car method) 'method)
832                  (let ((defn (save-excursion
833                                (goto-char (cdr method))
834                                (c-build-defun (or ccide-default-prefix "inline")))))
835                    (if (aref (caddr defn) 6)
836                        (setq defns (nconc defns (list (ccide-kill-inline-decl defn))))))))
837       (kill-new (loop for defn in (nreverse defns)
838                       for next = nil then t
839                       if next concat "\n";
840                       concat defn))
841       (message (format "%d inlines grabed to kill ring" (length defns))))))
842                        
843
844 (defun ccide-grab-create-constructor ()
845   (interactive)
846   (let ((defn (c-build-create-constructor)))
847     (kill-new (cadr defn))
848     (message (car defn))))
849
850 (defun ccide-grab-create-constructor-impl (&optional prefix)
851   (interactive "P")
852   (let* ((prfx (or (and prefix (nth (prefix-numeric-value prefix) c-user-prefixes))
853                    ccide-default-prefix))
854          (defn (c-build-create-constructor-impl prfx)))
855     (kill-new (cadr defn))
856     (message (concat (or prfx "")
857                      (if prfx " " "")
858                      (car defn)))))
859
860 ;; (defun ccide-find-implementation (&optional other-window)
861 ;;   "Find implementation of method declared at point."
862 ;;   (interactive "P")
863 ;;   (let ((def (c-build-defun))
864 ;;      match pos)
865 ;;     (setq match (concat (regexp-quote (car def)) "[ \t\n\r]*("))
866 ;;     (setq match (string-replace "::" "::[ \t\n\r]*" match t nil t t))
867 ;;     (message match)
868 ;;     (loop for ext in ccide-implementation-extensions
869 ;;        do (let* ((filename (ccide-file-name ext))
870 ;;                  (buf (and (file-readable-p filename) (find-file-noselect filename))))
871 ;;             (if buf
872 ;;                 (save-excursion
873 ;;                   (set-buffer buf)
874 ;;                   (goto-char (point-min))
875 ;;                   (if (loop while (search-forward-regexp match nil t)
876 ;;                             do (forward-char -1)
877 ;;                             thereis (c-at-toplevel-p))
878 ;;                       (setq pos (cons buf (point)))))))
879 ;;        until pos)
880 ;;     (if pos
881 ;;      (let ((win (get-buffer-window (car pos))))
882 ;;           (if win
883 ;;               (select-window win)
884 ;;             (if other-window
885 ;;                 (switch-to-buffer-other-window (car pos))
886 ;;               (switch-to-buffer (car pos))))
887 ;;        (goto-char (cdr pos))
888 ;;        (forward-char -1)
889 ;;        (c-beginning-of-defun-or-decl))
890 ;;       (message (concat "Implementation of " (car def) " not found.")))))
891
892 (defun ccide-find-implementation (&optional other-window)
893   "Find implementation of method declared at point."
894   (interactive "P")
895   (let* ((state (c-get-defun-state))
896          (name (c-defun-short-name state))
897          (scoped-name (c-defun-full-name state))
898          (args (ccide-implementation-args state))
899          rv fallback)
900
901     (loop for ext in ccide-implementation-extensions
902           for filename = (ccide-file-name ext)
903           while (not rv)
904           do (progn
905                (let ((buf (or (find-buffer-visiting filename)
906                                   (and (file-readable-p filename)
907                                        (find-file-noselect filename)))))
908                  (when buf
909                    (let ((found (save-excursion
910                                   (set-buffer buf)
911                                   (ccide-find-implementation-1 name scoped-name args
912                                                                (car (aref state 2))))))
913                      (if found
914                          (if (cdr found)
915                              (setq rv (cons buf found))
916                            (if (not fallback) (setq fallback (cons buf found))))))))))
917     (if (not rv) (setq rv fallback))
918     (if rv
919         (let* ((buf (car rv))
920                (pos (cadr rv))
921                (win (get-buffer-window buf)))
922           (if win 
923               (select-window win)
924             (if other-window
925                 (switch-to-buffer-other-window buf)
926               (switch-to-buffer buf)))
927           (goto-char pos)
928           (forward-char -1)
929           (c-beginning-of-defun-or-decl))
930       (message (concat "Implementation of " scoped-name " not found.")))))
931
932 (defun ccide-implementation-args (state)
933   (string-replace "[ \t\n\r]+" ""
934                   (loop for (start . end) in (aref state 3)
935                         for sep = "" then ","
936                         concat sep
937                         concat (buffer-substring-no-properties 
938                                 start (save-excursion
939                                         (goto-char start)
940                                         (if (search-forward "=" end 'move) (forward-char -1))
941                                         (point))))
942                   
943                   t))
944
945 (defun ccide-find-implementation-1 (name scoped-name args skip-def)
946   ;; Within the current buffer, search for all implementations of the
947   ;; given function. The rv is a list of conses. The car holds the
948   ;; buffer position of the implementation, the cdr is t if the name,
949   ;; scoped-name and args are matched, otherwise the args did not match.
950   (save-excursion
951     (goto-char (point-min))
952     (let (fallback rv check-state)
953       (while (and (not rv) (search-forward name nil t))
954         (if (and (c-at-toplevel-p) 
955                  (not (c-in-literal))
956                  (setq check-state (condition-case nil (c-get-defun-state) (error nil)))
957                  (not (= (car (aref check-state 2)) skip-def)))
958             (if (string= scoped-name (c-defun-full-name check-state))
959                 (if (string= args (ccide-implementation-args check-state))
960                     (setq rv (cons (point) t))
961                   (if (not fallback) 
962                       (setq fallback (cons (point) nil)))))))
963       (or rv fallback))))
964
965 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
966 ;; variable/type level
967   
968 (defun ccide-variable-comment ()
969   "Add a comment to current variable declaration."
970   (interactive)
971   (push-mark)
972   (beginning-of-line)
973   (open-line 1)
974   (insert "/// ")
975   (indent-according-to-mode))
976
977 (defun ccide-grab-access-fn ()
978   (interactive)
979   (save-excursion
980     (beginning-of-line)
981     (if (looking-at (concat c++-simple-type-regexp "[ \t\n\r][a-zA-Z0-9_]+[ \t\n\r]*;"))
982         (let ((vardef (match-string 0))
983               (in (make-string c-basic-offset ? ))
984               type varname ws doc)
985           (forward-line -1)
986           (back-to-indentation)
987           (if (looking-at "///[ \t\n\r]*")
988               (setq doc (buffer-substring (match-end 0)
989                                           (progn (end-of-line) (point)))))
990           (string-match "^[ \t\n\r]*\\(.*\\)[ \t\n\r]\\([a-zA-Z0-9_]+\\)[ \t\n\r]*;$"
991                         vardef)
992           (setq varname (match-string 2 vardef)
993                 type (match-string 1 vardef)
994                 ws (substring vardef 0 (match-beginning 1)))
995           (if (string-match "^[ \t\n\r]*" type)
996               (setq type (substring type (match-end 0))))
997           (kill-new (concat (if doc
998                                 (concat ws "/** Setze " doc ".\n\n"
999                                         ws "    @param _" varname " neu: " doc "\n"
1000                                         ws "    @return alt: " doc "\n"
1001                                         ws " */\n")
1002                               "")
1003                             ws type " q_" varname "(" type " _" varname ")\n"
1004                             ws in "{\n"
1005                             ws in in type " old" varname " = " varname ";\n"
1006                             ws in in varname " = _" varname ";\n"
1007                             ws in in "return(old" varname ");\n"
1008                             ws in "}\n\n"
1009                             (if doc
1010                                 (concat ws "/** Hole " doc ".\n\n"
1011                                         ws "    @return " doc "\n"
1012                                         ws "*/\n")
1013                               "")
1014                             ws type " q_" varname "(void) const\n"
1015                             ws in "{ return(" varname "); }\n"))
1016           
1017           (message varname))
1018       (message "No variable found"))))
1019
1020 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1021 ;; doxy comment support functions
1022
1023 (defun ccide-special-indent-function ()
1024   "Function to indent doxy comments correctly"
1025   (let ((indent (ccide-in-doxy-comment)))
1026     (if indent
1027         (let ((lim (save-excursion
1028                      (back-to-indentation)
1029                      (c-literal-limits)))
1030               (pos (- (point-max) (point))))
1031           (incf indent 4)
1032           (save-excursion
1033             (back-to-indentation)
1034             (if (looking-at "*/")
1035                 (incf indent -3)
1036               (let ((para (or (save-excursion (re-search-backward "^\\s-*$" (car lim) t))
1037                               (car lim))))
1038                 (if (and (not (looking-at ccide-doxy-tag-re))
1039                          (re-search-backward (concat "^\\s-*"
1040                                                      ccide-doxy-tag-re)
1041                                              para t))
1042                     (incf indent 4)))))
1043           (delete-region (progn (beginning-of-line) (point))
1044                          (progn (back-to-indentation) (point)))
1045           (indent-to indent)
1046           (if (> (- (point-max) pos) (point))
1047               (goto-char (- (point-max) pos)))))))
1048   
1049 (defun ccide-fill-function ()
1050   "auto-fill function for doxy comments"
1051   (if (do-auto-fill)
1052       (if (not fill-prefix)
1053           (indent-according-to-mode))))
1054
1055 (defun ccide-hide-all-doxy-comments ()
1056   "Hide all doxy comments"
1057   (interactive)
1058   (save-excursion
1059     (goto-char (point-min))
1060     (while (re-search-forward "^\\s-*/\\*\\*" nil t)
1061       (beginning-of-line)
1062       (forward-line -1)
1063       (if (not (looking-at "\\s-*$"))
1064           (forward-line 1))
1065       (forward-char -1)
1066       (let ((start (point)))
1067         (if (re-search-forward "\\*/" nil t)
1068             (progn
1069               (if (looking-at "\\s-*\n")
1070                   (forward-line 1))
1071               (forward-char -1)
1072               (let ((overlay (make-overlay start (point))))
1073                 (overlay-put overlay 'intangible 'hs)
1074                 (overlay-put overlay 'invisible 'hs)))))))
1075   (message "Done."))
1076
1077 (defun ccide-show-all-comments ()
1078   "Show all comments"
1079   (interactive)
1080   (save-excursion
1081     (goto-char (point-min))
1082     (while (not (eobp))
1083       (goto-char (next-overlay-change (point)))
1084       (loop for overlay in (overlays-at (point))
1085             if (eq (overlay-get overlay 'invisible) 'hs)
1086             do (delete-overlay overlay))))
1087   (message "Done."))
1088
1089
1090
1091 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1092 ;; CORBA support (omniORB2)
1093
1094 (defun ccide-get-corba-headers ()
1095   (let (files)
1096     (save-excursion
1097       (goto-char (point-min))
1098       (while (re-search-forward "#include\\s-*[\"<]\\([^\">]*\\)\\.hh[\">]" nil t)
1099         (setq files (cons (ccide-match-string 1) files)))
1100       (nreverse files))))
1101
1102 (defun ccide-corba-maybe-build-hh (file)
1103   (let ((skel (ccide-file-name ".hh" file ccide-corba-skel-dir))
1104         (idl (ccide-file-name ".idl" file ccide-corba-idl-dir)))
1105     (if (and (file-readable-p idl)
1106              (or (not (file-readable-p skel))
1107                  (file-newer-than-file-p idl skel)))
1108         (let ((buffer (find-buffer-visiting (ccide-file-name ".hh" file))))
1109           (if buffer
1110               (kill-buffer buffer))
1111           (message "Please wait ... building %s" (ccide-file-name ".hh" file))
1112           (if (ccide-shell-command (concat "cd " 
1113                                            (real-path-name ccide-corba-skel-dir) 
1114                                            " && " 
1115                                            ccide-corba-idl-command 
1116                                            (if (> (length ccide-corba-idl-dir) 0)
1117                                                (concat " -I" ccide-corba-idl-dir))
1118                                            " " 
1119                                            idl))
1120               ()
1121             (display-buffer (get-buffer-create "*ccide shell command*"))
1122             (error "Generation of %s failed" (ccide-file-name ".hh")))))
1123     (if (not (file-readable-p skel))
1124         (error "No file %s or %s" 
1125                (ccide-file-name ".hh" file) (ccide-file-name ".idl" file)))))
1126
1127 (defun ccide-corba-list-skeletons-1 (hh-file)
1128   (ccide-corba-maybe-build-hh hh-file)
1129   (let ((hh-buf (find-file-noselect (ccide-file-name ".hh" hh-file)))
1130         skels)
1131     (save-excursion
1132       (set-buffer hh-buf)
1133       (save-excursion
1134         (goto-char (point-min))
1135         (while (re-search-forward "^\\s-*class\\s-+_sk_\\([a-zA-Z0-9_]+\\)\\s-+:"
1136                                   nil t)
1137           (setq skels (cons (ccide-match-string 1) skels)))))
1138     (mapcar (function (lambda (x) (cons x hh-file)))
1139             (sort skels 'string-lessp))))
1140
1141 (defun ccide-corba-list-skeletons ()
1142   (let ((files (ccide-get-corba-headers)))
1143     (loop for file in files
1144           append (ccide-corba-list-skeletons-1 file))))
1145
1146 (defun ccide-gen-corba-impl (class)
1147   (interactive (list (completing-read "Class name of skeleton: "
1148                                       (ccide-corba-list-skeletons)
1149                                       nil t)))
1150   (let* ((skels (ccide-corba-list-skeletons))
1151          (hh-file (ccide-file-name ".hh" (cdr (assoc class skels))
1152                                    ccide-corba-skel-dir))
1153          (hh-buf (find-file-noselect (ccide-file-name ".hh" hh-file
1154                                                       ccide-corba-skel-dir))))
1155     (ccide-gen-class (concat class "_i"))
1156     (insert (make-string c-basic-offset ? ) ": public virtual _sk_" class "\n")
1157     (save-excursion
1158       (search-forward "protected:" nil t)
1159       (forward-line -1)
1160       (ccide-gen-corba-impl-methods)
1161       (insert "\n"))))
1162
1163 (defun ccide-get-corba-defns (hh-file class)
1164   (let ((hh-buf (find-file-noselect hh-file))
1165         defns)
1166     (save-excursion
1167       (set-buffer hh-buf)
1168       (save-excursion
1169         (goto-char (point-min))
1170         (if (not (re-search-forward (concat "^\\s-*class\\s-+_sk_" class "\\s-+:")
1171                                     nil t))
1172             (error "CORBA skeleton class not found.")
1173           (search-forward "{")
1174           (forward-char -1)
1175           (let ((end (save-excursion (forward-sexp) (point))))
1176             (while (and (< (point) end)
1177                         (< (forward-line 1) 1))
1178               (if (looking-at "\\s-+virtual\\s-+\\(.*)\\)\\s-*=\\s-*0;\\s-*$")
1179                   (setq defns (cons (match-string 1) defns))))))))
1180     (nreverse defns)))
1181
1182 (defun ccide-gen-corba-impl-methods ()
1183   (interactive)
1184   (let* ((class (c-get-class-at-point))
1185          (point (point)))
1186     (if (not class)
1187         (error "No class at point."))
1188     (save-excursion
1189       (goto-char (aref (car class) 1))
1190       (if (not (re-search-forward ":\\s-*public\\s-*virtual\\s-*_sk_\\([^ \t\n\r{},:]*\\)"
1191                                   nil t))
1192           (error "No CORBA impl at point."))
1193       (let* ((name (ccide-match-string 1))
1194              (skels (ccide-corba-list-skeletons))
1195              (hh-file (ccide-file-name ".hh" (cdr (assoc name skels))
1196                                        ccide-corba-skel-dir))
1197              (defns (ccide-get-corba-defns hh-file name))
1198              end)
1199         (goto-char (aref (car class) 2))
1200         (save-excursion
1201           (c-forward-sexp)
1202           (setq end (point)))
1203         (if (re-search-forward "^\\s-*// CORBA$" end t)
1204             (let ((start (match-beginning 0)))
1205               (if (re-search-forward "^\\s-*// END-CORBA$" end t)
1206                   (let ((eend (match-end 0)))
1207                     (goto-char start)
1208                     (forward-line 1)
1209                     (if (re-search-forward "/\\*\\|//" (match-beginning 0) t)
1210                         (if (y-or-n-p "Remove CORBA Funktion comments? (y/n)")
1211                             (delete-region start (1+ eend))
1212                           (goto-char eend)
1213                           (beginning-of-line)
1214                           (delete-region (point) (progn 
1215                                                    (end-of-line)
1216                                                    (1+ (point))))
1217                           (save-excursion
1218                             (goto-char start)
1219                             (delete-region (point) (progn 
1220                                                      (end-of-line)
1221                                                      (1+ (point)))))
1222                           (insert "\n"))
1223                       (delete-region start (1+ eend))))))
1224           (goto-char point))
1225         (indent-according-to-mode)
1226         (insert "// CORBA\n")
1227         (loop for defn in defns
1228               do (progn
1229                    (save-excursion (insert defn ";"))
1230                    (indent-according-to-mode)
1231                    (let ((start (point)) end)
1232                      (end-of-line)
1233                      (setq end (point))
1234                      (goto-char start)
1235                      (while (re-search-forward "\\s-+" end t)
1236                        (replace-match " ")
1237                        (setq end (- end (- (match-end 0) (match-beginning 0) 1))))
1238                      (end-of-line)
1239                      (loop with done = nil
1240                            while (> (current-column) c-max-def-column)
1241                            do (while (and (> (current-column) c-max-def-column)
1242                                           (search-backward "," start t)))
1243                            do (if (looking-at ",")
1244                                   (progn
1245                                     (forward-char 1)
1246                                     (insert "\n")
1247                                     (open-line 1)
1248                                     (indent-according-to-mode)
1249                                     (delete-char 2)
1250                                     (setq start (point))
1251                                     (end-of-line))
1252                                 (setq done t))
1253                            while (not done)))
1254                    (insert "\n")))
1255         (indent-according-to-mode)
1256         (insert "// END-CORBA\n")))))
1257
1258 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1259 ;; template support
1260
1261 (defun ccide-scan-mantemps ()
1262   "Scan *compilation* buffer for errors and generate manual template
1263 instatiations at point."
1264   (interactive)
1265   (save-excursion
1266     (set-buffer "*compilation*")
1267     (goto-char (point-min)))
1268   (save-excursion
1269     (set-buffer (get-buffer-create "*mantemps*"))
1270     (erase-buffer)
1271     (loop for temp = (ccide-get-mantemp)
1272           while temp
1273           do (insert temp "\n"))
1274     (mantemp-make-mantemps-buffer)
1275     (goto-char (point-min))
1276     (while (progn
1277              (ccide-fix-mantemp)
1278              (< (forward-line 1) 1))))
1279   (insert-buffer-substring "*mantemps*"))
1280
1281 (defun ccide-get-mantemp ()
1282   (save-excursion
1283     (set-buffer "*compilation*")
1284     (if (search-forward "undefined reference to `" nil t)
1285         (let ((start (point)))
1286           (end-of-line)
1287           (search-backward "'" nil t)
1288           (buffer-substring start (point))))))
1289
1290 (defun ccide-fix-mantemp ()
1291   (let ((end (save-excursion
1292                (end-of-line) (point))))
1293     (if (and (save-excursion (search-forward "(" end t))
1294              (search-forward " class" end t))
1295         (progn
1296           (forward-char -6)
1297           (delete-char 6)))))
1298       
1299 (provide 'cc-ide)
1300
1301 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1302 ;; other stuff
1303
1304 (defun ccide-open-compilation-frame ()
1305   (interactive)
1306   (let ((c-frame (selected-frame))
1307         (compilation-frame (make-frame '((minibuffer . nil) 
1308                                          (unsplittable . t) 
1309                                          (menu-bar-lines . 0) 
1310                                          (top . -87) 
1311                                          (left . 36) 
1312                                          (width . 169) 
1313                                          (height . 9)))))
1314     (select-frame compilation-frame)
1315     (switch-to-buffer "*compilation*")
1316     (set-window-dedicated-p (selected-window) t)))
1317
1318 (defun ccide-compile (command)
1319   (delete-other-windows)
1320   (split-window-horizontally)
1321   (compile command)
1322   (save-excursion
1323     (set-buffer "*compilation*")
1324     (let ((point (point-max)))
1325       (goto-char point)
1326       (loop for window in (get-buffer-window-list "*compilation*" nil t)
1327             do (set-window-point window point)))))
1328
1329 (defun ccide-compile-compile ()
1330   (interactive)
1331   (ccide-compile (concat "make -k " ccide-compile-opts)))
1332
1333 (defun ccide-compile-clean ()
1334   (interactive)
1335   (ccide-compile (concat "make -k " ccide-compile-opts " clean")))
1336
1337 (defun ccide-compile-cleandepends ()
1338   (interactive)
1339   (ccide-compile (concat "make -k " ccide-compile-opts " cleandepends")))
1340
1341 (defun ccide-compile-kill ()
1342   (interactive)
1343   (set-buffer "*compilation*")
1344   (kill-compilation))
1345
1346 (defun ccide-hide-compilation ()
1347   (interactive)
1348   (let ((active (selected-window)))
1349     (unwind-protect
1350         (loop for window in (get-buffer-window-list "*compilation*")
1351               do (progn (select-window window)
1352                         (switch-to-buffer (other-buffer "*compilation*"))))
1353       (select-window active))))
1354
1355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1356 ;; keymap and installation
1357
1358 (defun ccide-bind-keys (prefix map)
1359   (loop for binding in ccide-bindings
1360         do (apply 'vcmd-define-key
1361                   map
1362                   (concat prefix (car binding))
1363                   (cadr binding)
1364                   "IDE"
1365                   (cddr binding))))
1366
1367 (defun ccide-install-it ()
1368   (save-excursion
1369     (hs-minor-mode 1)
1370     (hs-show-all))
1371   (local-unset-key "\C-c;")
1372   (local-unset-key [menu-bar IDE])
1373   (ccide-bind-keys "\C-c;" (current-local-map))
1374   (local-set-key "\C-cC" 'ccide-hide-all-doxy-comments)
1375   (local-set-key "\C-cS" 'ccide-show-all-comments)
1376   (set (make-local-variable 'auto-fill-function) 'ccide-fill-function)
1377   (auto-fill-mode -1)
1378   (ccide-auto-decorate-new-files))
1379
1380 (add-hook 'c-mode-hook 'ccide-install-it)
1381 (add-hook 'c++-mode-hook 'ccide-install-it)
1382 (add-hook 'c-special-indent-hook 'ccide-special-indent-function)
1383
1384 (loop for extension in ccide-special-extensions
1385       for re = (concat (regexp-quote extension) "$")
1386       if (not (assoc re auto-mode-alist))
1387         do (setq auto-mode-alist (append auto-mode-alist
1388                                          (list (cons re 'c++-mode)))))
1389
1390 (defadvice c-indent-line (after c-indent-less compile disable) ;activate
1391   ;; new indent function for c-mode: do standard indentation first. If line
1392   ;; is to long using standard indentation, just indent by c-basic-indentation.
1393   (let ((cc (save-excursion (end-of-line) (current-column)))
1394         indent)
1395     (if (> cc  85)
1396         (let ((pos (- (point-max) (point))))
1397           (beginning-of-line)
1398           (let ((point (point))
1399                 (line (1+ (count-lines 1 (point))))
1400                 indent)
1401             (c-beginning-of-statement-2)
1402             (if (and (not (c-crosses-statement-barrier-p (point) point))
1403                      (not (eq (+ (count-lines 1 (point))
1404                                  (if (bolp) 1 0))
1405                               line)))
1406                 (progn
1407                   (setq indent (+ (current-indentation) c-basic-offset))
1408                   (goto-char point)
1409                   (if (< indent (current-indentation))
1410                       (progn
1411                         (setq ad-return-value
1412                               (+ ad-return-value
1413                                  (- (current-indentation) indent)))
1414                         (delete-region (c-point 'bol) (c-point 'boi))
1415                         (indent-to indent))))))
1416           (if (< (point) (c-point 'boi))
1417               (back-to-indentation)
1418             (if (> (- (point-max) pos) (point))
1419                 (goto-char (- (point-max) pos))))))))
1420
1421
1422 \f
1423 ;;; Local Variables:
1424 ;;; elisp-project-autoload-file-name: "cc-autoload.el"
1425 ;;; End: