-;;; align --- align text to a specific column, by regexp
+;;; align.el --- align text to a specific column, by regexp
-;; Copyright (C) 1999, 2000 Free Sofware Foundation
+;; Copyright (C) 1999, 2000, 2002, 2003, 2004,
+;; 2005, 2006 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@gnu.org>
;; Keywords: convenience languages lisp
-;; X-URL: http://www.emacs.org/~johnw/emacs.html
;; This file is part of GNU Emacs.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
(defgroup align nil
"Align text to a specific column, by regexp."
+ :version "21.1"
:group 'fill)
;;; User Variables:
:type '(repeat symbol)
:group 'align)
-(defcustom align-dq-string-modes (append align-lisp-modes
- align-c++-modes
- align-perl-modes)
+(defcustom align-dq-string-modes
+ (append align-lisp-modes align-c++-modes align-perl-modes
+ '(python-mode))
"*A list of modes where double quoted strings should be excluded."
:type '(repeat symbol)
:group 'align)
-(defcustom align-sq-string-modes align-perl-modes
+(defcustom align-sq-string-modes
+ (append align-perl-modes '(python-mode))
"*A list of modes where single quoted strings should be excluded."
:type '(repeat symbol)
:group 'align)
-(defcustom align-open-comment-modes (append align-lisp-modes
- align-c++-modes
- align-perl-modes
- '(makefile-mode))
+(defcustom align-open-comment-modes
+ (append align-lisp-modes align-c++-modes align-perl-modes
+ '(python-mode makefile-mode))
"*A list of modes with a single-line comment syntax.
These are comments as in Lisp, which have a beginning but, end with
the line (i.e., `comment-end' is an empty string)."
regexp function)))))))
"The `type' form for any `align-rules-list' variable.")
-(unless (functionp 'c-guess-basic-syntax)
- (autoload 'c-guess-basic-syntax "cc-engine"))
-
(defcustom align-rules-list
`((lisp-second-arg
(regexp . "\\(^\\s-+[^( \t\n]\\|(\\(\\S-+\\)\\s-+\\)\\S-+\\(\\s-+\\)")
(looking-at
"\\(goto\\|return\\|new\\|delete\\|throw\\)"))
(if (and (boundp 'font-lock-mode) font-lock-mode)
- (eq (cadr (memq 'face (text-properties-at (point))))
+ (eq (get-text-property (point) 'face)
'font-lock-comment-face)
(eq (caar (c-guess-basic-syntax)) 'c))))))))
(modes . align-perl-modes)
(tab-stop . nil))
+ (python-assignment
+ (regexp . ,(concat "[^=!<> \t\n]\\(\\s-*\\)="
+ "\\(\\s-*\\)\\([^>= \t\n]\\|$\\)"))
+ (group . (1 2))
+ (modes . '(python-mode))
+ (tab-stop . nil))
+
(make-assignment
(regexp . "^\\s-*\\w+\\(\\s-*\\):?=\\(\\s-*\\)\\([^\t\n \\\\]\\|$\\)")
(group . (1 2))
(repeat . t)
(modes . align-c++-modes)
(run-if . ,(function (lambda () current-prefix-arg))))
-; (valid
-; . ,(function
-; (lambda ()
-; (memq (caar (c-guess-basic-syntax))
-; '(brace-list-intro
-; brace-list-entry
-; brace-entry-open))))))
+ ; (valid
+ ; . ,(function
+ ; (lambda ()
+ ; (memq (caar (c-guess-basic-syntax))
+ ; '(brace-list-intro
+ ; brace-list-entry
+ ; brace-entry-open))))))
;; With a prefix argument, comma delimiter will be aligned. Since
;; perl-mode doesn't give us enough syntactic information (and we
;; don't do our own parsing yet), this rule is too destructive to
;; run normally.
- (perl-comma-delimiter
+ (basic-comma-delimiter
(regexp . ",\\(\\s-*\\)[^# \t\n]")
(repeat . t)
- (modes . align-perl-modes)
+ (modes . (append align-perl-modes '(python-mode)))
(run-if . ,(function (lambda () current-prefix-arg))))
(c++-comment
(goto-char (match-beginning 1))
(not (bolp)))))))
- (c-macro-line-continuation
- (regexp . "\\(\\s-*\\)\\\\$")
- (modes . (append align-c++-modes '(makefile-mode)))
- (column . c-backslash-column))
-; (valid
-; . ,(function
-; (lambda ()
-; (memq (caar (c-guess-basic-syntax))
-; '(cpp-macro cpp-macro-cont))))))
-
(c-chain-logic
(regexp . "\\(\\s-*\\)\\(&&\\|||\\|\\<and\\>\\|\\<or\\>\\)")
(modes . align-c++-modes)
(goto-char (match-end 2))
(looking-at "\\s-*\\(#\\|$\\)"))))))
+ (python-chain-logic
+ (regexp . "\\(\\s-*\\)\\(\\<and\\>\\|\\<or\\>\\)")
+ (modes . '(python-mode))
+ (valid . ,(function
+ (lambda ()
+ (save-excursion
+ (goto-char (match-end 2))
+ (looking-at "\\s-*\\(#\\|$\\|\\\\\\)"))))))
+
+ (c-macro-line-continuation
+ (regexp . "\\(\\s-*\\)\\\\$")
+ (modes . align-c++-modes)
+ (column . c-backslash-column))
+ ; (valid
+ ; . ,(function
+ ; (lambda ()
+ ; (memq (caar (c-guess-basic-syntax))
+ ; '(cpp-macro cpp-macro-cont))))))
+
+ (basic-line-continuation
+ (regexp . "\\(\\s-*\\)\\\\$")
+ (modes . '(python-mode makefile-mode)))
+
(tex-record-separator
(regexp . ,(function
(lambda (end reverse)
;; With a numeric prefix argument, or C-u, space delimited text
;; tables will be aligned.
(text-column
- (regexp . "\\(^\\|\\S-\\)\\(\\s-+\\)\\(\\S-\\|$\\)")
+ (regexp . "\\(^\\|\\S-\\)\\([ \t]+\\)\\(\\S-\\|$\\)")
(group . 2)
(modes . align-text-modes)
(repeat . t)
(justify . t)
(run-if . ,(function
(lambda ()
- (eq '- current-prefix-arg))))))
- "*An list describing all of the available alignment rules.
+ (eq '- current-prefix-arg)))))
+
+ (css-declaration
+ (regexp . "^\\s-*\\w+:\\(\\s-*\\).*;")
+ (group . (1))
+ (modes . '(css-mode html-mode))))
+ "*A list describing all of the available alignment rules.
The format is:
((TITLE
containing alphabetic character, sometimes you may want
the search to proceed case-insensitively (for languages
that ignore case, such as pascal for example). In that
- case, set `case-fold' to nil, and the regular expression
- search will ignore case. If `regexp' is set to a
- function, that function must handle the job of ignoring
+ case, set `case-fold' to a non-nil value, and the regular
+ expression search will ignore case. If `regexp' is set to
+ a function, that function must handle the job of ignoring
case by itself.
`tab-stop' If the `tab-stop' attribute is set, and non-nil, the
(regexp . "^\\s-*#\\s-*\\(if\\w*\\|endif\\)\\(.*\\)$")
(group . 2)
(modes . align-c++-modes)))
- "*An list describing text that should be excluded from alignment.
+ "*A list describing text that should be excluded from alignment.
See the documentation for `align-rules-list' for more info."
:type align-exclude-rules-list-type
:group 'align)
(interactive "r")
(let ((separator
(or separate
- (if (symbolp align-region-separate)
+ (if (and (symbolp align-region-separate)
+ (boundp align-region-separate))
(symbol-value align-region-separate)
align-region-separate)
'entire)))
region, call `align-regexp' and type in that regular expression."
(interactive
(append
- (list (min (point) (mark))
- (max (point) (mark)))
+ (list (region-beginning) (region-end))
(if current-prefix-arg
(list (read-string "Complex align using regexp: "
"\\(\\s-*\\)")
- (string-to-int
+ (string-to-number
(read-string
"Parenthesis group to modify (justify if negative): " "1"))
- (string-to-int
+ (string-to-number
(read-string "Amount of spacing (or column if negative): "
(number-to-string align-default-spacing)))
(y-or-n-p "Repeat throughout line? "))
default alignment rules that would have been used to identify the text
to be colored."
(interactive
- (list (min (mark) (point))
- (max (mark) (point))
+ (list (region-beginning) (region-end)
(completing-read
"Title of rule to highlight: "
(mapcar
(setq align-highlight-overlays
(cdr align-highlight-overlays))))
+;;;###autoload
+(defun align-newline-and-indent ()
+ "A replacement function for `newline-and-indent', aligning as it goes."
+ (interactive)
+ (let ((separate (or (if (and (symbolp align-region-separate)
+ (boundp align-region-separate))
+ (symbol-value align-region-separate)
+ align-region-separate)
+ 'entire))
+ (end (point)))
+ (call-interactively 'newline-and-indent)
+ (save-excursion
+ (forward-line -1)
+ (while (not (or (bobp)
+ (align-new-section-p (point) end separate)))
+ (forward-line -1))
+ (align (point) end))))
+
;;; Internal Functions:
(defun align-match-tex-pattern (regexp end &optional reverse)
(unless change
(goto-char (cdar a))
(if ecol
- (if (not (= ecol (current-column)))
+ (if (/= ecol (current-column))
(setq change t))
(setq ecol (current-column))))
(when justify
(goto-char (caar a))
(if (and (re-search-forward "\\s-*" (cdar a) t)
- (not (= (point) (cdar a))))
+ (/= (point) (cdar a)))
(let ((bcol (current-column)))
(setcdr (car a) (cons (point-marker) (cdar a)))
(goto-char (cdr (cdar a)))
;; `align-region', all we have to do here is indent.
(unless change
- (setq change (and ecol (not (= col ecol)))))
+ (setq change (and ecol (/= col ecol))))
(when (or func change)
(while areas
(cond ((< gocol 0) t) ; don't do anything
((= cur gocol) t) ; don't need to
((< cur gocol) ; just add space
+ ;; FIXME: It is stated above that "...the
+ ;; whitespace to be modified was already
+ ;; deleted by `align-region', all we have
+ ;; to do here is indent." However, this
+ ;; doesn't seem to be true, so we first
+ ;; delete the whitespace to avoid tabs
+ ;; after spaces.
+ (delete-horizontal-space t)
(indent-to gocol))
(t
;; This code works around an oddity in the
;; are, if it's a very large region being
;; aligned
(if report
- (message
- "Aligning `%s' [rule %d of %d] (%d%%)..."
- (symbol-name (car rule))
- rule-index rule-count
- (/ (* (- (point) real-beg) 100)
- (- end-mark real-beg))))
+ (let ((symbol (car rule)))
+ (if (and symbol (symbolp symbol))
+ (message
+ "Aligning `%s' (rule %d of %d) %d%%..."
+ (symbol-name symbol) rule-index rule-count
+ (/ (* (- (point) real-beg) 100)
+ (- end-mark real-beg)))
+ (message
+ "Aligning %d%%..."
+ (/ (* (- (point) real-beg) 100)
+ (- end-mark real-beg))))))
;; if the search ended us on the beginning of
;; the next line, move back to the end of the
(run-hooks 'align-load-hook)
+;;; arch-tag: ef79cccf-1db8-4888-a8a1-d7ce2d1532f7
;;; align.el ends here