]> git.donarmstrong.com Git - lilypond.git/blob - mudela-mode.el
patch::: 1.2.5.jcn1
[lilypond.git] / mudela-mode.el
1 ;;; mudela-mode.el --- Major mode for editing Mudela programs
2
3
4 ;; Copyright (C) 1992,1993,1994  Tim Peters
5
6 ;; Author: 1997: Han-Wen Nienhuys
7 ;; Author: 1995-1996 Barry A. Warsaw
8 ;;         1992-1994 Tim Peters
9 ;; Created:       Feb 1992
10 ;; Version:       0.0
11 ;; Last Modified: 12SEP97
12 ;; Keywords: mudela languages music
13
14 ;; This software is provided as-is, without express or implied
15 ;; warranty.  Permission to use, copy, modify, distribute or sell this
16 ;; software, without fee, for any purpose and by any individual or
17 ;; organization, is hereby granted, provided that the above copyright
18 ;; notice and this paragraph appear in all copies.
19
20
21
22 ;; Kyrie Eleison; it is my first real Elisp file
23 ;; This is a cannabalised version of python-mode.el (HWN)
24 ;;
25 ;; TODO: 
26 ;; * should handle block comments too.
27 ;; * handle lexer modes (\header, \melodic, \lyric) etc.
28 ;; * indentation
29 ;; * notenames?
30 ;; * fontlock: \melodic \melodic
31 ;; 
32
33 (defconst mudela-font-lock-keywords
34   (let* ((keywords '("spanrequest" "simultaneous" "sequential" "accepts"
35                      "alternative" "bar" "breathe"
36                      "cadenza" "chordmodifiers" "chords" "clef" "cm" "consists"
37                      "consistsend" "context"
38                      "duration" "font" "grace" "header" "in" "lyrics"
39                      "key" "keysignature" "mark" "musicalpitch"
40                      "time" "times" "midi" "mm" "name" "notenames"
41                      "notes" "partial" "paper" "penalty" "property" "pt"
42                      "relative" "remove" "repeat" "repetitions" "addlyrics"
43                      "scm" "scmfile" "score" "script"
44                      "shape" "skip" "textscript" "tempo" "translator" "transpose"
45                      "type" "version" 
46                      ))
47        (kwregex (mapconcat (lambda (x) (concat "\\\\" x))  keywords "\\|")))
48
49     (list 
50       (concat ".\\(" kwregex "\\)[^a-zA-Z]")
51       (concat "^\\(" kwregex "\\)[^a-zA-Z]")
52       '(".\\(\\\\[a-zA-Z][a-zA-Z]*\\)" 1 font-lock-variable-name-face)
53       '("^[\t ]*\\([a-zA-Z][_a-zA-Z]*\\) *=" 1 font-lock-variable-name-face)     
54     ))
55   "Additional expressions to highlight in Mudela mode.")
56
57 ;; define a mode-specific abbrev table for those who use such things
58 (defvar mudela-mode-abbrev-table nil
59   "Abbrev table in use in `mudela-mode' buffers.")
60
61 (define-abbrev-table 'mudela-mode-abbrev-table nil)
62
63 (defvar mudela-mode-hook nil
64   "*Hook called by `mudela-mode'.")
65
66 (defvar mu-mode-map ()
67   "Keymap used in `mudela-mode' buffers.")
68
69 (defun mu-newline-and-indent ()
70   (interactive)
71   (newline)
72   (indent-relative-maybe)
73   "Newline and copy previous indentation")
74
75 (if mu-mode-map
76     ()
77   (setq mu-mode-map (make-sparse-keymap))
78
79   (mapcar (function (lambda (key)
80                       (define-key
81                         mu-mode-map key 'mu-newline-and-indent)))
82    (where-is-internal 'newline-and-indent))
83
84   (mapcar (function
85            (lambda (x)
86              (define-key mu-mode-map (car x) (cdr x))))
87           '(("\C-c\C-c"  . mu-foo-bar)
88             ))
89   ;; should do all keybindings this way
90   (define-key mu-mode-map [RET] 'mu-newline-and-indent)
91   ) 
92
93 (defvar mu-mode-syntax-table nil
94   "Syntax table used in `mudela-mode' buffers.")
95
96 ;;
97 (if mu-mode-syntax-table
98     ()
99   (setq mu-mode-syntax-table (make-syntax-table))
100   (mapcar (function
101            (lambda (x) (modify-syntax-entry
102                         (car x) (cdr x) mu-mode-syntax-table)))
103           '(( ?\( . "." ) ( ?\) . "." )
104             ( ?\[ . "." ) ( ?\] . "." )
105             ( ?\{ . "(}" ) ( ?\} . "){" )
106             ( ?\< . "(>" )( ?\> . ")>") 
107             ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." )
108             ( ?\* . "." ) ( ?\+ . "." ) ( ?\- . "." )
109             ( ?\/ . "." )  ( ?\= . "." )
110             ( ?\| . "." ) (?\\ . "\\" )
111             ( ?\_ . "." )       
112             ( ?\' . "w")        
113             ( ?\" . "\"" )
114             ( ?\% . "<")
115             ( ?\n . ">")
116
117 ; FIXME
118 ;           ( ?%  .  ". 124b" )
119 ;           ( ?{  .  ". 23" )
120             ))
121
122   )     
123
124 (defconst mu-blank-or-comment-re "[ \t]*\\($\\|%\\)"
125   "Regexp matching blank or comment lines.")
126
127 (defconst mu-imenu-generic-re "^\\([a-zA-Z_][a-zA-Z0-9_]*\\) *="
128   "Regexp matching Identifier definitions.")
129
130 ;; Sadly we need this for a macro in Emacs 19.
131 (eval-when-compile
132   ;; Imenu isn't used in XEmacs, so just ignore load errors.
133   (condition-case ()
134       (require 'imenu)
135     (error nil)))
136
137 (defvar mu-imenu-generic-expression
138   (list (list nil mu-imenu-generic-re 1))
139   "Expression for imenu")
140
141 (defun mudela-mode ()
142   "Major mode for editing Mudela files."
143
144   (interactive)
145   ;; set up local variables
146   (kill-all-local-variables)
147   (make-local-variable 'font-lock-defaults)
148   (make-local-variable 'paragraph-separate)
149   (make-local-variable 'paragraph-start)
150   (make-local-variable 'require-final-newline)
151   (make-local-variable 'comment-start)
152   (make-local-variable 'block-comment-start)
153   (make-local-variable 'block-comment-end)  
154
155   (setq comment-end "\n"
156         comment-start          "%"
157         comment-start-skip     "%{? *"
158         block-comment-start     "%{"
159         block-comment-end       "%}"    
160         )
161   (make-local-variable 'comment-end)
162   (make-local-variable 'comment-start-skip)
163   (setq comment-start-skip "%{")        ;??
164   (make-local-variable 'comment-column)
165   (make-local-variable 'imenu-generic-expression)
166   (setq imenu-generic-expression mu-imenu-generic-expression)
167   (make-local-variable 'indent-line-function)
168  
169   ;;
170   (set-syntax-table mu-mode-syntax-table)
171   (setq major-mode             'mudela-mode
172         mode-name              "Mudela"
173         local-abbrev-table     mudela-mode-abbrev-table
174         font-lock-defaults     '(mudela-font-lock-keywords)
175         paragraph-separate     "^[ \t]*$"
176         paragraph-start        "^[ \t]*$"
177         require-final-newline  t
178         comment-column         40
179         indent-line-function    'indent-relative-maybe
180         )
181   (use-local-map mu-mode-map)
182
183   ;; run the mode hook. mu-mode-hook use is deprecated
184   (run-hooks 'mudela-mode-hook)
185 )
186
187
188 (defun mu-keep-region-active ()
189   ;; do whatever is necessary to keep the region active in XEmacs.
190   ;; Ignore byte-compiler warnings you might see.  Also note that
191   ;; FSF's Emacs 19 does it differently and doesn't its policy doesn't
192   ;; require us to take explicit action.
193   (and (boundp 'zmacs-region-stays)
194        (setq zmacs-region-stays t)))
195
196
197 (defun mu-comment-region (beg end &optional arg)
198   "Like `comment-region' but uses double hash (`#') comment starter."
199   (interactive "r\nP")
200   (let ((comment-start mu-block-comment-prefix))
201     (comment-region beg end arg)))
202 \f
203 (defconst mu-version "0.0.1"
204   "`mudela-mode' version number.")
205 (defconst mu-help-address "hanwen@cs.uu.nl"
206   "Address accepting submission of bug reports.")
207
208 (defun mu-version ()
209   "Echo the current version of `mudela-mode' in the minibuffer."
210   (interactive)
211   (message "Using `mudela-mode' version %s" mu-version)
212   (mu-keep-region-active))
213
214 (provide 'mu-mode)
215 ;;; mudela-mode.el ends here