[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: An automaton for indenting the lisp code in linear time
From: |
A Soare |
Subject: |
Re: An automaton for indenting the lisp code in linear time |
Date: |
Tue, 1 Jul 2008 04:24:59 +0200 (CEST) |
>
> Maybe it would be good if you explained a bit more how to use the
> example code. (The example code seems to have difficulties with lines
> that have indentation 0.)
>
For all: please report me problems , unconsidered cases, where the indent does
not work. When I wrote it, I tested it on a limited number (little) of examples.
This version works just on the examples that I tested. Today I realised that it
did not work on all the uses of comments.
I attach again here my last version. The automaton is written long time ago,
and yesterday I wrote just the examples: consult the 2 examples to understand.
The examples are just suggestions to understand how it works:
I explain here for all to understand:
1. Put the text of the function you want to indent.
2. Put after the function that you want to indent this code (leave before the
"(let" a space):
(let (indent-lines
state
(l (prog2 (beginning-of-line) (point))))
(save-excursion (lisp-indent-automaton))
indent-lines)
3. Evaluate this . You will get a list L whose (mapcar 'car L) is the correct
indentation.
I believed that there are hackers of lisp here and you see imediately how it
works :)
EXAMPLE:
(defun lisp-indent-automaton (&optional end state indent-what-argument
start-col)
"
an automaton to indent the lisp code
VERSION: NEW
"
(let (
indent
indent-next-line-to
)
(or end (beginning-of-line) (setq end (point)))
(or indent-what-argument
(setq indent-what-argument 0))
(or state (beginning-of-defun))
(and (null start-col) (setq start-col 0))
(catch 'STOP
(while (< (point) end)
(cond ((and (elt state 8)
(not (elt state 4)))
;; inside a string
(and (looking-at "\\s>")
(setq indent-lines (cons (lisp-indent-value) indent-lines)))
(setq state (lisp-indent-next-state))
)
((looking-at "\\s\"")
;; the start of a string
(setq indent (append indent (list :s () (current-column)))
state (lisp-indent-next-state))
)
((looking-at "\\s\(")
;; open a parenthesis
(let ((col (if indent-lines
(+ (current-column) (- (caar indent-lines) (cdar
indent-lines)))
(current-column))))
(setq indent (append indent (list :l () col))
state (lisp-indent-automaton end (lisp-indent-next-state)
(lisp-indent-what-argument)
col)))
)
((looking-at "\\s\)")
;; close a parenthesis
(throw 'STOP (lisp-indent-next-state))
)
((looking-at "\\s ")
;; spaces are ignored
(while (looking-at "[[:blank:]]")
(setq state (lisp-indent-next-state)))
)
((looking-at "\\sw\\|\\s_")
;; a function or a parameter
(let* ((col (if indent-lines
(+ (current-column) (- (caar indent-lines) (cdar
indent-lines)))
(current-column)))
r
(w (catch 'WORD
(while t
(setq r (concat r (string (following-char))))
(setq state (lisp-indent-next-state))
(and (not (looking-at "\\w\\|\\s_"))
(throw 'WORD r))))))
(setq indent (append indent (list :w w col))))
)
((looking-at "\\s<")
;; start of a comment
(while (not (looking-at "\\s>"))
(setq state (lisp-indent-next-state)))
)
((looking-at "\\s\'")
;; quote
(setq indent (append indent (list :q () (current-column))))
(setq state (lisp-indent-next-state))
)
((looking-at "\\s\\")
;; a special character
(setq state (lisp-indent-next-state 2))
)
((looking-at "\\s>")
;; end of line
(setq state (lisp-indent-next-state))
(while (looking-at "\\s ")
(setq state (lisp-indent-next-state)))
(setq indent-lines (cons (cons (lisp-indent-value)
(current-column)) indent-lines))
)
(t
(error "oops! unknown class of syntax ! (indent failed at
position %d)" (point))))))))
<ONE SPACE>(let (indent-lines
state
(l (prog2 (beginning-of-line) (point))))
(save-excursion (lisp-indent-automaton))
indent-lines)
EVALUATE HERE WITH M-x M-e
((0 . 0) (0 . 0) (0 . 0) (2 . 3) (2 . 3) (6 . 7) (6 . 7) (0 . 1) (0 . 0) (0 .
0) (0 . 0) (0 . 0) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (17 . 17) (15 . 15)
(15 . 15) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(15 . 15) (15 . 15) (15 . 15) (14 . 14) (15 . 15) (17 . 17) (15 . 15) (15 . 15)
(14 . 14) (15 . 15) (17 . 17) (34 . 34) (29 . 29) (29 . 29) (29 . 29) (27 . 27)
(22 . 22) (22 . 22) (29 . 28) (31 . 30) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(17 . 17) (15 . 15) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (15 . 15) (14 . 14)
(15 . 15) (52 . 52) (52 . 52) (23 . 23) (17 . 17) (28 . 28) (30 . 30) (15 . 15)
(15 . 15) (14 . 14) (15 . 15) (21 . 21) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(15 . 15) (20 . 20) (15 . 15) (15 . 15) (20 . 20) (8 . 8) (6 . 6) (4 . 4) (4 .
4) (4 . 4) (8 . 8) (4 . 4) (4 . 4) (8 . 8) (8 . 8) (8 . 8) (2 . 2) nil nil nil
(2 . 2))
(mapcar 'car
'((0 . 0) (0 . 0) (0 . 0) (2 . 3) (2 . 3) (6 . 7) (6 . 7) (0 . 1) (0 . 0) (0 .
0) (0 . 0) (0 . 0) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (17 . 17) (15 . 15)
(15 . 15) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(15 . 15) (15 . 15) (15 . 15) (14 . 14) (15 . 15) (17 . 17) (15 . 15) (15 . 15)
(14 . 14) (15 . 15) (17 . 17) (34 . 34) (29 . 29) (29 . 29) (29 . 29) (27 . 27)
(22 . 22) (22 . 22) (29 . 28) (31 . 30) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(17 . 17) (15 . 15) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (15 . 15) (14 . 14)
(15 . 15) (52 . 52) (52 . 52) (23 . 23) (17 . 17) (28 . 28) (30 . 30) (15 . 15)
(15 . 15) (14 . 14) (15 . 15) (21 . 21) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(15 . 15) (20 . 20) (15 . 15) (15 . 15) (20 . 20) (8 . 8) (6 . 6) (4 . 4) (4 .
4) (4 . 4) (8 . 8) (4 . 4) (4 . 4) (8 . 8) (8 . 8) (8 . 8) (2 . 2) nil nil nil
(2 . 2)))
(0 0 0 2 2 6 6 0 0 0 0 0 15 14 15 15 17 15 15 15 14 15 15 15 14 15 15 15 15 14
15 17 15 15 14 15 17 34 29 29 29 27 22 22 29 31 15 15 14 15 17 15 15 14 15 15
15 14 15 52 52 23 17 28 30 15 15 14 15 21 15 15 14 15 15 20 15 15 20 8 6 4 4 4
8 4 4 8 8 8 2 nil nil nil 2)
THIS IS THE CORRECT INDENTATION.
(mapcar 'cdr
'((0 . 0) (0 . 0) (0 . 0) (2 . 3) (2 . 3) (6 . 7) (6 . 7) (0 . 1) (0 . 0) (0 .
0) (0 . 0) (0 . 0) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (17 . 17) (15 . 15)
(15 . 15) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(15 . 15) (15 . 15) (15 . 15) (14 . 14) (15 . 15) (17 . 17) (15 . 15) (15 . 15)
(14 . 14) (15 . 15) (17 . 17) (34 . 34) (29 . 29) (29 . 29) (29 . 29) (27 . 27)
(22 . 22) (22 . 22) (29 . 28) (31 . 30) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(17 . 17) (15 . 15) (15 . 15) (14 . 14) (15 . 15) (15 . 15) (15 . 15) (14 . 14)
(15 . 15) (52 . 52) (52 . 52) (23 . 23) (17 . 17) (28 . 28) (30 . 30) (15 . 15)
(15 . 15) (14 . 14) (15 . 15) (21 . 21) (15 . 15) (15 . 15) (14 . 14) (15 . 15)
(15 . 15) (20 . 20) (15 . 15) (15 . 15) (20 . 20) (8 . 8) (6 . 6) (4 . 4) (4 .
4) (4 . 4) (8 . 8) (4 . 4) (4 . 4) (8 . 8) (8 . 8) (8 . 8) (2 . 2) nil nil nil
(2 . 2)))
(0 0 0 3 3 7 7 1 0 0 0 0 15 14 15 15 17 15 15 15 14 15 15 15 14 15 15 15 15 14
15 17 15 15 14 15 17 34 29 29 29 27 22 22 28 30 15 15 14 15 17 15 15 14 15 15
15 14 15 52 52 23 17 28 30 15 15 14 15 21 15 15 14 15 15 20 15 15 20 8 6 4 4 4
8 4 4 8 8 8 2 nil nil nil 2)
THIS IS THE OLD INDENTATION (nil means that there are spaces)
Read the indent-defun to see how to use it.
Alin Soare.
____________________________________________________
Sur le mail Voila, vous pouvez personnaliser l’anti-spam ! http://mail.voila.fr
indent.el
Description: Binary data