1 ;;; mudela-mode.el --- Major mode for editing Mudela programs
4 ;; Copyright (C) 1992,1993,1994 Tim Peters
6 ;; Author: 1997: Han-Wen Nienhuys
7 ;; Author: 1995-1996 Barry A. Warsaw
8 ;; 1992-1994 Tim Peters
11 ;; Last Modified: 12SEP97
12 ;; Keywords: mudela languages music
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.
22 ;; Kyrie Eleison; it is my first real Elisp file
23 ;; This is a cannabalised version of python-mode.el (HWN)
26 ;; * should handle block comments too.
27 ;; * handle lexer modes (\header, \melodic, \lyric) etc.
30 ;; * fontlock: \melodic \melodic
32 (defconst mudela-font-lock-keywords
34 "accepts" "break" "bar" "cadenza" "clear" "clef" "cm" "consists" "contains"
35 "duration" "absdynamic" "in" "translator" "type" "lyric" "key"
36 "melodic" "melodic_request" "meter" "midi" "mm" "multi" "header"
37 "notenames" "octave" "output" "partial" "paper" "plet" "property" "pt" "shape"
39 "score" "script" "skip" "staff" "table" "spandynamic" "symboltables"
40 "tempo" "texid" "textstyle" "transpose" "version" "grouping"
42 (kwregex (mapconcat (lambda (x) (concat "\\\\" x
)) keywords
"\\|")))
45 (cons (concat ".\\(" kwregex
"\\)[^a-zA-Z]") 1)
46 (cons (concat "^\\(" kwregex
"\\)[^a-zA-Z]") 1)
47 '(".\\(\\\\[a-zA-Z][a-zA-Z]*\\)" 1 font-lock-variable-name-face
)
48 '("^[\t ]*\\([a-zA-Z][_a-zA-Z]*\\) *=" 1 font-lock-variable-name-face
)
50 "Additional expressions to highlight in Mudela mode.")
52 ;; define a mode-specific abbrev table for those who use such things
53 (defvar mudela-mode-abbrev-table nil
54 "Abbrev table in use in `mudela-mode' buffers.")
56 (define-abbrev-table 'mudela-mode-abbrev-table nil
)
58 (defvar mudela-mode-hook nil
59 "*Hook called by `mudela-mode'.")
61 (defvar mu-mode-map
()
62 "Keymap used in `mudela-mode' buffers.")
64 (defun mu-newline-and-indent ()
67 (indent-relative-maybe)
68 "Newline and copy previous indentation")
72 (setq mu-mode-map
(make-sparse-keymap))
74 (mapcar (function (lambda (key)
76 mu-mode-map key
'mu-newline-and-indent
)))
77 (where-is-internal 'newline-and-indent
))
81 (define-key mu-mode-map
(car x
) (cdr x
))))
82 '(("\C-c\C-c" . mu-foo-bar
)
84 ;; should do all keybindings this way
85 (define-key mu-mode-map
[RET] 'mu-newline-and-indent)
88 (defvar mu-mode-syntax-table nil
89 "Syntax table used in `mudela-mode' buffers.")
92 (if mu-mode-syntax-table
94 (setq mu-mode-syntax-table (make-syntax-table))
96 (lambda (x) (modify-syntax-entry
97 (car x) (cdr x) mu-mode-syntax-table)))
98 '(( ?\( . "()" ) ( ?\) . ")(" )
99 ( ?\[ . "(]" ) ( ?\] . ")[" )
100 ( ?\{ . "(}" ) ( ?\} . "){" )
101 ( ?\< . "(>" )( ?\> . ")>")
102 ( ?\$ . "." ) ( ?\% . "." ) ( ?\& . "." )
103 ( ?\* . "." ) ( ?\+ . "." ) ( ?\- . "." )
104 ( ?\/ . "." ) ( ?\= . "." )
105 ( ?\| . "." ) (?\\ . "\\" )
114 (defconst mu-stringlit-re
115 "\"\\([^\"\n\\]\\|\\\\.\\)*\"" ; double-quoted
116 "Regexp matching a Mudela string literal.")
119 (defconst mu-blank-or-comment-re "[ \t]*\\($\\|%\\)"
120 "Regexp matching blank or comment lines.")
122 (defconst mu-imenu-generic-re "^\\([a-zA-Z_][a-zA-Z0-9_]*\\) *="
123 "Regexp matching Identifier definitions.")
125 ;; Sadly we need this for a macro in Emacs 19.
127 ;; Imenu isn't used in XEmacs, so just ignore load errors.
132 (defvar mu-imenu-generic-expression
133 (list (list nil mu-imenu-generic-re 1))
134 "Expression for imenu")
136 (defun mudela-mode ()
137 "Major mode for editing Mudela files."
140 ;; set up local variables
141 (kill-all-local-variables)
142 (make-local-variable 'font-lock-defaults)
143 (make-local-variable 'paragraph-separate)
144 (make-local-variable 'paragraph-start)
145 (make-local-variable 'require-final-newline)
146 (make-local-variable 'comment-start)
147 (setq comment-start "% ")
148 (setq comment-end "")
149 (make-local-variable 'comment-end)
150 (make-local-variable 'comment-start-skip)
151 (setf comment-start-skip "%{")
152 (make-local-variable 'comment-column)
153 (make-local-variable 'imenu-generic-expression)
154 (setq imenu-generic-expression mu-imenu-generic-expression)
155 (make-local-variable 'indent-line-function)
158 (set-syntax-table mu-mode-syntax-table)
159 (setq major-mode 'mudela-mode
161 local-abbrev-table mudela-mode-abbrev-table
162 font-lock-defaults '(mudela-font-lock-keywords)
163 paragraph-separate "^[ \t]*$"
164 paragraph-start "^[ \t]*$"
165 require-final-newline t
167 comment-start-skip "% *"
169 indent-line-function 'indent-relative-maybe
171 (use-local-map mu-mode-map)
173 ;; run the mode hook. mu-mode-hook use is deprecated
175 (run-hooks 'mudela-mode-hook)
176 (run-hooks 'mu-mode-hook)))
178 (defun mu-keep-region-active ()
179 ;; do whatever is necessary to keep the region active in XEmacs.
180 ;; Ignore byte-compiler warnings you might see. Also note that
181 ;; FSF's Emacs 19 does it differently and doesn't its policy doesn't
182 ;; require us to take explicit action.
183 (and (boundp 'zmacs-region-stays)
184 (setq zmacs-region-stays t)))
187 (defun mu-comment-region (beg end &optional arg)
188 "Like `comment-region' but uses double hash (`#') comment starter."
190 (let ((comment-start mu-block-comment-prefix))
191 (comment-region beg end arg)))
193 (defconst mu-version "0.0.1"
194 "`mudela-mode' version number.")
195 (defconst mu-help-address "hanwen@cs.ruu.nl"
196 "Address accepting submission of bug reports.")
199 "Echo the current version of `mudela-mode' in the minibuffer."
201 (message "Using `mudela-mode' version %s" mu-version)
202 (mu-keep-region-active))
205 ;;; mudela-mode.el ends here