From: fred Date: Wed, 27 Mar 2002 02:05:06 +0000 (+0000) Subject: lilypond-1.5.29 X-Git-Tag: release/1.5.59~354 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=589ca8f5a1417876ef27022df7851caaf45f2e5c;p=lilypond.git lilypond-1.5.29 --- diff --git a/GNUmakefile.in b/GNUmakefile.in index 1d8180ac5e..9b7cdd7ed3 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -20,7 +20,7 @@ SCRIPTS = configure aclocal.m4 README_FILES = ChangeLog CHANGES COPYING DEDICATION NEWS README.mandrake ROADMAP README_TXT_FILES = AUTHORS.txt README.txt INSTALL.txt FAQ.txt IN_FILES := $(wildcard *.in) -EXTRA_DIST_FILES = lilypond-font-lock.el lilypond-mode.el lilypond-init.el vimrc VERSION $(README_FILES) $(SCRIPTS) $(IN_FILES) emacsclient.patch lexer-gcc-3.0.patch .cvsignore +EXTRA_DIST_FILES = $(wildcard *.el) vimrc VERSION $(README_FILES) $(SCRIPTS) $(IN_FILES) emacsclient.patch lexer-gcc-3.0.patch .cvsignore NON_ESSENTIAL_DIST_FILES = $(README_TXT_FILES) INSTALLATION_DIR=$(datadir) INSTALLATION_FILES=$(configuration) VERSION diff --git a/lilypond-indent.el b/lilypond-indent.el new file mode 100644 index 0000000000..5c2e3be458 --- /dev/null +++ b/lilypond-indent.el @@ -0,0 +1,316 @@ +;;; lilypond-indent.el --- Auto-indentation for lilypond code +;;; +;;; Chris Jackson +;;; some code is taken from ESS (Emacs Speaks Statistics) S-mode by A.J.Rossini + +;;; Variables for customising indentation style + +(defcustom LilyPond-indent-level 4 + "*Indentation of lilypond statements with respect to containing block.") + +(defcustom LilyPond-brace-offset 0 + "*Extra indentation for open braces. +Compares with other text in same context.") + +(defcustom LilyPond-angle-offset 0 + "*Extra indentation for open angled brackets . +Compares with other text in same context.") + +(defcustom LilyPond-scheme-paren-offset 0 + "*Extra indentation for open scheme parens . +Compares with other text in same context.") + +(defcustom LilyPond-close-brace-offset 0 + "*Extra indentation for closing braces.") + +(defcustom LilyPond-close-angle-offset 0 + "*Extra indentation for closing angle brackets.") + +(defcustom LilyPond-close-scheme-paren-offset 0 + "*Extra indentation for closing scheme parens.") + +(defcustom LilyPond-fancy-comments t + "*Non-nil means distiguish between %, %%, and %%% for indentation.") + + +(defun LilyPond-calculate-indent () + "Return appropriate indentation for current line as lilypond code. +In usual case returns an integer: the column to indent to. +Returns nil if line starts inside a string" + (save-excursion + (beginning-of-line) + (let ((indent-point (point)) + (case-fold-search nil) + state) + (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))) is the traditional way for languages + ;; with simpler parenthesis delimiters + (cond ((nth 3 state) + ;; point is in the middle of a string + nil) + ((nth 4 state) + ;; point is in the middle of a block comment + (LilyPond-calculate-indent-within-blockcomment)) + ((null containing-sexp) + ;; Line is at top level - no indent + (beginning-of-line) + 0) + (t + ;; Find previous non-comment character. + (goto-char indent-point) + (LilyPond-backward-to-noncomment containing-sexp) + ;; Now we get the answer. + ;; Position following last unclosed open. + (goto-char containing-sexp) + (or + ;; Is line first statement after an open brace or bracket? + ;; If no, find that first statement and indent like it. + (save-excursion + (forward-char 1) + ;; Skip over comments following open brace. + (skip-chars-forward " \t\n") + (cond ((looking-at "%{") + (while (progn + (and (not (looking-at "%}")) + (< (point) (point-max)))) + (forward-line 1) + (skip-chars-forward " \t\n")) + (forward-line 1) + (skip-chars-forward " \t\n")) + ((looking-at "%") + (while (progn (skip-chars-forward " \t\n") + (looking-at "%")) + (forward-line 1)))) + ;; The first following code counts + ;; if it is before the line we want to indent. + (and (< (point) indent-point) + (current-column))) + ;; If no previous statement, + ;; indent it relative to line brace is on. + ;; For open brace in column zero, don't let statement + ;; start there too. If LilyPond-indent-level is zero, use + ;; LilyPond-brace-offset instead + (+ (if (and (bolp) (zerop LilyPond-indent-level)) + (cond ((= (following-char) ?{) + LilyPond-brace-offset) + ((= (following-char) ?<) + LilyPond-angle-offset) + ((= (following-char) ?\)) + LilyPond-scheme-paren-offset) + (t + 0)) + LilyPond-indent-level) + (progn + (skip-chars-backward " \t") + (current-indentation))))))))) + + + +(defun LilyPond-indent-line () + "Indent current line as lilypond code. +Return the amount the indentation changed by." + (let ((indent (LilyPond-calculate-indent)) + beg shift-amt + (case-fold-search nil) + (pos (- (point-max) (point)))) + (beginning-of-line) + (setq beg (point)) + (cond ((eq indent nil) + (setq indent (current-indentation))) + (t + (skip-chars-forward " \t") + (if (and LilyPond-fancy-comments (looking-at "%%%\\|%{\\|%}")) + (setq indent 0)) + (if (and LilyPond-fancy-comments + (looking-at "%") + (not (looking-at "%%\\|%{\\|%}"))) + (setq indent comment-column) + (if (eq indent t) (setq indent 0)) + (if (listp indent) (setq indent (car indent))) + (cond + ((= (following-char) ?}) + (setq indent (+ indent (- LilyPond-close-brace-offset LilyPond-indent-level)))) + ((= (following-char) ?>) + (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))) + ((= (following-char) ?<) + (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))) + (if (zerop shift-amt) + (if (> (- (point-max) pos) (point)) + (goto-char (- (point-max) pos))) + (delete-region beg (point)) + (indent-to indent) + ;; If initial point was within line's indentation, + ;; position after the indentation. + ;; Else stay at same point in text. + (if (> (- (point-max) pos) (point)) + (goto-char (- (point-max) pos)))) + shift-amt)) + + +(defun LilyPond-inside-comment-p () + "Return non-nil if point is inside a line or block comment" + (setq this-point (point)) + (or (save-excursion (beginning-of-line) + (skip-chars-forward " \t") + (looking-at "%")) + (save-excursion + ;; point is in the middle of a block comment + (setq lastopen (save-excursion (re-search-backward "%{[ \\t]*" (point-min) t))) + (setq lastclose (save-excursion (re-search-backward "%}[ \\t]*" (point-min) t))) + (if (or (and (= (char-before) ?%) (= (char-after) ?{)) + (and (= (char-after) ?%) (= (char-after (1+ (point))) ?{))) + (setq lastopen (save-excursion (backward-char) (point)))) + (and + lastopen + (or (not lastclose) + (<= lastclose lastopen)))) + )) + + +(defun LilyPond-inside-string-or-comment-p () + "Test if point is inside a string or a comment" + (setq this-point (point)) + (or (save-excursion (beginning-of-line) + (skip-chars-forward " \t") + (looking-at "%")) + (save-excursion + (beginning-of-defun) + (while (< (point) this-point) + (setq state (parse-partial-sexp (point) this-point 0))) + (cond ((nth 3 state) + ;; point is in the middle of a string + t ) + ((nth 4 state) + ;; point is in the middle of a block comment + t ) + (t + nil))))) + + +(defun LilyPond-backward-over-blockcomments (lim) + "Move point back to closest non-whitespace character not part of a block comment" + (setq lastopen (save-excursion (re-search-backward "%{[ \\t]*" lim t))) + (setq lastclose (save-excursion (re-search-backward "%}[ \\t]*" lim t))) + (if lastopen + (if lastclose + (if (<= lastclose lastopen) + (goto-char lastopen)) + (goto-char lastopen))) + (skip-chars-backward " %\t\n\f")) + + +(defun LilyPond-backward-over-linecomments (lim) + "Move point back to the closest non-whitespace character not part of a line comment. +Argument LIM limit." + (let (opoint stop) + (while (not stop) + (skip-chars-backward " \t\n\f" lim) + (setq opoint (point)) + (beginning-of-line) + (search-forward "%" opoint 'move) + (skip-chars-backward " \t%") + (setq stop (or (/= (preceding-char) ?\n) (<= (point) lim))) + (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) + (LilyPond-backward-over-blockcomments lim)) + + +(defun LilyPond-calculate-indent-within-blockcomment () + "Return the indentation amount for line inside a block comment." + (let (end percent-start) + (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + (skip-chars-backward " \t\n") + (setq end (point)) + (beginning-of-line) + (skip-chars-forward " \t") + (and (re-search-forward "%{[ \t]*" end t) + (goto-char (1+ (match-beginning 0)))) + (if (and (looking-at "[ \t]*$") (= (preceding-char) ?\%)) + (1+ (current-column)) + (current-column))))) + + +(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 + ("{" . "}"))) + + +(defconst LilyPond-parens-combined-regexp + (concat (mapconcat 'car LilyPond-parens-regexp-alist "\\|") + "\\|" + (mapconcat 'cdr LilyPond-parens-regexp-alist "\\|"))) + + +(defun LilyPond-beginning-of-containing-sexp () + "Move point to the beginning of the deepest parenthesis pair enclosing point." + (interactive) + (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))))