commit 47eb6d199464b5a510ec6c61a495fc57bcf4d96f
parent 7d03d1ed880f1a7356fc113635f3efd796e959b4
Author: Alex Balgavy <a.balgavy@gmail.com>
Date: Wed, 9 Oct 2019 01:38:12 -0400
emacs: more changes
Former-commit-id: c69b943a99c546fc8f7482ee458e592e47a795fc
Diffstat:
17 files changed, 8 insertions(+), 6710 deletions(-)
diff --git a/emacs/emacs b/emacs/emacs
@@ -27,10 +27,13 @@
`(("." . ,(concat user-emacs-directory "backup/")))
tramp-backup-directory-alist backup-directory-alist)
-;; Some version control for backups
-(custom-set-variables
- '(version-control t))
+;; Add package repositories
+(require 'package)
+(add-to-list 'package-archives
+ '("melpa-stable" . "http://stable.melpa.org/packages/") t)
+(package-initialize)
+;; Some version control for backups
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
@@ -43,6 +46,8 @@
'(custom-safe-themes
(quote
("1a232652b04b68380b1cff7ceeb62787b4eb43df826a97c67831c50b0c0d1451" "3fd57a3dc99eb0e2ec438555cf801572f649c79513d3a8da7980ab54cf66121b" default)))
+ '(package-selected-packages (quote (haskell-mode)))
+ '(version-control t)
'(xterm-mouse-mode t))
(custom-set-faces
;; custom-set-faces was added by Custom.
diff --git a/emacs/emacs.d/sml-mode-5.0/BUGS b/emacs/emacs.d/sml-mode-5.0/BUGS
@@ -1,11 +0,0 @@
--*- text -*-
-
-Here are the current known bugs.
-If you find any other, send it to <monnier@iro.umontreal.ca>.
-
-* M-x next-error and other compile.el support doesn't work on XEmacs.
-
-* indentation of a declaration after a long `datatype' is slow.
-
-* buggy indentation samples
- Try `make test' to see the known problems in testcases.sml
diff --git a/emacs/emacs.d/sml-mode-5.0/ChangeLog b/emacs/emacs.d/sml-mode-5.0/ChangeLog
@@ -1,573 +0,0 @@
-2012-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
-
- Merge sml-defs.el into sml-mode.el.
- * sml-mode.el: Merge code from sml-defs.el.
- Remove ":group 'sml" since they're now redundant.
- * makefile.pkg (ELFILES): Adjust.
-
-2012-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-mode.el (sml-mark-function): New implementation using SMIE.
- * sml-defs.el (sml-mode-map): Use backtab.
- Remove leftover unused sml-drag-region binding.
-
-2012-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
-
- Use SMIE by default and make sml-oldindent optional.
- * sml-mode.el: Only load sml-oldindent if necessary.
- (sml-use-smie): Default to t.
- (sml-smie-datatype-|-p): Better handle incomplete datatype branch.
- (sml-mode): Use prog-mode. Setup electric-layout and electric-indent.
- (sml-mode-variables): Always setup SMIE if possible.
- (sml-imenu-create-index, sml-funname-of-and, sml-electric-pipe)
- (sml-beginning-of-defun, sml-defuse-symdata-at-point)
- (sml-yacc-font-lock-keywords, sml-yacc-indentation):
- Avoid sml-oldindent functions.
- (sml-find-forward): Move from sml-oldindent and re-implement.
- (sml-electric-semi): Use self-insert-command so electric-layout and
- electric-indent can do their job.
- (sml-smie-find-matching-starter, sml-find-matching-starter)
- (sml-smie-skip-siblings, sml-skip-siblings): New functions.
- * sml-oldindent.el (sml-starters-indent-after, sml-exptrail-syms):
- Remove, unused.
- (sml-find-forward): Move back to sml-mode.el.
- (sml-old-find-matching-starter): Rename from sml-find-matching-starter.
- (sml-old-skip-siblings): Move&rename from sml-mode:sml-skip-siblings.
-
-2012-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
-
- Move non-SMIE indentation code to a separate file.
- * sml-oldindent.el: Rename from sml-move.el.
- * makefile.pkg (ELFILES): Adjust.
- * sml-mode.el (sml-indent-line, sml-find-comment-indent)
- (sml-calculate-indentation, sml-bolp, sml-first-starter-p)
- (sml-indent-starter, sml-indent-relative, sml-indent-pipe)
- (sml-find-forward, sml-indent-arg, sml-get-indent, sml-dangling-sym)
- (sml-delegated-indent, sml-get-sym-indent, sml-indent-default)
- (sml-current-indentation, sml-find-matching-starter):
- Move to sml-oldindent.el.
- (comment-quote-nested, compilation-error-regexp-alist): Declare.
-
- * sml-defs.el (sml-begin-syms, sml-begin-syms-re)
- (sml-sexp-head-symbols-re, sml-preproc-alist, sml-indent-rule)
- (sml-starters-indent-after, sml-delegate, sml-symbol-indent)
- (sml-open-paren, sml-close-paren, sml-agglomerate-re)
- (sml-exptrail-syms): Move to sml-oldindent.el.
-
-2012-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
-
- Get rid of ancient compatibility and small utility file.
- * sml-proc.el (inferior-sml-mode-map): Don't use defmap.
- * sml-move.el (sml-internal-syntax-table): Don't use defsyntax.
- * sml-mode.el (sml-syntax-prop-table): Don't use defsyntax.
- (sml-electric-space): `last-command-char' -> `last-command-event'.
- (sml-defuse-jump-to-def): Don't use goto-line from Elisp.
- * sml-defs.el (sml-mode-map): Don't use defmap.
- (sml-mode-syntax-table): Don't use defsyntax.
- (sml-preproc-alist, sml-builtin-nested-comments-flag):
- Move from sml-util.el.
- * sml-compat.el, sml-utils.el: Remove.
- * makefile.pkg (ELFILES): Update.
-
-2012-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
-
- Add SMIE support.
- * .bzrignore: New file.
- * makefile.pkg (test): Use sml-mode-startup.
-
- * sml-mode.el (sml-use-smie): New config var.
- (sml-smie-grammar, sml-indent-separator-outdent): New vars.
- (sml-smie-rules, sml-smie-definitional-equal-p)
- (sml-smie-non-nested-of-p, sml-smie-datatype-|-p)
- (sml-smie-forward-token-1, sml-smie-forward-token)
- (sml-smie-backward-token-1, sml-smie-backward-token): New functions.
- (sml-mode): Don't set forward-sexp-function.
- (sml-mode-variables): Set it here instead, and setup SMIE instead
- if applicable.
-
-2010-03-04 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * Release version 4.1.
-
- * sml-mode.el: Don't setup load-path here any more.
- * Makefile ($(PACKAGE)-startup.el): Recreate from scratch every time.
- Setup load-path.
- (dist): Try to update it to use Svn rather than CVS.
-
-2007-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-proc.el (inferior-sml-next-error-hook): Make it match one
- more format.
-
-2007-10-31 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * testcases.sml: Add (old) buggy case from Christopher Dutchyn.
-
- * sml-proc.el (inferior-sml-font-lock-keywords): Don't add
- error-regexps if compile.el already highlights them anyway.
-
- * sml-mode.el (sml-font-lock-symbols-alist): Fix char for "not".
-
-2007-10-31 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-mode.el (sml-def-skeleton): If possible, only expand for
- lower-case abbrevs and not inside strings or comments.
- (sml-mlton-typecheck): Typo.
-
- * sml-proc.el (sml-proc-comint-input-filter-function): New function.
- (inferior-sml-mode): Use it.
- (sml-update-cursor): Don't forget errors here any more.
-
-2007-10-31 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-util.el (defmap, defsyntax): Avoid defconst.
- (flatten): Remove.
-
- * sml-mode.el (sml-calculate-indentation): Avoid previous-line.
- (sml-keywords-regexp): Avoid the need for `flatten'.
- (sml-defuse-jump-to-def): Fix typo.
-
- * sml-defs.el (sml-syms-re): Don't use `flatten'.
- (sml-sexp-head-symbols-re, sml-starters-indent-after)
- (sml-non-nested-of-starter-re): Avoid the need for `flatten'.
-
- * sml-proc.el (inferior-sml-next-error-hook): New fun.
- (inferior-sml-mode): Use it.
-
-2007-06-29 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-mode.el (sml-mlton-error-regexp-alist): New var.
- (sml-mlton-typecheck): Use it.
- (compilation-error-regexp-alist): Add entries after loading "compile"
- so that M-x compile works.
-
- * sml-proc.el (inferior-sml-mode): Make TAB add a " rather than a space
- at the end of a file name.
-
-2007-06-14 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-mode.el (sml-mode-variables): Set comment-quote-nested instead of
- comment-nested. Set comment-end-skip.
- (sml-first-starter-p): New function.
- (sml-indent-starter): Use it to fix an indentation bug.
- (sml-mlton-command, sml-mlton-mainfile): New vars.
- (sml-mlton-typecheck): New command.
- (sml-defuse-file): New var.
- (sml-defuse-def-regexp, sml-defuse-use-regexp-format): New consts.
- (sml-defuse-file, sml-defuse-symdata-at-point): New functions.
- (sml-defuse-set-file, sml-defuse-jump-to-def): New commands.
-
-2005-11-20 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-move.el (sml-find-match-forward): Avoid infinite looping if the
- construct is not properly closed (yet).
-
-2005-11-16 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-defs.el (sml-mode-menu): Remove left over obsolete entries.
-
- * sml-proc.el (inferior-sml-mode): Preserve the menu-bar of the
- compilation minor mode, if any.
-
-2004-11-24 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * Release version 4.0.
-
-2004-11-23 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-mode.el (sml-font-lock-symbols-alist): Add yet more silly entries.
-
-2004-11-15 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-mode.el (sml-font-lock-symbols-alist): Add entries for >= and <=.
- (sml-font-lock-symbols-alist): Add entries for simple type variables.
- (sml-font-lock-compose-symbol): Add support for non-punctuation syms.
-
-2004-11-14 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-move.el (sml-backward-sexp, sml-forward-sexp): Remove unused var.
-
- * sml-mode.el (sml-calculate-indentation): Remove unused var.
- (sml-get-indent): Change first arg's meaning.
- (sml-get-sym-indent): Adjust call.
- (sml-forms-menu): Simplify.
- (sml-font-lock-symbols, sml-font-lock-symbols-alist): New vars.
- (sml-font-lock-compose-symbol, sml-font-lock-symbols-keywords):
- New funs.
- (sml-font-lock-keywords): Use them.
-
- * sml-compat.el (temp-directory): Get rid of warning.
-
- * Makefile (install_startup): Don't add to load-path any more.
-
- * sml-proc.el (sml-make-error): Use match-string.
- (sml-error-regexp-alist): Merge regexps.
- (sml-update-cursor): Check sml-temp-file is non-nil.
-
-2004-04-21 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-proc.el (sml-error-regexp-alist): Use new compile.el features
- if available.
- (sml-send-region): Remove unused var `file'.
- (sml-drag-region): Remove unused function.
- (sml-update-cursor): Use compilation-fake-loc if available.
- (compilation-goto-locus): Only advise if necessary.
-
- * sml-mode.el: Add self to load-path in sml-mode-startup.el.
- (sml-def-skeleton): Try to use the new `system' abbrev flag.
-
-2004-04-04 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * testcases.sml: Add a nasty case that is still wrong.
-
- * sml-proc.el (sml-error-regexp-alist): Tune the regexp for sml/nj.
-
- * sml-mode.el (sml-mode): Better handle paragraphs in comments.
- (sml-mode-variables): Clean up paragraph settings.
- (sml-electric-pipe): Fix a boundary bug.
- (sml-indent-starter, sml-get-sym-indent, sml-find-matching-starter):
- Fix indentation algorithm. Can't remember what it was about.
- This code is nasty, I just can't understand what's doing what.
- (completion-ignored-extensions): Add the new .cm directory.
-
-2003-12-09 Stefan Monnier <monnier@iro.umontreal.ca>
-
- * sml-defs.el (sml-mode-menu): Fix typo. Use std names.
- (sml-begin-syms-re): Reduce redundancy.
-
-2001-09-18 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-tyvarseq-re): Fix typo.
-
-2001-07-20 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-rightalign-and): New defcustom.
- (sml-tyvarseq-re): New var.
- (sml-font-lock-keywords): Use it.
- (sml-imenu-create-index): Don't get confused by tyvarseq's.
- (sml-mode-variables): Don't set `comment-column'.
- (sml-funname-of-and): New function.
- (sml-electric-pipe): Use it.
- (sml-find-comment-indent): Try to ignore comment-markers in strings.
- (sml-calculate-indentation): Handle closing parens specially.
- (sml-indent-pipe): Recognize the case where `and' defines a datatype.
- (sml-dangling-sym): Make it work if the symbol is an open-paren.
- (sml-indent-default): Change the behavior when preceded by `end',
- although I'm not quite sure why.
- Understand dangling open-parens.
- Properly skip *all* subexpressions of lower precedence.
- Allow use of sml-symbol-indent to outdent lines starting with , or ;.
- (sml-insert-form): Use preceding-char to avoid bug at bobp.
-
-2001-07-19 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-proc.el (sml-proc-buffer): Save excursion when calling run-sml.
-
- * sml-move.el (sml-syntax-prec): Split ; and , from `in' and `with'.
-
- * sml-mode.texi: Put the entry in `Emacs' rather than `Editors'.
-
- * sml-mode.spec (BuildArch): Simplify call to `install-info'.
-
- * sml-defs.el (sml-mode-menu): Add an explicit t for always-active.
- (sml-symbol-indent): Add entries for , and ; and turn into defcustom.
-
- * sml-compat.el: Add more stuff. It might help for Emacs-19.34.
-
- * makefile.pkg (test): Use elisp files in current dir.
-
-2000-12-24 Stefan Monnier <monnier@cs.yale.edu>
-
- * Release version 3.9.5.
-
- * Makefile (install): Also install .el files.
- (dist): Don't rely on $CVSROOT.
-
- * sml-mode.el: Require `skeleton'.
- (sml-mode): Add the menu for XEmacs. Make sure @ is a valid skeleton.
- (sml-comment-indent): Remove.
- (sml-mode-variables): Don't set comment-indent-function.
- (sml-def-skeleton): Nop if skeletons aren't available.
- (skeletons): Use `> _' and `@'.
- (sml-forms-menu): Don't bother with easy-menu-filter-return crap.
- (sml-cm-mode-syntax-table, sml-cm-font-lock-keywords): New vars.
- (sml-cm-mode): Use define-derived-mode rather than define-generic-mode.
- (sml-lex-font-lock-keywords, sml-lex-font-lock-defaults): New vars.
- (sml-yacc-font-lock-keywords): Use sml-lex-font-lock-keywords.
- Refine pattern to recognize the %prec keyword.
- (sml-yacc-font-lock-defaults): Fix typo.
-
- * sml-proc.el (inferior-sml-mode): Disable next-error for XEmacs.
-
- * sml-util.el (defsyntax): Don't forget to eval `doc'.
-
- * sml-mode.spec: Simplify.
-
- * sml-defs.el (sml-mode-menu): Remove bogus entry for sml-mode-version.
-
-2000-10-06 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el: Make the toplevel closer to usual practice.
- (sml-imenu-regexp, sml-imenu-create-index): New var and fun.
- (sml-mode): Use them.
- (sml-beginning-of-defun): Add `and' as function-leader.
- (sml-lex-mode): New trivial mode.
- (sml-yacc-bnf-face, sml-yacc-indent-action, sml-yacc-indent-pipe)
- (sml-yacc-indent-term, sml-yacc-font-lock-keywords)
- (sml-yacc-font-lock-defaults): New vars.
- (sml-yacc-indent-line, sml-yacc-indentation, sml-yacc-mode): New funs.
-
- * sml-mode.texi: Added yours truly to the list of authors.
-
- * sml-mode.spec: New file.
-
- * sml-defs.el (sml-outline-regexp): Slightly improved regexp.
-
-2000-08-24 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-proc.el (inferior-sml-mode-map): Don't inherit from sml-bindings.
- Add the binding for C-c C-l explicitly instead.
- (sml-run): Look in cwd (but only if the command has slashes).
-
- * sml-mode.el (sml-mode-abbrev-table): Remove (created by
- define-derived-mode).
- (sml-mode): Setup add-log's current-defun-function.
- (sml-indent-line): Never indent to a negative level.
- (sml-skip-siblings, sml-beginning-of-defun, sml-max-name-components)
- (sml-current-fun-name): New funs and vars for add-log support.
- (sml-comment-indent): Simplify.
- (sml-def-skeleton): Also create the skeleton as an abbrev.
- (skeletons): New for "struct", "sig", "val", "fn" and "fun".
- (sml-electric-space): Rewrite to use abbrev's machinery.
-
- * sml-defs.el (sml-mode-map): Merge with sml-bindings.
- (sml-bindings): Remove.
-
-2000-02-22 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-find-matching-starter): Use syms instead of a RE.
- (sml-indent-default): Use symbol membership rather than a regexp.
- Also, use `sym-indent' instead of (current-column).
- This fixes a problem with a hanging `structure Foo = (struct|let)'
- (due to `structure' having a sml-indent-rule, as opposed to `fun').
- Hopefully it won't introduce other problems.
- (sml-font-lock-keywords): Match vars `val x : int' also.
- (sml-electric-pipe): Update to the new `sml-find-matching-starter' and
- return a sensible default instead of raising an error in case of
- unexpected situations.
- (sml-indent-line): Ignore errors and keep the cursor where it is.
- (sml-calculate-indentation, sml-indent-pipe): Use syms instead of REs.
-
- * sml-defs.el (sml-starters-re, sml-pipehead-re): Remove.
-
- * testcases.sml: New file.
-
- * makefile.pkg (test): New target to run the test suite.
-
-2000-02-18 Stefan Monnier <monnier@cs.yale.edu>
-
- * *.el: Pass through checkdoc and use `eval-when-compile' whenever
- possible for (require 'cl).
-
-2000-02-18 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-util.el (make-temp-dir, make-temp-file, temp-file-dir)
- (delete-temp-dirs): Replace by the make-temp-file from Emacs-21.
- (custom-create-map): Add :group arg and allow key to be a list.
- (define-major-mode): Remove (use define-derived-mode instead).
- (sml-builtin-nested-comments-flag): New var.
- (concatq): Remove.
-
- * sml-proc.el (sml-host-name): New var.
- (sml-make-file-name): Replace by `sml-compile-commands'.
- (sml-config-file): New var.
- (sml-compile-commands-alist): New var.
- (inferior-sml-load-hook): Remove.
- (sml-buffer): Query if the current buffer is not a *sml*.
- (inferior-sml-mode): Use minor-mode-overriding-map-alist to disable
- compilation-minor-mode's keybindings.
- (run-sml): Turn into an alias for sml-run.
- (sml-run): Query the user for the command. If prefix is set (or if
- default value is not null) query for args and host.
- Use `split-string' rather than our own function.
- Run cmd on another host if requested and pass it an init file.
- Pop to the buffer at the end.
- (sml-args-to-list): Remove.
- (sml-compile): Look for special files (sml-compile-command-alist) in
- the current dir (and its parents) to choose a default command.
- Remember the command for next time in the same buffer.
- Make the `cd' explicit in the command so the user can change it.
- (sml-make-error): Fix for when `endline' is absent.
-
- * sml-mode.el: Pass it through checkdoc.
- (sml-mode-version): Remove.
- (sml-load-hook): Remove.
- (sml-mode-info): Use `info' rather than `Info-goto-node'.
- (sml-keywords-regexp): Add "o".
- (sml-syntax-prop-table): Use `defsyntax'.
- (sml-font-lock-syntactic-keywords): Only use nested comments if supported.
- (sml-mode): Use `define-derived-mode'.
- (sml-electric-pipe): `sml-indent-line' -> `indent-according-to-mode'.
- (sml-indent-line): Use `indent-line-to'.
- (sml-cm-mode): New mode for CM files.
-
- * Makefile: Update.
-
- * sml-mode-startup.el: Remove since it's now auto-generated.
-
- * sml-defs.el (sml-bindings): Remove left over C-c` binding.
- (sml-mode-map): Add binding for sml-drag-region (was in sml-proc.el).
- (sml-mode-syntax-table): Only use nested comments if supported.
- (sml-mode-menu): Use next-error rather than the old sml-next-error.
- (sml-pipehead-re): Remove "of".
-
- * sml-compat.el (set-keymap-parents): Make sure it also works when
- called with a single keymap rather than a list.
- (temporary-file-directory): Add a default definition for XEmacs.
- (make-temp-file): New function.
-
-1999-08-11 Stefan Monnier <monnier@cs.yale.edu>
-
- * Release version 3.9.3.
-
- * sml-mode.texi: Somewhat update the doc.
-
-1999-08-09 Stefan Monnier <monnier@cs.yale.edu>
-
- * Makefile: Update to the version of pcl-cvs.
-
- * sml-proc.el: Eliminate some old unused code.
-
- * sml-defs.el,sml-mode.el,sml-proc.el: Add simple customize support.
-
-1999-07-07 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-proc.el (sml-update-cursor): Make sure it also works if
- compile.el is fixed to uses a marker.
-
- * sml-mode.el (sml-indent): Fix the `fixindent'.
-
-1999-06-22 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode-startup.el: Fix to fulfill autoload.el assumptions.
-
-1999-06-21 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-defs.el (sml-bindings): Remove bindings for TAB and M-C-\.
-
-1999-06-19 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-font-lock-keywords): Skip type vars in "fun 'a myfn"
- (sml-calculate-indentation): Add a hack to allow the user to manually
- override the indentation algorithm with a magic comment.
-
- * sml-mode-startup.el: Update the autoloads automatically.
-
-1999-06-19 Stefan Monnier <monnier@cs.yale.edu>
-
- * Release version 3.9.2
-
- * sml-proc.el (sml-error-regexp-alist): Fix the pathological
- font-locking on long lines.
-
- * sml-move.el (sml-forward-sexp): Slightly improved.
-
-1999-06-17 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-insert-form): Only add a space if needed.
- (sml-electric-space): New command bound to M-SPC.
-
- * sml-defs.el (sml-close-paren): Add a second field that specifies when
- not to delegate. Only used for `else'.
-
-1999-06-16 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-move.el (sml-(for|back)ward-sym): Distinguish between
- operator "=" and syntax for definitions "d=".
-
- * sml-defs.el (sml-indent-starters, sml-delegate): Simplify.
- (sml-symbol-indent): Add outdentation for `fn' and generalize it to
- also work for `of' and `in' and `end'.
-
- * sml-mode.el (sml-nested-if-indent): Reintroduce as well as the
- special casing code for it.
- (sml-indent-relative): Generalize treatment of `of', `in', `end', ...
- (sml-electric-pipe): Remove the slow behavior and add smarts for the
- never-used type-variable arguments for function definitions.
-
-1999-06-15 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-defs.el (sml-mode-menu), sml-mode.el (sml-forms-menu):
- Make the menu dynamically.
-
- * sml-mode.el (sml-form-<foo>): Use skeletons.
- (sml-calculate-indentation): Add `with' indentation.
-
-1999-06-14 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-move.el (sml-(for|back)ward-sym): Now also return the string
- if any and take care of the "op" special keyword.
- (sml-op-prec): Setup an alist for the infix operators.
-
- * version 3.9.1: sent to Roland McGrath.
-
-1999-06-13 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-smlnj.el, sml-mosml.el, sml-poly-ml.el: Remove.
-
- * sml-proc.el (...): Get rid of sml-next-error by spicing up the
- interface with compile.el so that intervals can be displayed.
- `sml-overlay' is kept (and moved from sml-mode to sml-proc where it
- belongs) but is made redundant in the case of transient-mark-mode.
-
-1999-06-12 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-proc.el (sml-prompt-regexp): More general regexp to catch mosml,
- smlnj as well as polyml prompts.
- (sml-update-cursor, sml-send-command, inferior-sml-mode):
- Make it work with compile.el's `next-error'.
- (sml-temp-threshold): Drop: always use a temp file.
-
-1999-06-10 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-move.el (sml-op-prec): Update the list of default infix ops
- based on sml/nj's source files.
-
-1999-06-08 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-proc.el (sml-run): Remove dubious code to take care of a
- supposedly special case in order not to send "" when args=nil.
-
-1999-06-07 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-font-lock-syntactic-keywords): Add syntactic
- fontification for the ' \"' case (exhibited by lexgen.sml).
-
-1999-06-07 Stefan Monnier <monnier@cs.yale.edu>
-
- * ALL: The new indentation begins to work. v3_9_0
-
-1999-05-29 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-defs.el (sml-mode-syntax-table): Add ~ of prefix-syntax.
-
- * sml-mode.el (sml-find-match-indent): (nilp sml-type-of-indent) is
- only applied if the `let' is alone at the end of the line.
- (sml-type-of-indent): Default changed to `nil'.
-
-1999-05-28 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-font-lock-keywords): Change _ and ' back to word
- syntax for font-locking.
-
-1999-05-27 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-font-lock-syntactic-keywords): Finally got the
- matching of let...end working.
- (sml-electric-pipe): Take a fun sexp (symbol) rather than a fun word.
-
-1998-10-26 Stefan Monnier <monnier@cs.yale.edu>
-
- * sml-mode.el (sml-font-lock-syntactic-keywords):
- Add syntactic-keywords to support nested comments.
-
diff --git a/emacs/emacs.d/sml-mode-5.0/INSTALL b/emacs/emacs.d/sml-mode-5.0/INSTALL
@@ -1,39 +0,0 @@
-SML-MODE shouldn't require any special external support package,
-as far as I can rememebr. Just a recent copy of Emacs or XEmacs.
-
-Installation of the program
-===================================
-
- 1. Edit the file `Makefile' to reflect the situation at your site.
- The only things you have to change is the definition of `lispdir'
- and `infodir'. The elisp files will be copied to `lispdir', and
- the info file to `infodir'.
-
- 2. Have some sorbet.
-
- 3. Type `make install' in the source directory. This will byte-compile
- all `.el' files and copy all into the directory you specified in step
- 1. It will also copy the info files (and add a corresponding entry to
- the info-dir file if install-info can be found).
-
- If you only want to create the compiled elisp files, you can just type
- `make elcfiles' instead.
-
- 4. Edit the file `site-start.el' in your emacs lisp directory (usually
- `/usr/local/share/emacs/site-lisp' or something similar) and make it
- load the file `sml-mode-startup.el'. It contains a couple of
- `auto-load's that facilitates the use of sml-mode. Alternatively, you
- can just use `make install_startup'. If you're only installing it for
- yourself rather than for the whole system, then use something like
- `make install_startup startupfile=$HOME/.emacs'.
-
- 5. If you had copied the contents of a previous sml-mode-startup.el file to
- your site-start.el (or .emacs), you might want to remove that.
-
-
-How to make typeset documentation from the TeXinfo manual
-=========================================================
-
- If you have TeX installed at your site, you can make a typeset version of
-the manual typing ``make dvi''. If you prefer a postscript version of this
-file, just use ``make postscript''.
diff --git a/emacs/emacs.d/sml-mode-5.0/Makefile b/emacs/emacs.d/sml-mode-5.0/Makefile
@@ -1,176 +0,0 @@
-# Makefile for emacs-lisp package
-
-# Copyright (C) 1998, 1999, 2004, 2007, 2010 Stefan Monnier <monnier@gnu.org>
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 3, or (at your option) any
-# later version.
-
-# This file is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with GNU Emacs; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# load the package-specific settings
-include makefile.pkg
-
-# set up the usual installation paths
-prefix = /usr/local
-datadir = $(prefix)/share
-
-# the directory where you install third-party emacs packges
-lispdir = $(datadir)/emacs/site-lisp
-
-# the directory where the .elc files will be installed
-elcdir = $(lispdir)/$(PACKAGE)
-# the directory where the .el files will be installed
-eldir = $(elcdir)
-
-# the file where the initialization goes.
-#startupfile = $(HOME/.emacs
-startupfile = $(lispdir)/site-start.el
-
-# the directory where you installed the elib .elc files.
-# This is only needed if your site-start.el (or default.el) does not
-# set up elib correctly.
-elibdir = $(lispdir)/elib
-
-# the directory where you install the info doc
-infodir = $(prefix)/info
-docdir = $(prefix)/doc
-
-EMACS = emacs
-MAKEINFO= makeinfo
-TEXI2DVI= texi2dvi
-SHELL = /bin/sh
-DVIPS = dvips
-CP = cp
-RM = rm -f
-MKDIR = mkdir -p
-ETAGS = etags
-
-######################################################################
-### No changes below this line should be necessary ###
-######################################################################
-
-ELFLAGS = --eval '(setq load-path (append (list "." "$(elibdir)" "$(lispdir)") load-path))'
-ELC = $(EMACS) -batch $(ELFLAGS) -f batch-byte-compile
-
-ELCFILES = $(ELFILES:.el=.elc)
-
-TEXEXTS = *.cps *.fns *.kys *.vr *.tp *.pg *.log *.aux *.toc *.cp *.ky *.fn
-
-.SUFFIXES: .elc .el .info .ps .dvi .texi
-.PHONY: elcfiles info clean distclean default
-.PHONY: install_startup install_elc install install_el install_info
-.PHONY: dvi postscript
-
-.el.elc:
- $(ELC) $<
-
-.texi.info:
- $(MAKEINFO) $<
-
-.texi.dvi:
- $(TEXI2DVI) $<
-
-.dvi.ps:
- $(DVIPS) -f $< >$@
-
-######################################################################
-
-default: elcfiles
-
-elcfiles: $(ELCFILES)
-info: $(PACKAGE).info
-
-install_elc: $(ELCFILES) $(PACKAGE)-startup.el
- $(MKDIR) $(elcdir)
- for f in $(ELCFILES) $(PACKAGE)-startup.el; do \
- $(CP) $$f $(elcdir)/$$f ;\
- done
-
-install_el:
- $(MKDIR) $(eldir)
- for f in $(ELFILES); do \
- $(CP) $$f $(eldir)/$$f ;\
- done
-
-install_info: $(PACKAGE).info
- $(MKDIR) $(infodir)
- $(CP) *.info* $(infodir)/
- -[ ! -w $(infodir)/dir ] \
- || install-info --info-dir=$(infodir)/dir $(PACKAGE).info
-
-install_startup:
- $(MKDIR) $(lispdir)
- @if grep $(PACKAGE) $(lispdir)/site-start.el >/dev/null 2>&1 || \
- grep $(PACKAGE) $(startupfile) >/dev/null 2>&1 || \
- grep $(PACKAGE) $(lispdir)/default.el >/dev/null 2>&1; \
- then \
- echo "**********************************************************" ;\
- echo "*** It seems you already have some setup code" ;\
- echo "*** for $(PACKAGE) in your startup files." ;\
- echo "*** Check that it properly loads \"$(PACKAGE)-startup\"" ;\
- echo "**********************************************************" ;\
- else \
- echo 'echo ";; load $(PACKAGE) setup code" >>$(startupfile)' ;\
- echo ";; load $(PACKAGE) setup code" >>$(startupfile) ;\
- echo 'echo "(load \"$(elcdir)/$(PACKAGE)-startup\")" >>$(startupfile)' ;\
- echo "(load \"$(elcdir)/$(PACKAGE)-startup\")" >>$(startupfile) ;\
- fi
-
-postscript: $(PACKAGE).ps
-dvi: $(PACKAGE).dvi
-install_dvi: dvi
- $(MKDIR) $(docdir)
- $(CP) `find . -type f -name '*.dvi' -print` $(docdir)/
-
-install: install_elc install_info install_startup install_el
-
-clean:
- $(RM) *~ core .\#* $(TEXEXTS)
-
-TAGS tags:
- $(ETAGS) $(ELFILES)
-
-distclean: clean
- $(RM) *.elc *.dvi *.info* *.ps
-
-######################################################################
-### don't look below ###
-######################################################################
-
-$(PACKAGE)-startup.el: $(ELFILES)
- echo "\
- ;;; $@ --- automatically extracted autoloads\n\
- ;;; Code:\n\
- (add-to-list 'load-path\n\
- (or (file-name-directory load-file-name) (car load-path)))\n\
- " >$@
- $(EMACS) --batch --eval '(setq generated-autoload-file "'`pwd`'/$@")' -f batch-update-autoloads "."
-
-##
-
-#TAG = $(shell echo v$(VERSION) | tr '.' '_')
-URL=$(shell sed -n -e '5p' .svn/entries)
-TAG=$(shell dirname "$(URL)")/releases/$(PACKAGE)-$(VERSION)
-ftpdir=/u/monnier/html/elisp/
-cvsmodule=$(shell cat CVS/Repository)
-cvsroot=$(shell cat CVS/Root)
-
-dist:
- svn cp . "$(TAG)" &&\
- svn export "$(TAG)" "$(TMP)/$(PACKAGE)-$(VERSION)" &&\
- cd "$(TMP)/$(PACKAGE)-$(VERSION)" &&\
- $(MAKE) info $(PACKAGE)-startup.el &&\
- cd .. &&\
- ztar $(PACKAGE)-$(VERSION) &&\
- rm -rf $(PACKAGE)-$(VERSION)
- mv $(TMP)/$(PACKAGE)-$(VERSION).tar.gz $(ftpdir)/
- ln -sf $(PACKAGE)-$(VERSION).tar.gz $(ftpdir)/$(PACKAGE).tar.gz
diff --git a/emacs/emacs.d/sml-mode-5.0/NEWS b/emacs/emacs.d/sml-mode-5.0/NEWS
@@ -1,137 +0,0 @@
-Changes since 4.1:
-
-* New indentation code using SMIE when available.
-
-* `sml-back-to-outer-indent' is now on S-tab (aka `backtab') rather than M-tab.
-
-* Support for electric-layout-mode and electric-indent-mode.
-
-* `sml-mark-defun' tries to be more clever.
-
-* A single file (sml-mode.el) is needed unless you want to use an interactive
- process like SML/NJ, or if your Emacs does not provide SMIE.
-
-Changes since 4.0:
-
-* Switch to GPLv3+.
-
-* When possible (i.e. running under Emacs>=23), be case-sensitive when
- expanding abbreviations, and don't expand them in comments and strings.
-
-* When you `next-error' to a type error, highlight the actual parts of the
- types that differ.
-
-* Flush the recorded errors not only upon sml-compile and friends, but also
- when typing commands directly at the prompt.
-
-* New command sml-mlton-typecheck.
-
-* Simple support to parse errors and warnings in MLton's output.
-
-* Simple support for MLton's def-use files.
-
-Changes since 3.9.5:
-
-* No need to add the dir to your load-path any more.
- The sml-mode-startup.el file does it for you.
-
-* Symbols like -> can be displayed as real arrows. See sml-font-lock-symbols.
-
-* Fix some incompatibilities with the upcoming Emacs-21.4.
-
-* Indentation rules improved. New customizable variable
- `sml-rightalign-and'. Also `sml-symbol-indent' is now customizable.
-
-Changes since 3.9.3:
-
-* New add-log support (try C-x 4 a from within an SML function).
-
-* Imenu support
-
-* sml-bindings has disappeared.
-
-* The code skeletons are now abbrevs as well.
-
-* A new *sml* process is sent the content of sml-config-file (~/.sml-proc.sml)
- if it exists.
-
-* `sml-compile' works yet a bit differently. The command can begin
- with `cd "path";' and it will be replaced by OS.FileSys.chDir.
-
-* run-sml now pops up the new buffer. It can also run the command on another
- machine. And it always prompts for the command name. Use a prefix
- argument if you want to give args or to specify a host on which
- to run the command.
-
-* mouse-2 to yank in *sml* should work again (but won't work for next-error
- any more).
-
-* New major-modes sml-cm-mode, sml-lex-mode and sml-yacc-mode.
-
-* sml-load-hook has disappeared as has inferior-sml-load-hook.
-
-* sml-mode-startup.el is now automatically generated and you're supposed to
- `load' it from .emacs or site-start.el.
-
-* Minor bug fixes.
-
-Changes since 3.3:
-
-* the sml-drag-* commands have disappeared.
-
-* added a little bit of `customize' support. Many of the customization
- variables for indentation are still in flux, so they are not customize'd.
-
-* proformas have been replaced by skeletons. it's mostly the same as
- before (the layout has slightly changed, tho). The main difference
- is that the indentation relies on the major-mode indentation so it
- is implicitly customized, which makes more sense to me.
- Also I added an electric space M-SPC that will call the corresponding
- skeleton if any matches the immediately preceding symbol. Basically
- that allows you to type `l e t M-SPC' to call the `let' skeleton.
-
-* M-C-f and M-C-b try to be smart and jump around let..end and such blocks.
- It's probably either too smart or not smart enough, tho.
-
-* there is no more sml-<compiler>.el since the code should work for "all"
- known compilers. If your favorite compiler doesn't seem to work right
- send me a sample session.
-
-* hilite support has disappeared and font-lock and menu support is now built-in.
-
-* the indentation algorithm is inherently much slower. I've tried to ensure
- the slowness never manifests itself in practice, but if you find a case
- where the indentation doesn't feel instantaneous, tell me.
-
-* function arguments get properly indented (yes, madam).
-
-* the indentation has been majorly reworked. The list of changes is too long.
- Many customizations have disappeared, some may reappear depending on the
- feedback I get. The indentation should now "always" work right, so
- tell me when it doesn't.
-
-* nested comments are only properly handled if you have a nested-comments
- aware Emacs (I don't know of any yet) or if you turn on font-lock.
-
-* provide `sml-compile' which does something similat to `compile' except it
- passes the command to an inferior-sml process. Also it has an additional
- hack to look for sml-make-file-name in parent directories and cd to it
- before sending the command (handy for CM.make() when the sources.cm file
- is not in the current directory). This hack is very ad-hoc and quite
- misleading for people who don't use CM. I.e. the default is not safe.
-
-* sml-send-region and friends now always use a temp file. The temp file
- management has been made a little more secure.
-
-* the overlay is now turned off by default. Instead the region is activated,
- so that transient-mark-mode will end up highlighting the error just like
- the overlay used to do.
-
-* sml-proc uses compile.el for error parsing. This mostly means that instead
- of C-c ` you want to use the standard C-x `. It also means that error
- formats for any compiler can be added more easily.
-
-* The special frame handling has been thrown out because it doesn't interact
- well with Emacs' own similar feature. I believe XEmacs still doesn't provide
- such a feature, so if you miss it, either switch to Emacs or (convince
- someone else to) add it to XEmacs.
diff --git a/emacs/emacs.d/sml-mode-5.0/README b/emacs/emacs.d/sml-mode-5.0/README
@@ -1,19 +0,0 @@
-SML-MODE is a major Emacs mode for editing Standard ML.
-It provides syntax highlighting and automatic indentation and
-comes with sml-proc which allows interaction with an inferior SML
-interactive loop.
-
-This release should work on any recent version of Emacs or XEmacs.
-If it doesn't: complain.
-
-Some more or less out of date documentation can be found in TeXinfo format.
-
-Check the INSTALL file for installation instructions.
-Check the NEWS file for a list of changes in this version.
-Check the BUGS and TODO file before sending me bug reports and requests for
-enhancements.
-
-Send any complaint/question/praise/ice-cream to me,
-
-
- Stefan Monnier <monnier@iro.umontreal.ca>
diff --git a/emacs/emacs.d/sml-mode-5.0/TODO b/emacs/emacs.d/sml-mode-5.0/TODO
@@ -1,46 +0,0 @@
-* file-name completion in sml-cm-mode.
-
-* Don't always jump to the *sml* buffer when you send a snippet of code.
-
-* Fix inferior-sml-mode's TAB completion of filenames so it doesn't append
- a space.
-
-* Improve support for MLton's def-use info (see http://mlton.org/Emacs)
-
-* Add an sml-mlb-mode for ML Basis files (see http://mlton.org/Emacs)
-
-* make `M-x sml-compile' more generic.
-
-* allow specifying indentation of dependent keywords (how to indent `in'
- relative to `let', for example).
-
-* recognize irrefutable patterns (with "Capital"-heuristics, for example:
- a regexp like "\\([(),]\\|[_a-z][_a-z0-9]*\\)+").
- This can then be used to allow indenting like
-
- (fn x =>
- some expressions)
-
-* take advantage of text after-the-line (when available) for indentation.
-
-* obey fixity directives.
-
-* dangling `case e' in stuff like
-
- fun myfunction x = case x
- of bla =>
- | bli =>
-
-* deal with CPS kind of code ???
-
- function1 (arg1, arg2, fn v1 =>
- function2 (arg2, fn v2 =>
- function3 (arg5, arg3, arg8, fn v3 =>
- function4 (v1, v2, v3))))
-
- or even just
-
- F.LET (v1, foo,
- F.LET (v2, bar,
- F.LET (v3, baz,
- F.RET [v1, v2, v3])))
diff --git a/emacs/emacs.d/sml-mode-5.0/makefile.pkg b/emacs/emacs.d/sml-mode-5.0/makefile.pkg
@@ -1,15 +0,0 @@
-PACKAGE = sml-mode
-ELFILES = sml-mode.el sml-proc.el sml-oldindent.el
-
-default: elcfiles
-
-TESTCASE = testcases.sml
-
-test:
- $(RM) $(TESTCASE).new
- $(EMACS) --batch \
- --eval "(load \"$$(pwd)/sml-mode-startup\")" \
- $(TESTCASE) \
- --eval '(indent-region (point-min) (point-max) nil)' \
- --eval '(write-region (point-min) (point-max) "$(TESTCASE).new")'
- diff -u -B $(TESTCASE) $(TESTCASE).new
diff --git a/emacs/emacs.d/sml-mode-5.0/sml-mode-startup.el b/emacs/emacs.d/sml-mode-5.0/sml-mode-startup.el
@@ -1,59 +0,0 @@
-;;; sml-mode-startup.el --- automatically extracted autoloads
-;;; Code:
-(add-to-list 'load-path
- (or (file-name-directory load-file-name) (car load-path)))
-
-;;;### (autoloads (sml-yacc-mode sml-lex-mode sml-cm-mode sml-mode)
-;;;;;; "sml-mode" "sml-mode.el" (20358 8148))
-;;; Generated autoloads from sml-mode.el
-
-(add-to-list 'auto-mode-alist '("\\.s\\(ml\\|ig\\)\\'" . sml-mode))
-
-(autoload 'sml-mode "sml-mode" "\
-\\<sml-mode-map>Major mode for editing ML code.
-This mode runs `sml-mode-hook' just before exiting.
-\\{sml-mode-map}
-
-\(fn)" t nil)
-
-(add-to-list 'completion-ignored-extensions ".cm/")
-
-(add-to-list 'auto-mode-alist '("\\.cm\\'" . sml-cm-mode))
-
-(autoload 'sml-cm-mode "sml-mode" "\
-Major mode for SML/NJ's Compilation Manager configuration files.
-
-\(fn)" t nil)
-
-(autoload 'sml-lex-mode "sml-mode" "\
-Major Mode for editing ML-Lex files.
-
-\(fn)" t nil)
-
-(add-to-list 'auto-mode-alist '("\\.grm\\'" . sml-yacc-mode))
-
-(autoload 'sml-yacc-mode "sml-mode" "\
-Major Mode for editing ML-Yacc files.
-
-\(fn)" t nil)
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "sml-mode" '("font-lock-type-def-face" "font-lock-module-def-face" "font-lock-interface-def-face")))
-
-;;;***
-
-;;;### (autoloads nil "sml-oldindent" "sml-oldindent.el" (20358 8148))
-;;; Generated autoloads from sml-oldindent.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "sml-oldindent" '("sml-")))
-
-;;;***
-
-;;;### (autoloads nil "sml-proc" "sml-proc.el" (20358 8148))
-;;; Generated autoloads from sml-proc.el
-
-(autoload 'run-sml "sml-proc" nil t)
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "sml-proc" '("sml-" "inferior-sml-" "font-lock-" "run-sml" "switch-to-sml")))
-
-;;;***
-
diff --git a/emacs/emacs.d/sml-mode-5.0/sml-mode.el b/emacs/emacs.d/sml-mode-5.0/sml-mode.el
@@ -1,1436 +0,0 @@
-;;; sml-mode.el --- Major mode for editing (Standard) ML
-
-;; Copyright (C) 1999,2000,2004,2007,2010-2012 Stefan Monnier
-;; Copyright (C) 1994-1997 Matthew J. Morley
-;; Copyright (C) 1989 Lars Bo Nielsen
-
-;; Author: Lars Bo Nielsen
-;; Olin Shivers
-;; Fritz Knabe (?)
-;; Steven Gilmore (?)
-;; Matthew Morley <mjm@scs.leeds.ac.uk> (aka <matthew@verisity.com>)
-;; Matthias Blume <blume@cs.princeton.edu> (aka <blume@kurims.kyoto-u.ac.jp>)
-;; (Stefan Monnier) <monnier@iro.umontreal.ca>
-;; Maintainer: (Stefan Monnier) <monnier@iro.umontreal.ca>
-;; Keywords: SML
-
-;; This file is not part of GNU Emacs, but it is distributed under the
-;; same conditions.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 3, or (at
-;; your option) any later version.
-
-;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;; General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;;; HISTORY
-
-;; Still under construction: History obscure, needs a biographer as
-;; well as a M-x doctor. Change Log on request.
-
-;; Hacked by Olin Shivers for comint from Lars Bo Nielsen's sml.el.
-
-;; Hacked by Matthew Morley to incorporate Fritz Knabe's hilite and
-;; font-lock patterns, some of Steven Gilmore's (reduced) easy-menus,
-;; and numerous bugs and bug-fixes.
-
-;;; DESCRIPTION
-
-;; See accompanying info file: sml-mode.info
-
-;;; FOR YOUR .EMACS FILE
-
-;; If sml-mode.el lives in some non-standard directory, you must tell
-;; emacs where to get it. This may or may not be necessary:
-
-;; (add-to-list 'load-path "~jones/lib/emacs/")
-
-;; Then to access the commands autoload sml-mode with that command:
-
-;; (load "sml-mode-startup")
-
-;; sml-mode-hook is run whenever a new sml-mode buffer is created.
-
-;; Finally, there are inferior-sml-{mode,load}-hooks -- see comments
-;; in sml-proc.el. For much more information consult the mode's *info*
-;; tree.
-
-;;; Code:
-
-(eval-when-compile (require 'cl))
-(require 'smie nil 'noerror)
-
-(condition-case nil (require 'skeleton) (error nil))
-
-(defgroup sml ()
- "Editing SML code."
- :group 'languages)
-
-;;; VARIABLES CONTROLLING INDENTATION
-
-(defcustom sml-indent-level 4
- "Indentation of blocks in ML (see also `sml-indent-rule')."
- :type '(integer))
-
-(defcustom sml-indent-args sml-indent-level
- "Indentation of args placed on a separate line."
- :type '(integer))
-
-;; (defvar sml-indent-align-args t
-;; "*Whether the arguments should be aligned.")
-
-;; (defvar sml-case-indent nil
-;; "*How to indent case-of expressions.
-;; If t: case expr If nil: case expr of
-;; of exp1 => ... exp1 => ...
-;; | exp2 => ... | exp2 => ...
-
-;; The first seems to be the standard in SML/NJ, but the second
-;; seems nicer...")
-
-(defcustom sml-electric-semi-mode nil
- "If non-nil, `\;' will self insert, reindent the line, and do a newline.
-If nil, just insert a `\;'. (To insert while t, do: \\[quoted-insert] \;)."
- :type 'boolean)
-(when (fboundp 'electric-layout-mode)
- (make-obsolete-variable 'sml-electric-semi-mode
- 'electric-layout-mode "Emacs-24"))
-
-(defcustom sml-rightalign-and t
- "If non-nil, right-align `and' with its leader.
-If nil: If t:
- datatype a = A datatype a = A
- and b = B and b = B"
- :type 'boolean)
-
-;;; OTHER GENERIC MODE VARIABLES
-
-(defvar sml-mode-info "sml-mode"
- "*Where to find Info file for `sml-mode'.
-The default assumes the info file \"sml-mode.info\" is on Emacs' info
-directory path. If it is not, either put the file on the standard path
-or set the variable `sml-mode-info' to the exact location of this file
-
- (setq sml-mode-info \"/usr/me/lib/info/sml-mode\")
-
-in your .emacs file. You can always set it interactively with the
-set-variable command.")
-
-(defvar sml-mode-hook nil
- "*Run upon entering `sml-mode'.
-This is a good place to put your preferred key bindings.")
-
-;;; CODE FOR SML-MODE
-
-(defun sml-mode-info ()
- "Command to access the TeXinfo documentation for `sml-mode'.
-See doc for the variable `sml-mode-info'."
- (interactive)
- (require 'info)
- (condition-case nil
- (info sml-mode-info)
- (error (progn
- (describe-variable 'sml-mode-info)
- (message "Can't find it... set this variable first!")))))
-
-
-;;; Autoload functions -- no-doc is another idea cribbed from AucTeX!
-
-(let ((sml-no-doc
- "This function is part of sml-proc, and has not yet been loaded.
-Full documentation will be available after autoloading the function."))
-
- (autoload 'sml-compile "sml-proc" sml-no-doc t)
- (autoload 'sml-load-file "sml-proc" sml-no-doc t)
- (autoload 'switch-to-sml "sml-proc" sml-no-doc t)
- (autoload 'sml-send-region "sml-proc" sml-no-doc t)
- (autoload 'sml-send-buffer "sml-proc" sml-no-doc t))
-
-;; font-lock setup
-
-(defvar sml-outline-regexp
- ;; `st' and `si' are to match structure and signature.
- "\\|s[ti]\\|[ \t]*\\(let[ \t]+\\)?\\(fun\\|and\\)\\>"
- "Regexp matching a major heading.
-This actually can't work without extending `outline-minor-mode' with the
-notion of \"the end of an outline\".")
-
-;;
-;; Internal defines
-;;
-
-(defvar sml-mode-map
- (let ((map (make-sparse-keymap)))
- ;; Smarter cursor movement.
- ;; (define-key map [remap forward-sexp] 'sml-user-forward-sexp)
- ;; (define-key map [remap backward-sexp] 'sml-user-backward-sexp)
- ;; Text-formatting commands:
- (define-key map "\C-c\C-m" 'sml-insert-form)
- (define-key map "\C-c\C-i" 'sml-mode-info)
- (define-key map "\M-|" 'sml-electric-pipe)
- (define-key map "\M-\ " 'sml-electric-space)
- (define-key map "\;" 'sml-electric-semi)
- (define-key map [backtab] 'sml-back-to-outer-indent)
- ;; Process commands added to sml-mode-map -- these should autoload.
- (define-key map "\C-c\C-l" 'sml-load-file)
- (define-key map "\C-c\C-c" 'sml-compile)
- (define-key map "\C-c\C-s" 'switch-to-sml)
- (define-key map "\C-c\C-r" 'sml-send-region)
- (define-key map "\C-c\C-b" 'sml-send-buffer)
- map)
- "The keymap used in `sml-mode'.")
-
-(defconst sml-builtin-nested-comments-flag
- (ignore-errors
- (not (equal (let ((st (make-syntax-table)))
- (modify-syntax-entry ?\* ". 23n" st) st)
- (let ((st (make-syntax-table)))
- (modify-syntax-entry ?\* ". 23" st) st))))
- "Non-nil means this Emacs understands the `n' in syntax entries.")
-
-(defvar sml-mode-syntax-table
- (let ((st (make-syntax-table)))
- (modify-syntax-entry ?\* (if sml-builtin-nested-comments-flag
- ". 23n" ". 23") st)
- (modify-syntax-entry ?\( "()1" st)
- (modify-syntax-entry ?\) ")(4" st)
- (mapc (lambda (c) (modify-syntax-entry c "_" st)) "._'")
- (mapc (lambda (c) (modify-syntax-entry c "." st)) ",;")
- ;; `!' is not really a prefix-char, oh well!
- (mapc (lambda (c) (modify-syntax-entry c "'" st)) "~#!")
- (mapc (lambda (c) (modify-syntax-entry c "." st)) "%&$+-/:<=>?@`^|")
- st)
- "The syntax table used in `sml-mode'.")
-
-
-(easy-menu-define sml-mode-menu sml-mode-map "Menu used in `sml-mode'."
- '("SML"
- ("Process"
- ["Start default ML compiler" run-sml t]
- ["-" nil nil]
- ["run CM.make" sml-compile t]
- ["load ML source file" sml-load-file t]
- ["switch to ML buffer" switch-to-sml t]
- ["--" nil nil]
- ["send buffer contents" sml-send-buffer t]
- ["send region" sml-send-region t]
- ["send paragraph" sml-send-function t]
- ["goto next error" next-error (featurep 'sml-proc)]
- ["---" nil nil]
- ;; ["Standard ML of New Jersey" sml-smlnj (fboundp 'sml-smlnj)]
- ;; ["Poly/ML" sml-poly-ml (fboundp 'sml-poly-ml)]
- ;; ["Moscow ML" sml-mosml (fboundp 'sml-mosml)]
- ["Help for Inferior ML" (describe-function 'inferior-sml-mode)
- :active (featurep 'sml-proc)])
- ["electric pipe" sml-electric-pipe t]
- ["insert SML form" sml-insert-form t]
- ("Forms" :filter sml-forms-menu)
- ("Format/Mode Variables"
- ["indent region" indent-region t]
- ["outdent" sml-back-to-outer-indent t]
- ;; ["-" nil nil]
- ;; ["set indent-level" sml-indent-level t]
- ;; ["set pipe-indent" sml-pipe-indent t]
- ;; ["--" nil nil]
- ;; ["toggle type-of-indent" sml-type-of-indent t]
- ;; ["toggle nested-if-indent" sml-nested-if-indent t]
- ;; ["toggle electric-semi-mode" sml-electric-semi-mode t]
- )
- ["-----" nil nil]
- ["SML mode help (brief)" describe-mode t]
- ["SML mode *info*" sml-mode-info t]
- ["Remove overlay" (sml-error-overlay 'undo)
- :visible (or (and (boundp 'sml-error-overlay)
- sml-error-overlay)
- (not (fboundp 'compilation-fake-loc)))
- :active (and (boundp 'sml-error-overlay)
- (overlayp sml-error-overlay)
- (overlay-start sml-error-overlay))
- ]))
-
-;; Make's sure they appear in the menu bar when sml-mode-map is active.
-;; On the hook for XEmacs only -- see easy-menu-add in auc-menu.el.
-;; (defun sml-mode-menu-bar ()
-;; "Make sure menus appear in the menu bar as well as under mouse 3."
-;; (and (eq major-mode 'sml-mode)
-;; (easy-menu-add sml-mode-menu sml-mode-map)))
-;; (add-hook 'sml-mode-hook 'sml-mode-menu-bar)
-
-;;
-;; regexps
-;;
-
-(defun sml-syms-re (syms)
- (concat "\\<" (regexp-opt syms t) "\\>"))
-
-;;
-
-(defconst sml-module-head-syms
- '("signature" "structure" "functor" "abstraction"))
-
-
-(defconst sml-=-starter-syms
- (list* "|" "val" "fun" "and" "datatype" "type" "abstype" "eqtype"
- sml-module-head-syms)
- "Symbols that can be followed by a `='.")
-(defconst sml-=-starter-re
- (concat "\\S.|\\S.\\|" (sml-syms-re (cdr sml-=-starter-syms)))
- "Symbols that can be followed by a `='.")
-
-(defconst sml-non-nested-of-starter-re
- (sml-syms-re '("datatype" "abstype" "exception"))
- "Symbols that can introduce an `of' that shouldn't behave like a paren.")
-
-(defconst sml-starters-syms
- (append sml-module-head-syms
- '("abstype" "datatype" "exception" "fun"
- "local" "infix" "infixr" "sharing" "nonfix"
- "open" "type" "val" "and"
- "withtype" "with"))
- "The starters of new expressions.")
-
-(defconst sml-pipeheads
- '("|" "of" "fun" "fn" "and" "handle" "datatype" "abstype")
- "A `|' corresponds to one of these.")
-
-(defconst sml-keywords-regexp
- (sml-syms-re '("abstraction" "abstype" "and" "andalso" "as" "before" "case"
- "datatype" "else" "end" "eqtype" "exception" "do" "fn"
- "fun" "functor" "handle" "if" "in" "include" "infix"
- "infixr" "let" "local" "nonfix" "of" "op" "open" "orelse"
- "overload" "raise" "rec" "sharing" "sig" "signature"
- "struct" "structure" "then" "type" "val" "where" "while"
- "with" "withtype" "o"))
- "A regexp that matches any and all keywords of SML.")
-
-(defconst sml-tyvarseq-re
- "\\(\\('+\\(\\sw\\|\\s_\\)+\\|(\\([,']\\|\\sw\\|\\s_\\|\\s-\\)+)\\)\\s-+\\)?")
-
-;;; Font-lock settings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defcustom sml-font-lock-symbols nil
- "Display \\ and -> and such using symbols in fonts.
-This may sound like a neat trick, but be extra careful: it changes the
-alignment and can thus lead to nasty surprises w.r.t layout.
-If t, try to use whichever font is available. Otherwise you can
-set it to a particular font of your preference among `japanese-jisx0208'
-and `unicode'."
- :type '(choice (const nil)
- (const t)
- (const unicode)
- (const japanese-jisx0208)))
-
-(defconst sml-font-lock-symbols-alist
- (append
- ;; The symbols can come from a JIS0208 font.
- (and (fboundp 'make-char) (charsetp 'japanese-jisx0208)
- (memq sml-font-lock-symbols '(t japanese-jisx0208))
- (list (cons "fn" (make-char 'japanese-jisx0208 38 75))
- (cons "andalso" (make-char 'japanese-jisx0208 34 74))
- (cons "orelse" (make-char 'japanese-jisx0208 34 75))
- ;; (cons "as" (make-char 'japanese-jisx0208 34 97))
- (cons "not" (make-char 'japanese-jisx0208 34 76))
- (cons "div" (make-char 'japanese-jisx0208 33 96))
- ;; (cons "*" (make-char 'japanese-jisx0208 33 95))
- (cons "->" (make-char 'japanese-jisx0208 34 42))
- (cons "=>" (make-char 'japanese-jisx0208 34 77))
- (cons "<-" (make-char 'japanese-jisx0208 34 43))
- (cons "<>" (make-char 'japanese-jisx0208 33 98))
- (cons ">=" (make-char 'japanese-jisx0208 33 102))
- (cons "<=" (make-char 'japanese-jisx0208 33 101))
- (cons "..." (make-char 'japanese-jisx0208 33 68))
- ;; Some greek letters for type parameters.
- (cons "'a" (make-char 'japanese-jisx0208 38 65))
- (cons "'b" (make-char 'japanese-jisx0208 38 66))
- (cons "'c" (make-char 'japanese-jisx0208 38 67))
- (cons "'d" (make-char 'japanese-jisx0208 38 68))
- ))
- ;; Or a unicode font.
- (and (fboundp 'decode-char)
- (memq sml-font-lock-symbols '(t unicode))
- (list (cons "fn" (decode-char 'ucs 955))
- (cons "andalso" (decode-char 'ucs 8896))
- (cons "orelse" (decode-char 'ucs 8897))
- ;; (cons "as" (decode-char 'ucs 8801))
- (cons "not" (decode-char 'ucs 172))
- (cons "div" (decode-char 'ucs 247))
- (cons "*" (decode-char 'ucs 215))
- (cons "o" (decode-char 'ucs 9675))
- (cons "->" (decode-char 'ucs 8594))
- (cons "=>" (decode-char 'ucs 8658))
- (cons "<-" (decode-char 'ucs 8592))
- (cons "<>" (decode-char 'ucs 8800))
- (cons ">=" (decode-char 'ucs 8805))
- (cons "<=" (decode-char 'ucs 8804))
- (cons "..." (decode-char 'ucs 8943))
- ;; (cons "::" (decode-char 'ucs 8759))
- ;; Some greek letters for type parameters.
- (cons "'a" (decode-char 'ucs 945))
- (cons "'b" (decode-char 'ucs 946))
- (cons "'c" (decode-char 'ucs 947))
- (cons "'d" (decode-char 'ucs 948))
- ))))
-
-(defun sml-font-lock-compose-symbol (alist)
- "Compose a sequence of ascii chars into a symbol.
-Regexp match data 0 points to the chars."
- ;; Check that the chars should really be composed into a symbol.
- (let* ((start (match-beginning 0))
- (end (match-end 0))
- (syntaxes (if (eq (char-syntax (char-after start)) ?w)
- '(?w) '(?. ?\\))))
- (if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
- (memq (char-syntax (or (char-after end) ?\ )) syntaxes)
- (memq (get-text-property start 'face)
- '(font-lock-doc-face font-lock-string-face
- font-lock-comment-face)))
- ;; No composition for you. Let's actually remove any composition
- ;; we may have added earlier and which is now incorrect.
- (remove-text-properties start end '(composition))
- ;; That's a symbol alright, so add the composition.
- (compose-region start end (cdr (assoc (match-string 0) alist)))))
- ;; Return nil because we're not adding any face property.
- nil)
-
-(defun sml-font-lock-symbols-keywords ()
- (when (fboundp 'compose-region)
- (let ((alist nil))
- (dolist (x sml-font-lock-symbols-alist)
- (when (and (if (fboundp 'char-displayable-p)
- (char-displayable-p (cdr x))
- t)
- (not (assoc (car x) alist))) ;Not yet in alist.
- (push x alist)))
- (when alist
- `((,(regexp-opt (mapcar 'car alist) t)
- (0 (sml-font-lock-compose-symbol ',alist))))))))
-
-;; The font lock regular expressions.
-
-(defconst sml-font-lock-keywords
- `(;;(sml-font-comments-and-strings)
- (,(concat "\\<\\(fun\\|and\\)\\s-+" sml-tyvarseq-re "\\(\\sw+\\)\\s-+[^ \t\n=]")
- (1 font-lock-keyword-face)
- (6 font-lock-function-name-face))
- (,(concat "\\<\\(\\(data\\|abs\\|with\\|eq\\)?type\\)\\s-+" sml-tyvarseq-re "\\(\\sw+\\)")
- (1 font-lock-keyword-face)
- (7 font-lock-type-def-face))
- ("\\<\\(val\\)\\s-+\\(\\sw+\\>\\s-*\\)?\\(\\sw+\\)\\s-*[=:]"
- (1 font-lock-keyword-face)
- ;;(6 font-lock-variable-def-face nil t)
- (3 font-lock-variable-name-face))
- ("\\<\\(structure\\|functor\\|abstraction\\)\\s-+\\(\\sw+\\)"
- (1 font-lock-keyword-face)
- (2 font-lock-module-def-face))
- ("\\<\\(signature\\)\\s-+\\(\\sw+\\)"
- (1 font-lock-keyword-face)
- (2 font-lock-interface-def-face))
-
- (,sml-keywords-regexp . font-lock-keyword-face)
- ,@(sml-font-lock-symbols-keywords))
- "Regexps matching standard SML keywords.")
-
-(defface font-lock-type-def-face
- '((t (:bold t)))
- "Font Lock mode face used to highlight type definitions."
- :group 'font-lock-highlighting-faces)
-(defvar font-lock-type-def-face 'font-lock-type-def-face
- "Face name to use for type definitions.")
-
-(defface font-lock-module-def-face
- '((t (:bold t)))
- "Font Lock mode face used to highlight module definitions."
- :group 'font-lock-highlighting-faces)
-(defvar font-lock-module-def-face 'font-lock-module-def-face
- "Face name to use for module definitions.")
-
-(defface font-lock-interface-def-face
- '((t (:bold t)))
- "Font Lock mode face used to highlight interface definitions."
- :group 'font-lock-highlighting-faces)
-(defvar font-lock-interface-def-face 'font-lock-interface-def-face
- "Face name to use for interface definitions.")
-
-;;
-;; Code to handle nested comments and unusual string escape sequences
-;;
-
-(defvar sml-syntax-prop-table
- (let ((st (make-syntax-table)))
- (modify-syntax-entry ?\\ "." st)
- (modify-syntax-entry ?* "." st)
- st)
- "Syntax table for text-properties")
-
-;; For Emacsen that have no built-in support for nested comments
-(defun sml-get-depth-st ()
- (save-excursion
- (let* ((disp (if (eq (char-before) ?\)) (progn (backward-char) -1) nil))
- (_ (backward-char))
- (disp (if (eq (char-before) ?\() (progn (backward-char) 0) disp))
- (pt (point)))
- (when disp
- (let* ((depth
- (save-match-data
- (if (re-search-backward "\\*)\\|(\\*" nil t)
- (+ (or (get-char-property (point) 'comment-depth) 0)
- (case (char-after) (?\( 1) (?* 0))
- disp)
- 0)))
- (depth (if (> depth 0) depth)))
- (put-text-property pt (1+ pt) 'comment-depth depth)
- (when depth sml-syntax-prop-table))))))
-
-(defconst sml-font-lock-syntactic-keywords
- `(("^\\s-*\\(\\\\\\)" (1 ',sml-syntax-prop-table))
- ,@(unless sml-builtin-nested-comments-flag
- '(("(?\\(\\*\\))?" (1 (sml-get-depth-st)))))))
-
-(defconst sml-font-lock-defaults
- '(sml-font-lock-keywords nil nil ((?_ . "w") (?' . "w")) nil
- (font-lock-syntactic-keywords . sml-font-lock-syntactic-keywords)))
-
-
-;;; Indentation with SMIE
-
-(defvar sml-use-smie t)
-
-(defconst sml-smie-grammar
- (when (fboundp 'smie-prec2->grammar)
- ;; We have several problem areas where SML's syntax can't be handled by an
- ;; operator precedence grammar:
- ;;
- ;; "= A before B" is "= A) before B" if this is the
- ;; `boolean-=' but it is "= (A before B)" if it's the `definitional-='.
- ;; We can work around the problem by tweaking the lexer to return two
- ;; different tokens for the two different kinds of `='.
- ;; "of A | B" in a "case" we want "of (A | B, but in a `datatype'
- ;; we want "of A) | B".
- ;; "= A | B" can be "= A ) | B" if the = is from a "fun" definition,
- ;; but it is "= (A | B" if it is a `datatype' definition (of course, if
- ;; the previous token introducing the = is `and', deciding whether
- ;; it's a datatype or a function requires looking even further back).
- ;; "functor foo (...) where type a = b = ..." the first `=' looks very much
- ;; like a `definitional-=' even tho it's just an equality constraint.
- ;; Currently I don't even try to handle `where' at all.
- (smie-prec2->grammar
- (smie-merge-prec2s
- (smie-bnf->prec2
- '((exp ("if" exp "then" exp "else" exp)
- ("case" exp "of" branches)
- ("let" decls "in" cmds "end")
- ("struct" decls "end")
- ("sig" decls "end")
- (sexp)
- (sexp "handle" branches)
- ("fn" sexp "=>" exp))
- ;; "simple exp"s are the ones that can appear to the left of `handle'.
- (sexp (sexp ":" type) ("(" exps ")")
- (sexp "orelse" sexp)
- (marg ":>" type)
- (sexp "andalso" sexp))
- (cmds (cmds ";" cmds) (exp))
- (exps (exps "," exps) (exp)) ; (exps ";" exps)
- (branches (sexp "=>" exp) (branches "|" branches))
- ;; Operator precedence grammars handle separators much better then
- ;; starters/terminators, so let's pretend that let/fun are separators.
- (decls (sexp "d=" exp)
- (sexp "d=" databranches)
- (funbranches "|" funbranches)
- (sexp "=of" type) ;After "exception".
- ;; FIXME: Just like PROCEDURE in Pascal and Modula-2, this
- ;; interacts poorly with the other constructs since I
- ;; can't make "local" a separator like fun/val/type/...
- ("local" decls "in" decls "end")
- ;; (decls "local" decls "in" decls "end")
- (decls "functor" decls)
- (decls "signature" decls)
- (decls "structure" decls)
- (decls "type" decls)
- (decls "open" decls)
- (decls "and" decls)
- (decls "infix" decls)
- (decls "infixr" decls)
- (decls "nonfix" decls)
- (decls "abstype" decls)
- (decls "datatype" decls)
- (decls "exception" decls)
- (decls "fun" decls)
- (decls "val" decls))
- (type (type "->" type)
- (type "*" type))
- (funbranches (sexp "d=" exp))
- (databranches (sexp "=of" type) (databranches "d|" databranches))
- ;; Module language.
- ;; (mexp ("functor" marg "d=" mexp)
- ;; ("structure" marg "d=" mexp)
- ;; ("signature" marg "d=" mexp))
- (marg (marg ":" type) (marg ":>" type))
- (toplevel (decls) (exp) (toplevel ";" toplevel)))
- ;; '(("local" . opener))
- ;; '((nonassoc "else") (right "handle"))
- '((nonassoc "of") (assoc "|")) ; "case a of b => case c of d => e | f"
- '((nonassoc "handle") (assoc "|")) ; Idem for "handle".
- '((assoc "->") (assoc "*"))
- '((assoc "val" "fun" "type" "datatype" "abstype" "open" "infix" "infixr"
- "nonfix" "functor" "signature" "structure" "exception"
- ;; "local"
- )
- (assoc "and"))
- '((assoc "orelse") (assoc "andalso") (nonassoc ":"))
- '((assoc ";")) '((assoc ",")) '((assoc "d|")))
-
- (smie-precs->prec2
- '((nonassoc "andalso") ;To anchor the prec-table.
- (assoc "before") ;0
- (assoc ":=" "o") ;3
- (nonassoc ">" ">=" "<>" "<" "<=" "=") ;4
- (assoc "::" "@") ;5
- (assoc "+" "-" "^") ;6
- (assoc "/" "*" "quot" "rem" "div" "mod") ;7
- (nonassoc " -dummy- "))) ;Bogus anchor at the end.
- ))))
-
-(defvar sml-indent-separator-outdent 2)
-
-(defun sml-smie-rules (kind token)
- ;; I much preferred the pcase version of the code, especially while
- ;; edebugging the code. But that will have to wait until we get rid of
- ;; support for Emacs-23.
- (case kind
- (:elem (case token
- (basic sml-indent-level)
- (args sml-indent-args)))
- (:list-intro (member token '("fn")))
- (:after
- (cond
- ((equal token "struct") 0)
- ((equal token "=>") (if (smie-rule-hanging-p) 0 2))
- ((equal token "in") (if (smie-rule-parent-p "local") 0))
- ((equal token "of") 3)
- ((member token '("(" "{" "[")) (if (not (smie-rule-hanging-p)) 2))
- ((equal token "else") (if (smie-rule-hanging-p) 0)) ;; (:next "if" 0)
- ((member token '("|" "d|" ";" ",")) (smie-rule-separator kind))
- ((equal token "d=")
- (if (and (smie-rule-parent-p "val") (smie-rule-next-p "fn")) -3))))
- (:before
- (cond
- ((equal token "=>") (if (smie-rule-parent-p "fn") 3))
- ((equal token "of") 1)
- ;; In case the language is extended to allow a | directly after of.
- ((and (equal token "|") (smie-rule-prev-p "of")) 1)
- ((member token '("|" "d|" ";" ",")) (smie-rule-separator kind))
- ;; Treat purely syntactic block-constructs as being part of their parent,
- ;; when the opening statement is hanging.
- ((member token '("let" "(" "[" "{"))
- (if (smie-rule-hanging-p) (smie-rule-parent)))
- ;; Treat if ... else if ... as a single long syntactic construct.
- ;; Similarly, treat fn a => fn b => ... as a single construct.
- ((member token '("if" "fn"))
- (and (not (smie-rule-bolp))
- (smie-rule-prev-p (if (equal token "if") "else" "=>"))
- (smie-rule-parent)))
- ((equal token "and")
- ;; FIXME: maybe "and" (c|sh)ould be handled as an smie-separator.
- (cond
- ((smie-rule-parent-p "datatype") (if sml-rightalign-and 5 0))
- ((smie-rule-parent-p "fun" "val") 0)))
- ((equal token "d=")
- (cond
- ((smie-rule-parent-p "datatype") (if (smie-rule-bolp) 2))
- ((smie-rule-parent-p "structure" "signature") 0)))
- ;; Indent an expression starting with "local" as if it were starting
- ;; with "fun".
- ((equal token "local") (smie-indent-keyword "fun"))
- ;; FIXME: type/val/fun/... are separators but "local" is not, even though
- ;; it appears in the same list. Try to fix up the problem by hand.
- ;; ((or (equal token "local")
- ;; (equal (cdr (assoc token smie-grammar))
- ;; (cdr (assoc "fun" smie-grammar))))
- ;; (let ((parent (save-excursion (smie-backward-sexp))))
- ;; (when (or (and (equal (nth 2 parent) "local")
- ;; (null (car parent)))
- ;; (progn
- ;; (setq parent (save-excursion (smie-backward-sexp "fun")))
- ;; (eq (car parent) (nth 1 (assoc "fun" smie-grammar)))))
- ;; (goto-char (nth 1 parent))
- ;; (cons 'column (smie-indent-virtual)))))
- ))))
-
-(defun sml-smie-definitional-equal-p ()
- "Figure out which kind of \"=\" this is.
-Assumes point is right before the = sign."
- ;; The idea is to look backward for the first occurrence of a token that
- ;; requires a definitional "=" and then see if there's such a definitional
- ;; equal between that token and ourselves (in which case we're not
- ;; a definitional = ourselves).
- ;; The "search for =" is naive and will match "=>" and "<=", but it turns
- ;; out to be OK in practice because such tokens very rarely (if ever) appear
- ;; between the =-starter and the corresponding definitional equal.
- ;; One known problem case is code like:
- ;; "functor foo (structure s : S) where type t = s.t ="
- ;; where the "type t = s.t" is mistaken for a type definition.
- (let ((re (concat "\\(" sml-=-starter-re "\\)\\|=")))
- (save-excursion
- (and (re-search-backward re nil t)
- (or (match-beginning 1)
- ;; If we first hit a "=", then that = is probably definitional
- ;; and we're an equality, but not necessarily. One known
- ;; problem case is code like:
- ;; "functor foo (structure s : S) where type t = s.t ="
- ;; where the first = is more like an equality (tho it doesn't
- ;; matter much) and the second is definitional.
- ;;
- ;; FIXME: The test below could be used to recognize that the
- ;; second = is not a mere equality, but that's not enough to
- ;; parse the construct properly: we'd need something
- ;; like a third kind of = token for structure definitions, in
- ;; order for the parser to be able to skip the "type t = s.t"
- ;; as a sub-expression.
- ;;
- ;; (and (not (looking-at "=>"))
- ;; (not (eq ?< (char-before))) ;Not a <=
- ;; (re-search-backward re nil t)
- ;; (match-beginning 1)
- ;; (equal "type" (buffer-substring (- (match-end 1) 4)
- ;; (match-end 1))))
- )))))
-
-(defun sml-smie-non-nested-of-p ()
- ;; FIXME: Maybe datatype-|-p makes this nested-of business unnecessary.
- "Figure out which kind of \"of\" this is.
-Assumes point is right before the \"of\" symbol."
- (save-excursion
- (and (re-search-backward (concat "\\(" sml-non-nested-of-starter-re
- "\\)\\|\\<case\\>") nil t)
- (match-beginning 1))))
-
-(defun sml-smie-datatype-|-p ()
- "Figure out which kind of \"|\" this is.
-Assumes point is right before the | symbol."
- (save-excursion
- (forward-char 1) ;Skip the |.
- (let ((after-type-def
- '("|" "of" "in" "datatype" "and" "exception" "abstype" "infix"
- "infixr" "nonfix" "local" "val" "fun" "structure" "functor"
- "signature")))
- (or (member (sml-smie-forward-token-1) after-type-def) ;Skip the tag.
- (member (sml-smie-forward-token-1) after-type-def)))))
-
-(defun sml-smie-forward-token-1 ()
- (forward-comment (point-max))
- (buffer-substring-no-properties
- (point)
- (progn
- (or (/= 0 (skip-syntax-forward "'w_"))
- (skip-syntax-forward ".'"))
- (point))))
-
-(defun sml-smie-forward-token ()
- (let ((sym (sml-smie-forward-token-1)))
- (cond
- ((equal "op" sym)
- (concat "op " (sml-smie-forward-token-1)))
- ((member sym '("|" "of" "="))
- ;; The important lexer for indentation's performance is the backward
- ;; lexer, so for the forward lexer we delegate to the backward one.
- (save-excursion (sml-smie-backward-token)))
- (t sym))))
-
-(defun sml-smie-backward-token-1 ()
- (forward-comment (- (point)))
- (buffer-substring-no-properties
- (point)
- (progn
- (or (/= 0 (skip-syntax-backward ".'"))
- (skip-syntax-backward "'w_"))
- (point))))
-
-(defun sml-smie-backward-token ()
- (let ((sym (sml-smie-backward-token-1)))
- (unless (zerop (length sym))
- ;; FIXME: what should we do if `sym' = "op" ?
- (let ((point (point)))
- (if (equal "op" (sml-smie-backward-token-1))
- (concat "op " sym)
- (goto-char point)
- (cond
- ((string= sym "=") (if (sml-smie-definitional-equal-p) "d=" "="))
- ((string= sym "of") (if (sml-smie-non-nested-of-p) "=of" "of"))
- ((string= sym "|") (if (sml-smie-datatype-|-p) "d|" "|"))
- (t sym)))))))
-
-;;;;
-;;;; Imenu support
-;;;;
-
-(defvar sml-imenu-regexp
- (concat "^[ \t]*\\(let[ \t]+\\)?"
- (regexp-opt (append sml-module-head-syms
- '("and" "fun" "datatype" "abstype" "type")) t)
- "\\>"))
-
-(defun sml-imenu-create-index ()
- (let (alist)
- (goto-char (point-max))
- (while (re-search-backward sml-imenu-regexp nil t)
- (save-excursion
- (let ((kind (match-string 2))
- (column (progn (goto-char (match-beginning 2)) (current-column)))
- (location
- (progn (goto-char (match-end 0))
- (forward-comment (point-max))
- (when (looking-at sml-tyvarseq-re)
- (goto-char (match-end 0)))
- (point)))
- (name (sml-smie-forward-token)))
- ;; Eliminate trivial renamings.
- (when (or (not (member kind '("structure" "signature")))
- (progn (search-forward "=")
- (forward-comment (point-max))
- (looking-at "sig\\|struct")))
- (push (cons (concat (make-string (/ column 2) ?\ ) name) location)
- alist)))))
- alist))
-
-;;; MORE CODE FOR SML-MODE
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.s\\(ml\\|ig\\)\\'" . sml-mode))
-
-(unless (fboundp 'prog-mode) (defalias 'prog-mode 'fundamental-mode))
-(defvar comment-quote-nested)
-(defvar electric-indent-chars)
-(defvar electric-layout-rules)
-
-;;;###autoload
-(define-derived-mode sml-mode prog-mode "SML"
- "\\<sml-mode-map>Major mode for editing ML code.
-This mode runs `sml-mode-hook' just before exiting.
-\\{sml-mode-map}"
- (set (make-local-variable 'font-lock-defaults) sml-font-lock-defaults)
- (set (make-local-variable 'outline-regexp) sml-outline-regexp)
- (set (make-local-variable 'imenu-create-index-function)
- 'sml-imenu-create-index)
- (set (make-local-variable 'add-log-current-defun-function)
- 'sml-current-fun-name)
- ;; Treat paragraph-separators in comments as paragraph-separators.
- (set (make-local-variable 'paragraph-separate)
- (concat "\\([ \t]*\\*)?\\)?\\(" paragraph-separate "\\)"))
- (set (make-local-variable 'require-final-newline) t)
- (set (make-local-variable 'electric-indent-chars)
- (cons ?\; (if (boundp 'electric-indent-chars)
- electric-indent-chars '(?\n))))
- (set (make-local-variable 'electric-layout-rules)
- `((?\; . ,(lambda ()
- (save-excursion
- (skip-chars-backward " \t;")
- (unless (or (bolp)
- (progn (skip-chars-forward " \t;")
- (eolp)))
- 'after))))))
- ;; For XEmacs
- (easy-menu-add sml-mode-menu)
- ;; Compatibility. FIXME: we should use `-' in Emacs-CVS.
- (unless (boundp 'skeleton-positions) (set (make-local-variable '@) nil))
- (sml-mode-variables))
-
-(defun sml-mode-variables ()
- (set-syntax-table sml-mode-syntax-table)
- (setq local-abbrev-table sml-mode-abbrev-table)
- ;; Setup indentation and sexp-navigation.
- (when (fboundp 'smie-setup)
- (smie-setup sml-smie-grammar #'sml-smie-rules
- :backward-token #'sml-smie-backward-token
- :forward-token #'sml-smie-forward-token))
- (unless (and sml-use-smie (fboundp 'smie-setup))
- (set (make-local-variable 'forward-sexp-function) 'sml-user-forward-sexp)
- (set (make-local-variable 'indent-line-function) 'sml-indent-line))
- (set (make-local-variable 'parse-sexp-ignore-comments) t)
- (set (make-local-variable 'comment-start) "(* ")
- (set (make-local-variable 'comment-end) " *)")
- (set (make-local-variable 'comment-start-skip) "(\\*+\\s-*")
- (set (make-local-variable 'comment-end-skip) "\\s-*\\*+)")
- ;; No need to quote nested comments markers.
- (set (make-local-variable 'comment-quote-nested) nil))
-
-(defun sml-funname-of-and ()
- "Name of the function this `and' defines, or nil if not a function.
-Point has to be right after the `and' symbol and is not preserved."
- (forward-comment (point-max))
- (if (looking-at sml-tyvarseq-re) (goto-char (match-end 0)))
- (let ((sym (sml-smie-forward-token)))
- (forward-comment (point-max))
- (unless (or (member sym '(nil "d="))
- (member (sml-smie-forward-token) '("d=")))
- sym)))
-
-(defun sml-find-forward (re)
- (while (progn (forward-comment (point-max))
- (not (looking-at re)))
- (or (ignore-errors (forward-sexp 1) t) (forward-char 1))))
-
-(defun sml-electric-pipe ()
- "Insert a \"|\".
-Depending on the context insert the name of function, a \"=>\" etc."
- ;; FIXME: Make it a skeleton.
- (interactive)
- (unless (save-excursion (skip-chars-backward "\t ") (bolp)) (insert "\n"))
- (insert "| ")
- (let ((text
- (save-excursion
- (backward-char 2) ;back over the just inserted "| "
- (let ((sym (sml-find-matching-starter sml-pipeheads
- ;; (sml-op-prec "|" 'back)
- )))
- (sml-smie-forward-token)
- (forward-comment (point-max))
- (cond
- ((string= sym "|")
- (let ((f (sml-smie-forward-token)))
- (sml-find-forward "\\(=>\\|=\\||\\)\\S.")
- (cond
- ((looking-at "|") "") ;probably a datatype
- ((looking-at "=>") " => ") ;`case', or `fn' or `handle'
- ((looking-at "=") (concat f " = "))))) ;a function
- ((string= sym "and")
- ;; could be a datatype or a function
- (setq sym (sml-funname-of-and))
- (if sym (concat sym " = ") ""))
- ;; trivial cases
- ((string= sym "fun")
- (while (and (setq sym (sml-smie-forward-token))
- (string-match "^'" sym))
- (forward-comment (point-max)))
- (concat sym " = "))
- ((member sym '("case" "handle" "fn" "of")) " => ")
- ;;((member sym '("abstype" "datatype")) "")
- (t ""))))))
-
- (insert text)
- (indent-according-to-mode)
- (beginning-of-line)
- (skip-chars-forward "\t |")
- (skip-syntax-forward "w")
- (skip-chars-forward "\t ")
- (when (eq ?= (char-after)) (backward-char))))
-
-(defun sml-electric-semi ()
- "Insert a \;.
-If variable `sml-electric-semi-mode' is t, indent the current line, insert
-a newline, and indent."
- (interactive)
- (self-insert-command 1)
- (if sml-electric-semi-mode
- (reindent-then-newline-and-indent)))
-
-;;; Misc
-
-(defun sml-mark-function ()
- "Mark the surrounding function. Or try to at least."
- (interactive)
- (if (not (fboundp 'smie-setup))
- (mark-paragraph)
- ;; FIXME: Provide beginning-of-defun-function so mark-defun "just works".
- (let ((start (point)))
- (sml-beginning-of-defun)
- (let ((beg (point)))
- (smie-forward-sexp 'halfsexp)
- (if (or (< start beg) (> start (point)))
- (progn
- (goto-char start)
- (mark-paragraph))
- (push-mark nil t t)
- (goto-char beg))))))
-
-(defun sml-back-to-outer-indent ()
- "Unindents to the next outer level of indentation."
- (interactive)
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward "\t ")
- (let ((start-column (current-column))
- (indent (current-column)))
- (if (> start-column 0)
- (progn
- (save-excursion
- (while (>= indent start-column)
- (if (re-search-backward "^[^\n]" nil t)
- (setq indent (current-indentation))
- (setq indent 0))))
- (backward-delete-char-untabify (- start-column indent)))))))
-
-(defun sml-smie-find-matching-starter (syms)
- (let ((halfsexp nil)
- tok)
- ;;(sml-smie-forward-token)
- (while (not (or (bobp)
- (member (nth 2 (setq tok (smie-backward-sexp halfsexp)))
- syms)))
- (cond
- ((null (car tok)) nil)
- ((numberp (car tok)) (setq halfsexp 'half))
- (t (goto-char (cadr tok)))))
- (if (nth 2 tok) (goto-char (cadr tok)))
- (nth 2 tok)))
-
-(defun sml-find-matching-starter (syms)
- (cond
- ((and sml-use-smie (fboundp 'smie-backward-sexp))
- (sml-smie-find-matching-starter syms))
- ((fboundp 'sml-old-find-matching-starter)
- (sml-old-find-matching-starter syms))))
-
-(defun sml-smie-skip-siblings ()
- (let (tok)
- (while (and (not (bobp))
- (progn (setq tok (smie-backward-sexp 'half))
- (cond
- ((null (car tok)) t)
- ((numberp (car tok)) t)
- (t nil)))))
- (if (nth 2 tok) (goto-char (cadr tok)))
- (nth 2 tok)))
-
-(defun sml-skip-siblings ()
- (cond
- ((and sml-use-smie (fboundp 'smie-backward-sexp))
- (sml-smie-skip-siblings))
- ((fboundp 'sml-old-skip-siblings)
- (sml-old-skip-siblings))
- (t (up-list -1))))
-
-(defun sml-beginning-of-defun ()
- (let ((sym (sml-find-matching-starter sml-starters-syms)))
- (if (member sym '("fun" "and" "functor" "signature" "structure"
- "abstraction" "datatype" "abstype"))
- (save-excursion (sml-smie-forward-token) (forward-comment (point-max))
- (sml-smie-forward-token))
- ;; We're inside a "non function declaration": let's skip all other
- ;; declarations that we find at the same level and try again.
- (sml-skip-siblings)
- ;; Obviously, let's not try again if we're at bobp.
- (unless (bobp) (sml-beginning-of-defun)))))
-
-(defcustom sml-max-name-components 3
- "Maximum number of components to use for the current function name."
- :type 'integer)
-
-(defun sml-current-fun-name ()
- (save-excursion
- (let ((count sml-max-name-components)
- fullname name)
- (end-of-line)
- (while (and (> count 0)
- (setq name (sml-beginning-of-defun)))
- (decf count)
- (setq fullname (if fullname (concat name "." fullname) name))
- ;; Skip all other declarations that we find at the same level.
- (sml-skip-siblings))
- fullname)))
-
-
-;;; INSERTING PROFORMAS (COMMON SML-FORMS)
-
-(defvar sml-forms-alist nil
- "*Alist of code templates.
-You can extend this alist to your heart's content. For each additional
-template NAME in the list, declare a keyboard macro or function (or
-interactive command) called 'sml-form-NAME'.
-If 'sml-form-NAME' is a function it takes no arguments and should
-insert the template at point\; if this is a command it may accept any
-sensible interactive call arguments\; keyboard macros can't take
-arguments at all. Apropos keyboard macros, see `name-last-kbd-macro'
-and `sml-addto-forms-alist'.
-`sml-forms-alist' understands let, local, case, abstype, datatype,
-signature, structure, and functor by default.")
-
-(defmacro sml-def-skeleton (name interactor &rest elements)
- (when (fboundp 'define-skeleton)
- (let ((fsym (intern (concat "sml-form-" name))))
- ;; TODO: don't do the expansion in comments and strings.
- `(progn
- (add-to-list 'sml-forms-alist ',(cons name fsym))
- (condition-case err
- ;; Try to use the new `system' flag.
- (define-abbrev sml-mode-abbrev-table ,name "" ',fsym nil 'system)
- (wrong-number-of-arguments
- (define-abbrev sml-mode-abbrev-table ,name "" ',fsym)))
- (when (fboundp 'abbrev-put)
- (let ((abbrev (abbrev-symbol ,name sml-mode-abbrev-table)))
- (abbrev-put abbrev :case-fixed t)
- (abbrev-put abbrev :enable-function
- (lambda () (not (nth 8 (syntax-ppss)))))))
- (define-skeleton ,fsym
- ,(format "SML-mode skeleton for `%s..' expressions" name)
- ,interactor
- ,(concat name " ") >
- ,@elements)))))
-(put 'sml-def-skeleton 'lisp-indent-function 2)
-
-(sml-def-skeleton "let" nil
- @ "\nin " > _ "\nend" >)
-
-(sml-def-skeleton "if" nil
- @ " then " > _ "\nelse " > _)
-
-(sml-def-skeleton "local" nil
- @ "\nin" > _ "\nend" >)
-
-(sml-def-skeleton "case" "Case expr: "
- str "\nof " > _ " => ")
-
-(sml-def-skeleton "signature" "Signature name: "
- str " =\nsig" > "\n" > _ "\nend" >)
-
-(sml-def-skeleton "structure" "Structure name: "
- str " =\nstruct" > "\n" > _ "\nend" >)
-
-(sml-def-skeleton "functor" "Functor name: "
- str " () : =\nstruct" > "\n" > _ "\nend" >)
-
-(sml-def-skeleton "datatype" "Datatype name and type params: "
- str " =" \n)
-
-(sml-def-skeleton "abstype" "Abstype name and type params: "
- str " =" \n _ "\nwith" > "\nend" >)
-
-;;
-
-(sml-def-skeleton "struct" nil
- _ "\nend" >)
-
-(sml-def-skeleton "sig" nil
- _ "\nend" >)
-
-(sml-def-skeleton "val" nil
- @ " = " > _)
-
-(sml-def-skeleton "fn" nil
- @ " =>" > _)
-
-(sml-def-skeleton "fun" nil
- @ " =" > _)
-
-;;
-
-(defun sml-forms-menu (menu)
- (mapcar (lambda (x) (vector (car x) (cdr x) t))
- sml-forms-alist))
-
-(defvar sml-last-form "let")
-
-(defun sml-electric-space ()
- "Expand a symbol into an SML form, or just insert a space.
-If the point directly precedes a symbol for which an SML form exists,
-the corresponding form is inserted."
- (interactive)
- (let ((abbrev-mode (not abbrev-mode))
- (last-command-event ?\ )
- ;; Bind `this-command' to fool skeleton's special abbrev handling.
- (this-command 'self-insert-command))
- (call-interactively 'self-insert-command)))
-
-(defun sml-insert-form (name newline)
- "Interactive short-cut to insert the NAME common ML form.
-If a prefix argument is given insert a NEWLINE and indent first, or
-just move to the proper indentation if the line is blank\; otherwise
-insert at point (which forces indentation to current column).
-
-The default form to insert is 'whatever you inserted last time'
-\(just hit return when prompted\)\; otherwise the command reads with
-completion from `sml-forms-alist'."
- (interactive
- (list (completing-read
- (format "Form to insert: (default %s) " sml-last-form)
- sml-forms-alist nil t nil)
- current-prefix-arg))
- ;; default is whatever the last insert was...
- (if (string= name "") (setq name sml-last-form) (setq sml-last-form name))
- (unless (or (not newline)
- (save-excursion (beginning-of-line) (looking-at "\\s-*$")))
- (insert "\n"))
- (unless (/= ?w (char-syntax (preceding-char))) (insert " "))
- (let ((f (cdr (assoc name sml-forms-alist))))
- (cond
- ((commandp f) (command-execute f))
- (f (funcall f))
- (t (error "Undefined form: %s" name)))))
-
-;; See also macros.el in emacs lisp dir.
-
-(defun sml-addto-forms-alist (name)
- "Assign a name to the last keyboard macro defined.
-Argument NAME is transmogrified to sml-form-NAME which is the symbol
-actually defined.
-
-The symbol's function definition becomes the keyboard macro string.
-
-If that works, NAME is added to `sml-forms-alist' so you'll be able to
-reinvoke the macro through \\[sml-insert-form]. You might want to save
-the macro to use in a later editing session -- see `insert-kbd-macro'
-and add these macros to your .emacs file.
-
-See also `edit-kbd-macro' which is bound to \\[edit-kbd-macro]."
- (interactive "sName for last kbd macro (\"sml-form-\" will be added): ")
- (when (string= name "") (error "No command name given"))
- (let ((fsym (intern (concat "sml-form-" name))))
- (name-last-kbd-macro fsym)
- (message "Macro bound to %s" fsym)
- (add-to-list 'sml-forms-alist (cons name fsym))))
-
-;;;
-;;; MLton support
-;;;
-
-(defvar sml-mlton-command "mlton"
- "Command to run MLton. Can include arguments.")
-
-(defvar sml-mlton-mainfile nil)
-
-(defconst sml-mlton-error-regexp-alist
- ;; I wish they just changed MLton to use one of the standard
- ;; error formats.
- `(("^\\(?:Error\\|\\(Warning\\)\\): \\(.+\\) \\([0-9]+\\)\\.\\([0-9]+\\)\\.$"
- 2 3 4
- ;; If subgroup 1 matched, then it's a warning, otherwise it's an error.
- ,@(if (fboundp 'compilation-fake-loc) '((1))))))
-
-(defvar compilation-error-regexp-alist)
-(eval-after-load "compile"
- '(dolist (x sml-mlton-error-regexp-alist)
- (add-to-list 'compilation-error-regexp-alist x)))
-
-(defun sml-mlton-typecheck (mainfile)
- "typecheck using MLton."
- (interactive
- (list (if (and mainfile (not current-prefix-arg))
- mainfile
- (read-file-name "Main file: "))))
- (save-some-buffers)
- (require 'compile)
- (dolist (x sml-mlton-error-regexp-alist)
- (add-to-list 'compilation-error-regexp-alist x))
- (with-current-buffer (find-file-noselect mainfile)
- (compile (concat sml-mlton-command
- " -stop tc " ;Stop right after type checking.
- (shell-quote-argument
- (file-relative-name buffer-file-name))))))
-
-;;;
-;;; MLton's def-use info.
-;;;
-
-(defvar sml-defuse-file nil)
-
-(defun sml-defuse-file ()
- (or sml-defuse-file (sml-defuse-set-file)))
-
-(defun sml-defuse-set-file ()
- "Specify the def-use file to use."
- (interactive)
- (setq sml-defuse-file (read-file-name "Def-use file: ")))
-
-(defun sml-defuse-symdata-at-point ()
- (save-excursion
- (sml-smie-forward-token)
- (let ((symname (sml-smie-backward-token)))
- (if (equal symname "op")
- (save-excursion (setq symname (sml-smie-forward-token))))
- (when (string-match "op " symname)
- (setq symname (substring symname (match-end 0)))
- (forward-word)
- (forward-comment (point-max)))
- (list symname
- ;; Def-use files seem to count chars, not columns.
- ;; We hope here that they don't actually count bytes.
- ;; Also they seem to start counting at 1.
- (1+ (- (point) (progn (beginning-of-line) (point))))
- (save-restriction
- (widen) (1+ (count-lines (point-min) (point))))
- buffer-file-name))))
-
-(defconst sml-defuse-def-regexp
- "^[[:alpha:]]+ \\([^ \n]+\\) \\(.+\\) \\([0-9]+\\)\\.\\([0-9]+\\)$")
-(defconst sml-defuse-use-regexp-format "^ %s %d\\.%d $")
-
-(defun sml-defuse-jump-to-def ()
- "Jump to the definition corresponding to the symbol at point."
- (interactive)
- (let ((symdata (sml-defuse-symdata-at-point)))
- (if (null (car symdata))
- (error "Not on a symbol")
- (with-current-buffer (find-file-noselect (sml-defuse-file))
- (goto-char (point-min))
- (unless (re-search-forward
- (format sml-defuse-use-regexp-format
- (concat "\\(?:"
- ;; May be an absolute file name.
- (regexp-quote (nth 3 symdata))
- "\\|"
- ;; Or a relative file name.
- (regexp-quote (file-relative-name
- (nth 3 symdata)))
- "\\)")
- (nth 2 symdata)
- (nth 1 symdata))
- nil t)
- ;; FIXME: This is typically due to editing: any minor editing will
- ;; mess everything up. We should try to fail more gracefully.
- (error "Def-use info not found"))
- (unless (re-search-backward sml-defuse-def-regexp nil t)
- ;; This indicates a bug in this code.
- (error "Internal failure while looking up def-use"))
- (unless (equal (match-string 1) (nth 0 symdata))
- ;; FIXME: This again is most likely due to editing.
- (error "Incoherence in the def-use info found"))
- (let ((line (string-to-number (match-string 3)))
- (char (string-to-number (match-string 4))))
- (pop-to-buffer (find-file-noselect (match-string 2)))
- (goto-char (point-min))
- (forward-line (1- line))
- (forward-char (1- char)))))))
-
-;;;
-;;; SML/NJ's Compilation Manager support
-;;;
-
-(defvar sml-cm-mode-syntax-table sml-mode-syntax-table)
-(defvar sml-cm-font-lock-keywords
- `(,(concat "\\<" (regexp-opt '("library" "group" "is" "structure"
- "functor" "signature" "funsig") t)
- "\\>")))
-;;;###autoload
-(add-to-list 'completion-ignored-extensions ".cm/")
-;; This was used with the old compilation manager.
-(add-to-list 'completion-ignored-extensions "CM/")
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.cm\\'" . sml-cm-mode))
-;;;###autoload
-(define-derived-mode sml-cm-mode fundamental-mode "SML-CM"
- "Major mode for SML/NJ's Compilation Manager configuration files."
- (local-set-key "\C-c\C-c" 'sml-compile)
- (set (make-local-variable 'font-lock-defaults)
- '(sml-cm-font-lock-keywords nil t nil nil)))
-
-;;;
-;;; ML-Lex support
-;;;
-
-(defvar sml-lex-font-lock-keywords
- (append
- '(("^%\\sw+" . font-lock-builtin-face)
- ("^%%" . font-lock-module-def-face))
- sml-font-lock-keywords))
-(defconst sml-lex-font-lock-defaults
- (cons 'sml-lex-font-lock-keywords (cdr sml-font-lock-defaults)))
-
-;;;###autoload
-(define-derived-mode sml-lex-mode sml-mode "SML-Lex"
- "Major Mode for editing ML-Lex files."
- (set (make-local-variable 'font-lock-defaults) sml-lex-font-lock-defaults))
-
-;;;
-;;; ML-Yacc support
-;;;
-
-(defface sml-yacc-bnf-face
- '((t (:foreground "darkgreen")))
- "Face used to highlight (non)terminals in `sml-yacc-mode'.")
-(defvar sml-yacc-bnf-face 'sml-yacc-bnf-face)
-
-(defcustom sml-yacc-indent-action 16
- "Indentation column of the opening paren of actions."
- :type 'integer)
-
-(defcustom sml-yacc-indent-pipe nil
- "Indentation column of the pipe char in the BNF.
-If nil, align it with `:' or with previous cases."
- :type 'integer)
-
-(defcustom sml-yacc-indent-term nil
- "Indentation column of the (non)term part.
-If nil, align it with previous cases."
- :type 'integer)
-
-(defvar sml-yacc-font-lock-keywords
- (cons '("^\\(\\sw+\\s-*:\\|\\s-*|\\)\\(\\s-*\\sw+\\)*\\s-*\\(\\(%\\sw+\\)\\s-+\\sw+\\|\\)"
- (0 (save-excursion
- (save-match-data
- (goto-char (match-beginning 0))
- (unless (or (re-search-forward "\\<of\\>" (match-end 0) 'move)
- (progn (forward-comment (point-max))
- (not (looking-at "("))))
- sml-yacc-bnf-face))))
- (4 font-lock-builtin-face t t))
- sml-lex-font-lock-keywords))
-(defconst sml-yacc-font-lock-defaults
- (cons 'sml-yacc-font-lock-keywords (cdr sml-font-lock-defaults)))
-
-(defun sml-yacc-indent-line ()
- "Indent current line of ML-Yacc code."
- (let ((savep (> (current-column) (current-indentation)))
- (indent (max (or (ignore-errors (sml-yacc-indentation)) 0) 0)))
- (if savep
- (save-excursion (indent-line-to indent))
- (indent-line-to indent))))
-
-(defun sml-yacc-indentation ()
- (save-excursion
- (back-to-indentation)
- (or (and (looking-at "%\\|\\(\\sw\\|\\s_\\)+\\s-*:") 0)
- (when (save-excursion
- (condition-case nil (progn (up-list -1) nil) (scan-error t)))
- ;; We're outside an action.
- (cond
- ;; Special handling of indentation inside %term and %nonterm
- ((save-excursion
- (and (re-search-backward "^%\\(\\sw+\\)" nil t)
- (member (match-string 1) '("term" "nonterm"))))
- (if (numberp sml-yacc-indent-term) sml-yacc-indent-term
- (let ((offset (if (looking-at "|") -2 0)))
- (forward-line -1)
- (looking-at "\\s-*\\(%\\sw*\\||\\)?\\s-*")
- (goto-char (match-end 0))
- (+ offset (current-column)))))
- ((looking-at "(") sml-yacc-indent-action)
- ((looking-at "|")
- (if (numberp sml-yacc-indent-pipe) sml-yacc-indent-pipe
- (backward-sexp 1)
- (while (progn (forward-comment (- (point)))
- (/= 0 (skip-syntax-backward "w_"))))
- (forward-comment (- (point)))
- (if (not (looking-at "\\s-$"))
- (1- (current-column))
- (skip-syntax-forward " ")
- (- (current-column) 2))))))
- ;; default to SML rules
- (cond
- ((and sml-use-smie (fboundp 'smie-indent-calculate))
- (smie-indent-calculate))
- ((fboundp 'sml-calculate-indentation) (sml-calculate-indentation))))))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.grm\\'" . sml-yacc-mode))
-;;;###autoload
-(define-derived-mode sml-yacc-mode sml-mode "SML-Yacc"
- "Major Mode for editing ML-Yacc files."
- (set (make-local-variable 'indent-line-function) 'sml-yacc-indent-line)
- (set (make-local-variable 'font-lock-defaults) sml-yacc-font-lock-defaults))
-
-(provide 'sml-mode)
-
-(unless (and sml-use-smie (fboundp 'smie-setup))
- (require 'sml-oldindent))
-
-;;; sml-mode.el ends here
diff --git a/emacs/emacs.d/sml-mode-5.0/sml-mode.info b/emacs/emacs.d/sml-mode-5.0/sml-mode.info
@@ -1,908 +0,0 @@
-This is sml-mode.info, produced by makeinfo version 4.13 from
-sml-mode.texi.
-
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* sml:(sml-mode). Emacs mode for editing SML
-END-INFO-DIR-ENTRY
-
-
-File: sml-mode.info, Node: Top, Next: Copying, Prev: (dir), Up: (dir)
-
-1 SML Mode Info
-***************
-
-You are looking at the top node of the Info tree documenting SML-MODE
-(Version $Name$). Not all functions are documented here, but those that
-aren't you probably won't miss. All commands and settable variables
-have built-in documentation, as per usual Emacs conventions.
-
-* Menu:
-
-* Copying:: You can copy SML mode
-* Introduction:: Setting things up
-* SML Mode:: Editing SML source
-* Interaction Mode:: Running ML processes
-* Configuration:: Menus, highlighting, setting defaults
-
-Indexes
-* Command Index:: Commands you can invoke
-* Variable Index:: Variables you can set
-* Key Index:: Default keybindings
-
-Introduction
-* Contributors:: Who did what
-* Getting Started:: What to tell Emacs
-* Getting Help:: How Emacs can help
-
-SML Mode
-* Basics:: On entering SML mode
-* Indentation:: Prettying SML text
-* Magic Insertion:: Templates and electric keys
-* SML Mode Defaults:: Variables controlling indentation
-
-Interaction Mode
-* Running ML:: Commands to run the ML compiler in a buffer
-* ML Interaction:: Sending program fragments to the compiler
-* Tracking Errors:: Finding reported syntax errors
-* Process Defaults:: Setting defaults for process interaction
-
-Configuration
-* Hooks:: Creating hooks
-* Key Bindings:: Binding commands to keys
-* Highlighting:: Syntax colouring
-* Advanced Topics:: You may need to speak Emacs Lisp
-
-
-File: sml-mode.info, Node: Copying, Next: Introduction, Prev: Top, Up: Top
-
-2 Copying
-*********
-
-You can freely copy, modify and redistribute SML mode because it's made
-available under the liberal terms of the GNU General Public License.
-
- GNU General Public License as published by the Free Software
-Foundation; either version 3, or (at your option) any later version.
-
- SML mode is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-Public License for more details.
-
- You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to the Free
-Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-File: sml-mode.info, Node: Introduction, Next: SML Mode, Prev: Copying, Up: Top
-
-3 Introduction
-**************
-
-SML mode is a major mode for Emacs for editing Standard ML. It has some
-novel bugs, and some nice features:
-
- * Automatic indentation of sml code--a number of variables to
- customise the indentation.
-
- * Easy insertion for commonly used templates like let, local,
- signature, and structure declarations, with minibuffer prompting
- for types and expressions.
-
- * Magic pipe insertion: `|' automatically determines if it is used
- in a case or fun construct, and indents the next line as
- appropriate, inserting `=>' or the name of the function.
-
- * Inferior shell for running ML. There's no need to leave Emacs,
- just keep on editing while the compiler runs in another window.
-
- * Automatic "use file" in the inferior shell--you can send files,
- buffers, or regions of code to the ML subprocess.
-
- * Menus, and syntax and keyword highlighting supported for Emacs 19
- and derivatives.
-
- * Parsing errors from the inferior shell, and repositioning the
- source with next-error--just like in c-mode.
-
- * SML mode can be easily configured to work with a number of Standard
- ML compilers, and other SML based tools.
-
-* Menu:
-
-* Contributors:: Who did what
-* Getting Started:: What to tell Emacs
-* Getting Help:: How Emacs can help
-
-
-File: sml-mode.info, Node: Contributors, Next: Getting Started, Prev: Introduction, Up: Introduction
-
-3.1 Contributors to the SML mode
-================================
-
-Contributions to the package are welcome. I have limited time to work
-on this project, but I will gladly add any code that you contribute to
-me to this package.
-
- Although the history of sml-mode is obscure, it seems that the
-following persons have made contributions to sml-mode:
-
- * Lars Bo Nielsen wrote the original version of the code, providing
- the sml editing mode and the inferior-sml support.
-
- * Olin Shivers (`shivers@ai.mit.edu') hacked the inferior-sml support
- to use comint and call the whole thing ml-mode.
-
- * Steven Gilmore supposedly provided some early attempt at menubar
- support.
-
- * Matthew J. Morley (`matthew@verisity.com') was maintainer for a
- long time (until version 3.4) and provided many additions and
- fixes in all areas.
-
- * Frederick Knabe (`knabe@ecrc.de') provided the original code for
- font-lock and hilite support as well as for proper handling of
- nested comments and of all the string escape sequences.
-
- * Matthias Blume (`blume@kurims.kyoto-u.ac.jp') provided a sml-make
- which was replaced by sml-compile.
-
- * Monnier Stefan (`monnier@iro.umontreal.ca') completely reworked the
- indentation engine as well as most of the rest of the code and is
- the current maintainer since after version 3.4.
-
-
-
-File: sml-mode.info, Node: Getting Started, Next: Getting Help, Prev: Contributors, Up: Introduction
-
-3.2 Getting started
-===================
-
-With luck your system administrator will have installed SML mode
-somewhere convenient, so it will just magically all work--you can skip
-the rest of this getting started section. Otherwise you will need to
-tell Emacs where to find all the SML mode `.el' files, and when to use
-them. The where is addressed by locating the Lisp code on your Emacs
-Lisp load path--you may have to create a directory for this, say
-`/home/mjm/elisp', and then insert the following lines in your
-`/home/mjm/.emacs' file:
-
- (add-to-list 'load-path "/home/mjm/elisp")
- (autoload 'sml-mode "sml-mode" "Major mode for editing SML." t)
- (autoload 'run-sml "sml-proc" "Run an inferior SML process." t)
-
-The first line adjusts Emacs' internal search path so it can locate the
-Lisp source you have copied to that directory; the second and third
-lines tell Emacs to load the code automatically when it is needed. You
-can then switch any Emacs buffer into SML mode by entering the command
-
- M-x sml-mode
-
-It is usually more convenient to have Emacs automatically place the
-buffer in SML mode whenever you visit a file containing ML programs.
-The simplest way of achieving this is to put something like
-
- (add-to-list 'auto-mode-alist '("\\.\\(sml\\|sig\\)\\'" . sml-mode))
-
-also in your `.emacs' file. Subsequently (after a restart), any files
-with these extensions will be placed in SML mode buffers when you visit
-them.
-
- You may want to pre-compile the `sml-*.el' files (`M-x
-byte-compile-file') for greater speed--byte compiled code loads and
-runs somewhat faster.
-
-
-File: sml-mode.info, Node: Getting Help, Prev: Getting Started, Up: Introduction
-
-3.3 Help!
-=========
-
-You're reading it. Apart from the on-line info tree (`C-h i' is the
-Emacs key to enter the `info' system--you should follow the brief
-tutorial if this is unfamiliar), there are further details on specific
-commands in their documentation strings. Only the most useful SML mode
-commands are documented in the info tree: to find out more use Emacs'
-help facilities.
-
- Briefly, to get help on a specific function use `C-h f' and enter
-the command name. All (almost all, then) SML mode commands begin with
-`sml-', so if you type this and press <TAB> (for completion) you will
-get a list of all commands. Another way is to use `C-h a' and enter the
-string `sml'. This is command apropos; it will list all commands with
-that sub-string in their names, and any key binding they may have in
-the current buffer. Command apropos gives a one-line synopsis of what
-each command does.
-
- Some commands are also variables--such things are allowed in Lisp, if
-not in ML! *Note Command Index::, for a list of (info) documented
-functions. *Note Variable Index::, for a list of user settable variables
-to control the behaviour of SML mode.
-
- Before accessing this information on-line from within Emacs you may
-have to set the variable `sml-mode-info'. Put in your `.emacs' file
-something like:
-
- (setq sml-mode-info "/home/mjm/info/sml-mode.info")
-
-When different from the default this variable should be a string giving
-the absolute name of the `.info' file. Then `C-c C-i' in SML mode
-(i.e., the command `M-x sml-mode-info') will bring up the manual. This
-help is also accessible from the menu. (Resetting this variable will
-not be necessary if your site administrator has been kind enough to
-install SML mode and its attendant documentation in the Emacs
-hierarchy.)
-
-
-File: sml-mode.info, Node: SML Mode, Next: Interaction Mode, Prev: Introduction, Up: Top
-
-4 Editing with SML Mode
-***********************
-
-Now SML mode provides just a few additional editing commands. Most of
-the work has gone into implementing the indentation algorithm which, if
-you think about it, has to be complicated for a language like ML. *Note
-Indentation Defaults: SML Mode Defaults, for details on how to control
-some of the behaviour of the indentation algorithm. Principal goodies
-are the `electric pipe' feature, and the ability to insert common SML
-forms (macros or templates).
-
-* Menu:
-
-* Basics:: On entering SML mode
-* Indentation:: Prettying SML text
-* Magic Insertion:: Templates and electric keys
-* SML Mode Defaults:: Variables controlling indentation
-
-
-File: sml-mode.info, Node: Basics, Next: Indentation, Prev: SML Mode, Up: SML Mode
-
-4.1 On entering SML mode
-========================
-
-
-
- -- Command: sml-mode
- This switches a buffer into SML mode. This is a _major mode_ in
- Emacs. To get out of SML mode the buffer's major mode must be set
- to something else, like text-mode. *Note Getting Started::, for
- details on how to set this up automatically when visiting an SML
- file.
-
- Emacs is all hooks of course. A hook is a variable: if the variable
-is non-nil it binds a list of Emacs Lisp functions to be run in some
-order (usually left to right). You can customise SML mode with these
-hooks:
-
- -- Hook: sml-mode-hook
- Default: `nil'
-
- This is run every time a new SML mode buffer is created (or if you
- type `M-x sml-mode'). This is one place to put your preferred key
- bindings. *Note Configuration::, for some examples.
-
-
-File: sml-mode.info, Node: Indentation, Next: Magic Insertion, Prev: Basics, Up: SML Mode
-
-4.2 Automatic indentation
-=========================
-
-ML is a complicated language to parse, let alone compile. The
-indentation algorithm is a little wooden (for some tastes), and the best
-advice is not to fight it! There are several variables that can be
-adjusted to control the indentation algorithm (*note Customising SML
-Mode: SML Mode Defaults, below).
-
- -- Command: indent-for-tab-command
- Key: <TAB>
-
- This command indents the current line. If you set the indentation
- of the previous line by hand, `indent-for-tab-command' will indent
- relative to this setting.
-
- -- Command: indent-region
- Key: `C-M-\'
-
- Indent the current region. Be patient if the region is large (like
- the whole buffer).
-
- -- Command: sml-back-to-outer-indent
- Key: `M-<TAB>'
-
- Unindents the line to the next outer level of indentation.
-
- Further indentation commands that Emacs provides (generically, for
-all modes) that you may like to recall:
-
- - `M-x newline-and-indent'
-
- On <LFD> by default. Insert a newline, then indent according to
- the major mode. *Note Indentation for Programs: (emacs)Program
- Indent, for details.
-
- - `M-x indent-rigidly'
-
- On `C-x <TAB>' by default. Moves all lines in the region right by
- its argument (left, for negative arguments). *Note Indentation:
- (emacs)Indentation.
-
- - `M-x indent-for-comment'
-
- On `M-;' by default. Indent this line's comment to comment
- column, or insert an empty comment. *Note Comment Commands:
- (emacs)Comment Commands.
-
- - `M-x indent-new-comment-line'
-
- On `M-<LFD>' by default. Break line at point and indent,
- continuing comment if within one. *Note Multi-Line Comments:
- (emacs)Multi-Line Comments.
-
- As with other language modes, `M-;' gives you a comment at the end
-of the current line. The column where the comment starts is determined
-by the variable `comment-column'--default is 40, but it can be changed
-with `set-comment-column' (on `C-x ;' by default).
-
-
-File: sml-mode.info, Node: Magic Insertion, Next: SML Mode Defaults, Prev: Indentation, Up: SML Mode
-
-4.3 Electric features
-=====================
-
-Electric keys are generally pretty irritating, so those provided by SML
-mode are fairly muted. The only truly electric key is `;', and this has
-to be enabled to take effect.
-
- -- Command: sml-electric-pipe
- Key: `M-|'
-
- When the point is in a `case' statement this opens a new line,
- indents and inserts `| =>' leaving point just before the double
- arrow; if the enclosing construct is a `fun' declaration, the
- newline is indented and the function name copied at the
- appropriate column. Generally, try it whenever a `|' is
- wanted--you'll like it!
-
- -- Command: sml-electric-space
- Key: `M-SPC'
-
- When the point is after a keyword like `let', this inserts the
- corresponding predefined skeleton if one exists. Else it just
- inserts a space. Another way to insert those skeletons is to use
- `sml-insert-form', described below.
-
- -- Command: sml-electric-semi
- Key: `;'
-
- Just inserts a semi-colon, usually. The behaviour of this command
- is governed by the variable `sml-electric-semi-mode'.
-
- -- Variable: sml-electric-semi-mode
- Default: `nil'
-
- If this variable is `nil', `sml-electric-semi' just inserts a
- semi-colon, otherwise it inserts a semi-colon and a newline, and
- indents the newline for SML.
-
- -- Command: sml-insert-form
- Key: `C-c <RET>'
-
- Interactive short-cut to insert common ML forms (a.k.a. macros, or
- templates). Recognised forms are `let', `local', `case', `abstype',
- `datatype', `signature', `structure', and `functor'. Except for
- `let' and `local', these will prompt for appropriate parameters
- like functor name and signature, etc.. This command prompts in the
- mini-buffer, with completion.
-
- By default `C-c <RET>' will insert at point, with the indentation
- of the current column; if you give a prefix argument (i.e., `C-u
- C-c <RET>') the command will insert a newline first, indent, and
- then insert the template.
-
- `sml-insert-form' is also extensible: see *note Configuration:: for
-further details.
-
-
-File: sml-mode.info, Node: SML Mode Defaults, Prev: Magic Insertion, Up: SML Mode
-
-4.4 Indentation defaults
-========================
-
-Several variables try to control the indentation algorithm and other
-features of SML mode. Most of them are still in flux so they are not
-described here yet. If the default values are not acceptable you can
-set these variables permanently in your `.emacs' file. *Note
-Configuration::, for details and examples.
-
- -- Variable: sml-indent-level
- Default: `4'
-
- This variable controls the block indentation level.
-
-
-File: sml-mode.info, Node: Interaction Mode, Next: Configuration, Prev: SML Mode, Up: Top
-
-5 Running ML under Emacs
-************************
-
-The most useful feature of SML mode is that it provides a convenient
-interface to the compiler. How serious users of ML put up with a
-teletype interface to the compiler is beyond me... but perhaps there
-are other interfaces to compilers that require one to part with serious
-money. Such remarks can quickly become dated--in this case, let's hope
-so!
-
- Anyway, SML mode provides an interaction mode, `inferior-sml-mode',
-where the compiler runs in a separate buffer in a window or frame of
-its own. You can use this buffer just like a terminal, but it's usually
-more convenient to mark some text in the SML mode buffer and have Emacs
-communicate with the sub-process. The features discussed below are
-syntax-independent, so they should work with a wide range of ML-like
-tools and compilers. *Note Process Defaults::, for some hints.
-
- `inferior-sml-mode' is a specialisation of the `comint' package that
-comes with Emacs and XEmacs.
-
-* Menu:
-
-* Running ML:: Commands to run the ML compiler in a buffer
-* ML Interaction:: Sending program fragments to the compiler
-* Tracking Errors:: Finding reported syntax errors
-* Process Defaults:: Setting defaults for process interaction
-
-
-File: sml-mode.info, Node: Running ML, Next: ML Interaction, Prev: Interaction Mode, Up: Interaction Mode
-
-5.1 Starting the compiler
-=========================
-
-Start your favourite ML compiler with the command
-
- M-x run-sml
-
-This creates a process interaction buffer that inherits some key
-bindings from SML mode and from `comint' (*note Shell Mode:
-(emacs)Shell Mode.). Starting the ML compiler adds some functions to
-SML mode buffers so that program text can be communicated between
-editor and compiler (*note ML Interaction::).
-
- The name of the ML compiler is the first thing you should know how to
-specify:
-
- -- Variable: sml-program-name
- Default: `"sml"'
-
- The program to run as ML. You might need to specify the full path
- name of the program.
-
- -- Variable: sml-default-arg
- Default: `""'
-
- Useful for Poly/ML users who may supply a database file, or others
- who have wrappers for setting various options around the command
- to run the compiler. Moscow ML people might set this to `"-P
- full"', etc..
-
- The variable `sml-program-name' is a string holding the name of the
-program _as you would type it at the shell_. You can always choose a
-program different to the default by invoking
-
- C-u M-x run-sml
-
-With the prefix argument Emacs will prompt for the command name and any
-command line arguments to pass to the compiler. Thereafter Emacs will
-use this new name as the default, but for a permanent change you should
-set this in your `.emacs' with, e.g.:
-
- (setq sml-program-name "nj-sml")
-
- -- Command: run-sml
- Launches ML as an inferior process in another buffer; if an ML
- process already exists, just switch to the process buffer. A
- prefix argument allows you to edit the command line to specify the
- program, and any command line options.
-
- -- Hook: inferior-sml-mode-hook
- Default: `nil'
-
- `M-x run-sml' runs `comint-mode-hook' and `inferior-sml-mode-hook'
- hooks in that order, but _after_ the compiler is started. Use
- `inferior-sml-mode-hook' to set any `comint' buffer-local
- configurations for SML mode you like.
-
- -- Command: switch-to-sml
- Key: `C-c C-s'
-
- Switch from the SML buffer to the interaction buffer. By default
- point will be placed at the end of the process buffer, but a
- prefix argument will leave point wherever it was before. If you
- try `C-c C-s' before an ML process has been started, you'll just
- get an error message to the effect that there's no current process
- buffer.
-
- -- Command: sml-cd
- When started, the ML compiler's default working directory is the
- current buffer's default directory. This command allows the working
- directory to be changed, if the compiler can do this. The variable
- `sml-cd-command' specifies the compiler command to invoke (*note
- Process Defaults::).
-
-
-File: sml-mode.info, Node: ML Interaction, Next: Tracking Errors, Prev: Running ML, Up: Interaction Mode
-
-5.2 Speaking to the compiler
-============================
-
-Several commands are defined for sending program fragments to the
-running compiler. Each of the following commands takes a prefix argument
-that will switch the input focus to the process buffer afterwards
-(leaving point at the end of the buffer):
-
- -- Command: sml-load-file
- Key: `C-c C-l'
-
- Send a `use file' command to the current ML process. The variable
- `sml-use-command' is used to define the correct template for the
- command to invoke (*note Process Defaults::). The default file is
- the file associated with the current buffer, or the last file
- loaded if you are in the interaction buffer.
-
- -- Command: sml-send-region
- Key: `C-c C-r'
-
- Send the current region of text in the SML buffer.
- `sml-send-region-and-go' is a similar command for you to bind in
- SML mode if you wish: it'll send the region and then switch-to-sml.
-
- -- Command: sml-send-buffer
- Key: `C-c C-b'
-
- Send the contents of the current buffer to ML.
-
-
-File: sml-mode.info, Node: Tracking Errors, Next: Process Defaults, Prev: ML Interaction, Up: Interaction Mode
-
-5.3 Finding errors
-==================
-
-SML mode provides one customisable function for locating the source
-position of errors reported by the compiler. This should work whether
-you type `use "puzzle.sml";' into the interaction buffer, or use one of
-the mechanisms provided for sending programs directly to the
-compiler--*note ML Interaction::.
-
- -- Command: next-error
- Key: `C-x`'
-
- Jump to the source location of the next error reported by the
- compiler. All the usual error-navigation commands are available,
- see *note Compilation Mode: (emacs)Compilation Mode.
-
-
-File: sml-mode.info, Node: Process Defaults, Prev: Tracking Errors, Up: Interaction Mode
-
-5.4 Process defaults
-====================
-
-The process interaction code is independent of the compiler used,
-deliberately, so SML mode will work with a variety of ML compilers and
-ML-based tools. There are therefore a number of variables that may need
-to be set correctly before SML mode can speak to the compiler. Things
-are by default set up for Standard ML of New Jersey, but switching to a
-new system is quite easy.
-
- -- Variable: sml-use-command
- Default: `"use \"%s\""'
-
- Use file command template. Emacs will replace the `%s' with a file
- name. Note that Emacs requires double quote characters inside
- strings to be quoted with a backslash.
-
- -- Variable: sml-cd-command
- Default: `"OS.FileSys.chDir \"%s\""'
-
- Compiler command to change the working directory. Not all ML
- systems support this feature (well, Edinburgh (core) ML didn't),
- but they should.
-
- -- Variable: sml-prompt-regexp
- Default: `"^[-=>#] *"'
-
- Matches the ML compiler's prompt: `comint' uses this for various
- purposes.
-
- To customise error reportage for different ML compilers you need to
-set two further variables before `next-error' can be useful:
-
- -- Variable: sml-error-regexp-alist
- Alist that specifies how to match errors in compiler output. Each
- elt has the form (REGEXP FILE-IDX LINE-IDX [COLUMN-IDX
- FILE-FORMAT...]) If REGEXP matches, the FILE-IDX'th subexpression
- gives the file name, and the LINE-IDX'th subexpression gives the
- line number. If COLUMN-IDX is given, the COLUMN-IDX'th
- subexpression gives the column number on that line. If any
- FILE-FORMAT is given, each is a format string to produce a file
- name to try; %s in the string is replaced by the text matching the
- FILE-IDX'th subexpression.
-
-
-File: sml-mode.info, Node: Configuration, Prev: Interaction Mode, Up: Top
-
-6 Configuration Summary
-***********************
-
-This (sort of pedagogic) section gives more information on how to
-configure SML mode: menus, key bindings, hooks and highlighting are
-discussed, along with a few other random topics.
-
-* Menu:
-
-* Hooks:: Creating them
-* Key Bindings:: Binding commands to keys
-* Highlighting:: Syntax colouring
-* Advanced Topics:: You may need to speak Emacs Lisp
-
-
-File: sml-mode.info, Node: Hooks, Next: Key Bindings, Prev: Configuration, Up: Configuration
-
-6.1 Hooks
-=========
-
-One way to set SML mode variables (*note Indentation Defaults: SML Mode
-Defaults.), and other defaults, is through the `sml-mode-hook' in your
-`.emacs'. A simple example:
-
- (defun my-sml-mode-hook () "Local defaults for SML mode"
- (setq sml-indent-level 2) ; conserve on horizontal space
- (setq words-include-escape t) ; \ loses word break status
- (setq indent-tabs-mode nil)) ; never ever indent with tabs
- (add-hook 'sml-mode-hook 'my-sml-mode-hook)
- The body of `my-sml-mode-hook' is a sequence of assignments. In this
-case it is not really necessary to set `sml-indent-level' in a hook
-because this variable is global (most SML mode variables are). With
-similar effect:
-
- (setq sml-indent-level 2)
- anywhere in your `.emacs' file. The variable `indent-tabs-mode' is
-automatically made local to the current buffer whenever it is set
-explicitly, so it _must_ be set in a hook if you always want SML mode
-to behave like this.
-
- Another hook is `inferior-sml-mode-hook'. This can be used to
-control the behaviour of the interaction buffer through various
-variables meaningful to `comint'-based packages:
-
- (defun my-inf-sml-mode-hook () "Local defaults for inferior SML mode"
- (add-hook 'comint-output-filter-functions 'comint-truncate-buffer)
- (setq comint-scroll-show-maximum-output t)
- (setq comint-input-autoexpand nil))
- (add-hook 'inferior-sml-mode-hook 'my-inf-sml-mode-hook)
- Again, the body is a sequence of assignments. Unless you run several
-ML compilers simultaneously under one Emacs, this hook will normally
-only get run once. You might want to look up the documentation (`C-h v'
-and `C-h f') for these buffer-local `comint' things.
-
-
-File: sml-mode.info, Node: Key Bindings, Next: Highlighting, Prev: Hooks, Up: Configuration
-
-6.2 Key bindings
-================
-
-Customisation (in Emacs) usually entails putting favourite commands on
-easily remembered keys. Two `keymaps' are defined in SML mode: one is
-effective in program text buffers (`sml-mode-map') and the other is
-effective in interaction buffers (`inferior-sml-mode-map'). The
-initial design ensures that (many of) the default key bindings from the
-former keymap will also be available in the latter (e.g., `C-c`').
-
- Type `C-h m' in an SML mode buffer to find the default key bindings
-(and similarly in an ML interaction buffer), and use the hooks provided
-to install your preferred key bindings. Given that the keymaps are
-global (variables):
-
- (defun my-sml-mode-hook () "Global defaults for SML mode"
- (define-key sml-mode-map "\C-cd" 'sml-cd))
- (add-hook 'sml-mode-hook 'my-sml-mode-hook)
- This has the effect of binding `sml-cd' to the key `C-c d'. If you
-want the same behaviour from `C-c d' in the ML buffer:
-
- (defun my-inf-sml-mode-hook () "Global defaults for inferior SML mode"
- (define-key inferior-sml-mode-map "\C-cd" 'sml-cd)
- ;; NB. for SML/NJ '96
- (setq sml-cd-command "OS.FileSys.chDir \"%s\""))
- (add-hook 'inferior-sml-mode-hook 'my-inf-sml-mode-hook)
-
- There is nothing to stop you rebuilding the entire keymap for SML
-mode and the ML interaction buffer in your `.emacs' of course: SML mode
-won't define `sml-mode-map' or `inferior-sml-mode-map' if you have
-already done so.
-
-
-File: sml-mode.info, Node: Highlighting, Next: Advanced Topics, Prev: Key Bindings, Up: Configuration
-
-6.3 Syntax colouring
-====================
-
-Highlighting is very handy for picking out keywords in the program text,
-spotting misspelled kewyords, and, if you have Emacs' `ps-print'
-package installed (you usually do these days), obtaining pretty, even
-colourful code listings--quite properly for your colourful ML programs.
-
- The indentation scheme (strangely enough) also relies on the
-highlighting code to properly handle nested comments, which is yet
-another reason to turn on highlighting. To turn on highlighting, use
-either of:
-
- M-x font-lock-mode
- (add-hook 'sml-mode-hook 'turn-on-font-lock)
- (global-font-lock-mode 1)
-
- The first will turn it on in the current buffer. The second will
-turn it on in all sml-mode buffers. The last will turn it on
-everywhere. This is valid for Emacs but maybe not for XEmacs. Check
-font-lock documentation if you encounter problems.
-
-
-File: sml-mode.info, Node: Advanced Topics, Prev: Highlighting, Up: Configuration
-
-6.4 Advanced Topics
-===================
-
- _These forms are bloody useless; can't we have better ones?_
-
-
-You can indeed. `sml-insert-form' is extensible so all you need to do
-is create the macros yourself. Define a _keybord macro_ (`C-x ('
-<something> `C-x )') and give it a suitable name:
-`sml-addto-forms-alist' prompts for a name, say `NAME', and binds the
-macro `sml-form-NAME'. Thereafter `C-c <RET> NAME' will insert the
-macro at point, and `C-u C-c <RET> NAME' will insert the macro after a
-`newline-and-indent'. If you want to keep your macros from one editing
-session to the next, go to your `.emacs' file and call
-`insert-kbd-macro'; you'll need to add `NAME' to `sml-forms-alist'
-permanently yourself:
-
- (defun my-sml-mode-hook () "Global defaults for SML mode"
- ;; whatever else you do
- (add-to-list 'sml-forms-alist '("NAME" . FUNCTION)))
-
- If you want to create templates like `case' that prompt for
-parameters you'll have to do some Lisp programming. The `skeleton'
-package is a good stating point. Better yet, you can reuse the
-wrappers used by sml-mode itself in your sml-mode-hook:
-
- (add-hook 'sml-mode-hook
- (lambda ()
- (sml-def-skeleton "case" "Case expr: "
- str " of" \n _ " => ")))
-
- This will redefine `case' in order to leave the `of' on the first
-line. See the documentation of `skeleton-insert' to get a better
-understanding of how this works.
-
-
-_I hate that indentation algorithm; can't I tweak it?_
-
-
-Ah, yes, of course, but this manual will not tell you how.
-
-
-_Can SML mode handle more than one compiler running at once?_
-
- Sure, just rename the `*sml*' buffer and then use `run-sml' as usual.
-
-
-_What needs to be done to support other ML compilers?_
-
-
-Not much really. Just add the right regular expressions to
-`sml-error-regexp-alist' and that should be all.
-
-
-File: sml-mode.info, Node: Command Index, Next: Variable Index, Up: Top
-
-Command Index
-*************
-
--* Menu:
-
-* indent-for-tab-command: Indentation. (line 13)
-* indent-region: Indentation. (line 20)
-* inferior-sml-mode: Interaction Mode. (line 21)
-* next-error: Tracking Errors. (line 13)
-* run-sml: Running ML. (line 47)
-* sml-back-to-outer-indent: Indentation. (line 26)
-* sml-cd: Running ML. (line 71)
-* sml-electric-pipe: Magic Insertion. (line 11)
-* sml-electric-semi: Magic Insertion. (line 29)
-* sml-electric-space: Magic Insertion. (line 21)
-* sml-indent-level: SML Mode Defaults. (line 13)
-* sml-insert-form: Magic Insertion. (line 42)
-* sml-load-file: ML Interaction. (line 12)
-* sml-mode: Basics. (line 9)
-* sml-mode-info: Getting Help. (line 31)
-* sml-send-buffer: ML Interaction. (line 28)
-* sml-send-region: ML Interaction. (line 21)
-* sml-send-region-and-go: ML Interaction. (line 21)
-* switch-to-sml: Running ML. (line 61)
-
-
-File: sml-mode.info, Node: Variable Index, Next: Key Index, Prev: Command Index, Up: Top
-
-Variable Index
-**************
-
--* Menu:
-
-* inferior-sml-mode-hook: Running ML. (line 53)
-* sml-cd-command: Process Defaults. (line 21)
-* sml-default-arg: Running ML. (line 26)
-* sml-electric-semi-mode: Magic Insertion. (line 35)
-* sml-error-regexp-alist: Process Defaults. (line 37)
-* sml-indent-level: SML Mode Defaults. (line 13)
-* sml-mode-hook: Basics. (line 21)
-* sml-mode-info: Getting Help. (line 31)
-* sml-program-name: Running ML. (line 20)
-* sml-prompt-regexp: Process Defaults. (line 28)
-* sml-use-command: Process Defaults. (line 14)
-
-
-File: sml-mode.info, Node: Key Index, Prev: Variable Index, Up: Top
-
-Key Index
-*********
-
--* Menu:
-
-* ;: Magic Insertion. (line 29)
-* <LFD>: Indentation. (line 35)
-* <TAB>: Indentation. (line 13)
-* C-c <RET>: Magic Insertion. (line 42)
-* C-c C-b: ML Interaction. (line 28)
-* C-c C-i: Getting Help. (line 31)
-* C-c C-l: ML Interaction. (line 12)
-* C-c C-r: ML Interaction. (line 21)
-* C-c C-s: Running ML. (line 61)
-* C-M-\: Indentation. (line 20)
-* C-x ;: Indentation. (line 57)
-* C-x <TAB>: Indentation. (line 41)
-* C-x`: Tracking Errors. (line 13)
-* M-;: Indentation. (line 47)
-* M-<LFD>: Indentation. (line 53)
-* M-<TAB>: Indentation. (line 26)
-* M-SPC: Magic Insertion. (line 21)
-* M-|: Magic Insertion. (line 11)
-
-
-
-Tag Table:
-Node: Top187
-Node: Copying1782
-Node: Introduction2595
-Node: Contributors4011
-Node: Getting Started5484
-Node: Getting Help7192
-Node: SML Mode9060
-Node: Basics9868
-Node: Indentation10787
-Node: Magic Insertion12897
-Node: SML Mode Defaults15115
-Node: Interaction Mode15676
-Node: Running ML17025
-Node: ML Interaction19894
-Node: Tracking Errors21047
-Node: Process Defaults21750
-Node: Configuration23633
-Node: Hooks24141
-Node: Key Bindings25998
-Node: Highlighting27574
-Node: Advanced Topics28579
-Node: Command Index30523
-Node: Variable Index32039
-Node: Key Index32991
-
-End Tag Table
diff --git a/emacs/emacs.d/sml-mode-5.0/sml-mode.spec b/emacs/emacs.d/sml-mode-5.0/sml-mode.spec
@@ -1,67 +0,0 @@
-%define lispdir %{_datadir}/emacs/site-lisp
-%define startupfile %{lispdir}/site-start.el
-
-Summary: Emacs mode for editing Standard ML source code
-Name: sml-mode
-Version: $Name$
-Release: 0.1
-Group: Applications/Editors
-Copyright: GPL
-Packager: Stefan Monnier
-Source: http://iro.umontreal.ca/~monnier/elisp/%{name}.tar.gz
-Buildroot: %{_tmppath}/%{name}-buildroot
-BuildPreReq: emacs >= 20 xemacs >= 21
-BuildArch: noarch
-
-%description
-SML-MODE is a major Emacs mode for editing Standard ML. It provides
-syntax highlighting and automatic indentation and comes with sml-proc
-which allows interaction with an inferior SML interactive loop.
-
-%prep
-%setup -q -n %{name}
-
-%install
-make install \
- prefix=%{buildroot}%{_prefix} \
- infodir=%{buildroot}%{_infodir} \
- lispdir=%{buildroot}%{lispdir}
-gzip -9f %{buildroot}%{lispdir}/sml-mode/*.el
-
-texi2pdf sml-mode.texi
-
-%post
-cat >> %{lispdir}/site-start.el <<EOF
-;; sml-mode-start
-;; This section was automatically generated by rpm
-(load "sml-mode-startup")
-;; End of automatically generated section
-;; sml-mode-end
-EOF
-
-/sbin/install-info %{_infodir}/sml-mode.info.gz %{_infodir}/dir
-
-%postun
-ed -s %{lispdir}/site-start.el <<EOF
-/^;; sml-mode-start$/,/^;; sml-mode-end$/d
-wq
-EOF
-
-/sbin/install-info --delete %{_infodir}/sml-mode.info.gz %{_infodir}/dir \
- --section=Emacs \
- --entry="* SML: (sml-mode). Editing & Running Standard ML from Emacs"
-
-%clean
-rm -rf %{buildroot}
-
-%files
-%defattr(-,root,root)
-%doc BUGS ChangeLog INSTALL NEWS README TODO
-%doc sml-mode.texi sml-mode.pdf
-%doc %{_infodir}/*.info*
-%dir %{lispdir}/%{name}
-%{lispdir}/%{name}/*.elc
-%{lispdir}/%{name}/*.el
-%{lispdir}/%{name}/*.el.*
-
-%changelog
diff --git a/emacs/emacs.d/sml-mode-5.0/sml-mode.texi b/emacs/emacs.d/sml-mode-5.0/sml-mode.texi
@@ -1,1161 +0,0 @@
-\input texinfo @c -*-texinfo-*-
-
-@comment "@(#)$Name$:$Id$"
-
-@comment Documentation for the GNU Emacs SML mode.
-@comment Copyright (C) 1997-1999 Matthew J.@: Morley
-
-@comment This file is part of the sml-mode distribution.
-
-@comment sml-mode is free software; you can redistribute it and/or modify
-@comment it under the terms of the GNU General Public License as published by
-@comment the Free Software Foundation; either version 3 of the License,
-@comment or (at your option) any later version.
-
-@comment sml-mode is distributed in the hope that it will be useful,
-@comment but WITHOUT ANY WARRANTY; without even the implied warranty of
-@comment MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-@comment GNU General Public License for more details.
-
-@comment You should have received a copy of the GNU General Public License
-@comment along with sml-mode; see the file COPYING. If not, write to
-@comment the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-@setfilename sml-mode.info
-@settitle SML mode - The Emacs SML editing mode
-@dircategory Emacs
-@direntry
-* sml:(sml-mode). Emacs mode for editing SML
-@end direntry
-@setchapternewpage on
-
-@titlepage
-@sp 5
-@center @titlefont{Editing and Running Standard ML}
-@center @titlefont{under GNU Emacs}
-@sp 5
-@center {SML mode, Version $Name$}
-@center {August 1999}
-@sp 2
-@author Authors: Matthew J.@: Morley and Stefan Monnier
-
-@page
-@vskip 0pt plus 1filll
-Copyright @copyright{} (Anon)
-
-@sp 1
-@noindent
-GNU General Public License as published by the Free Software Foundation;
-either version 3, or (at your option) any later version.
-
-@sp 1
-@noindent
-SML mode is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-Public License for more details.
-
-@sp 1
-@noindent
-You should have received a copy of the GNU General Public License along
-with GNU Emacs; see the file COPYING. If not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-@end titlepage
-
-@setchapternewpage off
-@headings double
-
-@c ============================================================ TOP NODE
-
-@node Top, Copying, (dir), (dir)
-
-@ifinfo
-@chapter SML Mode Info
-
-@c == Top, Copying, (dir), (dir) =======================================
-
-@noindent
-You are looking at the top node of the Info tree documenting
-@sc{sml-mode} (Version $Name$). Not all functions are documented here, but
-those that aren't you probably won't miss. All commands and settable
-variables have built-in documentation, as per usual Emacs conventions.
-@end ifinfo
-
-@menu
-* Copying:: You can copy SML mode
-* Introduction:: Setting things up
-* SML Mode:: Editing SML source
-* Interaction Mode:: Running ML processes
-* Configuration:: Menus, highlighting, setting defaults
-
-Indexes
-* Command Index:: Commands you can invoke
-* Variable Index:: Variables you can set
-* Key Index:: Default keybindings
-
-Introduction
-* Contributors:: Who did what
-* Getting Started:: What to tell Emacs
-* Getting Help:: How Emacs can help
-
-SML Mode
-* Basics:: On entering SML mode
-* Indentation:: Prettying SML text
-* Magic Insertion:: Templates and electric keys
-* SML Mode Defaults:: Variables controlling indentation
-
-Interaction Mode
-* Running ML:: Commands to run the ML compiler in a buffer
-* ML Interaction:: Sending program fragments to the compiler
-* Tracking Errors:: Finding reported syntax errors
-* Process Defaults:: Setting defaults for process interaction
-
-Configuration
-* Hooks:: Creating hooks
-* Key Bindings:: Binding commands to keys
-* Highlighting:: Syntax colouring
-* Advanced Topics:: You may need to speak Emacs Lisp
-@end menu
-
-
-@c ============================================================= COPYING
-
-@node Copying, Introduction, Top, Top
-
-@ifinfo
-@chapter Copying
-
-@c == Copying, Introduction, Top, Top ==================================
-
-@noindent
-You can freely copy, modify and redistribute SML mode because it's
-made available under the liberal terms of the GNU General Public
-License.
-
-GNU General Public License as published by the Free Software Foundation;
-either version 3, or (at your option) any later version.
-
-SML mode is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with GNU Emacs; see the file COPYING. If not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-@end ifinfo
-
-
-
-
-@c ======================================================== INTRODUCTION
-
-@node Introduction, SML Mode, Copying, Top
-
-@chapter Introduction
-
-@c == Introduction, SML Mode, Copying, Top =============================
-
-
-@noindent
-SML mode is a major mode for Emacs for editing Standard ML. It has
-some novel bugs, and some nice features:
-
-@itemize @bullet
-@item
-Automatic indentation of sml code---a number of variables to customise
-the indentation.
-@item
-Easy insertion for commonly used templates like let, local, signature,
-and structure declarations, with minibuffer prompting for types and
-expressions.
-@item
-Magic pipe insertion: @code{|} automatically determines if it is used
-in a case or fun construct, and indents the next line as appropriate,
-inserting @code{=>} or the name of the function.
-@item
-Inferior shell for running ML. There's no need to leave Emacs, just keep
-on editing while the compiler runs in another window.
-@item
-Automatic ``use file'' in the inferior shell---you can send files,
-buffers, or regions of code to the ML subprocess.
-@item
-Menus, and syntax and keyword highlighting supported for Emacs 19 and
-derivatives.
-@item
-Parsing errors from the inferior shell, and repositioning the
-source with next-error---just like in c-mode.
-@item
-SML mode can be easily configured to work with a number of Standard
-ML compilers, and other SML based tools.
-@end itemize
-
-@menu
-* Contributors:: Who did what
-* Getting Started:: What to tell Emacs
-* Getting Help:: How Emacs can help
-@end menu
-
-
-
-@c ======================================================== CONTRIBUTORS
-
-@node Contributors, Getting Started, Introduction, Introduction
-
-@section Contributors to the SML mode
-@cindex Contributors
-@cindex Authors
-
-Contributions to the package are welcome. I have limited time to work
-on this project, but I will gladly add any code that you contribute to
-me to this package.
-
-Although the history of sml-mode is obscure, it seems that
-the following persons have made contributions to sml-mode:
-
-@itemize @bullet
-@item
-Lars Bo Nielsen wrote the original version of the code, providing the
-sml editing mode and the inferior-sml support.
-
-@item
-Olin Shivers (@samp{shivers@@ai.mit.edu}) hacked the inferior-sml support
-to use comint and call the whole thing ml-mode.
-
-@item
-Steven Gilmore supposedly provided some early attempt at menubar support.
-
-@item
-Matthew J. Morley (@samp{matthew@@verisity.com}) was maintainer for
-a long time (until version 3.4) and provided many additions and fixes in
-all areas.
-
-@item
-Frederick Knabe (@samp{knabe@@ecrc.de}) provided the original code for
-font-lock and hilite support as well as for proper handling of nested
-comments and of all the string escape sequences.
-
-@item
-Matthias Blume (@samp{blume@@kurims.kyoto-u.ac.jp}) provided a sml-make
-which was replaced by sml-compile.
-
-@item
-Monnier Stefan (@samp{monnier@@iro.umontreal.ca}) completely reworked the
-indentation engine as well as most of the rest of the code and is
-the current maintainer since after version 3.4.
-
-@end itemize
-
-
-@c ===================================================== GETTING STARTED
-
-@node Getting Started, Getting Help, Contributors, Introduction
-
-@section Getting started
-
-@c == Getting Started, Getting Help, Contributors, Introduction ========
-
-
-@noindent
-With luck your system administrator will have installed SML mode
-somewhere convenient, so it will just magically all work---you can
-skip the rest of this getting started section. Otherwise you will need
-to tell Emacs where to find all the SML mode @file{.el} files, and
-when to use them. The where is addressed by locating the Lisp code on
-your Emacs Lisp load path---you may have to create a directory for this,
-say @file{/home/mjm/elisp}, and then insert the following lines in your
-@file{/home/mjm/.emacs} file:
-
-@lisp
-(add-to-list 'load-path "/home/mjm/elisp")
-(autoload 'sml-mode "sml-mode" "Major mode for editing SML." t)
-(autoload 'run-sml "sml-proc" "Run an inferior SML process." t)
-@end lisp
-
-@noindent
-The first line adjusts Emacs' internal search path so it can locate the
-Lisp source you have copied to that directory; the second and third
-lines tell Emacs to load the code automatically when it is needed. You
-can then switch any Emacs buffer into SML mode by entering the command
-
-@example
-M-x sml-mode
-@end example
-
-@noindent
-It is usually more convenient to have Emacs automatically place the
-buffer in SML mode whenever you visit a file containing ML
-programs. The simplest way of achieving this is to put something like
-
-@lisp
-(add-to-list 'auto-mode-alist '("\\.\\(sml\\|sig\\)\\'" . sml-mode))
-@end lisp
-
-@noindent
-also in your @file{.emacs} file. Subsequently (after a restart), any
-files with these extensions will be placed in SML mode buffers when
-you visit them.
-
-
-You may want to pre-compile the @file{sml-*.el} files (@kbd{M-x
-byte-compile-file}) for greater speed---byte compiled code loads and
-runs somewhat faster.
-
-
-@c ======================================================== GETTING HELP
-
-@node Getting Help, , Getting Started, Introduction
-
-@section Help!
-
-@c == Getting Help, , Getting Started, Introduction ====================
-
-
-@noindent
-You're reading it. Apart from the on-line info tree (@kbd{C-h i} is the
-Emacs key to enter the @code{info} system---you should follow the brief
-tutorial if this is unfamiliar), there are further details on specific
-commands in their documentation strings. Only the most useful
-SML mode commands are documented in the info tree: to find out more
-use Emacs' help facilities.
-
-Briefly, to get help on a specific function use @kbd{C-h f} and enter
-the command name. All (almost all, then) SML mode commands begin
-with @code{sml-}, so if you type this and press @key{TAB} (for
-completion) you will get a list of all commands. Another way is to use
-@kbd{C-h a} and enter the string @code{sml}. This is command apropos; it
-will list all commands with that sub-string in their names, and any key
-binding they may have in the current buffer. Command apropos gives a
-one-line synopsis of what each command does.
-
-Some commands are also variables---such things are allowed in Lisp, if
-not in ML! @xref{Command Index}, for a list of (info) documented
-functions. @xref{Variable Index}, for a list of user settable variables
-to control the behaviour of SML mode.
-
-Before accessing this information on-line from within Emacs you may have
-to set the variable @code{sml-mode-info}. Put in your @file{.emacs} file
-something like:
-
-@vindex sml-mode-info
-@findex sml-mode-info
-@kindex @kbd{C-c C-i}
-@lisp
-(setq sml-mode-info "/home/mjm/info/sml-mode.info")
-@end lisp
-
-@noindent
-When different from the default this variable should be a string giving
-the absolute name of the @file{.info} file. Then @kbd{C-c C-i} in
-SML mode (i.e., the command @kbd{M-x sml-mode-info}) will bring up
-the manual. This help is also accessible from the menu. (Resetting this
-variable will not be necessary if your site administrator has been kind
-enough to install SML mode and its attendant documentation in the
-Emacs hierarchy.)
-
-
-@c ============================================================ SML MODE
-
-@node SML Mode, Interaction Mode, Introduction, Top
-
-@chapter Editing with SML Mode
-
-@c == SML Mode, Interaction Mode, Introduction, Top ====================
-
-
-@noindent
-Now SML mode provides just a few additional editing commands. Most of
-the work has gone into implementing the indentation algorithm which, if
-you think about it, has to be complicated for a language like
-ML. @xref{SML Mode Defaults,,Indentation Defaults}, for details on how
-to control some of the behaviour of the indentation algorithm. Principal
-goodies are the `electric pipe' feature, and the ability to insert
-common SML forms (macros or templates).
-
-@menu
-* Basics:: On entering SML mode
-* Indentation:: Prettying SML text
-* Magic Insertion:: Templates and electric keys
-* SML Mode Defaults:: Variables controlling indentation
-@end menu
-
-
-@c ============================================================== BASICS
-
-@node Basics, Indentation, SML Mode, SML Mode
-
-@section On entering SML mode
-
-@c == Basics, Indentation, SML Mode, SML Mode ==========================
-
-@noindent
-
-
-@deffn Command sml-mode
-This switches a buffer into SML mode. This is a @emph{major mode} in
-Emacs. To get out of SML mode the buffer's major mode must be set to
-something else, like @t{text-mode}. @xref{Getting Started}, for details
-on how to set this up automatically when visiting an SML file.
-@end deffn
-
-Emacs is all hooks of course. A hook is a variable: if the variable is
-non-nil it binds a list of Emacs Lisp functions to be run in some order
-(usually left to right). You can customise SML mode with these
-hooks:
-
-
-@defvr Hook sml-mode-hook
-Default: @code{nil}
-
-This is run every time a new SML mode buffer is created (or if you
-type @kbd{M-x sml-mode}). This is one place to put your preferred key
-bindings. @xref{Configuration}, for some examples.
-@end defvr
-
-
-@c ========================================================= INDENTATION
-
-@node Indentation, Magic Insertion, Basics, SML Mode
-
-@section Automatic indentation
-
-@c == Indentation, Magic Insertion, Basics, SML Mode ===================
-
-
-@noindent
-ML is a complicated language to parse, let alone compile. The
-indentation algorithm is a little wooden (for some tastes), and the best
-advice is not to fight it! There are several variables that can be
-adjusted to control the indentation algorithm (@pxref{SML Mode
-Defaults,,Customising SML Mode}, below).
-
-
-@deffn Command indent-for-tab-command
-Key: @key{TAB}
-@kindex @key{TAB}
-
-This command indents the current line. If you set the indentation of the
-previous line by hand, @code{indent-for-tab-command} will indent relative to
-this setting.
-@end deffn
-
-
-@deffn Command indent-region
-Key: @kbd{C-M-\}
-@kindex @kbd{C-M-\}
-
-Indent the current region. Be patient if the region is large (like the
-whole buffer).
-@end deffn
-
-
-@deffn Command sml-back-to-outer-indent
-Key: @kbd{M-@key{TAB}}
-@kindex @kbd{M-@key{TAB}}
-
-Unindents the line to the next outer level of indentation.
-@end deffn
-
-
-
-Further indentation commands that Emacs provides (generically, for all
-modes) that you may like to recall:
-
-@itemize @minus
-@item
-@kbd{M-x newline-and-indent}
-
-On @key{LFD} by default.
-@kindex @key{LFD}
-Insert a newline, then indent according to the major mode. @xref{Program
-Indent,,Indentation for Programs,emacs,The Emacs Editor Manual}, for
-details.
-
-@item
-@kbd{M-x indent-rigidly}
-
-On @kbd{C-x @key{TAB}} by default.
-@kindex @kbd{C-x @key{TAB}}
-Moves all lines in the region right by its argument (left, for negative
-arguments). @xref{Indentation,,,emacs,The Emacs Editor Manual}.
-
-@item
-@kbd{M-x indent-for-comment}
-
-On @kbd{M-;} by default.
-@kindex @kbd{M-;}
-Indent this line's comment to comment column, or insert an empty
-comment. @xref{Comment Commands,,,emacs,The Emacs Editor
-Manual}.
-
-@item
-@kbd{M-x indent-new-comment-line}
-
-On @kbd{M-@key{LFD}} by default.
-@kindex @kbd{M-@key{LFD}}
-Break line at point and indent, continuing comment if within one.
-@xref{Multi-Line Comments,,,emacs,The Emacs Editor Manual}.
-@end itemize
-
-@kindex @kbd{C-x ;}
-As with other language modes, @kbd{M-;} gives you a comment at the end
-of the current line. The column where the comment starts is determined
-by the variable @code{comment-column}---default is 40, but it can be
-changed with @code{set-comment-column} (on @kbd{C-x ;} by default).
-
-
-@c ===================================================== MAGIC INSERTION
-
-@node Magic Insertion, SML Mode Defaults, Indentation, SML Mode
-
-@section Electric features
-
-@c == Magic Insertion, SML Mode Defaults, Indentation, SML Mode ========
-
-
-@noindent
-Electric keys are generally pretty irritating, so those provided by
-SML mode are fairly muted. The only truly electric key is @kbd{;},
-and this has to be enabled to take effect.
-
-
-@deffn Command sml-electric-pipe
-Key: @kbd{M-|}
-@kindex @kbd{M-|}
-
-When the point is in a `case' statement this opens a new line, indents
-and inserts @code{| =>} leaving point just before the double arrow; if
-the enclosing construct is a `fun' declaration, the newline is indented
-and the function name copied at the appropriate column. Generally, try
-it whenever a @code{|} is wanted---you'll like it!
-@end deffn
-
-@deffn Command sml-electric-space
-Key: @kbd{M-SPC}
-@kindex @kbd{M-SPC}
-
-When the point is after a keyword like `let', this inserts the
-corresponding predefined skeleton if one exists. Else it just inserts a
-space. Another way to insert those skeletons is to use
-@code{sml-insert-form}, described below.
-@end deffn
-
-@deffn Command sml-electric-semi
-Key: @kbd{;}
-@kindex @kbd{;}
-
-Just inserts a semi-colon, usually. The behaviour of this command is
-governed by the variable @code{sml-electric-semi-mode}.
-@end deffn
-
-
-@defvr Variable sml-electric-semi-mode
-Default: @code{nil}
-
-If this variable is @code{nil}, @code{sml-electric-semi} just inserts a
-semi-colon, otherwise it inserts a semi-colon and a newline, and indents
-the newline for SML.
-@end defvr
-
-
-@deffn Command sml-insert-form
-Key: @kbd{C-c @key{RET}}
-@kindex @kbd{C-c @key{RET}}
-
-Interactive short-cut to insert common ML forms (a.k.a.@: macros, or
-templates). Recognised forms are `let', `local', `case', `abstype',
-`datatype', `signature', `structure', and `functor'. Except for `let'
-and `local', these will prompt for appropriate parameters like functor
-name and signature, etc.. This command prompts in the mini-buffer, with
-completion.
-
-By default @kbd{C-c @key{RET}} will insert at point, with the
-indentation of the current column; if you give a prefix argument (i.e.,
-@kbd{C-u C-c @key{RET}}) the command will insert a newline first,
-indent, and then insert the template.
-@end deffn
-
-@code{sml-insert-form} is also extensible: see @ref{Configuration} for
-further details.
-
-
-
-@c ======================================================= MODE DEFAULTS
-
-@node SML Mode Defaults, , Magic Insertion, SML Mode
-
-@section Indentation defaults
-
-@c == SML Mode Defaults, , Magic Insertion, SML Mode ===================
-
-
-@noindent
-Several variables try to control the indentation algorithm and other
-features of SML mode. Most of them are still in flux so they are not
-described here yet.
-If the default values are not acceptable you can set these variables
-permanently in your @file{.emacs} file. @xref{Configuration}, for
-details and examples.
-
-
-@defvr Variable sml-indent-level
-@findex sml-indent-level
-Default: @code{4}
-
-This variable controls the block indentation level.
-@end defvr
-
-@c end vtable
-
-
-@c ========================================================= INTERACTION
-
-@node Interaction Mode, Configuration, SML Mode, Top
-
-@chapter Running ML under Emacs
-
-@c == Interaction Mode, Configuration, SML Mode, Top ===================
-
-
-@noindent
-The most useful feature of SML mode is that it provides a convenient
-interface to the compiler. How serious users of ML put up with a
-teletype interface to the compiler is beyond me@.@.@. but perhaps there
-are other interfaces to compilers that require one to part with serious
-money. Such remarks can quickly become dated---in this case, let's hope
-so!
-
-Anyway, SML mode provides an interaction mode,
-@code{inferior-sml-mode}, where the compiler runs in a separate buffer
-in a window or frame of its own. You can use this buffer just like a
-terminal, but it's usually more convenient to mark some text in the
-SML mode buffer and have Emacs communicate with the sub-process. The
-features discussed below are syntax-independent, so they should work
-with a wide range of ML-like tools and compilers. @xref{Process
-Defaults}, for some hints.
-
-@findex inferior-sml-mode
-@code{inferior-sml-mode} is a specialisation of the @file{comint}
-package that comes with Emacs and XEmacs.
-
-
-@menu
-* Running ML:: Commands to run the ML compiler in a buffer
-* ML Interaction:: Sending program fragments to the compiler
-* Tracking Errors:: Finding reported syntax errors
-* Process Defaults:: Setting defaults for process interaction
-@end menu
-
-
-
-@c ========================================================== RUNNING ML
-
-@node Running ML, ML Interaction, Interaction Mode, Interaction Mode
-
-@section Starting the compiler
-
-@c == Running ML, ML Interaction, Interaction Mode, Interaction Mode ==
-
-@noindent
-Start your favourite ML compiler with the command
-
-@example
-@kbd{M-x run-sml}
-@end example
-
-@noindent
-This creates a process interaction buffer that inherits some key
-bindings from SML mode and from @file{comint} (@pxref{Shell Mode, ,
-, emacs, The Emacs Editor Manual}). Starting the ML compiler adds some
-functions to SML mode buffers so that program text can be
-communicated between editor and compiler (@pxref{ML Interaction}).
-
-The name of the ML compiler is the first thing you should know how to
-specify:
-
-
-@defvar sml-program-name
-Default: @code{"sml"}
-
-The program to run as ML. You might need to specify the full path name
-of the program.
-@end defvar
-
-
-@defvar sml-default-arg
-Default: @code{""}
-
-Useful for Poly/ML users who may supply a database file, or others who
-have wrappers for setting various options around the command to run the
-compiler. Moscow ML people might set this to @code{"-P full"}, etc..
-@end defvar
-
-The variable @code{sml-program-name} is a string holding the name
-of the program @emph{as you would type it at the shell}. You
-can always choose a program different to the default by invoking
-
-@example
-@kbd{C-u M-x run-sml}
-@end example
-
-@noindent
-With the prefix argument Emacs will prompt for the command name and any
-command line arguments to pass to the compiler. Thereafter Emacs will
-use this new name as the default, but for a permanent change you should
-set this in your @file{.emacs} with, e.g.:
-
-@lisp
-(setq sml-program-name "nj-sml")
-@end lisp
-
-
-@deffn Command run-sml
-Launches ML as an inferior process in another buffer; if an ML process
-already exists, just switch to the process buffer. A prefix argument
-allows you to edit the command line to specify the program, and any
-command line options.
-@end deffn
-
-
-@defvr Hook inferior-sml-mode-hook
-Default: @code{nil}
-
-@kbd{M-x run-sml} runs @code{comint-mode-hook} and
-@code{inferior-sml-mode-hook} hooks in that order, but @emph{after} the
-compiler is started. Use @code{inferior-sml-mode-hook} to set any
-@code{comint} buffer-local configurations for SML mode you like.
-@end defvr
-
-
-@deffn Command switch-to-sml
-Key: @kbd{C-c C-s}
-@kindex @kbd{C-c C-s}
-
-Switch from the SML buffer to the interaction buffer. By default point
-will be placed at the end of the process buffer, but a prefix argument
-will leave point wherever it was before. If you try @kbd{C-c C-s} before
-an ML process has been started, you'll just get an error message to the
-effect that there's no current process buffer.
-@end deffn
-
-
-@deffn Command sml-cd
-When started, the ML compiler's default working directory is the
-current buffer's default directory. This command allows the working
-directory to be changed, if the compiler can do this. The variable
-@code{sml-cd-command} specifies the compiler command to invoke
-(@pxref{Process Defaults}).
-@end deffn
-
-
-@c ======================================================== SENDING TEXT
-
-@node ML Interaction, Tracking Errors, Running ML, Interaction Mode
-
-@section Speaking to the compiler
-
-@c == ML Interaction, Tracking Errors, Running ML, Interaction Mode ====
-
-
-@noindent
-Several commands are defined for sending program fragments to the
-running compiler. Each of the following commands takes a prefix argument
-that will switch the input focus to the process buffer afterwards
-(leaving point at the end of the buffer):
-
-
-@deffn Command sml-load-file
-Key: @kbd{C-c C-l}
-@kindex @kbd{C-c C-l}
-
-Send a `use file' command to the current ML process. The variable
-@code{sml-use-command} is used to define the correct template for the
-command to invoke (@pxref{Process Defaults}). The default file is the
-file associated with the current buffer, or the last file loaded if you
-are in the interaction buffer.
-@end deffn
-
-
-
-@deffn Command sml-send-region
-@findex sml-send-region-and-go
-Key: @kbd{C-c C-r}
-@kindex @kbd{C-c C-r}
-
-Send the current region of text in the SML buffer.
-@code{sml-send-region-and-go} is a similar command for you to bind in
-SML mode if you wish: it'll send the region and then switch-to-sml.
-@end deffn
-
-@c @deffn Command sml-send-function
-@c @findex sml-send-function-and-go
-
-@c Send the enclosing `function' definition. Contrary to the suggestive
-@c name, this command @emph{does not} try to determine the extent of the
-@c function definition because that is too difficult with ML. Instead
-@c this just sends the enclosing @emph{paragraph} (delimited by blank
-@c lines or form-feed characters).
-@c @end deffn
-
-@deffn Command sml-send-buffer
-Key: @kbd{C-c C-b}
-@kindex @kbd{C-c C-b}
-
-Send the contents of the current buffer to ML.
-@end deffn
-
-@c ===================================================== TRACKING ERRORS
-
-@node Tracking Errors, Process Defaults, ML Interaction, Interaction Mode
-
-@section Finding errors
-
-@c == Tracking Errors, Process Defaults, ML Interaction, Interaction Mode
-
-
-@noindent
-SML mode provides one customisable function for locating the source
-position of errors reported by the compiler. This should work whether
-you type @code{use "puzzle.sml";} into the interaction buffer, or use
-one of the mechanisms provided for sending programs directly to the
-compiler---@pxref{ML Interaction}.
-
-
-@deffn Command next-error
-@findex next-error
-Key: @kbd{C-x`}
-@kindex @kbd{C-x`}
-
-Jump to the source location of the next error reported by the compiler.
-All the usual error-navigation commands are available, see
-@pxref{Compilation Mode, , , emacs, The Emacs Editor Manual}.
-@end deffn
-
-
-@c ==================================================== PROCESS DEFAULTS
-
-@node Process Defaults, , Tracking Errors, Interaction Mode
-
-@section Process defaults
-
-@c == Process Defaults, , Tracking Errors, Interaction Mode ============
-
-@noindent
-The process interaction code is independent of the compiler used,
-deliberately, so SML mode will work with a variety of ML compilers
-and ML-based tools. There are therefore a number of variables that may
-need to be set correctly before SML mode can speak to the compiler.
-Things are by default set up for Standard ML of New Jersey, but
-switching to a new system is quite easy.
-
-
-
-@defvar sml-use-command
-Default: @code{"use \"%s\""}
-
-Use file command template. Emacs will replace the @code{%s} with a file
-name. Note that Emacs requires double quote characters inside strings
-to be quoted with a backslash.
-@end defvar
-
-
-@defvar sml-cd-command
-Default: @code{"OS.FileSys.chDir \"%s\""}
-
-Compiler command to change the working directory. Not all ML systems
-support this feature (well, Edinburgh (core) ML didn't), but they
-should.
-@end defvar
-
-
-@defvar sml-prompt-regexp
-Default: @code{"^[-=>#] *"}
-
-Matches the ML compiler's prompt: @file{comint} uses this for various
-purposes.
-@end defvar
-
-
-To customise error reportage for different ML compilers you need to set
-two further variables before @code{next-error} can be useful:
-
-
-@defvar sml-error-regexp-alist
-
-Alist that specifies how to match errors in compiler output.
-Each elt has the form (REGEXP FILE-IDX LINE-IDX [COLUMN-IDX FILE-FORMAT...])
-If REGEXP matches, the FILE-IDX'th subexpression gives the file name, and
-the LINE-IDX'th subexpression gives the line number. If COLUMN-IDX is
-given, the COLUMN-IDX'th subexpression gives the column number on that line.
-If any FILE-FORMAT is given, each is a format string to produce a file name to
-try; %s in the string is replaced by the text matching the FILE-IDX'th
-subexpression.
-@end defvar
-
-
-@c A typical way of (re)setting these variables correctly is to put
-@c something in your @file{.emacs} file that resembles
-
-@c @example
-@c (setq sml-use-command "PolyML.use \"%s\"")
-@c (setq sml-prompt-regexp "^[>#] *")
-@c @end example
-
-@c ======================================================= CONFIGURATION
-
-@node Configuration, , Interaction Mode, Top
-
-@chapter Configuration Summary
-
-@c @footnote{@url{http://www.ahl.co.uk/}}
-@c @footnote{@url{http://www.dina.kvl.dk/~sestoft/mosml.html}}
-
-@noindent
-This (sort of pedagogic) section gives more information on how to
-configure SML mode: menus, key bindings, hooks and highlighting are
-discussed, along with a few other random topics.
-
-@menu
-* Hooks:: Creating them
-* Key Bindings:: Binding commands to keys
-* Highlighting:: Syntax colouring
-* Advanced Topics:: You may need to speak Emacs Lisp
-@end menu
-
-
-@c =============================================================== HOOKS
-
-@node Hooks, Key Bindings, Configuration, Configuration
-
-@section Hooks
-
-@c == Hooks, Key Bindings, Configuration, Configuration ================
-
-
-@noindent
-One way to set SML mode variables (@pxref{SML Mode
-Defaults,,Indentation Defaults}), and other defaults, is through the
-@code{sml-mode-hook} in your @file{.emacs}. A simple example:
-
-@lisp
-(defun my-sml-mode-hook () "Local defaults for SML mode"
- (setq sml-indent-level 2) ; conserve on horizontal space
- (setq words-include-escape t) ; \ loses word break status
- (setq indent-tabs-mode nil)) ; never ever indent with tabs
-(add-hook 'sml-mode-hook 'my-sml-mode-hook)
-@end lisp
-@noindent
-The body of @code{my-sml-mode-hook} is a sequence of assignments. In this
-case it is not really necessary to set @code{sml-indent-level} in a hook
-because this variable is global (most SML mode variables are). With
-similar effect:
-
-@lisp
-(setq sml-indent-level 2)
-@end lisp
-@noindent
-anywhere in your @file{.emacs} file. The variable @code{indent-tabs-mode} is
-automatically made local to the current buffer whenever it is set
-explicitly, so it @emph{must} be set in a hook if you always want
-SML mode to behave like this.
-
-Another hook is @code{inferior-sml-mode-hook}. This can be used to
-control the behaviour of the interaction buffer through various
-variables meaningful to @file{comint}-based packages:
-
-@lisp
-(defun my-inf-sml-mode-hook () "Local defaults for inferior SML mode"
- (add-hook 'comint-output-filter-functions 'comint-truncate-buffer)
- (setq comint-scroll-show-maximum-output t)
- (setq comint-input-autoexpand nil))
-(add-hook 'inferior-sml-mode-hook 'my-inf-sml-mode-hook)
-@end lisp
-@noindent
-Again, the body is a sequence of assignments. Unless you run several ML
-compilers simultaneously under one Emacs, this hook will normally only
-get run once. You might want to look up the documentation (@kbd{C-h v}
-and @kbd{C-h f}) for these buffer-local @code{comint} things.
-
-
-@c ======================================================== Key Bindings
-
-@node Key Bindings, Highlighting, Hooks, Configuration
-
-@section Key bindings
-
-@noindent
-Customisation (in Emacs) usually entails putting favourite commands on
-easily remembered keys. Two `keymaps' are defined in SML mode: one
-is effective in program text buffers (@code{sml-mode-map}) and the other
-is effective in interaction buffers (@code{inferior-sml-mode-map}).
-The initial design ensures that (many of) the default key bindings from
-the former keymap will also be available in the latter (e.g.,
-@kbd{C-c`}).
-
-Type @kbd{C-h m} in an SML mode buffer to find the default key
-bindings (and similarly in an ML interaction buffer), and use the hooks
-provided to install your preferred key bindings. Given that the keymaps
-are global (variables):
-
-@lisp
-(defun my-sml-mode-hook () "Global defaults for SML mode"
- (define-key sml-mode-map "\C-cd" 'sml-cd))
-(add-hook 'sml-mode-hook 'my-sml-mode-hook)
-@end lisp
-@noindent
-This has the effect of binding @code{sml-cd} to the key @kbd{C-c d}.
-If you want the same behaviour from @kbd{C-c d} in the ML buffer:
-
-@lisp
-(defun my-inf-sml-mode-hook () "Global defaults for inferior SML mode"
- (define-key inferior-sml-mode-map "\C-cd" 'sml-cd)
- ;; NB. for SML/NJ '96
- (setq sml-cd-command "OS.FileSys.chDir \"%s\""))
-(add-hook 'inferior-sml-mode-hook 'my-inf-sml-mode-hook)
-@end lisp
-
-There is nothing to stop you rebuilding the entire keymap for
-SML mode and the ML interaction buffer in your @file{.emacs} of
-course: SML mode won't define @code{sml-mode-map} or
-@code{inferior-sml-mode-map} if you have already done so.
-
-
-@c ======================================================== Highlighting
-
-@node Highlighting, Advanced Topics, Key Bindings, Configuration
-
-@section Syntax colouring
-
-
-@noindent
-Highlighting is very handy for picking out keywords in the program text,
-spotting misspelled kewyords, and, if you have Emacs' @file{ps-print}
-package installed (you usually do these days), obtaining pretty, even
-colourful code listings---quite properly for your colourful ML programs.
-
-The indentation scheme (strangely enough) also relies on the
-highlighting code to properly handle nested comments, which is yet
-another reason to turn on highlighting. To turn on highlighting,
-use either of:
-
-@lisp
-M-x font-lock-mode
-(add-hook 'sml-mode-hook 'turn-on-font-lock)
-(global-font-lock-mode 1)
-@end lisp
-
-The first will turn it on in the current buffer.
-The second will turn it on in all sml-mode buffers.
-The last will turn it on everywhere.
-This is valid for Emacs but maybe not for XEmacs. Check font-lock
-documentation if you encounter problems.
-
-@c ===================================================== ADVANCED TOPICS
-
-@node Advanced Topics, , Highlighting, Configuration
-
-@section Advanced Topics
-
-@flushright
-@emph{These forms are bloody useless; can't we have better ones?}
-@end flushright
-
-@sp 1
-@noindent
-You can indeed. @code{sml-insert-form} is extensible so all you need to
-do is create the macros yourself. Define a @emph{keybord macro}
-(@kbd{C-x (} <something> @kbd{C-x )}) and give it a suitable name:
-@code{sml-addto-forms-alist} prompts for a name, say @code{NAME}, and
-binds the macro @code{sml-form-NAME}. Thereafter @kbd{C-c @key{RET}
-NAME} will insert the macro at point, and @kbd{C-u C-c @key{RET} NAME}
-will insert the macro after a @code{newline-and-indent}. If you want to
-keep your macros from one editing session to the next, go to your
-@file{.emacs} file and call @code{insert-kbd-macro}; you'll need
-to add @code{NAME} to @code{sml-forms-alist} permanently yourself:
-
-@lisp
-(defun my-sml-mode-hook () "Global defaults for SML mode"
- ;; whatever else you do
- (add-to-list 'sml-forms-alist '("NAME" . FUNCTION)))
-@end lisp
-
-If you want to create templates like `case' that prompt for parameters
-you'll have to do some Lisp programming. The @code{skeleton} package is
-a good stating point. Better yet, you can reuse the wrappers used by
-sml-mode itself in your sml-mode-hook:
-
-@lisp
-(add-hook 'sml-mode-hook
- (lambda ()
- (sml-def-skeleton "case" "Case expr: "
- str " of" \n _ " => ")))
-@end lisp
-
-This will redefine `case' in order to leave the `of' on the first line.
-See the documentation of @code{skeleton-insert} to get a better
-understanding of how this works.
-
-@sp 1
-@flushright
-@emph{I hate that indentation algorithm; can't I tweak it?}
-@end flushright
-
-@sp 1
-@noindent
-Ah, yes, of course, but this manual will not tell you how.
-
-
-@sp 1
-@flushright
-@emph{Can SML mode handle more than one compiler running at once?}
-@end flushright
-
-Sure, just rename the @samp{*sml*} buffer and then use @code{run-sml}
-as usual.
-
-@sp 1
-@flushright
-@emph{What needs to be done to support other ML compilers?}
-@end flushright
-
-@sp 1
-@noindent
-Not much really. Just add the right regular expressions to
-@code{sml-error-regexp-alist} and that should be all.
-
-
-@c ======================================================= COMMAND INDEX
-
-@headings singleafter
-
-@node Command Index, Variable Index, , Top
-
-@unnumbered Command Index
-
-@printindex fn
-
-@c ====================================================== VARIABLE INDEX
-
-@c node Variable Index, , Command Index, Top
-@node Variable Index, Key Index, Command Index, Top
-
-@unnumbered Variable Index
-
-@c == Variable Index, Key Index, Command Index, Top ====================
-
-@printindex vr
-
-@c =========================================================== KEY INDEX
-
-@node Key Index, , Variable Index, Top
-
-@unnumbered Key Index
-
-@c == Key Index, , Variable Index, Top =================================
-
-@printindex ky
-
-@contents
-@bye
diff --git a/emacs/emacs.d/sml-mode-5.0/sml-oldindent.el b/emacs/emacs.d/sml-mode-5.0/sml-oldindent.el
@@ -1,713 +0,0 @@
-;;; sml-oldindent.el --- Navigation and indentation for SML without SMIE
-
-;; Copyright (C) 1999,2000,2004,2007,2012 Stefan Monnier <monnier@gnu.org>
-;;
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-;;; Commentary:
-
-
-;;; Code:
-
-(eval-when-compile (require 'cl))
-(require 'sml-mode)
-
-(defun sml-preproc-alist (al)
- "Expand an alist AL where keys can be lists of keys into a normal one."
- (apply #'nconc
- (mapcar (lambda (x)
- (let ((k (car x))
- (v (cdr x)))
- (if (consp k)
- (mapcar (lambda (y) (cons y v)) k)
- (list x))))
- al)))
-
-(defconst sml-begin-syms
- '("let" "abstype" "local" "struct" "sig")
- "Symbols matching the `end' symbol.")
-
-(defconst sml-begin-syms-re
- (sml-syms-re sml-begin-syms)
- "Symbols matching the `end' symbol.")
-
-;; (defconst sml-user-begin-symbols-re
-;; (sml-syms-re '("let" "abstype" "local" "struct" "sig" "in" "with"))
-;; "Symbols matching (loosely) the `end' symbol.")
-
-(defconst sml-sexp-head-symbols-re
- (sml-syms-re `("let" "abstype" "local" "struct" "sig" "in" "with"
- "if" "then" "else" "case" "of" "fn" "fun" "val" "and"
- "datatype" "type" "exception" "open" "infix" "infixr" "nonfix"
- ,@sml-module-head-syms
- "handle" "raise"))
- "Symbols starting an sexp.")
-
-;; (defconst sml-not-arg-start-re
-;; (sml-syms-re '("in" "of" "end" "andalso"))
-;; "Symbols that can't be found at the head of an arg.")
-
-;; (defconst sml-not-arg-re
-;; (sml-syms-re '("in" "of" "end" "andalso"))
-;; "Symbols that should not be confused with an arg.")
-
-(defconst sml-indent-rule
- (sml-preproc-alist
- `(("struct" . 0)
- (,sml-module-head-syms "d=" 0)
- ("local" "in" 0)
- ;;("of" . (3 nil))
- ;;("else" . (sml-indent-level 0))
- ;;(("in" "fun" "and" "of") . (sml-indent-level nil))
- ("if" "else" 0)
- (,sml-=-starter-syms nil)
- (("abstype" "case" "datatype" "if" "then" "else" "sharing" "infix" "infixr"
- "let" "local" "nonfix" "open" "raise" "sig" "struct" "type" "val" "while"
- "do" "with" "withtype")))))
-
-(defconst sml-delegate
- (sml-preproc-alist
- `((("of" "else" "then" "d=") . (not (sml-bolp)))
- ("in" . t)))
- "Words which might delegate indentation to their parent.")
-
-(defcustom sml-symbol-indent
- '(("fn" . -3)
- ("of" . 1)
- ("|" . -2)
- ("," . -2)
- (";" . -2)
- ;;("in" . 1)
- ("d=" . 2))
- "Special indentation alist for some symbols.
-An entry like (\"in\" . 1) indicates that a line starting with the
-symbol `in' should be indented one char further to the right.
-This is only used in a few specific cases, so it does not work
-for all symbols and in all lines starting with the given symbol."
- :group 'sml
- :type '(repeat (cons string integer)))
-
-(defconst sml-open-paren
- (sml-preproc-alist
- `((,(list* "with" "in" sml-begin-syms) ,sml-begin-syms-re "\\<end\\>")))
- "Symbols that should behave somewhat like opening parens.")
-
-(defconst sml-close-paren
- `(("in" "\\<l\\(ocal\\|et\\)\\>")
- ("with" "\\<abstype\\>")
- ("withtype" "\\<\\(abs\\|data\\)type\\>")
- ("end" ,sml-begin-syms-re)
- ("then" "\\<if\\>")
- ("else" "\\<if\\>" (sml-bolp))
- ("of" "\\<case\\>")
- ("d=" nil))
- "Symbols that should behave somewhat like close parens.")
-
-(defconst sml-agglomerate-re "\\<else[ \t]+if\\>"
- "Regexp of compound symbols (pairs of symbols to be considered as one).")
-
-(defvar sml-internal-syntax-table
- (let ((st (make-syntax-table sml-mode-syntax-table)))
- (modify-syntax-entry ?_ "w" st)
- (modify-syntax-entry ?' "w" st)
- (modify-syntax-entry ?. "w" st)
- ;; Treating `~' as a word constituent is not quite right, but
- ;; close enough. Think about 12.3E~2 for example. Also `~' on its
- ;; own *is* a nonfix symbol.
- (modify-syntax-entry ?~ "w" st)
- st)
- "Syntax table used for internal sml-mode operation.")
-
-;;;
-;;; various macros
-;;;
-
-(defmacro sml-with-ist (&rest r)
- (let ((ost-sym (make-symbol "oldtable")))
- `(let ((,ost-sym (syntax-table))
- (case-fold-search nil)
- (parse-sexp-lookup-properties t)
- (parse-sexp-ignore-comments t))
- (unwind-protect
- (progn (set-syntax-table sml-internal-syntax-table) . ,r)
- (set-syntax-table ,ost-sym)))))
-(def-edebug-spec sml-with-ist t)
-
-(defmacro sml-move-if (&rest body)
- (let ((pt-sym (make-symbol "point"))
- (res-sym (make-symbol "result")))
- `(let ((,pt-sym (point))
- (,res-sym ,(cons 'progn body)))
- (unless ,res-sym (goto-char ,pt-sym))
- ,res-sym)))
-(def-edebug-spec sml-move-if t)
-
-(defmacro sml-point-after (&rest body)
- `(save-excursion
- ,@body
- (point)))
-(def-edebug-spec sml-point-after t)
-
-;;
-
-(defvar sml-op-prec
- (sml-preproc-alist
- '(("before" . 0)
- ((":=" "o") . 3)
- ((">" ">=" "<>" "<" "<=" "=") . 4)
- (("::" "@") . 5)
- (("+" "-" "^") . 6)
- (("/" "*" "quot" "rem" "div" "mod") . 7)))
- "Alist of SML infix operators and their precedence.")
-
-(defconst sml-syntax-prec
- (sml-preproc-alist
- `((("in" "with") . 10)
- ((";" ",") . 20)
- (("=>" "d=" "=of") . (65 . 40))
- ("|" . (47 . 30))
- (("case" "of" "fn") . 45)
- (("if" "then" "else" "while" "do" "raise") . 50)
- ("handle" . 60)
- ("orelse" . 70)
- ("andalso" . 80)
- ((":" ":>") . 90)
- ("->" . 95)
- (,(cons "end" sml-begin-syms) . 10000)))
- "Alist of pseudo-precedence of syntactic elements.")
-
-(defun sml-op-prec (op dir)
- "Return the precedence of OP or nil if it's not an infix.
-DIR should be set to BACK if you want to precedence w.r.t the left side
- and to FORW for the precedence w.r.t the right side.
-This assumes that we are `looking-at' the OP."
- (when op
- (let ((sprec (cdr (assoc op sml-syntax-prec))))
- (cond
- ((consp sprec) (if (eq dir 'back) (car sprec) (cdr sprec)))
- (sprec sprec)
- (t
- (let ((prec (cdr (assoc op sml-op-prec))))
- (when prec (+ prec 100))))))))
-
-;;
-
-(defun sml-forward-spaces () (forward-comment 100000))
-(defun sml-backward-spaces () (forward-comment -100000))
-
-
-;;
-;; moving forward around matching symbols
-;;
-
-(defun sml-looking-back-at (re)
- (save-excursion
- (when (= 0 (skip-syntax-backward "w_")) (backward-char))
- (looking-at re)))
-
-(defun sml-find-match-forward (this match)
- "Only works for word matches."
- (let ((level 1)
- (forward-sexp-function nil)
- (either (concat this "\\|" match)))
- (while (and (not (eobp)) (> level 0))
- (forward-sexp 1)
- (while (not (or (eobp) (sml-looking-back-at either)))
- (condition-case () (forward-sexp 1) (error (forward-char 1))))
- (setq level
- (cond
- ((sml-looking-back-at this) (1+ level))
- ((sml-looking-back-at match) (1- level))
- (t (error "Unbalanced")))))
- t))
-
-(defun sml-find-match-backward (this match)
- (let ((level 1)
- (forward-sexp-function nil)
- (either (concat this "\\|" match)))
- (while (> level 0)
- (backward-sexp 1)
- (while (not (or (bobp) (looking-at either)))
- (condition-case () (backward-sexp 1) (error (backward-char 1))))
- (setq level
- (cond
- ((looking-at this) (1+ level))
- ((looking-at match) (1- level))
- (t (error "Unbalanced")))))
- t))
-
-;;;
-;;; Read a symbol, including the special "op <sym>" case
-;;;
-
-(defmacro sml-move-read (&rest body)
- (let ((pt-sym (make-symbol "point")))
- `(let ((,pt-sym (point)))
- ,@body
- (when (/= (point) ,pt-sym)
- (buffer-substring-no-properties (point) ,pt-sym)))))
-(def-edebug-spec sml-move-read t)
-
-(defun sml-poly-equal-p ()
- (< (sml-point-after (re-search-backward sml-=-starter-re nil 'move))
- (sml-point-after (re-search-backward "=" nil 'move))))
-
-(defun sml-nested-of-p ()
- (< (sml-point-after
- (re-search-backward sml-non-nested-of-starter-re nil 'move))
- (sml-point-after (re-search-backward "\\<case\\>" nil 'move))))
-
-(defun sml-forward-sym-1 ()
- (or (/= 0 (skip-syntax-forward "'w_"))
- (/= 0 (skip-syntax-forward ".'"))))
-(defun sml-forward-sym ()
- (let ((sym (sml-move-read (sml-forward-sym-1))))
- (cond
- ((equal "op" sym)
- (sml-forward-spaces)
- (concat "op " (or (sml-move-read (sml-forward-sym-1)) "")))
- ((equal sym "=")
- (save-excursion
- (sml-backward-sym-1)
- (if (sml-poly-equal-p) "=" "d=")))
- ((equal sym "of")
- (save-excursion
- (sml-backward-sym-1)
- (if (sml-nested-of-p) "of" "=of")))
- ;; ((equal sym "datatype")
- ;; (save-excursion
- ;; (sml-backward-sym-1)
- ;; (sml-backward-spaces)
- ;; (if (eq (preceding-char) ?=) "=datatype" sym)))
- (t sym))))
-
-(defun sml-backward-sym-1 ()
- (or (/= 0 (skip-syntax-backward ".'"))
- (/= 0 (skip-syntax-backward "'w_"))))
-(defun sml-backward-sym ()
- (let ((sym (sml-move-read (sml-backward-sym-1))))
- (when sym
- ;; FIXME: what should we do if `sym' = "op" ?
- (let ((point (point)))
- (sml-backward-spaces)
- (if (equal "op" (sml-move-read (sml-backward-sym-1)))
- (concat "op " sym)
- (goto-char point)
- (cond
- ((string= sym "=") (if (sml-poly-equal-p) "=" "d="))
- ((string= sym "of") (if (sml-nested-of-p) "of" "=of"))
- ;; ((string= sym "datatype")
- ;; (save-excursion (sml-backward-spaces)
- ;; (if (eq (preceding-char) ?=) "=datatype" sym)))
- (t sym)))))))
-
-
-(defun sml-backward-sexp (prec)
- "Move one sexp backward if possible, or one char else.
-Returns t if the move indeed moved through one sexp and nil if not.
-PREC is the precedence currently looked for."
- (let ((parse-sexp-lookup-properties t)
- (parse-sexp-ignore-comments t))
- (sml-backward-spaces)
- (let* ((op (sml-backward-sym))
- (op-prec (sml-op-prec op 'back))
- match)
- (cond
- ((not op)
- (let ((point (point)))
- (ignore-errors (let ((forward-sexp-function nil)) (backward-sexp 1)))
- (if (/= point (point)) t (ignore-errors (backward-char 1)) nil)))
- ;; stop as soon as precedence is smaller than `prec'
- ((and prec op-prec (>= prec op-prec)) nil)
- ;; special rules for nested constructs like if..then..else
- ((and (or (not prec) (and prec op-prec))
- (setq match (second (assoc op sml-close-paren))))
- (sml-find-match-backward (concat "\\<" op "\\>") match))
- ;; don't back over open-parens
- ((assoc op sml-open-paren) nil)
- ;; infix ops precedence
- ((and prec op-prec) (< prec op-prec))
- ;; [ prec = nil ] a new operator, let's skip the sexps until the next
- (op-prec (while (sml-move-if (sml-backward-sexp op-prec))) t)
- ;; special symbols indicating we're getting out of a nesting level
- ((string-match sml-sexp-head-symbols-re op) nil)
- ;; if the op was not alphanum, then we still have to do the backward-sexp
- ;; this reproduces the usual backward-sexp, but it might be bogus
- ;; in this case since !@$% is a perfectly fine symbol
- (t t))))) ;(or (string-match "\\sw" op) (sml-backward-sexp prec))
-
-(defun sml-forward-sexp (prec)
- "Moves one sexp forward if possible, or one char else.
-Returns T if the move indeed moved through one sexp and NIL if not."
- (let ((parse-sexp-lookup-properties t)
- (parse-sexp-ignore-comments t))
- (sml-forward-spaces)
- (let* ((op (sml-forward-sym))
- (op-prec (sml-op-prec op 'forw))
- match)
- (cond
- ((not op)
- (let ((point (point)))
- (ignore-errors (let ((forward-sexp-function nil)) (forward-sexp 1)))
- (if (/= point (point)) t (forward-char 1) nil)))
- ;; stop as soon as precedence is smaller than `prec'
- ((and prec op-prec (>= prec op-prec)) nil)
- ;; special rules for nested constructs like if..then..else
- ((and (or (not prec) (and prec op-prec))
- (setq match (cdr (assoc op sml-open-paren))))
- (sml-find-match-forward (first match) (second match)))
- ;; don't forw over close-parens
- ((assoc op sml-close-paren) nil)
- ;; infix ops precedence
- ((and prec op-prec) (< prec op-prec))
- ;; [ prec = nil ] a new operator, let's skip the sexps until the next
- (op-prec (while (sml-move-if (sml-forward-sexp op-prec))) t)
- ;; special symbols indicating we're getting out of a nesting level
- ((string-match sml-sexp-head-symbols-re op) nil)
- ;; if the op was not alphanum, then we still have to do the backward-sexp
- ;; this reproduces the usual backward-sexp, but it might be bogus
- ;; in this case since !@$% is a perfectly fine symbol
- (t t))))) ;(or (string-match "\\sw" op) (sml-backward-sexp prec))
-
-(defun sml-in-word-p ()
- (and (eq ?w (char-syntax (or (char-before) ? )))
- (eq ?w (char-syntax (or (char-after) ? )))))
-
-(defun sml-user-backward-sexp (&optional count)
- "Like `backward-sexp' but tailored to the SML syntax."
- (interactive "p")
- (unless count (setq count 1))
- (sml-with-ist
- (let ((point (point)))
- (if (< count 0) (sml-user-forward-sexp (- count))
- (when (sml-in-word-p) (forward-word 1))
- (dotimes (i count)
- (unless (sml-backward-sexp nil)
- (goto-char point)
- (error "Containing expression ends prematurely")))))))
-
-(defun sml-user-forward-sexp (&optional count)
- "Like `forward-sexp' but tailored to the SML syntax."
- (interactive "p")
- (unless count (setq count 1))
- (sml-with-ist
- (let ((point (point)))
- (if (< count 0) (sml-user-backward-sexp (- count))
- (when (sml-in-word-p) (backward-word 1))
- (dotimes (i count)
- (unless (sml-forward-sexp nil)
- (goto-char point)
- (error "Containing expression ends prematurely")))))))
-
-;;(defun sml-forward-thing ()
-;; (if (= ?w (char-syntax (char-after))) (forward-word 1) (forward-char 1)))
-
-(defun sml-backward-arg () (sml-backward-sexp 1000))
-(defun sml-forward-arg () (sml-forward-sexp 1000))
-
-(provide 'sml-move)
-
-(defvar sml-rightalign-and)
-(defvar sml-indent-args)
-(defvar sml-indent-level)
-
-(defun sml-indent-line ()
- "Indent current line of ML code."
- (interactive)
- (let ((savep (> (current-column) (current-indentation)))
- (indent (max (or (ignore-errors (sml-calculate-indentation)) 0) 0)))
- (if savep
- (save-excursion (indent-line-to indent))
- (indent-line-to indent))))
-
-(defun sml-find-comment-indent ()
- (save-excursion
- (let ((depth 1))
- (while (> depth 0)
- (if (re-search-backward "(\\*\\|\\*)" nil t)
- (cond
- ;; FIXME: That's just a stop-gap.
- ((eq (get-text-property (point) 'face) 'font-lock-string-face))
- ((looking-at "*)") (incf depth))
- ((looking-at comment-start-skip) (decf depth)))
- (setq depth -1)))
- (if (= depth 0)
- (1+ (current-column))
- nil))))
-
-(defun sml-calculate-indentation ()
- (save-excursion
- (beginning-of-line) (skip-chars-forward "\t ")
- (sml-with-ist
- ;; Indentation for comments alone on a line, matches the
- ;; proper indentation of the next line.
- (when (looking-at "(\\*") (sml-forward-spaces))
- (let (data
- (sym (save-excursion (sml-forward-sym))))
- (or
- ;; Allow the user to override the indentation.
- (when (looking-at (concat ".*" (regexp-quote comment-start)
- "[ \t]*fixindent[ \t]*"
- (regexp-quote comment-end)))
- (current-indentation))
-
- ;; Continued comment.
- (and (looking-at "\\*") (sml-find-comment-indent))
-
- ;; Continued string ? (Added 890113 lbn)
- (and (looking-at "\\\\")
- (or (save-excursion (forward-line -1)
- (if (looking-at "[\t ]*\\\\")
- (current-indentation)))
- (save-excursion
- (if (re-search-backward "[^\\\\]\"" nil t)
- (1+ (current-column))
- 0))))
-
- ;; Closing parens. Could be handled below with `sml-indent-relative'?
- (and (looking-at "\\s)")
- (save-excursion
- (skip-syntax-forward ")")
- (backward-sexp 1)
- (if (sml-dangling-sym)
- (sml-indent-default 'noindent)
- (current-column))))
-
- (and (setq data (assoc sym sml-close-paren))
- (sml-indent-relative sym data))
-
- (and (member sym sml-starters-syms)
- (sml-indent-starter sym))
-
- (and (string= sym "|") (sml-indent-pipe))
-
- (sml-indent-arg)
- (sml-indent-default))))))
-
-(defsubst sml-bolp ()
- (save-excursion (skip-chars-backward " \t|") (bolp)))
-
-(defun sml-first-starter-p ()
- "Non-nil if starter at point is immediately preceded by let/local/in/..."
- (save-excursion
- (let ((sym (unless (save-excursion (sml-backward-arg))
- (sml-backward-spaces)
- (sml-backward-sym))))
- (if (member sym '(";" "d=")) (setq sym nil))
- sym)))
-
-(defun sml-indent-starter (orig-sym)
- "Return the indentation to use for a symbol in `sml-starters-syms'.
-Point should be just before the symbol ORIG-SYM and is not preserved."
- (let ((sym (unless (save-excursion (sml-backward-arg))
- (sml-backward-spaces)
- (sml-backward-sym))))
- (if (member sym '(";" "d=")) (setq sym nil))
- (if sym (sml-get-sym-indent sym)
- ;; FIXME: this can take a *long* time !!
- (setq sym (sml-old-find-matching-starter sml-starters-syms))
- (if (or (sml-first-starter-p)
- ;; Don't align with `and' because it might be specially indented.
- (and (or (equal orig-sym "and") (not (equal sym "and")))
- (sml-bolp)))
- (+ (current-column)
- (if (and sml-rightalign-and (equal orig-sym "and"))
- (- (length sym) 3) 0))
- (sml-indent-starter orig-sym)))))
-
-(defun sml-indent-relative (sym data)
- (save-excursion
- (sml-forward-sym) (sml-backward-sexp nil)
- (unless (second data) (sml-backward-spaces) (sml-backward-sym))
- (+ (or (cdr (assoc sym sml-symbol-indent)) 0)
- (sml-delegated-indent))))
-
-(defun sml-indent-pipe ()
- (let ((sym (sml-old-find-matching-starter sml-pipeheads
- (sml-op-prec "|" 'back))))
- (when sym
- (if (string= sym "|")
- (if (sml-bolp) (current-column) (sml-indent-pipe))
- (let ((pipe-indent (or (cdr (assoc "|" sml-symbol-indent)) -2)))
- (when (or (member sym '("datatype" "abstype"))
- (and (equal sym "and")
- (save-excursion
- (forward-word 1)
- (not (sml-funname-of-and)))))
- (re-search-forward "="))
- (sml-forward-sym)
- (sml-forward-spaces)
- (+ pipe-indent (current-column)))))))
-
-(defun sml-indent-arg ()
- (and (save-excursion (ignore-errors (sml-forward-arg)))
- ;;(not (looking-at sml-not-arg-re))
- ;; looks like a function or an argument
- (sml-move-if (sml-backward-arg))
- ;; an argument
- (if (save-excursion (not (sml-backward-arg)))
- ;; a first argument
- (+ (current-column) sml-indent-args)
- ;; not a first arg
- (while (and (/= (current-column) (current-indentation))
- (sml-move-if (sml-backward-arg))))
- (unless (save-excursion (sml-backward-arg))
- ;; all earlier args are on the same line
- (sml-forward-arg) (sml-forward-spaces))
- (current-column))))
-
-(defun sml-get-indent (data sym)
- (let (d)
- (cond
- ((not (listp data)) data)
- ((setq d (member sym data)) (cadr d))
- ((and (consp data) (not (stringp (car data)))) (car data))
- (t sml-indent-level))))
-
-(defun sml-dangling-sym ()
- "Non-nil if the symbol after point is dangling.
-The symbol can be an SML symbol or an open-paren. \"Dangling\" means that
-it is not on its own line but is the last element on that line."
- (save-excursion
- (and (not (sml-bolp))
- (< (sml-point-after (end-of-line))
- (sml-point-after (or (sml-forward-sym) (skip-syntax-forward "("))
- (sml-forward-spaces))))))
-
-(defun sml-delegated-indent ()
- (if (sml-dangling-sym)
- (sml-indent-default 'noindent)
- (sml-move-if (backward-word 1)
- (looking-at sml-agglomerate-re))
- (current-column)))
-
-(defun sml-get-sym-indent (sym &optional style)
- "Find the indentation for the SYM we're `looking-at'.
-If indentation is delegated, point will move to the start of the parent.
-Optional argument STYLE is currently ignored."
- (assert (equal sym (save-excursion (sml-forward-sym))))
- (save-excursion
- (let ((delegate (and (not (equal sym "end")) (assoc sym sml-close-paren)))
- (head-sym sym))
- (when (and delegate (not (eval (third delegate))))
- ;;(sml-find-match-backward sym delegate)
- (sml-forward-sym) (sml-backward-sexp nil)
- (setq head-sym
- (if (second delegate)
- (save-excursion (sml-forward-sym))
- (sml-backward-spaces) (sml-backward-sym))))
-
- (let ((idata (assoc head-sym sml-indent-rule)))
- (when idata
- ;;(if (or style (not delegate))
- ;; normal indentation
- (let ((indent (sml-get-indent (cdr idata) sym)))
- (when indent (+ (sml-delegated-indent) indent)))
- ;; delgate indentation to the parent
- ;;(sml-forward-sym) (sml-backward-sexp nil)
- ;;(let* ((parent-sym (save-excursion (sml-forward-sym)))
- ;; (parent-indent (cdr (assoc parent-sym sml-indent-starters))))
- ;; check the special rules
- ;;(+ (sml-delegated-indent)
- ;; (or (sml-get-indent (cdr indent-data) 1 'strict)
- ;; (sml-get-indent (cdr parent-indent) 1 'strict)
- ;; (sml-get-indent (cdr indent-data) 0)
- ;; (sml-get-indent (cdr parent-indent) 0))))))))
- )))))
-
-(defun sml-indent-default (&optional noindent)
- (let* ((sym-after (save-excursion (sml-forward-sym)))
- (_ (sml-backward-spaces))
- (sym-before (sml-backward-sym))
- (sym-indent (and sym-before (sml-get-sym-indent sym-before)))
- (indent-after (or (cdr (assoc sym-after sml-symbol-indent)) 0)))
- (when (equal sym-before "end")
- ;; I don't understand what's really happening here, but when
- ;; it's `end' clearly, we need to do something special.
- (forward-word 1)
- (setq sym-before nil sym-indent nil))
- (cond
- (sym-indent
- ;; the previous sym is an indentation introducer: follow the rule
- (if noindent
- ;;(current-column)
- sym-indent
- (+ sym-indent indent-after)))
- ;; If we're just after a hanging open paren.
- ((and (eq (char-syntax (preceding-char)) ?\()
- (save-excursion (backward-char) (sml-dangling-sym)))
- (backward-char)
- (sml-indent-default))
- (t
- ;; default-default
- (let* ((prec-after (sml-op-prec sym-after 'back))
- (prec (or (sml-op-prec sym-before 'back) prec-after 100)))
- ;; go back until you hit a symbol that has a lower prec than the
- ;; "current one", or until you backed over a sym that has the same prec
- ;; but is at the beginning of a line.
- (while (and (not (sml-bolp))
- (while (sml-move-if (sml-backward-sexp (1- prec))))
- (not (sml-bolp)))
- (while (sml-move-if (sml-backward-sexp prec))))
- (if noindent
- ;; the `noindent' case does back over an introductory symbol
- ;; such as `fun', ...
- (progn
- (sml-move-if
- (sml-backward-spaces)
- (member (sml-backward-sym) sml-starters-syms))
- (current-column))
- ;; Use `indent-after' for cases such as when , or ; should be
- ;; outdented so that their following terms are aligned.
- (+ (if (progn
- (if (equal sym-after ";")
- (sml-move-if
- (sml-backward-spaces)
- (member (sml-backward-sym) sml-starters-syms)))
- (and sym-after (not (looking-at sym-after))))
- indent-after 0)
- (current-column))))))))
-
-
-;; maybe `|' should be set to word-syntax in our temp syntax table ?
-(defun sml-current-indentation ()
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t|")
- (current-column)))
-
-
-(defun sml-old-find-matching-starter (syms &optional prec)
- (let (sym)
- (ignore-errors
- (while
- (progn (sml-backward-sexp prec)
- (setq sym (save-excursion (sml-forward-sym)))
- (not (or (member sym syms) (bobp)))))
- (if (member sym syms) sym))))
-
-(defun sml-old-skip-siblings ()
- (while (and (not (bobp)) (sml-backward-arg))
- (sml-old-find-matching-starter sml-starters-syms))
- (when (looking-at "in\\>\\|local\\>")
- ;; Skip over `local...in' and continue.
- (forward-word 1)
- (sml-backward-sexp nil)
- (sml-old-skip-siblings)))
-
-(provide 'sml-oldindent)
-
-;;; sml-oldindent.el ends here
diff --git a/emacs/emacs.d/sml-mode-5.0/sml-proc.el b/emacs/emacs.d/sml-mode-5.0/sml-proc.el
@@ -1,784 +0,0 @@
-;;; sml-proc.el --- Comint based interaction mode for Standard ML.
-
-;; Copyright (C) 1999,2000,2003,2004,2005,2007,2012 Stefan Monnier
-;; Copyright (C) 1994-1997 Matthew J. Morley
-;; Copyright (C) 1989 Lars Bo Nielsen
-
-;; ====================================================================
-
-;; This file is not part of GNU Emacs, but it is distributed under the
-;; same conditions.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 3, or (at
-;; your option) any later version.
-
-;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;; General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 0139, USA.
-;; (See sml-mode.el for HISTORY.)
-
-;; ====================================================================
-
-;; [MJM 10/94] Separating this from sml-mode means sml-mode will run
-;; under 18.59 (or anywhere without comint, if there are such places).
-;; See sml-mode.el for further information.
-
-;;; Commentary:
-
-;; Inferior-sml-mode is for interacting with an ML process run under
-;; emacs. This uses the comint package so you get history, expansion,
-;; backup and all the other benefits of comint. Interaction is
-;; achieved by M-x run-sml which starts a sub-process under emacs. You may
-;; need to set this up for autoloading in your .emacs:
-
-;; (autoload 'run-sml "sml-proc" "Run an inferior ML process." t)
-
-;; Exactly what process is governed by the variable sml-program-name
-;; -- just "sml" by default. If you give a prefix argument (C-u M-x
-;; run-sml) you will be prompted for a different program to execute from
-;; the default -- if you just hit RETURN you get the default anyway --
-;; along with the option to specify any command line arguments. Once
-;; you select the ML program name in this manner, it remains the
-;; default (unless you set in a hook, or otherwise).
-
-;; NOTE: inferior-sml-mode-hook is run AFTER the ML program has been
-;; launched. inferior-sml-load-hook is run only when sml-proc.el is
-;; loaded into Emacs.
-
-;; When running an ML process some further key-bindings are effective
-;; in sml-mode buffer(s). C-c C-s (switch-to-sml) will split the
-;; screen into two windows if necessary and place you in the ML
-;; process buffer. In the interaction buffer, C-c C-s is bound to the
-;; `sml' command by default (in case you need to restart).
-
-;; C-c C-l (sml-load-file) will load an SML source file into the
-;; inferior process, C-c C-r (sml-send-region) will send the current
-;; region of text to the ML process, etc. Given a prefix argument to
-;; these commands will switch you from the SML buffer to the ML
-;; process buffer as well as sending the text. If you get errors
-;; reported by the compiler, C-x ` (next-error) will step through
-;; the errors with you.
-
-;; NOTE. There is only limited support for this as it obviously
-;; depends on the compiler's error messages being recognised by the
-;; mode. Error reporting is currently only geared up for SML/NJ,
-;; Moscow ML, and Poly/ML. For other compilers, add the relevant
-;; regexp to sml-error-regexp-alist and send it to me.
-
-;; To send pieces of code to the underlying compiler, we never send the text
-;; directly but use a temporary file instead. This breaks if the compiler
-;; does not understand `use', but has the benefit of allowing better error
-;; reporting.
-
-;; Bugs:
-
-;; Todo:
-
-;; - Keep improving `sml-compile'.
-;; - ignore warnings (if requested) for next-error
-
-;;; Code:
-
-(eval-when-compile (require 'cl))
-(require 'sml-mode)
-(require 'comint)
-(require 'compile)
-
-(defgroup sml-proc ()
- "Interacting with an SML process."
- :group 'sml)
-
-(defcustom sml-program-name "sml"
- "Program to run as ML."
- :type '(string))
-
-(defcustom sml-default-arg ""
- "Default command line option to pass, if any."
- :type '(string))
-
-(defcustom sml-host-name ""
- "Host on which to run ML."
- :type '(string))
-
-(defcustom sml-config-file "~/.smlproc.sml"
- "File that should be fed to the ML process when started."
- :type '(string))
-
-(defcustom sml-compile-command "CM.make()"
- "The command used by default by `sml-compile'.
-See also `sml-compile-commands-alist'.")
-
-(defcustom sml-compile-commands-alist
- '(("CMB.make()" . "all-files.cm")
- ("CMB.make()" . "pathconfig")
- ("CM.make()" . "sources.cm")
- ("use \"load-all\"" . "load-all"))
- "Commands used by default by `sml-compile'.
-Each command is associated with its \"main\" file.
-It is perfectly OK to associate several files with a command or several
-commands with the same file.")
-
-(defvar inferior-sml-mode-hook nil
- "*This hook is run when the inferior ML process is started.
-All buffer local customisations for the interaction buffers go here.")
-
-(defvar sml-error-overlay nil
- "*Non-nil means use an overlay to highlight errorful code in the buffer.
-The actual value is the name of a face to use for the overlay.
-Instead of setting this variable to 'region, you can also simply keep
-it NIL and use (transient-mark-mode) which will provide similar
-benefits (but with several side effects).")
-
-(defvar sml-buffer nil
- "*The current ML process buffer.
-
-MULTIPLE PROCESS SUPPORT (Whoever wants multi-process support anyway?)
-=====================================================================
-`sml-mode' supports, in a fairly simple fashion, running multiple ML
-processes. To run multiple ML processes, you start the first up with
-\\[sml]. It will be in a buffer named *sml*. Rename this buffer with
-\\[rename-buffer]. You may now start up a new process with another
-\\[sml]. It will be in a new buffer, named *sml*. You can switch
-between the different process buffers with \\[switch-to-buffer].
-
-NB *sml* is just the default name for the buffer. It actually gets
-it's name from the value of `sml-program-name' -- *poly*, *smld*,...
-
-If you have more than one ML process around, commands that send text
-from source buffers to ML processes -- like `sml-send-function' or
-`sml-send-region' -- have to choose a process to send it to. This is
-determined by the global variable `sml-buffer'. Suppose you have three
-inferior ML's running:
- Buffer Process
- sml #<process sml>
- mosml #<process mosml>
- *sml* #<process sml<2>>
-If you do a \\[sml-send-function] command on some ML source code,
-what process do you send it to?
-
-- If you're in a process buffer (sml, mosml, or *sml*), you send it to
- that process (usually makes sense only to `sml-load-file').
-- If you're in some other buffer (e.g., a source file), you send it to
- the process attached to buffer `sml-buffer'.
-
-This process selection is performed by function `sml-proc' which looks
-at the value of `sml-buffer' -- which must be a Lisp buffer object, or
-a string \(or nil\).
-
-Whenever \\[sml] fires up a new process, it resets `sml-buffer' to be
-the new process's buffer. If you only run one process, this will do
-the right thing. If you run multiple processes, you can change
-`sml-buffer' to another process buffer with \\[set-variable], or
-use the command \\[sml-buffer] in the interaction buffer of choice.")
-
-
-;;; ALL STUFF THAT DEFAULTS TO THE SML/NJ COMPILER (0.93)
-
-(defvar sml-use-command "use \"%s\""
- "*Template for loading a file into the inferior ML process.
-Set to \"use \\\"%s\\\"\" for SML/NJ or Edinburgh ML;
-set to \"PolyML.use \\\"%s\\\"\" for Poly/ML, etc.")
-
-(defvar sml-cd-command "OS.FileSys.chDir \"%s\""
- "*Command template for changing working directories under ML.
-Set this to nil if your compiler can't change directories.
-
-The format specifier \"%s\" will be converted into the directory name
-specified when running the command \\[sml-cd].")
-
-(defcustom sml-prompt-regexp "^[-=>#] *"
- "Regexp used to recognise prompts in the inferior ML process."
- :type '(regexp))
-
-(defvar sml-error-regexp-alist
- `( ;; Poly/ML messages
- ("^\\(Error\\|Warning:\\) in '\\(.+\\)', line \\([0-9]+\\)" 2 3)
- ;; Moscow ML
- ("^File \"\\([^\"]+\\)\", line \\([0-9]+\\)\\(-\\([0-9]+\\)\\)?, characters \\([0-9]+\\)-\\([0-9]+\\):" 1 2 5)
- ;; SML/NJ: the file-pattern is anchored to avoid
- ;; pathological behavior with very long lines.
- ("^[-= ]*\\(.*[^\n)]\\)\\( (.*)\\)?:\\([0-9]+\\)\\.\\([0-9]+\\)\\(-\\([0-9]+\\)\\.\\([0-9]+\\)\\)? \\(Error\\|Warnin\\(g\\)\\): .*" 1
- ,@(if (fboundp 'compilation-fake-loc) ;New compile.el.
- '((3 . 6) (4 . 7) (9))
- '(sml-make-error 3 4 6 7)))
- ;; SML/NJ's exceptions: see above.
- ("^ +\\(raised at: \\)?\\(.+\\):\\([0-9]+\\)\\.\\([0-9]+\\)\\(-\\([0-9]+\\)\\.\\([0-9]+\\)\\)" 2
- ,@(if (fboundp 'compilation-fake-loc) ;New compile.el.
- '((3 . 6) (4 . 7))
- '(sml-make-error 3 4 6 7))))
- "Alist that specifies how to match errors in compiler output.
-See `compilation-error-regexp-alist' for a description of the format.")
-
-;; font-lock support
-(defconst inferior-sml-font-lock-keywords
- `(;; prompt and following interactive command
- ;; FIXME: Actually, this should already be taken care of by comint.
- (,(concat "\\(" sml-prompt-regexp "\\)\\(.*\\)")
- (1 font-lock-prompt-face)
- (2 font-lock-command-face keep))
- ;; CM's messages
- ("^\\[\\(.*GC #.*\n\\)*.*\\]" . font-lock-comment-face)
- ;; SML/NJ's irritating GC messages
- ("^GC #.*" . font-lock-comment-face)
- ;; error messages
- ,@(unless (fboundp 'compilation-fake-loc)
- (mapcar (lambda (ra) (cons (car ra) 'font-lock-warning-face))
- sml-error-regexp-alist)))
- "Font-locking specification for inferior SML mode.")
-
-(defface font-lock-prompt-face
- '((t (:bold t)))
- "Font Lock mode face used to highlight prompts."
- :group 'font-lock-highlighting-faces)
-(defvar font-lock-prompt-face 'font-lock-prompt-face
- "Face name to use for prompts.")
-
-(defface font-lock-command-face
- '((t (:bold t)))
- "Font Lock mode face used to highlight interactive commands."
- :group 'font-lock-highlighting-faces)
-(defvar font-lock-command-face 'font-lock-command-face
- "Face name to use for interactive commands.")
-
-(defconst inferior-sml-font-lock-defaults
- '(inferior-sml-font-lock-keywords nil nil nil nil))
-
-
-;;; CODE
-
-(defvar inferior-sml-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map comint-mode-map)
- (define-key map "\C-c\C-s" 'run-sml)
- (define-key map "\C-c\C-l" 'sml-load-file)
- (define-key map "\t"
- (if (fboundp 'completion-at-point)
- 'completion-at-point 'comint-dynamic-complete))
- map)
- "Keymap for inferior-sml mode")
-
-;; buffer-local
-
-(defvar sml-temp-file nil)
-;;(defvar sml-error-file nil) ; file from which the last error came
-(defvar sml-error-cursor nil) ; ditto
-
-(defun sml-proc-buffer ()
- "Return the current ML process buffer.
-or the current buffer if it is in `inferior-sml-mode'. Raises an error
-if the variable `sml-buffer' does not appear to point to an existing
-buffer."
- (or (and (eq major-mode 'inferior-sml-mode) (current-buffer))
- (and sml-buffer
- (let ((buf (get-buffer sml-buffer)))
- ;; buffer-name returns nil if the buffer has been killed
- (and buf (buffer-name buf) buf)))
- ;; no buffer found, make a new one
- (save-excursion (call-interactively 'run-sml))))
-
-(defun sml-buffer (echo)
- "Make the current buffer the current `sml-buffer' if that is sensible.
-Lookup variable `sml-buffer' to see why this might be useful.
-If prefix argument ECHO is set, then it only reports on the current state."
- (interactive "P")
- (when (not echo)
- (setq sml-buffer
- (if (eq major-mode 'inferior-sml-mode) (current-buffer)
- (read-buffer "Set ML process buffer to: " nil t))))
- (message "ML process buffer is now %s."
- (or (ignore-errors (buffer-name (get-buffer sml-buffer)))
- "undefined")))
-
-(defun sml-proc ()
- "Return the current ML process. See variable `sml-buffer'."
- (assert (eq major-mode 'inferior-sml-mode))
- (or (get-buffer-process (current-buffer))
- (progn (call-interactively 'run-sml)
- (get-buffer-process (current-buffer)))))
-
-(defun sml-proc-comint-input-filter-function (str)
- ;; `compile.el' in Emacs-22 fails to notice that file location info from
- ;; errors should be recomputed afresh (without using stale info from
- ;; earlier compilations). We used to cause a refresh in sml-send-string,
- ;; but this doesn't catch the case when the user types commands directly
- ;; at the prompt.
- (compilation-forget-errors) ;Has to run before compilation-fake-loc.
- (if (and (fboundp 'compilation-fake-loc) sml-temp-file)
- (compilation-fake-loc (cdr sml-temp-file) (car sml-temp-file)))
- str)
-
-(defun inferior-sml-next-error-hook ()
- ;; Try to recognize SML/NJ type error message and to highlight finely the
- ;; difference between the two types (in case they're large, it's not
- ;; always obvious to spot it).
- ;;
- ;; Sample messages:
- ;;
- ;; Data.sml:31.9-33.33 Error: right-hand-side of clause doesn't agree with function result type [tycon mismatch]
- ;; expression: Hstring
- ;; result type: Hstring * int
- ;; in declaration:
- ;; des2hs = (fn SYM_ID hs => hs
- ;; | SYM_OP hs => hs
- ;; | SYM_CHR hs => hs)
- ;; Data.sml:35.44-35.63 Error: operator and operand don't agree [tycon mismatch]
- ;; operator domain: Hstring * Hstring
- ;; operand: (Hstring * int) * (Hstring * int)
- ;; in expression:
- ;; HSTRING.ieq (h1,h2)
- ;; vparse.sml:1861.6-1922.14 Error: case object and rules don't agree [tycon mismatch]
- ;; rule domain: STConstraints list list option
- ;; object: STConstraints list option
- ;; in expression:
- (save-current-buffer
- (when (and (derived-mode-p 'sml-mode 'inferior-sml-mode)
- (boundp 'next-error-last-buffer)
- (bufferp next-error-last-buffer)
- (set-buffer next-error-last-buffer)
- (derived-mode-p 'inferior-sml-mode)
- ;; The position of `point' is not guaranteed :-(
- (looking-at (concat ".*\\[tycon mismatch\\]\n"
- " \\(operator domain\\|expression\\|rule domain\\): +")))
- (ignore-errors (require 'smerge-mode))
- (if (not (fboundp 'smerge-refine-subst))
- (remove-hook 'next-error-hook 'inferior-sml-next-error-hook)
- (save-excursion
- (let ((b1 (match-end 0))
- e1 b2 e2)
- (when (re-search-forward "\n in \\(expression\\|declaration\\):\n"
- nil t)
- (setq e2 (match-beginning 0))
- (when (re-search-backward
- "\n \\(operand\\|result type\\|object\\): +"
- b1 t)
- (setq e1 (match-beginning 0))
- (setq b2 (match-end 0))
- (smerge-refine-subst b1 e1 b2 e2
- '((face . smerge-refined-change)))))))))))
-
-(define-derived-mode inferior-sml-mode comint-mode "Inferior-SML"
- "Major mode for interacting with an inferior ML process.
-
-The following commands are available:
-\\{inferior-sml-mode-map}
-
-An ML process can be fired up (again) with \\[sml].
-
-Customisation: Entry to this mode runs the hooks on `comint-mode-hook'
-and `inferior-sml-mode-hook' (in that order).
-
-Variables controlling behaviour of this mode are
-
-`sml-program-name' (default \"sml\")
- Program to run as ML.
-
-`sml-use-command' (default \"use \\\"%s\\\"\")
- Template for loading a file into the inferior ML process.
-
-`sml-cd-command' (default \"System.Directory.cd \\\"%s\\\"\")
- ML command for changing directories in ML process (if possible).
-
-`sml-prompt-regexp' (default \"^[\\-=] *\")
- Regexp used to recognise prompts in the inferior ML process.
-
-You can send text to the inferior ML process from other buffers containing
-ML source.
- `switch-to-sml' switches the current buffer to the ML process buffer.
- `sml-send-function' sends the current *paragraph* to the ML process.
- `sml-send-region' sends the current region to the ML process.
-
- Prefixing the sml-send-<whatever> commands with \\[universal-argument]
- causes a switch to the ML process buffer after sending the text.
-
-For information on running multiple processes in multiple buffers, see
-documentation for variable `sml-buffer'.
-
-Commands:
-RET after the end of the process' output sends the text from the
- end of process to point.
-RET before the end of the process' output copies the current line
- to the end of the process' output, and sends it.
-DEL converts tabs to spaces as it moves back.
-TAB file name completion, as in shell-mode, etc.."
- (setq comint-prompt-regexp sml-prompt-regexp)
- (sml-mode-variables)
-
- ;; We have to install it globally, 'cause it's run in the *source* buffer :-(
- (add-hook 'next-error-hook 'inferior-sml-next-error-hook)
-
- ;; Make TAB add a " rather than a space at the end of a file name.
- (set (make-local-variable 'comint-completion-addsuffix) '(?/ . ?\"))
- (add-hook 'comint-input-filter-functions
- 'sml-proc-comint-input-filter-function nil t)
-
- (set (make-local-variable 'font-lock-defaults)
- inferior-sml-font-lock-defaults)
- ;; For sequencing through error messages:
- (set (make-local-variable 'sml-error-cursor) (point-max-marker))
- (set-marker-insertion-type sml-error-cursor nil)
-
- ;; Compilation support (used for `next-error').
- ;; The keymap of compilation-minor-mode is too unbearable, so we
- ;; just can't use the minor-mode if we can't override the map.
- (when (boundp 'minor-mode-overriding-map-alist)
- (set (make-local-variable 'compilation-error-regexp-alist)
- sml-error-regexp-alist)
- (compilation-minor-mode 1)
- ;; Eliminate compilation-minor-mode's map.
- (let ((map (make-sparse-keymap)))
- (dolist (keys '([menu-bar] [follow-link]))
- ;; Preserve some of the bindings.
- (define-key map keys (lookup-key compilation-minor-mode-map keys)))
- (add-to-list 'minor-mode-overriding-map-alist
- (cons 'compilation-minor-mode map)))
- ;; I'm sure people might kill me for that
- (setq compilation-error-screen-columns nil)
- (make-local-variable 'sml-endof-error-alist))
- ;;(make-local-variable 'sml-error-overlay)
-
- (setq mode-line-process '(": %s")))
-
-;;; FOR RUNNING ML FROM EMACS
-
-;;;###autoload
-(autoload 'run-sml "sml-proc" nil t)
-(defalias 'run-sml 'sml-run)
-(defun sml-run (cmd arg &optional host)
- "Run the program CMD with given arguments ARG.
-The command is run in buffer *CMD* using mode `inferior-sml-mode'.
-If the buffer already exists and has a running process, then
-just go to this buffer.
-
-This updates `sml-buffer' to the new buffer.
-You can have several inferior M(or L process running, but only one (> s
-current one -- given by `sml-buffer' (qv).
-
-If a prefix argument is used, the user is also prompted for a HOST
-on which to run CMD using `remote-shell-program'.
-
-\(Type \\[describe-mode] in the process buffer for a list of commands.)"
- (interactive
- (list
- (read-string "ML command: " sml-program-name)
- (if (or current-prefix-arg (> (length sml-default-arg) 0))
- (read-string "Any args: " sml-default-arg)
- sml-default-arg)
- (if (or current-prefix-arg (> (length sml-host-name) 0))
- (read-string "On host: " sml-host-name)
- sml-host-name)))
- (let* ((pname (file-name-nondirectory cmd))
- (args (if (equal arg "") () (split-string arg)))
- (file (when (and sml-config-file (file-exists-p sml-config-file))
- sml-config-file)))
- ;; and this -- to keep these as defaults even if
- ;; they're set in the mode hooks.
- (setq sml-program-name cmd)
- (setq sml-default-arg arg)
- (setq sml-host-name host)
- ;; For remote execution, use `remote-shell-program'
- (when (> (length host) 0)
- (setq args (list* host "cd" default-directory ";" cmd args))
- (setq cmd remote-shell-program))
- ;; go for it
- (let ((exec-path (if (file-name-directory cmd)
- ;; If the command has slashes, make sure we
- ;; first look relative to the current directory.
- ;; Emacs-21 does it for us, but not Emacs-20.
- (cons default-directory exec-path) exec-path)))
- (setq sml-buffer (apply 'make-comint pname cmd file args)))
-
- (pop-to-buffer sml-buffer)
- ;;(message (format "Starting \"%s\" in background." pname))
- (inferior-sml-mode)
- (goto-char (point-max))
- sml-buffer))
-
-(defun switch-to-sml (eobp)
- "Switch to the ML process buffer.
-Move point to the end of buffer unless prefix argument EOBP is set."
- (interactive "P")
- (pop-to-buffer (sml-proc-buffer))
- (unless eobp
- (push-mark (point) t)
- (goto-char (point-max))))
-
-;; Fakes it with a "use <temp-file>;" if necessary.
-
-(defun sml-send-region (start end &optional and-go)
- "Send current region START..END to the inferior ML process.
-Prefix AND-GO argument means switch-to-sml afterwards.
-
-The region is written out to a temporary file and a \"use <temp-file>\" command
-is sent to the compiler.
-See variables `sml-use-command'."
- (interactive "r\nP")
- (if (= start end)
- (message "The region is zero (ignored)")
- (let* ((buf (sml-proc-buffer))
- (marker (copy-marker start))
- (tmp (make-temp-file "sml")))
- (write-region start end tmp nil 'silently)
- (with-current-buffer buf
- (when sml-temp-file
- (ignore-errors (delete-file (car sml-temp-file)))
- (set-marker (cdr sml-temp-file) nil))
- (setq sml-temp-file (cons tmp marker))
- (sml-send-string (format sml-use-command tmp) nil and-go)))))
-
-;; This is quite bogus, so it isn't bound to a key by default.
-;; Anyone coming up with an algorithm to recognise fun & local
-;; declarations surrounding point will do everyone a favour!
-
-(defun sml-send-function (&optional and-go)
- "Send current paragraph to the inferior ML process.
-With a prefix argument AND-GO switch to the sml buffer as well
-\(cf. `sml-send-region'\)."
- (interactive "P")
- (save-excursion
- (sml-mark-function)
- (sml-send-region (point) (mark)))
- (if and-go (switch-to-sml nil)))
-
-(defvar sml-source-modes '(sml-mode)
- "*Used to determine if a buffer contains ML source code.
-If it's loaded into a buffer that is in one of these major modes, it's
-considered an ML source file by `sml-load-file'. Used by these commands
-to determine defaults.")
-
-(defun sml-send-buffer (&optional and-go)
- "Send buffer to inferior shell running ML process.
-With a prefix argument AND-GO switch to the sml buffer as well
-\(cf. `sml-send-region'\)."
- (interactive "P")
- (if (memq major-mode sml-source-modes)
- (sml-send-region (point-min) (point-max) and-go)))
-
-;; Since sml-send-function/region take an optional prefix arg, these
-;; commands are redundant. But they are kept around for the user to
-;; bind if she wishes, since its easier to type C-c r than C-u C-c C-r.
-
-(defun sml-send-region-and-go (start end)
- "Send current region START..END to the inferior ML process, and go there."
- (interactive "r")
- (sml-send-region start end t))
-
-(defun sml-send-function-and-go ()
- "Send current paragraph to the inferior ML process, and go there."
- (interactive)
- (sml-send-function t))
-
-;;; LOADING AND IMPORTING SOURCE FILES:
-
-(defvar sml-prev-dir/file nil
- "Cache for (DIRECTORY . FILE) pair last.
-Set in `sml-load-file' and `sml-cd' commands.
-Used to determine the default in the next `ml-load-file'.")
-
-(defun sml-load-file (&optional and-go)
- "Load an ML file into the current inferior ML process.
-With a prefix argument AND-GO switch to sml buffer as well.
-
-This command uses the ML command template `sml-use-command' to construct
-the command to send to the ML process\; a trailing \"\;\\n\" will be added
-automatically."
- (interactive "P")
- (let ((file (car (comint-get-source
- "Load ML file: " sml-prev-dir/file sml-source-modes t))))
- (with-current-buffer (sml-proc-buffer)
- ;; Check if buffer needs saved. Should (save-some-buffers) instead?
- (comint-check-source file)
- (setq sml-prev-dir/file
- (cons (file-name-directory file) (file-name-nondirectory file)))
- (sml-send-string (format sml-use-command file) nil and-go))))
-
-(defun sml-cd (dir)
- "Change the working directory of the inferior ML process.
-The default directory of the process buffer is changed to DIR. If the
-variable `sml-cd-command' is non-nil it should be an ML command that will
-be executed to change the compiler's working directory\; a trailing
-\"\;\\n\" will be added automatically."
- (interactive "DSML Directory: ")
- (let ((dir (expand-file-name dir)))
- (with-current-buffer (sml-proc-buffer)
- (sml-send-string (format sml-cd-command dir) t)
- (setq default-directory dir))
- (setq sml-prev-dir/file (cons dir nil))))
-
-(defun sml-send-string (str &optional print and-go)
- (let ((proc (sml-proc))
- (str (concat str ";\n"))
- (win (get-buffer-window (current-buffer) 'visible)))
- (when win (select-window win))
- (goto-char (point-max))
- (when print (insert str))
- (sml-update-cursor)
- (set-marker (process-mark proc) (point-max))
- (setq compilation-last-buffer (current-buffer))
- (comint-send-string proc str)
- (when and-go (switch-to-sml nil))))
-
-(defun sml-compile (command &optional and-go)
- "Pass a COMMAND to the SML process to compile the current program.
-
-You can then use the command \\[next-error] to find the next error message
-and move to the source code that caused it.
-
-Interactively, prompts for the command if `compilation-read-command' is
-non-nil. With prefix arg, always prompts.
-
-Prefix arg AND-GO also means to `switch-to-sml' afterwards."
- (interactive
- (let* ((dir default-directory)
- (cmd "cd \"."))
- ;; look for files to determine the default command
- (while (and (stringp dir)
- (dolist (cf sml-compile-commands-alist 1)
- (when (file-exists-p (expand-file-name (cdr cf) dir))
- (setq cmd (concat cmd "\"; " (car cf))) (return nil))))
- (let ((newdir (file-name-directory (directory-file-name dir))))
- (setq dir (unless (equal newdir dir) newdir))
- (setq cmd (concat cmd "/.."))))
- (setq cmd
- (cond
- ((local-variable-p 'sml-compile-command) sml-compile-command)
- ((string-match "^\\s-*cd\\s-+\"\\.\"\\s-*;\\s-*" cmd)
- (substring cmd (match-end 0)))
- ((string-match "^\\s-*cd\\s-+\"\\(\\./\\)" cmd)
- (replace-match "" t t cmd 1))
- ((string-match ";" cmd) cmd)
- (t sml-compile-command)))
- ;; code taken from compile.el
- (if (or compilation-read-command current-prefix-arg)
- (list (read-from-minibuffer "Compile command: "
- cmd nil nil '(compile-history . 1)))
- (list cmd))))
- ;; ;; now look for command's file to determine the directory
- ;; (setq dir default-directory)
- ;; (while (and (stringp dir)
- ;; (dolist (cf sml-compile-commands-alist t)
- ;; (when (and (equal cmd (car cf))
- ;; (file-exists-p (expand-file-name (cdr cf) dir)))
- ;; (return nil))))
- ;; (let ((newdir (file-name-directory (directory-file-name dir))))
- ;; (setq dir (unless (equal newdir dir) newdir))))
- ;; (setq dir (or dir default-directory))
- ;; (list cmd dir)))
- (set (make-local-variable 'sml-compile-command) command)
- (save-some-buffers (not compilation-ask-about-save) nil)
- (let ((dir default-directory))
- (when (string-match "^\\s-*cd\\s-+\"\\([^\"]+\\)\"\\s-*;" command)
- (setq dir (match-string 1 command))
- (setq command (replace-match "" t t command)))
- (setq dir (expand-file-name dir))
- (with-current-buffer (sml-proc-buffer)
- (setq default-directory dir)
- (sml-send-string (concat (format sml-cd-command dir) "; " command)
- t and-go))))
-
-;;; PARSING ERROR MESSAGES
-
-;; This should need no modification to support other compilers.
-
-;; Update the buffer-local error-cursor in proc-buffer to be its
-;; current proc mark.
-
-(defvar sml-endof-error-alist nil)
-
-(defun sml-update-cursor ()
- ;; Update buffer local variable.
- (set-marker sml-error-cursor (1- (process-mark (sml-proc))))
- (setq sml-endof-error-alist nil)
- ;; This is now done in comint-input-filter-functions.
- ;; (compilation-forget-errors) ;Has to run before compilation-fake-loc.
- ;; (if (and (fboundp 'compilation-fake-loc) sml-temp-file)
- ;; (compilation-fake-loc (cdr sml-temp-file) (car sml-temp-file)))
- (if (markerp compilation-parsing-end)
- (set-marker compilation-parsing-end sml-error-cursor)
- (setq compilation-parsing-end sml-error-cursor)))
-
-(defun sml-make-error (f c)
- (let ((err (point-marker))
- (linenum (string-to-number c))
- (filename (list (first f) (second f)))
- (column (string-to-number (match-string (third f)))))
- ;; record the end of error, if any
- (when (fourth f)
- (let ((endlinestr (match-string (fourth f))))
- (when endlinestr
- (let* ((endline (string-to-number endlinestr))
- (endcol (string-to-number
- (or (match-string (fifth f)) "0")))
- (linediff (- endline linenum)))
- (push (list err linediff (if (= 0 linediff) (- endcol column) endcol))
- sml-endof-error-alist)))))
- ;; build the error descriptor
- (if (string= (car sml-temp-file) (first f))
- ;; special case for code sent via sml-send-region
- (let ((marker (cdr sml-temp-file)))
- (with-current-buffer (marker-buffer marker)
- (goto-char marker)
- (forward-line (1- linenum))
- (forward-char (1- column))
- ;; A pair of markers is the right thing to return, but some
- ;; code in compile.el doesn't like it (when we reach the end
- ;; of the errors). So we could try to avoid it, but we don't
- ;; because that doesn't work correctly if the current buffer
- ;; has unsaved modifications. And it's fixed in Emacs-21.
- ;; (if buffer-file-name
- ;; (list err buffer-file-name
- ;; (count-lines (point-min) (point)) (current-column))
- (cons err (point-marker)))) ;; )
- ;; taken from compile.el
- (list err filename linenum column))))
-
-(unless (fboundp 'compilation-fake-loc)
-(defadvice compilation-goto-locus (after sml-endof-error activate)
- (let* ((next-error (ad-get-arg 0))
- (err (car next-error))
- (pos (cdr next-error))
- (endof (with-current-buffer (marker-buffer err)
- (assq err sml-endof-error-alist))))
- (if (not endof) (sml-error-overlay 'undo)
- (with-current-buffer (marker-buffer pos)
- (goto-char pos)
- (let ((linediff (second endof))
- (coldiff (third endof)))
- (when (> 0 linediff) (forward-line linediff))
- (forward-char coldiff))
- (sml-error-overlay nil pos (point))
- (push-mark nil t (not sml-error-overlay))
- (goto-char pos))))))
-
-(defun sml-error-overlay (undo &optional beg end)
- "Move `sml-error-overlay' to the text region in the current buffer.
-If the buffer-local variable `sml-error-overlay' is
-non-nil it should be an overlay \(or extent, in XEmacs speak\)\; this
-function moves the overlay over the current region. If the optional
-BUFFER argument is given, move the overlay in that buffer instead of
-the current buffer.
-
-Called interactively, the optional prefix argument UNDO indicates that
-the overlay should simply be removed: \\[universal-argument] \
-\\[sml-error-overlay]."
- (interactive "P")
- (when sml-error-overlay
- (unless (overlayp sml-error-overlay)
- (let ((ol sml-error-overlay))
- (setq sml-error-overlay (make-overlay (point) (point)))
- (overlay-put sml-error-overlay 'face (if (symbolp ol) ol 'region))))
- (if undo (delete-overlay sml-error-overlay)
- ;; If active regions, signals mark not active if no region set.
- (move-overlay sml-error-overlay
- (or beg (region-beginning)) (or end (region-end))
- (current-buffer)))))
-
-(provide 'sml-proc)
-
-;;; sml-proc.el ends here
diff --git a/emacs/emacs.d/sml-mode-5.0/testcases.sml b/emacs/emacs.d/sml-mode-5.0/testcases.sml
@@ -1,563 +0,0 @@
-(* Copyright 1999,2004,2007,2010-2012 Stefan Monnier <monnier@gnu.org> *)
-
-(* sml-mode here treats the second `=' as an equal op because it
- * thinks it's seeing something like "... type t = (s.t = ...)". FIXME! *)
-functor foo (structure s : S) where type t = s.t =
-struct (* fixindent *)
-val bar = fn a1 a2 a3
- a5 a6
- a4 => 1
-val rec bar =
- fn a1 a2 a3
- a5 a6 a4 => 1
-val bar =
- fn a1 a2 a3
- a5 a6
- a4 => (1
- ;(
- w
- ,
- s
- ,
- s
- , s , a ,
- a
- , s , a ,
- a
- )
- ;(
- w
- ,s
- ,a
- )
- ;(
- w
- , s
- , a
- )
- ;( w
- , s
- , a
- )
- ;( w
- ,s
- ,a
- )
- ;3
- + a
- * 4
- + let val x = 3
- in toto
- end
- + if a then
- b
- else
- c
- ;4)
-
-val ber = 1;
-val sdfg = 1
-val tut = fn (x,y) z y e r =>
- body
-val tut = fn (x,y) => fn z y => fn e r =>
- body
-val tut = fn (x,y)
- z
- y e
- r =>
- body
-val tut =
- (let
- local
- val x = 1 in val x = x end
- val a = 1 val b = 2
- local val x = 1 in val x = x end
- local val x = 1 in val x = x end
- local val x = 1 in val x = x end (* fixindent *)
- local val x = 1 in val x = x end
- val c = 3
- in
- let
- val x = 3
- in
- x + a * b
- * c
- end
- end)
-
-val x =
- (* From "Christopher Dutchyn" <cdutchyn@cs.ubc.ca> *)
- (case foo of
- (* This is actually not valid SML anyway. *)
- | BAR => baz
- | BAR => baz)
-
-
-val x =
- (x := 1;
- x := 2;
- (* Testing obedience to user overrides: *)
- x := 3; (* fixindent *)
- case x of
- FOO => 1
- | BAR =>
- 2;
- case x of
- FOO => 1
- | BAR =>
- case y of
- FAR => 2
- | FRA => 3;
- hello);
-
-datatype foobar
- = FooB of int
- | FooA of bool * int
-datatype foo = FOO | BAR of baz
- and baz = BAZ | QUUX of foo
-
-fun toto = if a
- then
- b
- else c
-
-datatype foo = FOO
- | BAR of baz
- and baz = BAZ (* fixindent *)
- | QUUX of foo
- and b = g
-
-datatype foo = datatype M.foo
-val _ = 42 val x = 5
-
-signature S = S' where type foo = int
-val _ = 42
-
-val foo = [
- "blah"
- , let val x = f 42 in g (x,x,44) end
-]
-
-val foo = [
- "blah",
- let val x = f 42 in g (x,x,44) end
-]
-
-val foo =
- [
- "blah",
- let val x = f 42 in g (x,x,44) end
- ]
-
-val foo = [ "blah"
- , let val x = f 42 in g (x,x,44) end
- , foldl (fn ((p,q),s) => g (p,q,Vector.length q) ^ ":" ^ s)
- "" (Beeblebrox.masterCountList mlist2)
- , if null mlist2 then ";" else ""
- ]
-
-fun foo (true::rest) = 1 + 2 * foo rest
- | foo (false::rest)
- = let val _ = 1 in 2 end
- + 2
- * foo rest
-
-val x = if foo then
- 1
- else if bar then
- 2
- else
- 3
-val y = if foo
- then 1
- else if foo
- then 2 (* Could also be indented by a basic offset. *)
- else 3
-
-val yt = 4
-
-val x =
- (if a then b else c;
- case M.find(m,f)
- of SOME(fl, filt) =>
- F.APP(F.VAR fl, OU.filter filt vs)
- | NONE
- => le
- | NONE =>
- le
- | NONE => le;
- x := x + 1;
- (case foo
- of a => f
- ))
-
-val y = (
- let fun f1 =
- let fun g1 x = 2
- fun g2 y = 4
- local fun toto y = 1
- (* val x = 5 *)
- in
- fun g3 z = z
- end
- in toto
- end
- in a;( ( let
- val f =1
- in
- toto
- end
- )
- )
- foo("(*")
- * 2;
- end;
-
- let
- in a
- ; b
- end;
-
- let
- in
- a +
- b +
- c
- ; b
- end;
-
- let
- in if a then
- b
- else
- c
- end;
-
- let
- in case a of
- F => 1
- | D => 2
- end;
-
- let
- in case a
- of F => 1
- | D => 2
- end;
-
- let
- in if a then b else
- c
- end;
-
- let
- in if a then b
- else
- c
- end)
-end;
-
-structure Foo = struct
-val x = 1
-end
-
-structure Foo = struct val x = 1
- end
-
-signature FSPLIT =
-sig
- type flint = FLINT.prog
- val split: flint -> flint * flint option
-end
-
-structure FSplit :> FSPLIT =
-struct
-
-local
- structure F = FLINT
- structure S = IntRedBlackSet
- structure M = FLINTIntMap
- structure O = Option
- structure OU = OptUtils
- structure FU = FlintUtil
- structure LT = LtyExtern
- structure PO = PrimOp
- structure PP = PPFlint
- structure CTRL = FLINT_Control
-in
-
-val say = Control_Print.say
-fun bug msg = ErrorMsg.impossible ("FSplit: "^msg)
-fun buglexp (msg,le) = (say "\n"; PP.printLexp le; say " "; bug msg)
-fun bugval (msg,v) = (say "\n"; PP.printSval v; say " "; bug msg)
-fun assert p = if p then () else bug ("assertion failed")
-
-type flint = F.prog
-val mklv = LambdaVar.mkLvar
-val cplv = LambdaVar.dupLvar
-
-fun S_rmv(x, s) = S.delete(s, x) handle NotFound => s
-
-fun addv (s,F.VAR lv) = S.add(s, lv)
- | addv (s,_) = s
-fun addvs (s,vs) = foldl (fn (v,s) => addv(s, v)) s vs
-fun rmvs (s,lvs) = foldl (fn (l,s) => S_rmv(l, s)) s lvs
-
-exception Unknown
-
-fun split (fdec as (fk,f,args,body)) = let
- val {getLty,addLty,...} = Recover.recover (fdec, false)
-
- val m = Intmap.new(64, Unknown)
- fun addpurefun f = Intmap.add m (f, false)
- fun funeffect f = (Intmap.map m f) handle Uknown => true
-
-(* sexp: env -> lexp -> (leE, leI, fvI, leRet)
- * - env: IntSetF.set current environment
- * - lexp: lexp expression to split
- * - leRet: lexp the core return expression of lexp
- * - leE: lexp -> lexp recursively split lexp: leE leRet == lexp
- * - leI: lexp option inlinable part of lexp (if any)
- * - fvI: IntSetF.set free variables of leI: FU.freevars leI == fvI
- *
- * sexp splits the lexp into an expansive part and an inlinable part.
- * The inlinable part is guaranteed to be side-effect free.
- * The expansive part doesn't bother to eliminate unused copies of
- * elements copied to the inlinable part.
- * If the inlinable part cannot be constructed, leI is set to F.RET[].
- * This implies that fvI == S.empty, which in turn prevents us from
- * mistakenly adding anything to leI.
- *)
-fun sexp env lexp = (* fixindent *)
- let
- (* non-side effecting binds are copied to leI if exported *)
- fun let1 (le,lewrap,lv,vs,effect) =
- let val (leE,leI,fvI,leRet) = sexp (S.add(env, lv)) le
- val leE = lewrap o leE
- in if effect orelse not (S.member(fvI, lv))
- then (leE, leI, fvI, leRet)
- else (leE, lewrap leI, addvs(S_rmv(lv, fvI), vs), leRet)
- end
-
- in case lexp
- (* we can completely move both RET and TAPP to the I part *)
- of F.RECORD (rk,vs,lv,le as F.RET [F.VAR lv']) =>
- if lv' = lv
- then (fn e => e, lexp, addvs(S.empty, vs), lexp)
- else (fn e => e, le, S.singleton lv', le)
- | F.RET vs =>
- (fn e => e, lexp, addvs(S.empty, vs), lexp)
- | F.TAPP (F.VAR tf,tycs) =>
- (fn e => e, lexp, S.singleton tf, lexp)
-
- (* recursive splittable lexps *)
- | F.FIX (fdecs,le) => sfix env (fdecs, le)
- | F.TFN (tfdec,le) => stfn env (tfdec, le)
-
- (* binding-lexps *)
- | F.CON (dc,tycs,v,lv,le) =>
- let1(le, fn e => F.CON(dc, tycs, v, lv, e), lv, [v], false)
- | F.RECORD (rk,vs,lv,le) =>
- let1(le, fn e => F.RECORD(rk, vs, lv, e), lv, vs, false)
- | F.SELECT (v,i,lv,le) =>
- let1(le, fn e => F.SELECT(v, i, lv, e), lv, [v], false)
- | F.PRIMOP (po,vs,lv,le) =>
- let1(le, fn e => F.PRIMOP(po, vs, lv, e), lv, vs, PO.effect(#2 po))
-
- (* IMPROVEME: lvs should not be restricted to [lv] *)
- | F.LET(lvs as [lv],body as F.TAPP (v,tycs),le) =>
- let1(le, fn e => F.LET(lvs, body, e), lv, [v], false)
- | F.LET (lvs as [lv],body as F.APP (v as F.VAR f,vs),le) =>
- let1(le, fn e => F.LET(lvs, body, e), lv, v::vs, funeffect f)
-
- | F.SWITCH (v,ac,[(dc as F.DATAcon(_,_,lv),le)],NONE) =>
- let1(le, fn e => F.SWITCH(v, ac, [(dc, e)], NONE), lv, [v], false)
-
- | F.LET (lvs,body,le) =>
- let val (leE,leI,fvI,leRet) = sexp (S.union(S.addList(S.empty, lvs), env)) le
- in (fn e => F.LET(lvs, body, leE e), leI, fvI, leRet)
- end
-
- (* useless sophistication *)
- | F.APP (F.VAR f,args) =>
- if funeffect f
- then (fn e => e, F.RET[], S.empty, lexp)
- else (fn e => e, lexp, addvs(S.singleton f, args), lexp)
-
- (* other non-binding lexps result in unsplittable functions *)
- | (F.APP _ | F.TAPP _) => bug "strange (T)APP"
- | (F.SWITCH _ | F.RAISE _ | F.BRANCH _ | F.HANDLE _) =>
- (fn e => e, F.RET[], S.empty, lexp)
- end
-
-(* Functions definitions fall into the following categories:
- * - inlinable: if exported, copy to leI
- * - (mutually) recursive: don't bother
- * - non-inlinable non-recursive: split recursively *)
-and sfix env (fdecs,le) =
- let val nenv = S.union(S.addList(S.empty, map #2 fdecs), env)
- val (leE,leI,fvI,leRet) = sexp nenv le
- val nleE = fn e => F.FIX(fdecs, leE e)
- in case fdecs
- of [({inline=inl as (F.IH_ALWAYS | F.IH_MAYBE _),...},f,args,body)] =>
- let val min = case inl of F.IH_MAYBE(n,_) => n | _ => 0
- in if not(S.member(fvI, f)) orelse min > !CTRL.splitThreshold
- then (nleE, leI, fvI, leRet)
- else (nleE, F.FIX(fdecs, leI),
- rmvs(S.union(fvI, FU.freevars body),
- f::(map #1 args)),
- leRet)
- end
- | [fdec as (fk as {cconv=F.CC_FCT,...},_,_,_)] =>
- sfdec env (leE,leI,fvI,leRet) fdec
-
- | _ => (nleE, leI, fvI, leRet)
- end
-
-and sfdec env (leE,leI,fvI,leRet) (fk,f,args,body) =
- let val benv = S.union(S.addList(S.empty, map #1 args), env)
- val (bodyE,bodyI,fvbI,bodyRet) = sexp benv body
- in case bodyI
- of F.RET[] =>
- (fn e => F.FIX([(fk, f, args, bodyE bodyRet)], e),
- leI, fvI, leRet)
- | _ =>
- let val fvbIs = S.listItems(S.difference(fvbI, benv))
- val (nfk,fkE) = OU.fk_wrap(fk, NONE)
-
- (* fdecE *)
- val fE = cplv f
- val fErets = (map F.VAR fvbIs)
- val bodyE = bodyE(F.RET fErets)
- (* val tmp = mklv()
- val bodyE = bodyE(F.RECORD(F.RK_STRUCT, map F.VAR fvbIs,
- tmp, F.RET[F.VAR tmp])) *)
- val fdecE = (fkE, fE, args, bodyE)
- val fElty = LT.ltc_fct(map #2 args, map getLty fErets)
- val _ = addLty(fE, fElty)
-
- (* fdecI *)
- val fkI = {inline=F.IH_ALWAYS, cconv=F.CC_FCT,
- known=true, isrec=NONE}
- val argsI =
- (map (fn lv => (lv, getLty(F.VAR lv))) fvbIs) @ args
- val fdecI as (_,fI,_,_) = FU.copyfdec(fkI,f,argsI,bodyI)
- val _ = addpurefun fI
-
- (* nfdec *)
- val nargs = map (fn (v,t) => (cplv v, t)) args
- val argsv = map (fn (v,t) => F.VAR v) nargs
- val nbody =
- let val lvs = map cplv fvbIs
- in F.LET(lvs, F.APP(F.VAR fE, argsv),
- F.APP(F.VAR fI, (map F.VAR lvs)@argsv))
- end
- (* let val lv = mklv()
- in F.LET([lv], F.APP(F.VAR fE, argsv),
- F.APP(F.VAR fI, (F.VAR lv)::argsv))
- end *)
- val nfdec = (nfk, f, nargs, nbody)
-
- (* and now, for the whole F.FIX *)
- fun nleE e =
- F.FIX([fdecE], F.FIX([fdecI], F.FIX([nfdec], leE e)))
-
- in if not(S.member(fvI, f)) then (nleE, leI, fvI, leRet)
- else (nleE,
- F.FIX([fdecI], F.FIX([nfdec], leI)),
- S.add(S.union(S_rmv(f, fvI), S.intersection(env, fvbI)), fE),
- leRet)
- end
- end
-
-(* TFNs are kinda like FIX except there's no recursion *)
-and stfn env (tfdec as (tfk,tf,args,body),le) =
- let val (bodyE,bodyI,fvbI,bodyRet) =
- if #inline tfk = F.IH_ALWAYS
- then (fn e => body, body, FU.freevars body, body)
- else sexp env body
- val nenv = S.add(env, tf)
- val (leE,leI,fvI,leRet) = sexp nenv le
- in case (bodyI, S.listItems(S.difference(fvbI, env)))
- of ((F.RET _ | F.RECORD(_,_,_,F.RET _)),_) =>
- (* split failed *)
- (fn e => F.TFN((tfk, tf, args, bodyE bodyRet), leE e),
- leI, fvI, leRet)
- | (_,[]) =>
- (* everything was split out *)
- let val ntfdec = ({inline=F.IH_ALWAYS}, tf, args, bodyE bodyRet)
- val nlE = fn e => F.TFN(ntfdec, leE e)
- in if not(S.member(fvI, tf)) then (nlE, leI, fvI, leRet)
- else (nlE, F.TFN(ntfdec, leI),
- S_rmv(tf, S.union(fvI, fvbI)), leRet)
- end
- | (_,fvbIs) =>
- let (* tfdecE *)
- val tfE = cplv tf
- val tfEvs = map F.VAR fvbIs
- val bodyE = bodyE(F.RET tfEvs)
- val tfElty = LT.lt_nvpoly(args, map getLty tfEvs)
- val _ = addLty(tfE, tfElty)
-
- (* tfdecI *)
- val tfkI = {inline=F.IH_ALWAYS}
- val argsI = map (fn (v,k) => (cplv v, k)) args
- (* val tmap = ListPair.map (fn (a1,a2) =>
- * (#1 a1, LT.tcc_nvar(#1 a2)))
- * (args, argsI) *)
- val bodyI = FU.copy tmap M.empty
- (F.LET(fvbIs, F.TAPP(F.VAR tfE, map #2 tmap),
- bodyI))
- (* F.TFN *)
- fun nleE e =
- F.TFN((tfk, tfE, args, bodyE),
- F.TFN((tfkI, tf, argsI, bodyI), leE e))
-
- in if not(S.member(fvI, tf)) then (nleE, leI, fvI, leRet)
- else (nleE,
- F.TFN((tfkI, tf, argsI, bodyI), leI),
- S.add(S.union(S_rmv(tf, fvI), S.intersection(env, fvbI)), tfE),
- leRet)
- end
- end
-
-(* here, we use B-decomposition, so the args should not be
- * considered as being in scope *)
-val (bodyE,bodyI,fvbI,bodyRet) = sexp S.empty body
-in case (bodyI, bodyRet)
- of (F.RET _,_) => ((fk, f, args, bodyE bodyRet), NONE)
- | (_,F.RECORD (rk,vs,lv,F.RET[lv'])) =>
- let val fvbIs = S.listItems fvbI
-
- (* fdecE *)
- val bodyE = bodyE(F.RECORD(rk, vs@(map F.VAR fvbIs), lv, F.RET[lv']))
- val fdecE as (_,fE,_,_) = (fk, cplv f, args, bodyE)
-
- (* fdecI *)
- val argI = mklv()
- val argLtys = (map getLty vs) @ (map (getLty o F.VAR) fvbIs)
- val argsI = [(argI, LT.ltc_str argLtys)]
- val (_,bodyI) = foldl (fn (lv,(n,le)) =>
- (n+1, F.SELECT(F.VAR argI, n, lv, le)))
- (length vs, bodyI) fvbIs
- val fdecI as (_,fI,_,_) = FU.copyfdec (fk, f, argsI, bodyI)
-
- val nargs = map (fn (v,t) => (cplv v, t)) args
- in
- (fdecE, SOME fdecI)
- (* ((fk, f, nargs,
- F.FIX([fdecE],
- F.FIX([fdecI],
- F.LET([argI],
- F.APP(F.VAR fE, map (F.VAR o #1) nargs),
- F.APP(F.VAR fI, [F.VAR argI]))))),
- NONE) *)
- end
-
- | _ => (fdec, NONE) (* sorry, can't do that *)
-(* (PPFlint.printLexp bodyRet; bug "couldn't find the returned record") *)
-
-end
-
-end
-end