]> git.donarmstrong.com Git - lilypond.git/blob - mudela-mode.el
release: 1.1.43
[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 '("alternative" "repeat"
35                      "accepts" "accidentals" "break" "bar" "cadenza" 
36                      "clef" "cm" "consists" "consistsend" "contains" "duration" 
37                      "spanrequest" "scmfile" "lyrics"
38                      "in" "translator" "context" "key" "maininput" "notes"
39                      "musical_pitch" "time" "midi" "mm" "header"
40                      "notenames" "octave" "output" "partial" "paper" "plet" "name"
41                      "property" "pt" "shape" "relative" "include" "score"
42                      "scm" "scmfile"
43                      "script" "skip"  "table" "times" "textscript" "symboltables" "type"
44                      "tempo" "transpose" "version" "grouping"
45                      ))
46        (kwregex (mapconcat (lambda (x) (concat "\\\\" x))  keywords "\\|")))
47
48     (list 
49       (concat ".\\(" kwregex "\\)[^a-zA-Z]")
50       (concat "^\\(" kwregex "\\)[^a-zA-Z]")
51       '(".\\(\\\\[a-zA-Z][a-zA-Z]*\\)" 1 font-lock-variable-name-face)
52       '("^[\t ]*\\([a-zA-Z][_a-zA-Z]*\\) *=" 1 font-lock-variable-name-face)     
53     ))
54   "Additional expressions to highlight in Mudela mode.")
55
56 ;; define a mode-specific abbrev table for those who use such things
57 (defvar mudela-mode-abbrev-table nil
58   "Abbrev table in use in `mudela-mode' buffers.")
59
60 (define-abbrev-table 'mudela-mode-abbrev-table nil)
61
62 (defvar mudela-mode-hook nil
63   "*Hook called by `mudela-mode'.")
64
65 (defvar mu-mode-map ()
66   "Keymap used in `mudela-mode' buffers.")
67
68 (defun mu-newline-and-indent ()
69   (interactive)
70   (newline)
71   (indent-relative-maybe)
72   "Newline and copy previous indentation")
73
74 (if mu-mode-map
75     ()
76   (setq mu-mode-map (make-sparse-keymap))
77
78   (mapcar (function (lambda (key)
79                       (define-key
80                         mu-mode-map key 'mu-newline-and-indent)))
81    (where-is-internal 'newline-and-indent))
82
83   (mapcar (function
84            (lambda (x)
85              (define-key mu-mode-map (car x) (cdr x))))
86           '(("\C-c\C-c"  . mu-foo-bar)
87             ))
88   ;; should do all keybindings this way
89   (define-key mu-mode-map [RET] 'mu-newline-and-indent)
90   ) 
91
92 (defvar mu-mode-syntax-table nil
93   "Syntax table used in `mudela-mode' buffers.")
94
95 ;;
96 (if mu-mode-syntax-table
97     ()
98   (setq mu-mode-syntax-table (make-syntax-table))
99   (mapcar (function
100            (lambda (x) (modify-syntax-entry
101                         (car x) (cdr x) mu-mode-syntax-table)))
102           '(( ?\( . "." ) ( ?\) . "." )
103             ( ?\[ . "." ) ( ?\] . "." )
104             ( ?\{ . "(}" ) ( ?\} . "){" )
105             ( ?\< . "(>" )( ?\> . ")>") 
106             ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." )
107             ( ?\* . "." ) ( ?\+ . "." ) ( ?\- . "." )
108             ( ?\/ . "." )  ( ?\= . "." )
109             ( ?\| . "." ) (?\\ . "\\" )
110             ( ?\_ . "." )       
111             ( ?\' . "w")        
112             ( ?\" . "\"" )
113             ( ?\% . "<")
114             ( ?\n . ">")
115
116 ; FIXME
117 ;           ( ?%  .  ". 124b" )
118 ;           ( ?{  .  ". 23" )
119             ))
120
121   )     
122
123 (defconst mu-blank-or-comment-re "[ \t]*\\($\\|%\\)"
124   "Regexp matching blank or comment lines.")
125
126 (defconst mu-imenu-generic-re "^\\([a-zA-Z_][a-zA-Z0-9_]*\\) *="
127   "Regexp matching Identifier definitions.")
128
129 ;; Sadly we need this for a macro in Emacs 19.
130 (eval-when-compile
131   ;; Imenu isn't used in XEmacs, so just ignore load errors.
132   (condition-case ()
133       (require 'imenu)
134     (error nil)))
135
136 (defvar mu-imenu-generic-expression
137   (list (list nil mu-imenu-generic-re 1))
138   "Expression for imenu")
139
140 (defun mudela-mode ()
141   "Major mode for editing Mudela files."
142
143   (interactive)
144   ;; set up local variables
145   (kill-all-local-variables)
146   (make-local-variable 'font-lock-defaults)
147   (make-local-variable 'paragraph-separate)
148   (make-local-variable 'paragraph-start)
149   (make-local-variable 'require-final-newline)
150   (make-local-variable 'comment-start)
151   (make-local-variable 'block-comment-start)
152   (make-local-variable 'block-comment-end)  
153
154   (setq comment-end "\n"
155         comment-start          "%"
156         comment-start-skip     "%{? *"
157         block-comment-start     "%{"
158         block-comment-end       "%}"    
159         )
160   (make-local-variable 'comment-end)
161   (make-local-variable 'comment-start-skip)
162   (setf comment-start-skip "%{")
163   (make-local-variable 'comment-column)
164   (make-local-variable 'imenu-generic-expression)
165   (setq imenu-generic-expression mu-imenu-generic-expression)
166   (make-local-variable 'indent-line-function)
167  
168   ;;
169   (set-syntax-table mu-mode-syntax-table)
170   (setq major-mode             'mudela-mode
171         mode-name              "Mudela"
172         local-abbrev-table     mudela-mode-abbrev-table
173         font-lock-defaults     '(mudela-font-lock-keywords)
174         paragraph-separate     "^[ \t]*$"
175         paragraph-start        "^[ \t]*$"
176         require-final-newline  t
177         comment-column         40
178         indent-line-function    'indent-relative-maybe
179         )
180   (use-local-map mu-mode-map)
181
182   ;; run the mode hook. mu-mode-hook use is deprecated
183   (run-hooks 'mudela-mode-hook)
184 )
185
186
187 (defun mu-keep-region-active ()
188   ;; do whatever is necessary to keep the region active in XEmacs.
189   ;; Ignore byte-compiler warnings you might see.  Also note that
190   ;; FSF's Emacs 19 does it differently and doesn't its policy doesn't
191   ;; require us to take explicit action.
192   (and (boundp 'zmacs-region-stays)
193        (setq zmacs-region-stays t)))
194
195
196 (defun mu-comment-region (beg end &optional arg)
197   "Like `comment-region' but uses double hash (`#') comment starter."
198   (interactive "r\nP")
199   (let ((comment-start mu-block-comment-prefix))
200     (comment-region beg end arg)))
201 \f
202 (defconst mu-version "0.0.1"
203   "`mudela-mode' version number.")
204 (defconst mu-help-address "hanwen@cs.uu.nl"
205   "Address accepting submission of bug reports.")
206
207 (defun mu-version ()
208   "Echo the current version of `mudela-mode' in the minibuffer."
209   (interactive)
210   (message "Using `mudela-mode' version %s" mu-version)
211   (mu-keep-region-active))
212
213 (provide 'mu-mode)
214 ;;; mudela-mode.el ends here