Initial Commit
[packages] / xemacs-packages / sml-mode / sml-defs.el
1 ;;; sml-defs.el --- Various definitions for sml-mode
2
3 ;; Copyright (C) 1999-2000  Stefan Monnier <monnier@cs.yale.edu>
4 ;;
5 ;; This program is free software; you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation; either version 2 of the License, or
8 ;; (at your option) any later version.
9 ;;
10 ;; This program is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ;; GNU General Public License for more details.
14 ;;
15 ;; You should have received a copy of the GNU General Public License
16 ;; along with this program; if not, write to the Free Software
17 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 ;;; Commentary:
20
21
22 ;;; Code:
23
24 (eval-when-compile (require 'cl))
25 (require 'sml-util)
26
27
28 (defgroup sml ()
29   "Editing SML code."
30   :group 'languages)
31
32 (defvar sml-outline-regexp
33   ;; `st' and `si' are to match structure and signature.
34   "\f\\|s[ti]\\|[ \t]*\\(let[ \t]+\\)?\\(fun\\|and\\)\\>"
35   "Regexp matching a major heading.
36 This actually can't work without extending `outline-minor-mode' with the
37 notion of \"the end of an outline\".")
38
39 ;;; 
40 ;;; Internal defines
41 ;;; 
42
43 (defmap sml-mode-map
44   ;; smarter cursor movement
45   '((forward-sexp       . sml-user-forward-sexp)
46     (backward-sexp      . sml-user-backward-sexp)
47     ;; Text-formatting commands:
48     ("\C-c\C-m" . sml-insert-form)
49     ("\C-c\C-i" . sml-mode-info)
50     ("\M-|"     . sml-electric-pipe)
51     ("\M-\ "    . sml-electric-space)
52     ("\;"       . sml-electric-semi)
53     ("\M-\t"    . sml-back-to-outer-indent)
54     ;; Process commands added to sml-mode-map -- these should autoload
55     ("\C-c\C-l" . sml-load-file)
56     ("\C-c\C-c" . sml-compile)
57     ("\C-c\C-s" . switch-to-sml)
58     ("\C-c\C-r" . sml-send-region)
59     ("\C-c\C-b" . sml-send-buffer)
60     ([(meta shift down-mouse-1)] . sml-drag-region))
61   "The keymap used in `sml-mode'."
62   ;; :inherit sml-bindings
63   :group 'sml)
64
65 (defsyntax sml-mode-syntax-table
66   `((?\*   . ,(if sml-builtin-nested-comments-flag ". 23n" ". 23"))
67     (?\(   . "()1")
68     (?\)   . ")(4")
69     ("._'" . "_")
70     (",;"  . ".")
71     ;; `!' is not really a prefix-char, oh well!
72     ("~#!" . "'")
73     ("%&$+-/:<=>?@`^|"   . "."))
74   "The syntax table used in `sml-mode'.")
75
76
77 (easy-menu-define sml-mode-menu sml-mode-map "Menu used in `sml-mode'."
78   '("SML"
79     ("Process"
80      ["Start default ML compiler" run-sml               t]
81      ["-" nil nil]
82      ["run CM.make"             sml-make        t]
83      ["load ML source file"     sml-load-file   t]
84      ["switch to ML buffer"     switch-to-sml   t]
85      ["--" nil nil]
86      ["send buffer contents"    sml-send-buffer t]
87      ["send region"             sml-send-region t]
88      ["send paragraph"          sml-send-function t]
89      ["goto next error"         next-error      (featurep 'sml-proc)]
90      ["---" nil nil]
91      ;; ["Standard ML of New Jersey" sml-smlnj  (fboundp 'sml-smlnj)]
92      ;; ["Poly/ML"                      sml-poly-ml     (fboundp 'sml-poly-ml)]
93      ;; ["Moscow ML"            sml-mosml       (fboundp 'sml-mosml)]
94      ["Help for Inferior ML"    (describe-function 'inferior-sml-mode) :active (featurep 'sml-proc)])
95     ["electric pipe"     sml-electric-pipe t]
96     ["insert SML form"   sml-insert-form t]
97     ("Forms" :filter sml-forms-menu)
98     ("Format/Mode Variables"
99      ["indent region"             indent-region t]
100      ["outdent"                   sml-back-to-outer-indent t]
101      ["-" nil nil]
102      ["set indent-level"          sml-indent-level t]
103      ["set pipe-indent"           sml-pipe-indent t]
104      ["--" nil nil]
105      ["toggle type-of-indent"     (sml-type-of-indent) t]
106      ["toggle nested-if-indent"   (sml-nested-if-indent) t]
107      ["toggle case-indent"        (sml-case-indent) t]
108      ["toggle electric-semi-mode" (sml-electric-semi-mode) t])
109     ["-----" nil nil]
110     ["SML mode help (brief)"       describe-mode t]
111     ["SML mode *info*"             sml-mode-info t]
112     ["-----" nil nil]
113     ["Remove overlay"    (sml-error-overlay 'undo) t ;:active (sml-overlay-active-p)
114      ]))
115
116 ;; Make's sure they appear in the menu bar when sml-mode-map is active.
117 ;; On the hook for XEmacs only -- see easy-menu-add in auc-menu.el.
118 ;; (defun sml-mode-menu-bar ()
119 ;;   "Make sure menus appear in the menu bar as well as under mouse 3."
120 ;;   (and (eq major-mode 'sml-mode)
121 ;;        (easy-menu-add sml-mode-menu sml-mode-map)))
122 ;; (add-hook 'sml-mode-hook 'sml-mode-menu-bar)
123
124 ;;
125 ;; regexps
126 ;;
127
128 (defun sml-syms-re (&rest syms)
129   (concat "\\<" (regexp-opt (flatten syms) t) "\\>"))
130
131 ;;
132
133 (defconst sml-module-head-syms
134   '("signature" "structure" "functor" "abstraction"))
135
136
137 (defconst sml-begin-syms
138   '("let" "abstype" "local" "struct" "sig")
139   "Symbols matching the `end' symbol.")
140
141 (defconst sml-begin-syms-re
142   (sml-syms-re "let" "abstype" "local" "struct" "sig")
143   "Symbols matching the `end' symbol.")
144
145 ;; (defconst sml-user-begin-symbols-re
146 ;;   (sml-syms-re "let" "abstype" "local" "struct" "sig" "in" "with")
147 ;;   "Symbols matching (loosely) the `end' symbol.")
148
149 (defconst sml-sexp-head-symbols-re
150   (sml-syms-re "let" "abstype" "local" "struct" "sig" "in" "with"
151                "if" "then" "else" "case" "of" "fn" "fun" "val" "and"
152                "datatype" "type" "exception" "open" "infix" "infixr" "nonfix"
153                sml-module-head-syms
154                "handle" "raise")
155   "Symbols starting an sexp.")
156
157 ;; (defconst sml-not-arg-start-re
158 ;;   (sml-syms-re "in" "of" "end" "andalso")
159 ;;   "Symbols that can't be found at the head of an arg.")
160
161 ;; (defconst sml-not-arg-re
162 ;;   (sml-syms-re "in" "of" "end" "andalso")
163 ;;   "Symbols that should not be confused with an arg.")
164
165 (defconst sml-=-starter-syms
166   (list* "|" "val" "fun" "and" "datatype" "type" "abstype" "eqtype"
167          sml-module-head-syms)
168   "Symbols that can be followed by a `='.")
169 (defconst sml-=-starter-re
170   (concat "\\S.|\\S.\\|" (sml-syms-re (cdr sml-=-starter-syms)))
171   "Symbols that can be followed by a `='.")
172
173 (defconst sml-indent-rule
174   (sml-preproc-alist
175    `(("struct" . 0)
176      (,sml-module-head-syms "d=" 0)
177      ("local" "in" 0)
178      ;;("of" . (3 nil))
179      ;;("else" . (sml-indent-level 0))
180      ;;(("in" "fun" "and" "of") . (sml-indent-level nil))
181      ("if" "else" 0)
182      (,sml-=-starter-syms nil)
183      (("abstype" "case" "datatype" "if" "then" "else" "sharing" "infix" "infixr"
184        "let" "local" "nonfix" "open" "raise" "sig" "struct" "type" "val" "while"
185        "do" "with" "withtype")))))
186
187 (defconst sml-starters-indent-after
188   (sml-syms-re "let" "local" "struct" "in" "sig" "with")
189   "Indent after these.")
190
191 (defconst sml-delegate
192   (sml-preproc-alist
193    `((("of" "else" "then" "d=") . (not (sml-bolp)))
194      ("in" . t)))
195   "Words which might delegate indentation to their parent.")
196
197 (defcustom sml-symbol-indent
198   '(("fn" . -3)
199     ("of" . 1)
200     ("|" . -2)
201     ("," . -2)
202     (";" . -2)
203     ;;("in" . 1)
204     ("d=" . 2))
205   "Special indentation alist for some symbols.
206 An entry like (\"in\" . 1) indicates that a line starting with the
207 symbol `in' should be indented one char further to the right.
208 This is only used in a few specific cases, so it does not work
209 for all symbols and in all lines starting with the given symbol."
210   :group 'sml
211   :type '(repeat (cons string integer)))
212
213 (defconst sml-open-paren
214   (sml-preproc-alist
215    `((,(list* "with" "in" sml-begin-syms) ,sml-begin-syms-re "\\<end\\>")))
216   "Symbols that should behave somewhat like opening parens.")
217
218 (defconst sml-close-paren
219   `(("in" "\\<l\\(ocal\\|et\\)\\>")
220     ("with" "\\<abstype\\>")
221     ("withtype" "\\<\\(abs\\|data\\)type\\>")
222     ("end" ,sml-begin-syms-re)
223     ("then" "\\<if\\>")
224     ("else" "\\<if\\>" (sml-bolp))
225     ("of" "\\<case\\>")
226     ("d=" nil))
227   "Symbols that should behave somewhat like close parens.")
228
229 (defconst sml-agglomerate-re "\\<else[ \t]+if\\>"
230   "Regexp of compound symbols (pairs of symbols to be considered as one).")
231
232 (defconst sml-non-nested-of-starter-re
233   (sml-syms-re "datatype" "abstype" "exception")
234   "Symbols that can introduce an `of' that shouldn't behave like a paren.")
235
236 (defconst sml-starters-syms
237   (append sml-module-head-syms
238           '("abstype" "datatype" "exception" "fun"
239             "local" "infix" "infixr" "sharing" "nonfix"
240             "open" "type" "val" "and"
241             "withtype" "with"))
242   "The starters of new expressions.")
243
244 (defconst sml-exptrail-syms
245   '("if" "then" "else" "while" "withtype" "do" "case" "of" "raise" "fn"))
246
247 (defconst sml-pipeheads
248    '("|" "of" "fun" "fn" "and" "handle" "datatype" "abstype")
249    "A `|' corresponds to one of these.")
250
251
252 (provide 'sml-defs)
253
254 ;;; sml-defs.el ends here