+;;; This mode was originally LilyPond-quick-note-insert by Heikki Junes.
+;;; The original version has been junked since CVS-1.97,
+;;; in order to merge the efforts done by Nicolas Sceaux.
+;;; LilyPond Quick Insert Mode is a major mode, toggled by C-c q.
+(defun LilyPond-quick-insert-mode ()
+ "Insert notes with fewer key strokes by using a simple keyboard piano."
+ (interactive)
+ (progn
+ (message "Invoke (C-c q) from keyboard. If you still see this message,") (sit-for 5 0)
+ (message "then you have not installed LilyPond Quick Insert Mode (lyqi).") (sit-for 5 0)
+ (message "Download lyqi from http://nicolas.sceaux.free.fr/lilypond/lyqi.html,") (sit-for 5 0)
+ (message "see installation instructions from lyqi's README -file.") (sit-for 5 0)
+ (message "You need also eieio (Enhanced Integration of Emacs Interpreted Objects).") (sit-for 5 0)
+ (message "Download eieio from http://cedet.sourceforge.net/eieio.shtml,") (sit-for 5 0)
+ (message "see installation instructions from eieio's INSTALL -file.") (sit-for 5 0)
+ (message "")
+ ))
+
+(defun LilyPond-pre-word-search ()
+ "Fetch the alphabetic characters and \\ in front of the cursor."
+ (let ((pre "")
+ (prelen 0)
+ (ch (char-before (- (point) 0))))
+ (while (and ch (or (and (>= ch 65) (<= ch 90)) ; not bolp, A-Z
+ (and (>= ch 97) (<= ch 122)) ; a-z
+ (= ch 92))) ; \\
+ (setq pre (concat (char-to-string ch) pre))
+ (setq prelen (+ prelen 1))
+ (setq ch (char-before (- (point) prelen))))
+ pre))
+
+(defun LilyPond-post-word-search ()
+ "Fetch the alphabetic characters behind the cursor."
+ (let ((post "")
+ (postlen 0)
+ (ch (char-after (+ (point) 0))))
+ (while (and ch (or (and (>= ch 65) (<= ch 90)) ; not eolp, A-Z
+ (and (>= ch 97) (<= ch 122)))) ; a-z
+ (setq post (concat post (char-to-string ch)))
+ (setq postlen (+ postlen 1))
+ (setq ch (char-after (+ (point) postlen))))
+ post))
+
+(defun LilyPond-autocompletion ()
+ "Show completions in mini-buffer for the given word."
+ (interactive)
+ (let ((pre (LilyPond-pre-word-search))
+ (post (LilyPond-post-word-search))
+ (compsstr ""))
+ ;; insert try-completion and show all-completions
+ (if (> (length pre) 0)
+ (progn
+ (setq trycomp (try-completion pre (LilyPond-add-dictionary-word ())))
+ (if (char-or-string-p trycomp)
+ (if (string-equal (concat pre post) trycomp)
+ (goto-char (+ (point) (length post)))
+ (progn
+ (delete-region (point) (+ (point) (length post)))
+ (insert (substring trycomp (length pre) nil))))
+ (progn
+ (delete-region (point) (+ (point) (length post)))
+ (font-lock-fontify-buffer))) ; only inserting fontifies
+
+ (setq complist (all-completions pre (LilyPond-add-dictionary-word ())))
+ (while (> (length complist) 0)
+ (setq compsstr (concat compsstr "\"" (car complist) "\" "))
+ (setq complist (cdr complist)))
+ (message compsstr)
+ (sit-for 0 100)))))
+
+(defun LilyPond-info ()
+ "Launch Info for lilypond."
+ (interactive)
+ (info "lilypond"))
+
+(defun LilyPond-music-glossary-info ()
+ "Launch Info for music-glossary."
+ (interactive)
+ (info "music-glossary"))
+
+(defun LilyPond-internals-info ()
+ "Launch Info for lilypond-internals."
+ (interactive)
+ (info "lilypond-internals"))
+
+(defun LilyPond-info-index-search ()
+ "In `*info*'-buffer, launch `info lilypond --index-search word-under-cursor'"
+ (interactive)
+ (let ((str (concat (LilyPond-pre-word-search) (LilyPond-post-word-search))))
+ (if (and (> (length str) 0)
+ (string-equal (substring str 0 1) "\\"))
+ (setq str (substring str 1 nil)))
+ (LilyPond-info)
+ (Info-index str)))
+
+(defun LilyPond-insert-tag-current (&optional word)
+ "Set the current tag to be inserted."
+ (interactive)
+ (if word
+ (setq LilyPond-insert-tag-current word))
+ (if (memq LilyPond-insert-tag-current LilyPond-menu-keywords)
+ (LilyPond-insert-tag)
+ (message "No tag was selected from LilyPond->Insert tag-menu.")))
+
+(defun LilyPond-insert-tag ()
+ "Insert syntax for given tag. The definitions are in LilyPond-words-filename."
+ (interactive)
+ (setq b (find-file-noselect (LilyPond-words-filename) t t))
+ (let ((word LilyPond-insert-tag-current)
+ (found nil)
+ (p nil)
+ (query nil)
+ (m (set-marker (make-marker) 1 (get-buffer b)))
+ (distance (if (LilyPond-mark-active)
+ (abs (- (mark-marker) (point-marker))) 0))
+ )
+ ;; find the place first
+ (if (LilyPond-mark-active)
+ (goto-char (min (mark-marker) (point-marker))))
+ (while (and (not found) (> (buffer-size b) (marker-position m)))
+ (setq copy (car (copy-alist (list (eval (symbol-name (read m)))))))
+ (if (string-equal word copy) (setq found t)))
+ (if found (insert word))
+ (if (> (buffer-size b) (marker-position m))
+ (setq copy (car (copy-alist (list (eval (symbol-name (read m))))))))
+ (if (not (string-equal "-" copy))
+ (setq found nil))
+ (while (and found (> (buffer-size b) (marker-position m)))
+ ;; find next symbol
+ (setq copy (car (copy-alist (list (eval (symbol-name (read m)))))))
+ ;; check whether it is the word, or the word has been found
+ (cond
+ ((string-equal "-" copy) (setq found nil))
+ ((string-equal "%" copy) (insert " " (read-string "Give Arguments: ")))
+ ((string-equal "_" copy)
+ (progn
+ (setq p (point))
+ (goto-char (+ p distance))))
+ ((string-equal "\?" copy) (setq query t))
+ ((string-equal "\!" copy) (setq query nil))
+ ((string-equal "\\n" copy)
+ (if (not query)
+ (progn (LilyPond-indent-line) (insert "\n") (LilyPond-indent-line))))
+ ((string-equal "{" copy)
+ (if (not query)
+ (progn (insert " { "))))
+ ((string-equal "}" copy)
+ (if (not query)
+ (progn (insert " } ") (setq query nil) )))
+ ((not query)
+ (insert copy))
+ (query
+ (if (y-or-n-p (concat "Proceed with `" copy "'? "))
+ (progn (insert copy) (setq query nil))))
+ ))
+ (if p (goto-char p))
+ (kill-buffer b))
+)
+