* An automaton for indenting the lisp code in linear time
@ 2008-06-30 0:41 A Soare
0 siblings, 0 replies; 7+ messages in thread
From: A Soare @ 2008-06-30 0:41 UTC (permalink / raw)
To: Emacs Dev [emacs-devel]
[-- Attachment #1: Type: text/plain, Size: 3333 bytes --]
Here I send the old promised automaton for indenting in linear time...
I looked in the code of emacs to the function scan_sexps_forward,
because I want to write for myself a little web browser, and I saw
that its automaton of changing the classes of syntax looks very
closely to the automaton that I wrote about 1 year ago to indent the
lisp code.
That is the reason for which I decided to open the archives and
to remember.
This code indents a line of code and a whole region in O(n) time
complexity; oups! no, sorry, in O(n+l) (the automaton in O(n) + O(l)
to use its output to indent), where n is the number of bytes from the
beginning of the function to the ending point, and l is the number of
lines from the beginning of the function to the ending point. (in the
code it's true that (current-column) is called very often, but I can
insert a variable `column' that keeps the current column, and it is
reset when we meet newline, and grows by 1 when the automaton passes
to the next state, and I think that I will modify it to keep the idea
of O(n)).
This code is very compact; installing it will cut thousands of lines
of old code from Emacs.
And, besides, it is imcomplete! Here are just the most basics. I can
complete it just after I speak with the emacs developers, in order to
agree on its behaviour. I do not like to work on in vain.
In this period I wish to work for this code, in order to finish it. If
I do not work now, I do not know when I can work on.
Besides, looking these days to write my web browser, I realised that
it would be a good idea embedding this automaton in C. But, again, I
do not want to work on it before asking you, because I want this job
to have a practical utility, not just to spend time working on this.
Here I give you just 2 very samples examples of how this automaton
works. It's evident how it works, and these 2 examples are too much!
There are a few new things in this code: for example, note the
easyness to add indent for comments, constant symbols, and look at the
easyness with which I made the indentation of a parameter of a
function before the first parameter, not under the second (i.e. one
makes now the difference between many kinds of list : not all the
lists have the first parameter a function):
(defun a (x y
z t)
...
and not the old behaviour:
(defun a (x y
z t)
...
The problem of indentig of lisp code is a problem of... homotopy:
however I deform the code (the spaces at the beginning of the lines),
this automaton must always return the same result.
Before calling (lisp-indent-automaton), one must have in the upper
environment the variables `state' and `indents-lines' initialised with
nil. It will return the result in indents-lines. The mapcar of car of
indents-lines is a list that contains the correct answer to the
homotopy problem. This result must be the same however I deform the
code (spaces at the beginning of lines). The mapcar of the cdr is a
list with the current indentation.
Please, tell me your impressions and... give me to work in order to
finish it well :)
Alin Soare.
____________________________________________________
Sur le mail Voila, vous pouvez personnaliser l’anti-spam ! http://mail.voila.fr
[-- Attachment #2: indent.el --]
[-- Type: application/octet-stream, Size: 8137 bytes --]
(defun lisp-indent-value ()
"
VERSION : NEW
"
(cond ((elt state 3)
;; Inside a string, don't change indentation.
nil
)
((null (cadr state))
;; outside an expression align to the left column
0
)
((null indent)
;; and empty parethesis
(1+ start-col))
((and (integerp lisp-indent-offset)
(integerp (cadr indent)))
;; indent by constant offset
(+ (cadr indent) lisp-indent-offset)
)
((looking-at "\\s<\\s<\\s<")
;; Comments that start with three semicolons or more, should
;; start at the left margin
0
)
((eq (car indent) :l)
;; indent beneath a list
(caddr indent)
)
((and (eq (car indent) :w)
(stringp (cadr indent))
(string-match "def" (cadr indent))
(zerop (string-match "def" (cadr indent))))
;; indent a def-form
(+ lisp-body-indent start-col)
)
((and (eq (car indent) :w)
(wholenump (get (intern-soft (cadr indent)) 'lisp-indent-function)))
;; here there is a special form
(setq oo (or (get (intern-soft (cadr indent)) 'lisp-indent-function)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)))
(if (> (length indent) (* 3 oo))
(+ lisp-body-indent start-col)
(+ (* 2 lisp-body-indent) start-col))
)
((and (eq (car indent) :w)
(get (intern-soft (cadr indent)) 'lisp-indent-hook))
;; indent defined by another function
(funcall (get (intern-soft (cadr indent)) 'lisp-indent-hook))
)
((and (equal (following-char) ?:)
nil)
;; indent of a constant symbol
;; not yed defined
(caddr indent)
)
((and (eq (car indent) :w)
(> (length indent) 3))
;; indent beneath the `indent-what-argument' parameter
(elt indent (+ 3 (1- (* 3 indent-what-argument))))
)
(t
;; the first parameter of a function call
(caddr indent))
))
(defun lisp-indent-what-argument nil
(cond ((and (eq (car indent) :w)
(stringp (cadr indent))
(string-match "def" (cadr indent))
(= (length indent) 9)
(zerop (string-match "def" (cadr indent))))
;; if the third parameter of defun is a list, then this list
;; is not a function call
0)
((or
(and (>= (length indent) 6)
(eq (elt indent (- (length indent ) 6)) :q))
(and (eq (car indent) :w)
(stringp (cadr indent))
(string-equal "quote" (cadr indent))))
;; a quoted list is not a function call
0
)
(t
;; for the rest, always indent after the first parameter of
;; the function...
1)))
(defun lisp-indent-next-state (&optional n)
(parse-partial-sexp (point) (+ (or n 1) (point)) () () state))
(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
(setq indent (append indent (list :c (current-column))))
(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))))))))
(defun indent-defun-example nil
"
An example how to use the automatonin for indentig a whole region
of lisp code in linear time (a function from the beginning to the point).
"
(let* (indent-lines
state
l)
(save-excursion
(lisp-indent-automaton)
(dolist (i indent-lines)
(when (consp i)
(setq l (prog2 (beginning-of-line) (point)))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (- l (point)) (- (cdr i) (car i)))))
(delete-region l (point))
(indent-to (car i))))
(previous-line)))))
(defun indent-line-example nil
"
An example how to indent a line of code using the automaton
"
(let* (indent-lines
state
dif
(pos (point-marker))
(l (prog2 (beginning-of-line) (point))))
(save-excursion (lisp-indent-automaton))
(if (not (consp (car indent-lines)))
nil
(setq dif
(catch 'DIF
(dolist (i (cdr indent-lines))
(and (consp i)
(throw 'DIF (- (cdr i) (car i)))))))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (+ (caar indent-lines) dif) (- (point) l))))
(delete-region l (point))
(indent-to (+ (caar indent-lines) dif))
(goto-char (max pos (point)))))))
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: An automaton for indenting the lisp code in linear time
@ 2008-07-01 0:49 A Soare
2008-07-01 1:06 ` Lennart Borgman (gmail)
0 siblings, 1 reply; 7+ messages in thread
From: A Soare @ 2008-07-01 0:49 UTC (permalink / raw)
To: Emacs Dev [emacs-devel]
[-- Attachment #1: Type: text/plain, Size: 362 bytes --]
What do you think about the code? Do I have any chance that the code be used?
In this case, what functions should I write? (indent-region, etc)...
I modified it a little and I send a new version.
A Soare.
____________________________________________________
Sur le mail Voila, vous pouvez personnaliser l’anti-spam ! http://mail.voila.fr
[-- Attachment #2: indent.el --]
[-- Type: application/octet-stream, Size: 8119 bytes --]
(defun lisp-indent-value ()
"
VERSION : NEW
"
(cond ((elt state 3)
;; Inside a string, don't change indentation.
nil
)
((null (cadr state))
;; outside an expression align to the left column
0
)
((null indent)
;; an empty parethesis
(1+ start-col))
((and (integerp lisp-indent-offset)
(integerp (cadr indent)))
;; indent by constant offset
(+ (cadr indent) lisp-indent-offset)
)
((looking-at "\\s<\\s<\\s<")
;; Comments that start with three semicolons or more, should
;; start at the left margin
0
)
((eq (car indent) :l)
;; indent beneath a list
(caddr indent)
)
((and (eq (car indent) :w)
(stringp (cadr indent))
(>= (length (cadr indent)) 3)
(string-equal "def" (substring (cadr indent) 0 3)))
;; indent a def-form
(+ lisp-body-indent start-col)
)
((and (eq (car indent) :w)
(wholenump (get (intern-soft (cadr indent)) 'lisp-indent-function)))
;; here there is a special form
(setq oo (or (get (intern-soft (cadr indent)) 'lisp-indent-function)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)))
(if (> (length indent) (* 3 oo))
(+ lisp-body-indent start-col)
(+ (* 2 lisp-body-indent) start-col))
)
((and (eq (car indent) :w)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)
nil)
;; indent defined by another function
;; not defined yet
(funcall (get (intern-soft (cadr indent)) 'lisp-indent-hook))
)
((and (equal (following-char) ?:)
nil)
;; indent of a constant symbol
;; not yed defined
(caddr indent)
)
((and (eq (car indent) :w)
(> (length indent) 3))
;; indent beneath the `indent-what-argument' parameter
(elt indent (+ 3 (1- (* 3 indent-what-argument))))
)
(t
;; the first parameter of a function call
(caddr indent))
))
(defun lisp-indent-what-argument nil
(cond ((and (eq (car indent) :w)
(stringp (cadr indent))
(>= (length (cadr indent)) 3)
(string-equal "def" (substring (cadr indent) 0 3))
(= (length indent) 9))
;; if the second parameter of defun is a list, then this list
;; is not a function call
0)
((or
(and (>= (length indent) 6)
(eq (elt indent (- (length indent ) 6)) :q))
(and (eq (car indent) :w)
(stringp (cadr indent))
(string-equal "quote" (cadr indent))))
;; a quoted list is not a function call
0
)
(t
;; for the rest, always indent beneath the first parameter of
;; the function...
1)))
(defun lisp-indent-next-state (&optional n)
(parse-partial-sexp (point) (+ (or n 1) (point)) () () state))
(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))))))))
(defun indent-defun-example nil
"
An example how to use the automatonin for indentig a whole region
of lisp code in linear time (a function from the beginning to the point).
"
(let* (indent-lines
state
l)
(save-excursion
(lisp-indent-automaton)
(dolist (i indent-lines)
(when (consp i)
(setq l (prog2 (beginning-of-line) (point)))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (- l (point)) (- (cdr i) (car i)))))
(delete-region l (point))
(indent-to (car i))))
(previous-line)))))
(defun indent-line-example nil
"
An example how to indent a line of code using the automaton
"
(let* (indent-lines
state
dif
(pos (point-marker))
(l (prog2 (beginning-of-line) (point))))
(save-excursion (lisp-indent-automaton))
(if (not (consp (car indent-lines)))
nil
(setq dif
(catch 'DIF
(dolist (i (cdr indent-lines))
(and (consp i)
(throw 'DIF (- (cdr i) (car i)))))))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (+ (caar indent-lines) dif) (- (point) l))))
(delete-region l (point))
(indent-to (+ (caar indent-lines) dif))
(goto-char (max pos (point)))))))
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: An automaton for indenting the lisp code in linear time
2008-07-01 0:49 A Soare
@ 2008-07-01 1:06 ` Lennart Borgman (gmail)
0 siblings, 0 replies; 7+ messages in thread
From: Lennart Borgman (gmail) @ 2008-07-01 1:06 UTC (permalink / raw)
To: alinsoar; +Cc: Emacs Dev [emacs-devel]
A Soare wrote:
> What do you think about the code? Do I have any chance that the code be used?
>
> In this case, what functions should I write? (indent-region, etc)...
>
> I modified it a little and I send a new version.
>
>
> A Soare.
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.)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: An automaton for indenting the lisp code in linear time
@ 2008-07-01 2:24 A Soare
0 siblings, 0 replies; 7+ messages in thread
From: A Soare @ 2008-07-01 2:24 UTC (permalink / raw)
To: Lennart Borgman (gmail); +Cc: Emacs Dev [emacs-devel]
[-- Attachment #1: Type: text/plain, Size: 8666 bytes --]
>
> 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 #2: indent.el --]
[-- Type: application/octet-stream, Size: 8119 bytes --]
(defun lisp-indent-value ()
"
VERSION : NEW
"
(cond ((elt state 3)
;; Inside a string, don't change indentation.
nil
)
((null (cadr state))
;; outside an expression align to the left column
0
)
((null indent)
;; an empty parethesis
(1+ start-col))
((and (integerp lisp-indent-offset)
(integerp (cadr indent)))
;; indent by constant offset
(+ (cadr indent) lisp-indent-offset)
)
((looking-at "\\s<\\s<\\s<")
;; Comments that start with three semicolons or more, should
;; start at the left margin
0
)
((eq (car indent) :l)
;; indent beneath a list
(caddr indent)
)
((and (eq (car indent) :w)
(stringp (cadr indent))
(>= (length (cadr indent)) 3)
(string-equal "def" (substring (cadr indent) 0 3)))
;; indent a def-form
(+ lisp-body-indent start-col)
)
((and (eq (car indent) :w)
(wholenump (get (intern-soft (cadr indent)) 'lisp-indent-function)))
;; here there is a special form
(setq oo (or (get (intern-soft (cadr indent)) 'lisp-indent-function)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)))
(if (> (length indent) (* 3 oo))
(+ lisp-body-indent start-col)
(+ (* 2 lisp-body-indent) start-col))
)
((and (eq (car indent) :w)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)
nil)
;; indent defined by another function
;; not defined yet
(funcall (get (intern-soft (cadr indent)) 'lisp-indent-hook))
)
((and (equal (following-char) ?:)
nil)
;; indent of a constant symbol
;; not yed defined
(caddr indent)
)
((and (eq (car indent) :w)
(> (length indent) 3))
;; indent beneath the `indent-what-argument' parameter
(elt indent (+ 3 (1- (* 3 indent-what-argument))))
)
(t
;; the first parameter of a function call
(caddr indent))
))
(defun lisp-indent-what-argument nil
(cond ((and (eq (car indent) :w)
(stringp (cadr indent))
(>= (length (cadr indent)) 3)
(string-equal "def" (substring (cadr indent) 0 3))
(= (length indent) 9))
;; if the second parameter of defun is a list, then this list
;; is not a function call
0)
((or
(and (>= (length indent) 6)
(eq (elt indent (- (length indent ) 6)) :q))
(and (eq (car indent) :w)
(stringp (cadr indent))
(string-equal "quote" (cadr indent))))
;; a quoted list is not a function call
0
)
(t
;; for the rest, always indent beneath the first parameter of
;; the function...
1)))
(defun lisp-indent-next-state (&optional n)
(parse-partial-sexp (point) (+ (or n 1) (point)) () () state))
(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))))))))
(defun indent-defun-example nil
"
An example how to use the automatonin for indentig a whole region
of lisp code in linear time (a function from the beginning to the point).
"
(let* (indent-lines
state
l)
(save-excursion
(lisp-indent-automaton)
(dolist (i indent-lines)
(when (consp i)
(setq l (prog2 (beginning-of-line) (point)))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (- l (point)) (- (cdr i) (car i)))))
(delete-region l (point))
(indent-to (car i))))
(previous-line)))))
(defun indent-line-example nil
"
An example how to indent a line of code using the automaton
"
(let* (indent-lines
state
dif
(pos (point-marker))
(l (prog2 (beginning-of-line) (point))))
(save-excursion (lisp-indent-automaton))
(if (not (consp (car indent-lines)))
nil
(setq dif
(catch 'DIF
(dolist (i (cdr indent-lines))
(and (consp i)
(throw 'DIF (- (cdr i) (car i)))))))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (+ (caar indent-lines) dif) (- (point) l))))
(delete-region l (point))
(indent-to (+ (caar indent-lines) dif))
(goto-char (max pos (point)))))))
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: An automaton for indenting the lisp code in linear time
@ 2008-07-01 13:59 A Soare
0 siblings, 0 replies; 7+ messages in thread
From: A Soare @ 2008-07-01 13:59 UTC (permalink / raw)
To: Robert J. Chassell; +Cc: Emacs Dev [emacs-devel]
I do not know what are you speaking about.
> Message du 01/07/08 à 13h04
> De : "Robert J. Chassell" <bob@rattlesnake.com>
> A : alinsoar@voila.fr
> Copie à :
> Objet : Re: An automaton for indenting the lisp code in linear time
>
>
> For all: please report me problems , unconsidered cases, where the indent d=
> oes not work.
>
> Every line of your message has an equals sign at the end of that line.
> When I format your message as MIME, that gets rid of the equals signs
> but the line lacks filling and looks bad. If you don't have anything
> special in your .emacs file, it looks like this:
>
> For all: please report me problems , unconsidered cases, where the indent does not work.
>
> My other mail has been filled, has two spaces at the end of every
> sentence, and looks fine to me.
>
> --
> Robert J. Chassell GnuPG Key ID: 004B4AC8
> bob@rattlesnake.com bob@gnu.org
> http://www.rattlesnake.com http://www.teak.cc
>
>
____________________________________________________
Sur le mail Voila, vous pouvez personnaliser l’anti-spam ! http://mail.voila.fr
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: An automaton for indenting the lisp code in linear time
@ 2008-07-01 15:28 A Soare
0 siblings, 0 replies; 7+ messages in thread
From: A Soare @ 2008-07-01 15:28 UTC (permalink / raw)
To: Emacs Dev [emacs-devel]
[-- Attachment #1: Type: text/plain, Size: 1533 bytes --]
> (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)
>
Sorry , I wanted to say "nil means that there are STRINGS"
(the lines that start into a string are not modified)
____________________________________________________
Sur le mail Voila, vous pouvez personnaliser l’anti-spam ! http://mail.voila.fr
[-- Attachment #2: indent.el --]
[-- Type: application/octet-stream, Size: 8119 bytes --]
(defun lisp-indent-value ()
"
VERSION : NEW
"
(cond ((elt state 3)
;; Inside a string, don't change indentation.
nil
)
((null (cadr state))
;; outside an expression align to the left column
0
)
((null indent)
;; an empty parethesis
(1+ start-col))
((and (integerp lisp-indent-offset)
(integerp (cadr indent)))
;; indent by constant offset
(+ (cadr indent) lisp-indent-offset)
)
((looking-at "\\s<\\s<\\s<")
;; Comments that start with three semicolons or more, should
;; start at the left margin
0
)
((eq (car indent) :l)
;; indent beneath a list
(caddr indent)
)
((and (eq (car indent) :w)
(stringp (cadr indent))
(>= (length (cadr indent)) 3)
(string-equal "def" (substring (cadr indent) 0 3)))
;; indent a def-form
(+ lisp-body-indent start-col)
)
((and (eq (car indent) :w)
(wholenump (get (intern-soft (cadr indent)) 'lisp-indent-function)))
;; here there is a special form
(setq oo (or (get (intern-soft (cadr indent)) 'lisp-indent-function)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)))
(if (> (length indent) (* 3 oo))
(+ lisp-body-indent start-col)
(+ (* 2 lisp-body-indent) start-col))
)
((and (eq (car indent) :w)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)
nil)
;; indent defined by another function
;; not defined yet
(funcall (get (intern-soft (cadr indent)) 'lisp-indent-hook))
)
((and (equal (following-char) ?:)
nil)
;; indent of a constant symbol
;; not yed defined
(caddr indent)
)
((and (eq (car indent) :w)
(> (length indent) 3))
;; indent beneath the `indent-what-argument' parameter
(elt indent (+ 3 (1- (* 3 indent-what-argument))))
)
(t
;; the first parameter of a function call
(caddr indent))
))
(defun lisp-indent-what-argument nil
(cond ((and (eq (car indent) :w)
(stringp (cadr indent))
(>= (length (cadr indent)) 3)
(string-equal "def" (substring (cadr indent) 0 3))
(= (length indent) 9))
;; if the second parameter of defun is a list, then this list
;; is not a function call
0)
((or
(and (>= (length indent) 6)
(eq (elt indent (- (length indent ) 6)) :q))
(and (eq (car indent) :w)
(stringp (cadr indent))
(string-equal "quote" (cadr indent))))
;; a quoted list is not a function call
0
)
(t
;; for the rest, always indent beneath the first parameter of
;; the function...
1)))
(defun lisp-indent-next-state (&optional n)
(parse-partial-sexp (point) (+ (or n 1) (point)) () () state))
(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))))))))
(defun indent-defun-example nil
"
An example how to use the automatonin for indentig a whole region
of lisp code in linear time (a function from the beginning to the point).
"
(let* (indent-lines
state
l)
(save-excursion
(lisp-indent-automaton)
(dolist (i indent-lines)
(when (consp i)
(setq l (prog2 (beginning-of-line) (point)))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (- l (point)) (- (cdr i) (car i)))))
(delete-region l (point))
(indent-to (car i))))
(previous-line)))))
(defun indent-line-example nil
"
An example how to indent a line of code using the automaton
"
(let* (indent-lines
state
dif
(pos (point-marker))
(l (prog2 (beginning-of-line) (point))))
(save-excursion (lisp-indent-automaton))
(if (not (consp (car indent-lines)))
nil
(setq dif
(catch 'DIF
(dolist (i (cdr indent-lines))
(and (consp i)
(throw 'DIF (- (cdr i) (car i)))))))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (+ (caar indent-lines) dif) (- (point) l))))
(delete-region l (point))
(indent-to (+ (caar indent-lines) dif))
(goto-char (max pos (point)))))))
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: An automaton for indenting the lisp code in linear time
@ 2008-07-04 21:14 A Soare
0 siblings, 0 replies; 7+ messages in thread
From: A Soare @ 2008-07-04 21:14 UTC (permalink / raw)
To: Emacs Dev [emacs-devel]
[-- Attachment #1: Type: text/plain, Size: 279 bytes --]
Here I send a more simplified version of the indentation of lisp code... This might be useful for more developpers...
Alin Soare.
____________________________________________________
Sur le mail Voila, vous pouvez personnaliser l’anti-spam ! http://mail.voila.fr
[-- Attachment #2: indent.el --]
[-- Type: application/octet-stream, Size: 7985 bytes --]
(defun lisp-indent-value ()
"
VERSION : NEW
"
(cond ((elt state 3)
;; Inside a string, don't change indentation.
nil
)
((null (cadr state))
;; outside an expression align to the left column
0
)
((null indent)
;; an empty parethesis
(1+ start-col))
((and (integerp lisp-indent-offset)
(integerp (cadr indent)))
;; indent by constant offset
(+ (cadr indent) lisp-indent-offset)
)
((looking-at "\\s<\\s<\\s<")
;; Comments that start with three semicolons or more, should
;; start at the left margin
0
)
((eq (car indent) :l)
;; indent beneath a list
(caddr indent)
)
((and (eq (car indent) :w)
(stringp (cadr indent))
(>= (length (cadr indent)) 3)
(string-equal "def" (substring (cadr indent) 0 3)))
;; indent a def-form
(+ lisp-body-indent start-col)
)
((and (eq (car indent) :w)
(wholenump (get (intern-soft (cadr indent)) 'lisp-indent-function)))
;; here there is a special form
(setq oo (or (get (intern-soft (cadr indent)) 'lisp-indent-function)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)))
(if (> (length indent) (* 3 oo))
(+ lisp-body-indent start-col)
(+ (* 2 lisp-body-indent) start-col))
)
((and (eq (car indent) :w)
(get (intern-soft (cadr indent)) 'lisp-indent-hook)
nil)
;; indent defined by another function
;; not defined yet
(funcall (get (intern-soft (cadr indent)) 'lisp-indent-hook))
)
((and (equal (following-char) ?:)
nil)
;; indent of a constant symbol
;; not yed defined
(caddr indent)
)
((and (eq (car indent) :w)
(> (length indent) 3))
;; indent beneath the `indent-what-argument' parameter
(elt indent (+ 3 (1- (* 3 indent-what-argument))))
)
(t
;; the first parameter of a function call
(caddr indent))
))
(defun lisp-indent-what-argument nil
(cond ((and (eq (car indent) :w)
(stringp (cadr indent))
(>= (length (cadr indent)) 3)
(string-equal "def" (substring (cadr indent) 0 3))
(= (length indent) 9))
;; if the second parameter of defun is a list, then this list
;; is not a function call
0)
((or
(and (>= (length indent) 6)
(eq (elt indent (- (length indent ) 6)) :q))
(and (eq (car indent) :w)
(stringp (cadr indent))
(string-equal "quote" (cadr indent))))
;; a quoted list is not a function call
0
)
(t
;; for the rest, always indent beneath the first parameter of
;; the function...
1)))
(defun lisp-indent-next-state (&optional n)
(setq state (parse-partial-sexp (point) (+ (or n 1) (point)) () () state)
column (+ (or n 1) column)))
(defun lisp-indent-automaton (&optional end indent-what-argument start-col indent)
"
an automaton to indent the lisp code
VERSION: NEW
"
(or end (beginning-of-line) (setq end (point)))
(or indent-what-argument
(setq indent-what-argument 0))
(or state (and (beginning-of-defun)
(setq column (current-column))))
(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)
column 0))
(lisp-indent-next-state)
)
((looking-at "\\s\"")
;; the start of a string
(setq indent (append indent (list :s () column)))
(lisp-indent-next-state)
)
((looking-at "\\s\(")
;; open a parenthesis
(let ((col (if indent-lines
(+ column (- (caar indent-lines) (cdar indent-lines)))
column)))
(setq indent (append indent (list :l () col)))
(lisp-indent-next-state)
(lisp-indent-automaton end (lisp-indent-what-argument) col))
)
((looking-at "\\s\)")
;; close a parenthesis
(lisp-indent-next-state)
(throw 'STOP nil)
)
((looking-at "\\s ")
;; spaces are ignored
(while (looking-at "[[:blank:]]")
(lisp-indent-next-state))
)
((looking-at "\\sw\\|\\s_")
;; a function or a parameter
(let* ((col (if indent-lines
(+ column (- (caar indent-lines) (cdar indent-lines)))
column))
r
(w (catch 'WORD
(while t
(setq r (concat r (string (following-char))))
(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>"))
(lisp-indent-next-state))
)
((looking-at "\\s\'")
;; quote
(setq indent (append indent (list :q () column)))
(lisp-indent-next-state)
)
((looking-at "\\s\\")
;; a special character
(lisp-indent-next-state 2)
)
((looking-at "\\s>")
;; end of line
(lisp-indent-next-state)
(setq column 0)
(while (looking-at "\\s ")
(lisp-indent-next-state))
(setq indent-lines (cons (cons (lisp-indent-value) column) indent-lines))
)
(t
(error "oops! unknown class of syntax ! (indent failed at position %d)" (point)))))))
(defun indent-defun-example nil
"
An example how to use the automatonin for indentig a whole region
of lisp code in linear time (a function from the beginning to the point).
"
(let* (indent-lines
state
l)
(save-excursion
(lisp-indent-automaton)
(dolist (i indent-lines)
(when (consp i)
(setq l (prog2 (beginning-of-line) (point)))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (- l (point)) (- (cdr i) (car i)))))
(delete-region l (point))
(indent-to (car i))))
(previous-line)))))
(defun indent-line-example nil
"
An example how to indent a line of code using the automaton
"
(let* (indent-lines
state
dif
(pos (point-marker))
(l (prog2 (beginning-of-line) (point))))
(save-excursion (lisp-indent-automaton))
(if (not (consp (car indent-lines)))
nil
(setq dif
(catch 'DIF
(dolist (i (cdr indent-lines))
(and (consp i)
(throw 'DIF (- (cdr i) (car i)))))))
(skip-chars-forward "[[:blank:]]")
(when (not (zerop (- (+ (caar indent-lines) dif) (- (point) l))))
(delete-region l (point))
(indent-to (+ (caar indent-lines) dif))
(goto-char (max pos (point)))))))
;;this code shows the indentation of the precedeeng function (indent-line-example)
(let* (indent-lines
state
column)
(lisp-indent-automaton)
indent-lines)
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-07-04 21:14 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-04 21:14 An automaton for indenting the lisp code in linear time A Soare
-- strict thread matches above, loose matches on Subject: below --
2008-07-01 15:28 A Soare
2008-07-01 13:59 A Soare
2008-07-01 2:24 A Soare
2008-07-01 0:49 A Soare
2008-07-01 1:06 ` Lennart Borgman (gmail)
2008-06-30 0:41 A Soare
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).