From dcb6a2e379b58da6318ba80c15c3a23042227fee Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Sat, 16 Jan 2016 16:40:44 +0900 Subject: [PATCH] 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 a3d21d049..ece29faf5 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 4ab82c0ad..be25a100a 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 +;; gobject-align.el --- GObject-style alignment -*- lexical-binding: t; -*- +;; Copyright (C) 2016 Daiki Ueno ;; Author: Daiki Ueno ;; 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 f61bfc696..dee08a821 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 +;;; gobject-minor-mode.el --- minor mode for editing GObject-style C source code -*- lexical-binding: t; -*- +;; Copyright (C) 2016 Daiki Ueno ;; Author: Daiki Ueno ;; 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 cbf4fa616..f7dfd44d7 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 ;; Author: Daiki Ueno @@ -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") -- 2.39.2