;;; mwe:defclass-formatter.el --- formats defclass forms ;;; NOTE: This file has been superseded by Redshank mode ;;; ;; Copyright (C) 2006 Michael Weber ;; Author: Michael Weber ;; Keywords: lisp ;; $Id: mwe-defclass-formatter.el,v 1.7 2007/11/07 14:33:51 michaelw Exp $ ;;; Commentary: ;; Test: ;; Move cursor to beginning of a Common Lisp DEFCLASS form ;; and type M-x mwe:align-defclass-slots RET ;; Issues: ;; * Does not work if slots sexps contain newlines ;; * Does not work well with #+ and #- reader conditionals ;; * Long slot options cause large columns (:documentation ...) ;;; Code: (require 'cl) (defun mwe:end-of-sexp-column () "Move point to end of current form, neglecting trailing whitespace." (forward-sexp) (while (forward-comment +1)) (skip-chars-backward "[:space:]")) (defun mwe:sexp-column-widths () "Return list of column widths for s-expression at point." (down-list) (loop do (while (forward-comment 1)) until (or (looking-at ")") (eobp)) collect (- (- (point) (progn (mwe:end-of-sexp-column) (point)))) finally (up-list))) (defun mwe:align-sexp-columns (column-widths) "Align forms in s-expression according to COLUMN-WIDTHS." (down-list) (loop initially (while (forward-comment +1)) for width in column-widths until (looking-at ")") do (let ((beg (point))) (mwe:end-of-sexp-column) (let ((used (- (point) beg))) (just-one-space (if (looking-at "[[:space:]]*)") 0 (1+ (- width used)))))) finally (up-list))) (defun mwe:max* (&rest args) (reduce #'max args :key (lambda (arg) (or arg 0)))) (defun mwe:align-forms-as-columns (beg end) "Align s-expressions in region in columns. Example: (define-symbol-macro MEM (mem-of *cpu*)) (define-symbol-macro IP (ip-of *cpu*)) (define-symbol-macro STACK (stack-of *cpu*)) is formatted as: (define-symbol-macro MEM (mem-of *cpu*)) (define-symbol-macro IP (ip-of *cpu*)) (define-symbol-macro STACK (stack-of *cpu*))" (interactive "*r") (save-restriction (narrow-to-region beg end) (goto-char beg) (let* ((columns (loop do (while (forward-comment +1)) until (or (looking-at ")") (eobp)) collect (mwe:sexp-column-widths))) (max-column-widths (loop for cols = columns then (mapcar #'cdr cols) while (some #'consp cols) collect (apply #'mwe:max* (mapcar #'car cols))))) (goto-char beg) (loop do (while (forward-comment +1)) until (or (looking-at ")") (eobp)) do (mwe:align-sexp-columns max-column-widths))))) (defun mwe:align-defclass-slots () "Aligns slots of the Common Lisp DEFCLASS form after point. Example (-!- denotes cursor position): -!-(defclass identifier () ((name :reader name-of :initarg :name) (location :reader location-of :initarg :location) (scope :accessor scope-of :initarg :scope) (definition :accessor definition-of :initform nil)) (:default-initargs :scope *current-scope*)) is formatted as: -!-(defclass identifier () ((name :reader name-of :initarg :name) (location :reader location-of :initarg :location) (scope :accessor scope-of :initarg :scope) (definition :accessor definition-of :initform nil)) (:default-initargs :scope *current-scope*))" (interactive "*") (save-excursion (down-list) (cond ((looking-at "defclass") (forward-sexp +3) (let ((end (save-excursion (forward-sexp) (point)))) (mwe:align-forms-as-columns (progn (down-list) (point)) end)))))) (provide 'mwe:defclass-formatter) ;;; mwe:defclass-formatter.el ends here ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; 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., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA.