emacs-devel
[Top][All Lists]
Advanced

[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

Attachment: indent.el
Description: Binary data


reply via email to

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