]> git.donarmstrong.com Git - lilypond.git/blobdiff - lilypond-indent.el
* ly/engraver-init.ly (VoiceContext): move Note_head_line_engraver
[lilypond.git] / lilypond-indent.el
index 06cfd50e3a4ec55b5cd29d9059db1876ed37b5f8..3d62982550e1479d1d9a12556122011b746610a1 100644 (file)
@@ -5,6 +5,13 @@
 
 ;;; Variables for customising indentation style
 
+;;; TODO:
+;;;    * emulate show-paren-mode, i.e., highlight the matching bracket if
+;;;      - the cursor is on the matching opening bracket
+;;;      - the cursor is after the matching closing bracket
+;;;    * separate '('- and ')'-slurs from '\('- and '\)'-slurs.
+;;;    * separate '['- and ']'-slurs from '\['- and '\]'-slurs.
+
 (defcustom LilyPond-indent-level 4
   "*Indentation of lilypond statements with respect to containing block.")
 
@@ -16,6 +23,10 @@ Compares with other text in same context.")
   "*Extra indentation for open angled brackets .
 Compares with other text in same context.")
 
+(defcustom LilyPond-square-offset 0
+  "*Extra indentation for open square 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.")
@@ -26,6 +37,9 @@ Compares with other text in same context.")
 (defcustom LilyPond-close-angle-offset 0
   "*Extra indentation for closing angle brackets.")
 
+(defcustom LilyPond-close-square-offset 0
+  "*Extra indentation for closing square brackets.")
+
 (defcustom LilyPond-close-scheme-paren-offset 0
   "*Extra indentation for closing scheme parens.")
 
@@ -98,6 +112,8 @@ Returns nil if line starts inside a string"
                            LilyPond-brace-offset)
                           ((= (following-char) ?<) 
                            LilyPond-angle-offset)
+                          ((= (following-char) ?[) 
+                           LilyPond-square-offset)
                           ((= (following-char) ?\))
                            LilyPond-scheme-paren-offset)
                           (t
@@ -135,12 +151,16 @@ Return the amount the indentation changed by."
               (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-square-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)))
+             ((= (following-char) ?[)
+              (setq indent  (+ indent LilyPond-square-offset)))
              ((and (= (following-char) ?\() (LilyPond-inside-scheme-p))
               (setq indent  (+ indent LilyPond-scheme-paren-offset)))
              ))))
@@ -250,31 +270,37 @@ Argument LIM limit."
 
 
 ;; 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
+;; Value: Pair of regexps representing the corresponding open and close bracket
+;; () are treated specially (need to indent in Scheme but not in music)
 
 (defconst LilyPond-parens-regexp-alist
-  `( ( ?>  .  ("[^\\]<" . "[^ \\n\\t_^-]\\s-*>\\|[_^-]\\s-*[-^]\\s-*>"))
+  `( ( ?>  .  ("\\([^\\]\\|^\\)<" . "[^ \\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
      ( ?}  .  ("{" . "}"))
+     ;; ligatures  '\[ ... \]' are skipped in the following expression
+     ( ?]  .  ("\\([^\\]\\([\\][\\]\\)*\\|^\\)[[]" . "\\([^\\]\\([\\][\\]\\)*\\|^\\)[]]"))
+     ;; ( "\\]" . ("\\([^\\]\\|^\\)\\([\\][\\]\\)*[\\][[]" . "\\([^\\]\\|^\\)\\([\\][\\]\\)*[\\][]]"))
+     ;; ( "\\)" . ("\\([^\\]\\|^\\)\\([\\][\\]\\)*[\\][(]" . "\\([^\\]\\|^\\)\\([\\][\\]\\)*[\\][)]"))
      ))
 
 
 (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))
