/[emacs]/emacs/lisp/progmodes/cc-cmds.el
ViewVC logotype

Diff of /emacs/lisp/progmodes/cc-cmds.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.41 by rms, Sun Sep 25 23:58:28 2005 UTC revision 1.42 by acmacm, Fri Dec 2 12:30:35 2005 UTC
# Line 1  Line 1 
1  ;;; cc-cmds.el --- user level commands for CC Mode  ;;; cc-cmds.el --- user level commands for CC Mode
2    
3  ;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc.  ;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4    ;; Inc.
5    
6  ;; Authors:    1998- Martin Stjernholm  ;; Authors:    1998- Martin Stjernholm
7  ;;             1992-1999 Barry A. Warsaw  ;;             1992-1999 Barry A. Warsaw
# Line 24  Line 25 
25  ;; GNU General Public License for more details.  ;; GNU General Public License for more details.
26    
27  ;; You should have received a copy of the GNU General Public License  ;; 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  ;; along with this program; see the file COPYING.  If not, write to
29  ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,  ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
30  ;; Boston, MA 02110-1301, USA.  ;; Boston, MA 02110-1301, USA.
31    
# Line 45  Line 46 
46  (cc-require 'cc-engine)  (cc-require 'cc-engine)
47    
48  ;; Silence the compiler.  ;; Silence the compiler.
49  (cc-bytecomp-defvar delete-key-deletes-forward) ; XEmacs 20+  (cc-bytecomp-defun delete-forward-p)    ; XEmacs
 (cc-bytecomp-defun delete-forward-p)    ; XEmacs 21+  
 (cc-bytecomp-obsolete-fun insert-and-inherit) ; Marked obsolete in XEmacs 19  
50  (cc-bytecomp-defvar filladapt-mode)     ; c-fill-paragraph contains a kludge  (cc-bytecomp-defvar filladapt-mode)     ; c-fill-paragraph contains a kludge
51                                          ; which looks at this.                                          ; which looks at this.
52    (cc-bytecomp-defun c-forward-subword)
53    (cc-bytecomp-defun c-backward-subword)
54    
55  (defvar c-fix-backslashes t)  (defvar c-fix-backslashes t)
56    
# Line 64  point is used to decide where the old in Line 64  point is used to decide where the old in
64  is otherwise empty \(ignoring any line continuation backslash), but  is otherwise empty \(ignoring any line continuation backslash), but
65  that's not done if IGNORE-POINT-POS is non-nil.  Returns the amount of  that's not done if IGNORE-POINT-POS is non-nil.  Returns the amount of
66  indentation change \(in columns)."  indentation change \(in columns)."
   ;;  
   ;; This function does not do any hidden buffer changes.  
