I've been playing with elisp again. This patch restores the blinking of
matching open parentheses, which broke when I did the indentation stuff.
Blinking should work for ) } > and ], with warnings when } and > are
unbalanced. Although I haven't emulated the fancy 'show-paren-mode'
(which highlights the paren pair when you move the cursor over one of
them) yet. 

The patch was made using cvs diff, hope it applies OK! 

-- 
chris
Index: ChangeLog
===================================================================
RCS file: /home/lilypond/lilypond/ChangeLog,v
retrieving revision 1.55
diff -p -u -r1.55 ChangeLog
--- ChangeLog   4 Apr 2002 22:05:50 -0000       1.55
+++ ChangeLog   6 Apr 2002 14:35:47 -0000
@@ -1,3 +1,9 @@
+2002-04-06  Chris Jackson <[EMAIL PROTECTED]>
+
+       * lilypond-indent.el: Support for blinking of matching parentheses
+       
+       * lilypond-font-lock.el: Fix fontification of closing > on its own line
+       
 2002-04-05  Han-Wen  <[EMAIL PROTECTED]>
 
        * mf/cmbase.mf: remove file. -- do without s and z signs for now.
Index: lilypond-font-lock.el
===================================================================
RCS file: /home/lilypond/lilypond/lilypond-font-lock.el,v
retrieving revision 1.10
diff -p -u -r1.10 lilypond-font-lock.el
--- lilypond-font-lock.el       26 Mar 2002 15:12:18 -0000      1.10
+++ lilypond-font-lock.el       6 Apr 2002 14:35:47 -0000
@@ -9,8 +9,8 @@
 ;; Author: 1995-1996 Barry A. Warsaw
 ;;         1992-1994 Tim Peters
 ;; Created:       Feb 1992
-;; Version:       1.5.47
-;; Last Modified: 26MAR2002
+;; Version:       1.5.50
+;; Last Modified: 6APR2002
 ;; Keywords: lilypond languages music notation
 
 ;; This software is provided as-is, without express or implied
@@ -137,12 +137,14 @@
 
 ;; highlight bracketing constructs
       '("\\([][}{]\\)" 0 font-lock-warning-face t)
-;; these regexps allow angle-brackets to be highlighted,
-;; but leave accented notes, e.g. a b c->, alone
+      ;; these regexps allow angle-brackets to be highlighted when and only when they 
+delimit simultaneous music
+      ;; fontify open < but leave crescendos \< alone
       '("[^\\]\\(<\\)" 1 font-lock-warning-face t)
-      '("[_^-]\\s-*[-^]\\s-*\\(>\\)" 1 font-lock-warning-face t)
-      '("[^\\t\\n _^-]\\s-*\\(>\\)" 1 font-lock-warning-face t)
-
+      ;; fontify the close-brackets in <a b c--> (tenuto) and <a b c-^> (marcato)
+      '("[_^-]\\s-*[-^]\\s-*\\(>\\)" 1 font-lock-warning-face t) 
+      ;; but leave a b c-> (accent) alone, accounting for whitespace
+      '("\\([^\\t\\n _^-]\\|^\\)\\s-*\\(>\\)" 2 font-lock-warning-face t)
+      ;; ties ~, slurs (), hairpins \<,  \>, end-of-hairpin \!, 
       '("\\([(~)]\\|\\\\<\\|\\\\!\\|\\\\>\\)" 0 font-lock-builtin-face t)
 
 ;; highlight comments (again)
@@ -169,9 +171,9 @@
           (lambda (x) (modify-syntax-entry
                        (car x) (cdr x) LilyPond-mode-syntax-table)))
          '(( ?\( . "." ) ( ?\) . "." ) 
-           ( ?\[ . "(]" ) ( ?\] . ")[" )
-           ( ?\{  .  "(}2b" )
-           ( ?\}  .  "){4b" )
+           ( ?\[ . "(]" ) ( ?\] . ")[" ) ;; all the other paren characters are now 
+handled by          
+           ( ?\{  .  ".2b" )             ;; lily-specific indenting/matching code in 
+lilypond-indent.el 
+           ( ?\}  .  ".4b" )              
            ( ?\< . "." )( ?\> . ".") 
            ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." )
            ( ?\* . "." ) ( ?\+ . "." )
