[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: declare indent for common lisp?
Pascal J. Bourguignon
Re: declare indent for common lisp?
Fri, 01 Aug 2008 23:59:59 +0200
Gnus/5.1008 (Gnus v5.10.8) Emacs/22.2 (gnu/linux)
Joost Kremers <address@hidden> writes:
> hi all,
> in emacs lisp, if i define a macro that is going to take a body of code as
> argument, i generally include a statement such as (declare (indent defun))
> in the macro definition, so that the indentation looks better.
> is there a way to get emacs to do the same thing for macros in common lisp
(defmacro example (a b c &body d) nil)
You could evaluate in emacs: (put 'example 'lisp-indent-function 3)
You could put these forms in the local variable section in your source files,
;; Local Variables:
;; eval: (put 'example 'lisp-indent-function 3)
but this is not convenient.
Insteadn for my Common Lisp symbols, I keep the indentation parameters
in files named lisp.indentations, and I have the following functions
in ~/.emacs to load all the lisp.indentations found in the file system
hierarchy from the current directory up.
(defun cl-indent (symbol num-forms)
Put on the SYMBOL and its lower case and upper case variants
a 'lisp-indent-function property set to NUM-FORMS.
(dolist (property '(lisp-indent-function common-lisp-indent-function))
(put symbol property num-forms)
(put (intern (string-downcase (symbol-name symbol))) property num-forms)
(put (intern (string-upcase (symbol-name symbol))) property num-forms)))
(defun* read* (stream &optional (eof-error-p t) eof-value ignored)
(handler-case (read stream)
(end-of-file (err) (if eof-error-p
(defun %batch-cl-indent (&rest indent-symbols-list)
(dolist (item indent-symbols-list)
(let ((indent (car item)))
(dolist (sym (cdr item))
(cl-indent sym indent)
(let ((p (position (character ":") (symbol-name sym))))
(cl-indent (intern (subseq (symbol-name sym) (1+ p)))
(defmacro* do-directories-up ((var dir-path &optional result) &body body)
DO: Evaluates body with var bound to dir-path, then dir-path's parent,
and so on up to the root directory.
RETURN: The evaluation of the result form.
`(do ((,var ,dir-path
(if (string-match "^\\(.*/\\)[^/]+/$" ,var)
(match-string 1 ,var)
((string-equal "" ,var) ,result)
(defun load-lisp-indentations ()
"Processes a lisp.indentations file,
in the current directory, or in a parent."
(do-directories-up (dir default-directory)
(let ((file (concat dir "lisp.indentations")))
;; (message "file = %S" file)
(when (file-exists-p file)
(let ((count (length (buffer-list)))) ; is there a better way?
(let ((killp (/= count (length (buffer-list)))))
for clause = (read* (current-buffer) nil (current-buffer))
until (eql clause (current-buffer))
do (message "(%%batch-cl-indent '%S)" clause)
do (%batch-cl-indent clause))
(when killp (kill-buffer (current-buffer)))))))))))
;;; -*- mode:lisp -*-
;;; This file is processed by batch-cl-indent
(defun lambda macrolet)
(((&whole 4 &rest (&whole 1 &lambda &body)) &body)
(((&whole 6 1 1 1 1 1 1) (&whole 4 1 1 1 1 1 1) &body)
;; (put 'progn 'lisp-indent-function 0), say, causes progn to be indented
;; like defun if the first form is placed on the next line, otherwise
;; it is indented like any other form (i.e. forms line up under first).
(1 block case catch ccase concatenate
do-all-symbols do-external-symbols do-symbols
dolist dotimes ecase eval-when
if let let*
typecase ctypecase etypecase
prog1 rename-package run-program struct unless
unwind-protect when while with-accessors
with-gensyms with-hash-table-iterator with-input-from-string
with-open-file with-open-stream with-output-to-string
with-standard-io-syntax with-temp-file without-package-lock)
(2 condition-case destructuring-bind do do* multiple-value-bind
multiple-value-setq prog2 with-slots set-dispatch-macro-character
__Pascal Bourguignon__ http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"