+  (cond ( (member bracket-type (mapcar 'car LilyPond-parens-alist))
          (cdr (assoc bracket-type LilyPond-parens-alist)) )
-       ( (memq bracket-type (mapcar 'cdr LilyPond-parens-alist))
+       ( (member bracket-type (mapcar 'cdr LilyPond-parens-alist))
          (car (rassoc bracket-type LilyPond-parens-alist)) )
        nil))
 
@@ -291,15 +317,17 @@ 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)
+;;; An user does not call this function directly, or by a key sequence.
+  ;;  (interactive)
   (let ( (level 1) 
         (regexp-alist LilyPond-parens-regexp-alist) 
         (oldpos (point) ) )
     (if (LilyPond-inside-scheme-p)
        (setq paren-regexp "(\\|)")
       (if slur-paren-p
-         (setq regexp-alist (cons '( ?\) . ("(" . ")")) regexp-alist)))
-      (if (memq bracket-type (mapcar 'car regexp-alist))
+         ;; expressional slurs  '\( ... \)' are not taken into account
+         (setq regexp-alist (cons '( ?\) . ("\\([^\\]\\([\\][\\]\\)*\\|^\\)(" . "\\([^\\]\\([\\][\\]\\)*\\|^\\))")) regexp-alist)))
+      (if (member 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) "\\|") "\\|"
@@ -309,16 +337,17 @@ slur-paren-p defaults to nil.
                (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 '(?} ?> ?\)))
+         (if (memq match '(?} ?> ?] ?\)))
              (progn (setq level (1+ level))
                     (if (and (= match ?>) 
-                             (looking-at ".\\s-+>\\|\\({\\|}\\|<\\|>\\|(\\|)\\)>"))
+                             (looking-at ".\\s-+>\\|\\({\\|}\\|<\\|>\\|(\\|)\\|[][]\\)>"))
                         (forward-char 1)))
            (progn (setq level (1- level))
                   (if (and (= match ?<)
-                           (looking-at ".\\s-+<\\|\\({\\|}\\|<\\|>\\|(\\|)\\)<"))
+                           (looking-at ".\\s-+<\\|\\({\\|}\\|<\\|>\\|(\\|)\\|[][]\\)<"))
                       (forward-char 1))))))
-    (if (looking-at ".<\\|.>") (forward-char 1))
+    ;; somehow here two-char brackets \<, \>, \[, \], \(, \) are handled
+    (if (looking-at ".<\\|.>\\|.[][)(]") (forward-char 1))
     (if (= level 0) 
        (point)
       (progn (goto-char oldpos)
@@ -327,7 +356,8 @@ slur-paren-p defaults to nil.
 
 (defun LilyPond-inside-scheme-p ()
   "Tests if point is inside embedded Scheme code"
-  (interactive)
+;;; An user does not call this function directly, or by a key sequence.
+  ;;  (interactive)
   (let ( (test-point (point))
         (level 0) )
     (save-excursion 
@@ -357,20 +387,35 @@ slur-paren-p defaults to nil.
 
 (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)
+point. In lilypond files this is used for closing ), ], } and >, whereas the
+builtin 'blink-matching-open' is not used. In syntax table, see
+`lilypond-font-lock.el', all brackets are punctuation characters."
+;;; An user does not call this function directly, or by a key sequence.
+  ;;  (interactive)
   (let ( (oldpos (point))
         (level 0) 
         (mismatch) )
+    ;; Test if a ligature \] or expressional slur \) was encountered;
+    ;; the result is now in backslashed-close-char, BUT
+    ;; the result should also be used  -- match also \] or \) !
+    ;; Thus, update: LilyPond-parens-regexp-alist, LilyPond-blink-matching-open
+    (setq char-before-bracket-type nil)
+    (if (memq close-char '(?] ?\)))
+      (progn 
+       (setq np -1)
+       (while (eq (char-before (- (point) (setq np (+ np 1)))) ?\\)
+         (setq char-before-bracket-type (if char-before-bracket-type nil ?\\)))))
+    (if (eq char-before-bracket-type ?\\)
+       (if (eq bracket-type ?])
+            (message "trying to match ligatures \\[ ... \\]")
+          (message "trying to match slurs \\( ... \\)")))
     (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 
+    (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))
@@ -422,7 +467,7 @@ the syntax table"
 
 
 (defun LilyPond-electric-close-paren ()
-  "Blink on the matching open paren when a > or ) is inserted"
+  "Blink on the matching open paren when a >, ), } or ] is inserted"
   (interactive)
   (let ((oldpos (point)))
     (self-insert-command 1)
@@ -435,7 +480,3 @@ the syntax table"
        (progn (backward-char 1)
               (LilyPond-blink-matching-open close-char)
               (forward-char 1)))))
-
-
-;;; TODO:
-;;; emulate show-paren-mode