emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master dcb6a2e 03/40: align: Support guessing/setting alignment r


From: Daiki Ueno
Subject: [elpa] master dcb6a2e 03/40: align: Support guessing/setting alignment rules
Date: Fri, 22 Jan 2016 22:48:34 +0000

branch: master
commit dcb6a2e379b58da6318ba80c15c3a23042227fee
Author: Daiki Ueno <address@hidden>
Commit: Daiki Ueno <address@hidden>

    align: Support guessing/setting alignment rules
---
 README.md             |   14 +-
 gobject-align.el      |  720 +++++++++++++++++++++++++------------------------
 gobject-minor-mode.el |   16 +-
 gobject-snippet.el    |    8 +-
 4 files changed, 390 insertions(+), 368 deletions(-)

diff --git a/README.md b/README.md
index a3d21d0..ece29fa 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
 gobject-minor-mode
 ======
 
-In the C coding style widely used in GNOME, identifiers are written in
-camel case and function arguments are aligned to the right end.  That
-makes it a bit cumbersome to keep your code consistent with the style
-with ordinary editor commands.
+In the C coding style commonly used in GNOME, identifiers are written
+in camel case and function arguments are aligned to the right end.
+That makes it a bit cumbersome to keep your code consistent with the
+style, even with align.el or plugins like yasnippet.
 
 gobject-minor-mode is an Emacs minor mode intended to help editing C
 source code in that style.  It mainly provides two features: text
@@ -27,9 +27,11 @@ Usage
 
 | Key         | Command                                           |
 --------------|---------------------------------------------------|
+| C-c C-g g   | Guess alignment columns from region               |
+| C-c C-g s   | Set alignment column to point                     |
 | C-c C-g a   | Align argument list at point                      |
-| C-c C-g f   | Align function declarations in the current region |
+| C-c C-g r   | Align function declarations in the current region |
 | C-c C-g c   | Insert ```module_object```                        |
 | C-c C-g C   | Insert ```MODULE_OBJECT```                        |
 | C-c C-g C-c | Insert ```ModuleObject```                         |
-| C-c C-g s   | Insert custom snippets                            |
+| C-c C-g s   | Insert custom snippet                             |
diff --git a/gobject-align.el b/gobject-align.el
index 4ab82c0..be25a10 100644
--- a/gobject-align.el
+++ b/gobject-align.el
@@ -1,5 +1,5 @@
-;;; gobject-align.el --- GObject C code alignment
-;; Copyright (C) 2010,2011 Daiki Ueno <address@hidden>
+;; gobject-align.el --- GObject-style alignment -*- lexical-binding: t; -*-
+;; Copyright (C) 2016 Daiki Ueno <address@hidden>
 
 ;; Author: Daiki Ueno <address@hidden>
 ;; Keywords: GObject, C, coding style
