Roy Smith <[EMAIL PROTECTED]> wrote on Wed, 31 Aug 2005 19:50:01 -0400:
> In article <[EMAIL PROTECTED]>, Alan Mackenzie <[EMAIL PROTECTED]> wrote:
>> And if you're not a Lisp hacker (or can't be bothered), say so, and I'll
>> throw some code together for you.

> Wow.  An offer I can't refuse.  Thanks!

OK, here goes!  Put the code into your .emacs.  Both the functions here
get byte compiled (they'll be getting called a _lot_).  To hook up to
your CC Mode, do one of:

(a) If you're a hooker:
  (add-hook 'c-special-indent-hook 'rs-LOCK-reindent)

(b) If you're a touch more stylish:
  Put a line like this into your style definition:
(c-special-indent-hook . rs-LOCK-reindent)

Here's the code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun rs-back-to-LOCK-p ()
  "Search backwards for the LOCK keyword.  If we find it, leave point there
and return non-`nil'.  If we don't find it, return nil, and point is left
undefined."
  (let (in-lit target)
    (while (and (search-backward-regexp "^[ \t]*\\(LOCK[ \t]*(\\)" nil t)
                (setq target (match-beginning 1))
                (setq in-lit (c-in-literal))))
    (when (and target (not in-lit))
      (goto-char target)
      t)))
(byte-compile 'rs-back-to-LOCK-p)

(defun rs-LOCK-reindent ()
  "Function to reindent lines inside and around blocks of lines delimited by
the macros LOCK and END_LOCK, as follows:

1   LOCK (mydatalock)
2       *myData++ = foo;
3       Data_count += 1;
4   END_LOCK
5   do_something_else ();

NOTE:  There are no semicolons terminating the LOCK/END_LOCK lines."
  ;; Another note: c-syntactic-context is bound to the s.c. for the current
  ;; line.
  (let (org-indent new-indent stmt-dpair)
    (save-excursion
      (save-match-data
        (setq org-indent (progn (back-to-indentation) (current-column))
              new-indent org-indent)
        (cond
         ;; L4?
         ((looking-at "END_LOCK")
          (if (rs-back-to-LOCK-p)
            (setq new-indent (current-column))))
         ((setq stmt-dpair (assq 'statement-cont c-syntactic-context))
          (goto-char (if (consp (cdr stmt-dpair))
                         (cadr stmt-dpair) ; cc-mode >= 5.30
                       (cdr stmt-dpair))) ; cc-mode 5.28
          (cond
           ;; L5?
           ((looking-at "END_LOCK\\>\\([^_]\\|$\\)")
            (if (rs-back-to-LOCK-p)
                (setq new-indent (current-column))))
           ;; L2?
           ((looking-at "LOCK[ \t]")
            (setq new-indent (+ (current-column) c-basic-offset)))))
         ;; L3?
         ((and (assq 'statement c-syntactic-context)
               ;; (eq (c-beginning-of-statement-1) 'previous) ; Needs >= 5.30
               (progn (c-beginning-of-statement-1)
                      (looking-at "LOCK[ \t]+(")))
          (setq new-indent (+ (current-column) c-basic-offset))))))
    (c-shift-line-indentation (- new-indent org-indent))))
(byte-compile 'rs-LOCK-reindent)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Just one thing - the code as it stands might not handle labels properly.
I mean, you've not got any goto's in the C code, have you?  Certainly not
in critical sections.  ;-)

Let me know how you get on!

-- 
Alan Mackenzie (Munich, Germany)
Email: [EMAIL PROTECTED]; to decode, wherever there is a repeated letter
(like "aa"), remove half of them (leaving, say, "a").

_______________________________________________
Help-gnu-emacs mailing list
Help-gnu-emacs@gnu.org
http://lists.gnu.org/mailman/listinfo/help-gnu-emacs

Reply via email to