]> git.donarmstrong.com Git - lilypond.git/blobdiff - lilypond-mode.el
updates
[lilypond.git] / lilypond-mode.el
index 3e5053befd75c142d1f226ccb09cfd8b92cbc980..6b5fea2f3e5ec6fc6c6fd3ab0b0b94131049936f 100644 (file)
@@ -3,7 +3,7 @@
 ;;;
 ;;; source file of the GNU LilyPond music typesetter
 ;;;  
-;;; (c) 1999--2001 Jan Nieuwenhuizen <janneke@gnu.org>
+;;; (c)  1999--2003 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;; 
 ;;; Changed 2001--2003 Heikki Junes <heikki.junes@hut.fi>
 ;;;    * Add PS-compilation, PS-viewing and MIDI-play (29th Aug 2001)
 ;;; Look lilypond-init.el or Documentation/topdocs/INSTALL.texi
 ;;; for installing instructions.
 
-;;; TODO:
-;;;    * XEmacs, broken ?
-;;;    * parenthesis matching
-
 (require 'easymenu)
 (require 'compile)
 
-(defconst LilyPond-version "1.7.12"
+(defconst LilyPond-version "1.7.18"
   "`LilyPond-mode' version number.")
 
 (defconst LilyPond-help-address "bug-lilypond@gnu.org"
@@ -35,6 +31,9 @@
 (defvar LilyPond-mode-hook nil
   "*Hook called by `LilyPond-mode'.")
 
+(defvar LilyPond-region-file-prefix "emacs-lily"
+  "File prefix for commands on buffer or region.")
+
 ;; FIXME: find ``\score'' in buffers / make settable?
 (defun LilyPond-master-file ()
   ;; duh
@@ -65,17 +64,20 @@ Finds file lilypond-words from load-path."
       (setq fn (concat (car lp) "/" words-file))
       (if (not (file-readable-p fn)) 
          (progn (setq fn nil) (setq lp (cdr lp)))))
+    (if (not fn)
+       (progn (message "Warning: `lilypond.words' not found in `load-path'. See `lilypond-init.el'.")
+              (sit-for 5 0)))
     fn))
 
 (defun LilyPond-add-dictionary-word (x)
-  "Contains all words: keywords, identifiers, reserved words."
+  "Contains all words: \keywords \Identifiers and ReservedWords."
   (nconc '(("" . 1)) x))
 
 ;; creates dictionary if empty
-(if (eq (length (LilyPond-add-dictionary-word ())) 1)
+(if (and (eq (length (LilyPond-add-dictionary-word ())) 1)
+        (not (eq (LilyPond-words-filename) nil)))
     (progn
-      (setq fn (LilyPond-words-filename))
-      (setq b (find-file-noselect fn t t))
+      (setq b (find-file-noselect (LilyPond-words-filename) t t))
       (setq m (set-marker (make-marker) 1 (get-buffer b)))
       (setq i 1)
       (while (> (buffer-size b) (marker-position m))
@@ -95,6 +97,8 @@ Finds file lilypond-words from load-path."
                     (string-equal (downcase (car co)) (car co)))
                (add-to-list 'wordlist (car co))))
        (setq co (cdr co)))
+      (if (eq (length wordlist) 0)
+         (setq wordlist '("\\score"))) ; add \keywords to lilypond.words
       wordlist))
   "LilyPond \\keywords")
 
@@ -108,6 +112,8 @@ Finds file lilypond-words from load-path."
                     (not (string-equal (downcase (car co)) (car co))))
                (add-to-list 'wordlist (car co))))
        (setq co (cdr co)))
+      (if (eq (length wordlist) 0)
+         (setq wordlist '("\\voiceOne"))) ; add \Identifiers to lilypond.words
       wordlist))
   "LilyPond \\Identifiers")
 
@@ -120,6 +126,8 @@ Finds file lilypond-words from load-path."
            (if (not (string-equal "\\" (substring (car co) 0 1)))
                (add-to-list 'wordlist (car co))))
        (setq co (cdr co)))
+      (if (eq (length wordlist) 0)
+         (setq wordlist '("Staff"))) ; add ReservedWords to lilypond.words
       wordlist))
   "LilyPond ReservedWords")
 
@@ -298,7 +306,9 @@ in LilyPond-include-path."
 (defun LilyPond-string-current-midi ()
   "Check the midi file of the following midi-score in the current document."
   (interactive)
-  (let ((fnameprefix (substring (LilyPond-master-file) 0 -3)) ; suppose ".ly"
+  (let ((fnameprefix (if (eq LilyPond-command-current 'LilyPond-command-master)
+                        (substring (LilyPond-master-file) 0 -3); suppose ".ly"
+                      LilyPond-region-file-prefix))
        (allcount (string-to-number (substring (count-midi-words) 0 -12)))
        (count (string-to-number (substring (count-midi-words-backwards) 0 -12))))
     (concat  fnameprefix
@@ -311,7 +321,9 @@ in LilyPond-include-path."
 (defun LilyPond-string-all-midi ()
   "Return the midi files of the current document in ascending order."
   (interactive)
-  (let ((fnameprefix (substring (LilyPond-master-file) 0 -3))
+  (let ((fnameprefix (if (eq LilyPond-command-current 'LilyPond-command-master)
+                        (substring (LilyPond-master-file) 0 -3); suppose ".ly"
+                      LilyPond-region-file-prefix))
        (allcount (string-to-number (substring (count-midi-words) 0 -12))))
     (concat (if (> allcount 0)  ; at least one midi-score
                (concat fnameprefix ".midi "))
@@ -420,7 +432,7 @@ Must be the car of an entry in `LilyPond-command-alist'."
 
 (defun LilyPond-command-query (name)
   "Query the user for what LilyPond command to use."
-  (let* ((default (cond ((if (string-equal name "emacs-lily")
+  (let* ((default (cond ((if (string-equal name LilyPond-region-file-prefix)
                             (LilyPond-check-files (concat name ".tex")
                                                   (list name)
                                                   LilyPond-file-extensions)
@@ -496,7 +508,7 @@ Must be the car of an entry in `LilyPond-command-alist'."
   (LilyPond-command (LilyPond-command-menu "ViewPS") 'LilyPond-master-file)
 )
 
-;; FIXME, does not find commend ender
+;;; Refer to syntax-table (in lilypond-font-lock.el) for comment characters.
 (defun LilyPond-un-comment-region (start end level)
   "Remove up to LEVEL comment characters from each line in the region."
   (interactive "*r\np") 
@@ -508,7 +520,7 @@ Must be the car of an entry in `LilyPond-command-alist'."
        ;; (dir "/tmp/")
        ;; urg
        (dir "./")
-       (base "emacs-lily")
+       (base LilyPond-region-file-prefix)
        ;; Hmm
        (ext (if (string-match "^[\\]score" (buffer-substring begin end))
                 ".ly"
@@ -667,10 +679,11 @@ command."
   (define-key LilyPond-mode-map "\C-cs" 'LilyPond-insert-tag-score)
   (define-key LilyPond-mode-map "\C-c:" 'LilyPond-un-comment-region)
   (define-key LilyPond-mode-map "\C-c;" 'comment-region)
-  (define-key LilyPond-mode-map ")" 'LilyPond-electric-close-paren) ; urgh
-  (define-key LilyPond-mode-map ">" 'LilyPond-electric-close-paren) ; argh
-  (define-key LilyPond-mode-map "}" 'LilyPond-electric-close-paren) ; ..rgh
-  (define-key LilyPond-mode-map [S-iso-lefttab] 'LilyPond-autocompletion)
+  (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)
+  (define-key LilyPond-mode-map [iso-lefttab] 'LilyPond-autocompletion) ; Emacs
+  (define-key LilyPond-mode-map [iso-left-tab] 'LilyPond-autocompletion) ; XEmacs
   (define-key LilyPond-mode-map "\C-c\t" 'LilyPond-info-index-search)
   )
 
@@ -680,16 +693,17 @@ command."
   "Insert notes with fewer key strokes by using a simple keyboard piano."
   (interactive)
   (setq dutch-notes
-       '(("k" "a") ("l" "b") ("a" "c") ("s" "d") 
-         ("d" "e") ("f" "f") ("j" "g") ("r" "r")))
+       '(("k" "a") ("l" "b") ("a" "c") ("s" "d")
+         ("d" "e") ("f" "f") ("j" "g") ("r" "r")))
   (setq dutch-note-ends '("eses" "es" "" "is" "isis"))
   (setq dutch-note-replacements '("" ""))
   (setq finnish-note-replacements
-       '(("eeses" "eses") ("ees" "es") ("aeses" "asas") ("aes" "as") ("b" "h")
-         ("beses" "heses") ("bes" "b") ("bis" "his") ("bisis" "hisis")))
-                             ; add more translations of the note names
+       '(("eeses" "eses") ("ees" "es") ("aeses" "asas") ("aes" "as") ("b" "h")
+         ("beses" "heses") ("bes" "b") ("bis" "his") ("bisis" "hisis")))
+                             ; add more translations of the note names
   (setq spanish-note-replacements
-       '(("c" "do") ("d" "re") ("e" "mi") ("f" "fa") ("g" "sol") ("a" "la") ("b" "si")
+       '(("c" "do") ("d" "re") ("e" "mi") ("f" "fa") ("g" "sol") ("a" "la") ("b
+" "si")
       ("cis" "dos") ("cisis" "doss") ("ces" "dob") ("ceses" "dobb")
       ("dis" "res") ("disis" "ress") ("des" "reb") ("deses" "rebb")
       ("eis" "mis") ("eisis" "miss") ("ees" "mib") ("eeses" "mibb")
@@ -700,38 +714,42 @@ command."
   (setq other-keys "()<>~}")
   (setq accid 0) (setq octav 0) (setq durat "") (setq dots 0)
 
-  (message "Press h for help.") (sit-for 0 750 1)
+  (message "Press h for help.") (sit-for 0 750)
 
   (setq note-replacements dutch-note-replacements)
-  (while (not (= 27 ; esc to quit
-    (setq x (read-char-exclusive 
-            (format " | a[_]s[_]d | f[_]j[_]k[_]l | r with ie ,' 12345678 . 0 (<~>)/}\\b\\n Esc \n | c | d | e | f | g | a | %s | r with %s%s%s%s"
-                    (if (string= (car(cdr(assoc "b" note-replacements))) "h")
-                        "h" "b")
+  (setq xkey 0) (setq xinitpoint (point))
+  (< xinitpoint (point))
+  (while (not (= xkey 27)) ; esc to quit
+    (message (format " a[]s[]d f[]j[]k[]l r with %4s%-4s%3s%-4s ie ,' 12345678 . 0 (<~>)/}b\\b\\n Esc"
                     (nth (+ accid 2) dutch-note-ends)
-                    (make-string (abs octav) (if (> octav 0) ?' ?,)) 
-                    durat 
-                    (if (string= durat "") "" (make-string dots ?.)))))))
-    ;; (insert (number-to-string x)) ; test numbers for characters
-    (setq note (cdr (assoc (char-to-string x) dutch-notes)))
-    (cond
-     ((= x 127) (backward-kill-word 1)) ; backspace
-     ((= x 13) (progn (insert "\n") (LilyPond-indent-line)))) ; return
-    (setq x (char-to-string x))
+                    (make-string (abs octav) (if (> octav 0) ?' ?,))
+                    durat
+                    (if (string= durat "") "" (make-string dots ?.))))
+    (setq xkey (read-char-exclusive))
+    (setq x (char-to-string xkey))
+    (setq note (cdr (assoc x dutch-notes)))
     (cond
+     ((string= x "q") (progn (setq xkey 27))) ; quit
+     ((= xkey 13) (progn (insert "\n") (LilyPond-indent-line))) ; return
+     ((or (= xkey 127) (string= x "b")) ; backspace is a char only in Emacs
+      (progn (narrow-to-region xinitpoint (point))
+            (backward-kill-word 1)
+            (widen)))
      ((and (string< x "9") (string< "0" x))
       (progn (setq durat (int-to-string (expt 2 (- (string-to-int x) 1))))
-            (setq dots 0)))
+             (setq dots 0)))
      ((string= x " ") (insert " "))
      ((string= x "/") (progn (insert "\\times ")
-                            (while (not (and (string< x "9") (string< "0" x)))
-                              (setq x (char-to-string (read-char-exclusive "Insert a number for the denominator (\"x/\")"))))
-                            (insert (format "%s/" x)) (setq x "/")
-                            (while (not (and (string< x "9") (string< "0" x)))
-                              (setq x (char-to-string (read-char-exclusive "Insert a number for the numerator (\"/y\")"))))
-                            (insert (format "%s { " x))))
-     ((string= x "0") (progn (setq accid 0) (setq octav 0) 
-                            (setq durat "") (setq dots 0)))
+                            (message "Insert a number for the denominator (\"x/\")")
+                             (while (not (and (string< x "9") (string< "0" x)))
+                               (setq x (char-to-string (read-char-exclusive))))
+                             (insert (format "%s/" x)) (setq x "/")
+                            (message "Insert a number for the numerator (\"/y\")")
+                             (while (not (and (string< x "9") (string< "0" x)))
+                               (setq x (char-to-string (read-char-exclusive))))
+                             (insert (format "%s { " x))))
+     ((string= x "0") (progn (setq accid 0) (setq octav 0)
+                             (setq durat "") (setq dots 0)))
      ((string= x "i") (setq accid (if (= accid 2) 0 (max (+ accid 1) 1))))
      ((string= x "e") (setq accid (if (= accid -2) 0 (min (+ accid -1) -1))))
      ((string= x "'") (setq octav (if (= octav 4) 0 (max (+ octav 1) 1))))
@@ -741,37 +759,37 @@ command."
       (insert (format "%s " x)))
      ((not (null note))
       (progn
-       (setq note 
-             (format "%s%s" (car note) (if (string= "r" (car note)) "" 
-                                         (nth (+ accid 2) dutch-note-ends))))
-       (setq notetwo (car (cdr (assoc note note-replacements))))
-       (if (not (null notetwo)) (setq note notetwo))
-       (insert
-        (format "%s%s%s%s " 
-                note
-                (if (string= "r" note) ""
-                    (make-string (abs octav) (if (> octav 0) ?' ?,)))
-                durat
-                (if (string= durat "") "" (make-string dots ?.))))
-       (setq accid 0) (setq octav 0) (setq durat "") (setq dots 0)))
+        (setq note
+              (format "%s%s" (car note) (if (string= "r" (car note)) ""
+                                          (nth (+ accid 2) dutch-note-ends))))
+        (setq notetwo (car (cdr (assoc note note-replacements))))
+        (if (not (null notetwo)) (setq note notetwo))
+        (insert
+         (format "%s%s%s%s "
+                 note
+                 (if (string= "r" note) ""
+                     (make-string (abs octav) (if (> octav 0) ?' ?,)))
+                 durat
+                 (if (string= durat "") "" (make-string dots ?.))))
+        (setq accid 0) (setq octav 0) (setq durat "") (setq dots 0)))
      ((string= x "t") (progn (setq note-replacements dutch-note-replacements)
-                            (message "Selected Dutch notes") 
-                            (sit-for 0 750 1))) ; t
+                             (message "Selected Dutch notes")
+                             (sit-for 0 750)))
      ((string= x "n") (progn (setq note-replacements finnish-note-replacements)
-                            (message "Selected Finnish/Deutsch notes") 
-                            (sit-for 0 750 1))) ; n
-                             ; add more translations of the note names
+                             (message "Selected Finnish/Deutsch notes")
+                             (sit-for 0 750)))
+                              ; add more translations of the note names
      ((string= x "p") (progn (setq note-replacements spanish-note-replacements)
-                            (message "Selected Spanish notes") 
-                            (sit-for 0 750 1))) ; p
-     ((string= x "h") 
-      (progn (message "Insert notes with fewer key strokes. For example \"i,5.f\" produces \"fis,32. \".") (sit-for 5 0 1) 
-            (message "Add also \"a ~ a\"-ties, \"a ( ) b\"-slurs and \"< a b >\"-chords.") (sit-for 5 0 1) 
-            (message "Note names are in Du(t)ch by default. Hit 'n' for Fin(n)ish/Deutsch note names. Hit 'p' for S(p)anish note names") (sit-for 5 0 1) 
-            (message "Backspace deletes last note, return starts a new indented line and Esc quits.") (sit-for 5 0 1) 
-            (message "Insert note triplets \"\\times 2/3 { a b } \" by typing \"/23ab}\".") (sit-for 5 0 1) 
-            (message "Remember to add all other details as well.") (sit-for 5 0 1)))
-    )))
+                             (message "Selected Spanish notes")
+                             (sit-for 0 750)))
+     ((string= x "h")
+      (progn (message "Insert notes with fewer key strokes. For example \"i,5.f\" produces \"fis,32. \".") (sit-for 5 0)
+             (message "Add also \"a ~ a\"-ties, \"a ( ) b\"-slurs and \"< a b >\"-chords.") (sit-for 5 0)
+             (message "There are Du(t)ch, Fin(n)ish/Deutsch (hit 'n') and S(p)anish note names.") (sit-for 5 0)
+             (message "(B)ackspace deletes last note, Ret starts a new indented line and Esc (q)uits.") (sit-for 5 0)
+             (message "Insert note triplets \"\\times 2/3 { a b } \" by typing \"/23ab}\".") (sit-for 5 0)
+             (message "This mode is experimental. Use normal mode to add further details.") (sit-for 5 0)))))
+  (message "Normal editing mode."))
 
 (defun LilyPond-pre-word-search ()
   "Fetch the alphabetic characters and \\ in front of the cursor."
@@ -825,7 +843,7 @@ command."
          (setq compsstr (concat compsstr "\"" (car complist) "\" "))
          (setq complist (cdr complist)))
        (message compsstr) 
-       (sit-for 0 100 1)))))
+       (sit-for 0 100)))))
 
 (defun LilyPond-info ()
   "Launch Info for lilypond."
@@ -1068,10 +1086,18 @@ LilyPond-xdvi-command\t\tcommand to display dvi files -- bit superfluous"
   (setq local-abbrev-table LilyPond-mode-abbrev-table)
   (use-local-map LilyPond-mode-map)
 
+  ;; In Emacs blink-...-on-screen needs to be declared (, not in XEmacs).
+  (make-local-variable 'blink-matching-paren-on-screen)
+  (setq blink-matching-paren-on-screen t)
+
   (make-local-variable 'imenu-generic-expression)
   (setq imenu-generic-expression LilyPond-imenu-generic-expression)
   (imenu-add-to-menubar "Index")
 
+  ;; In XEmacs one needs to use 'easy-menu-add' (, not in Emacs).
+  (easy-menu-add LilyPond-mode-menu)
+  (easy-menu-add LilyPond-command-menu)
+
   ;; run the mode hook. LilyPond-mode-hook use is deprecated
   (run-hooks 'LilyPond-mode-hook))