|
|
1.1 root 1:
2:
3:
4: SML MODE
5:
6: Version 2.4
7:
8:
9: A major mode for editing and running SML.
10:
11:
12: Lars Bo Nielsen
13: ([email protected])
14:
15:
16:
17: Sml-mode is a major GnuEmacs mode for editing and running (Standard) ML
18: (sml). It features:
19:
20: o Automatic indentation of sml code. With a number of constants to
21: customize the indentation.
22:
23: o Short cut insertion of commonly used structures, like
24: "let in end", "signature xxx = sig end", etc.
25:
26: o Short cut insertion of "|". Will automaticly determine if
27: "|" is used after a "case", "fun" etc. If used after a "fun"
28: automaticly insert the name of the function, used after
29: case automaticly insert "=>" etc.
30:
31: o Inferior shell running sml. No need to leave emacs, just
32: keep right on editing while sml runs in another window.
33:
34: o Automatic "use file" in inferior shell. Send regions of code
35: to the running sml program.
36:
37: o Parsing of errors in the inferior shell. Like the next-error
38: function used in c-mode (This will only work with SML of
39: New Jersey).
40:
41:
42:
43: 1. HOW TO USE THE SML-MODE
44: ==========================
45:
46: Here is a short introduction to the mode. If you are an experienced user of
47: Emacs, just skip the first section, and go straight to 1.2.
48:
49: If you run into any problems, your local emacs-administrator should be able
50: to help you. You are also wellcome to send me a note asking for help.
51:
52:
53: 1.1 GETTING STARTED
54: -------------------
55:
56: The mode for sml is in the file "sml-mode.el". We will have to tell Emacs
57: where to find this file and when to use it.
58:
59: Insert this in your "~/.emacs" file :
60:
61: (setq auto-mode-alist (cons '("\\.sml$" . sml-mode)
62: auto-mode-alist))
63: (autoload 'sml-mode "sml-mode" "Major mode for editing SML." t)
64:
65: Now every time a file with the extension `.sml' is found, it is
66: automatically started up in sml-mode.
67:
68: You will also have to specify the path to the "sml-mode.el" file, so you
69: will have to add this as well:
70:
71: (setq load-path (cons "/usr/me/emacs" load-path))
72:
73: where "/usr/me/emacs" is the directory where the file "sml-mode.el" is
74: located.
75:
76: You may also want to compile the file (M-x byte-compile-file)
77: for speed.
78:
79: You are now ready to start using sml-mode. If you have tried other
80: language modes (like lisp-mode or C-mode), you should have no
81: problems. There are only a few extra functions in this mode.
82:
83:
84: 1.2. EDITING COMMANDS.
85: ----------------------
86:
87: The following editing and inferior-shell commands can ONLY be issued
88: from within a buffer in sml-mode. (The names in parenthesis is the
89: Emacs-lisp name of the function, that is associated with the keystroke
90: command).
91:
92: M-| (sml-electric-pipe).
93: In the case you are typing in a case expression, a function with
94: patterns etc., this function will give you some help. First of all
95: it will put the `|' on a line by itself. If it is used in the
96: definition of a function it inserts the functions name, else it
97: inserts `=>'. Just try it, you will like it.
98:
99: LFD (reindent-then-newline-and-indent).
100: This is probably the function you will be using the most (press
101: CTRL while you press Return, press C-j or press Newline). It
102: will reindent the line, then make a new line and perform a new
103: indentation.
104:
105: TAB (sml-indent-line).
106: This function indents the current line.
107:
108: C-c TAB (sml-indent-region).
109: This function indents the current region (be patient if the
110: region is large).
111:
112: M-; (indent-for-comment).
113: Like in other language modes, this command will give you a comment
114: at the of the current line. The column where the comment starts is
115: determined by the variable comment-column (default: 40).
116:
117: C-c C-v (sml-mode-version).
118: Get the version of the sml-mode.
119:
120:
121: 1.3. COMMANDS RELATED TO THE INFERIOR SHELL
122: -------------------------------------------
123:
124: C-c C-s (sml-pop-to-shell).
125: This command starts up an inferior shell running sml. If the shell
126: is running, it will just pop up the shell window.
127:
128: C-c C-u (sml-save-buffer-use-file).
129: This command will save the current buffer and send a "use file",
130: where file is the file visited by the current buffer, to the
131: inferior shell running sml.
132:
133: C-c i (sml-import-file)
134: Will save the current buffer and send an "import file", where file
135: is the file visited by the current buffer, to the inferior shell
136: running sml.
137:
138: C-c C-f (sml-run-on-file).
139: Will send a "use file" to the inferior shell running sml,
140: prompting you for the file name.
141:
142: C-c ' (sml-next-error).
143: This function parses the buffer of the inferior shell running sml,
144: and finds the errors one by one. The cursor is positioned at the
145: line of the file indicated by the error message, while the
146: inferior shell buffer running sml will be positioned at the error
147: message in another window.
148:
149: C-c C-k (sml-skip-errors)
150: This function will skip past the rest of the error messages in
151: the inferior shell
152:
153: IMPORTANT: These two functions only knows the syntax of error
154: messages produced by SML of New Jersey. To have these functions
155: working with other implementations of sml you will have to
156: rewrite them.
157:
158: C-c C-r (sml-send-region).
159: Will send region, from point to mark, to the inferior shell
160: running sml.
161:
162: C-c C-c (sml-send-function).
163: Will send function to the inferior shell running sml. (This only
164: sends the paragraph, so you might prefer the sml-send-region
165: instead. Paragraphs are separated by blank lines only).
166:
167: C-c C-b (sml-send-buffer).
168: Will send whole buffer to inferior shell running sml.
169:
170:
171: 2. INDENTATION
172: ==============
173:
174: The indentation algorithm has been the hardest one to implement.
175:
176: What is the standard way of indenting sml-code?
177:
178: The algorithm has its own view of the right way to indent code,
179: according to the constants you can set to control the mode.
180:
181:
182: 2.1. CONSTANTS CONTROLLING THE INDENTATION
183: ------------------------------------------
184:
185: sml-indent-level (default 4)
186: Indentation of blocks in sml.
187:
188: sml-pipe-indent (default -2)
189: The amount of extra indentation (negative) of lines beginning
190: with "|".
191:
192: sml-case-indent (default nil)
193: How to indent case-of expressions.
194:
195: If t: case expr If nil: case expr of
196: of exp1 => ... exp1 => ...
197: | exp2 => ... | exp2 => ...
198:
199: The first seems to be the standard in NJ-SML. The second is the
200: default.
201:
202: sml-nested-if-indent (default nil)
203: If set to t, nested if-then-else expressions will have the
204: indentation:
205:
206: if exp1 then exp2
207: else if exp3 then exp4
208: else if exp5 then exp6
209: else exp7
210:
211: If nil, they will be indented as:
212:
213: if exp1 then exp2
214: else if exp3 then exp4
215: else if exp5 then exp6
216: else exp7
217:
218: With the "else" at the same column as the matching "if".
219:
220: sml-type-of-indent (default t)
221: Determines how to indent `let', `struct' etc.
222:
223: If t: fun foo bar = let
224: val p = 4
225: in
226: bar + p
227: end
228:
229: If nil: fun foo bar = let
230: val p = 4
231: in
232: bar + p
233: end
234:
235: Will not have any effect if the starting keyword is first on the
236: line.
237:
238: sml-electric-semi-mode (default t)
239: If t, a ";" will reindent the current line, and make a newline. To
240: override this (to type in a ";" without a newline) just type: C-q ;
241:
242: sml-paren-lookback (default 200)
243: Determines how far back (in chars) the indentation algorithm
244: should look for open parenthesis. High value means slow
245: indentation algorithm. A value of 200 (being the equivalent of
246: 4-6 lines) should suffice most uses. (A value of nil, means do
247: not look at all).
248:
249: To change these constants, See CUSTOMIZING YOUR SML-MODE below.
250:
251:
252: 3. INFERIOR SHELL.
253: ==================
254:
255: The mode for Standard ML also contains a mode for an inferior shell
256: running sml. The mode is the same as the shell-mode, with just one
257: extra command.
258:
259:
260: 3.1. INFERIOR SHELL COMMANDS
261: ----------------------------
262:
263: C-c C-f (sml-run-on-file). Send a `use file' to the process running
264: sml.
265:
266:
267: 3.2. CONSTANTS CONTROLLING THE INFERIOR SHELL MODE
268: --------------------------------------------------
269:
270: Because sml is called differently on various machines, and the
271: sml-systems have their own command for reading in a file, a set of
272: constants controls the behavior of the inferior shell running sml (to
273: change these constants: See CUSTOMIZING YOUR SML-MODE below).
274:
275: sml-prog-name (default "sml").
276: This constant is a string, containing the command to invoke
277: Standard ML on your system.
278:
279: sml-prog-name-ask-p (default nil)
280: If t, you will be asked which program to run when the inferior
281: shell starts up. Usefull if you have exported images of sml.
282:
283: sml-use-right-delim (default "\"")
284: sml-use-left-delim (default "\"")
285: The left and right delimiter used by your version of sml, for
286: `use file-name'.
287:
288: sml-process-name (default "SML").
289: The name of the process running sml. (This will be the name
290: appearing on the mode line of the buffer)
291:
292: NOTE: The sml-mode functions: sml-send-buffer, sml-send-function and
293: sml-send-region, creates temporary files (I could not figure out how
294: to send large amounts of data to a process). These files will be
295: removed when you leave emacs.
296:
297:
298: 4. CUSTOMIZING YOUR SML-MODE
299: ============================
300:
301: If you have to change some of the constants, you will have to add a
302: `hook' to the sml-mode. Insert this in your "~/.emacs" file.
303:
304: (setq sml-mode-hook 'my-sml-constants)
305:
306: Your function "my-sml-constants" will then be executed every time
307: "sml-mode" is invoked. Now you only have to write the emacs-lisp
308: function "my-sml-constants", and put it in your "~/.emacs" file.
309:
310: Say you are running a version of sml that uses the syntax `use
311: ["file"]', is invoked by the command "OurSML" and you don't want the
312: indentation algorithm to indent according to open parenthesis, your
313: function should look like this:
314:
315: (defun my-sml-constants ()
316: (setq sml-prog-name "OurSML")
317: (setq sml-use-left-delim "[\"")
318: (setq sml-use-right-delim "\"]")
319: (setq sml-paren-lookback nil))
320:
321: Other things could be added to this function. As an example:
322:
323: (setq sml-paren-lookback 1000) ; Look back 1000 chars for open
324: ; parenthesis.
325:
326: (setq sml-case-indent t) ; Select other type of case
327: ; expressions
328:
329: (turn-on-auto-fill) ; Turn on auto-fill
330:
331: (setq sml-indent-level 8) ; change the indentation to 8
332:
333: (setq sml-prog-name-ask-p t) ; Ask which program to run when the
334: ; inferior shell starts up.
335:
336: (define-key sml-mode-map "|" ; Let "|" be electric,
337: 'sml-electric-pipe) ; like M-|
338:
339: The sml-shell also runs a `hook' (sml-shell-hook) when it is invoked.
340:
341:
342: 5. CHANGES FROM PREVIOUS VERSIONS
343: ================================
344:
345: For those of you who have been using sml-mode in an earlier version,
346: here is a compiled list of the changes made.
347:
348:
349: 5.1 VERSION 1.0 TO 2.0
350: ----------------------
351:
352: o Some bugs fixed.
353:
354: o The indentation algorithm has become better at determining the
355: right indentation, and faster.
356:
357: o A number of constants have been introduced to customize the mode
358: to your needs.
359:
360: o The indentation algorithm recognizes `else if' (nested if then
361: else), but only if the variable "sml-nested-if-indent" has been
362: set to t, the default is nil.
363:
364: o By setting the variable sml-case-indent to either nil or t you now
365: can have two different indentations of case-expr-of.
366:
367: o The constant sml-type-of-indent now determines the way to indent
368: blocks, if the starting keyword is not first on the line.
369:
370: o The indentation algorithm now indents to same level as an open
371: parenthesis if this was left open at a previous line (the variable
372: sml-paren-lookback controls this action.)
373:
374: o A couple of extra functions have been added:
375: sml-next-error and sml-save-buffer-use-file.
376:
377: o If temporary files are created, these files will be removed when
378: emacs is killed.
379:
380: o Thanks to Andy Norman (ange%[email protected]) you are no
381: longer placed in the inferior shell when you send a `use file' to
382: the inferior shell. The shell window will pop up, and the window
383: will scroll. He also added a shell-prompt-pattern variable for the
384: inferior sml shell mode. This will allow you to move the cursor
385: backwards in the buffer, and re-execute lines that begin with this
386: pattern (pattern is found in the variable sml-shell-prompt-pattern).
387:
388:
389: 5.2 VERSION 2.0 TO 2.1
390: ----------------------
391:
392: o Some bugs fixed.
393:
394: o Due to a bug in the Un*x function mktemp, you could only send
395: 26 temporary files. This has been fixed by adding an extra letter
396: to the file-name (sml-tmp-file-name) in the function that sends
397: the files (sml-simulate-send-region).
398:
399:
400: 5.3 VERSION 2.1 TO 2.2
401: ----------------------
402:
403: o Some bugs fixed.
404:
405: o A new function (sml-skip-errors, bound to C-c C-k) has been
406: added. It skips the rest of the error messages. Very handy if a
407: lot of errors follows a simple mistake.
408:
409: o Sending something to the process running sml, will call
410: sml-skip-errors first, so old errors will be forgotten.
411:
412: o sml-indent-line (TAB) now leaves the point where it is (unless
413: if it is before the indentation).
414:
415: 5.3 VERSION 2.2 TO 2.3
416: ----------------------
417:
418: o Some bugs fixed.
419:
420: o New variable (sml-prog-name-ask-p). If t, you will be asked which
421: program to run when the inferior shell starts up. Usefull if you have
422: exported images of sml.
423:
424: 5.4 VERSION 2.2 TO 2.4
425: ----------------------
426:
427: o Some bugs fixed.
428:
429: o Added sml-import-file.
430:
431: 6. THINGS TO DO
432: ===============
433:
434: And there are still things to do:
435:
436: o Find a better way to send regions to the inferior shell (the command
437: process-send-region does not work on larger regions, that is why the
438: function sml-simulate-send-region uses temporary files).
439:
440: o Have sml-next-error recognizing more than just SML of New Jersey
441: syntax of error messages.
442:
443: o The indentation algorithm still can be fooled. I don't know if it
444: will ever be 100% right, as this means it will have to actually
445: parse all of the buffer up to the actual line (this can get -very-
446: slow).
447:
448: o Add tags.
449:
450:
451: Thanks
452: ======
453:
454: Thanks to Andy Norman (ange%[email protected]) for helping me a
455: lot. Not only did he tell me about the bugs, he also included fixes.
456:
457:
458: Author
459: ======
460: Lars Bo Nielsen
461: Aalborg University
462: Computer Science Dept.
463: 9000 Aalborg
464: Denmark
465:
466: [email protected]
467: or: ...!mcvax!diku!iesd!lbn
468: or: [email protected]
469:
470: Please let me know if you come up with any ideas, bugs, or fixes.
471:
472:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.