67    
68    (let ((line-cont-backslash (save-excursion    (let ((line-cont-backslash (save-excursion
69                                 (end-of-line)                                 (end-of-line)
# Line 134  indentation change \(in columns)." Line 132  indentation change \(in columns)."
132      shift-amt))      shift-amt))
133    
134  (defun c-newline-and-indent (&optional newline-arg)  (defun c-newline-and-indent (&optional newline-arg)
135    "Inserts a newline and indents the new line.    "Insert a newline and indent the new line.
136  This function fixes line continuation backslashes if inside a macro,  This function fixes line continuation backslashes if inside a macro,
137  and takes care to set the indentation before calling  and takes care to set the indentation before calling
138  `indent-according-to-mode', so that lineup functions like  `indent-according-to-mode', so that lineup functions like
139  `c-lineup-dont-change' works better."  `c-lineup-dont-change' works better."
   ;;  
   ;; This function does not do any hidden buffer changes.  
140    
141    ;; TODO: Backslashes before eol in comments and literals aren't    ;; TODO: Backslashes before eol in comments and literals aren't
142    ;; kept intact.    ;; kept intact.
# Line 221  With universal argument, inserts the ana Line 217  With universal argument, inserts the ana
217                     (c-save-buffer-state nil                     (c-save-buffer-state nil
218                       (c-guess-basic-syntax)))))                       (c-guess-basic-syntax)))))
219      (if (not (consp arg))      (if (not (consp arg))
220          (message "syntactic analysis: %s" syntax)          (let (elem pos ols)
221              (message "Syntactic analysis: %s" syntax)
222              (unwind-protect
223                  (progn
224                    (while syntax
225                      (setq elem (pop syntax))
226                      (when (setq pos (c-langelem-pos elem))
227                        (push (c-put-overlay pos (1+ pos)
228                                             'face 'highlight)
229                              ols))
230                      (when (setq pos (c-langelem-2nd-pos elem))
231                        (push (c-put-overlay pos (1+ pos)
232                                             'face 'secondary-selection)
233                              ols)))
234                    (sit-for 10))
235                (while ols
236                  (c-delete-overlay (pop ols)))))
237        (indent-for-comment)        (indent-for-comment)
238        (insert-and-inherit (format "%s" syntax))        (insert-and-inherit (format "%s" syntax))
239        ))        ))
240    (c-keep-region-active))    (c-keep-region-active))
241    
242  (defun c-syntactic-information-on-region (from to)  (defun c-syntactic-information-on-region (from to)
243    "Inserts a comment with the syntactic analysis on every line in the region."    "Insert a comment with the syntactic analysis on every line in the region."
244    (interactive "*r")    (interactive "*r")
245    (save-excursion    (save-excursion
246      (save-restriction      (save-restriction
# Line 239  With universal argument, inserts the ana Line 251  With universal argument, inserts the ana
251          (forward-line)))))          (forward-line)))))
252    
253    
254    (defun c-update-modeline ()
255      (let ((fmt (format "/%s%s%s%s"
256                         (if c-electric-flag "l" "")
257                         (if (and c-electric-flag c-auto-newline)
258                             "a" "")
259                         (if c-hungry-delete-key "h" "")
260                         (if (and
261                              ;; cc-subword might not be loaded.
262                              (boundp 'c-subword-mode)
263                              (symbol-value 'c-subword-mode))
264                             "w"
265                           ""))))
266        (setq c-submode-indicators
267              (if (> (length fmt) 1)
268                  fmt))
269        (force-mode-line-update)))
270    
271  (defun c-toggle-syntactic-indentation (&optional arg)  (defun c-toggle-syntactic-indentation (&optional arg)
272    "Toggle syntactic indentation.    "Toggle syntactic indentation.
273  Optional numeric ARG, if supplied, turns on syntactic indentation when  Optional numeric ARG, if supplied, turns on syntactic indentation when
# Line 249  When syntactic indentation is turned on Line 278  When syntactic indentation is turned on
278  functions and the electric keys indent according to the syntactic  functions and the electric keys indent according to the syntactic
279  context keys, when applicable.  context keys, when applicable.
280    
281  When it's turned off, the electric keys does no reindentation, the  When it's turned off, the electric keys don't reindent, the indentation
282  indentation functions indents every new line to the same level as the  functions indents every new line to the same level as the previous
283  previous nonempty line, and \\[c-indent-command] adjusts the  nonempty line, and \\[c-indent-command] adjusts the indentation in steps
284  indentation in seps specified `c-basic-offset'.  The indentation style  specified by `c-basic-offset'.  The indentation style has no effect in
285  has no effect in this mode, nor any of the indentation associated  this mode, nor any of the indentation associated variables,
286  variables, e.g. `c-special-indent-hook'.  e.g. `c-special-indent-hook'.
287    
288  This command sets the variable `c-syntactic-indentation'."  This command sets the variable `c-syntactic-indentation'."
289    (interactive "P")    (interactive "P")
# Line 262  This command sets the variable `c-syntac Line 291  This command sets the variable `c-syntac
291          (c-calculate-state arg c-syntactic-indentation))          (c-calculate-state arg c-syntactic-indentation))
292    (c-keep-region-active))    (c-keep-region-active))
293    
294  (defun c-toggle-auto-state (&optional arg)  (defun c-toggle-auto-newline (&optional arg)
295    "Toggle auto-newline feature.    "Toggle auto-newline feature.
296  Optional numeric ARG, if supplied, turns on auto-newline when  Optional numeric ARG, if supplied, turns on auto-newline when
297  positive, turns it off when negative, and just toggles it when zero or  positive, turns it off when negative, and just toggles it when zero or
298  left out.  left out.
299    
300  When the auto-newline feature is enabled (as evidenced by the `/a' or  Turning on auto-newline automatically enables electric indentation.
301  `/ah' on the modeline after the mode name) newlines are automatically  
302  inserted after special characters such as brace, comma, semi-colon,  When the auto-newline feature is enabled (indicated by \"/la\" on the
303  and colon."  modeline after the mode name) newlines are automatically inserted
304    after special characters such as brace, comma, semi-colon, and colon."
305    (interactive "P")    (interactive "P")
306    (setq c-auto-newline (c-calculate-state arg c-auto-newline))    (setq c-auto-newline
307            (c-calculate-state arg (and c-auto-newline c-electric-flag)))
308      (if c-auto-newline (setq c-electric-flag t))
309    (c-update-modeline)    (c-update-modeline)
310    (c-keep-region-active))    (c-keep-region-active))
311    
312    (defalias 'c-toggle-auto-state 'c-toggle-auto-newline)
313    (make-obsolete 'c-toggle-auto-state 'c-toggle-auto-newline)
314    
315  (defun c-toggle-hungry-state (&optional arg)  (defun c-toggle-hungry-state (&optional arg)
316    "Toggle hungry-delete-key feature.    "Toggle hungry-delete-key feature.
317  Optional numeric ARG, if supplied, turns on hungry-delete when  Optional numeric ARG, if supplied, turns on hungry-delete when
318  positive, turns it off when negative, and just toggles it when zero or  positive, turns it off when negative, and just toggles it when zero or
319  left out.  left out.
320    
321  When the hungry-delete-key feature is enabled (as evidenced by the  When the hungry-delete-key feature is enabled (indicated by \"/h\" on
322  `/h' or `/ah' on the modeline after the mode name) the delete key  the modeline after the mode name) the delete key gobbles all preceding
323  gobbles all preceding whitespace in one fell swoop."  whitespace in one fell swoop."
324    (interactive "P")    (interactive "P")
325    (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))    (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
326    (c-update-modeline)    (c-update-modeline)
# Line 297  Optional numeric ARG, if supplied, turns Line 332  Optional numeric ARG, if supplied, turns
332  hungry-delete when positive, turns them off when negative, and just  hungry-delete when positive, turns them off when negative, and just
333  toggles them when zero or left out.  toggles them when zero or left out.
334    
335  See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."  See `c-toggle-auto-newline' and `c-toggle-hungry-state' for details."
336    (interactive "P")    (interactive "P")
337    (setq c-auto-newline (c-calculate-state arg c-auto-newline))    (setq c-auto-newline (c-calculate-state arg c-auto-newline))
338    (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))    (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
339    (c-update-modeline)    (c-update-modeline)
340    (c-keep-region-active))    (c-keep-region-active))
341    
342    (defun c-toggle-electric-state (&optional arg)
343      "Toggle the electric indentation feature.
344    Optional numeric ARG, if supplied, turns on electric indentation when
345    positive, turns it off when negative, and just toggles it when zero or
346    left out."
347      (interactive "P")
348      (setq c-electric-flag (c-calculate-state arg c-electric-flag))
349      (c-update-modeline)
350      (c-keep-region-active))
351    
352    
353  ;; Electric keys  ;; Electric keys
354    
355  (defun c-electric-backspace (arg)  (defun c-electric-backspace (arg)
356    "Delete the preceding character or whitespace.    "Delete the preceding character or whitespace.
357  If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or  If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode
358  \"/ah\" string on the mode line, then all preceding whitespace is  line) then all preceding whitespace is consumed.  If however a prefix
359  consumed.  If however a prefix argument is supplied, or  argument is supplied, or `c-hungry-delete-key' is nil, or point is
360  `c-hungry-delete-key' is nil, or point is inside a literal then the  inside a literal then the function in the variable
361  function in the variable `c-backspace-function' is called."  `c-backspace-function' is called."
362    (interactive "*P")    (interactive "*P")
363    (if (or (not c-hungry-delete-key)    (if (c-save-buffer-state ()
364            arg          (or (not c-hungry-delete-key)
365            (c-in-literal))              arg
366                (c-in-literal)))
367        (funcall c-backspace-function (prefix-numeric-value arg))        (funcall c-backspace-function (prefix-numeric-value arg))
368      (c-hungry-backspace)))      (c-hungry-backspace)))
369    
# Line 334  See also \\[c-hungry-delete-forward]." Line 380  See also \\[c-hungry-delete-forward]."
380    
381  (defun c-electric-delete-forward (arg)  (defun c-electric-delete-forward (arg)
382    "Delete the following character or whitespace.    "Delete the following character or whitespace.
383  If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or  If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode
384  \"/ah\" string on the mode line, then all following whitespace is  line) then all following whitespace is consumed.  If however a prefix
385  consumed.  If however a prefix argument is supplied, or  argument is supplied, or `c-hungry-delete-key' is nil, or point is
386  `c-hungry-delete-key' is nil, or point is inside a literal then the  inside a literal then the function in the variable `c-delete-function'
387  function in the variable `c-delete-function' is called."  is called."
388    (interactive "*P")    (interactive "*P")
389    (if (or (not c-hungry-delete-key)    (if (c-save-buffer-state ()
390            arg          (or (not c-hungry-delete-key)
391            (c-in-literal))              arg
392                (c-in-literal)))
393        (funcall c-delete-function (prefix-numeric-value arg))        (funcall c-delete-function (prefix-numeric-value arg))
394      (c-hungry-delete-forward)))      (c-hungry-delete-forward)))
395    
# Line 361  See also \\[c-hungry-backspace]." Line 408  See also \\[c-hungry-backspace]."
408  (defun c-electric-delete (arg)  (defun c-electric-delete (arg)
409    "Deletes preceding or following character or whitespace.    "Deletes preceding or following character or whitespace.
410  This function either deletes forward as `c-electric-delete-forward' or  This function either deletes forward as `c-electric-delete-forward' or
411  backward as `c-electric-backspace', depending on the configuration:  backward as `c-electric-backspace', depending on the configuration: If
412    the function `delete-forward-p' is defined and returns non-nil, it
413  If the function `delete-forward-p' is defined (XEmacs 21) and returns  deletes forward.  Otherwise it deletes backward.
414  non-nil, it deletes forward.  Else, if the variable  
415  `delete-key-deletes-forward' is defined (XEmacs 20) and is set to  Note: This is the way in XEmacs to choose the correct action for the
416  non-nil, it deletes forward.  Otherwise it deletes backward.  \[delete] key, whichever key that means.  Other flavors don't use this
417    function to control that."
 Note: This is the way in XEmacs 20 and later to choose the correct  
 action for the [delete] key, whichever key that means.  In other  
 flavors this function isn't used, instead it's left to the user to  
 bind [delete] to either \\[c-electric-delete-forward] or \\[c-electric-backspace] as appropriate  
 \(the keymap `function-key-map' is useful for that).  Emacs 21 handles  
 that automatically, though."  
418    (interactive "*P")    (interactive "*P")
419    (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21    (if (and (fboundp 'delete-forward-p)
420                 (delete-forward-p))             (delete-forward-p))
           (and (boundp 'delete-key-deletes-forward) ;XEmacs 20  
                delete-key-deletes-forward))  
421        (c-electric-delete-forward arg)        (c-electric-delete-forward arg)
422      (c-electric-backspace arg)))      (c-electric-backspace arg)))
423    
424    ;; This function is only used in XEmacs.
425    (defun c-hungry-delete ()
426      "Delete a non-whitespace char, or all whitespace up to the next non-whitespace char.
427    The direction of deletion depends on the configuration: If the
428    function `delete-forward-p' is defined and returns non-nil, it deletes
429    forward using `c-hungry-delete-forward'.  Otherwise it deletes
430    backward using `c-hungry-backspace'.
431    
432    Note: This is the way in XEmacs to choose the correct action for the
433    \[delete] key, whichever key that means.  Other flavors don't use this
434    function to control that."
435      (interactive)
436      (if (and (fboundp 'delete-forward-p)
437               (delete-forward-p))
438          (c-hungry-delete-forward)
439        (c-hungry-backspace)))
440    
441  (defun c-electric-pound (arg)  (defun c-electric-pound (arg)
442    "Electric pound (`#') insertion.    "Insert a \"#\".
443  Inserts a `#' character specially depending on the variable  If `c-electric-flag' is set, handle it specially according to the variable
444  `c-electric-pound-behavior'.  If a numeric ARG is supplied, or if  `c-electric-pound-behavior'.  If a numeric ARG is supplied, or if point is
445  point is inside a literal or a macro, nothing special happens."  inside a literal or a macro, nothing special happens."
446    (interactive "*P")    (interactive "*P")
447    (if (or arg    (if (c-save-buffer-state ()
448            (not (memq 'alignleft c-electric-pound-behavior))          (or arg
449            (save-excursion              (not c-electric-flag)
450              (skip-chars-backward " \t")              (not (memq 'alignleft c-electric-pound-behavior))
451              (not (bolp)))              (save-excursion
452            (save-excursion                (skip-chars-backward " \t")
453              (and (= (forward-line -1) 0)                (not (bolp)))
454                   (progn (end-of-line)              (save-excursion
455                          (eq (char-before) ?\\))))                (and (= (forward-line -1) 0)
456            (c-in-literal))                     (progn (end-of-line)
457                              (eq (char-before) ?\\))))
458                (c-in-literal)))
459        ;; do nothing special        ;; do nothing special
460        (self-insert-command (prefix-numeric-value arg))        (self-insert-command (prefix-numeric-value arg))
461      ;; place the pound character at the left edge      ;; place the pound character at the left edge
# Line 410  point is inside a literal or a macro, no Line 468  point is inside a literal or a macro, no
468             (goto-char (- (point-max) pos)))             (goto-char (- (point-max) pos)))
469        )))        )))
470    
471    (defun c-point-syntax ()
472      ;; Return the syntactic context of the construct at point.  (This is NOT
473      ;; nec. the same as the s.c. of the line point is on).  N.B. This won't work
474      ;; between the `#' of a cpp thing and what follows (see c-opt-cpp-prefix).
475      (c-save-buffer-state (;; shut this up too
476            (c-echo-syntactic-information-p nil)
477            syntax)
478        (c-tentative-buffer-changes
479          ;; insert a newline to isolate the construct at point for syntactic
480          ;; analysis.
481          (insert-char ?\n 1)
482          ;; In AWK (etc.) or in a macro, make sure this CR hasn't changed
483          ;; the syntax.  (There might already be an escaped NL there.)
484          (when (or (c-at-vsemi-p (1- (point)))
485                    (let ((pt (point)))
486                      (save-excursion
487                        (backward-char)
488                        (and (c-beginning-of-macro)
489                             (progn (c-end-of-macro)
490                                    (< (point) pt))))))
491            (backward-char)
492            (insert-char ?\\ 1)
493            (forward-char))
494          (let ((c-syntactic-indentation-in-macros t)
495                (c-auto-newline-analysis t))
496            ;; Turn on syntactic macro analysis to help with auto
497            ;; newlines only.
498            (setq syntax (c-guess-basic-syntax))
499            nil))
500        syntax))
501    
502    (defun c-brace-newlines (syntax)
503      ;; A brace stands at point.  SYNTAX is the syntactic context of this brace
504      ;; (not necessarily the same as the S.C. of the line it is on).  Return
505      ;; NEWLINES, the list containing some combination of the symbols `before'
506      ;; and `after' saying where newlines should be inserted.
507      (c-save-buffer-state
508          ((syms
509            ;; This is the list of brace syntactic symbols that can hang.
510            ;; If any new ones are added to c-offsets-alist, they should be
511            ;; added here as well.
512            '(class-open class-close defun-open defun-close
513                         inline-open inline-close
514                         brace-list-open brace-list-close
515                         brace-list-intro brace-entry-open
516                         block-open block-close
517                         substatement-open statement-case-open
518                         extern-lang-open extern-lang-close
519                         namespace-open namespace-close
520                         module-open module-close
521                         composition-open composition-close
522                         inexpr-class-open inexpr-class-close
523                         ;; `statement-cont' is here for the case with a brace
524                         ;; list opener inside a statement.  C.f. CASE B.2 in
525                         ;; `c-guess-continued-construct'.
526                         statement-cont))
527           ;; shut this up too
528           (c-echo-syntactic-information-p nil)
529           symb-newlines)                ; e.g. (substatement-open . (after))
530        
531        (setq symb-newlines
532              ;; Do not try to insert newlines around a special
533              ;; (Pike-style) brace list.
534              (if (and c-special-brace-lists
535                       (save-excursion
536                         (c-safe (if (= (char-before) ?{)
537                                     (forward-char -1)
538                                   (c-forward-sexp -1))
539                                 (c-looking-at-special-brace-list))))
540                  nil
541                ;; Seek the matching entry in c-hanging-braces-alist.
542                (or (c-lookup-lists
543                     syms
544                     ;; Substitute inexpr-class and class-open or
545                     ;; class-close with inexpr-class-open or
546                     ;; inexpr-class-close.
547                     (if (assq 'inexpr-class syntax)
548                         (cond ((assq 'class-open syntax)
549                                '((inexpr-class-open)))
550                               ((assq 'class-close syntax)
551                                '((inexpr-class-close)))
552                               (t syntax))
553                       syntax)
554                     c-hanging-braces-alist)
555                    '(ignore before after)))) ; Default, when not in c-h-b-l.
556    
557        ;; If syntax is a function symbol, then call it using the
558        ;; defined semantics.
559        (if (and (not (consp (cdr symb-newlines)))
560                 (functionp (cdr symb-newlines)))
561            (let ((c-syntactic-context syntax))
562              (funcall (cdr symb-newlines)
563                       (car symb-newlines)
564                       (point)))
565          (cdr symb-newlines))))
566    
567    (defun c-try-one-liner ()
568      ;; Point is just after a newly inserted }.  If the non-whitespace
569      ;; content of the braces is a single line of code, compact the whole
570      ;; construct to a single line, if this line isn't too long.  The Right
571      ;; Thing is done with comments.
572      ;;
573      ;; Point will be left after the }, regardless of whether the clean-up is
574      ;; done.  Return NON-NIL if the clean-up happened, NIL if it didn't.
575    
576      (let ((here (point))
577            (pos (- (point-max) (point)))
578            mbeg1 mend1 mbeg4 mend4
579            eol-col cmnt-pos cmnt-col cmnt-gap)
580    
581        (when
582            (save-excursion
583              (save-restriction
584                ;; Avoid backtracking over a very large block.  The one we
585                ;; deal with here can never be more than three lines.
586                (narrow-to-region (save-excursion
587                                    (forward-line -2)
588                                    (point))
589                                  (point))
590                (and (c-safe (c-backward-sexp))
591                     (progn
592                       (forward-char)
593                       (narrow-to-region (point) (1- here)) ; innards of {.}
594                       (looking-at
595                        (cc-eval-when-compile
596                          (concat
597                           "\\("            ; (match-beginning 1)
598                           "[ \t]*\\([\r\n][ \t]*\\)?" ; WS with opt. NL
599                           "\\)"            ; (match-end 1)
600                           "[^ \t\r\n]+\\([ \t]+[^ \t\r\n]+\\)*" ; non-WS
601                           "\\("            ; (match-beginning 4)
602                           "[ \t]*\\([\r\n][ \t]*\\)?" ; WS with opt. NL
603                           "\\)\\'")))))))  ; (match-end 4) at EOB.
604    
605          (if (c-tentative-buffer-changes
606                (setq mbeg1 (match-beginning 1) mend1 (match-end 1)
607                      mbeg4 (match-beginning 4) mend4 (match-end 4))
608                (backward-char)             ; back over the `}'
609                (save-excursion
610                  (setq cmnt-pos (and (c-backward-single-comment)
611                                      (- (point) (- mend1 mbeg1)))))
612                (delete-region mbeg4 mend4)
613                (delete-region mbeg1 mend1)
614                (setq eol-col (save-excursion (end-of-line) (current-column)))
615    
616                ;; Necessary to put the closing brace before any line
617                ;; oriented comment to keep it syntactically significant.
618                ;; This isn't necessary for block comments, but the result
619                ;; looks nicer anyway.
620                (when cmnt-pos
621                  (delete-char 1)           ; the `}' has blundered into a comment
622                  (goto-char cmnt-pos)
623                  (setq cmnt-col (1+ (current-column)))
624                  (setq cmnt-pos (1+ cmnt-pos)) ; we're inserting a `}'
625                  (c-skip-ws-backward)
626                  (insert-char ?\} 1)       ; reinsert the `}' before the comment.
627                  (setq cmnt-gap (- cmnt-col (current-column)))
628                  (when (zerop cmnt-gap)
629                    (insert-char ?\  1)     ; Put a space before a bare comment.
630                    (setq cmnt-gap 1)))
631    
632                (or (null c-max-one-liner-length)
633                    (zerop c-max-one-liner-length)
634                    (<= eol-col c-max-one-liner-length)
635                    ;; Can we trim space before comment to make the line fit?
636                    (and cmnt-gap
637                         (< (- eol-col cmnt-gap) c-max-one-liner-length)
638                         (progn (goto-char cmnt-pos)
639                                (backward-delete-char-untabify
640                                 (- eol-col c-max-one-liner-length))
641                                t))))
642              (goto-char (- (point-max) pos))))))
643    
644  (defun c-electric-brace (arg)  (defun c-electric-brace (arg)
645    "Insert a brace.    "Insert a brace.
646    
647  If the auto-newline feature is turned on, as evidenced by the \"/a\"  If `c-electric-flag' is non-nil, the brace is not inside a literal and a
648  or \"/ah\" string on the mode line, newlines are inserted before and  numeric ARG hasn't been supplied, the command performs several electric
649  after braces based on the value of `c-hanging-braces-alist'.  actions:
650    
651  Also, the line is re-indented unless a numeric ARG is supplied, the  \(a) If the auto-newline feature is turned on (indicated by \"/ln\" on
652  brace is inserted inside a literal, or `c-syntactic-indentation' is  the mode line) newlines are inserted before and after the brace as
653  nil.  directed by the settings in `c-hanging-braces-alist'.
654    
655    \(b) Any auto-newlines are indented.  The original line is also
656    reindented unless `c-syntactic-indentation' is nil.
657    
658    \(c) If auto-newline is turned on, various newline cleanups based on the
659    settings of `c-cleanup-list' are done."
660    
 This function does various newline cleanups based on the value of  
 `c-cleanup-list'."  
661    (interactive "*P")    (interactive "*P")
662    (let* ((safepos (c-safe-position (point) (c-parse-state)))    (let (safepos literal
663           (literal (c-in-literal safepos))          ;; We want to inhibit blinking the paren since this would be
664           ;; We want to inhibit blinking the paren since this will be          ;; most disruptive.  We'll blink it ourselves later on.
665           ;; most disruptive.  We'll blink it ourselves later on.          (old-blink-paren blink-paren-function)
666           (old-blink-paren blink-paren-function)          blink-paren-function)
667           blink-paren-function)  
668      (cond      (c-save-buffer-state ()
669       ((or literal arg)        (setq safepos (c-safe-position (point) (c-parse-state))
670        (self-insert-command (prefix-numeric-value arg)))              literal (c-in-literal safepos)))
671       ((not (looking-at "[ \t]*\\\\?$"))  
672        (self-insert-command (prefix-numeric-value arg))      ;; Insert the brace.  Note that expand-abbrev might reindent
673        (if c-syntactic-indentation      ;; the line here if there's a preceding "else" or something.
674            (indent-according-to-mode)))      (self-insert-command (prefix-numeric-value arg))
675       (t  
676        (let* ((syms      (when (and c-electric-flag (not literal) (not arg))
677                ;; This is the list of brace syntactic symbols that can        (if (not (looking-at "[ \t]*\\\\?$"))
678                ;; hang.  If any new ones are added to c-offsets-alist,            (if c-syntactic-indentation
679                ;; they should be added here as well.                (indent-according-to-mode))
680                '(class-open class-close defun-open defun-close  
681                  inline-open inline-close          (let ( ;; shut this up too
682                  brace-list-open brace-list-close                (c-echo-syntactic-information-p nil)
683                  brace-list-intro brace-entry-open                newlines
684                  block-open block-close                ln-syntax br-syntax syntax) ; Syntactic context of the original line,
685                  substatement-open statement-case-open                          ; of the brace itself, of the line the brace ends up on.
686                  extern-lang-open extern-lang-close            (c-save-buffer-state ((c-syntactic-indentation-in-macros t)
687                  namespace-open namespace-close                                  (c-auto-newline-analysis t))
688                  module-open module-close              (setq ln-syntax (c-guess-basic-syntax)))
689                  composition-open composition-close            (if c-syntactic-indentation
690                  inexpr-class-open inexpr-class-close                (c-indent-line ln-syntax))
691                  ;; `statement-cont' is here for the case with a brace  
692                  ;; list opener inside a statement.  C.f. CASE B.2 in            (when c-auto-newline
693                  ;; `c-guess-continued-construct'.              (backward-char)
694                  statement-cont))              (setq br-syntax (c-point-syntax)
695               (insertion-point (point))                    newlines (c-brace-newlines br-syntax))
696               (preserve-p (and (not (bobp))  
697                                (eq ?\  (char-syntax (char-before)))))              ;; Insert the BEFORE newline, if wanted, and reindent the newline.
698               ;; shut this up too              (if (and (memq 'before newlines)
699               (c-echo-syntactic-information-p nil)                       (> (current-column) (current-indentation)))
700               delete-temp-newline syntax newlines)                  (if c-syntactic-indentation
701          ;; only insert a newline if there is non-whitespace behind us                      ;; Only a plain newline for now - it's indented
702          (when (save-excursion                      ;; after the cleanups when the line has its final
703                  (skip-chars-backward " \t")                      ;; appearance.
704                  (not (bolp)))                      (newline)
705            (c-newline-and-indent)                    (c-newline-and-indent)))
706            ;; Set markers around the newline and indention inserted              (forward-char)
707            ;; above.  We insert the start marker here and not before  
708            ;; the call to kludge around a misfeature in expand-abbrev:              ;; `syntax' is the syntactic context of the line which ends up
709            ;; If the line contains e.g. "else" then expand-abbrev will              ;; with the brace on it.
710            ;; be called when c-newline-and-indent inserts the newline.              (setq syntax (if (memq 'before newlines) br-syntax ln-syntax))
711            ;; That function first removes the abbrev "else" and then  
712            ;; inserts the expansion, which is an identical "else" in              ;; Do all appropriate clean ups
713            ;; this case.  So the marker that we put after "else" would              (let ((here (point))
714            ;; end up before it.                    (pos (- (point-max) (point)))
715            (setq delete-temp-newline                    mbeg mend
716                  (cons (save-excursion                    )
717                          (end-of-line 0)  
718                          (if (eq (char-before) ?\\)                ;; `}': clean up empty defun braces
719                              ;; Ignore a line continuation.                (when (c-save-buffer-state ()
720                              (backward-char))                        (and (memq 'empty-defun-braces c-cleanup-list)
721                          (skip-chars-backward " \t")                             (eq last-command-char ?\})
722                          (copy-marker (point) t))                             (c-intersect-lists '(defun-close class-close inline-close)
723                        (point-marker))))                                                syntax)
724          (unwind-protect                             (progn
725              (progn                               (forward-char -1)
726                (if (eq last-command-char ?{)                               (c-skip-ws-backward)
727                    (setq c-state-cache (cons (point) c-state-cache)))                               (eq (char-before) ?\{))
728                (self-insert-command (prefix-numeric-value arg))                             ;; make sure matching open brace isn't in a comment
729                (c-save-buffer-state ((c-syntactic-indentation-in-macros t)                             (not (c-in-literal))))
730                                      (c-auto-newline-analysis t))                  (delete-region (point) (1- here))
731                  ;; Turn on syntactic macro analysis to help with auto                  (setq here (- (point-max) pos)))
732                  ;; newlines only.                (goto-char here)
733                  (setq syntax (c-guess-basic-syntax)))  
734                (setq newlines                ;; `}': compact to a one-liner defun?
735                      (and                (save-match-data
736                       c-auto-newline                  (when
737                       (or (c-lookup-lists                      (and (eq last-command-char ?\})
738                            syms                           (memq 'one-liner-defun c-cleanup-list)
739                            ;; Substitute inexpr-class and class-open or                           (c-intersect-lists '(defun-close) syntax)
740                            ;; class-close with inexpr-class-open or                           (c-try-one-liner))
741                            ;; inexpr-class-close.                    (setq here (- (point-max) pos))))
742                            (if (assq 'inexpr-class syntax)  
743                                (cond ((assq 'class-open syntax)                ;; `{': clean up brace-else-brace and brace-elseif-brace
744                                       '((inexpr-class-open)))                (when (eq last-command-char ?\{)
745                                      ((assq 'class-close syntax)                  (cond
746                                       '((inexpr-class-close)))                   ((and (memq 'brace-else-brace c-cleanup-list)
747                                      (t syntax))                         (re-search-backward
748                              syntax)                          (concat "}"
749                            c-hanging-braces-alist)                                  "\\([ \t\n]\\|\\\\\n\\)*"
750                           '(ignore before after))))                                  "else"
751                ;; Do not try to insert newlines around a special                                  "\\([ \t\n]\\|\\\\\n\\)*"
752                ;; (Pike-style) brace list.                                  "{"
753                (if (and c-special-brace-lists                                  "\\=")
754                         (save-excursion                          nil t))
755                           (c-save-buffer-state nil                    (delete-region mbeg mend)
756                             (c-safe (if (= (char-before) ?{)                    (insert-and-inherit "} else {"))
757                                         (forward-char -1)                   ((and (memq 'brace-elseif-brace c-cleanup-list)
758                                       (c-forward-sexp -1))                         (progn
759                                     (c-looking-at-special-brace-list)))))                           (goto-char (1- here))
760                    (setq newlines nil))                           (setq mend (point))
761                ;; If syntax is a function symbol, then call it using the                           (c-skip-ws-backward)
762                ;; defined semantics.                           (setq mbeg (point))
763                (if (and (not (consp (cdr newlines)))                           (eq (char-before) ?\)))
764                         (functionp (cdr newlines)))                         (zerop (c-save-buffer-state nil (c-backward-token-2 1 t)))
765                    (let ((c-syntactic-context syntax))                         (eq (char-after) ?\()
766                      (setq newlines                        ; (progn
767                            (funcall (cdr newlines)                          ; (setq tmp (point))
768                                     (car newlines)                           (re-search-backward
769                                     insertion-point))))                            (concat "}"
770                ;; does a newline go before the open brace?                                    "\\([ \t\n]\\|\\\\\n\\)*"
771                (when (memq 'before newlines)                                    "else"
772                  ;; we leave the newline we've put in there before,                                    "\\([ \t\n]\\|\\\\\n\\)+"
773                  ;; but we need to re-indent the line above                                    "if"
774                  (when delete-temp-newline                                    "\\([ \t\n]\\|\\\\\n\\)*"
775                    (set-marker (car delete-temp-newline) nil)                                    "\\=")
776                    (set-marker (cdr delete-temp-newline) nil)                            nil t);)
777                    (setq delete-temp-newline nil))                         ;(eq (match-end 0) tmp);
778                  (when c-syntactic-indentation                           )
779                    (let ((pos (- (point-max) (point)))                    (delete-region mbeg mend)
780                          (here (point)))                    (goto-char mbeg)
781                      (forward-line -1)                    (insert ?\ ))))
782                      (indent-according-to-mode)  
783                      (goto-char (- (point-max) pos))                (goto-char (- (point-max) pos))
784                      ;; if the buffer has changed due to the  
785                      ;; indentation, we need to recalculate syntax for                ;; Indent the line after the cleanups since it might
786                      ;; the current line.                ;; very well indent differently due to them, e.g. if
787                      (if (/= (point) here)                ;; c-indent-one-line-block is used together with the
788                          (c-save-buffer-state                ;; one-liner-defun cleanup.
789                              ((c-syntactic-indentation-in-macros t)                (when c-syntactic-indentation
790                               (c-auto-newline-analysis t))                  (c-indent-line)))
791                            ;; Turn on syntactic macro analysis to help  
792                            ;; with auto newlines only.              ;; does a newline go after the brace?
793                            (setq syntax (c-guess-basic-syntax))))))))              (if (memq 'after newlines)
794            ;; must remove the newline we just stuck in (if we really did it)                  (c-newline-and-indent))
795            (when delete-temp-newline              ))))
796              (save-excursion  
               (delete-region (car delete-temp-newline)  
                              (cdr delete-temp-newline))  
               (goto-char (car delete-temp-newline))  
               (set-marker (car delete-temp-newline) nil)  
               (set-marker (cdr delete-temp-newline) nil)  
               ;; if there is whitespace before point, then preserve  
               ;; at least one space.  
               (just-one-space)  
               (if (not preserve-p)  
                   (delete-char -1)))))  
         (if (not (memq 'before newlines))  
             ;; since we're hanging the brace, we need to recalculate  
             ;; syntax.  
             (c-save-buffer-state ((c-syntactic-indentation-in-macros t)  
                                   (c-auto-newline-analysis t))  
               ;; Turn on syntactic macro analysis to help with auto  
               ;; newlines only.  
               (setq syntax (c-guess-basic-syntax))))  
         (when c-syntactic-indentation  
           ;; Now adjust the line's indentation.  Don't update the state  
           ;; cache since c-guess-basic-syntax isn't called when  
           ;; c-syntactic-context is set.  
           (let* ((c-syntactic-context syntax))  
             (indent-according-to-mode)))  
         ;; Do all appropriate clean ups  
         (let ((here (point))  
               (pos (- (point-max) (point)))  
               mbeg mend tmp)  
           ;; clean up empty defun braces  
           (if (and c-auto-newline  
                    (memq 'empty-defun-braces c-cleanup-list)  
                    (eq last-command-char ?\})  
                    (c-intersect-lists '(defun-close class-close inline-close)  
                                       syntax)  
                    (progn  
                      (forward-char -1)  
                      (c-skip-ws-backward)  
                      (eq (char-before) ?\{))  
                    ;; make sure matching open brace isn't in a comment  
                    (not (c-in-literal)))  
               (delete-region (point) (1- here)))  
           ;; clean up brace-else-brace and brace-elseif-brace  
           (when (and c-auto-newline  
                      (eq last-command-char ?\{))  
             (cond  
              ((and (memq 'brace-else-brace c-cleanup-list)  
                    (re-search-backward  
                     (concat "}"  
                             "\\([ \t\n]\\|\\\\\n\\)*"  
                             "else"  
                             "\\([ \t\n]\\|\\\\\n\\)*"  
                             "{")  
                     nil t)  
                    (progn  
                      (setq mbeg (match-beginning 0)  
                            mend (match-end 0))  
                      (eq (match-end 0) here)))  
               (delete-region mbeg mend)  
               (insert-and-inherit "} else {"))  
              ((and (memq 'brace-elseif-brace c-cleanup-list)  
                    (progn  
                      (goto-char (1- here))  
                      (setq mend (point))  
                      (c-skip-ws-backward)  
                      (setq mbeg (point))  
                      (eq (char-before) ?\)))  
                    (zerop (c-save-buffer-state nil (c-backward-token-2 1 t)))  
                    (eq (char-after) ?\()  
                    (progn  
                      (setq tmp (point))  
                      (re-search-backward  
                       (concat "}"  
                               "\\([ \t\n]\\|\\\\\n\\)*"  
                               "else"  
                               "\\([ \t\n]\\|\\\\\n\\)+"  
                               "if"  
                               "\\([ \t\n]\\|\\\\\n\\)*")  
                       nil t))  
                    (eq (match-end 0) tmp))  
               (delete-region mbeg mend)  
               (goto-char mbeg)  
               (insert ?\ ))))  
           (goto-char (- (point-max) pos))  
           )  
         ;; does a newline go after the brace?  
         (if (memq 'after newlines)  
             (c-newline-and-indent))  
         )))  
797      ;; blink the paren      ;; blink the paren
798      (and (eq last-command-char ?\})      (and (eq last-command-char ?\})
799           (not executing-kbd-macro)           (not executing-kbd-macro)
# Line 659  This function does various newline clean Line 806  This function does various newline clean
806  (defun c-electric-slash (arg)  (defun c-electric-slash (arg)
807    "Insert a slash character.    "Insert a slash character.
808    
809    If the slash is inserted immediately after the comment prefix in a c-style
810    comment, the comment might get closed by removing whitespace and possibly
811    inserting a \"*\".  See the variable `c-cleanup-list'.
812    
813  Indent the line as a comment, if:  Indent the line as a comment, if:
814    
815    1. The slash is second of a `//' line oriented comment introducing    1. The slash is second of a \"//\" line oriented comment introducing
816       token and we are on a comment-only-line, or       token and we are on a comment-only-line, or
817    
818    2. The slash is part of a `*/' token that closes a block oriented    2. The slash is part of a \"*/\" token that closes a block oriented
819       comment.       comment.
820    
821  If a numeric ARG is supplied, point is inside a literal, or  If a numeric ARG is supplied, point is inside a literal, or
822  `c-syntactic-indentation' is nil, indentation is inhibited."  `c-syntactic-indentation' is nil or `c-electric-flag' is nil, indentation
823    is inhibited."
824    (interactive "*P")    (interactive "*P")
825    (let* ((ch (char-before))    (let ((literal (c-save-buffer-state () (c-in-literal)))
826           (literal (c-in-literal))          indentp
827           (indentp (and c-syntactic-indentation          ;; shut this up
828                         (not arg)          (c-echo-syntactic-information-p nil))
829    
830        ;; comment-close-slash cleanup?  This DOESN'T need `c-electric-flag' or
831        ;; `c-syntactic-indentation' set.
832        (when (and (not arg)
833                   (eq literal 'c)
834                   (memq 'comment-close-slash c-cleanup-list)
835                   (eq last-command-char ?/)
836            ; (eq c-block-comment-ender "*/") ; C-style comments ALWAYS end in */
837                   (save-excursion
838                     (back-to-indentation)
839                     (looking-at (concat c-current-comment-prefix "[ \t]*$"))))
840          (end-of-line)
841          (delete-horizontal-space)
842          (or (eq (char-before) ?*) (insert-char ?* 1))) ; Do I need a t (retain sticky properties) here?
843    
844        (setq indentp (and (not arg)
845                           c-syntactic-indentation
846                           c-electric-flag
847                         (eq last-command-char ?/)                         (eq last-command-char ?/)
848                         (or (and (eq ch ?/)                         (eq (char-before) (if literal ?* ?/))))
                                 (not literal))  
                            (and (eq ch ?*)  
                                 literal))  
                        ))  
          ;; shut this up  
          (c-echo-syntactic-information-p nil))  
849      (self-insert-command (prefix-numeric-value arg))      (self-insert-command (prefix-numeric-value arg))
850      (if indentp      (if indentp
851          (indent-according-to-mode))))          (indent-according-to-mode))))
852    
853  (defun c-electric-star (arg)  (defun c-electric-star (arg)
854    "Insert a star character.    "Insert a star character.
855  If the star is the second character of a C style comment introducing  If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, and
856  construct, and we are on a comment-only-line, indent line as comment.  the star is the second character of a C style comment starter on a
857  If a numeric ARG is supplied, point is inside a literal, or  comment-only-line, indent the line as a comment.  If a numeric ARG is
858  `c-syntactic-indentation' is nil, indentation is inhibited."  supplied, point is inside a literal, or `c-syntactic-indentation' is nil,
859    this indentation is inhibited."
860    
861    (interactive "*P")    (interactive "*P")
862    (self-insert-command (prefix-numeric-value arg))    (self-insert-command (prefix-numeric-value arg))
863    ;; if we are in a literal, or if arg is given do not re-indent the    ;; if we are in a literal, or if arg is given do not reindent the
864    ;; current line, unless this star introduces a comment-only line.    ;; current line, unless this star introduces a comment-only line.
865    (if (and c-syntactic-indentation    (if (c-save-buffer-state ()
866             (not arg)          (and c-syntactic-indentation
867             (eq (c-in-literal) 'c)               c-electric-flag
868             (eq (char-before) ?*)               (not arg)
869             (save-excursion               (eq (c-in-literal) 'c)
870               (forward-char -1)               (eq (char-before) ?*)
871               (skip-chars-backward "*")               (save-excursion
872               (if (eq (char-before) ?/)                 (forward-char -1)
873                   (forward-char -1))                 (skip-chars-backward "*")
874               (skip-chars-backward " \t")                 (if (eq (char-before) ?/)
875               (bolp)))                     (forward-char -1))
876                   (skip-chars-backward " \t")
877                   (bolp))))
878        (let (c-echo-syntactic-information-p) ; shut this up        (let (c-echo-syntactic-information-p) ; shut this up
879          (indent-according-to-mode))          (indent-according-to-mode))
880      ))      ))
881    
882  (defun c-electric-semi&comma (arg)  (defun c-electric-semi&comma (arg)
883    "Insert a comma or semicolon.    "Insert a comma or semicolon.
 When the auto-newline feature is turned on, as evidenced by the \"/a\"  
 or \"/ah\" string on the mode line, a newline might be inserted.  See  
 the variable `c-hanging-semi&comma-criteria' for how newline insertion  
 is determined.  
   
 When a semicolon is inserted, the line is re-indented unless a numeric  
 arg is supplied, point is inside a literal, or  
 `c-syntactic-indentation' is nil.  
884    
885  Based on the value of `c-cleanup-list', this function cleans up commas  If `c-electric-flag' is non-nil, point isn't inside a literal and a
886  following brace lists and semicolons following defuns."  numeric ARG hasn't been supplied, the command performs several electric
887    actions:
888    
889    \(a) When the auto-newline feature is turned on (indicated by \"/ln\" on
890    the mode line) a newline might be inserted.  See the variable
891    `c-hanging-semi&comma-criteria' for how newline insertion is determined.
892    
893    \(b) Any auto-newlines are indented.  The original line is also
894    reindented unless `c-syntactic-indentation' is nil.
895    
896    \(c) If auto-newline is turned on, a comma following a brace list or a
897    semicolon following a defun might be cleaned up, depending on the
898    settings of `c-cleanup-list'."
899    (interactive "*P")    (interactive "*P")
900    (let* ((lim (c-most-enclosing-brace (c-parse-state)))    (let* (lim literal c-syntactic-context
          (literal (c-in-literal lim))  
901           (here (point))           (here (point))
902           ;; shut this up           ;; shut this up
903           (c-echo-syntactic-information-p nil))           (c-echo-syntactic-information-p nil))
904      (if (or literal arg)  
905          (self-insert-command (prefix-numeric-value arg))      (c-save-buffer-state ()
906        ;; do some special stuff with the character        (setq lim (c-most-enclosing-brace (c-parse-state))
907        (self-insert-command (prefix-numeric-value arg))              literal (c-in-literal lim)))
908        ;; do all cleanups and newline insertions if c-auto-newline is  
909        ;; turned on      (self-insert-command (prefix-numeric-value arg))
910        (if (or (not c-auto-newline)  
911                (not (looking-at "[ \t]*\\\\?$")))      (if (and c-electric-flag (not literal) (not arg))
912            (if c-syntactic-indentation          ;; do all cleanups and newline insertions if c-auto-newline is on.
913                (indent-according-to-mode))          (if (or (not c-auto-newline)
914          ;; clean ups                  (not (looking-at "[ \t]*\\\\?$")))
915          (let ((pos (- (point-max) (point))))              (if c-syntactic-indentation
916            (if (and (or (and                  (c-indent-line))
917                          (eq last-command-char ?,)            ;; clean ups: list-close-comma or defun-close-semi
918                          (memq 'list-close-comma c-cleanup-list))            (let ((pos (- (point-max) (point))))
919                         (and              (if (c-save-buffer-state ()
920                          (eq last-command-char ?\;)                    (and (or (and
921                          (memq 'defun-close-semi c-cleanup-list)))                              (eq last-command-char ?,)
922                     (progn                              (memq 'list-close-comma c-cleanup-list))
923                       (forward-char -1)                             (and
924                       (c-skip-ws-backward)                              (eq last-command-char ?\;)
925                       (eq (char-before) ?}))                              (memq 'defun-close-semi c-cleanup-list)))
926                     ;; make sure matching open brace isn't in a comment                         (progn
927                     (not (c-in-literal lim)))                           (forward-char -1)
928                (delete-region (point) here))                           (c-skip-ws-backward)
929            (goto-char (- (point-max) pos)))                           (eq (char-before) ?}))
930          ;; re-indent line                         ;; make sure matching open brace isn't in a comment
931          (if c-syntactic-indentation                         (not (c-in-literal lim))))
932              (indent-according-to-mode))                  (delete-region (point) here))
933          ;; check to see if a newline should be added              (goto-char (- (point-max) pos)))
934          (let ((criteria c-hanging-semi&comma-criteria)            ;; reindent line
935                answer add-newline-p)            (when c-syntactic-indentation
936            (while criteria              (setq c-syntactic-context (c-guess-basic-syntax))
937              (setq answer (funcall (car criteria)))              (c-indent-line c-syntactic-context))
938              ;; only nil value means continue checking            ;; check to see if a newline should be added
939              (if (not answer)            (let ((criteria c-hanging-semi&comma-criteria)
940                  (setq criteria (cdr criteria))                  answer add-newline-p)
941                (setq criteria nil)              (while criteria
942                ;; only 'stop specifically says do not add a newline                (setq answer (funcall (car criteria)))
943                (setq add-newline-p (not (eq answer 'stop)))                ;; only nil value means continue checking
944                ))                (if (not answer)
945            (if add-newline-p                    (setq criteria (cdr criteria))
946                (c-newline-and-indent))                  (setq criteria nil)
947            )))))                  ;; only 'stop specifically says do not add a newline
948                    (setq add-newline-p (not (eq answer 'stop)))
949                    ))
950                (if add-newline-p
951                    (c-newline-and-indent))
952                )))))
953    
954  (defun c-electric-colon (arg)  (defun c-electric-colon (arg)
955    "Insert a colon.    "Insert a colon.
956    
957  If the auto-newline feature is turned on, as evidenced by the \"/a\"  If `c-electric-flag' is non-nil, the colon is not inside a literal and a
958  or \"/ah\" string on the mode line, newlines are inserted before and  numeric ARG hasn't been supplied, the command performs several electric
959  after colons based on the value of `c-hanging-colons-alist'.  actions:
960    
961  Also, the line is re-indented unless a numeric ARG is supplied, the  \(a) If the auto-newline feature is turned on (indicated by \"/ln\" on
962  colon is inserted inside a literal, or `c-syntactic-indentation' is  the mode line) newlines are inserted before and after the colon based on
963  nil.  the settings in `c-hanging-colons-alist'.
964    
965    \(b) Any auto-newlines are indented.  The original line is also
966    reindented unless `c-syntactic-indentation' is nil.
967    
968    \(c) If auto-newline is turned on, whitespace between two colons will be
969    \"cleaned up\" leaving a scope operator, if this action is set in
970    `c-cleanup-list'."
971    
 This function cleans up double colon scope operators based on the  
 value of `c-cleanup-list'."  
972    (interactive "*P")    (interactive "*P")
973    (let* ((bod (c-point 'bod))    (let* ((bod (c-point 'bod))
974           (literal (c-in-literal bod))           (literal (c-save-buffer-state () (c-in-literal bod)))
975           newlines is-scope-op           newlines is-scope-op
976           ;; shut this up           ;; shut this up
977           (c-echo-syntactic-information-p nil))           (c-echo-syntactic-information-p nil))
978      (cond      (self-insert-command (prefix-numeric-value arg))
979       ((or literal arg)      ;; Any electric action?
980        (self-insert-command (prefix-numeric-value arg)))      (if (and c-electric-flag (not literal) (not arg))
981       ((not (looking-at "[ \t]*\\\\?$"))          ;; Unless we're at EOL, only re-indentation happens.
982        (self-insert-command (prefix-numeric-value arg))          (if (not (looking-at "[ \t]*\\\\?$"))
983        (if c-syntactic-indentation              (if c-syntactic-indentation
984            (indent-according-to-mode)))                  (indent-according-to-mode))
985       (t  
986        ;; insert the colon, then do any specified cleanups            ;; scope-operator clean-up?
987        (self-insert-command (prefix-numeric-value arg))            (let ((pos (- (point-max) (point)))
988        (let ((pos (- (point-max) (point)))                  (here (point)))
989              (here (point)))              (if (c-save-buffer-state () ; Why do we need this? [ACM, 2003-03-12]
990          (if (and c-auto-newline                    (and c-auto-newline
991                   (memq 'scope-operator c-cleanup-list)                         (memq 'scope-operator c-cleanup-list)
992                   (eq (char-before) ?:)                         (eq (char-before) ?:)
993                   (progn                         (progn
994                     (forward-char -1)                           (forward-char -1)
995                     (c-skip-ws-backward)                           (c-skip-ws-backward)
996                     (eq (char-before) ?:))                           (eq (char-before) ?:))
997                   (not (c-in-literal))                         (not (c-in-literal))
998                   (not (eq (char-after (- (point) 2)) ?:)))                         (not (eq (char-after (- (point) 2)) ?:))))
999              (progn                  (progn
1000                (delete-region (point) (1- here))                    (delete-region (point) (1- here))
1001                (setq is-scope-op t)))                    (setq is-scope-op t)))
1002          (goto-char (- (point-max) pos)))              (goto-char (- (point-max) pos)))
1003        ;; indent the current line if it's done syntactically.  
1004        (if c-syntactic-indentation            ;; indent the current line if it's done syntactically.
1005            ;; Cannot use the same syntax analysis as we find below,            (if c-syntactic-indentation
1006            ;; since that's made with c-syntactic-indentation-in-macros                ;; Cannot use the same syntax analysis as we find below,
1007            ;; always set to t.                ;; since that's made with c-syntactic-indentation-in-macros
1008            (indent-according-to-mode))                ;; always set to t.
1009        (c-save-buffer-state                (indent-according-to-mode))
1010              ((c-syntactic-indentation-in-macros t)  
1011               (c-auto-newline-analysis t)            ;; Calculate where, if anywhere, we want newlines.
1012               ;; Turn on syntactic macro analysis to help with auto newlines            (c-save-buffer-state
1013               ;; only.                ((c-syntactic-indentation-in-macros t)
1014               (syntax (c-guess-basic-syntax))                 (c-auto-newline-analysis t)
1015               (elem syntax))                 ;; Turn on syntactic macro analysis to help with auto newlines
1016          ;; Translate substatement-label to label for this operation.                 ;; only.
1017          (while elem                 (syntax (c-guess-basic-syntax))
1018            (if (eq (car (car elem)) 'substatement-label)                 (elem syntax))
1019                (setcar (car elem) 'label))              ;; Translate substatement-label to label for this operation.
1020            (setq elem (cdr elem)))              (while elem
1021          ;; some language elements can only be determined by checking                (if (eq (car (car elem)) 'substatement-label)
1022          ;; the following line.  Lets first look for ones that can be                    (setcar (car elem) 'label))
1023          ;; found when looking on the line with the colon                (setq elem (cdr elem)))
1024          (setq newlines              ;; some language elements can only be determined by checking
1025                (and c-auto-newline              ;; the following line.  Lets first look for ones that can be
1026                     (or (c-lookup-lists '(case-label label access-label)              ;; found when looking on the line with the colon
1027                                         syntax c-hanging-colons-alist)              (setq newlines
1028                         (c-lookup-lists '(member-init-intro inher-intro)                    (and c-auto-newline
1029                                         (progn                         (or (c-lookup-lists '(case-label label access-label)
1030                                           (insert ?\n)                                             syntax c-hanging-colons-alist)
1031                                           (unwind-protect                             (c-lookup-lists '(member-init-intro inher-intro)
1032                                               (c-guess-basic-syntax)                                             (progn
1033                                             (delete-char -1)))                                               (insert ?\n)
1034                                         c-hanging-colons-alist)))))                                               (unwind-protect
1035        ;; does a newline go before the colon?  Watch out for already                                                   (c-guess-basic-syntax)
1036        ;; non-hung colons.  However, we don't unhang them because that                                                 (delete-char -1)))
1037        ;; would be a cleanup (and anti-social).                                             c-hanging-colons-alist)))))
1038        (if (and (memq 'before newlines)            ;; does a newline go before the colon?  Watch out for already
1039                 (not is-scope-op)            ;; non-hung colons.  However, we don't unhang them because that
1040                 (save-excursion            ;; would be a cleanup (and anti-social).
1041                   (skip-chars-backward ": \t")            (if (and (memq 'before newlines)
1042                   (not (bolp))))                     (not is-scope-op)
1043            (let ((pos (- (point-max) (point))))                     (save-excursion
1044              (forward-char -1)                       (skip-chars-backward ": \t")
1045              (c-newline-and-indent)                       (not (bolp))))
1046              (goto-char (- (point-max) pos))))                (let ((pos (- (point-max) (point))))
1047        ;; does a newline go after the colon?                  (forward-char -1)
1048        (if (and (memq 'after (cdr-safe newlines))                  (c-newline-and-indent)
1049                 (not is-scope-op))                  (goto-char (- (point-max) pos))))
1050            (c-newline-and-indent))            ;; does a newline go after the colon?
1051        ))))            (if (and (memq 'after (cdr-safe newlines))
1052                       (not is-scope-op))
1053                  (c-newline-and-indent))
1054              ))))
1055    
1056  (defun c-electric-lt-gt (arg)  (defun c-electric-lt-gt (arg)
1057    "Insert a less-than, or greater-than character.    "Insert a \"<\" or \">\" character.
1058  The line will be re-indented if the character inserted is the second  If the current language uses angle bracket parens (e.g. template
1059  of a C++ style stream operator and the buffer is in C++ mode.  arguments in C++), try to find out if the inserted character is a
1060  Exceptions are when a numeric argument is supplied, point is inside a  paren and give it paren syntax if appropriate.
1061  literal, or `c-syntactic-indentation' is nil, in which case the line  
1062  will not be re-indented."  If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, the
1063    line will be reindented if the inserted character is a paren or if it
1064    finishes a C++ style stream operator in C++ mode.  Exceptions are when a
1065    numeric argument is supplied, or the point is inside a literal."
1066    
1067    (interactive "*P")    (interactive "*P")
1068    (let ((indentp (and c-syntactic-indentation    (let ((c-echo-syntactic-information-p nil)
1069                        (not arg)          final-pos close-paren-inserted)
1070                        (eq (char-before) last-command-char)  
                       (not (c-in-literal))))  
         ;; shut this up  
         (c-echo-syntactic-information-p nil))  
1071      (self-insert-command (prefix-numeric-value arg))      (self-insert-command (prefix-numeric-value arg))
1072      (if indentp      (setq final-pos (point))
1073          (indent-according-to-mode))))  
1074        (c-save-buffer-state (c-parse-and-markup-<>-arglists
1075                              c-restricted-<>-arglists
1076                              <-pos)
1077    
1078          (when c-recognize-<>-arglists
1079            (if (eq last-command-char ?<)
1080                (when (and (progn
1081                             (backward-char)
1082                             (= (point)
1083                                (progn
1084                                  (c-beginning-of-current-token)
1085                                  (point))))
1086                           (progn
1087                             (c-backward-token-2)
1088                             (looking-at c-opt-<>-sexp-key)))
1089                  (c-mark-<-as-paren (1- final-pos)))
1090    
1091              ;; It's a ">".  Check if there's an earlier "<" which either has
1092              ;; open paren syntax already or that can be recognized as an arglist
1093              ;; together with this ">".  Note that this won't work in cases like
1094              ;; "template <x, a < b, y>" but they ought to be rare.
1095    
1096              (save-restriction
1097                ;; Narrow to avoid that `c-forward-<>-arglist' below searches past
1098                ;; our position.
1099                (narrow-to-region (point-min) final-pos)
1100    
1101                (while (and
1102                        (progn
1103                          (goto-char final-pos)
1104                          (c-syntactic-skip-backward "^<;}" nil t)
1105                          (eq (char-before) ?<))
1106                        (progn
1107                          (backward-char)
1108                          ;; If the "<" already got open paren syntax we know we
1109                          ;; have the matching closer.  Handle it and exit the
1110                          ;; loop.
1111                          (if (looking-at "\\s\(")
1112                              (progn
1113                                (c-mark->-as-paren (1- final-pos))
1114                                (setq close-paren-inserted t)
1115                                nil)
1116                            t))
1117    
1118                        (progn
1119                          (setq <-pos (point))
1120                          (c-backward-syntactic-ws)
1121                          (c-simple-skip-symbol-backward))
1122                        (or (looking-at c-opt-<>-sexp-key)
1123                            (not (looking-at c-keywords-regexp)))
1124    
1125                        (let ((c-parse-and-markup-<>-arglists t)
1126                              c-restricted-<>-arglists
1127                              (containing-sexp
1128                               (c-most-enclosing-brace (c-parse-state))))
1129                          (when (and containing-sexp
1130                                     (progn (goto-char containing-sexp)
1131                                            (eq (char-after) ?\())
1132                                     (not (eq (get-text-property (point) 'c-type)
1133                                              'c-decl-arg-start)))
1134                            (setq c-restricted-<>-arglists t))
1135                          (goto-char <-pos)
1136                          (c-forward-<>-arglist nil))
1137    
1138                        ;; Loop here if the "<" we found above belongs to a nested
1139                        ;; angle bracket sexp.  When we start over we'll find the
1140                        ;; previous or surrounding sexp.
1141                        (if (< (point) final-pos)
1142                            t
1143                          (setq close-paren-inserted t)
1144                          nil)))))))
1145        (goto-char final-pos)
1146    
1147        ;; Indent the line if appropriate.
1148        (when (and c-electric-flag c-syntactic-indentation)
1149          (backward-char)
1150          (when (prog1 (or (looking-at "\\s\(\\|\\s\)")
1151                           (and (c-major-mode-is 'c++-mode)
1152                                (progn
1153                                  (c-beginning-of-current-token)
1154                                  (looking-at "<<\\|>>"))
1155                                (= (match-end 0) final-pos)))
1156                  (goto-char final-pos))
1157            (indent-according-to-mode)))
1158    
1159        (when (and close-paren-inserted
1160                   (not executing-kbd-macro)
1161                   blink-paren-function)
1162          ;; Note: Most paren blink functions, such as the standard
1163          ;; `blink-matching-open', currently doesn't handle paren chars
1164          ;; marked with text properties very well.  Maybe we should avoid
1165          ;; this call for the time being?
1166          (funcall blink-paren-function))))
1167    
1168  (defun c-electric-paren (arg)  (defun c-electric-paren (arg)
1169    "Insert a parenthesis.    "Insert a parenthesis.
1170    
1171  Some newline cleanups are done if appropriate; see the variable  If `c-syntactic-indentation' and `c-electric-flag' are both non-nil, the
1172  `c-cleanup-list'.  line is reindented unless a numeric ARG is supplied, or the parenthesis
1173    is inserted inside a literal.
1174    
1175    Whitespace between a function name and the parenthesis may get added or
1176    removed; see the variable `c-cleanup-list'.
1177    
1178  Also, the line is re-indented unless a numeric ARG is supplied, the  Also, if `c-electric-flag' and `c-auto-newline' are both non-nil, some
1179  parenthesis is inserted inside a literal, or `c-syntactic-indentation'  newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
 is nil."  
1180    (interactive "*P")    (interactive "*P")
1181    (let ((literal (c-in-literal (c-point 'bod)))    (let ((literal (c-save-buffer-state () (c-in-literal)))
1182          ;; shut this up          ;; shut this up
1183          (c-echo-syntactic-information-p nil))          (c-echo-syntactic-information-p nil))
1184      (if (or arg literal)      (self-insert-command (prefix-numeric-value arg))
1185          (self-insert-command (prefix-numeric-value arg))  
1186        ;; do some special stuff with the character      (if (and (not arg) (not literal))
1187        (let* (;; We want to inhibit blinking the paren since this will          (let* ( ;; We want to inhibit blinking the paren since this will
1188               ;; be most disruptive.  We'll blink it ourselves                 ;; be most disruptive.  We'll blink it ourselves
1189               ;; afterwards.                 ;; afterwards.
1190               (old-blink-paren blink-paren-function)                 (old-blink-paren blink-paren-function)
1191               blink-paren-function                 blink-paren-function)
1192               (noblink (eq last-input-event ?\()))            (if (and c-syntactic-indentation c-electric-flag)
1193          (self-insert-command (prefix-numeric-value arg))                (indent-according-to-mode))
1194          (if c-syntactic-indentation  
1195              (indent-according-to-mode))            ;; If we're at EOL, check for new-line clean-ups.
1196          (when (looking-at "[ \t]*\\\\?$")            (when (and c-electric-flag c-auto-newline
1197            (when c-auto-newline                       (looking-at "[ \t]*\\\\?$"))
1198              ;; Do all appropriate clean ups  
1199              (let ((here (point))              ;; clean up brace-elseif-brace
1200                    (pos (- (point-max) (point)))              (when
1201                    mbeg mend)                  (and (memq 'brace-elseif-brace c-cleanup-list)
1202                ;; clean up brace-elseif-brace                       (eq last-command-char ?\()
1203                (if (and (memq 'brace-elseif-brace c-cleanup-list)                       (re-search-backward
1204                         (eq last-command-char ?\()                        (concat "}"
1205                         (re-search-backward                                "\\([ \t\n]\\|\\\\\n\\)*"
1206                          (concat "}"                                "else"
1207                                  "\\([ \t\n]\\|\\\\\n\\)*"                                "\\([ \t\n]\\|\\\\\n\\)+"
1208                                  "else"                                "if"
1209                                  "\\([ \t\n]\\|\\\\\n\\)+"                                "\\([ \t\n]\\|\\\\\n\\)*"
1210                                  "if"                                "("
1211                                  "\\([ \t\n]\\|\\\\\n\\)*"                                "\\=")
1212                                  "(")                        nil t)
1213                          nil t)                       (not  (c-save-buffer-state () (c-in-literal))))
1214                         (save-excursion                (delete-region (match-beginning 0) (match-end 0))
1215                           (setq mbeg (match-beginning 0)                (insert-and-inherit "} else if ("))
1216                                 mend (match-end 0))  
1217                           (= mend here))              ;; clean up brace-catch-brace
1218                         (not (c-in-literal)))              (when
1219                    (progn                  (and (memq 'brace-catch-brace c-cleanup-list)
1220                      (delete-region mbeg mend)                       (eq last-command-char ?\()
1221                      (insert-and-inherit "} else if ("))                       (re-search-backward
1222                  ;; clean up brace-catch-brace                        (concat "}"
1223                  (goto-char here)                                "\\([ \t\n]\\|\\\\\n\\)*"
1224                  (if (and (memq 'brace-catch-brace c-cleanup-list)                                "catch"
1225                           (eq last-command-char ?\()                                "\\([ \t\n]\\|\\\\\n\\)*"
1226                           (re-search-backward                                "("
1227                            (concat "}"                                "\\=")
1228                                    "\\([ \t\n]\\|\\\\\n\\)*"                        nil t)
1229                                    "catch"                       (not  (c-save-buffer-state () (c-in-literal))))
1230                                    "\\([ \t\n]\\|\\\\\n\\)*"                (delete-region (match-beginning 0) (match-end 0))
1231                                    "(")                (insert-and-inherit "} catch (")))
1232                            nil t)  
1233                           (save-excursion            ;; Check for clean-ups at function calls.  These two DON'T need
1234                             (setq mbeg (match-beginning 0)            ;; `c-electric-flag' or `c-syntactic-indentation' set.
1235                                   mend (match-end 0))            ;; Point is currently just after the inserted paren.
1236                             (= mend here))            (let (beg (end (1- (point))))
1237                           (not (c-in-literal)))              (cond
1238                      (progn  
1239                        (delete-region mbeg mend)               ;; space-before-funcall clean-up?
1240                        (insert-and-inherit "} catch ("))))               ((and (memq 'space-before-funcall c-cleanup-list)
1241                (goto-char (- (point-max) pos))                     (eq last-command-char ?\()
1242                )))                     (save-excursion
1243          (let (beg (end (1- (point))))                       (backward-char)
1244            (cond ((and (memq 'space-before-funcall c-cleanup-list)                       (skip-chars-backward " \t")
1245                        (eq last-command-char ?\()                       (setq beg (point))
1246                        (save-excursion                       (c-save-buffer-state () (c-on-identifier))))
1247                          (backward-char)                (save-excursion
1248                          (skip-chars-backward " \t")                  (delete-region beg end)
1249                          (setq beg (point))                  (goto-char beg)
1250                          (c-on-identifier)))                  (insert ?\ )))
1251                   (save-excursion  
1252                     (delete-region beg end)               ;; compact-empty-funcall clean-up?
1253                     (goto-char beg)                    ((c-save-buffer-state ()
1254                     (insert ?\ )))                       (and (memq 'compact-empty-funcall c-cleanup-list)
1255                  ((and (memq 'compact-empty-funcall c-cleanup-list)                            (eq last-command-char ?\))
1256                        (eq last-command-char ?\))                            (save-excursion
1257                        (save-excursion                              (c-safe (backward-char 2))
1258                          (c-safe (backward-char 2))                              (when (looking-at "()")
1259                          (when (looking-at "()")                                (setq end (point))
1260                            (setq end (point))                                (skip-chars-backward " \t")
1261                            (skip-chars-backward " \t")                                (setq beg (point))
1262                            (setq beg (point))                                (c-on-identifier)))))
1263                            (c-on-identifier))))                     (delete-region beg end))))
1264                   (delete-region beg end))))            (and (eq last-input-event ?\))
1265          (and (not executing-kbd-macro)                 (not executing-kbd-macro)
1266               old-blink-paren                 old-blink-paren
1267               (not noblink)                 (funcall old-blink-paren))))))
              (funcall old-blink-paren))))))  
1268    
1269  (defun c-electric-continued-statement ()  (defun c-electric-continued-statement ()
1270    "Reindent the current line if appropriate.    "Reindent the current line if appropriate.
# Line 995  continues an earlier statement is typed, Line 1275  continues an earlier statement is typed,
1275    
1276  The line is reindented if there is nothing but whitespace before the  The line is reindented if there is nothing but whitespace before the
1277  keyword on the line, the keyword is not inserted inside a literal, and  keyword on the line, the keyword is not inserted inside a literal, and
1278  `c-syntactic-indentation' is non-nil."  `c-electric-flag' and `c-syntactic-indentation' are both non-nil."
1279    (let (;; shut this up    (let (;; shut this up
1280          (c-echo-syntactic-information-p nil))          (c-echo-syntactic-information-p nil))
1281      (when (and c-syntactic-indentation      (when (c-save-buffer-state ()
1282                 (not (eq last-command-char ?_))              (and c-electric-flag
1283                 (= (save-excursion                   c-syntactic-indentation
1284                      (skip-syntax-backward "w")                   (not (eq last-command-char ?_))
1285                      (point))                   (= (save-excursion
1286                    (c-point 'boi))                        (skip-syntax-backward "w")
1287                 (not (c-in-literal (c-point 'bod))))                        (point))
1288                        (c-point 'boi))
1289                     (not (c-in-literal (c-point 'bod)))))
1290        ;; Have to temporarily insert a space so that        ;; Have to temporarily insert a space so that
1291        ;; c-guess-basic-syntax recognizes the keyword.  Follow the        ;; c-guess-basic-syntax recognizes the keyword.  Follow the
1292        ;; space with a nonspace to avoid messing up any whitespace        ;; space with a nonspace to avoid messing up any whitespace
# Line 1016  keyword on the line, the keyword is not Line 1298  keyword on the line, the keyword is not
1298          (delete-char -2)))))          (delete-char -2)))))
1299    
1300    
 ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus  
 ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com  
1301  (defun c-forward-into-nomenclature (&optional arg)  (defun c-forward-into-nomenclature (&optional arg)
1302    "Move forward to end of a nomenclature section or word.    "Compatibility alias for `c-forward-subword'."
 With arg, do it arg times."  
1303    (interactive "p")    (interactive "p")
1304    (let ((case-fold-search nil))    (require 'cc-subword)
1305      (if (> arg 0)    (c-forward-subword arg))
1306          (re-search-forward  (make-obsolete 'c-forward-into-nomenclature 'c-forward-subword)
          (cc-eval-when-compile  
            (concat "\\W*\\([" c-upper "]*[" c-lower c-digit "]*\\)"))  
          (point-max) t arg)  
       (while (and (< arg 0)  
                   (re-search-backward  
                    (cc-eval-when-compile  
                      (concat  
                       "\\(\\(\\W\\|[" c-lower c-digit "]\\)[" c-upper "]+"  
                       "\\|\\W\\w+\\)"))  
                    (point-min) 0))  
         (forward-char 1)  
         (setq arg (1+ arg)))))  
   (c-keep-region-active))  
1307    
1308  (defun c-backward-into-nomenclature (&optional arg)  (defun c-backward-into-nomenclature (&optional arg)
1309    "Move backward to beginning of a nomenclature section or word.    "Compatibility alias for `c-backward-subword'."
 With optional ARG, move that many times.  If ARG is negative, move  
 forward."  
1310    (interactive "p")    (interactive "p")
1311    (c-forward-into-nomenclature (- arg))    (require 'cc-subword)
1312    (c-keep-region-active))    (c-backward-subword arg))
1313    (make-obsolete 'c-backward-into-nomenclature 'c-backward-subword)
1314    
1315  (defun c-scope-operator ()  (defun c-scope-operator ()
1316    "Insert a double colon scope operator at point.    "Insert a double colon scope operator at point.
# Line 1246  the open-parenthesis that starts a defun Line 1511  the open-parenthesis that starts a defun
1511    ;; following one is chosen instead (if there is any).  The end    ;; following one is chosen instead (if there is any).  The end
1512    ;; position is at the next line, providing there is one before the    ;; position is at the next line, providing there is one before the
1513    ;; declaration.    ;; declaration.
1514      ;;
1515      ;; This function might do hidden buffer changes.
1516    (save-excursion    (save-excursion
1517    
1518      ;; Note: Some code duplication in `c-beginning-of-defun' and      ;; Note: Some code duplication in `c-beginning-of-defun' and
# Line 1369  function does not require the declaratio Line 1636  function does not require the declaratio
1636        (push-mark (cdr decl-limits) nil t))))        (push-mark (cdr decl-limits) nil t))))
1637    
1638    
1639    (defun c-in-comment-line-prefix-p ()
1640      ;; Point is within a comment.  Is it also within a comment-prefix?
1641      ;; Space at BOL which precedes a comment-prefix counts as part of it.
1642      ;;
1643      ;; This function might do hidden buffer changes.
1644      (let ((here (point)))
1645        (save-excursion
1646          (beginning-of-line)
1647          (skip-chars-forward " \t")
1648          (and (looking-at c-current-comment-prefix)
1649               (/= (match-beginning 0) (match-end 0))
1650               (< here (match-end 0))))))
1651    
1652    (defun c-narrow-to-comment-innards (range)
1653      ;; Narrow to the "inside" of the comment (block) defined by range, as
1654      ;; follows:
1655      ;;
1656      ;; A c-style block comment has its opening "/*" and its closing "*/" (if
1657      ;; present) removed.  A c++-style line comment retains its opening "//" but
1658      ;; has any final NL removed.  If POINT is currently outwith these innards,
1659      ;; move it to the appropriate boundary.
1660      ;;
1661      ;; This narrowing simplifies the sentence movement functions, since it
1662      ;; eliminates awkward things at the boundaries of the comment (block).
1663      ;;
1664      ;; This function might do hidden buffer changes.
1665      (let* ((lit-type (c-literal-type range))
1666             (beg (if (eq lit-type 'c) (+ (car range) 2) (car range)))
1667             (end (if (eq lit-type 'c)
1668                      (if (and (eq (char-before (cdr range)) ?/)
1669                               (eq (char-before (1- (cdr range))) ?*))
1670                          (- (cdr range) 2)
1671                        (point-max))
1672                    (if (eq (cdr range) (point-max))
1673                        (point-max)
1674                      (- (cdr range) 1)))))
1675        (if (> (point) end)
1676            (goto-char end))                ; This would be done automatically by ...
1677        (if (< (point) beg)
1678            (goto-char beg))        ;  ... narrow-to-region but is not documented.
1679        (narrow-to-region beg end)))
1680    
1681    (defun c-beginning-of-sentence-in-comment (range)
1682      ;; Move backwards to the "beginning of a sentence" within the comment
1683      ;; defined by RANGE, a cons of its starting and ending positions.  If we
1684      ;; find a BOS, return NIL.  Otherwise, move point to just before the start
1685      ;; of the comment and return T.
1686      ;;
1687      ;; The BOS is either text which follows a regexp match of sentence-end,
1688      ;; or text which is a beginning of "paragraph".  
1689      ;; Comment-prefixes are treated like WS when calculating BOSes or BOPs.
1690      ;;
1691      ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1692      ;; It is not a general function, but is intended only for calling from
1693      ;; c-move-over-sentence.  Not all preconditions have been explicitly stated.
1694      ;;
1695      ;; This function might do hidden buffer changes.
1696      (save-match-data
1697        (let ((start-point (point)))
1698          (save-restriction
1699            (c-narrow-to-comment-innards range) ; This may move point back.
1700            (let* ((here (point))
1701                   last
1702                   (here-filler        ; matches WS and comment-prefices at point.
1703                    (concat "\\=\\(^[ \t]*\\(" c-current-comment-prefix "\\)"
1704                            "\\|[ \t\n\r\f]\\)*"))
1705                   (prefix-at-bol-here ; matches WS and prefix at BOL, just before point
1706                    (concat "^[ \t]*\\(" c-current-comment-prefix "\\)[ \t\n\r\f]*\\="))
1707                   ;; First, find the previous paragraph start, if any.
1708                   (par-beg ; point where non-WS/non-prefix text of paragraph starts.
1709                    (save-excursion
1710                      (forward-paragraph -1) ; uses cc-mode values of
1711                                            ; paragraph-\(start\|separate\)
1712                      (if (> (re-search-forward here-filler nil t) here)
1713                          (goto-char here))
1714                      (when (>= (point) here)
1715                        (forward-paragraph -2)
1716                        (if (> (re-search-forward here-filler nil t) here)
1717                            (goto-char here)))
1718                      (point))))
1719    
1720              ;; Now seek successively earlier sentence ends between PAR-BEG and
1721              ;; HERE, until the "start of sentence" following it is earlier than
1722              ;; HERE, or we hit PAR-BEG.  Beware of comment prefices!
1723              (while (and (re-search-backward (c-sentence-end) par-beg 'limit)
1724                          (setq last (point))
1725                          (goto-char (match-end 0)) ; tentative beginning of sentence
1726                          (or (>= (point) here)
1727                              (and (not (bolp)) ; Found a non-blank comment-prefix?
1728                                   (save-excursion
1729                                     (if (re-search-backward prefix-at-bol-here nil t)
1730                                         (/= (match-beginning 1) (match-end 1)))))
1731                              (progn        ; Skip the crud to find a real b-o-s.
1732                                (if (c-in-comment-line-prefix-p)
1733                                    (beginning-of-line))
1734                                (re-search-forward here-filler) ; always succeeds.
1735                                (>= (point) here))))
1736                (goto-char last))
1737              (re-search-forward here-filler)))
1738    
1739          (if (< (point) start-point)
1740              nil
1741            (goto-char (car range))
1742            t))))
1743    
1744    (defun c-end-of-sentence-in-comment (range)
1745      ;; Move forward to the "end of a sentence" within the comment defined by
1746      ;; RANGE, a cons of its starting and ending positions (enclosing the opening
1747      ;; comment delimiter and the terminating */ or newline).  If we find an EOS,
1748      ;; return NIL.  Otherwise, move point to just after the end of the comment
1749      ;; and return T.
1750      ;;
1751      ;; The EOS is just after the non-WS part of the next match of the regexp
1752      ;; sentence-end.  Typically, this is just after one of [.!?].  If there is
1753      ;; no sentence-end match following point, any WS before the end of the
1754      ;; comment will count as EOS, providing we're not already in it.
1755      ;;
1756      ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1757      ;; It is not a general function, but is intended only for calling from
1758      ;; c-move-over-sentence.
1759      ;;
1760      ;; This function might do hidden buffer changes.
1761      (save-match-data
1762        (let ((start-point (point))
1763              ;; (lit-type (c-literal-type range))  ; Commented out, 2005/11/23, ACM
1764              )
1765          (save-restriction
1766            (c-narrow-to-comment-innards range) ; This might move point forwards.
1767            (let* ((here (point))
1768                   (par-end ; EOL position of last text in current/next paragraph.
1769                    (save-excursion
1770                      ;; The cc-mode values of paragraph-\(start\|separate\), set
1771                      ;; in c-setup-paragraph-variables, are used in the
1772                      ;; following.
1773                      (forward-paragraph 1)
1774                      (if (eq (preceding-char) ?\n) (forward-char -1))
1775                      (when (<= (point) here) ; can happen, e.g., when HERE is at EOL.
1776                        (goto-char here)
1777                        (forward-paragraph 2)
1778                        (if (eq (preceding-char) ?\n) (forward-char -1)))
1779                      (point)))
1780    
1781                   last
1782                   (prefix-at-bol-here
1783                    (concat "^[ \t]*\\(" c-current-comment-prefix "\\)\\=")))
1784              ;; Go forward one "comment-prefix which looks like sentence-end"
1785              ;; each time round the following:
1786              (while (and (re-search-forward (c-sentence-end) par-end 'limit)
1787                          (progn
1788                            (setq last (point))
1789                            (skip-chars-backward " \t\n")
1790                            (or (and (not (bolp))
1791                                     (re-search-backward prefix-at-bol-here nil t)
1792                                     (/= (match-beginning 1) (match-end 1)))
1793                                (<= (point) here))))
1794                (goto-char last))
1795    
1796              ;; Take special action if we're up against the end of a comment (of
1797              ;; either sort): Leave point just after the last non-ws text.
1798              (if (eq (point) (point-max))
1799                  (while (or (/= (skip-chars-backward " \t\n") 0)
1800                             (and (re-search-backward prefix-at-bol-here nil t)
1801                                  (/= (match-beginning 1) (match-end 1))))))))
1802    
1803          (if (> (point) start-point)
1804                  nil
1805                (goto-char (cdr range))
1806                t))))
1807    
1808    (defun c-beginning-of-sentence-in-string (range)
1809      ;; Move backwards to the "beginning of a sentence" within the string defined
1810      ;; by RANGE, a cons of its starting and ending positions (enclosing the
1811      ;; string quotes).  If we find a BOS, return NIL.  Otherwise, move point to
1812      ;; just before the start of the string and return T.
1813      ;;
1814      ;; The BOS is either the text which follows a regexp match of sentence-end
1815      ;; or text which is a beginning of "paragraph".  For the purposes of
1816      ;; determining paragraph boundaries, escaped newlines are treated as
1817      ;; ordinary newlines.
1818      ;;
1819      ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1820      ;; It is not a general function, but is intended only for calling from
1821      ;; c-move-over-sentence.
1822      ;;
1823      ;; This function might do hidden buffer changes.
1824      (save-match-data
1825        (let* ((here (point)) last
1826               (end (1- (cdr range)))
1827               (here-filler            ; matches WS and escaped newlines at point.
1828                "\\=\\([ \t\n\r\f]\\|\\\\[\n\r]\\)*")
1829               ;; Enhance paragraph-start and paragraph-separate also to recognise
1830               ;; blank lines terminated by escaped EOLs.  IT MAY WELL BE that
1831               ;; these values should be customizable user options, or something.
1832               (paragraph-start c-string-par-start)
1833               (paragraph-separate c-string-par-separate)
1834    
1835               (par-beg            ; beginning of current (or previous) paragraph.
1836                (save-excursion
1837                  (save-restriction
1838                    (narrow-to-region (1+ (car range)) end)
1839                    (forward-paragraph -1)  ; uses above values of
1840                                            ; paragraph-\(start\|separate\)
1841                    (if (> (re-search-forward here-filler nil t) here)
1842                        (goto-char here))
1843                    (when (>= (point) here)
1844                      (forward-paragraph -2)
1845                      (if (> (re-search-forward here-filler nil t) here)
1846                          (goto-char here)))
1847                    (point)))))
1848          ;; Now see if we can find a sentence end after PAR-BEG.
1849          (while (and (re-search-backward c-sentence-end-with-esc-eol par-beg 'limit)
1850                      (setq last (point))
1851                      (goto-char (match-end 0))
1852                      (or (> (point) end)
1853                          (progn
1854                            (re-search-forward
1855                             here-filler end t) ; always succeeds.  Use end rather
1856                                            ; than here, in case point starts
1857                                            ; beyond the closing quote.
1858                            (>= (point) here))))
1859            (goto-char last))
1860          (re-search-forward here-filler here t)
1861          (if (< (point) here)
1862              nil
1863            (goto-char (car range))
1864            t))))
1865    
1866    (defun c-end-of-sentence-in-string (range)
1867      ;; Move forward to the "end of a sentence" within the string defined by
1868      ;; RANGE, a cons of its starting and ending positions.  If we find an EOS,
1869      ;; return NIL.  Otherwise, move point to just after the end of the string
1870      ;; and return T.
1871      ;;
1872      ;; The EOS is just after the non-WS part of the next match of the regexp
1873      ;; sentence-end.  Typically, this is just after one of [.!?].  If there is
1874      ;; no sentence-end match following point, any WS before the end of the
1875      ;; string will count as EOS, providing we're not already in it.
1876      ;;
1877      ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1878      ;; It is not a general function, but is intended only for calling from
1879      ;; c-move-over-sentence.
1880      ;;
1881      ;; This function might do hidden buffer changes.
1882      (save-match-data
1883        (let* ((here (point))
1884               last
1885               ;; Enhance paragraph-start and paragraph-separate to recognise
1886               ;; blank lines terminated by escaped EOLs.
1887               (paragraph-start c-string-par-start)
1888               (paragraph-separate c-string-par-separate)
1889    
1890               (par-end     ; EOL position of last text in current/next paragraph.
1891                (save-excursion
1892                  (save-restriction
1893                    (narrow-to-region (car range) (1- (cdr range)))
1894                    ;; The above values of paragraph-\(start\|separate\) are used
1895                    ;; in the following.
1896                    (forward-paragraph 1)
1897                    (setq last (point))
1898                    ;; (re-search-backward filler-here nil t) would find an empty
1899                    ;; string.  Therefore we simulate it by the following:
1900                    (while (or (/= (skip-chars-backward " \t\n\r\f") 0)
1901                               (re-search-backward "\\\\\\($\\)\\=" nil t)))
1902                    (unless (> (point) here)
1903                      (goto-char last)
1904                      (forward-paragraph 1)
1905                      (while (or (/= (skip-chars-backward " \t\n\r\f") 0)
1906                                 (re-search-backward "\\\\\\($\\)\\=" nil t))))
1907                    (point)))))
1908          ;; Try to go forward a sentence.
1909          (when (re-search-forward c-sentence-end-with-esc-eol par-end 'limit)
1910            (setq last (point))
1911            (while (or (/= (skip-chars-backward " \t\n") 0)
1912                       (re-search-backward "\\\\\\($\\)\\=" nil t))))
1913          ;; Did we move a sentence, or did we hit the end of the string?
1914          (if (> (point) here)
1915              nil
1916            (goto-char (cdr range))
1917            t))))
1918    
1919    (defun c-ascertain-preceding-literal ()
1920      ;; Point is not in a literal (i.e. comment or string (include AWK regexp)).
1921      ;; If a literal is the next thing (aside from whitespace) to be found before
1922      ;; point, return a cons of its start.end positions (enclosing the
1923      ;; delimiters).  Otherwise return NIL.
1924      ;;
1925      ;; This function might do hidden buffer changes.
1926      (save-excursion
1927        (c-collect-line-comments
1928         (let ((here (point))
1929               pos)
1930           (if (c-backward-single-comment)
1931               (cons (point) (progn (c-forward-single-comment) (point)))
1932             (save-restriction
1933               ;; to prevent `looking-at' seeing a " at point.
1934               (narrow-to-region (point-min) here)
1935               (when
1936                   (or
1937                    ;; An EOL can act as an "open string" terminator in AWK.
1938                    (looking-at c-ws*-string-limit-regexp)
1939                    (and (not (bobp))
1940                         (progn (backward-char)
1941                                (looking-at c-string-limit-regexp))))
1942                 (goto-char (match-end 0))  ; just after the string terminator.
1943                 (setq pos (point))
1944                 (c-safe (c-backward-sexp 1) ; move back over the string.
1945                         (cons (point) pos)))))))))
1946    
1947    (defun c-ascertain-following-literal ()
1948      ;; Point is not in a literal (i.e. comment or string (include AWK regexp)).
1949      ;; If a literal is the next thing (aside from whitespace) following point,
1950      ;; return a cons of its start.end positions (enclosing the delimiters).
1951      ;; Otherwise return NIL.
1952      ;;
1953      ;; This function might do hidden buffer changes.
1954      (save-excursion
1955        (c-collect-line-comments
1956         (let (pos)
1957           (c-skip-ws-forward)
1958           (if (looking-at c-string-limit-regexp) ; string-delimiter.
1959               (cons (point) (or (c-safe (progn (c-forward-sexp 1) (point)))
1960                                 (point-max)))
1961             (setq pos (point))
1962             (if (c-forward-single-comment)
1963                 (cons pos (point))))))))
1964    
1965    (defun c-after-statement-terminator-p () ; Should we pass in LIM here?
1966      ;; Does point immediately follow a statement "terminator"?  A virtual
1967      ;; semicolon is regarded here as such.  So is a an opening brace ;-)
1968      ;;
1969      ;; This function might do hidden buffer changes.
1970      (or (save-excursion
1971            (backward-char)
1972            (and (looking-at "[;{}]")
1973                 (not (and c-special-brace-lists ; Pike special brace lists.
1974                           (eq (char-after) ?{)
1975                           (c-looking-at-special-brace-list)))))
1976          (c-at-vsemi-p)
1977          ;; The following (for macros) is not strict about exactly where we are
1978          ;; wrt white space at the end of the macro.  Doesn't seem to matter too
1979          ;; much.  ACM 2004/3/29.
1980          (let (eom)
1981            (save-excursion
1982              (if (c-beginning-of-macro)
1983                  (setq eom (progn (c-end-of-macro)
1984                                   (point)))))
1985            (when eom
1986              (save-excursion
1987                (c-forward-comments)
1988                (>= (point) eom))))))
1989    
1990    (defun c-back-over-illiterals (macro-start)
1991      ;; Move backwards over code which isn't a literal (i.e. comment or string),
1992      ;; stopping before reaching BOB or a literal or the boundary of a
1993      ;; preprocessor statement or the "beginning of a statement".  MACRO-START is
1994      ;; the position of the '#' beginning the current preprocessor directive, or
1995      ;; NIL if we're not in such.
1996      ;;
1997      ;; Return a cons (A.B), where
1998      ;;   A is NIL if we moved back to a BOS (and know it), T otherwise (we
1999      ;;     didn't move, or we hit a literal, or we're not sure about BOS).
2000      ;;   B is MACRO-BOUNDARY if we are about to cross the boundary out of or
2001      ;;     into a macro, otherwise LITERAL if we've hit a literal, otherwise NIL
2002      ;;
2003      ;;   The total collection of returned values is as follows:
2004      ;;     (nil . nil): Found a BOS whilst remaining inside the illiterals.
2005      ;;     (t . literal): No BOS found: only a comment/string.  We _might_ be at
2006      ;;                    a BOS - the caller must check this.
2007      ;;     (nil . macro-boundary): only happens with non-nil macro-start.  We've
2008      ;;                             moved and reached the opening # of the macro.
2009      ;;     (t . macro-boundary): Every other circumstance in which we're at a
2010      ;;                           macro-boundary.  We might be at a BOS.
2011      ;;
2012      ;; Point is left either at the beginning-of-statement, or at the last non-ws
2013      ;; code before encountering the literal/BOB or macro-boundary.
2014      ;;
2015      ;; Note that this function moves within either preprocessor commands
2016      ;; (macros) or normal code, but will not cross a boundary between the two,
2017      ;; or between two distinct preprocessor commands.
2018      ;;
2019      ;; Stop before `{' and after `;', `{', `}' and `};' when not followed by `}'
2020      ;; or `)', but on the other side of the syntactic ws.  Move by sexps and
2021      ;; move into parens.  Also stop before `#' when it's at boi on a line.
2022      ;;
2023      ;; This function might do hidden buffer changes.
2024      (save-match-data
2025        (let ((here (point))
2026              last) ; marks the position of non-ws code, what'll be BOS if, say, a
2027                                            ; semicolon precedes it.
2028          (catch 'done
2029            (while t ;; We go back one "token" each iteration of the loop.
2030              (setq last (point))
2031              (cond
2032              ;; Stop at the token after a comment.
2033               ((c-backward-single-comment) ; Also functions as backwards-ws.
2034                (goto-char last)
2035                (throw 'done '(t . literal)))
2036    
2037              ;; If we've gone back over a LF, we might have moved into or out of
2038              ;; a preprocessor line.
2039               ((and (save-excursion
2040                       (beginning-of-line)
2041                       (re-search-forward "\\(^\\|[^\\]\\)[\n\r]" last t))
2042                     (if macro-start
2043                         (< (point) macro-start)
2044                       (c-beginning-of-macro)))
2045                (goto-char last)
2046                ;; Return a car of NIL ONLY if we've hit the opening # of a macro.
2047                (throw 'done (cons (or (eq (point) here)
2048                                       (not macro-start))
2049                                   'macro-boundary)))
2050    
2051               ;; Have we found a virtual semicolon?  If so, stop, unless the next
2052               ;; statement is where we started from.
2053               ((and (c-at-vsemi-p)
2054                     (< last here)
2055                     (not (memq (char-after last) '(?\) ?})))) ; we've moved back from ) or }
2056                (goto-char last)
2057                (throw 'done '(nil . nil)))
2058    
2059               ;; Hit the beginning of the buffer/region?
2060               ((bobp)
2061                (if (/= here last)
2062                    (goto-char last))
2063                (throw 'done '(nil . nil)))
2064    
2065               ;; Move back a character.
2066               ((progn (backward-char) nil))
2067    
2068               ;; Stop at "{" (unless it's a PIKE special brace list.)
2069               ((eq (char-after) ?\{)
2070                (if (and c-special-brace-lists
2071                         (c-looking-at-special-brace-list))
2072                    (skip-syntax-backward "w_") ; Speedup only.
2073                  (if (/= here last)
2074                      (goto-char last))
2075                  (throw 'done '(nil . nil))))
2076    
2077               ;; Have we reached the start of a macro?  This always counts as
2078               ;; BOS.  (N.B. I don't think (eq (point) here) can ever be true
2079               ;; here.  FIXME!!! ACM 2004/3/29)
2080               ((and macro-start (eq (point) macro-start))
2081                (throw 'done (cons (eq (point) here) 'macro-boundary)))
2082    
2083               ;; Stop at token just after "}" or ";".
2084               ((looking-at "[;}]")
2085                ;; If we've gone back over ;, {, or }, we're done.
2086                (if (or (= here last)
2087                        (memq (char-after last) '(?\) ?}))) ; we've moved back from ) or }
2088                    (if (and (eq (char-before) ?}) ; If };, treat them as a unit.
2089                             (eq (char-after) ?\;))
2090                        (backward-char))
2091                  (goto-char last)   ; To the statement starting after the ; or }.
2092                  (throw 'done '(nil . nil))))
2093    
2094               ;; Stop at the token after a string.
2095               ((looking-at c-string-limit-regexp) ; Just gone back over a string terminator?
2096                (goto-char last)
2097                (throw 'done '(t . literal)))
2098            
2099               ;; Nothing special: go back word characters.
2100               (t (skip-syntax-backward "w_")) ; Speedup only.
2101               ))))))
2102    
2103    (defun c-forward-over-illiterals (macro-end allow-early-stop)
2104      ;; Move forwards over code, stopping before reaching EOB or a literal
2105      ;; (i.e. a comment/string) or the boundary of a preprocessor statement or
2106      ;; the "end of a statement".  MACRO-END is the position of the EOL/EOB which
2107      ;; terminates the current preprocessor directive, or NIL if we're not in
2108      ;; such.
2109      ;;
2110      ;; ALLOW-EARLY-STOP is non-nil if it is permissible to return without moving
2111      ;; forward at all, should we encounter a `{'.  This is an ugly kludge, but
2112      ;; seems unavoidable.  Depending on the context this function is called
2113      ;; from, we _sometimes_ need to stop there.  Currently (2004/4/3),
2114      ;; ALLOW-EARLY-STOP is applied only to open braces, not to virtual
2115      ;; semicolons, or anything else.
2116      ;;
2117      ;; Return a cons (A.B), where
2118      ;;   A is NIL if we moved forward to an EOS, or stay at one (when
2119      ;;     ALLOW-EARLY-STOP is set), T otherwise (we hit a literal).
2120      ;;   B is 'MACRO-BOUNDARY if we are about to cross the boundary out of or
2121      ;;     into a macro, otherwise 'LITERAL if we've hit a literal, otherwise NIL
2122      ;;
2123      ;; Point is left either after the end-of-statement, or at the last non-ws
2124      ;; code before encountering the literal, or the # of the preprocessor
2125      ;; statement, or at EOB [or just after last non-WS stuff??].
2126      ;;
2127      ;; As a clarification of "after the end-of-statement", if a comment or
2128      ;; whitespace follows a completed AWK statement, that statement is treated
2129      ;; as ending just after the last non-ws character before the comment.
2130      ;;
2131      ;; Note that this function moves within either preprocessor commands
2132      ;; (macros) or normal code, but not both within the same invocation.
2133      ;;
2134      ;; Stop before `{', `}', and `#' when it's at boi on a line, but on the
2135      ;; other side of the syntactic ws, and after `;', `}' and `};'.  Only
2136      ;; stop before `{' if at top level or inside braces, though.  Move by
2137      ;; sexps and move into parens.  Also stop at eol of lines with `#' at
2138      ;; the boi.
2139      ;;
2140      ;; This function might do hidden buffer changes.
2141      (let ((here (point))
2142            last)
2143        (catch 'done
2144          (while t ;; We go one "token" forward each time round this loop.
2145            (setq last (point))
2146    
2147            ;; If we've moved forward to a virtual semicolon, we're done.
2148            (if (and (> last here) ; Should we check ALLOW-EARLY-STOP, here? 2004/4/3
2149                     (c-at-vsemi-p))
2150                (throw 'done '(nil . nil)))
2151    
2152            (c-skip-ws-forward)
2153            (cond
2154             ;; Gone past the end of a macro?
2155             ((and macro-end (> (point) macro-end))
2156              (goto-char last)
2157              (throw 'done (cons (eq (point) here) 'macro-boundary)))
2158    
2159             ;; About to hit a comment?
2160             ((save-excursion (c-forward-single-comment))
2161              (goto-char last)
2162              (throw 'done '(t . literal)))
2163    
2164             ;; End of buffer?
2165             ((eobp)
2166              (if (/= here last)
2167                  (goto-char last))
2168              (throw 'done '(nil . nil)))
2169    
2170             ;; If we encounter a '{', stop just after the previous token.
2171             ((and (eq (char-after) ?{)
2172                   (not (and c-special-brace-lists
2173                             (c-looking-at-special-brace-list)))
2174                   (or allow-early-stop (/= here last))
2175                   (save-excursion  ; Is this a check that we're NOT at top level?
2176    ;;;; NO!  This seems to check that (i) EITHER we're at the top level; OR (ii) The next enclosing
2177    ;;;; level of bracketing is a '{'.  HMM.  Doesn't seem to make sense.
2178    ;;;; 2003/8/8 This might have something to do with the GCC extension "Statement Expressions", e.g.
2179    ;;;; while ({stmt1 ; stmt2 ; exp ;}).  This form excludes such Statement Expressions.
2180                     (or (not (c-safe (up-list -1) t))
2181                         (= (char-after) ?{))))
2182              (goto-char last)
2183              (throw 'done '(nil . nil)))
2184    
2185             ;; End of a PIKE special brace list?  If so, step over it and continue.
2186             ((and c-special-brace-lists
2187                   (eq (char-after) ?})
2188                   (save-excursion
2189                     (and (c-safe (up-list -1) t)
2190                          (c-looking-at-special-brace-list))))
2191              (forward-char)
2192              (skip-syntax-forward "w_"))   ; Speedup only.
2193    
2194             ;; Have we got a '}' after having moved?  If so, stop after the
2195             ;; previous token.
2196             ((and (eq (char-after) ?})
2197                   (/= here last))
2198              (goto-char last)
2199              (throw 'done '(nil . nil)))
2200    
2201             ;; Stop if we encounter a preprocessor line.
2202             ((and (not macro-end)
2203                   (eq (char-after) ?#)
2204                   (= (point) (c-point 'boi)))
2205              (goto-char last)
2206              ;(throw 'done (cons (eq (point) here) 'macro-boundary))) ; Changed 2003/3/26
2207              (throw 'done '(t . macro-boundary)))
2208    
2209             ;; Stop after a ';', '}', or "};"
2210             ((looking-at ";\\|};?")
2211              (goto-char (match-end 0))
2212              (throw 'done '(nil . nil)))
2213    
2214             ;; Found a string (this subsumes AWK regexps)?
2215             ((looking-at c-string-limit-regexp)
2216              (goto-char last)
2217              (throw 'done '(t . literal)))
2218    
2219             (t
2220              (forward-char)          ; Can't fail - we checked (eobp) earlier on.
2221              (skip-syntax-forward "w_")    ; Speedup only.
2222              (when (and macro-end (> (point) macro-end))
2223                (goto-char last)
2224                (throw 'done (cons (eq (point) here) 'macro-boundary))))
2225             )))))
2226    
2227    (defun c-one-line-string-p (range)
2228      ;; Is the literal defined by RANGE a string contained in a single line?
2229      ;;
2230      ;; This function might do hidden buffer changes.
2231      (save-excursion
2232        (goto-char (car range))
2233        (and (looking-at c-string-limit-regexp)
2234             (progn (skip-chars-forward "^\n" (cdr range))
2235                    (eq (point) (cdr range))))))
2236    
2237  (defun c-beginning-of-statement (&optional count lim sentence-flag)  (defun c-beginning-of-statement (&optional count lim sentence-flag)
2238    "Go to the beginning of the innermost C statement.    "Go to the beginning of the innermost C statement.
2239  With prefix arg, go back N - 1 statements.  If already at the  With prefix arg, go back N - 1 statements.  If already at the
# Line 1382  repetition count, a buffer position limi Line 2247  repetition count, a buffer position limi
2247  to search for the syntactic context, and a flag saying whether to do  to search for the syntactic context, and a flag saying whether to do
2248  sentence motion in or near comments and multiline strings.  sentence motion in or near comments and multiline strings.
2249    
2250  Note that `c-beginning-of-statement-1' is usually better to use from  Note that for use in programs, `c-beginning-of-statement-1' is
2251  programs.  It has much more well defined semantics than this one,  usually better.  It has much better defined semantics than this one,
2252  which is intended for interactive use and might therefore change to be  which is intended for interactive use, and might therefore change to
2253  more \"DWIM:ey\"."  be more \"DWIM:ey\"."
2254    (interactive (list (prefix-numeric-value current-prefix-arg)    (interactive (list (prefix-numeric-value current-prefix-arg)
2255                       nil t))                       nil t))
2256    (c-save-buffer-state    (if (< count 0)
2257        ((count (or count 1))        (c-end-of-statement (- count) lim sentence-flag)
2258         here      (c-save-buffer-state
2259         (range (c-collect-line-comments (c-literal-limits lim))))          ((count (or count 1))
2260      (while (and (/= count 0)           last ; start point for going back ONE chunk.  Updated each chunk movement.
2261                  (or (not lim) (> (point) lim)))           (macro-fence
2262        (setq here (point))            (save-excursion (and (not (bobp)) (c-beginning-of-macro) (point))))
2263        (if (and (not range) sentence-flag)           res                            ; result from sub-function call
2264            (save-excursion           not-bos                        ; "not beginning-of-statement"
2265              ;; Find the comment next to point if we're not in one.           (range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL
2266              (if (> count 0)  
2267                  (if (c-backward-single-comment)        ;; Go back one statement at each iteration of the following loop.
2268                      (setq range (cons (point)        (while (and (/= count 0)
2269                                        (progn (c-forward-single-comment)                    (or (not lim) (> (point) lim)))
2270                                               (point))))          ;; Go back one "chunk" each time round the following loop, stopping
2271                    (c-skip-ws-backward)          ;; when we reach a statement boundary, etc.
2272                    (setq range (point))          (setq last (point))
2273                    (setq range          (while
2274                          (if (eq (char-before) ?\")              (cond ; Each arm of this cond returns NIL on reaching a desired
2275                              (c-safe (c-backward-sexp 1)                    ; statement boundary, non-NIL otherwise.
2276                                      (cons (point) range)))))               ((bobp)
2277                (c-skip-ws-forward)                (setq count 0)
2278                (if (eq (char-after) ?\")                nil)
2279                    (setq range (cons (point)  
2280                                      (progn               (range                ; point is within or approaching a literal.
2281                                        (c-forward-sexp 1)                (cond
2282                                        (point))))                 ;; Single line string or sentence-flag is null => skip the
2283                  (setq range (point))                 ;; entire literal.
2284                  (setq range (if (c-forward-single-comment)                 ((or (null sentence-flag)
2285                                  (cons range (point))                      (c-one-line-string-p range))
2286                                nil))))                  (goto-char (car range))
2287              (setq range (c-collect-line-comments range))))                  (setq range (c-ascertain-preceding-literal))
2288        (if (and (< count 0) (= here (point-max)))                  ;; N.B. The following is essentially testing for an AWK regexp
2289            ;; Special case because eob might be in a literal.                  ;; at BOS:
2290            (setq range nil))                  ;; Was the previous non-ws thing an end of statement?
2291        (if range                  (save-excursion
2292            (if (and sentence-flag                    (if macro-fence
2293                     (or (/= (char-syntax (char-after (car range))) ?\")                        (c-backward-comments)
2294                         ;; Only visit a string if it spans more than one line.                      (c-backward-syntactic-ws))
2295                         (save-excursion                    (not (or (bobp) (c-after-statement-terminator-p)))))
2296                           (goto-char (car range))  
2297                           (skip-chars-forward "^\n" (cdr range))                 ;; Comment inside a statement or a multi-line string.
2298                           (< (point) (cdr range)))))                 (t (when (setq res ; returns non-nil when we go out of the literal
2299                (let* ((lit-type (c-literal-type range))                                (if (eq (c-literal-type range) 'string)
2300                       (line-prefix (concat "[ \t]*\\("                                    (c-beginning-of-sentence-in-string range)
2301                                            c-current-comment-prefix                                  (c-beginning-of-sentence-in-comment range)))
2302                                            "\\)[ \t]*"))                      (setq range (c-ascertain-preceding-literal)))
2303                       (beg (if (eq lit-type 'string)                    res)))
2304                                (1+ (car range))  
2305                              (save-excursion               ;; Non-literal code.
2306                                (goto-char (car range))               (t (setq res (c-back-over-illiterals macro-fence))
2307                                (max (progn                  (setq not-bos          ; "not reached beginning-of-statement".
2308                                       (looking-at comment-start-skip)                        (or (= (point) last)
2309                                       (match-end 0))                            (memq (char-after) '(?\) ?\}))
2310                                     (progn                            (and
2311                                       (looking-at line-prefix)                             (car res)
2312                                       (match-end 0))))))                             ;; We're at a tentative BOS.  The next form goes
2313                       (end (- (cdr range) (if (eq lit-type 'c) 2 1)))                             ;; back over WS looking for an end of previous
2314                       (beg-of-para (if (eq lit-type 'string)                             ;; statement.
2315                                        (lambda ())                             (not (save-excursion
2316                                      (lambda ()                                    (if macro-fence
2317                                        (beginning-of-line)                                        (c-backward-comments)
2318                                        (if (looking-at line-prefix)                                      (c-backward-syntactic-ws))
2319                                            (goto-char (match-end 0)))))))                                    (or (bobp) (c-after-statement-terminator-p)))))))
2320                  (save-restriction                  ;; Are we about to move backwards into or out of a
2321                    ;; Move by sentence, but not past the limit of the                  ;; preprocessor command?  If so, locate it's beginning.
2322                    ;; literal, narrowed to the appropriate                  (when (eq (cdr res) 'macro-boundary)
2323                    ;; paragraph(s).                    (save-excursion
2324                    (narrow-to-region (save-excursion                      (beginning-of-line)
2325                                        (let ((pos (min here end)))                      (setq macro-fence
2326                                          (goto-char pos)                            (and (not (bobp))
2327                                          (forward-paragraph -1)                                 (progn (c-skip-ws-backward) (c-beginning-of-macro))
2328                                          (if (looking-at paragraph-separate)                                 (point)))))
2329                                              (forward-line))                  ;; Are we about to move backwards into a literal?
2330                                          (when (> (point) beg)                  (when (memq (cdr res) '(macro-boundary literal))
2331                                            (funcall beg-of-para)                    (setq range (c-ascertain-preceding-literal)))
2332                                            (when (>= (point) pos)                  not-bos))
2333                                              (forward-paragraph -2)            (setq last (point)))
2334                                              (funcall beg-of-para)))  
2335                                          (max (point) beg)))          (if (/= count 0) (setq count (1- count))))
2336                                      end)        (c-keep-region-active))))
                   (c-safe (forward-sentence (if (< count 0) 1 -1)))  
                   (if (and (memq lit-type '(c c++))  
                            ;; Check if we stopped due to a comment  
                            ;; prefix and not a sentence end.  
                            (/= (point) (point-min))  
                            (/= (point) (point-max))  
                            (save-excursion  
                              (beginning-of-line)  
                              (looking-at line-prefix))  
                            (>= (point) (match-beginning 0))  
                            (/= (match-beginning 1) (match-end 1))  
                            (or (< (point) (match-end 0))  
                                (and  
                                 (= (point) (match-end 0))  
                                 ;; The comment prefix may contain  
                                 ;; characters that is regarded as end  
                                 ;; of sentence.  
                                 (or (eolp)  
                                     (and  
                                      (save-excursion  
                                        (forward-paragraph -1)  
                                        (< (point) (match-beginning 0)))  
                                      (save-excursion  
                                        (beginning-of-line)  
                                        (or (not (re-search-backward  
                                                  (sentence-end)  
                                                  (c-point 'bopl)  
                                                  t))  
                                            (< (match-end 0)  
                                               (c-point 'eol)))))))))  
                       (setq count (+ count (if (< count 0) -1 1)))  
                     (if (< count 0)  
                         (progn  
                           ;; In block comments, if there's only  
                           ;; horizontal ws between the text and the  
                           ;; comment ender, stop before it.  Stop after  
                           ;; the ender if there's either nothing or  
                           ;; newlines between.  
                           (when (and (eq lit-type 'c)  
                                      (eq (point) (point-max)))  
                             (widen)  
                             (when (or (= (skip-chars-backward " \t") 0)  
                                       (eq (point) (point-max))  
                                       (bolp))  
                               (goto-char (cdr range)))))  
                       (when (and (eq (point) (point-min))  
                                  (looking-at "[ \t]*\\\\?$"))  
                         ;; Stop before instead of after the comment  
                         ;; starter if nothing follows it.  
                         (widen)  
                         (goto-char (car range))  
                         (if (and (eq lit-type 'string) (/= (point) here))  
                             (setq count (1+ count)  
                                   range nil))))))  
                 ;; See if we should escape the literal.  
                 (if (> count 0)  
                     (if (< (point) here)  
                         (setq count (1- count))  
                       (goto-char (car range))  
                       (setq range nil))  
                   (if (> (point) here)  
                       (setq count (1+ count))  
                     (goto-char (cdr range))  
                     (setq range nil))))  
             (goto-char (if (> count 0) (car range) (cdr range)))  
             (setq range nil))  
         (goto-char here)  
         (if (> count 0)  
             (condition-case nil  
                 ;; Stop before `{' and after `;', `{', `}' and `};'  
                 ;; when not followed by `}' or `)', but on the other  
                 ;; side of the syntactic ws.  Move by sexps and move  
                 ;; into parens.  Also stop before `#' when it's at boi  
                 ;; on a line.  
                 (let ((literal-pos (not sentence-flag))  
                       last last-below-line)  
                   (catch 'done  
                     (while t  
                       (setq last (point))  
                       (when (and (or (eq (char-after) ?\{)  
                                      (and (eq (char-after) ?#)  
                                           (eq (point) (c-point 'boi)))  
                                      )  
                                  (/= here last))  
                         (unless (and c-special-brace-lists  
                                      (eq (char-after) ?{)  
                                      (c-looking-at-special-brace-list))  
                           (if (and (eq (char-after) ?#)  
                                    (numberp last-below-line)  
                                    (not (eq last-below-line here)))  
                               (goto-char last-below-line))  
                           (throw 'done t)))  
                       ;; Don't know why I added the following, but it  
                       ;; doesn't work when point is preceded by a line  
                       ;; style comment. /mast  
                       ;;(c-skip-ws-backward)  
                       (if literal-pos  
                           (c-backward-comments)  
                         (when (c-backward-single-comment)  
                           ;; Record position of first comment.  
                           (save-excursion  
                             (c-forward-single-comment)  
                             (setq literal-pos (point)))  
                           (c-backward-comments)))  
                       (unless last-below-line  
                         (if (save-excursion  
                               (re-search-forward "\\(^\\|[^\\]\\)$" last t))  
                             (setq last-below-line last)))  
                       (cond ((bobp)     ; Must handle bob specially.  
                              (if (= here last)  
                                  (throw 'done t)  
                                (goto-char last)  
                                (throw 'done t)))  
                             ((progn (backward-char)  
                                     (looking-at "[;{}]"))  
                              (if (and c-special-brace-lists  
                                       (eq (char-after) ?{)  
                                       (c-looking-at-special-brace-list))  
                                  (skip-syntax-backward "w_") ; Speedup only.  
                                (if (or (= here last)  
                                        (memq (char-after last) '(?\) ?})))  
                                    (if (and (eq (char-before) ?})  
                                             (eq (char-after) ?\;))  
                                        (backward-char))  
                                  (goto-char last)  
                                  (throw 'done t))))  
                             ((= (char-syntax (char-after)) ?\")  
                              (let ((end (point)))  
                                (forward-char)  
                                (c-backward-sexp)  
                                (save-excursion  
                                  (skip-chars-forward "^\n" end)  
                                  (when (< (point) end)  
                                    ;; Break at multiline string.  
                                    (setq literal-pos (1+ end))  
                                    (throw 'done t)))))  
                             (t (skip-syntax-backward "w_")) ; Speedup only.  
                             )))  
                   (if (and (numberp literal-pos)  
                            (< (point) literal-pos))  
                       ;; We jumped over a comment or string that  
                       ;; should be investigated.  
                       (goto-char literal-pos)  
                     (setq count (1- count))))  
               (error  
                (goto-char (point-min))  
                (setq count 0)))  
           (condition-case nil  
               ;; Stop before `{', `}', and `#' when it's at boi on a  
               ;; line, but on the other side of the syntactic ws, and  
               ;; after `;', `}' and `};'.  Only stop before `{' if at  
               ;; top level or inside braces, though.  Move by sexps  
               ;; and move into parens.  Also stop at eol of lines  
               ;; with `#' at the boi.  
               (let ((literal-pos (not sentence-flag))  
                     last)  
                 (catch 'done  
                   (while t  
                     (setq last (point))  
                     (if literal-pos  
                         (c-forward-comments)  
                       (if (progn  
                             (c-skip-ws-forward)  
                             ;; Record position of first comment.  
                             (setq literal-pos (point))  
                             (c-forward-single-comment))  
                           (c-forward-comments)  
                         (setq literal-pos nil)))  
                     (cond ((and (eq (char-after) ?{)  
                                 (not (and c-special-brace-lists  
                                           (c-looking-at-special-brace-list)))  
                                 (/= here last)  
                                 (save-excursion  
                                   (or (not (c-safe (up-list -1) t))  
                                       (= (char-after) ?{))))  
                            (goto-char last)  
                            (throw 'done t))  
                           ((and c-special-brace-lists  
                                 (eq (char-after) ?})  
                                 (save-excursion  
                                   (and (c-safe (up-list -1) t)  
                                        (c-looking-at-special-brace-list))))  
                            (forward-char 1)  
                            (skip-syntax-forward "w_")) ; Speedup only.  
                           ((and (eq (char-after) ?})  
                                 (/= here last))  
                            (goto-char last)  
                            (throw 'done t))  
 ;                         ((and (eq (char-after) ?#)  
 ;                               (= (point) (c-point 'boi)))  
 ;                          (if (= here last)  
 ;                              (or (re-search-forward "\\(^\\|[^\\]\\)$" nil t)  
 ;                                  (goto-char (point-max)))  
 ;                            (goto-char last))  
 ;                          (throw 'done t))  
                           ((looking-at ";\\|};?")  
                            (goto-char (match-end 0))  
                            (throw 'done t))  
                           ((= (char-syntax (char-after)) ?\")  
                            (let ((beg (point)))  
                              (c-forward-sexp)  
                              (save-excursion  
                                (skip-chars-backward "^\n" beg)  
                                (when (> (point) beg)  
                                  ;; Break at multiline string.  
                                  (setq literal-pos beg)  
                                  (throw 'done t)))))  
                           (t  
                            (forward-char 1)  
                            (skip-syntax-forward "w_")) ; Speedup only.  
                           )))  
                 (if (and (numberp literal-pos)  
                          (> (point) literal-pos))  
                     ;; We jumped over a comment that should be investigated.  
                     (goto-char literal-pos)  
                   (setq count (1+ count))))  
             (error  
              (goto-char (point-max))  
              (setq count 0)))  
           ))  
       ;; If we haven't moved we're near a buffer limit.  
       (when (and (not (zerop count)) (= (point) here))  
         (goto-char (if (> count 0) (point-min) (point-max)))  
         (setq count 0))))  
   (c-keep-region-active))  
2337    
2338  (defun c-end-of-statement (&optional count lim sentence-flag)  (defun c-end-of-statement (&optional count lim sentence-flag)
2339    "Go to the end of the innermost C statement.    "Go to the end of the innermost C statement.
# Line 1708  to search for the syntactic context, and Line 2348  to search for the syntactic context, and
2348  sentence motion in or near comments and multiline strings."  sentence motion in or near comments and multiline strings."
2349    (interactive (list (prefix-numeric-value current-prefix-arg)    (interactive (list (prefix-numeric-value current-prefix-arg)
2350                       nil t))                       nil t))
2351    (c-beginning-of-statement (- (or count 1)) lim sentence-flag)    (setq count (or count 1))
2352    (c-keep-region-active))    (if (< count 0) (c-beginning-of-statement (- count) lim sentence-flag)
2353    
2354        (c-save-buffer-state
2355            (here ; start point for going forward ONE statement.  Updated each statement.
2356             (macro-fence
2357              (save-excursion
2358                (and (not (eobp)) (c-beginning-of-macro)
2359                     (progn (c-end-of-macro) (point)))))
2360             res
2361             (range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL
2362    
2363          ;; Go back/forward one statement at each iteration of the following loop.
2364          (while (and (/= count 0)
2365                      (or (not lim) (< (point) lim)))
2366            (setq here (point))             ; ONLY HERE is HERE updated
2367    
2368            ;; Go forward one "chunk" each time round the following loop, stopping
2369            ;; when we reach a statement boundary, etc.
2370            (while
2371                (cond    ; Each arm of this cond returns NIL on reaching a desired
2372                         ; statement boundary, non-NIL otherwise.
2373                 ((eobp)
2374                  (setq count 0)
2375                  nil)
2376    
2377                 (range                     ; point is within a literal.
2378                  (cond
2379                   ;; sentence-flag is null => skip the entire literal.
2380                   ;; or a Single line string.
2381                   ((or (null sentence-flag)
2382                        (c-one-line-string-p range))
2383                    (goto-char (cdr range))
2384                    (setq range (c-ascertain-following-literal))
2385                    ;; Is there a virtual semicolon here (e.g. for AWK)?
2386                    (not (c-at-vsemi-p)))
2387    
2388                   ;; Comment or multi-line string.
2389                   (t (when (setq res ; gets non-nil when we go out of the literal
2390                                  (if (eq (c-literal-type range) 'string)
2391                                      (c-end-of-sentence-in-string range)
2392                                    (c-end-of-sentence-in-comment range)))
2393                        (setq range (c-ascertain-following-literal)))
2394                      ;; If we've just come forward out of a literal, check for
2395                      ;; vsemi.  (N.B. AWK can't have a vsemi after a comment, but
2396                      ;; some other language may do in the future)
2397                      (and res
2398                           (not (c-at-vsemi-p))))))
2399    
2400                 ;; Non-literal code.
2401                 (t (setq res (c-forward-over-illiterals macro-fence
2402                                                         (> (point) here)))
2403                    ;; Are we about to move forward into or out of a
2404                    ;; preprocessor command?
2405                    (when (eq (cdr res) 'macro-boundary)
2406                      (save-excursion
2407                        (end-of-line)
2408                        (setq macro-fence
2409                              (and (not (eobp))
2410                                   (progn (c-skip-ws-forward)
2411                                          (c-beginning-of-macro))
2412                                   (progn (c-end-of-macro)
2413                                          (point))))))
2414                    ;; Are we about to move forward into a literal?
2415                    (when (memq (cdr res) '(macro-boundary literal))
2416                      (setq range (c-ascertain-following-literal)))
2417                    (car res))))
2418    
2419            (if (/= count 0) (setq count (1- count))))
2420          (c-keep-region-active))))
2421                                  
2422    
2423    
2424  ;; set up electric character functions to work with pending-del,  ;; set up electric character functions to work with pending-del,
# Line 1737  sentence motion in or near comments and Line 2446  sentence motion in or near comments and
2446    
2447    
2448  (defun c-calc-comment-indent (entry)  (defun c-calc-comment-indent (entry)
2449      ;; This function might do hidden buffer changes.
2450    (if (symbolp entry)    (if (symbolp entry)
2451        (setq entry (or (assq entry c-indent-comment-alist)        (setq entry (or (assq entry c-indent-comment-alist)
2452                        (assq 'other c-indent-comment-alist)                        (assq 'other c-indent-comment-alist)
# Line 1760  sentence motion in or near comments and Line 2470  sentence motion in or near comments and
2470                     (let ((lim (c-literal-limits (c-point 'bol) t)))                     (let ((lim (c-literal-limits (c-point 'bol) t)))
2471                       (when (consp lim)                       (when (consp lim)
2472                         (goto-char (car lim))                         (goto-char (car lim))
2473                         (when (looking-at "/[/*]")                         (when (looking-at "/[/*]") ; FIXME!!!  Adapt for AWK! (ACM, 2005/11/18)
2474                           ;; Found comment to align with.                           ;; Found comment to align with.
2475                           (if (bolp)                           (if (bolp)
2476                               ;; Do not pad with one space if we're at bol.                               ;; Do not pad with one space if we're at bol.
# Line 1835  See `c-indent-comment-alist' for a descr Line 2545  See `c-indent-comment-alist' for a descr
2545  A prefix argument acts as a repeat count.  With a negative argument,  A prefix argument acts as a repeat count.  With a negative argument,
2546  move forward to the end of the containing preprocessor conditional.  move forward to the end of the containing preprocessor conditional.
2547    
2548  `#elif' is treated like `#else' followed by `#if', so the function  \"#elif\" is treated like \"#else\" followed by \"#if\", so the
2549  stops at them when going backward, but not when going forward."  function stops at them when going backward, but not when going
2550    forward."
2551    (interactive "p")    (interactive "p")
2552    (c-forward-conditional (- count) -1)    (c-forward-conditional (- count) -1)
2553    (c-keep-region-active))    (c-keep-region-active))
2554        
2555  (defun c-up-conditional-with-else (count)  (defun c-up-conditional-with-else (count)
2556    "Move back to the containing preprocessor conditional, including `#else'.    "Move back to the containing preprocessor conditional, including \"#else\".
2557  Just like `c-up-conditional', except it also stops at `#else'  Just like `c-up-conditional', except it also stops at \"#else\"
2558  directives."  directives."
2559    (interactive "p")    (interactive "p")
2560    (c-forward-conditional (- count) -1 t)    (c-forward-conditional (- count) -1 t)
# Line 1854  directives." Line 2565  directives."
2565  A prefix argument acts as a repeat count.  With a negative argument,  A prefix argument acts as a repeat count.  With a negative argument,
2566  move backward into the previous preprocessor conditional.  move backward into the previous preprocessor conditional.
2567    
2568  `#elif' is treated like `#else' followed by `#if', so the function  \"#elif\" is treated like \"#else\" followed by \"#if\", so the
2569  stops at them when going forward, but not when going backward."  function stops at them when going forward, but not when going
2570    backward."
2571    (interactive "p")    (interactive "p")
2572    (c-forward-conditional count 1)    (c-forward-conditional count 1)
2573    (c-keep-region-active))    (c-keep-region-active))
2574    
2575  (defun c-down-conditional-with-else (count)  (defun c-down-conditional-with-else (count)
2576    "Move forward into the next preprocessor conditional, including `#else'.    "Move forward into the next preprocessor conditional, including \"#else\".
2577  Just like `c-down-conditional', except it also stops at `#else'  Just like `c-down-conditional', except it also stops at \"#else\"
2578  directives."  directives."
2579    (interactive "p")    (interactive "p")
2580    (c-forward-conditional count 1 t)    (c-forward-conditional count 1 t)
# Line 1881  move forward across a preprocessor condi Line 2593  move forward across a preprocessor condi
2593  A prefix argument acts as a repeat count.  With a negative argument,  A prefix argument acts as a repeat count.  With a negative argument,
2594  move backward across a preprocessor conditional.  move backward across a preprocessor conditional.
2595    
2596  `#elif' is treated like `#else' followed by `#if', except that the  \"#elif\" is treated like \"#else\" followed by \"#if\", except that
2597  nesting level isn't changed when tracking subconditionals.  the nesting level isn't changed when tracking subconditionals.
2598    
2599  The optional argument TARGET-DEPTH specifies the wanted nesting depth  The optional argument TARGET-DEPTH specifies the wanted nesting depth
2600  after each scan.  I.e. if TARGET-DEPTH is -1, the function will move  after each scan.  I.e. if TARGET-DEPTH is -1, the function will move
2601  out of the enclosing conditional.  A non-integer non-nil TARGET-DEPTH  out of the enclosing conditional.  A non-integer non-nil TARGET-DEPTH
2602  counts as -1.  counts as -1.
2603    
2604  If the optional argument WITH-ELSE is non-nil, `#else' directives are  If the optional argument WITH-ELSE is non-nil, \"#else\" directives
2605  treated as conditional clause limits.  Normally they are ignored."  are treated as conditional clause limits.  Normally they are ignored."
2606    (interactive "p")    (interactive "p")
2607    (let* ((forward (> count 0))    (let* ((forward (> count 0))
2608           (increment (if forward -1 1))           (increment (if forward -1 1))
# Line 1996  prefix argument is equivalent to -1. Line 2708  prefix argument is equivalent to -1.
2708    just inserts a tab character, or the equivalent number of spaces,    just inserts a tab character, or the equivalent number of spaces,
2709    depending on the variable `indent-tabs-mode'."    depending on the variable `indent-tabs-mode'."
2710    
2711    (interactive "p")    (interactive "P")
2712    (let ((indent-function    (let ((indent-function
2713           (if c-syntactic-indentation           (if c-syntactic-indentation
2714               (symbol-function 'indent-according-to-mode)               (symbol-function 'indent-according-to-mode)
2715             (lambda ()             (lambda ()
2716               (let ((c-macro-start c-macro-start)               (let ((c-macro-start c-macro-start)
2717                     (steps (cond ((not current-prefix-arg) 1)                     (steps (if (equal arg '(4))
2718                                  ((equal current-prefix-arg '(4)) -1)                                -1
2719                                  (t arg))))                              (prefix-numeric-value arg))))
2720                 (c-shift-line-indentation (* steps c-basic-offset))                 (c-shift-line-indentation (* steps c-basic-offset))
2721                 (when (and c-auto-align-backslashes                 (when (and c-auto-align-backslashes
2722                            (save-excursion                            (save-excursion
# Line 2014  prefix argument is equivalent to -1. Line 2726  prefix argument is equivalent to -1.
2726                   ;; Realign the line continuation backslash if inside a macro.                   ;; Realign the line continuation backslash if inside a macro.
2727                   (c-backslash-region (point) (point) nil t)))                   (c-backslash-region (point) (point) nil t)))
2728               ))))               ))))
2729      (if (and c-syntactic-indentation current-prefix-arg)      (if (and c-syntactic-indentation arg)
2730          ;; If c-syntactic-indentation and got arg, always indent this          ;; If c-syntactic-indentation and got arg, always indent this
2731          ;; line as C and shift remaining lines of expression the same          ;; line as C and shift remaining lines of expression the same
2732          ;; amount.          ;; amount.
# Line 2029  prefix argument is equivalent to -1. Line 2741  prefix argument is equivalent to -1.
2741                               shift-amt))                               shift-amt))
2742            (save-excursion            (save-excursion
2743              (if (eq c-tab-always-indent t)              (if (eq c-tab-always-indent t)
2744                  (beginning-of-line))                  (beginning-of-line))    ; FIXME!!! What is this here for?  ACM 2005/10/31
2745              (setq beg (point))              (setq beg (point))
2746              (c-forward-sexp 1)              (c-forward-sexp 1)
2747              (setq end (point))              (setq end (point))
# Line 2040  prefix argument is equivalent to -1. Line 2752  prefix argument is equivalent to -1.
2752                (indent-code-rigidly beg end shift-amt "#")))                (indent-code-rigidly beg end shift-amt "#")))
2753        ;; Else use c-tab-always-indent to determine behavior.        ;; Else use c-tab-always-indent to determine behavior.
2754        (cond        (cond
2755         ;; CASE 1: indent when at column zero or in lines indentation,         ;; CASE 1: indent when at column zero or in line's indentation,
2756         ;; otherwise insert a tab         ;; otherwise insert a tab
2757         ((not c-tab-always-indent)         ((not c-tab-always-indent)
2758          (if (save-excursion          (if (save-excursion
# Line 2054  prefix argument is equivalent to -1. Line 2766  prefix argument is equivalent to -1.
2766         ;; CASE 3: if in a literal, insert a tab, but always indent the         ;; CASE 3: if in a literal, insert a tab, but always indent the
2767         ;; line         ;; line
2768         (t         (t
2769          (if (c-in-literal)          (if (c-save-buffer-state () (c-in-literal))
2770              (funcall c-insert-tab-function))              (funcall c-insert-tab-function))
2771          (funcall indent-function)          (funcall indent-function)
2772          )))))          )))))
# Line 2135  non-nil." Line 2847  non-nil."
2847                      ;; shut up any echo msgs on indiv lines                      ;; shut up any echo msgs on indiv lines
2848                      (c-echo-syntactic-information-p nil)                      (c-echo-syntactic-information-p nil)
2849                      (in-macro (and c-auto-align-backslashes                      (in-macro (and c-auto-align-backslashes
2850                                     (save-excursion (c-beginning-of-macro))                                     (c-save-buffer-state ()
2851                                         (save-excursion (c-beginning-of-macro)))
2852                                     start))                                     start))
2853                      (c-fix-backslashes nil)                      (c-fix-backslashes nil)
2854                      syntax)                      syntax)
# Line 2181  non-nil." Line 2894  non-nil."
2894  (defun c-fn-region-is-active-p ()  (defun c-fn-region-is-active-p ()
2895    ;; Function version of the macro for use in places that aren't    ;; Function version of the macro for use in places that aren't
2896    ;; compiled, e.g. in the menus.    ;; compiled, e.g. in the menus.
   ;;  
   ;; This function does not do any hidden buffer changes.  
2897    (c-region-is-active-p))    (c-region-is-active-p))
2898    
2899  (defun c-indent-line-or-region ()  (defun c-indent-line-or-region ()
# Line 2199  indent the current line syntactically." Line 2910  indent the current line syntactically."
2910  (defvar c-progress-info nil)  (defvar c-progress-info nil)
2911    
2912  (defun c-progress-init (start end context)  (defun c-progress-init (start end context)
   ;; This function does not do any hidden buffer changes.  
2913    (cond    (cond
2914     ;; Be silent     ;; Be silent
2915     ((not c-progress-interval))     ((not c-progress-interval))
# Line 2221  indent the current line syntactically." Line 2931  indent the current line syntactically."
2931     ))     ))
2932    
2933  (defun c-progress-update ()  (defun c-progress-update ()
   ;; This function does not do any hidden buffer changes.  
2934    (if (not (and c-progress-info c-progress-interval))    (if (not (and c-progress-info c-progress-interval))
2935        nil        nil
2936      (let ((now (nth 1 (current-time)))      (let ((now (nth 1 (current-time)))
# Line 2238  indent the current line syntactically." Line 2947  indent the current line syntactically."
2947        )))        )))
2948    
2949  (defun c-progress-fini (context)  (defun c-progress-fini (context)
   ;; This function does not do any hidden buffer changes.  
2950    (if (not c-progress-interval)    (if (not c-progress-interval)
2951        nil        nil
2952      (if (or (eq context (aref c-progress-info 3))      (if (or (eq context (aref c-progress-info 3))
# Line 2399  command to conveniently insert and align Line 3107  command to conveniently insert and align
3107          (set-marker point-pos nil))))          (set-marker point-pos nil))))
3108    
3109  (defun c-append-backslashes-forward (to-mark column point-pos)  (defun c-append-backslashes-forward (to-mark column point-pos)
   ;; This function does not do any hidden buffer changes.  
3110    (let ((state (parse-partial-sexp (c-point 'bol) (point))))    (let ((state (parse-partial-sexp (c-point 'bol) (point))))
3111      (if column      (if column
3112          (while          (while
# Line 2473  command to conveniently insert and align Line 3180  command to conveniently insert and align
3180             (bolp))))))                  ; forward-line has funny behavior at eob.             (bolp))))))                  ; forward-line has funny behavior at eob.
3181    
3182  (defun c-delete-backslashes-forward (to-mark point-pos)  (defun c-delete-backslashes-forward (to-mark point-pos)
   ;; This function does not do any hidden buffer changes.  
3183    (while    (while
3184        (and (<= (point) to-mark)        (and (<= (point) to-mark)
3185             (progn             (progn
# Line 2518  command to conveniently insert and align Line 3224  command to conveniently insert and align
3224    ;; comment.  Return a cons of the prefix string and the column where    ;; comment.  Return a cons of the prefix string and the column where
3225    ;; it ends.  If fill-prefix is set, it'll override.  Note that this    ;; it ends.  If fill-prefix is set, it'll override.  Note that this
3226    ;; function also uses the value of point in some heuristics.    ;; function also uses the value of point in some heuristics.
3227      ;;
3228      ;; This function might do hidden buffer changes.
3229    
3230    (let* ((here (point))    (let* ((here (point))
3231           (prefix-regexp (concat "[ \t]*\\("           (prefix-regexp (concat "[ \t]*\\("
# Line 2877  command to conveniently insert and align Line 3585  command to conveniently insert and align
3585    ;; If APPLY-OUTSIDE-LITERAL is nil then the function will be called    ;; If APPLY-OUTSIDE-LITERAL is nil then the function will be called
3586    ;; only if the point turns out to be inside a comment or a string.    ;; only if the point turns out to be inside a comment or a string.
3587    ;;    ;;
3588    ;; This function does not do any hidden buffer changes.    ;; Note that this function does not do any hidden buffer changes.
3589    
3590    (let (fill    (let (fill
3591          ;; beg and end limits the region to narrow.  end is a marker.          ;; beg and end limits the region to narrow.  end is a marker.
# Line 2892  command to conveniently insert and align Line 3600  command to conveniently insert and align
3600          ;; hanging.  In that case it's set to the number of spaces          ;; hanging.  In that case it's set to the number of spaces
3601          ;; that should be between the text and the ender.          ;; that should be between the text and the ender.
3602          hang-ender-stuck          hang-ender-stuck
3603            ;; auto-fill-spaces is the exact sequence of whitespace between a
3604            ;; comment's last word and the comment ender, temporarily replaced
3605            ;; with 'x's before calling FUN when FILL-PARAGRAPH is nil.  
3606            auto-fill-spaces
3607          (here (point))          (here (point))
3608          (c-lit-limits c-lit-limits)          (c-lit-limits c-lit-limits)
3609          (c-lit-type c-lit-type))          (c-lit-type c-lit-type))
# Line 2902  command to conveniently insert and align Line 3614  command to conveniently insert and align
3614      (if (and buffer-undo-list (not (eq buffer-undo-list t)))      (if (and buffer-undo-list (not (eq buffer-undo-list t)))
3615          (setq buffer-undo-list (cons (point) buffer-undo-list)))          (setq buffer-undo-list (cons (point) buffer-undo-list)))
3616    
3617      (save-restriction      (c-save-buffer-state ()
3618        ;; Widen to catch comment limits correctly.        (save-restriction
3619        (widen)          ;; Widen to catch comment limits correctly.
3620        (unless c-lit-limits          (widen)
3621          (setq c-lit-limits (c-literal-limits nil fill-paragraph)))          (unless c-lit-limits
3622        (setq c-lit-limits (c-collect-line-comments c-lit-limits))            (setq c-lit-limits (c-literal-limits nil fill-paragraph)))
3623        (unless c-lit-type          (setq c-lit-limits (c-collect-line-comments c-lit-limits))
3624          (setq c-lit-type (c-literal-type c-lit-limits))))          (unless c-lit-type
3625              (setq c-lit-type (c-literal-type c-lit-limits))))
3626    
3627      (save-excursion        (save-excursion
3628        (unless (c-safe (backward-char)          (unless (c-safe (backward-char)
3629                        (forward-paragraph)                          (forward-paragraph)
3630                        (>= (point) here))                          (>= (point) here))
3631          (goto-char here)            (goto-char here)
3632          (forward-paragraph))            (forward-paragraph))
3633        (setq end (point-marker)))          (setq end (point-marker)))
3634      (save-excursion        (save-excursion
3635        (unless (c-safe (forward-char)          (unless (c-safe (forward-char)
3636                        (backward-paragraph)                          (backward-paragraph)
3637                        (<= (point) here))                          (<= (point) here))
3638          (goto-char here)            (goto-char here)
3639          (backward-paragraph))            (backward-paragraph))
3640        (setq beg (point)))          (setq beg (point))))
3641    
3642      (unwind-protect      (unwind-protect
3643          (progn          (progn
# Line 2965  command to conveniently insert and align Line 3678  command to conveniently insert and align
3678                               ;; own.  Keep it that way.                               ;; own.  Keep it that way.
3679                               (set-marker end (point))))                               (set-marker end (point))))
3680    
3681                  (if fill-paragraph                  ;; The comment ender should hang.  Replace all space between
3682                      ;; The comment ender should hang.  Replace all                  ;; it and the last word either by one or two 'x's (when
3683                      ;; cruft between it and the last word with one or                  ;; FILL-PARAGRAPH is non-nil), or a row of x's the same width
3684                      ;; two 'x' and include it in the region.  We'll                  ;; as the whitespace (when auto filling), and include it in
3685                      ;; change them back to spaces afterwards.  This                  ;; the region.  We'll change them back to whitespace
3686                      ;; isn't done when auto filling, since that'd                  ;; afterwards.  The effect of this is to glue the comment
3687                      ;; effectively make it impossible to insert extra                  ;; ender to the last word in the comment during filling.
3688                      ;; spaces before the comment ender.                  (let* ((ender-start (save-excursion
3689                      (let* ((ender-start (save-excursion                                        (goto-char (cdr c-lit-limits))
3690                                            (goto-char (cdr c-lit-limits))                                        (skip-syntax-backward "^w ")
3691                                            (skip-syntax-backward "^w ")                                        (point)))
3692                                            (point)))                         (ender-column (save-excursion
3693                             (point-rel (- ender-start here))                                         (goto-char ender-start)
3694                             spaces)                                         (current-column)))
3695                           (point-rel (- ender-start here))
3696                           spaces)
3697    
3698                        (save-excursion                    (save-excursion
3699                          (goto-char (cdr c-lit-limits))                      (goto-char (cdr c-lit-limits))
3700                          (setq tmp-post (point-marker))                      (setq tmp-post (point-marker))
3701                          (insert ?\n)                      (insert ?\n)
3702                          (set-marker end (point))                      (set-marker end (point))
3703                          (forward-line -1)                      (forward-line -1)   ; last line of the comment
3704                          (if (and (looking-at (concat "[ \t]*\\(\\("                      (if (and (looking-at (concat "[ \t]*\\(\\("
3705                                                       c-current-comment-prefix                                                   c-current-comment-prefix
3706                                                       "\\)[ \t]*\\)"))                                                   "\\)[ \t]*\\)"))
3707                                   (eq ender-start (match-end 0)))                               (eq ender-start (match-end 0)))
3708                              ;; The comment ender is prefixed by nothing                          ;; The comment ender is prefixed by nothing
3709                              ;; but a comment line prefix.  Remove it                          ;; but a comment line prefix.  Remove it
3710                              ;; along with surrounding ws.                          ;; along with surrounding ws.
3711                              (setq spaces (- (match-end 1) (match-end 2)))                          (setq spaces (- (match-end 1) (match-end 2)))
3712                            (goto-char ender-start))                        (goto-char ender-start))
3713                          (skip-chars-backward " \t\r\n")                      (skip-chars-backward " \t\r\n") ; Surely this can be
3714                                            ; " \t"? "*/" is NOT alone on the line (ACM, 2005/8/18)
3715    
3716                          (if (/= (point) ender-start)                      (if (/= (point) ender-start)
3717                              (progn                          (progn
3718                                (if (<= here (point))                            (if (<= here (point))
3719                                    ;; Don't adjust point below if it's                                ;; Don't adjust point below if it's
3720                                    ;; before the string we replace.                                ;; before the string we replace.
3721                                    (setq point-rel -1))                                (setq point-rel -1))
3722                                ;; Keep one or two spaces between the                            ;; Keep one or two spaces between the
3723                                ;; text and the ender, depending on how                            ;; text and the ender, depending on how
3724                                ;; many there are now.                            ;; many there are now.
3725                                (unless spaces                            (unless spaces
3726                                  (setq spaces (- ender-start (point))))                              (setq spaces (- ender-column (current-column))))
3727                              (setq auto-fill-spaces (c-delete-and-extract-region
3728                                                      (point) ender-start))
3729                              ;; paragraph filling condenses multiple spaces to
3730                              ;; single or double spaces.  auto-fill doesn't.
3731                              (if fill-paragraph
3732                                (setq spaces                                (setq spaces
3733                                      (max                                      (max
3734                                       (min spaces                                       (min spaces
3735                                            (if sentence-end-double-space 2 1))                                            (if sentence-end-double-space 2 1))
3736                                       1))                                       1)))
3737                                ;; Insert the filler first to keep marks right.                            ;; Insert the filler first to keep marks right.
3738                                (insert-char ?x spaces t)                            (insert-char ?x spaces t)
3739                                (delete-region (point) (+ ender-start spaces))                            (setq hang-ender-stuck spaces)
3740                                (setq hang-ender-stuck spaces)                            (setq point-rel
3741                                (setq point-rel                                  (and (>= point-rel 0)
3742                                      (and (>= point-rel 0)                                       (- (point) (min point-rel spaces)))))
3743                                           (- (point) (min point-rel spaces)))))                        (setq point-rel nil)))
3744                            (setq point-rel nil)))  
3745                      (if point-rel
3746                        (if point-rel                        ;; Point was in the middle of the string we
3747                            ;; Point was in the middle of the string we                        ;; replaced above, so put it back in the same
3748                            ;; replaced above, so put it back in the same                        ;; relative position, counting from the end.
3749                            ;; relative position, counting from the end.                        (goto-char point-rel)))
3750                            (goto-char point-rel)))                  ))
   
                   ;; We're doing auto filling.  Just move the marker  
                   ;; to the comment end to ignore any code after the  
                   ;; comment.  
                   (move-marker end (cdr c-lit-limits)))))  
3751    
3752              (when (<= beg (car c-lit-limits))              (when (<= beg (car c-lit-limits))
3753                ;; The region includes the comment starter.                ;; The region includes the comment starter.
# Line 3068  command to conveniently insert and align Line 3784  command to conveniently insert and align
3784              ;; inside macros is bogus to begin with since the line              ;; inside macros is bogus to begin with since the line
3785              ;; continuation backslashes aren't handled).              ;; continuation backslashes aren't handled).
3786              (save-excursion              (save-excursion
3787                (c-beginning-of-macro)                (c-save-buffer-state ()
3788                (beginning-of-line)                  (c-beginning-of-macro)
3789                (if (> (point) beg)                  (beginning-of-line)
3790                    (setq beg (point)))                  (if (> (point) beg)
3791                (c-end-of-macro)                      (setq beg (point)))
3792                (forward-line)                  (c-end-of-macro)
3793                (if (< (point) end)                  (forward-line)
3794                    (set-marker end (point)))))                  (if (< (point) end)
3795                        (set-marker end (point))))))
3796    
3797             (t                           ; Other code.             (t                           ; Other code.
3798              ;; Try to avoid comments and macros in the paragraph to              ;; Try to avoid comments and macros in the paragraph to
# Line 3192  Warning: Regexp from `c-comment-prefix-r Line 3909  Warning: Regexp from `c-comment-prefix-r
3909            (goto-char tmp-post)            (goto-char tmp-post)
3910            (skip-syntax-backward "^w ")            (skip-syntax-backward "^w ")
3911            (forward-char (- hang-ender-stuck))            (forward-char (- hang-ender-stuck))
3912            (insert-char ?\  hang-ender-stuck t)            (if (or fill-paragraph (not auto-fill-spaces))
3913                  (insert-char ?\  hang-ender-stuck t)
3914                (insert auto-fill-spaces)
3915                (setq here (- here (- hang-ender-stuck (length auto-fill-spaces)))))
3916            (delete-char hang-ender-stuck)            (delete-char hang-ender-stuck)
3917            (goto-char here))            (goto-char here))
3918          (set-marker tmp-post nil))          (set-marker tmp-post nil))
# Line 3233  Optional prefix ARG means justify paragr Line 3953  Optional prefix ARG means justify paragr
3953  (defun c-do-auto-fill ()  (defun c-do-auto-fill ()
3954    ;; Do automatic filling if not inside a context where it should be    ;; Do automatic filling if not inside a context where it should be
3955    ;; ignored.    ;; ignored.
   ;;  
   ;; This function does not do any hidden buffer changes.  
3956    (let ((c-auto-fill-prefix    (let ((c-auto-fill-prefix
3957           ;; The decision whether the line should be broken is actually           ;; The decision whether the line should be broken is actually
3958           ;; done in c-indent-new-comment-line, which do-auto-fill           ;; done in c-indent-new-comment-line, which do-auto-fill
# Line 3274  If a fill prefix is specified, it overri Line 3992  If a fill prefix is specified, it overri
3992          (c-lit-limits c-lit-limits)          (c-lit-limits c-lit-limits)
3993          (c-lit-type c-lit-type)          (c-lit-type c-lit-type)
3994          (c-macro-start c-macro-start))          (c-macro-start c-macro-start))
3995      (when (not (eq c-auto-fill-prefix t))  
3996        ;; Called from do-auto-fill.      (c-save-buffer-state ()
3997        (unless c-lit-limits        (when (not (eq c-auto-fill-prefix t))
3998          (setq c-lit-limits (c-literal-limits nil nil t)))          ;; Called from do-auto-fill.
3999        (unless c-lit-type          (unless c-lit-limits
4000          (setq c-lit-type (c-literal-type c-lit-limits)))            (setq c-lit-limits (c-literal-limits nil nil t)))
4001        (if (memq (cond ((c-query-and-set-macro-start) 'cpp)          (unless c-lit-type
4002                        ((null c-lit-type) 'code)            (setq c-lit-type (c-literal-type c-lit-limits)))
4003                        (t c-lit-type))          (if (memq (cond ((c-query-and-set-macro-start) 'cpp)
4004                  c-ignore-auto-fill)                          ((null c-lit-type) 'code)
4005            (setq fill-prefix t)          ; Used as flag in the cond.                          (t c-lit-type))
4006          (if (and (null c-auto-fill-prefix)                    c-ignore-auto-fill)
4007                   (eq c-lit-type 'c)              (setq fill-prefix t)        ; Used as flag in the cond.
4008                   (<= (c-point 'bol) (car c-lit-limits)))            (if (and (null c-auto-fill-prefix)
4009              ;; The adaptive fill function has generated a prefix, but                     (eq c-lit-type 'c)
4010              ;; we're on the first line in a block comment so it'll be                     (<= (c-point 'bol) (car c-lit-limits)))
4011              ;; wrong.  Ignore it to guess a better one below.                ;; The adaptive fill function has generated a prefix, but
4012              (setq fill-prefix nil)                ;; we're on the first line in a block comment so it'll be
4013            (when (and (eq c-lit-type 'c++)                ;; wrong.  Ignore it to guess a better one below.
4014                       (not (string-match "\\`[ \t]*//" (or fill-prefix ""))))                (setq fill-prefix nil)
4015              ;; Kludge: If the function that adapted the fill prefix              (when (and (eq c-lit-type 'c++)
4016              ;; doesn't produce the required comment starter for line                         (not (string-match (concat "\\`[ \t]*"
4017              ;; comments, then we ignore it.                                                    c-line-comment-starter)
4018              (setq fill-prefix nil)))                                            (or fill-prefix ""))))
4019          ))                ;; Kludge: If the function that adapted the fill prefix
4020                  ;; doesn't produce the required comment starter for line
4021                  ;; comments, then we ignore it.
4022                  (setq fill-prefix nil)))
4023              )))
4024    
4025      (cond ((eq fill-prefix t)      (cond ((eq fill-prefix t)
4026             ;; A call from do-auto-fill which should be ignored.             ;; A call from do-auto-fill which should be ignored.
4027             )             )
# Line 3306  If a fill prefix is specified, it overri Line 4029  If a fill prefix is specified, it overri
4029             ;; A fill-prefix overrides anything.             ;; A fill-prefix overrides anything.
4030             (funcall do-line-break)             (funcall do-line-break)
4031             (insert-and-inherit fill-prefix))             (insert-and-inherit fill-prefix))
4032            ((progn            ((c-save-buffer-state ()
4033               (unless c-lit-limits               (unless c-lit-limits
4034                 (setq c-lit-limits (c-literal-limits)))                 (setq c-lit-limits (c-literal-limits)))
4035               (unless c-lit-type               (unless c-lit-type
# Line 3440  When point is inside a comment, continue Line 4163  When point is inside a comment, continue
4163  comment prefix (see the `c-comment-prefix-regexp' and  comment prefix (see the `c-comment-prefix-regexp' and
4164  `c-block-comment-prefix' variables for details).  The end of a  `c-block-comment-prefix' variables for details).  The end of a
4165  C++-style line comment doesn't count as inside it."  C++-style line comment doesn't count as inside it."
4166    
4167    (interactive "*")    (interactive "*")
4168    (let* ((c-lit-limits (c-literal-limits nil nil t))    (let* (c-lit-limits c-lit-type
          (c-lit-type (c-literal-type c-lit-limits))  
4169           (c-macro-start c-macro-start))           (c-macro-start c-macro-start))
4170      (if (or (eq c-lit-type 'c)  
4171              (and (eq c-lit-type 'c++)      (if (c-save-buffer-state ()
4172                   (< (save-excursion            (setq c-lit-limits (c-literal-limits nil nil t)
4173                        (skip-chars-forward " \t")                  c-lit-type (c-literal-type c-lit-limits))
4174                        (point))            (or (eq c-lit-type 'c)
4175                      (1- (cdr (setq c-lit-limits                (and (eq c-lit-type 'c++)
4176                                     (c-collect-line-comments c-lit-limits))))))                     (< (save-excursion
4177              (and (or (not (looking-at "\\s *$"))                          (skip-chars-forward " \t")
4178                       (eq (char-before) ?\\))                          (point))
4179                   (c-query-and-set-macro-start)                        (1- (cdr (setq c-lit-limits (c-collect-line-comments
4180                   (<= (save-excursion                                                     c-lit-limits))))))
4181                         (goto-char c-macro-start)                (and (or (not (looking-at "\\s *$"))
4182                         (if (looking-at c-opt-cpp-start)                         (eq (char-before) ?\\))
4183                             (goto-char (match-end 0)))                     (c-query-and-set-macro-start)
4184                         (point))                     (<= (save-excursion
4185                      (point))))                           (goto-char c-macro-start)
4186                             (if (looking-at c-opt-cpp-start)
4187                                 (goto-char (match-end 0)))
4188                             (point))
4189                           (point)))))
4190    
4191          (let ((comment-multi-line t)          (let ((comment-multi-line t)
4192                (fill-prefix nil))                (fill-prefix nil))
4193            (c-indent-new-comment-line nil t))            (c-indent-new-comment-line nil t))
4194    
4195        (delete-horizontal-space)        (delete-horizontal-space)
4196        (newline)        (newline)
4197    
4198        ;; c-indent-line may look at the current indentation, so let's        ;; c-indent-line may look at the current indentation, so let's
4199        ;; start out with the same indentation as the previous line.        ;; start out with the same indentation as the previous line.
4200        (let ((col (save-excursion        (let ((col (save-excursion
# Line 3473  C++-style line comment doesn't count as Line 4203  C++-style line comment doesn't count as
4203                                 (= (forward-line -1) 0)))                                 (= (forward-line -1) 0)))
4204                     (current-indentation))))                     (current-indentation))))
4205          (indent-to col))          (indent-to col))
4206    
4207        (indent-according-to-mode))))        (indent-according-to-mode))))
4208    
4209  (defun c-context-open-line ()  (defun c-context-open-line ()

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.42

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26