@@ -23,399 +23,415 @@
 ;;; Code:
 
 (require 'cc-mode)
-(require 'regexp-opt)
+(require 'cl-lib)
 
-(defvar gobject-align-whitespace
-  " \f\t\n\r\v")
+(defvar gobject-align-max-column 80)
 
-(defvar gobject-align-max-line-width 80)
+(defvar gobject-align-identifier-start-column nil)
+(make-variable-buffer-local 'gobject-align-identifier-start-column)
 
-(defun gobject-align--make-arg (type-start type-end arg-name-start 
arg-name-end)
-  (vector type-start type-end arg-name-start arg-name-end))
+(defvar gobject-align-arglist-start-column nil)
+(make-variable-buffer-local 'gobject-align-arglist-start-column)
 
-(defun gobject-align--arg-type-start (arg)
-  (aref arg 0))
+(defvar gobject-align-arglist-identifier-start-column nil)
+(make-variable-buffer-local 'gobject-align-arglist-identifier-start-column)
 
-(defun gobject-align--arg-arg-name-start (arg)
-  (aref arg 2))
+(cl-defstruct (gobject-align--argument
+              (:constructor nil)
+              (:constructor gobject-align--make-argument (type-start
+                                                          type-end
+                                                          identifier-start
+                                                          identifier-end))
+              (:copier nil)
+              (:predicate nil))
+  (type-start nil :read-only t)
+  (type-end nil :read-only t)
+  (identifier-start nil :read-only t)
+  (identifier-end nil :read-only t))
 
-(defun gobject-align--arg-type-width (arg)
-  (- (gobject-align--arg-arg-name-start arg)
-     (gobject-align--arg-type-start arg)))
+(defun gobject-align--marker-column (marker)
+  (save-excursion
+    (goto-char marker)
+    (current-column)))
 
-(defun gobject-align--arglist-type-column-width (arglist)
-  (let ((width 0)
-       length)
-    (while arglist
-      (setq length (gobject-align--arg-type-width (car arglist)))
-      (if (> length width)
-         (setq width length))
-      (setq arglist (cdr arglist)))
-    width))
+(defun gobject-align--indent-to-column (column)
+  ;; Prefer 'char **foo' than 'char ** foo'
+  (when (looking-back "\*+" nil t)
+    (setq column (- column (- (match-end 0) (match-beginning 0))))
+    (goto-char (match-beginning 0)))
+  (let (indent-tabs-mode)
+    (indent-to-column column)))
 
-(defun gobject-align--arglist-arg-name-column-width (arglist)
+(defun gobject-align--argument-type-width (arg)
+  (- (gobject-align--marker-column (gobject-align--argument-type-end arg))
+     (gobject-align--marker-column (gobject-align--argument-type-start arg))))
+
+(defun gobject-align--arglist-identifier-start-column (arglist start-column)
+  (let ((column start-column)
+       argument-column)
+    (dolist (argument arglist)
+      (setq argument-column (+ start-column
+                              (gobject-align--argument-type-width argument)))
+      (when (gobject-align--argument-identifier-start argument)
+       (save-excursion
+         (goto-char (gobject-align--argument-identifier-start argument))
+         (when (eq (preceding-char) ? )
+           (setq argument-column (1+ argument-column)))))
+      (when (> argument-column column)
+       (setq column argument-column)))
+    column))
+
+(defun gobject-align--argument-identifier-width (argument)
+  (if (gobject-align--argument-identifier-start argument)
+      (- (gobject-align--marker-column
+         (gobject-align--argument-identifier-end argument))
+        (gobject-align--marker-column
+         (gobject-align--argument-identifier-start argument)))
+    0))
+
+(defun gobject-align--arglist-identifier-width (arglist)
   (let ((width 0)
-       length)
-    (while arglist
-      (setq length (- (aref (car arglist) 3) ;arg-name-end
-                     (gobject-align--arg-arg-name-start (car arglist))))
-      (if (> length width)
-         (setq width length))
-      (setq arglist (cdr arglist)))
+       argument-width)
+    (dolist (argument arglist)
+      (setq argument-width (gobject-align--argument-identifier-width argument))
+      (when (> argument-width width)
+       (setq width argument-width)))
     width))
 
+(defun gobject-align--normalize-arglist (beg end)
+  (save-excursion
+    (save-restriction
+      (narrow-to-region beg end)
+      (goto-char (point-min))
+      (while (re-search-forward "\\s-+" nil t)
+       (replace-match " "))
+      (goto-char (point-min))
+      (while (re-search-forward "\\s-*," nil t)
+       (replace-match ",\n"))
+      (goto-char (point-min))
+      (delete-trailing-whitespace)
+      ;; Remove whitespace at the beginning of line
+      (goto-char (point-min))
+      (while (re-search-forward "^\\s-+" nil t)
+       (replace-match ""))
+      ;; Remove empty lines
+      (goto-char (point-min))
+      (delete-matching-lines "^$"))))
+
 (defun gobject-align--parse-arglist (beg end)
   (save-excursion
     (save-restriction
       (narrow-to-region beg end)
       (let (type-start
            type-end
-           arg-name-start
-           arg-name-end
-           arg
+           identifier-start
+           identifier-end
            arglist
-           point)
-       (goto-char (point-min))
-       (while (and (not (eobp))
-                   (setq type-start (point-marker))
-                   (if (prog1 (re-search-forward
-                               (concat
-                                "["
-                                (regexp-quote gobject-align-whitespace)
-                                "]*,["
-                                (regexp-quote gobject-align-whitespace)
-                                "]*")
-                               nil 'noerror)
-                         (setq point (point)))
-                       (goto-char (match-beginning 0))
-                     (goto-char (point-max))))
-         (setq arg-name-end (point-marker))
-         (c-backward-token-1)
-         (setq arg-name-start (point-marker))
-         (skip-chars-backward (concat gobject-align-whitespace "*"))
-         (setq type-end (point-marker))
-         (setq arg (gobject-align--make-arg type-start type-end
-                                            arg-name-start arg-name-end)
-               arglist (cons arg arglist))
-         (goto-char point))
+           last-token-start
+           c)
+       (goto-char (point-max))
+       (while (not (bobp))
+         (c-backward-syntactic-ws)
+         (setq identifier-end (point-marker))
+         ;; Array argument, such as 'int a[]'
+         (if (eq (preceding-char) ?\])
+             (c-backward-sexp))
+         (c-backward-token-2)
+         (setq identifier-start (point-marker))
+         (c-backward-syntactic-ws)
+         (if (or (bobp) (eq (preceding-char) ?,))
+             ;; Identifier is omitted, or '...'.
+             (setq type-start identifier-start
+                   type-end identifier-end
+                   identifier-start nil
+                   identifier-end nil)
+           (setq type-end (point-marker)
+                 last-token-start type-end)
+           (while (and (not (bobp))
+                       (progn
+                         (c-backward-token-2)
+                         (unless (eq (setq c (char-after)) ?,)
+                           (setq last-token-start (point-marker)))))
+             (c-backward-syntactic-ws))
+           (setq type-start last-token-start))
+         (push (gobject-align--make-argument type-start type-end
+                                             identifier-start identifier-end)
+               arglist))
        arglist))))
 
-(defun gobject-align--make-func-decl (type-start type-end
-                                                func-name-start func-name-end
-                                                arglist-start arglist-end
-                                                func-decl-end
-                                                arglist)
-  (vector type-start type-end func-name-start func-name-end
-         arglist-start arglist-end func-decl-end arglist))
-
-(defun gobject-align--func-decl-start (func-decl)
-  (aref func-decl 0))
-
-(defun gobject-align--func-decl-func-name-start (func-decl)
-  (aref func-decl 2))
-
-(defun gobject-align--func-decl-func-name-end (func-decl)
-  (aref func-decl 3))
-
-(defun gobject-align--func-decl-arglist-start (func-decl)
-  (aref func-decl 4))
-
-(defun gobject-align--func-decl-arglist-end (func-decl)
-  (aref func-decl 5))
-
-(defun gobject-align--func-decl-end (func-decl)
-  (aref func-decl 6))
-
-(defun gobject-align--func-decl-arglist (func-decl)
-  (aref func-decl 7))
-
-(defun gobject-align--func-decl-type-width (func-decl)
-  (- (gobject-align--func-decl-func-name-start func-decl)
-     (gobject-align--func-decl-start func-decl)))
-
-(defun gobject-align--func-decl-func-name-width (func-decl)
-  (- (gobject-align--func-decl-arglist-start func-decl)
-     (gobject-align--func-decl-func-name-start func-decl)))
-
-(defun gobject-align--func-decls-type-column-width (func-decls)
-  (let ((width 0)
-       length)
-    (while func-decls
-      (setq length (gobject-align--func-decl-type-width (car func-decls)))
-      (if (> length width)
-         (setq width length))
-      (setq func-decls (cdr func-decls)))
-    width))
-
-(defun gobject-align--func-decls-func-name-column-width (func-decls
-                                                        start-column
-                                                        arglist-column-width)
-  (let ((width 0)
-       length)
-    (while func-decls
-      (setq length (gobject-align--func-decl-func-name-width (car func-decls)))
-
-      (if (and (<= (+ start-column
-                     length
-                     arglist-column-width)
-                  gobject-align-max-line-width)
-              (> length width))
-         (setq width length))
-      (setq func-decls (cdr func-decls)))
-    width))
-
-(defun gobject-align--func-decls-arglist-type-column-width (func-decls)
-  (let ((width 0)
-       arglist-type-column-width)
-    (while func-decls
-      (setq arglist-type-column-width
-           (gobject-align--arglist-type-column-width
-            (gobject-align--func-decl-arglist (car func-decls))))
-      (if (> arglist-type-column-width width)
-         (setq width arglist-type-column-width))
-      (setq func-decls (cdr func-decls)))
-    width))
-
-(defun gobject-align--func-decls-arglist-arg-name-column-width (func-decls)
+;;;###autoload
+(defun gobject-align-at-point (&optional identifier-start-column)
+  "Reformat argument list at point, aligning argument to the right end."
+  (interactive)
+  (save-excursion
+    (let* (start-column arglist)
+      (cl-destructuring-bind (beg end)
+         (gobject-align--arglist-region-at-point (point))
+       (goto-char beg)
+       (setq start-column (current-column))
+       (save-restriction
+         (narrow-to-region beg end)
+         (setq arglist (gobject-align--parse-arglist (point-min) (point-max)))
+         (gobject-align--normalize-arglist (point-min) (point-max))
+         (unless identifier-start-column
+           (setq identifier-start-column
+                 (gobject-align--arglist-identifier-start-column arglist 0)))
+         (dolist (argument arglist)
+           (goto-char (gobject-align--argument-type-start argument))
+           (let ((column (if (bobp) 0 start-column)))
+             (when (not (bobp))
+               (gobject-align--indent-to-column start-column))
+             (when (gobject-align--argument-identifier-start argument)
+               (setq column (+ column identifier-start-column))
+               (goto-char (gobject-align--argument-identifier-start argument))
+               (gobject-align--indent-to-column column)))))))))
+
+(cl-defstruct (gobject-align--decl
+              (:constructor nil)
+              (:constructor gobject-align--make-decl (start
+                                                      end
+                                                      identifier-start
+                                                      identifier-end
+                                                      arglist-start
+                                                      arglist-end
+                                                      arglist))
+              (:copier nil)
+              (:predicate nil))
+  (start nil :read-only t)
+  (end nil :read-only t)
+  (identifier-start nil :read-only t)
+  (identifier-end nil :read-only t)
+  (arglist-start nil :read-only t)
+  (arglist-end nil :read-only t)
+  (arglist nil :read-only t))
+
+(defun gobject-align--decls-identifier-start-column (decls start-column)
+  (let ((column start-column)
+       decl-column)
+    (dolist (decl decls)
+      (setq decl-column (+ start-column
+                          (gobject-align--marker-column
+                           (gobject-align--decl-identifier-start decl))))
+      (when (and (<= decl-column gobject-align-max-column)
+                (> decl-column column))
+       (setq column decl-column)))
+    column))
+
+(defun gobject-align--decl-identifier-width (decl)
+  (- (gobject-align--marker-column
+      (gobject-align--decl-identifier-end decl))
+     (gobject-align--marker-column
+      (gobject-align--decl-identifier-start decl))))
+
+(defun gobject-align--decls-arglist-start-column (decls start-column)
+  (let ((column start-column)
+       decl-column
+       (arglist-width
+        (+ (gobject-align--decls-arglist-identifier-start-column decls 0)
+           (gobject-align--decls-arglist-identifier-width decls)
+           (length ");"))))
+    (dolist (decl decls)
+      (setq decl-column (+ start-column
+                          (gobject-align--decl-identifier-width decl)))
+      (when (and (<= (+ decl-column arglist-width)
+                    gobject-align-max-column)
+                (> decl-column column))
+       (setq column decl-column)))
+    (1+ column)))
+
+(defun gobject-align--decls-arglist-identifier-width (decls)
   (let ((width 0)
-       arglist-arg-name-column-width)
-    (while func-decls
-      (setq arglist-arg-name-column-width
-           (gobject-align--arglist-arg-name-column-width
-            (gobject-align--func-decl-arglist (car func-decls))))
-      (if (> arglist-arg-name-column-width width)
-         (setq width arglist-arg-name-column-width))
-      (setq func-decls (cdr func-decls)))
+       decl-width)
+    (dolist (decl decls)
+      (setq decl-width (gobject-align--arglist-identifier-width
+                       (gobject-align--decl-arglist decl)))
+      (when (> decl-width width)
+       (setq width decl-width)))
     width))
 
-(defun gobject-align--parse-func-decl (beg end)
-  ;; Parse one func-decl in BEG END.  BEG and END must point to the
-  ;; beginning/end of the func-decl.
+(defun gobject-align--decls-arglist-identifier-start-column (decls 
start-column)
+  (let ((column start-column)
+       decl-column)
+    (dolist (decl decls)
+      (setq decl-column (gobject-align--arglist-identifier-start-column
+                        (gobject-align--decl-arglist decl)
+                        start-column))
+      ;; FIXME: should wrap lines inside argument list?
+      (when (> decl-column column)
+       (setq column decl-column)))
+    column))
+
+(defun gobject-align--parse-decl (beg end)
+  ;; Parse at most one func declaration found in BEG END.
   (save-excursion
     (save-restriction
       (narrow-to-region beg end)
-      (goto-char (point-max))
       (let (arglist-start
            arglist-end
-           func-name-start
-           func-name-end)
-       ;; foo *bar (baz a) G_GNUC_CONST;
-       ;;                              ^
-       (unless (looking-back (concat "["
-                                     (regexp-quote gobject-align-whitespace)
-                                     "]*\\(?:[A-Z_]*\\>["
-                                     (regexp-quote gobject-align-whitespace)
-                                     "]*\\)*["
-                                     (regexp-quote gobject-align-whitespace)
-                                     "]*;["
-                                     (regexp-quote gobject-align-whitespace)
-                                     "]*")
-                             nil
-                             t)
-         (error "No func-decl at point"))
-       (goto-char (match-beginning 0))
-       ;; foo *bar (baz a) G_GNUC_CONST;
-       ;;                ^
-       (unless (eq (char-before) ?\))
-         (error "No arglist at point"))
-       (setq arglist-end (point-marker))
-       (c-backward-sexp)               ;skip arglist
-       ;; foo *bar (baz a) G_GNUC_CONST;
-       ;;          ^
-       (setq arglist-start (point-marker))
-       (skip-chars-backward gobject-align-whitespace)
-       ;; foo *bar (baz a) G_GNUC_CONST;
-       ;;        ^
-       (setq func-name-end (point-marker))
-       ;;(c-backward-token-2)
-       (c-backward-sexp)               ;may be either an identifier
-                                       ;or a pointer
-       ;; foo *bar (baz a) G_GNUC_CONST;
-       ;;      ^
-       (setq func-name-start (point-marker))
-       (skip-chars-backward (concat gobject-align-whitespace "*"))
-       ;; foo *bar (baz a) G_GNUC_CONST;
-       ;;   ^
-       (gobject-align--make-func-decl (point-min-marker) (point-marker)
-                                      func-name-start func-name-end
-                                      arglist-start arglist-end
-                                      (point-max-marker)
-                                      (gobject-align--parse-arglist
-                                       (1+ arglist-start)
-                                       (1- arglist-end)))))))
-
-(defun gobject-align--normalize-arglist (beg end)
+           identifier-start
+           identifier-end)
+       (goto-char (point-min))
+       (c-forward-syntactic-ws)
+       (unless (looking-at "typedef\\|#")
+         (while (and (not (eobp))
+                     (not (eq (char-after) ?\()))
+           (c-forward-token-2)
+           (c-forward-syntactic-ws))
+         (when (eq (char-after) ?\()
+           (setq arglist-start (point-marker))
+           (c-backward-syntactic-ws)
+           (setq identifier-end (point-marker))
+           (c-backward-token-2)
+           (setq identifier-start (point-marker))
+           (goto-char arglist-start)
+           (c-forward-sexp)
+           (setq arglist-end (point-marker))
+           (gobject-align--make-decl beg end
+                                     identifier-start identifier-end
+                                     arglist-start arglist-end
+                                     (gobject-align--parse-arglist
+                                      (1+ arglist-start)
+                                      (1- arglist-end)))))))))
+
+(defun gobject-align--normalize-decl (beg end)
   (save-excursion
     (save-restriction
       (narrow-to-region beg end)
       (goto-char (point-min))
-      (while (re-search-forward (concat "["
-                                       (regexp-quote gobject-align-whitespace)
-                                       "]+")
-                               nil t)
+      (while (re-search-forward "\n" (1- (point-max)) t)
        (replace-match " "))
       (goto-char (point-min))
-      (while (re-search-forward " *, *" nil t)
-       (replace-match ",\n")))))
+      (while (re-search-forward "\\s-+" nil t)
+       (replace-match " ")))))
 
-(defun gobject-align--normalize-func-decl (beg end)
+(defun gobject-align--arglist-region-at-point (point)
+  (save-excursion
+    (let (start)
+      (goto-char point)
+      (c-beginning-of-statement-1)
+      (c-backward-syntactic-ws)
+      (unless (eq ?\( (preceding-char))
+       (error "No containing argument list"))
+      (setq start (point))
+      (backward-char)
+      (condition-case nil
+         (c-forward-sexp)
+       (error
+        (error "No closing parenthesis")))
+      (backward-char)
+      (list start (point)))))
+
+;;;###autoload
+(defun gobject-align-set-column (symbol)
+  "Set alignment column of SYMBOL."
+  (interactive
+   (let ((symbol-name (completing-read "Symbol to change: "
+                                      '("identifier-start"
+                                        "arglist-start"
+                                        "arglist-identifier-start")
+                                      nil t)))
+     (list (intern (format "gobject-align-%s-column" symbol-name)))))
+  (set symbol (current-column)))
+
+(defun gobject-align--scan-decls (beg end)
   (save-excursion
     (save-restriction
       (narrow-to-region beg end)
       (goto-char (point-min))
-      (while (re-search-forward (concat "["
-                                       (regexp-quote gobject-align-whitespace)
-                                       "]+")
-                               nil t)
-       (replace-match " ")))))
-
-(defun gobject-align--indent-identifier-to-column (column)
-  (when (looking-back "\*+" nil t)
-    (setq column (- column (- (match-end 0) (match-beginning 0))))
-    (goto-char (match-beginning 0)))
-  (let (indent-tabs-mode)
-    (indent-to-column column)))
-
-(defun gobject-align--expand-region-to-arglist-extent (beg end)
-  (setq beg (save-excursion
-             (goto-char beg)
-             (c-beginning-of-decl-1)
-             (point))
-       end (save-excursion
-             (goto-char end)
-             (c-end-of-decl-1)
-             (point)))
-  (unless (and (eq (char-before beg) ?\()
-              (eq (char-after end) ?\)))
-    (error "No arglist around point"))
-  (list beg end))
-
-(defun gobject-align-arglist-region (beg end &optional type-column-width)
-  "Reformat argument list in the region between BEG and END.
-It applies proper alignment rule."
-  (interactive (apply #'gobject-align--expand-region-to-arglist-extent
-                     (if (region-active-p)
-                         (list (region-beginning) (region-end))
-                       (list (point) (point)))))
-  (save-excursion
-    (let ((indent-level (progn (goto-char beg) (current-column)))
-         arg
-         arglist
-         column)
-      (save-restriction
-       (narrow-to-region beg end)
-       (setq arglist (gobject-align--parse-arglist (point-min) (point-max)))
-       ;; This may move markers in arglist.
-       (gobject-align--normalize-arglist (point-min) (point-max))
-       (unless type-column-width
-         (setq type-column-width (gobject-align--arglist-type-column-width
-                                  arglist)))
-       (while arglist
-         (setq arg (car arglist))
-         (goto-char (gobject-align--arg-type-start arg))
-         (if (bobp)
-             (setq column 0)
-           (setq column indent-level))
-         (gobject-align--indent-identifier-to-column column)
-         ;; Don't indent for no-arg-name arg.
-         (unless (= (gobject-align--arg-type-start arg)
-                    (gobject-align--arg-arg-name-start arg))
-           (setq column (+ column type-column-width))
-           (goto-char (gobject-align--arg-arg-name-start arg))
-           (gobject-align--indent-identifier-to-column column))
-         (setq arglist (cdr arglist)))))))
-
-(defun gobject-align-func-decls-region (beg end)
-  "Reformat function declarations in the region between BEG and END.
-It applies proper alignment rule."
+      (let (decls)
+       (while (not (eobp))
+         (let (decl-start decl-end decl)
+           (c-forward-syntactic-ws)
+           (setq decl-start (point-marker))
+           (c-end-of-statement)
+           (setq decl-end (point-marker))
+           (setq decl (gobject-align--parse-decl decl-start decl-end))
+           (when decl
+             (push decl decls))))
+       decls))))
+
+(defun gobject-align--guess-columns (beg end)
+  (let ((buffer (current-buffer))
+       decls)
+    (with-temp-buffer
+      (insert-buffer-substring-no-properties buffer beg end)
+      (c-mode)
+      (setq decls (gobject-align--scan-decls (point-min) (point-max)))
+      (dolist (decl decls)
+       (gobject-align--normalize-decl (gobject-align--decl-start decl)
+                                      (gobject-align--decl-end decl)))
+      (let* ((identifier-start-column
+             (gobject-align--decls-identifier-start-column
+              decls 0))
+            (arglist-start-column
+             (gobject-align--decls-arglist-start-column
+              decls identifier-start-column))
+            (arglist-identifier-start-column
+             (gobject-align--decls-arglist-identifier-start-column
+              decls arglist-start-column)))
+       (message
+        "identifier-start: %d, arglist-start: %d, arglist-identifier-start: %d"
+        identifier-start-column
+        arglist-start-column
+        arglist-identifier-start-column)
+       (list (cons 'identifier-start-column
+                   identifier-start-column)
+             (cons 'arglist-start-column
+                   arglist-start-column)
+             (cons 'arglist-identifier-start-column
+                   arglist-identifier-start-column))))))
+
+;;;###autoload
+(defun gobject-align-guess-columns (beg end)
+  "Guess the alignment rule from the function declarations in BEG and END"
+  (interactive "r")
+  (let ((columns (gobject-align--guess-columns beg end)))
+    (setq gobject-align-identifier-start-column
+         (cdr (assq 'identifier-start-column columns))
+         gobject-align-arglist-start-column
+         (cdr (assq 'arglist-start-column columns))
+         gobject-align-arglist-identifier-start-column
+         (cdr (assq 'arglist-identifier-start-column columns)))))
+
+;;;###autoload
+(defun gobject-align-region (beg end)
+  "Reformat function declarations in the region between BEG and END."
   (interactive "r")
   (save-excursion
-    (let ((indent-level (save-excursion
-                         (goto-char beg)
-                         (skip-chars-forward gobject-align-whitespace)
-                         (current-column)))
-         func-decl-end
-         func-decl
-         func-decls
-         pointer
-         func-name-width
-         type-column-width
-         func-name-column-width
-         arglist-type-column-width
-         arglist-arg-name-column-width
-         arglist-column-width
-         column)
+    (let (decls)
       (save-restriction
        (narrow-to-region beg end)
-       (goto-char (point-min))
-       (while (search-forward ";" nil t)
-         ;; XXX: Should skip non-func-decl statements.
-         (setq func-decl-end (point-marker))
-         (c-beginning-of-statement-1)
-         (setq func-decl (gobject-align--parse-func-decl (point-marker)
-                                                         func-decl-end)
-               func-decls (cons func-decl func-decls))
-         (goto-char func-decl-end))
-       ;; This may move markers in func-decls.
-       (setq pointer func-decls)
-       (while pointer
-         (setq func-decl (car pointer))
-         (gobject-align--normalize-func-decl
-          (gobject-align--func-decl-start func-decl)
-          (gobject-align--func-decl-end func-decl))
-         (setq pointer (cdr pointer)))
-       (setq type-column-width
-             (gobject-align--func-decls-type-column-width func-decls)
-             arglist-type-column-width
-             (gobject-align--func-decls-arglist-type-column-width func-decls)
-             arglist-arg-name-column-width
-             (gobject-align--func-decls-arglist-arg-name-column-width
-              func-decls)
-             arglist-column-width
-             (+ arglist-type-column-width
-                arglist-arg-name-column-width
-                3)                     ;(length "();")
-             func-name-column-width
-             (gobject-align--func-decls-func-name-column-width
-              func-decls
-              (+ indent-level
-                 type-column-width)
-              arglist-column-width))
-       (setq pointer func-decls)
-       (while pointer
-         (setq func-decl (car pointer))
-         (goto-char (gobject-align--func-decl-start func-decl))
-         (setq column indent-level)
-         (gobject-align--indent-identifier-to-column column)
-         ;; Align type column.
-         (setq func-name-width
-               (- (gobject-align--func-decl-func-name-end func-decl)
-                  (gobject-align--func-decl-func-name-start func-decl)))
-         (if (> (+ column type-column-width func-name-width)
-                gobject-align-max-line-width)
-             (setq column
-                   (+ column
-                      (gobject-align--func-decl-type-width func-decl)))
-           (setq column (+ column type-column-width)))
-         (goto-char (gobject-align--func-decl-func-name-start func-decl))
-         (gobject-align--indent-identifier-to-column column)
-         ;; Align func-name column.
-         (when (> (- (gobject-align--func-decl-func-name-end func-decl)
-                     (point))
-                  func-name-column-width)
-           (goto-char (gobject-align--func-decl-func-name-end func-decl))
-           (insert "\n")
-           (setq column (+ indent-level type-column-width)))
-         (setq column (+ column func-name-column-width))
-         (goto-char (gobject-align--func-decl-arglist-start func-decl))
-         (gobject-align--indent-identifier-to-column column)
-         ;; Align arglist.
-         (gobject-align-arglist-region
-          (1+ (point-marker))
-          (1- (gobject-align--func-decl-arglist-end
-               func-decl))
-          arglist-type-column-width)
-         (setq pointer (cdr pointer)))))))
+       (unless (and gobject-align-identifier-start-column
+                    gobject-align-arglist-start-column
+                    gobject-align-arglist-identifier-start-column)
+         (let ((columns (gobject-align--guess-columns beg end)))
+           (unless gobject-align-identifier-start-column
+             (setq gobject-align-identifier-start-column
+                   (cdr (assq 'identifier-start-column columns))))
+           (unless gobject-align-arglist-start-column
+             (setq gobject-align-arglist-start-column
+                   (cdr (assq 'arglist-start-column columns))))
+           (unless gobject-align-arglist-identifier-start-column
+             (setq gobject-align-arglist-identifier-start-column
+                   (cdr (assq 'arglist-identifier-start-column columns))))))
+       (setq decls (gobject-align--scan-decls beg end))
+       (dolist (decl decls)
+         (gobject-align--normalize-decl (gobject-align--decl-start decl)
+                                        (gobject-align--decl-end decl)))
+       (dolist (decl decls)
+         (goto-char (gobject-align--decl-identifier-start decl))
+         (gobject-align--indent-to-column
+          gobject-align-identifier-start-column)
+         (goto-char (gobject-align--decl-identifier-end decl))
+         (when (> (current-column) gobject-align-arglist-start-column)
+           (insert "\n"))
+         (goto-char (gobject-align--decl-arglist-start decl))
+         (gobject-align--indent-to-column
+          gobject-align-arglist-start-column)
+         (forward-char)
+         (gobject-align-at-point
+          (- gobject-align-arglist-identifier-start-column
+             gobject-align-arglist-start-column)))))))
 
 (provide 'gobject-align)
 
diff --git a/gobject-minor-mode.el b/gobject-minor-mode.el
index f61bfc6..dee08a8 100644
--- a/gobject-minor-mode.el
+++ b/gobject-minor-mode.el
@@ -1,5 +1,5 @@
-;;; gobject-minor-mode.el --- minor mode for editing GObject-based C source 
code
-;; Copyright (C) 2010,2011,2016 Daiki Ueno <address@hidden>
+;;; gobject-minor-mode.el --- minor mode for editing GObject-style C source 
code -*- lexical-binding: t; -*-
+;; Copyright (C) 2016 Daiki Ueno <address@hidden>
 
 ;; Author: Daiki Ueno <address@hidden>
 ;; Keywords: GObject, C, coding style
@@ -22,8 +22,10 @@
 
 ;;; Code:
 
-(autoload 'gobject-align-arglist-region "gobject-align")
-(autoload 'gobject-align-func-decls-region "gobject-align")
+(autoload 'gobject-align-at-point "gobject-align")
+(autoload 'gobject-align-region "gobject-align")
+(autoload 'gobject-align-set-column "gobject-align")
+(autoload 'gobject-align-guess-columns "gobject-align")
 (autoload 'gobject-snippet-insert-package_class "gobject-snippet")
 (autoload 'gobject-snippet-insert-PACKAGE_CLASS "gobject-snippet")
 (autoload 'gobject-snippet-insert-PackageClass "gobject-snippet")
@@ -39,8 +41,10 @@
 
 (defvar gobject-minor-mode-map
   (let ((keymap (make-sparse-keymap)))
-    (define-key keymap "\C-c\C-ga" 'gobject-align-arglist-region)
-    (define-key keymap "\C-c\C-gf" 'gobject-align-func-decls-region)
+    (define-key keymap "\C-c\C-ga" 'gobject-align-at-point)
+    (define-key keymap "\C-c\C-gr" 'gobject-align-region)
+    (define-key keymap "\C-c\C-gf" 'gobject-align-set-column)
+    (define-key keymap "\C-c\C-gg" 'gobject-align-guess-columns)
     (define-key keymap "\C-c\C-gc" 'gobject-snippet-insert-package_class)
     (define-key keymap "\C-c\C-gC" 'gobject-snippet-insert-PACKAGE_CLASS)
     (define-key keymap "\C-c\C-g\C-c" 'gobject-snippet-insert-PackageClass)
diff --git a/gobject-snippet.el b/gobject-snippet.el
index cbf4fa6..f7dfd44 100644
--- a/gobject-snippet.el
+++ b/gobject-snippet.el
@@ -1,4 +1,4 @@
-;;; gobject-snippet.el --- GObject C code generation
+;;; gobject-snippet.el --- GObject code generation -*- lexical-binding: t; -*-
 ;; Copyright (C) 2016 Daiki Ueno <address@hidden>
 
 ;; Author: Daiki Ueno <address@hidden>
@@ -311,7 +311,7 @@ static GObject *
 guint n_construct_properties,
 GObjectConstructParam *construct_properties")
     (funcall (if gobject-snippet-align-arglist
-                #'gobject-align-arglist-region
+                #'gobject-align-region
               #'indent-region)
             arglist-start (point))
     (insert ")\n")
@@ -342,7 +342,7 @@ guint prop_id,
 const GValue *value,
 GParamSpec *pspec")
     (funcall (if gobject-snippet-align-arglist
-                #'gobject-align-arglist-region
+                #'gobject-align-region
               #'indent-region)
             arglist-start (point))
     (insert ")\n")
@@ -378,7 +378,7 @@ guint prop_id,
 GValue *value,
 GParamSpec *pspec")
     (funcall (if gobject-snippet-align-arglist
-                #'gobject-align-arglist-region
+                #'gobject-align-region
               #'indent-region)
             arglist-start (point))
     (insert ")\n")



reply via email to

[Prev in Thread] Current Thread [Next in Thread]