root/trunk/lisp/align.el

Revision 4220, 53.6 kB (checked in by miyoshi, 8 months ago)

Sync up with Emacs22.2.

  • Property svn:eol-style set to LF
Line 
1 ;;; align.el --- align text to a specific column, by regexp
2
3 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
4 ;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
6 ;; Author: John Wiegley <johnw@gnu.org>
7 ;; Maintainer: FSF
8 ;; Keywords: convenience languages lisp
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 ;;; Commentary:
28
29 ;; This mode allows you to align regions in a context-sensitive fashion.
30 ;; The classic use is to align assignments:
31 ;;
32 ;;    int a = 1;
33 ;;    short foo = 2;
34 ;;    double blah = 4;
35 ;;
36 ;; becomes
37 ;;
38 ;;    int    a    = 1;
39 ;;    short  foo  = 2;
40 ;;    double blah = 4;
41
42 ;;; Usage:
43
44 ;; There are several variables which define how certain "categories"
45 ;; of syntax are to be treated.  These variables go by the name
46 ;; `align-CATEGORY-modes'.  For example, "c++" is such a category.
47 ;; There are several rules which apply to c++, but since several other
48 ;; languages have a syntax similar to c++ (e.g., c, java, etc), these
49 ;; modes are treated as belonging to the same category.
50 ;;
51 ;; If you want to add a new mode under a certain category, just
52 ;; customize that list, or add the new mode manually.  For example, to
53 ;; make jde-mode a c++ category mode, use this code in your .emacs
54 ;; file:
55 ;;
56 ;;    (setq align-c++-modes (cons 'jde-mode align-c++-modes))
57
58 ;; In some programming modes, it's useful to have the aligner run only
59 ;; after indentation is performed.  To achieve this, customize or set
60 ;; the variable `align-indent-before-aligning' to t.
61
62 ;;; Module Authors:
63
64 ;; In order to incorporate align's functionality into your own
65 ;; modules, there are only a few steps you have to follow.
66
67 ;;  1. Require or load in the align.el library.
68 ;;
69 ;;  2. Define your alignment and exclusion rules lists, either
70 ;;     customizable or not.
71 ;;
72 ;;  3. In your mode function, set the variables
73 ;;     `align-mode-rules-list' and `align-mode-exclude-rules-list'
74 ;;     to your own rules lists.
75
76 ;; If there is any need to add your mode name to one of the
77 ;; align-?-modes variables (for example, `align-dq-string-modes'), use
78 ;; `add-to-list', or some similar function which checks first to see
79 ;; if the value is already there.  Since the user may customize that
80 ;; mode list, and then write your mode name into their .emacs file,
81 ;; causing the symbol already to be present the next time they load
82 ;; your package.
83
84 ;; Example:
85 ;;
86 ;;   (require 'align)
87 ;;
88 ;;   (defcustom my-align-rules-list
89 ;;     '((my-rule
90 ;;        (regexp . "Sample")))
91 ;;     :type align-rules-list-type
92 ;;     :group 'my-package)
93 ;;
94 ;;   (put 'my-align-rules-list 'risky-local-variable t)
95 ;;
96 ;;   (add-to-list 'align-dq-string-modes 'my-package-mode)
97 ;;   (add-to-list 'align-open-comment-modes 'my-package-mode)
98 ;;
99 ;;   (defun my-mode ()
100 ;;      ...
101 ;;      (setq align-mode-rules-list my-align-rules-list))
102 ;;
103 ;; Note that if you need to install your own exclusion rules, then you
104 ;; will also need to reproduce any double-quoted string, or open
105 ;; comment exclusion rules that are defined in the standard
106 ;; `align-exclude-rules-list'.  At the moment there is no convenient
107 ;; way to mix both mode-local and global rules lists.
108
109 ;;; History:
110
111 ;; Version 1.0 was created in the earlier part of 1996, using a very
112 ;; simple algorithm that understand only basic regular expressions.
113 ;; Parts of the code were broken up and included in vhdl-mode.el
114 ;; around this time.  After several comments from users, and a need to
115 ;; find a more robust, performant algorithm, 2.0 was born in late
116 ;; 1998.  Many different approaches were taken (mostly due to the
117 ;; complexity of TeX tables), but finally a scheme was discovered
118 ;; which worked fairly well for most common usage cases.  Development
119 ;; beyond version 2.8 is not planned, except for problems that users
120 ;; might encounter.
121
122 ;;; Code:
123
124 (defgroup align nil
125   "Align text to a specific column, by regexp."
126   :version "21.1"
127   :group 'fill)
128
129 ;;; User Variables:
130
131 (defcustom align-load-hook nil
132   "*Hook that gets run after the aligner has been loaded."
133   :type 'hook
134   :group 'align)
135
136 (defcustom align-indent-before-aligning nil
137   "*If non-nil, indent the marked region before aligning it."
138   :type 'boolean
139   :group 'align)
140
141 (defcustom align-default-spacing 1
142   "*An integer that represents the default amount of padding to use.
143 If `align-to-tab-stop' is non-nil, this will represent the number of
144 tab stops to use for alignment, rather than the number of spaces.
145 Each alignment rule can optionally override both this variable.  See
146 `align-mode-alist'."
147   :type 'integer
148   :group 'align)
149
150 (defcustom align-to-tab-stop 'indent-tabs-mode
151   "*If non-nil, alignments will always fall on a tab boundary.
152 It may also be a symbol, whose value will be taken."
153   :type '(choice (const nil) symbol)
154   :group 'align)
155
156 (defcustom align-region-heuristic 500
157   "*If non-nil, used as a heuristic by `align-current'.
158 Since each alignment rule can possibly have its own set of alignment
159 sections (whenever `align-region-separate' is non-nil, and not a
160 string), this heuristic is used to determine how far before and after
161 point we should search in looking for a region separator.  Larger
162 values can mean slower perform in large files, although smaller values
163 may cause unexpected behavior at times."
164   :type 'integer
165   :group 'align)
166
167 (defcustom align-highlight-change-face 'highlight
168   "*The face to highlight with if changes are necessary."
169   :type 'face
170   :group 'align)
171
172 (defcustom align-highlight-nochange-face 'secondary-selection
173   "*The face to highlight with if no changes are necessary."
174   :type 'face
175   :group 'align)
176
177 (defcustom align-large-region 10000
178   "*If an integer, defines what constitutes a \"large\" region.
179 If nil,then no messages will ever be printed to the minibuffer."
180   :type 'integer
181   :group 'align)
182
183 (defcustom align-c++-modes '(c++-mode c-mode java-mode)
184   "*A list of modes whose syntax resembles C/C++."
185   :type '(repeat symbol)
186   :group 'align)
187
188 (defcustom align-perl-modes '(perl-mode cperl-mode)
189   "*A list of modes where perl syntax is to be seen."
190   :type '(repeat symbol)
191   :group 'align)
192
193 (defcustom align-lisp-modes
194   '(emacs-lisp-mode lisp-interaction-mode lisp-mode scheme-mode)
195   "*A list of modes whose syntax resembles Lisp."
196   :type '(repeat symbol)
197   :group 'align)
198
199 (defcustom align-tex-modes
200   '(tex-mode plain-tex-mode latex-mode slitex-mode)
201   "*A list of modes whose syntax resembles TeX (and family)."
202   :type '(repeat symbol)
203   :group 'align)
204
205 (defcustom align-text-modes '(text-mode outline-mode)
206   "*A list of modes whose content is plain text."
207   :type '(repeat symbol)
208   :group 'align)
209
210 (defcustom align-dq-string-modes
211   (append align-lisp-modes align-c++-modes align-perl-modes
212           '(python-mode))
213   "*A list of modes where double quoted strings should be excluded."
214   :type '(repeat symbol)
215   :group 'align)
216
217 (defcustom align-sq-string-modes
218   (append align-perl-modes '(python-mode))
219   "*A list of modes where single quoted strings should be excluded."
220   :type '(repeat symbol)
221   :group 'align)
222
223 (defcustom align-open-comment-modes
224   (append align-lisp-modes align-c++-modes align-perl-modes
225           '(python-mode makefile-mode))
226   "*A list of modes with a single-line comment syntax.
227 These are comments as in Lisp, which have a beginning but, end with
228 the line (i.e., `comment-end' is an empty string)."
229   :type '(repeat symbol)
230   :group 'align)
231
232 (defcustom align-region-separate "^\\s-*[{}]?\\s-*$"
233   "*Select the method by which alignment sections will be separated.
234 If this is a symbol, that symbol's value will be used.
235
236 For the sake of clarification, consider the following example, which
237 will be referred to in the descriptions below.
238
239     int alpha = 1; /* one */
240     double beta = 2.0;
241     long gamma; /* ten */
242
243     unsigned int delta = 1; /* one */
244     long double epsilon = 3.0;
245     long long omega; /* ten */
246
247 The possible settings for `align-region-separate' are:
248
249  `entire'  The entire region being aligned will be considered as a
250            single alignment section.  Assuming that comments were not
251            being aligned to a particular column, the example would
252            become:
253
254              int          alpha    = 1;   /* one */
255              double       beta     = 2.0;
256              long         gamma;          /* ten */
257
258              unsigned int delta    = 1;   /* one */
259              long double  epsilon;
260              long long    chi      = 10;  /* ten */
261
262  `group'   Each contiguous set of lines where a specific alignment
263            occurs is considered a section for that alignment rule.
264            Note that each rule will may have any entirely different
265            set of section divisions than another.
266
267              int    alpha = 1; /* one */
268              double beta  = 2.0;
269              long   gamma; /* ten */
270
271              unsigned int delta = 1; /* one */
272              long double  epsilon;
273              long long    chi = 10; /* ten */
274
275  `largest' When contiguous rule sets overlap, the largest section
276            described will be taken as the alignment section for each
277            rule touched by that section.
278
279              int    alpha = 1;   /* one */
280              double beta  = 2.0;
281              long   gamma;       /* ten */
282
283              unsigned int delta    = 1;  /* one */
284              long double  epsilon;
285              long long    chi      = 10; /* ten */
286
287            NOTE: This option is not supported yet, due to algorithmic
288            issues which haven't been satisfactorily resolved.  There
289            are ways to do it, but they're both ugly and resource
290            consumptive.
291
292  regexp    A regular expression string which defines the section
293            divider.  If the mode you're in has a consistent divider
294            between sections, the behavior will be very similar to
295            `largest', and faster.  But if the mode does not use clear
296            separators (for example, if you collapse your braces onto
297            the preceding statement in C or perl), `largest' is
298            probably the better alternative.
299
300  function  A function that will be passed the beginning and ending
301            locations of the region in which to look for the section
302            separator.  At the very beginning of the attempt to align,
303            both of these parameters will be nil, in which case the
304            function should return non-nil if it wants each rule to
305            define its own section, or nil if it wants the largest
306            section found to be used as the common section for all rules
307            that occur there.
308
309  list      A list of markers within the buffer that represent where
310            the section dividers lie.  Be certain to use markers!  For
311            when the aligning begins, the ensuing contract/expanding of
312            whitespace will throw off any non-marker positions.
313
314            This method is intended for use in Lisp programs, and not
315            by the user."
316   :type '(choice
317           (const :tag "Entire region is one section" entire)
318           (const :tag "Align by contiguous groups" group)
319 ;         (const largest)
320           (regexp :tag "Regexp defines section boundaries")
321           (function :tag "Function defines section boundaries"))
322   :group 'align)
323
324 (put 'align-region-separate 'risky-local-variable t)
325
326 (defvar align-rules-list-type
327   '(repeat
328     (cons
329      :tag "Alignment rule"
330      (symbol :tag "Title")
331      (cons :tag "Required attributes"
332            (cons :tag "Regexp"
333                  (const :tag "(Regular expression to match)" regexp)
334                  (choice :value "\\(\\s-+\\)" regexp function))
335            (repeat
336             :tag "Optional attributes"
337             (choice
338              (cons :tag "Repeat"
339                    (const :tag "(Repeat this rule throughout line)"
340                           repeat)
341                    (boolean :value t))
342              (cons :tag "Paren group"
343                    (const :tag "(Parenthesis group to use)" group)
344                    (choice :value 2
345                            integer (repeat integer)))
346              (cons :tag "Modes"
347                    (const :tag "(Modes where this rule applies)" modes)
348                    (sexp :value (text-mode)))
349              (cons :tag "Case-fold"
350                    (const :tag "(Should case be ignored for this rule)"
351                           case-fold)
352                    (boolean :value t))
353              (cons :tag "To Tab Stop"
354                    (const :tag "(Should rule align to tab stops)"
355                           tab-stop)
356                    (boolean :value nil))
357              (cons :tag "Valid"
358                    (const :tag "(Return non-nil if rule is valid)"
359                           valid)
360                    (function :value t))
361              (cons :tag "Run If"
362                    (const :tag "(Return non-nil if rule should run)"
363                           run-if)
364                    (function :value t))
365              (cons :tag "Column"
366                    (const :tag "(Column to fix alignment at)" column)
367                    (choice :value comment-column
368                            integer symbol))
369              (cons :tag "Spacing"
370                    (const :tag "(Amount of spacing to use)" spacing)
371                    (integer :value 1))
372              (cons :tag "Justify"
373                    (const :tag "(Should text be right justified)"
374                           justify)
375                    (boolean :value t))
376              ;; make sure this stays up-to-date with any changes
377              ;; in `align-region-separate'
378              (cons :tag "Separate"
379                    (const :tag "(Separation to use for this rule)"
380                           separate)
381                    (choice :value "^\\s-*$"
382                            (const entire)
383                            (const group)
384 ;                          (const largest)
385                            regexp function)))))))
386   "The `type' form for any `align-rules-list' variable.")
387
388 (defcustom align-rules-list
389   `((lisp-second-arg
390      (regexp   . "\\(^\\s-+[^( \t\n]\\|(\\(\\S-+\\)\\s-+\\)\\S-+\\(\\s-+\\)")
391      (group    . 3)
392      (modes    . align-lisp-modes)
393      (run-if   . ,(function (lambda () current-prefix-arg))))
394
395     (lisp-alist-dot
396      (regexp   . "\\(\\s-*\\)\\.\\(\\s-*\\)")
397      (group    . (1 2))
398      (modes    . align-lisp-modes))
399
400     (open-comment
401      (regexp   . ,(function
402                    (lambda (end reverse)
403                      (funcall (if reverse 're-search-backward
404                                 're-search-forward)
405                               (concat "[^ \t\n\\\\]"
406                                       (regexp-quote comment-start)
407                                       "\\(.+\\)$") end t))))
408      (modes    . align-open-comment-modes))
409
410     (c-macro-definition
411      (regexp   . "^\\s-*#\\s-*define\\s-+\\S-+\\(\\s-+\\)")
412      (modes    . align-c++-modes))
413
414     (c-variable-declaration
415      (regexp   . ,(concat "[*&0-9A-Za-z_]>?[&*]*\\(\\s-+[*&]*\\)"
416                           "[A-Za-z_][0-9A-Za-z:_]*\\s-*\\(\\()\\|"
417                           "=[^=\n].*\\|(.*)\\|\\(\\[.*\\]\\)*\\)?"
418                           "\\s-*[;,]\\|)\\s-*$\\)"))
419      (group    . 1)
420      (modes    . align-c++-modes)
421      (justify  . t)
422      (valid
423       . ,(function
424           (lambda ()
425             (not (or (save-excursion
426                        (goto-char (match-beginning 1))
427                        (backward-word 1)
428                        (looking-at
429                         "\\(goto\\|return\\|new\\|delete\\|throw\\)"))
430                      (if (and (boundp 'font-lock-mode) font-lock-mode)
431                          (eq (get-text-property (point) 'face)
432                              'font-lock-comment-face)
433                        (eq (caar (c-guess-basic-syntax)) 'c))))))))
434
435     (c-assignment
436      (regexp   . ,(concat "[^-=!^&*+<>/| \t\n]\\(\\s-*[-=!^&*+<>/|]*\\)"
437                           "=\\(\\s-*\\)\\([^= \t\n]\\|$\\)"))
438      (group    . (1 2))
439      (modes    . align-c++-modes)
440      (justify  . t)
441      (tab-stop . nil))
442
443     (perl-assignment
444      (regexp   . ,(concat "[^=!^&*-+<>/| \t\n]\\(\\s-*\\)=[~>]?"
445                           "\\(\\s-*\\)\\([^>= \t\n]\\|$\\)"))
446      (group    . (1 2))
447      (modes    . align-perl-modes)
448      (tab-stop . nil))
449
450     (python-assignment
451      (regexp   . ,(concat "[^=!<> \t\n]\\(\\s-*\\)="
452                           "\\(\\s-*\\)\\([^>= \t\n]\\|$\\)"))
453      (group    . (1 2))
454      (modes    . '(python-mode))
455      (tab-stop . nil))
456
457     (make-assignment
458      (regexp   . "^\\s-*\\w+\\(\\s-*\\):?=\\(\\s-*\\)\\([^\t\n \\\\]\\|$\\)")
459      (group    . (1 2))
460      (modes    . '(makefile-mode))
461      (tab-stop . nil))
462
463     (c-comma-delimiter
464      (regexp   . ",\\(\\s-*\\)[^/ \t\n]")
465      (repeat   . t)
466      (modes    . align-c++-modes)
467      (run-if   . ,(function (lambda () current-prefix-arg))))
468                                         ;      (valid
469                                         ;       . ,(function
470                                         ;         (lambda ()
471                                         ;           (memq (caar (c-guess-basic-syntax))
472                                         ;                 '(brace-list-intro
473                                         ;                   brace-list-entry
474                                         ;                   brace-entry-open))))))
475
476     ;; With a prefix argument, comma delimiter will be aligned.  Since
477     ;; perl-mode doesn't give us enough syntactic information (and we
478     ;; don't do our own parsing yet), this rule is too destructive to
479     ;; run normally.
480     (basic-comma-delimiter
481      (regexp   . ",\\(\\s-*\\)[^# \t\n]")
482      (repeat   . t)
483      (modes    . (append align-perl-modes '(python-mode)))
484      (run-if   . ,(function (lambda () current-prefix-arg))))
485
486     (c++-comment
487      (regexp   . "\\(\\s-*\\)\\(//.*\\|/\\*.*\\*/\\s-*\\)$")
488      (modes    . align-c++-modes)
489      (column   . comment-column)
490      (valid    . ,(function
491                    (lambda ()
492                      (save-excursion
493                        (goto-char (match-beginning 1))
494                        (not (bolp)))))))
495
496     (c-chain-logic
497      (regexp   . "\\(\\s-*\\)\\(&&\\|||\\|\\<and\\>\\|\\<or\\>\\)")
498      (modes    . align-c++-modes)
499      (valid    . ,(function
500                    (lambda ()
501                      (save-excursion
502                        (goto-char (match-end 2))
503                        (looking-at "\\s-*\\(/[*/]\\|$\\)"))))))
504
505     (perl-chain-logic
506      (regexp   . "\\(\\s-*\\)\\(&&\\|||\\|\\<and\\>\\|\\<or\\>\\)")
507      (modes    . align-perl-modes)
508      (valid    . ,(function
509                    (lambda ()
510                      (save-excursion
511                        (goto-char (match-end 2))
512                        (looking-at "\\s-*\\(#\\|$\\)"))))))
513
514     (python-chain-logic
515      (regexp   . "\\(\\s-*\\)\\(\\<and\\>\\|\\<or\\>\\)")
516      (modes    . '(python-mode))
517      (valid    . ,(function
518                    (lambda ()
519                      (save-excursion
520                        (goto-char (match-end 2))
521                        (looking-at "\\s-*\\(#\\|$\\|\\\\\\)"))))))
522
523     (c-macro-line-continuation
524      (regexp   . "\\(\\s-*\\)\\\\$")
525      (modes    . align-c++-modes)
526      (column   . c-backslash-column))
527                                         ;      (valid
528                                         ;       . ,(function
529                                         ;         (lambda ()
530                                         ;           (memq (caar (c-guess-basic-syntax))
531                                         ;                 '(cpp-macro cpp-macro-cont))))))
532
533     (basic-line-continuation
534      (regexp   . "\\(\\s-*\\)\\\\$")
535      (modes    . '(python-mode makefile-mode)))
536
537     (tex-record-separator
538      (regexp . ,(function
539                  (lambda (end reverse)
540                    (align-match-tex-pattern "&" end reverse))))
541      (group    . (1 2))
542      (modes    . align-tex-modes)
543      (repeat   . t))
544
545     (tex-tabbing-separator
546      (regexp   . ,(function
547                    (lambda (end reverse)
548                      (align-match-tex-pattern "\\\\[=>]" end reverse))))
549      (group    . (1 2))
550      (modes    . align-tex-modes)
551      (repeat   . t)
552      (run-if   . ,(function
553                    (lambda ()
554                      (eq major-mode 'latex-mode)))))
555
556     (tex-record-break
557      (regexp   . "\\(\\s-*\\)\\\\\\\\")
558      (modes    . align-tex-modes))
559
560     ;; With a numeric prefix argument, or C-u, space delimited text
561     ;; tables will be aligned.
562     (text-column
563      (regexp   . "\\(^\\|\\S-\\)\\([ \t]+\\)\\(\\S-\\|$\\)")
564      (group    . 2)
565      (modes    . align-text-modes)
566      (repeat   . t)
567      (run-if   . ,(function
568                    (lambda ()
569                      (and current-prefix-arg
570                           (not (eq '- current-prefix-arg)))))))
571
572     ;; With a negative prefix argument, lists of dollar figures will
573     ;; be aligned.
574     (text-dollar-figure
575      (regexp   . "\\$?\\(\\s-+[0-9]+\\)\\.")
576      (modes    . align-text-modes)
577      (justify  . t)
578      (run-if   . ,(function
579                    (lambda ()
580                      (eq '- current-prefix-arg)))))
581
582     (css-declaration
583      (regexp . "^\\s-*\\w+:\\(\\s-*\\).*;")
584      (group . (1))
585      (modes . '(css-mode html-mode))))
586   "*A list describing all of the available alignment rules.
587 The format is:
588
589    ((TITLE
590      (ATTRIBUTE . VALUE) ...)
591     ...)
592
593 The following attributes are meaningful:
594
595 `regexp'    This required attribute must be either a string describing
596             a regular expression, or a function (described below).
597             For every line within the section that this regular
598             expression matches, the given rule will be applied to that
599             line.  The exclusion rules denote which part(s) of the
600             line should not be modified; the alignment rules cause the
601             identified whitespace group to be contracted/expanded such
602             that the \"alignment character\" (the character
603             immediately following the identified parenthesis group),
604             occurs in the same column for every line within the
605             alignment section (see `align-region-separate' for a
606             description of how the region is broken up into alignment
607             sections).
608
609             The `regexp' attribute describes how the text should be
610             treated.  Within this regexp, there must be at least one
611             group of characters (typically whitespace) identified by
612             the special opening and closing parens used in regexp
613             expressions (`\\\\(' and `\\\\)') (see the Emacs manual on
614             the syntax of regular expressions for more info).
615
616             If `regexp' is a function, it will be called as a
617             replacement for `re-search-forward'.  This means that it
618             should return nil if nothing is found to match the rule,
619             or it should set the match data appropriately, move point
620             to the end of the match, and return the value of point.
621
622 `group'     For exclusion rules, the group identifies the range of
623             characters that should be ignored.  For alignment rules,
624             these are the characters that will be deleted/expanded for
625             the purposes of alignment.  The \"alignment character\" is
626             always the first character immediately following this
627             parenthesis group.  This attribute may also be a list of
628             integer, in which case multiple alignment characters will
629             be aligned, with the list of integer identifying the
630             whitespace groups which precede them.  The default for
631             this attribute is 1.
632
633 `modes'     The `modes' attribute, if set, should name a list of
634             major modes -- or evaluate to such a value -- in which the
635             rule is valid.  If not set, the rule will apply to all
636             modes.
637
638 `case-fold' If `regexp' is an ordinary regular expression string
639             containing alphabetic character, sometimes you may want
640             the search to proceed case-insensitively (for languages
641             that ignore case, such as pascal for example).  In that
642             case, set `case-fold' to a non-nil value, and the regular
643             expression search will ignore case.  If `regexp' is set to
644             a function, that function must handle the job of ignoring
645             case by itself.
646
647 `tab-stop'  If the `tab-stop' attribute is set, and non-nil, the
648             alignment character will always fall on a tab stop
649             (whether it uses tabs to get there or not depends on the
650             value of `indent-tabs-mode').  If the `tab-stop' attribute
651             is set to nil, tab stops will never be used.  Otherwise,
652             the value of `align-to-tab-stop' determines whether or not
653             to align to a tab stop.  The `tab-stop' attribute may also
654             be a list of t or nil values, corresponding to the number
655             of parenthesis groups specified by the `group' attribute.
656
657 `repeat'    If the `repeat' attribute is present, and non-nil, the
658             rule will be applied to the line continuously until no
659             further matches are found.
660
661 `valid'     If the `valid' attribute is set, it will be used to
662             determine whether the rule should be invoked.  This form
663             is evaluated after the regular expression match has been
664             performed, so that it is possible to use the results of
665             that match to determine whether the alignment should be
666             performed.  The buffer should not be modified during the
667             evaluation of this form.
668
669 `run-if'    Like `valid', the `run-if' attribute tests whether the
670             rule should be run at all -- even before any searches are
671             done to determine if the rule applies to the alignment
672             region.  This can save time, since `run-if' will only be
673             run once for each rule.  If it returns nil, the rule will
674             not be attempted.
675
676 `column'    For alignment rules, if the `column' attribute is set --
677             which must be an integer, or a symbol whose value is an
678             integer -- it will be used as the column in which to align
679             the alignment character.  If the text on a particular line
680             happens to overrun that column, a single space character,
681             or tab stop (see `align-to-tab-stop') will be added
682             between the last text character and the alignment
683             character.
684
685 `spacing'   Alignment rules may also override the amount of spacing
686             that would normally be used by providing a `spacing'
687             attribute.  This must be an integer, or a list of integers
688             corresponding to the number of parenthesis groups matched
689             by the `group' attribute.  If a list of value is used, and
690             any of those values is nil, `align-default-spacing' will
691             be used for that subgroup.  See `align-default-spacing'
692             for more details on spacing, tab stops, and how to
693             indicate how much spacing should be used.  If TAB-STOP is
694             present, it will override the value of `align-to-tab-stop'
695             for that rule.
696
697 `justify'   It is possible with `regexp' and `group' to identify a
698             character group that contains more than just whitespace
699             characters.  By default, any non-whitespace characters in
700             that group will also be deleted while aligning the
701             alignment character.  However, if the `justify' attribute
702             is set to a non-nil value, only the initial whitespace
703             characters within that group will be deleted.  This has
704             the effect of right-justifying the characters that remain,
705             and can be used for outdenting or just plain old right-
706             justification.
707
708 `separate'  Each rule can define its own section separator, which
709             describes how to identify the separation of \"sections\"
710             within the region to be aligned.  Setting the `separate'
711             attribute overrides the value of `align-region-separate'
712             (see the documentation of that variable for possible
713             values), and any separation argument passed to `align'."
714   :type align-rules-list-type
715   :group 'align)
716
717 (put 'align-rules-list 'risky-local-variable t)
718
719 (defvar align-exclude-rules-list-type
720   '(repeat
721     (cons
722      :tag "Exclusion rule"
723      (symbol :tag "Title")
724      (cons :tag "Required attributes"
725            (cons :tag "Regexp"
726                  (const :tag "(Regular expression to match)" regexp)
727                  (choice :value "\\(\\s-+\\)" regexp function))
728            (repeat
729             :tag "Optional attributes"
730             (choice
731              (cons :tag "Repeat"
732                    (const :tag "(Repeat this rule throughout line)"
733                           repeat)
734                    (boolean :value t))
735              (cons :tag "Paren group"
736                    (const :tag "(Parenthesis group to use)" group)
737                    (choice :value 2
738                            integer (repeat integer)))
739              (cons :tag "Modes"
740                    (const :tag "(Modes where this rule applies)" modes)
741                    (sexp :value (text-mode)))
742              (cons :tag "Case-fold"
743                    (const :tag "(Should case be ignored for this rule)"
744                           case-fold)
745                    (boolean :value t)))))))
746   "The `type' form for any `align-exclude-rules-list' variable.")
747
748 (defcustom align-exclude-rules-list
749   `((exc-dq-string
750      (regexp . "\"\\([^\"\n]+\\)\"")
751      (repeat . t)
752      (modes  . align-dq-string-modes))
753
754     (exc-sq-string
755      (regexp . "'\\([^'\n]+\\)'")
756      (repeat . t)
757      (modes  . align-sq-string-modes))
758
759     (exc-open-comment
760      (regexp
761       . ,(function
762           (lambda (end reverse)
763             (funcall (