[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Emacs mode indentation
From: |
Chris Jackson |
Subject: |
Re: Emacs mode indentation |
Date: |
Sat, 26 Jan 2002 13:12:03 +0000 |
User-agent: |
Mutt/1.3.25i |
On Thu, Jan 24, 2002 at 11:20:42AM +0100, Jan Nieuwenhuizen wrote:
> I must say that the speed is not too bad. On my fairly old G3/233MHz,
> it feels comparable with c-mode's indenting speed.
OK - the patch below (relative to my previous patch) sorts out some of the
speed problems, and replaces a bloated and inefficient function... It can
still struggle with .ly files over 20K, though.
--
chris
--- lilypond-1.5.28-new/lilypond-indent.el Wed Jan 23 22:14:52 2002
+++ lilypond-indent-newnew.el Sat Jan 26 13:03:39 2002
@@ -46,9 +46,9 @@ Returns nil if line starts inside a stri
(setq containing-sexp (save-excursion
(LilyPond-beginning-of-containing-sexp)))
(beginning-of-defun)
(while (< (point) indent-point)
- (setq state (parse-partial-sexp (point) indent-point 0))
- ;(setq containing-sexp (car (cdr
state)))
- )
+ (setq state (parse-partial-sexp (point) indent-point 0)))
+ ;; (setq containing-sexp (car (cdr state))) is the traditional way for
languages
+ ;; with simpler parenthesis delimiters
(cond ((nth 3 state)
;; point is in the middle of a string
nil)
@@ -133,17 +133,17 @@ Return the amount the indentation change
(if (listp indent) (setq indent (car indent)))
(cond
((= (following-char) ?})
- (setq indent (- (+ indent LilyPond-close-brace-offset)
LilyPond-indent-level)))
+ (setq indent (+ indent (- LilyPond-close-brace-offset
LilyPond-indent-level))))
((= (following-char) ?>)
- (setq indent (- (+ indent LilyPond-close-angle-offset)
LilyPond-indent-level)))
- ((= (following-char) ?\))
- (setq indent (- (+ indent LilyPond-close-scheme-paren-offset)
LilyPond-indent-level)))
+ (setq indent (+ indent (- LilyPond-close-angle-offset
LilyPond-indent-level))))
+ ((and (= (following-char) ?\)) (LilyPond-inside-scheme-p))
+ (setq indent (+ indent (- LilyPond-close-scheme-paren-offset
LilyPond-indent-level))))
((= (following-char) ?{)
- (setq indent (+ indent LilyPond-brace-offset)))
+ (setq indent (+ indent LilyPond-brace-offset)))
((= (following-char) ?<)
- (setq indent (+ indent LilyPond-angle-offset)))
- ((= (following-char) ?\()
- (setq indent (+ indent LilyPond-scheme-paren-offset)))
+ (setq indent (+ indent LilyPond-angle-offset)))
+ ((and (= (following-char) ?\() (LilyPond-inside-scheme-p))
+ (setq indent (+ indent LilyPond-scheme-paren-offset)))
))))
(skip-chars-forward " \t")
(setq shift-amt (- indent (current-column)))
@@ -226,6 +226,7 @@ Argument LIM limit."
(if stop (point)
(beginning-of-line)))))
+
(defun LilyPond-backward-to-noncomment (lim)
"Move point back to closest non-whitespace character not part of a comment"
(LilyPond-backward-over-linecomments lim)
@@ -248,134 +249,69 @@ Argument LIM limit."
(1+ (current-column))
(current-column)))))
-(defconst LilyPond-parens-alist
- `(("{" . "}")
- ("(" . ")")
- ("<" . ">")))
(defconst LilyPond-parens-regexp-alist
- `(("{" . "}")
- ("(" . ")")
- ("[^\\]<" . "[^ \\n\\t_^-]\\s-*>\\|[_^-]\\s-*[-^]\\s-*>")))
-;; a b c->, a b c^> and a b c_> are not close-angle-brackets, they're accents
-;; but a b c^-> and a b c^^> are close brackets with tenuto/marcato before them
-;; also \> and \< are hairpins
+ `(("[^\\]<" . "[^ \\n\\t_^-]\\s-*>\\|[_^-]\\s-*[-^]\\s-*>")
+ ;; a b c->, a b c^> and a b c_> are not close-angle-brackets, they're
accents
+ ;; but a b c^-> and a b c^^> are close brackets with tenuto/marcato before
them
+ ;; also \> and \< are hairpins
+ ("{" . "}")))
+
+
+(defconst LilyPond-parens-combined-regexp
+ (concat (mapconcat 'car LilyPond-parens-regexp-alist "\\|")
+ "\\|"
+ (mapconcat 'cdr LilyPond-parens-regexp-alist "\\|")))
-;; This ensures that something like 'foo = \notes {' is treated as the
beginning of a defun
-(setq defun-prompt-regexp "\w+\\s-*=.*")
(defun LilyPond-beginning-of-containing-sexp ()
- "Move point to the opening of the syntactic parenthesis pair which contains
point.
-Ignores parenthesis within comments, and does not count accented notes, e.g
aes->, as
-closing parentheses"
+ "Move point to the beginning of the deepest parenthesis pair enclosing
point."
(interactive)
- (let ((parse-point (point)) ;; Point whose containing expression we want to
locate
- (nest-level 0) ;; Current nesting depth
- (scheme-nest-level 0) ;; Depth of Scheme parentheses ( () ) enclosing
point
- (finished nil) ;; Have we located the expression containing
point yet?
- (found-nest-level 0) ;; Nest level we are looking for
- (level-starts (list (point-min))) ;; List of open-bracket positions for
the hierarchy of nest levels enclosing point
- (sexp-types (list 0)) ;; Corresponding list of hierarchy of types of
bracket eg ( { < enclosing point
- (inside-scheme nil)) ;; Are we currently in embedded Scheme
- (beginning-of-defun)
- (while (not finished)
- (save-excursion
- ;; Search forward for the nearest opening bracket
- (setq done nil)
- (if (looking-at "{\\|<")
- ;; We are already at the nearest opening bracket
- ;; Need this bit as searching forward for the 2-character regexp
"[^\\]<" won't work.
- (progn (setq nextopen (point))
- (setq nextopen-char (char-after (point))))
- (while (not done)
- (if (re-search-forward (mapconcat 'car LilyPond-parens-regexp-alist
"\\|") nil t)
- (progn (setq match-loc (match-end 0))
- ;; If bracket is in a comment then search again
- (if (not (LilyPond-inside-string-or-comment-p))
- (progn
- ;; If bracket is a ( and we are not in embedded
scheme, then search again
- ;; We don't include phrasemarks/slurs as
parenthesis pairs
- (if (and (= (char-before (point)) ?\()
- (= scheme-nest-level 0)
- ;; Embedded scheme brackets begin with a
#( or a #`(
- (or (= (char-before (- (point) 1)) ?#)
- (and (= (char-before (- (point) 2))
?#)
- (= (char-before (- (point) 1))
?`))))
- (setq inside-scheme t))
- ;; Otherwise we've found a { or a <. Record its
position.
- (if (or inside-scheme (not (= (char-before
(point)) ?\()))
- (progn (setq nextopen (- match-loc 1))
- (setq nextopen-char (char-before
(point)))
- (setq done t))))))
- (setq nextopen (point-max))
- (setq done t)))))
- (save-excursion
- ;; Search forward for the nearest closing bracket
- (setq done nil)
- (skip-chars-forward " \t\n")
- (if (looking-at ">")
- ;; We are already at the nearest opening bracket
- ;; Need this bit as searching forward for a the 3-4 character
regexp including whitespace won't work.
- (progn (setq nextclose (point))
- (setq nextclose-char (char-after (point))))
- (while (not done)
- (if (re-search-forward (mapconcat 'cdr LilyPond-parens-regexp-alist
"\\|") nil t)
- (progn (setq match-loc (match-end 0))
- ;; If bracket is inside a comment then search again
- (if (not (LilyPond-inside-string-or-comment-p))
- (progn
- ;; If bracket is a ) and we are not in embedded
scheme, then search again
- (if (or (and (< nextopen (point)) inside-scheme)
- (> scheme-nest-level 0)
- (not (= (char-before (point)) ?\))))
- (progn (setq nextclose (- match-loc 1))
- (setq nextclose-char (char-before
(point)))
- (setq done t))))))
- (setq nextclose (point-max))
- (setq done t)))))
- (cond ((= nextclose (point-max))
- ;; If there are no more closing brackets, then we are done and
point is at top level.
- (setq finished t)
- (setq nest-level 0))
- ((< nextclose nextopen)
- ;; If next closing bracket is earlier then next open,
- ;; then go to the closing bracket. We are closing a currently-open
nest level.
- (if (<= parse-point nextclose);; if point is inside that nest
level, then we are done.
- (progn (setq found-nest-level nest-level)
- (setq finished t))
- (progn (goto-char nextclose)
- (forward-char 1)
- (setq matching-open (nth nest-level (reverse sexp-types)))
- ;;; Warn if our close bracket and its matching open bracket
are of different types
- (if (and (/= matching-open ?\()
- (/= nextclose-char (string-to-char (cdr (assoc
(string matching-open) LilyPond-parens-alist)))))
- (message "Warning: Unbalanced parentheses"))
- ;;; Move back to a higher nesting level
- (setq nest-level (1- nest-level))
- (if (and (= nextclose-char ?\)) inside-scheme)
- (setq scheme-nest-level (1- scheme-nest-level)))
- (if (eq scheme-nest-level 0) (setq inside-scheme nil));;
We are leaving a piece of inline Scheme
- (setq level-starts (cdr level-starts));; Forget the
starting position of the just-closed nest level
- (setq sexp-types (cdr sexp-types))
- )))
- (t
- ;; If next open bracket is earlier than next close bracket,
- ;; then go to the open bracket
- (if (<= parse-point nextopen)
- (progn (setq found-nest-level nest-level)
- (setq finished t))
- (progn
- (goto-char nextopen)
- (forward-char 1)
- (setq nest-level (1+ nest-level)) ;;; Descend into a further
nesting level
- (setq level-starts (cons nextopen level-starts));; Record the
starting position of this nest level
- (if (= nextopen-char ?\()
- (setq scheme-nest-level (1+ scheme-nest-level)))
- (setq sexp-types (cons nextopen-char sexp-types)))))))
- ;; Get the open-bracket position corresponding to the located nest level
and go there.
- (setq beginning (nth found-nest-level (nreverse level-starts)))
- (goto-char beginning)
- (if (= beginning 1);; Return nil if point is at top level
- nil
- beginning)))
+ (let ((level 1))
+ (if (LilyPond-inside-scheme-p)
+ (setq paren-regexp "(\\|)" inside-scheme t)
+ (setq paren-regexp LilyPond-parens-combined-regexp inside-scheme nil))
+ (while (and (> level 0)
+ (re-search-backward paren-regexp nil t)
+ (setq match (char-before (match-end 0))))
+ (if (not (save-excursion (goto-char (match-end 0))
+ (LilyPond-inside-string-or-comment-p)))
+ (if (memq match '(?} ?> ?\)))
+ (progn (setq level (1+ level))
+ (if (and (= match ?>)
+ (looking-at
".\\s-+>\\|\\({\\|}\\|<\\|>\\|(\\|)\\)>"))
+ (forward-char 1)))
+ (progn (setq level (1- level))
+ (if (and (= match ?<)
+ (looking-at
".\\s-+<\\|\\({\\|}\\|<\\|>\\|(\\|)\\)<"))
+ (forward-char 1))))))
+ (if (looking-at ".<\\|.>") (forward-char 1))
+ (if (/= level 1)
+ (point)
+ nil)))
+
+(defun LilyPond-inside-scheme-p ()
+ "Tests if point is inside embedded Scheme code"
+ (interactive)
+ (let ( (test-point (point))
+ (level 0) )
+ (save-excursion
+ (if (or (and (= (char-after (point)) ?\()
+ (or (= (char-after (- (point) 1)) ?#)
+ (and (= (char-after (- (point) 2)) ?#)
+ (= (char-after (- (point) 1)) ?`))))
+ (and (re-search-backward "#(\\|#`(" nil t)
+ (progn
+ (search-forward "(")
+ (setq level 1)
+ (while (and (> level 0)
+ (re-search-forward "(\\|)" test-point t)
+ (setq match (char-after (match-beginning 0)))
+ (<= (point) test-point))
+ (if (= match ?\()
+ (setq level (1+ level))
+ (setq level (1- level))))
+ (> level 0))))
+ t
+ nil))))