Index: lilypond-indent.el
===================================================================
RCS file: /home/lilypond/lilypond/lilypond-indent.el,v
retrieving revision 1.1
diff -p -u -r1.1 lilypond-indent.el
--- lilypond-indent.el  1 Feb 2002 16:44:12 -0000       1.1
+++ lilypond-indent.el  6 Apr 2002 14:35:47 -0000
@@ -249,27 +249,61 @@ Argument LIM limit."
        (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 "\\|")))
-
+;; Key:   Type of bracket (character). 
+;; Value: Pair of regexps representing the corresponding open and close bracket"
+;; () are treated specially (need to indent in Scheme but not in music), and []
+;; are handled by the syntax table
 
-(defun LilyPond-beginning-of-containing-sexp ()
-  "Move point to the beginning of the deepest parenthesis pair enclosing point."
+(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-alist
+  `( ( ?<  .  ?> )    
+     ( ?{  .  ?} )    
+     ( ?\(  .  ?\) )
+     ))
+
+
+(defun LilyPond-matching-paren (bracket-type)
+  "Returns the open corresponding to the close specified by bracket-type, or vice 
+versa"
+  (cond ( (memq bracket-type (mapcar 'car LilyPond-parens-alist))
+         (cdr (assoc bracket-type LilyPond-parens-alist)) )
+       ( (memq bracket-type (mapcar 'cdr LilyPond-parens-alist))
+         (car (rassoc bracket-type LilyPond-parens-alist)) )
+       nil))
+
+
+(defun LilyPond-beginning-of-containing-sexp (&optional bracket-type slur-paren-p)
+  "Move point to the beginning of the deepest parenthesis pair enclosing point. 
+
+If the optional argument bracket-type, a character representing a
+close bracket such as ) or }, is specified, then the parenthesis pairs
+searched are limited to this type.
+
+If the optional argument slur-paren-p is non-nil, then slur
+parentheses () are considered as matching pairs. Otherwise Scheme
+parentheses are considered to be matching pairs, but slurs are not.
+slur-paren-p defaults to nil.
+"
   (interactive)
-  (let ((level 1))
+  (let ( (level 1) 
+        (regexp-alist LilyPond-parens-regexp-alist) 
+        (oldpos (point) ) )
     (if (LilyPond-inside-scheme-p)
-       (setq paren-regexp "(\\|)" inside-scheme t)
-      (setq paren-regexp LilyPond-parens-combined-regexp inside-scheme nil))
+       (setq paren-regexp "(\\|)")
+      (if slur-paren-p
+         (setq regexp-alist (cons '( ?\) . ("(" . ")")) regexp-alist)))
+      (if (memq bracket-type (mapcar 'car regexp-alist))
+         (progn (setq paren-regexp (cdr (assoc bracket-type regexp-alist)))
+                (setq paren-regexp (concat (car paren-regexp) "\\|" (cdr 
+paren-regexp))))
+       (setq paren-regexp (concat (mapconcat 'car (mapcar 'cdr regexp-alist) "\\|") 
+"\\|"
+                                  (mapconcat 'cdr (mapcar 'cdr regexp-alist) 
+"\\|")))))
     (while (and (> level 0) 
                (re-search-backward paren-regexp nil t)
                (setq match (char-before (match-end 0))))
@@ -285,9 +319,10 @@ Argument LIM limit."
                            (looking-at ".\\s-+<\\|\\({\\|}\\|<\\|>\\|(\\|)\\)<"))
                       (forward-char 1))))))
     (if (looking-at ".<\\|.>") (forward-char 1))
-    (if (/= level 1) 
+    (if (= level 0) 
        (point)
-      nil)))
+      (progn (goto-char oldpos)
+            nil))))
 
 
 (defun LilyPond-inside-scheme-p ()
@@ -314,3 +349,92 @@ Argument LIM limit."
                     (> level 0))))
          t
        nil))))
+
+
+;;; Largely taken from the 'blink-matching-open' in lisp/simple.el in
+;;; the Emacs distribution.
+
+(defun LilyPond-blink-matching-open (bracket-type)
+  "Move cursor momentarily to the beginning of the sexp before
+point. In lilypond files this is used for closing ), } and >, whereas the
+builtin 'blink-matching-open' is used for closing ],  which is in
+the syntax table"
+  (interactive)
+  (let ( (oldpos (point))
+        (level 0) 
+        (mismatch) )
+    (save-restriction
+      (if blink-matching-paren-distance
+         (narrow-to-region (max (point-min)
+                                (- (point) blink-matching-paren-distance))
+                           oldpos)))
+    (if (memq bracket-type '(?> ?}))
+       ;; < { need to be mutually balanced and nested, so search backwards for both 
+of these bracket types 
+       (LilyPond-beginning-of-containing-sexp nil nil)  
+      ;; whereas ( ) slurs within music don't, so only need to search for ( )
+      (LilyPond-beginning-of-containing-sexp bracket-type t))
+    (setq blinkpos (point))
+    (setq mismatch
+         (or (null (LilyPond-matching-paren (char-after blinkpos)))
+             (/= (char-after oldpos)
+                 (LilyPond-matching-paren (char-after blinkpos)))))
+    (if mismatch (progn (setq blinkpos nil)
+                       (message "Mismatched parentheses")))
+    (if blinkpos
+       (if (pos-visible-in-window-p)
+           (and blink-matching-paren-on-screen
+                (sit-for blink-matching-delay))
+         (message
+          "Matches %s"
+          ;; Show what precedes the open in its line, if anything.
+          (if (save-excursion
+                (skip-chars-backward " \t")
+                (not (bolp)))
+              (buffer-substring (progn (beginning-of-line) (point))
+                                (1+ blinkpos))
+            ;; Show what follows the open in its line, if anything.
+            (if (save-excursion
+                  (forward-char 1)
+                  (skip-chars-forward " \t")
+                  (not (eolp)))
+                (buffer-substring blinkpos
+                                  (progn (end-of-line) (point)))
+              ;; Otherwise show the previous nonblank line,
+              ;; if there is one.
+              (if (save-excursion
+                    (skip-chars-backward "\n \t")
+                    (not (bobp)))
+                  (concat
+                   (buffer-substring (progn
+                                       (skip-chars-backward "\n \t")
+                                       (beginning-of-line)
+                                       (point))
+                                     (progn (end-of-line)
+                                            (skip-chars-backward " \t")
+                                            (point)))
+                   ;; Replace the newline and other whitespace with `...'.
+                   "..."
+                   (buffer-substring blinkpos (1+ blinkpos)))
+                ;; There is nothing to show except the char itself.
+                (buffer-substring blinkpos (1+ blinkpos))))))))
+    (goto-char oldpos)))
+
+
+(defun LilyPond-electric-close-paren ()
+  "Blink on the matching open paren when a > or ) is inserted"
+  (interactive)
+  (let ((oldpos (point)))
+    (self-insert-command 1)
+    (setq close-char (char-before (point)))
+    (if (and blink-matching-paren
+            (not (LilyPond-inside-string-or-comment-p))
+            (save-excursion (re-search-backward 
+                             (concat (mapconcat 'cdr (mapcar 'cdr 
+LilyPond-parens-regexp-alist) "\\|") "\\|)") nil t)
+                            (eq oldpos (1- (match-end 0)))))
+       (progn (backward-char 1)
+              (LilyPond-blink-matching-open close-char)
+              (forward-char 1)))))
+
+
+;;; TODO:
+;;; emulate show-paren-mode 
Index: lilypond-mode.el
===================================================================
RCS file: /home/lilypond/lilypond/lilypond-mode.el,v
retrieving revision 1.28
diff -p -u -r1.28 lilypond-mode.el
--- lilypond-mode.el    17 Mar 2002 18:22:19 -0000      1.28
+++ lilypond-mode.el    6 Apr 2002 14:35:48 -0000
@@ -487,6 +487,9 @@ command."
   (define-key LilyPond-mode-map "\C-cn" 'LilyPond-insert-tag-notes)
   (define-key LilyPond-mode-map "\C-cs" 'LilyPond-insert-tag-score)
   (define-key LilyPond-mode-map "\C-c;" 'comment-region)
+  (define-key LilyPond-mode-map ")" 'LilyPond-electric-close-paren)
+  (define-key LilyPond-mode-map ">" 'LilyPond-electric-close-paren)
+  (define-key LilyPond-mode-map "}" 'LilyPond-electric-close-paren)
   )
 
 ;;; Menu Support

Reply via email to