;;;; Hacks for Lilypond work (use-package lilypond-mode :load-path "elisp-git/lilypond/elisp" :bind (("C-c C-i" . LilyPond-info) ("M-]" . set-selective-display) :map LilyPond-mode-map ("M-p" . cp-backward-def) ("M-n" . cp-forward-def) ("M-P" . cp-upper-level) ("M-N" . cp-lower-level) ("C-c C-w" . cp-ly-wrap-para)) :commands LilyPond-mode :load-path "../user/" :mode (("\\.ly$" . LilyPond-mode) ("\\.ily$" . LilyPond-mode)) :config (--map (add-hook 'LilyPond-mode-hook it) '(subword-mode (lambda () (turn-on-font-lock)))) (defalias 'string-to-int #'string-to-number) (defvar cp/ly-definition-rx '(and bol (1+ (any "a-z" "A-Z" "\\\\")) (1+ (any "a-z" "A-Z" "\\\\" " ")) (any "{" "=" "#"))) (defun cp-backward-def () (interactive) (unless (region-active-p) (push-mark)) (re-search-backward (rx-to-string cp/ly-definition-rx) nil t) (beginning-of-line) (recenter)) (defun cp-forward-def () (interactive) (let* ((regex (rx-to-string cp/ly-definition-rx)) (count (if (looking-at-p regex) 2 1))) (unless (region-active-p) (push-mark)) ;; (forward-char) (if (not (re-search-forward regex nil t count)) (re-search-forward "^}" nil t)) ;; (re-search-forward "^[\\a-zA-Z]" nil t) (beginning-of-line) (recenter))) ;; (defun cp-backward-def () ;; (interactive) ;; (re-search-backward "\(^\\\\?[a-zA-Z]\|^ *\\[a-zA-Z]\)") ;; (beginning-of-line)) ;; (defun cp-forward-def () ;; (interactive) ;; (forward-char) ;; (re-search-forward "\(^\\\\?[a-zA-Z]\|^ *\\[a-zA-Z]\)") ;; (beginning-of-line)) (defun cp-upper-level () (interactive) (re-search-backward "{")) (defun cp-lower-level () (interactive) (if (equal (string (char-after)) "{") (forward-char)) (if (not (re-search-forward "{")) (message "At deepest level.")) (backward-char)) ;; (defun cp-lilypond-enclose-<< () ;; (interactive) ;; (if (equal (string (char-after)) "\\") ;; (progn (insert "<< ") ;; (search-forward "{") ;; (backward-char) ;; (forward-sexp)))) ;; if at a \new ... block - enclose expression ;; otherwise, enclose current position and after the first bar check ;; found ;; if region is active, enclose beginning and end ;; (defun cp-lilypond-enclose-<< () ;; (interactive) ;; (if (equal (thing-at-point 'sexp) ;; "\\new") ;; (progn ;; (insert "<< ") ;; (newline-and-indent) ;; (search-forward "{") ;; (backward-char) ;; (forward-list) ;; ;; (forward-sexp)) ;; ) ;; ;; (let ((point1 (point))) ;; ;; (next-line) ;; ;; (goto-char point1)) ;; )) ;; (define-key LilyPond-mode-map (kbd "<<") ;; 'cp-lilypond-enclose-<<) ;; If I change files, it's still main.ly that gets compiled; this is ;; good most of the time, but many times I want to compile a part-* ;; file instead. If we compile both main.ly and the respective part-* ;; file every time, it's wasteful. Having to select means giving up ;; the 'effortless-compilation' behaviour. ;; 2017-03-14T00:52:07+0530 - commented out, see cp/after-save ;; (defadvice LilyPond-save-buffer ;; (after lysb activate) ;; ;; (compile "make") ;; (cd (locate-dominating-file (buffer-file-name) ;; "main.ly")) ;; (compile (car compile-history))) ;; ;; (defadvice compile ;; (before compile activate) ;; (if (equal major-mode 'LilyPond-mode) ;; (cd (locate-dominating-file (buffer-file-name) ;; "main.ly")))) ;; TODO - refactor into one COND, with one case per operation. ;; TODO - operate on region as well. (defun cp-ly-wrap-para (arg) "Wrap current paragraph with - \\relative c { ... } with no args, \\repeat { ... } with universal argument, and only braces - { ... } - with null argument. Numeric arg wraps that many paragraphs. TODO - wrap region if region active" (interactive "P") (let ((point-a (point))) (beginning-of-line) (unless (looking-at "[[:blank:]]*$") ;; go to start of paragraph or block, or previous blank line (re-search-backward (rx (or (and bol (0+ blank) eol) (and "{" eol)))) (end-of-line)) (newline-and-indent) (insert (pcase arg (`(,x) "\\repeat {") (0 "{") ;; nil (_ "\\relative c {"))) (let ((indent-start (point))) (forward-paragraph (pcase arg (`(,x) 1) (_ (if (and arg (<= arg 0)) 1 arg)))) (indent-region indent-start (point)) (insert "}") (indent-for-tab-command) (newline) ;; FIXME (goto-char (pcase arg (0 point-a) (_ (- indent-start 2)))))))) ;; TODO - cp-ly-new-var, bind to M-RET. ;; Exits current variable body, if in any, and inserts "| = \relative ;; c {\n\n \n}", where | is the cursor (provide 'cp-lily)