commit dea864b68d8190a846691f2a7d986e695415ffd9
parent 48b51497af322ccfdaa9d90a4db7c70b03b073b2
Author: Alex Balgavy <a.balgavy@gmail.com>
Date: Wed, 9 Oct 2019 01:27:24 -0400
emacs: because it supports SML
Former-commit-id: c2fb88ef303f7b08c4402b7aa2675e4d979f6105
Diffstat:
19 files changed, 8065 insertions(+), 0 deletions(-)
diff --git a/emacs/emacs b/emacs/emacs
@@ -0,0 +1,56 @@
+;; SML mode
+(setq load-path (cons "/Users/alex/.emacs.d/sml-mode-5.0" load-path))
+(load "sml-mode-startup")
+(setenv "PATH" (concat "/usr/local/smlnj-110.73/bin:" (getenv "PATH")))
+(setq exec-path (cons "/usr/local/smlnj-110.73/bin" exec-path))
+
+;; Set the shell
+(setq-default explicit-shell-file-name "/bin/bash")
+
+;; Set themes
+(add-to-list 'custom-theme-load-path "~/.emacs.d/themes")
+(load-theme 'cyberpunk t)
+
+;; Let me press 'y'/'n' to answer yes-or-no questions
+(fset 'yes-or-no-p 'y-or-n-p)
+
+;; Show matching parens
+(show-paren-mode 1)
+
+;; Fuzzy file matching
+(setq ido-enable-flex-matching t)
+(setq ido-everywhere t)
+(ido-mode 1)
+
+;; Keep all backup files in ~/.emacs.d/backup
+(setq backup-directory-alist
+ `(("." . ,(concat user-emacs-directory "backup/")))
+ tramp-backup-directory-alist backup-directory-alist)
+
+;; Some version control for backups
+(custom-set-variables
+ '(version-control t))
+
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(ansi-color-names-vector
+ ["#242424" "#e5786d" "#95e454" "#cae682" "#8ac6f2" "#333366" "#ccaa8f" "#f6f3e8"])
+ '(blink-cursor-mode t)
+ '(blink-matching-paren t)
+ '(custom-safe-themes
+ (quote
+ ("1a232652b04b68380b1cff7ceeb62787b4eb43df826a97c67831c50b0c0d1451" "3fd57a3dc99eb0e2ec438555cf801572f649c79513d3a8da7980ab54cf66121b" default)))
+ '(xterm-mouse-mode t))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(menu ((t (:background "red" :inverse-video nil :slant italic))))
+ '(tty-menu-disabled-face ((t (:background "color-238" :foreground "color-16"))))
+ '(tty-menu-enabled-face ((t (:background "red" :foreground "white" :weight bold))))
+ '(tty-menu-selected-face ((t (:background "magenta" :foreground "white")))))
+
diff --git a/emacs/emacs.d/sml-mode-5.0/BUGS b/emacs/emacs.d/sml-mode-5.0/BUGS
@@ -0,0 +1,11 @@
+-*- 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
@@ -0,0 +1,573 @@
+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
@@ -0,0 +1,39 @@
+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
@@ -0,0 +1,176 @@
+# 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
@@ -0,0 +1,137 @@
+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
@@ -0,0 +1,19 @@
+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
@@ -0,0 +1,46 @@
+* 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
@@ -0,0 +1,15 @@
+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
@@ -0,0 +1,59 @@
+;;; 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
@@ -0,0 +1,1436 @@
+;;; 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
@@ -0,0 +1,908 @@
+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
@@ -0,0 +1,67 @@
+%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
@@ -0,0 +1,1161 @@
+\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
@@ -0,0 +1,713 @@
+;;; 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
@@ -0,0 +1,784 @@
+;;; 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
@@ -0,0 +1,563 @@
+(* 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
diff --git a/emacs/emacs.d/themes/cyberpunk-theme.el b/emacs/emacs.d/themes/cyberpunk-theme.el
@@ -0,0 +1,844 @@
+;;; cyberpunk-theme.el --- Cyberpunk Color Theme
+
+;; Copyright 2012-2018, Nicholas M. Van Horn
+
+;; Author: Nicholas M. Van Horn <nvanhorn@protonmail.com>
+;; Homepage: https://github.com/n3mo/cyberpunk-theme.el
+;; Keywords: color theme cyberpunk
+;; Version: 1.21
+
+;; 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 2, 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+;;
+
+;; "and he'd still see the matrix in his sleep, bright lattices of logic
+;; unfolding across that colorless void..."
+;; William Gibson, Neuromancer.
+
+;;; Commentary:
+
+;; This theme is a port of Sam Aaron's overtone/emacs-live theme of the
+;; same name (https://github.com/overtone/emacs-live). The original theme
+;; was designed for use with the color-theme package. This theme adopts
+;; the new built-in theme support deftheme. Additionally, this
+;; theme strives to offer as many mode-specific customizations as
+;; possible, with further tweaks that suit my fancy.
+
+(deftheme cyberpunk "The Cyberpunk color theme")
+
+(defcustom cyberpunk-transparent-background nil
+ "Make transparent background in terminal. (Workaround)")
+
+(let ((class '((class color) (min-colors 89)))
+ ;; Cyberpunk palette
+ (cyberpunk-fg "#dcdccc")
+ (cyberpunk-bg-1 "#2b2b2b")
+ (cyberpunk-bg-05 "#383838")
+ (cyberpunk-bg "#000000")
+ (cyberpunk-bg+1 "#4f4f4f")
+ (cyberpunk-bg+2 "#5f5f5f")
+ (cyberpunk-bg+3 "#6f6f6f")
+ (cyberpunk-red+1 "#dca3a3")
+ (cyberpunk-red "#ff0000")
+ (cyberpunk-red-1 "#8b0000")
+ (cyberpunk-red-2 "#8b0000")
+ (cyberpunk-red-3 "#9c6363")
+ (cyberpunk-red-4 "#8c5353")
+ (cyberpunk-red-5 "#7F073F")
+ (cyberpunk-pink "#ff69b4")
+ (cyberpunk-pink-1 "#ff1493")
+ (cyberpunk-pink-2 "#cd1076")
+ (cyberpunk-orange-2 "#FF6400")
+ (cyberpunk-orange-1 "#ff8c00") ;; DarkOrange
+ (cyberpunk-orange "#ffa500")
+ (cyberpunk-yellow "#ffff00")
+ (cyberpunk-yellow-1 "#FBDE2D")
+ (cyberpunk-yellow-2 "#d0bf8f")
+ (cyberpunk-yellow-3 "#D8FA3C")
+ (cyberpunk-yellow-4 "#E9C062")
+ (cyberpunk-yellow-5 "#ffd700")
+ (cyberpunk-green-2 "#006400")
+ (cyberpunk-green-1 "#2e8b57")
+ (cyberpunk-green "#00ff00")
+ (cyberpunk-green+1 "#61CE3C")
+ (cyberpunk-green+2 "#9fc59f")
+ (cyberpunk-green+3 "#afd8af")
+ (cyberpunk-green+4 "#bfebbf")
+ (cyberpunk-cyan "#93e0e3")
+ (cyberpunk-blue+1 "#94bff3")
+ (cyberpunk-blue "#0000ff") ;; blue
+ (cyberpunk-blue-1 "#7b68ee") ;; medium slate blue
+ (cyberpunk-blue-2 "#6a5acd") ;; slate blue
+ (cyberpunk-blue-3 "#add8e6") ;; light blue
+ (cyberpunk-blue-4 "#b2dfee") ;; LightBlue2
+ (cyberpunk-blue-5 "#4c83ff")
+ (cyberpunk-blue-6 "#96CBFE")
+ (cyberpunk-blue-7 "#00ffff")
+ (cyberpunk-blue-8 "#4F94CD")
+ (cyberpunk-magenta "#dc8cc3")
+ (cyberpunk-black (if (and cyberpunk-transparent-background
+ (not (display-graphic-p))
+ (eq system-type 'darwin))
+ "ARGBBB000000"
+ "#000000"))
+ (cyberpunk-black-2 "#0C1021")
+ (cyberpunk-black-3 "#0A0A0A")
+ (cyberpunk-gray "#d3d3d3")
+ (cyberpunk-gray-2 "#8B8989")
+ (cyberpunk-gray-3 "#919191")
+ (cyberpunk-gray-4 "#999999")
+ (cyberpunk-gray-5 "#333333")
+ (cyberpunk-gray-6 "#1A1A1A")
+ (cyberpunk-gray-7 "#4D4D4D")
+ (cyberpunk-gray-8 "#262626")
+ (cyberpunk-white "#ffffff")
+ (cyberpunk-white-2 "#F8F8F8")
+ (cyberpunk-white-3 "#fffafa"))
+
+ (custom-theme-set-faces
+ 'cyberpunk
+ '(button ((t (:underline t))))
+ `(link ((,class (:foreground ,cyberpunk-yellow :underline t :weight bold))))
+ `(link-visited ((,class (:foreground ,cyberpunk-yellow-2 :underline t :weight normal))))
+ `(blue ((,class (:foreground ,cyberpunk-blue))))
+ `(bold ((,class (:bold t))))
+ `(border-glyph ((,class (nil))))
+ `(buffers-tab ((,class (:background ,cyberpunk-black-2 :foreground ,cyberpunk-white-2))))
+
+ ;;; basic coloring
+ `(default ((,class (:foreground ,cyberpunk-gray :background ,cyberpunk-black))))
+ `(cursor ((,class (:background ,cyberpunk-fg))))
+ `(escape-glyph-face ((,class (:foreground ,cyberpunk-red))))
+ `(fringe ((,class (:foreground ,cyberpunk-fg :background ,cyberpunk-bg-1))))
+ `(header-line ((,class (:foreground ,cyberpunk-yellow
+ :background ,cyberpunk-bg-1
+ :box (:line-width -1 :style released-button)))))
+ `(highlight ((,class (:background ,cyberpunk-gray-5))))
+
+ ;;; compilation
+ `(compilation-column-face ((,class (:foreground ,cyberpunk-yellow))))
+ `(compilation-enter-directory-face ((,class (:foreground ,cyberpunk-green))))
+ `(compilation-error-face ((,class (:foreground ,cyberpunk-red-1 :weight bold :underline t))))
+ `(compilation-face ((,class (:foreground ,cyberpunk-fg))))
+ `(compilation-info-face ((,class (:foreground ,cyberpunk-blue))))
+ `(compilation-info ((,class (:foreground ,cyberpunk-green+4 :underline t))))
+ `(compilation-leave-directory-face ((,class (:foreground ,cyberpunk-green))))
+ `(compilation-line-face ((,class (:foreground ,cyberpunk-yellow))))
+ `(compilation-line-number ((,class (:foreground ,cyberpunk-yellow))))
+ `(compilation-message-face ((,class (:foreground ,cyberpunk-blue))))
+ `(compilation-warning-face ((,class (:foreground ,cyberpunk-yellow-1 :weight bold :underline t))))
+
+ ;;; grep
+ `(grep-context-face ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-pink-1))))
+ `(grep-error-face ((,class (:foreground ,cyberpunk-red :weight bold :underline t))))
+ `(grep-hit-face ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-red))))
+ `(grep-match-face ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-pink-1))))
+ `(match ((,class (:background ,cyberpunk-black :foreground ,cyberpunk-pink-1))))
+
+
+ ;;; multiple-cursors
+ `(mc/cursor-face ((,class (:inverse-video nil, :background ,cyberpunk-pink :foreground ,cyberpunk-black))))
+
+ ;; faces used by isearch
+ `(isearch ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-pink-1))))
+ `(isearch-fail ((,class (:background ,cyberpunk-red-1))))
+
+ `(lazy-highlight ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-yellow))))
+ `(query-replace ((,class (:background ,cyberpunk-gray-5))))
+ `(Highline-face ((,class (:background ,cyberpunk-green-1))))
+ `(left-margin ((,class (nil))))
+ `(toolbar ((,class (nil))))
+ `(text-cursor ((,class (:background ,cyberpunk-yellow :foreground ,cyberpunk-black))))
+
+ `(menu ((,class (:foreground ,cyberpunk-fg :background ,cyberpunk-bg))))
+ `(minibuffer-prompt ((,class (:foreground ,cyberpunk-green+1 :background ,cyberpunk-black))))
+ `(mode-line
+ ((,class (:foreground ,cyberpunk-blue-5
+ :background ,cyberpunk-gray-5
+ :box (:line-width -1 :color ,cyberpunk-blue-5)))))
+ ;; `(mode-line-buffer-id ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(mode-line-inactive
+ ((,class (:foreground ,cyberpunk-gray-7
+ :background ,cyberpunk-gray-6
+ :box (:line-width -1 :color ,cyberpunk-blue-5)))))
+ `(region ((,class (:background ,cyberpunk-red-5))))
+ `(secondary-selection ((,class (:background ,cyberpunk-bg+2))))
+ `(trailing-whitespace ((,class (:background ,cyberpunk-red))))
+ `(vertical-border ((,class (:foreground ,cyberpunk-gray-5 :background ,cyberpunk-black))))
+
+ ;;; font lock
+ `(font-lock-builtin-face ((,class (:foreground ,cyberpunk-blue-5))))
+ `(font-lock-comment-face ((,class (:foreground ,cyberpunk-gray-2 :italic t))))
+ ;; `(font-lock-comment-delimiter-face ((,class (:foreground ,cyberpunk-green))))
+ `(font-lock-constant-face ((,class (:foreground ,cyberpunk-blue-6))))
+ ;; `(font-lock-doc-face ((,class (:foreground ,cyberpunk-green+1))))
+ `(font-lock-doc-face ((,class (:foreground ,cyberpunk-yellow-1))))
+ `(font-lock-function-name-face ((,class (:foreground ,cyberpunk-pink-1))))
+ `(font-lock-keyword-face ((,class (:foreground ,cyberpunk-blue-5))))
+ ;; `(font-lock-negation-char-face ((,class (:foreground ,cyberpunk-fg))))
+ `(font-lock-preprocessor-face ((,class (:foreground ,cyberpunk-gray-3))))
+ `(font-lock-string-face ((,class (:foreground ,cyberpunk-green+1))))
+ `(font-lock-type-face ((,class (:foreground ,cyberpunk-green+3))))
+ `(font-lock-variable-name-face ((,class (:foreground ,cyberpunk-pink))))
+ `(font-lock-warning-face ((,class (:foreground ,cyberpunk-pink))))
+ `(font-lock-reference-face ((,class (:foreground ,cyberpunk-gray))))
+ `(font-lock-regexp-grouping-backslash ((,class (:foreground ,cyberpunk-yellow-4))))
+ `(font-lock-regexp-grouping-construct ((,class (:foreground ,cyberpunk-red))))
+
+ `(c-annotation-face ((,class (:inherit font-lock-constant-face))))
+
+ `(gui-element ((,class (:background ,cyberpunk-gray-5 :foreground ,cyberpunk-blue-6))))
+
+ ;;; newsticker
+ ;; These are currently placeholders that probably look terrible.
+ ;; Someone who uses newsticker is welcome to change these
+ `(newsticker-date-face ((,class (:foreground ,cyberpunk-fg))))
+ `(newsticker-default-face ((,class (:foreground ,cyberpunk-fg))))
+ `(newsticker-enclosure-face ((,class (:foreground ,cyberpunk-green+3))))
+ `(newsticker-extra-face ((,class (:foreground ,cyberpunk-bg+2 :height 0.8))))
+ `(newsticker-feed-face ((,class (:foreground ,cyberpunk-fg))))
+ `(newsticker-immortal-item-face ((,class (:foreground ,cyberpunk-green))))
+ `(newsticker-new-item-face ((,class (:foreground ,cyberpunk-blue))))
+ `(newsticker-obsolete-item-face ((,class (:foreground ,cyberpunk-red))))
+ `(newsticker-old-item-face ((,class (:foreground ,cyberpunk-bg+3))))
+ `(newsticker-statistics-face ((,class (:foreground ,cyberpunk-fg))))
+ `(newsticker-treeview-face ((,class (:foreground ,cyberpunk-fg))))
+ `(newsticker-treeview-immortal-face ((,class (:foreground ,cyberpunk-green))))
+ `(newsticker-treeview-listwindow-face ((,class (:foreground ,cyberpunk-fg))))
+ `(newsticker-treeview-new-face ((,class (:foreground ,cyberpunk-blue :weight bold))))
+ `(newsticker-treeview-obsolete-face ((,class (:foreground ,cyberpunk-red))))
+ `(newsticker-treeview-old-face ((,class (:foreground ,cyberpunk-bg+3))))
+ `(newsticker-treeview-selection-face ((,class (:foreground ,cyberpunk-yellow))))
+
+ ;;; external
+
+ ;; full-ack
+ `(ack-separator ((,class (:foreground ,cyberpunk-fg))))
+ `(ack-file ((,class (:foreground ,cyberpunk-blue))))
+ `(ack-line ((,class (:foreground ,cyberpunk-yellow))))
+ `(ack-match ((,class (:foreground ,cyberpunk-orange :background ,cyberpunk-bg-1 :weigth bold))))
+
+ ;; auctex
+ `(font-latex-bold ((,class (:inherit bold))))
+ `(font-latex-warning ((,class (:inherit font-lock-warning))))
+ `(font-latex-sedate ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(font-latex-string ((,class (:foreground ,cyberpunk-green))))
+ `(font-latex-title-4 ((,class (:inherit variable-pitch :weight bold))))
+ `(font-latex-sectioning-0 ((,class (:foreground ,cyberpunk-blue :background ,cyberpunk-black :scale 1.5))))
+ `(font-latex-sectioning-1 ((,class (:foreground ,cyberpunk-blue :background ,cyberpunk-black :scale 1.5))))
+
+ ;; auto-complete
+ `(ac-completion-face ((,class (:background ,cyberpunk-gray-2 :underline t))))
+ `(ac-candidate-face ((,class (:background ,cyberpunk-gray-4 :foreground ,cyberpunk-black))))
+ `(ac-selection-face ((,class (:background ,cyberpunk-pink-1 :foreground ,cyberpunk-black))))
+ `(popup-tip-face ((,class (:background ,cyberpunk-gray-5 :foreground ,cyberpunk-white))))
+ `(popup-scroll-bar-foreground-face ((,class (:background ,cyberpunk-black-3))))
+ `(popup-scroll-bar-background-face ((,class (:background ,cyberpunk-gray-5))))
+ `(popup-isearch-match ((,class (:background ,cyberpunk-black :foreground ,cyberpunk-pink-1))))
+
+ `(window-number-face ((,class (:background ,cyberpunk-gray-6 :foreground ,cyberpunk-blue-5))))
+
+ ;; company-mode
+ `(company-tooltip ((,class (:background ,cyberpunk-gray-2 :foreground ,cyberpunk-yellow))))
+ `(company-tooltip-common ((,class (:inherit company-tooltip :foreground ,cyberpunk-blue))))
+ `(company-tooltip-common-selection ((,class (:inherit company-tooltip-selection :foreground ,cyberpunk-blue))))
+ `(company-tooltip-selection ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-pink-1))))
+ `(company-tooltip-annotation ((,class (:inherit company-tooltip :foreground ,cyberpunk-black-3))))
+ `(company-scrollbar-fg ((,class (:background ,cyberpunk-black-3))))
+ `(company-scrollbar-bg ((,class (:background ,cyberpunk-gray-5))))
+ `(company-preview ((,class (:foreground ,cyberpunk-gray :background ,cyberpunk-pink-1))))
+ `(company-preview-common ((,class (:foreground ,cyberpunk-gray :background ,cyberpunk-pink-1))))
+
+ ;; diff
+ `(diff-added ((,class (:foreground ,cyberpunk-green))))
+ `(diff-changed ((,class (:foreground ,cyberpunk-yellow))))
+ `(diff-removed ((,class (:foreground ,cyberpunk-red))))
+ `(diff-header ((,class (:background ,cyberpunk-bg+2))))
+ `(diff-file-header ((,class (:background ,cyberpunk-bg+2 :foreground ,cyberpunk-fg :bold t))))
+
+ ;; ediff
+ `(ediff-current-diff-Ancestor ((,class (:foreground ,cyberpunk-fg :background ,cyberpunk-pink))))
+ `(ediff-current-diff-A ((,class (:foreground ,cyberpunk-fg :background ,cyberpunk-bg-05))))
+ `(ediff-current-diff-B ((,class (:foreground ,cyberpunk-fg :background ,cyberpunk-bg+1))))
+ `(ediff-current-diff-C ((,class (:foreground ,cyberpunk-fg :background ,cyberpunk-bg+2))))
+ `(ediff-even-diff-Ancestor ((,class (:foreground ,cyberpunk-white :background ,cyberpunk-bg-05))))
+ `(ediff-even-diff-A ((,class (:foreground ,cyberpunk-white :background ,cyberpunk-bg+1))))
+ `(ediff-even-diff-B ((,class (:foreground ,cyberpunk-white :background ,cyberpunk-bg+2))))
+ `(ediff-even-diff-C ((,class (:foreground ,cyberpunk-white :background ,cyberpunk-bg+3))))
+ `(ediff-fine-diff-Ancestor ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-pink))))
+ `(ediff-fine-diff-A ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-blue-5))))
+ `(ediff-fine-diff-B ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-blue-5))))
+ `(ediff-fine-diff-C ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-blue-5))))
+ `(ediff-odd-diff-Ancestor ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-gray-2))))
+ `(ediff-odd-diff-A ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-gray-3))))
+ `(ediff-odd-diff-B ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-gray-4))))
+ `(ediff-odd-diff-C ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-gray))))
+
+ ;; ert
+ `(ert-test-result-expected ((,class (:foreground ,cyberpunk-green+4 :background ,cyberpunk-bg))))
+ `(ert-test-result-unexpected ((,class (:foreground ,cyberpunk-red :background ,cyberpunk-bg))))
+
+ ;; eshell
+ `(eshell-prompt ((,class (:foreground ,cyberpunk-blue-5 :weight bold))))
+ `(eshell-ls-archive ((,class (:foreground ,cyberpunk-magenta :weight bold))))
+ `(eshell-ls-backup ((,class (:inherit font-lock-comment))))
+ `(eshell-ls-clutter ((,class (:inherit font-lock-comment))))
+ `(eshell-ls-directory ((,class (:foreground ,cyberpunk-blue+1 :weight bold))))
+ `(eshell-ls-executable ((,class (:foreground ,cyberpunk-red+1 :weight bold))))
+ `(eshell-ls-unreadable ((,class (:foreground ,cyberpunk-fg))))
+ `(eshell-ls-missing ((,class (:inherit font-lock-warning))))
+ `(eshell-ls-product ((,class (:inherit font-lock-doc))))
+ `(eshell-ls-special ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(eshell-ls-symlink ((,class (:foreground ,cyberpunk-cyan :weight bold))))
+
+ ;; flymake
+ `(flymake-errline ((,class (:foreground ,cyberpunk-red-1 :weight bold :underline t))))
+ `(flymake-warnline ((,class (:foreground ,cyberpunk-yellow-1 :weight bold :underline t))))
+
+ ;; flyspell
+ `(flyspell-duplicate ((,class (:foreground ,cyberpunk-yellow-1 :weight bold :underline t))))
+ `(flyspell-incorrect ((,class (:foreground ,cyberpunk-orange-2 :weight bold :underline t))))
+
+ ;; erc
+ `(erc-action-face ((,class (:inherit erc-default-face))))
+ `(erc-bold-face ((,class (:weight bold))))
+ `(erc-current-nick-face ((,class (:foreground ,cyberpunk-blue :weight bold))))
+ `(erc-dangerous-host-face ((,class (:inherit font-lock-warning))))
+ `(erc-default-face ((,class (:foreground ,cyberpunk-fg))))
+ `(erc-direct-msg-face ((,class (:inherit erc-default))))
+ `(erc-error-face ((,class (:inherit font-lock-warning))))
+ `(erc-fool-face ((,class (:inherit erc-default))))
+ `(erc-highlight-face ((,class (:inherit hover-highlight))))
+ `(erc-input-face ((,class (:foreground ,cyberpunk-yellow))))
+ `(erc-keyword-face ((,class (:foreground ,cyberpunk-blue :weight bold))))
+ `(erc-nick-default-face ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(erc-my-nick-face ((,class (:foreground ,cyberpunk-red :weigth bold))))
+ `(erc-nick-msg-face ((,class (:inherit erc-default))))
+ `(erc-notice-face ((,class (:foreground ,cyberpunk-green))))
+ `(erc-pal-face ((,class (:foreground ,cyberpunk-orange :weight bold))))
+ `(erc-prompt-face ((,class (:foreground ,cyberpunk-orange :background ,cyberpunk-bg :weight bold))))
+ `(erc-timestamp-face ((,class (:foreground ,cyberpunk-green+1))))
+ `(erc-underline-face ((t (:underline t))))
+
+ ;; gnus
+ `(gnus-group-mail-1 ((,class (:bold t :inherit gnus-group-mail-1-empty))))
+ `(gnus-group-mail-1-empty ((,class (:inherit gnus-group-news-1-empty))))
+ `(gnus-group-mail-2 ((,class (:bold t :inherit gnus-group-mail-2-empty))))
+ `(gnus-group-mail-2-empty ((,class (:inherit gnus-group-news-2-empty))))
+ `(gnus-group-mail-3 ((,class (:bold t :inherit gnus-group-mail-3-empty))))
+ `(gnus-group-mail-3-empty ((,class (:inherit gnus-group-news-3-empty))))
+ `(gnus-group-mail-4 ((,class (:bold t :inherit gnus-group-mail-4-empty))))
+ `(gnus-group-mail-4-empty ((,class (:inherit gnus-group-news-4-empty))))
+ `(gnus-group-mail-5 ((,class (:bold t :inherit gnus-group-mail-5-empty))))
+ `(gnus-group-mail-5-empty ((,class (:inherit gnus-group-news-5-empty))))
+ `(gnus-group-mail-6 ((,class (:bold t :inherit gnus-group-mail-6-empty))))
+ `(gnus-group-mail-6-empty ((,class (:inherit gnus-group-news-6-empty))))
+ `(gnus-group-mail-low ((,class (:bold t :inherit gnus-group-mail-low-empty))))
+ `(gnus-group-mail-low-empty ((,class (:inherit gnus-group-news-low-empty))))
+ `(gnus-group-news-1 ((,class (:bold t :inherit gnus-group-news-1-empty))))
+ `(gnus-group-news-2 ((,class (:bold t :inherit gnus-group-news-2-empty))))
+ `(gnus-group-news-3 ((,class (:bold t :inherit gnus-group-news-3-empty))))
+ `(gnus-group-news-4 ((,class (:bold t :inherit gnus-group-news-4-empty))))
+ `(gnus-group-news-5 ((,class (:bold t :inherit gnus-group-news-5-empty))))
+ `(gnus-group-news-6 ((,class (:bold t :inherit gnus-group-news-6-empty))))
+ `(gnus-group-news-low ((,class (:bold t :inherit gnus-group-news-low-empty))))
+ `(gnus-header-content ((,class (:inherit message-header-other))))
+ `(gnus-header-from ((,class (:inherit message-header-from))))
+ `(gnus-header-name ((,class (:inherit message-header-name))))
+ `(gnus-header-newsgroups ((,class (:inherit message-header-other))))
+ `(gnus-header-subject ((,class (:inherit message-header-subject))))
+ `(gnus-summary-cancelled ((,class (:foreground ,cyberpunk-orange))))
+ `(gnus-summary-high-ancient ((,class (:foreground ,cyberpunk-blue))))
+ `(gnus-summary-high-read ((,class (:foreground ,cyberpunk-green :weight bold))))
+ `(gnus-summary-high-ticked ((,class (:foreground ,cyberpunk-orange :weight bold))))
+ `(gnus-summary-high-unread ((,class (:foreground ,cyberpunk-fg :weight bold))))
+ `(gnus-summary-low-ancient ((,class (:foreground ,cyberpunk-blue))))
+ `(gnus-summary-low-read ((t (:foreground ,cyberpunk-green))))
+ `(gnus-summary-low-ticked ((,class (:foreground ,cyberpunk-orange :weight bold))))
+ `(gnus-summary-low-unread ((,class (:foreground ,cyberpunk-fg))))
+ `(gnus-summary-normal-ancient ((,class (:foreground ,cyberpunk-blue+1))))
+ `(gnus-summary-normal-read ((,class (:foreground ,cyberpunk-green))))
+ `(gnus-summary-normal-ticked ((,class (:foreground ,cyberpunk-orange :weight bold))))
+ `(gnus-summary-normal-unread ((,class (:foreground ,cyberpunk-fg))))
+ `(gnus-summary-selected ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(gnus-cite-1 ((,class (:foreground ,cyberpunk-yellow-2))))
+ `(gnus-cite-10 ((,class (:foreground ,cyberpunk-yellow-1))))
+ `(gnus-cite-11 ((,class (:foreground ,cyberpunk-yellow))))
+ `(gnus-cite-2 ((,class (:foreground ,cyberpunk-blue-1))))
+ `(gnus-cite-3 ((,class (:foreground ,cyberpunk-blue-2))))
+ `(gnus-cite-4 ((,class (:foreground ,cyberpunk-green+2))))
+ `(gnus-cite-5 ((,class (:foreground ,cyberpunk-green+1))))
+ `(gnus-cite-6 ((,class (:foreground ,cyberpunk-green))))
+ `(gnus-cite-7 ((,class (:foreground ,cyberpunk-red))))
+ `(gnus-cite-8 ((,class (:foreground ,cyberpunk-red-1))))
+ `(gnus-cite-9 ((,class (:foreground ,cyberpunk-red-2))))
+ `(gnus-group-news-1-empty ((,class (:foreground ,cyberpunk-yellow))))
+ `(gnus-group-news-2-empty ((,class (:foreground ,cyberpunk-green+3))))
+ `(gnus-group-news-3-empty ((,class (:foreground ,cyberpunk-green+1))))
+ `(gnus-group-news-4-empty ((,class (:foreground ,cyberpunk-blue-2))))
+ `(gnus-group-news-5-empty ((,class (:foreground ,cyberpunk-blue-3))))
+ `(gnus-group-news-6-empty ((,class (:foreground ,cyberpunk-bg+2))))
+ `(gnus-group-news-low-empty ((,class (:foreground ,cyberpunk-bg+2))))
+ `(gnus-signature ((,class (:foreground ,cyberpunk-yellow))))
+ `(gnus-x ((,class (:background ,cyberpunk-fg :foreground ,cyberpunk-bg))))
+
+ ;; helm
+ `(helm-header
+ ((,class (:foreground ,cyberpunk-green
+ :background ,cyberpunk-bg
+ :underline nil
+ :box nil))))
+ `(helm-source-header
+ ((,class (:foreground ,cyberpunk-yellow
+ :background ,cyberpunk-bg-1
+ :underline nil
+ :weight bold
+ :box (:line-width -1 :style released-button)))))
+ `(helm-selection ((,class (:background ,cyberpunk-bg-1 :underline nil))))
+ `(helm-selection-line ((,class (:background ,cyberpunk-bg+1))))
+ `(helm-visible-mark ((,class (:foreground ,cyberpunk-bg :background ,cyberpunk-yellow-2))))
+ `(helm-candidate-number ((,class (:foreground ,cyberpunk-green+4 :background ,cyberpunk-bg-1))))
+ `(helm-ff-directory ((,class (:foreground ,cyberpunk-pink :background ,cyberpunk-bg))))
+ `(helm-ff-dotted-directory ((,class (:foreground ,cyberpunk-pink :background ,cyberpunk-bg))))
+
+ ;; hl-line-mode
+ `(hl-sexp-face ((,class (:background ,cyberpunk-gray-5))))
+ `(hl-line-face ((,class (:background ,cyberpunk-gray-5))))
+
+ ;; ido-mode
+ `(ido-first-match ((,class (:foreground ,cyberpunk-pink-1 :background ,cyberpunk-black))))
+ `(ido-only-match ((,class (:foreground ,cyberpunk-pink-1 :background ,cyberpunk-black))))
+ `(ido-subdir ((,class (:foreground ,cyberpunk-gray-4 :backgroun ,cyberpunk-black))))
+ `(ido-indicator ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-pink-1))))
+
+ ;; js2-mode
+ `(js2-warning-face ((,class (:underline ,cyberpunk-orange))))
+ `(js2-error-face ((,class (:foreground ,cyberpunk-red :weight bold))))
+ `(js2-jsdoc-tag-face ((,class (:foreground ,cyberpunk-green-1))))
+ `(js2-jsdoc-type-face ((,class (:foreground ,cyberpunk-green+2))))
+ `(js2-jsdoc-value-face ((,class (:foreground ,cyberpunk-green+3))))
+ `(js2-function-param-face ((,class (:foreground ,cyberpunk-green+3))))
+ `(js2-external-variable-face ((,class (:foreground ,cyberpunk-orange))))
+
+ ;; jabber-mode
+ `(jabber-roster-user-away ((,class (:foreground ,cyberpunk-green+2))))
+ `(jabber-roster-user-online ((,class (:foreground ,cyberpunk-blue-1))))
+ `(jabber-roster-user-dnd ((,class (:foreground ,cyberpunk-red+1))))
+ `(jabber-rare-time-face ((,class (:foreground ,cyberpunk-green+1))))
+ `(jabber-chat-prompt-local ((,class (:foreground ,cyberpunk-blue-1))))
+ `(jabber-chat-prompt-foreign ((,class (:foreground ,cyberpunk-red+1))))
+ `(jabber-activity-face((,class (:foreground ,cyberpunk-red+1))))
+ `(jabber-activity-personal-face ((,class (:foreground ,cyberpunk-blue+1))))
+ `(jabber-title-small ((,class (:height 1.1 :weight bold))))
+ `(jabber-title-medium ((,class (:height 1.2 :weight bold))))
+ `(jabber-title-large ((,class (:height 1.3 :weight bold))))
+
+ ;; linum-mode
+ `(linum ((,class (:foreground ,cyberpunk-green+2 :background ,cyberpunk-bg))))
+
+ ;;linum-relative
+ `(linum-relative-current-face ((,class (:inherit linum :foreground ,cyberpunk-white :weight bold))))
+
+ ;; magit
+ ;; magit headings and diffs
+ `(magit-section-highlight ((t (:background ,cyberpunk-bg+1))))
+ `(magit-section-heading ((t (:foreground ,cyberpunk-blue+1 :weight bold))))
+ `(magit-section-heading-selection ((t (:foreground ,cyberpunk-red+1 :weight bold))))
+ `(magit-diff-file-heading ((t (:weight bold))))
+ `(magit-diff-file-heading-highlight ((t (:background ,cyberpunk-bg+2 :weight bold))))
+ `(magit-diff-file-heading-selection ((t (:background ,cyberpunk-bg+2
+ :foreground ,cyberpunk-blue-6 :weight bold))))
+ `(magit-diff-hunk-heading ((t (:background ,cyberpunk-bg))))
+ `(magit-diff-hunk-heading-highlight ((t (:background ,cyberpunk-bg+1))))
+ `(magit-diff-hunk-heading-selection ((t (:background ,cyberpunk-bg+1
+ :foreground ,cyberpunk-blue-6))))
+ `(magit-diff-lines-heading ((t (:background ,cyberpunk-blue-6
+ :foreground ,cyberpunk-bg+1))))
+ `(magit-diff-added ((t (:foreground ,cyberpunk-blue-5))))
+ `(magit-diff-added-highlight ((t (:inherit magit-diff-added :weight bold))))
+ `(magit-diff-removed ((t (:foreground ,cyberpunk-magenta))))
+ `(magit-diff-removed-highlight ((t (:inherit magit-diff-removed :weight bold))))
+ `(magit-diff-context ((t (:foreground ,cyberpunk-gray))))
+ `(magit-diff-context-highlight ((t (:inherit magit-diff-context :weight bold))))
+ `(magit-diffstat-added ((t (:inherit magit-diff-added))))
+ `(magit-diffstat-removed ((t (:inherit magit-diff-removed))))
+ ;; magit popup
+ `(magit-popup-heading ((t (:foreground ,cyberpunk-pink-1 :weight bold))))
+ `(magit-popup-key ((t (:foreground ,cyberpunk-blue+1 :weight bold))))
+ `(magit-popup-argument ((t (:foreground ,cyberpunk-blue-4 :weight bold))))
+ `(magit-popup-disabled-argument ((t (:foreground ,cyberpunk-fg :weight normal))))
+ `(magit-popup-option-value ((t (:foreground ,cyberpunk-blue-2 :weight bold))))
+ ;; ;; magit process
+ `(magit-process-ok ((t (:foreground ,cyberpunk-green+1 :weight bold))))
+ `(magit-process-ng ((t (:foreground ,cyberpunk-pink-2 :weight bold))))
+ ;; ;; magit log
+ `(magit-log-author ((t (:foreground ,cyberpunk-pink))))
+ `(magit-log-date ((t (:foreground ,cyberpunk-gray))))
+ `(magit-log-graph ((t (:foreground ,cyberpunk-white-2))))
+ ;; ;; magit sequence
+ `(magit-sequence-pick ((t (:foreground ,cyberpunk-magenta))))
+ `(magit-sequence-stop ((t (:foreground ,cyberpunk-green+1))))
+ `(magit-sequence-part ((t (:foreground ,cyberpunk-pink-1))))
+ `(magit-sequence-head ((t (:foreground ,cyberpunk-blue+1))))
+ `(magit-sequence-drop ((t (:foreground ,cyberpunk-orange))))
+ `(magit-sequence-done ((t (:foreground ,cyberpunk-gray-2))))
+ `(magit-sequence-onto ((t (:foreground ,cyberpunk-gray-2))))
+ ;; ;; magit bisect
+ `(magit-bisect-good ((t (:foreground ,cyberpunk-green+1))))
+ `(magit-bisect-skip ((t (:foreground ,cyberpunk-pink-1))))
+ `(magit-bisect-bad ((t (:foreground ,cyberpunk-orange))))
+ ;; ;; magit blame
+ `(magit-blame-heading ((t (:background ,cyberpunk-bg+1 :foreground ,cyberpunk-green))))
+ `(magit-blame-hash ((t (:background ,cyberpunk-bg+1 :foreground ,cyberpunk-green))))
+ `(magit-blame-name ((t (:background ,cyberpunk-bg+1 :foreground ,cyberpunk-pink-1))))
+ `(magit-blame-date ((t (:background ,cyberpunk-bg+1 :foreground ,cyberpunk-yellow-1))))
+ `(magit-blame-summary ((t (:background ,cyberpunk-bg+1 :foreground ,cyberpunk-blue-4
+ :weight bold))))
+ ;; ;; magit references etc
+ `(magit-dimmed ((t (:foreground ,cyberpunk-bg+3))))
+ `(magit-hash ((t (:foreground ,cyberpunk-bg+1))))
+ `(magit-tag ((t (:foreground ,cyberpunk-pink-1 :weight bold))))
+ `(magit-branch-remote ((t (:foreground ,cyberpunk-green+2 :weight bold))))
+ `(magit-branch-local ((t (:foreground ,cyberpunk-blue+1 :weight bold))))
+ `(magit-branch-current ((t (:foreground ,cyberpunk-green :weight bold :box t))))
+ `(magit-head ((t (:foreground ,cyberpunk-blue :weight bold))))
+ `(magit-refname ((t (:background ,cyberpunk-bg+2 :foreground ,cyberpunk-fg :weight bold))))
+ `(magit-refname-stash ((t (:background ,cyberpunk-bg+2 :foreground ,cyberpunk-fg :weight bold))))
+ `(magit-refname-wip ((t (:background ,cyberpunk-bg+2 :foreground ,cyberpunk-fg :weight bold))))
+ `(magit-signature-good ((t (:foreground ,cyberpunk-green))))
+ `(magit-signature-bad ((t (:foreground ,cyberpunk-red))))
+ `(magit-signature-untrusted ((t (:foreground ,cyberpunk-yellow))))
+ `(magit-cherry-unmatched ((t (:foreground ,cyberpunk-cyan))))
+ `(magit-cherry-equivalent ((t (:foreground ,cyberpunk-magenta))))
+ `(magit-reflog-commit ((t (:foreground ,cyberpunk-green))))
+ `(magit-reflog-amend ((t (:foreground ,cyberpunk-magenta))))
+ `(magit-reflog-merge ((t (:foreground ,cyberpunk-green))))
+ `(magit-reflog-checkout ((t (:foreground ,cyberpunk-blue))))
+ `(magit-reflog-reset ((t (:foreground ,cyberpunk-red))))
+ `(magit-reflog-rebase ((t (:foreground ,cyberpunk-magenta))))
+ `(magit-reflog-cherry-pick ((t (:foreground ,cyberpunk-green))))
+ `(magit-reflog-remote ((t (:foreground ,cyberpunk-cyan))))
+ `(magit-reflog-other ((t (:foreground ,cyberpunk-cyan))))
+
+ `(eval-sexp-fu-flash ((,class (:background ,cyberpunk-gray-8 :foreground ,cyberpunk-pink-2))))
+
+ ;; message-mode
+ `(message-cited-text ((,class (:inherit font-lock-comment))))
+ `(message-header-name ((,class (:foreground ,cyberpunk-blue-5))))
+ `(message-header-other ((,class (:foreground ,cyberpunk-green))))
+ `(message-header-to ((,class (:foreground ,cyberpunk-pink-1 :weight bold))))
+ `(message-header-from ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(message-header-cc ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(message-header-newsgroups ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(message-header-subject ((,class (:foreground ,cyberpunk-orange :weight bold))))
+ `(message-header-xheader ((,class (:foreground ,cyberpunk-green))))
+ `(message-mml ((,class (:foreground ,cyberpunk-yellow :weight bold))))
+ `(message-separator ((,class (:inherit font-lock-comment))))
+
+ ;; mew
+ `(mew-face-header-subject ((,class (:foreground ,cyberpunk-orange))))
+ `(mew-face-header-from ((,class (:foreground ,cyberpunk-yellow))))
+ `(mew-face-header-date ((,class (:foreground ,cyberpunk-green))))
+ `(mew-face-header-to ((,class (:foreground ,cyberpunk-red))))
+ `(mew-face-header-key ((,class (:foreground ,cyberpunk-green))))
+ `(mew-face-header-private ((,class (:foreground ,cyberpunk-green))))
+ `(mew-face-header-important ((,class (:foreground ,cyberpunk-blue))))
+ `(mew-face-header-marginal ((,class (:foreground ,cyberpunk-fg :weight bold))))
+ `(mew-face-header-warning ((,class (:foreground ,cyberpunk-red))))
+ `(mew-face-header-xmew ((,class (:foreground ,cyberpunk-green))))
+ `(mew-face-header-xmew-bad ((,class (:foreground ,cyberpunk-red))))
+ `(mew-face-body-url ((,class (:foreground ,cyberpunk-orange))))
+ `(mew-face-body-comment ((,class (:foreground ,cyberpunk-fg :slant italic))))
+ `(mew-face-body-cite1 ((,class (:foreground ,cyberpunk-green))))
+ `(mew-face-body-cite2 ((,class (:foreground ,cyberpunk-blue))))
+ `(mew-face-body-cite3 ((,class (:foreground ,cyberpunk-orange))))
+ `(mew-face-body-cite4 ((,class (:foreground ,cyberpunk-yellow))))
+ `(mew-face-body-cite5 ((,class (:foreground ,cyberpunk-red))))
+ `(mew-face-mark-review ((,class (:foreground ,cyberpunk-blue))))
+ `(mew-face-mark-escape ((,class (:foreground ,cyberpunk-green))))
+ `(mew-face-mark-delete ((,class (:foreground ,cyberpunk-red))))
+ `(mew-face-mark-unlink ((,class (:foreground ,cyberpunk-yellow))))
+ `(mew-face-mark-refile ((,class (:foreground ,cyberpunk-green))))
+ `(mew-face-mark-unread ((,class (:foreground ,cyberpunk-red-2))))
+ `(mew-face-eof-message ((,class (:foreground ,cyberpunk-green))))
+ `(mew-face-eof-part ((,class (:foreground ,cyberpunk-yellow))))
+
+ ;; mic-paren
+ `(paren-face-match ((,class (:foreground ,cyberpunk-cyan :background ,cyberpunk-bg :weight bold))))
+ `(paren-face-mismatch ((,class (:foreground ,cyberpunk-bg :background ,cyberpunk-magenta :weight bold))))
+ `(paren-face-no-match ((,class (:foreground ,cyberpunk-bg :background ,cyberpunk-red :weight bold))))
+
+ ;; nav
+ `(nav-face-heading ((,class (:foreground ,cyberpunk-yellow))))
+ `(nav-face-button-num ((,class (:foreground ,cyberpunk-cyan))))
+ `(nav-face-dir ((,class (:foreground ,cyberpunk-green))))
+ `(nav-face-hdir ((,class (:foreground ,cyberpunk-red))))
+ `(nav-face-file ((,class (:foreground ,cyberpunk-fg))))
+ `(nav-face-hfile ((,class (:foreground ,cyberpunk-red-4))))
+
+ ;; mumamo
+ `(mumamo-background-chunk-major ((,class (:background ,cyberpunk-black))))
+ `(mumamo-background-chunk-submode1 ((,class (:background ,cyberpunk-black))))
+ `(mumamo-background-chunk-submode2 ((,class (:background ,cyberpunk-bg+2))))
+ `(mumamo-background-chunk-submode3 ((,class (:background ,cyberpunk-bg+3))))
+ `(mumamo-background-chunk-submode4 ((,class (:background ,cyberpunk-bg+1))))
+
+ ;; org-mode
+ `(org-document-title ((,class (:foreground ,cyberpunk-blue-3 :background ,cyberpunk-black :weight bold :height 1.5))))
+ `(org-document-info ((,class (:foreground ,cyberpunk-blue-3 :background ,cyberpunk-black :weight bold))))
+ `(org-document-info-keyword ((,class (:foreground ,cyberpunk-gray-2 :background ,cyberpunk-black))))
+ `(org-agenda-date-today
+ ((,class (:foreground ,cyberpunk-orange-2 :slant italic :weight bold))) t)
+ `(org-agenda-structure
+ ((,class (:inherit font-lock-comment-face))))
+ `(org-archived ((,class (:slant italic))))
+ `(org-checkbox ((,class (:background ,cyberpunk-gray-2 :foreground ,cyberpunk-black
+ :box (:line-width 1 :style released-button)))))
+ `(org-date ((,class (:foreground ,cyberpunk-blue-7 :underline t))))
+ `(org-done ((,class (:bold t :weight bold :foreground ,cyberpunk-green
+ :box (:line-width 1 :style none)))))
+ `(org-todo ((,class (:bold t :foreground ,cyberpunk-orange :weight bold
+ :box (:line-width 1 :style none)))))
+ `(org-level-1 ((,class (:foreground ,cyberpunk-pink-1 :height 1.3))))
+ `(org-level-2 ((,class (:foreground ,cyberpunk-yellow :height 1.2))))
+ `(org-level-3 ((,class (:foreground ,cyberpunk-blue-5 :height 1.1))))
+ `(org-level-4 ((,class (:foreground ,cyberpunk-green))))
+ `(org-level-5 ((,class (:foreground ,cyberpunk-orange))))
+ `(org-level-6 ((,class (:foreground ,cyberpunk-pink))))
+ `(org-level-7 ((,class (:foreground ,cyberpunk-green+3))))
+ `(org-level-8 ((,class (:foreground ,cyberpunk-blue-1))))
+ `(org-link ((,class (:foreground ,cyberpunk-blue-6 :underline t))))
+ `(org-tag ((,class (:bold t :weight bold))))
+ `(org-column ((,class (:background ,cyberpunk-gray-7 :foreground ,cyberpunk-black))))
+ `(org-column-title ((,class (:background ,cyberpunk-gray-7 :underline t :weight bold))))
+ `(org-block ((,class (:foreground ,cyberpunk-fg :background ,cyberpunk-bg-05))))
+ `(org-block-begin-line
+ ((,class (:foreground "#008ED1" :background ,cyberpunk-bg-1))))
+ `(org-block-background ((,class (:background ,cyberpunk-bg-05))))
+ `(org-block-end-line
+ ((,class (:foreground "#008ED1" :background ,cyberpunk-bg-1))))
+
+ ;; `(org-deadline-announce ((,class (:foreground ,cyberpunk-red-1))))
+ ;; `(org-scheduled ((,class (:foreground ,cyberpunk-green+4))))
+ ;; `(org-scheduled-previously ((,class (:foreground ,cyberpunk-red-4))))
+ ;; `(org-scheduled-today ((,class (:foreground ,cyberpunk-blue+1))))
+ ;; `(org-special-keyword ((,class (:foreground ,cyberpunk-yellow-1))))
+ ;; `(org-table ((,class (:foreground ,cyberpunk-green+2))))
+ ;; `(org-time-grid ((,class (:foreground ,cyberpunk-orange))))
+ ;; `(org-upcoming-deadline ((,class (:inherit font-lock-keyword-face))))
+ ;; `(org-warning ((,class (:bold t :foreground ,cyberpunk-red :weight bold :underline nil))))
+ ;; `(org-formula ((,class (:foreground ,cyberpunk-yellow-2))))
+ ;; `(org-headline-done ((,class (:foreground ,cyberpunk-green+3))))
+ ;; `(org-hide ((,class (:foreground ,cyberpunk-bg-1))))
+
+ ;; outline
+ `(outline-8 ((,class (:inherit default))))
+ `(outline-7 ((,class (:inherit outline-8 :height 1.0))))
+ `(outline-6 ((,class (:inherit outline-7 :height 1.0))))
+ `(outline-5 ((,class (:inherit outline-6 :height 1.0))))
+ `(outline-4 ((,class (:inherit outline-5 :height 1.0))))
+ `(outline-3 ((,class (:inherit outline-4 :height 1.0))))
+ `(outline-2 ((,class (:inherit outline-3 :height 1.0))))
+ `(outline-1 ((,class (:inherit outline-2 :height 1.0))))
+
+ ;; emms
+ `(emms-browser-year/genre-face ((,class (:foreground ,cyberpunk-blue-3 :height 1.0))))
+ `(emms-browser-artist-face ((,class (:foreground ,cyberpunk-pink-1 :height 1.0))))
+ `(emms-browser-composer-face ((,class (:foreground ,cyberpunk-blue-3 :height 1.0))))
+ `(emms-browser-performer-face ((,class (:foreground ,cyberpunk-blue-3 :height 1.0))))
+ `(emms-browser-album-face ((,class (:foreground ,cyberpunk-yellow :height 1.0))))
+ `(emms-browser-track-face ((,class (:foreground ,cyberpunk-blue-5 :height 1.0))))
+
+ ;; Calfw
+ `(cfw:face-title ((,class (:foreground ,cyberpunk-pink-1 :weight bold :height 1.8))))
+ `(cfw:face-header ((,class (:foreground ,cyberpunk-yellow-5 :weight bold))))
+ `(cfw:face-sunday ((,class (:foreground ,cyberpunk-red :weight bold))))
+ `(cfw:face-saturday ((,class (:foreground ,cyberpunk-green :weight bold))))
+ `(cfw:face-holiday ((,class (:foreground ,cyberpunk-pink-2 :weight bold))))
+ `(cfw:face-grid ((,class (:foreground ,cyberpunk-gray-3))))
+ `(cfw:face-default-content ((,class (:foreground ,cyberpunk-cyan))))
+ `(cfw:face-periods ((,class (:foreground ,cyberpunk-cyan :weight bold))))
+ `(cfw:face-day-title ((,class (:foreground ,cyberpunk-fg))))
+ `(cfw:face-default-day ((,class (:foreground ,cyberpunk-fg :weight bold))))
+ `(cfw:face-annotation ((,class (:foreground ,cyberpunk-gray))))
+ `(cfw:face-disable ((,class (:foreground ,cyberpunk-gray-2 :weight bold))))
+ `(cfw:face-today-title ((,class (:foreground ,cyberpunk-blue :background ,cyberpunk-magenta))))
+ `(cfw:face-today ((,class (:foreground ,cyberpunk-fg :weight bold))))
+ `(cfw:face-select ((,class (:background ,cyberpunk-bg+2))))
+ `(cfw:face-toolbar ((,class (:background ,cyberpunk-blue-8))))
+ `(cfw:face-toolbar-button-off ((,class (:foreground ,cyberpunk-white :background ,cyberpunk-blue-8 :weight bold))))
+ `(cfw:face-toolbar-button-on ((,class (:foreground ,cyberpunk-white :background ,cyberpunk-orange-1 :weight bold))))
+
+ ;; racket-mode
+ `(racket-keyword-argument-face ((t (:inherit font-lock-constant-face))))
+ `(racket-selfeval-face ((t (:inherit font-lock-type-face))))
+
+ ;; rainbow-delimiters
+ `(rainbow-delimiters-depth-1-face ((,class (:foreground ,cyberpunk-red-1))))
+ `(rainbow-delimiters-depth-2-face ((,class (:foreground ,cyberpunk-green-2))))
+ `(rainbow-delimiters-depth-3-face ((,class (:foreground ,cyberpunk-pink-1))))
+ `(rainbow-delimiters-depth-4-face ((,class (:foreground ,cyberpunk-yellow))))
+ `(rainbow-delimiters-depth-5-face ((,class (:foreground ,cyberpunk-green))))
+ `(rainbow-delimiters-depth-6-face ((,class (:foreground ,cyberpunk-blue-3))))
+ `(rainbow-delimiters-depth-7-face ((,class (:foreground ,cyberpunk-orange))))
+ `(rainbow-delimiters-depth-8-face ((,class (:foreground ,cyberpunk-blue-2))))
+ `(rainbow-delimiters-depth-9-face ((,class (:foreground ,cyberpunk-gray))))
+ `(rainbow-delimiters-depth-10-face ((,class (:foreground ,cyberpunk-white))))
+ `(rainbow-delimiters-depth-11-face ((,class (:foreground ,cyberpunk-blue+1))))
+ `(rainbow-delimiters-depth-12-face ((,class (:foreground ,cyberpunk-red-4))))
+
+ ;; rpm-mode
+ `(rpm-spec-dir-face ((,class (:foreground ,cyberpunk-green))))
+ `(rpm-spec-doc-face ((,class (:foreground ,cyberpunk-green))))
+ `(rpm-spec-ghost-face ((,class (:foreground ,cyberpunk-red))))
+ `(rpm-spec-macro-face ((,class (:foreground ,cyberpunk-yellow))))
+ `(rpm-spec-obsolete-tag-face ((,class (:foreground ,cyberpunk-red))))
+ `(rpm-spec-package-face ((,class (:foreground ,cyberpunk-red))))
+ `(rpm-spec-section-face ((,class (:foreground ,cyberpunk-yellow))))
+ `(rpm-spec-tag-face ((,class (:foreground ,cyberpunk-blue))))
+ `(rpm-spec-var-face ((,class (:foreground ,cyberpunk-red))))
+
+ ;; rst-mode
+ `(rst-level-1-face ((,class (:foreground ,cyberpunk-orange))))
+ `(rst-level-2-face ((,class (:foreground ,cyberpunk-green+1))))
+ `(rst-level-3-face ((,class (:foreground ,cyberpunk-blue-1))))
+ `(rst-level-4-face ((,class (:foreground ,cyberpunk-yellow-2))))
+ `(rst-level-5-face ((,class (:foreground ,cyberpunk-cyan))))
+ `(rst-level-6-face ((,class (:foreground ,cyberpunk-green-1))))
+
+ ;; show-paren
+ `(show-paren-mismatch ((,class (:foreground ,cyberpunk-red-3 :background ,cyberpunk-black))))
+ `(show-paren-match ((,class (:foreground ,cyberpunk-black :background ,cyberpunk-pink-1))))
+
+ `(naeu-green-face ((,class (:foreground ,cyberpunk-green :background ,cyberpunk-black))))
+ `(naeu-pink-face ((,class (:foreground ,cyberpunk-pink-1 :background ,cyberpunk-black))))
+ `(naeu-blue-face ((,class (:foreground ,cyberpunk-blue-1 :background ,cyberpunk-black))))
+ `(naeu-orange-face ((,class (:foreground ,cyberpunk-yellow-1 :background ,cyberpunk-black))))
+ `(naeu-red-face ((,class (:foreground ,cyberpunk-orange :background ,cyberpunk-black))))
+ `(naeu-grey-face ((,class (:foreground ,cyberpunk-gray-7 :background ,cyberpunk-black))))
+
+ ;; SLIME
+ `(slime-repl-inputed-output-face ((,class (:foreground ,cyberpunk-red))))
+
+ ;;; ansi-term
+ `(term-color-black ((,class (:foreground ,cyberpunk-bg
+ :background ,cyberpunk-bg-1))))
+ `(term-color-red ((,class (:foreground ,cyberpunk-red-2
+ :background ,cyberpunk-red-4))))
+ `(term-color-green ((,class (:foreground ,cyberpunk-green
+ :background ,cyberpunk-green+2))))
+ `(term-color-yellow ((,class (:foreground ,cyberpunk-orange
+ :background ,cyberpunk-yellow))))
+ `(term-color-blue ((,class (:foreground ,cyberpunk-blue-1
+ :background ,cyberpunk-blue-4))))
+ `(term-color-magenta ((,class (:foreground ,cyberpunk-magenta
+ :background ,cyberpunk-red))))
+ `(term-color-cyan ((,class (:foreground ,cyberpunk-cyan
+ :background ,cyberpunk-blue))))
+ `(term-color-white ((,class (:foreground ,cyberpunk-fg
+ :background ,cyberpunk-bg-1))))
+ `(term-default-fg-color ((,class (:inherit term-color-white))))
+ `(term-default-bg-color ((,class (:inherit term-color-black))))
+
+ ;; volatile-highlights
+ `(vhl/default-face ((,class (:background ,cyberpunk-gray-5))))
+
+ `(undo-tree-visualizer-active-branch-face ((,class (:foreground ,cyberpunk-pink-1 :background ,cyberpunk-black))))
+
+ ;; whitespace-mode
+ `(whitespace-space ((,class (:background ,cyberpunk-bg :foreground ,cyberpunk-bg+1))))
+ `(whitespace-hspace ((,class (:background ,cyberpunk-bg :foreground ,cyberpunk-bg+1))))
+ `(whitespace-tab ((,class (:background ,cyberpunk-bg :foreground ,cyberpunk-red))))
+ `(whitespace-newline ((,class (:foreground ,cyberpunk-bg+1))))
+ `(whitespace-trailing ((,class (:foreground ,cyberpunk-red :background ,cyberpunk-bg))))
+ `(whitespace-line ((,class (:background ,cyberpunk-bg-05 :foreground ,cyberpunk-magenta))))
+ `(whitespace-space-before-tab ((,class (:background ,cyberpunk-orange :foreground ,cyberpunk-orange))))
+ `(whitespace-indentation ((,class (:background ,cyberpunk-yellow :foreground ,cyberpunk-red))))
+ `(whitespace-empty ((,class (:background ,cyberpunk-yellow :foreground ,cyberpunk-red))))
+ `(whitespace-space-after-tab ((,class (:background ,cyberpunk-yellow :foreground ,cyberpunk-red))))
+
+ ;; wanderlust
+ `(wl-highlight-folder-few-face ((,class (:foreground ,cyberpunk-red-2))))
+ `(wl-highlight-folder-many-face ((,class (:foreground ,cyberpunk-red-1))))
+ `(wl-highlight-folder-path-face ((,class (:foreground ,cyberpunk-orange))))
+ `(wl-highlight-folder-unread-face ((,class (:foreground ,cyberpunk-blue))))
+ `(wl-highlight-folder-zero-face ((,class (:foreground ,cyberpunk-fg))))
+ `(wl-highlight-folder-unknown-face ((,class (:foreground ,cyberpunk-blue))))
+ `(wl-highlight-message-citation-header ((,class (:foreground ,cyberpunk-red-1))))
+ `(wl-highlight-message-cited-text-1 ((,class (:foreground ,cyberpunk-red))))
+ `(wl-highlight-message-cited-text-2 ((,class (:foreground ,cyberpunk-green+2))))
+ `(wl-highlight-message-cited-text-3 ((,class (:foreground ,cyberpunk-blue))))
+ `(wl-highlight-message-cited-text-4 ((,class (:foreground ,cyberpunk-blue+1))))
+ `(wl-highlight-message-header-contents-face ((,class (:foreground ,cyberpunk-green))))
+ `(wl-highlight-message-headers-face ((,class (:foreground ,cyberpunk-red+1))))
+ `(wl-highlight-message-important-header-contents ((,class (:foreground ,cyberpunk-green+2))))
+ `(wl-highlight-message-header-contents ((,class (:foreground ,cyberpunk-green+1))))
+ `(wl-highlight-message-important-header-contents2 ((,class (:foreground ,cyberpunk-green+2))))
+ `(wl-highlight-message-signature ((,class (:foreground ,cyberpunk-green))))
+ `(wl-highlight-message-unimportant-header-contents ((,class (:foreground ,cyberpunk-fg))))
+ `(wl-highlight-summary-answered-face ((,class (:foreground ,cyberpunk-blue))))
+ `(wl-highlight-summary-disposed-face ((,class (:foreground ,cyberpunk-fg
+ :slant italic))))
+ `(wl-highlight-summary-new-face ((,class (:foreground ,cyberpunk-blue))))
+ `(wl-highlight-summary-normal-face ((,class (:foreground ,cyberpunk-fg))))
+ `(wl-highlight-summary-thread-top-face ((,class (:foreground ,cyberpunk-yellow))))
+ `(wl-highlight-thread-indent-face ((,class (:foreground ,cyberpunk-magenta))))
+ `(wl-highlight-summary-refiled-face ((,class (:foreground ,cyberpunk-fg))))
+ `(wl-highlight-summary-displaying-face ((,class (:underline t :weight bold))))
+
+ ;; which-func-mode
+ `(which-func ((,class (:foreground ,cyberpunk-green+4))))
+
+ ;; yasnippet
+ `(yas/field-highlight-face ((,class (:background ,cyberpunk-pink-1 :foreground ,cyberpunk-black))))
+
+ ;; enh-ruby-mode enh-ruby-op-face
+ `(enh-ruby-op-face ((,class (:foreground ,cyberpunk-blue-7))))
+ `(enh-ruby-heredoc-delimiter-face ((,class (:foreground ,cyberpunk-green+2))))
+ `(enh-ruby-string-delimiter-face ((,class (:foreground ,cyberpunk-green+2))))
+ `(enh-ruby-regexp-delimiter-face ((,class (:foreground ,cyberpunk-blue-1))))
+
+ ;; yascroll
+ `(yascroll:thumb-text-area ((,class (:background ,cyberpunk-bg-1))))
+ `(yascroll:thumb-fringe ((,class (:background ,cyberpunk-bg-1 :foreground ,cyberpunk-bg-1))))
+
+ ;; customize
+ `(custom-button ((,class (:box (:line-width 2 :style released-button)
+ :background ,cyberpunk-bg-05 :foreground ,cyberpunk-fg))))
+ `(custom-button-unraised ((,class (:background ,cyberpunk-bg-05 :foreground ,cyberpunk-fg))))
+ )
+
+ ;;; custom theme variables
+ (custom-theme-set-variables
+ 'cyberpunk
+ `(ansi-color-names-vector [,cyberpunk-bg ,cyberpunk-red-2 ,cyberpunk-green ,cyberpunk-orange
+ ,cyberpunk-blue-1 ,cyberpunk-magenta ,cyberpunk-cyan ,cyberpunk-fg])
+ ;; fill-column-indicator
+ `(fci-rule-color ,cyberpunk-bg-05)))
+
+;;;###autoload
+(when load-file-name
+ (add-to-list 'custom-theme-load-path
+ (file-name-as-directory (file-name-directory load-file-name))))
+
+(provide-theme 'cyberpunk)
+
+;; Local Variables:
+;; no-byte-compile: t
+;; indent-tabs-mode: nil
+;; eval: (when (fboundp 'rainbow-mode) (rainbow-mode +1))
+;; End:
+
+;;; cyberpunk-theme.el ends here.
diff --git a/emacs/emacs.d/themes/dracula-theme.el b/emacs/emacs.d/themes/dracula-theme.el
@@ -0,0 +1,458 @@
+;;; dracula-theme.el --- Dracula Theme
+
+;; Copyright 2015-present, All rights reserved
+;;
+;; Code licensed under the MIT license
+
+;; Author: film42
+;; Version: 1.5.1
+;; Package-Requires: ((emacs "24"))
+;; URL: https://github.com/dracula/emacs
+
+;;; Commentary:
+
+;; A dark color theme available for a number of editors.
+
+;;; Code:
+(require 'cl-lib)
+(deftheme dracula)
+
+(let ((colors '((fg1 "#f8f8f2") ; Assigment form: VARIABLE COLOR [TTY-COLOR]
+ (fg2 "#e2e2dc")
+ (fg3 "#ccccc7")
+ (fg4 "#b6b6b2")
+ (bg1 "#282a36" "#000000")
+ (bg2 "#373844")
+ (bg3 "#464752")
+ (bg4 "#565761")
+ (bg5 "#44475a")
+ (bg6 "#b45bcf")
+ (key2 "#0189cc")
+ (key3 "#ff79c6")
+ (builtin "#ffb86c")
+ (keyword "#ff79c6")
+ (const "#8be9fd")
+ (comment "#6272a4")
+ (func "#50fa7b")
+ (str "#f1fa8c")
+ (type "#bd93f9")
+ (var "#f8f8f2")
+ (warning "#ffb86c")
+ (rainbow-1 "#f8f8f2")
+ (rainbow-2 "#8be9fd")
+ (rainbow-3 "#bd93f9")
+ (rainbow-4 "#ff79c6")
+ (rainbow-5 "#ffb86c")
+ (rainbow-6 "#50fa7b")
+ (rainbow-7 "#f1fa8c")
+ (rainbow-8 "#0189cc")
+ (rainbow-9 "#ff5555")
+ (rainbow-10 "#a0522d")
+ (eph-verbatim "#f1fa8c")
+ (eph-code "#ff79c6")))
+ (faces '(;; default
+ (cursor :background ,fg3)
+ (default :background ,bg1 :foreground ,fg1)
+ (default-italic :italic t)
+ (ffap :foreground ,fg4)
+ (fringe :background ,bg1 :foreground ,fg4)
+ (highlight :foreground ,fg3 :background ,bg3)
+ (hl-line :background ,bg5)
+ (info-quoted-name :foreground ,builtin)
+ (info-string :foreground ,str)
+ (lazy-highlight :foreground ,fg2 :background ,bg3)
+ (link :foreground ,const :underline t)
+ (linum :slant italic :foreground ,bg4 :background ,bg1)
+ (line-number :slant italic :foreground ,bg4 :background ,bg1)
+ (minibuffer-prompt :bold t :foreground ,keyword)
+ (region :background ,str :foreground ,bg1)
+ (show-paren-match-face :background ,warning)
+ (trailing-whitespace :foreground nil :background ,warning)
+ (vertical-border :foreground ,bg2)
+ (warning :foreground ,warning)
+ (whitespace-trailing :inherit trailing-whitespace)
+ (header-line :background ,bg1)
+ ;; syntax
+ (font-lock-builtin-face :foreground ,builtin)
+ (font-lock-comment-face :foreground ,comment)
+ (font-lock-constant-face :foreground ,const)
+ (font-lock-doc-face :foreground ,comment)
+ (font-lock-function-name-face :foreground ,func :bold t)
+ (font-lock-keyword-face :bold t :foreground ,keyword)
+ (font-lock-negation-char-face :foreground ,const)
+ (font-lock-reference-face :foreground ,const)
+ (font-lock-string-face :foreground ,str)
+ (font-lock-type-face :foreground ,type )
+ (font-lock-variable-name-face :foreground ,var)
+ (font-lock-warning-face :foreground ,warning :background ,bg2)
+ ;; auto-complete
+ (ac-completion-face :underline t :foreground ,keyword)
+ ;; company
+ (company-echo-common :foreground ,bg1 :background ,fg1)
+ (company-preview :background ,bg1 :foreground ,key2)
+ (company-preview-common :foreground ,bg2 :foreground ,fg3)
+ (company-preview-search :foreground ,type :background ,bg1)
+ (company-scrollbar-bg :background ,bg3)
+ (company-scrollbar-fg :foreground ,keyword)
+ (company-template-field :inherit region)
+ (company-tooltip :foreground ,fg2 :background ,bg1 :bold t)
+ (company-tooltip-annotation :foreground ,const)
+ (company-tooltip-common :foreground ,fg3)
+ (company-tooltip-common-selection :foreground ,str)
+ (company-tooltip-mouse :inherit highlight)
+ (company-tooltip-selection :background ,bg3 :foreground ,fg3)
+ ;; diff-hl
+ (diff-hl-change :foreground ,rainbow-5 :background ,rainbow-5)
+ (diff-hl-delete :foreground ,rainbow-9 :background ,rainbow-9)
+ (diff-hl-insert :foreground ,rainbow-6 :background ,rainbow-6)
+ ;; enh-ruby
+ (enh-ruby-heredoc-delimiter-face :foreground ,str)
+ (enh-ruby-op-face :foreground ,keyword)
+ (enh-ruby-regexp-delimiter-face :foreground ,str)
+ (enh-ruby-string-delimiter-face :foreground ,str)
+ ;; font-latex
+ (font-latex-bold-face :foreground ,type)
+ (font-latex-italic-face :foreground ,key3 :italic t)
+ (font-latex-match-reference-keywords :foreground ,const)
+ (font-latex-match-variable-keywords :foreground ,var)
+ (font-latex-string-face :foreground ,str)
+ ;; gnus-group
+ (gnus-group-mail-1 :foreground ,keyword :bold t)
+ (gnus-group-mail-1-empty :inherit gnus-group-mail-1 :bold nil)
+ (gnus-group-mail-2 :foreground ,const :bold t)
+ (gnus-group-mail-2-empty :inherit gnus-group-mail-2 :bold nil)
+ (gnus-group-mail-3 :foreground ,comment :bold t)
+ (gnus-group-mail-3-empty :inherit gnus-group-mail-3 :bold nil)
+ (gnus-group-mail-low :foreground ,bg5 :bold t)
+ (gnus-group-mail-low-empty :inherit gnus-group-mail-low :bold nil)
+ (gnus-group-news-1 :foreground ,keyword :bold t)
+ (gnus-group-news-1-empty :inherit gnus-group-news-1 :bold nil)
+ (gnus-group-news-2 :foreground ,const :bold t)
+ (gnus-group-news-2-empty :inherit gnus-group-news-2 :bold nil)
+ (gnus-group-news-3 :foreground ,comment :bold t)
+ (gnus-group-news-3-empty :inherit gnus-group-news-3 :bold nil)
+ (gnus-group-news-4 :inherit gnus-group-news-low)
+ (gnus-group-news-4-empty :inherit gnus-group-news-low-empty)
+ (gnus-group-news-5 :inherit gnus-group-news-low)
+ (gnus-group-news-5-empty :inherit gnus-group-news-low-empty)
+ (gnus-group-news-6 :inherit gnus-group-news-low)
+ (gnus-group-news-6-empty :inherit gnus-group-news-low-empty)
+ (gnus-group-news-low :foreground ,bg5 :bold t)
+ (gnus-group-news-low-empty :inherit gnus-group-news-low :bold nil)
+ (gnus-header-content :foreground ,keyword)
+ (gnus-header-from :foreground ,var)
+ (gnus-header-name :foreground ,type)
+ (gnus-header-subject :foreground ,func :bold t)
+ (gnus-summary-markup-face :foreground ,const)
+ (gnus-summary-high-unread :foreground ,keyword :weight bold)
+ (gnus-summary-high-read :inherit gnus-summary-high-unread :weight normal)
+ (gnus-summary-high-ancient :inherit gnus-summary-high-read)
+ (gnus-summary-high-ticked :inherit gnus-summary-high-read :underline t)
+ (gnus-summary-normal-unread :foreground ,key2 :weight bold)
+ (gnus-summary-normal-read :inherit gnus-summary-normal-unread :weight normal)
+ (gnus-summary-normal-ancient :inherit gnus-summary-normal-read)
+ (gnus-summary-normal-ticked :inherit gnus-summary-normal-read :underline t)
+ (gnus-summary-low-unread :foreground ,comment :weight bold)
+ (gnus-summary-low-read :inherit gnus-summary-low-unread :weight normal)
+ (gnus-summary-low-ancient :inherit gnus-summary-low-read)
+ (gnus-summary-low-ticked :inherit gnus-summary-low-read :underline t)
+ (gnus-summary-selected :inverse-video t)
+ ;; helm
+ (helm-bookmark-w3m :foreground ,type)
+ (helm-buffer-not-saved :foreground ,type :background ,bg1)
+ (helm-buffer-process :foreground ,builtin :background ,bg1)
+ (helm-buffer-saved-out :foreground ,fg1 :background ,bg1)
+ (helm-buffer-size :foreground ,fg1 :background ,bg1)
+ (helm-candidate-number :foreground ,bg1 :background ,fg1)
+ (helm-ff-directory :foreground ,func :background ,bg1 :weight bold)
+ (helm-ff-executable :foreground ,key2 :background ,bg1 :weight normal)
+ (helm-ff-file :foreground ,fg1 :background ,bg1 :weight normal)
+ (helm-ff-invalid-symlink :foreground ,key3 :background ,bg1 :weight bold)
+ (helm-ff-prefix :foreground ,bg1 :background ,keyword :weight normal)
+ (helm-ff-symlink :foreground ,keyword :background ,bg1 :weight bold)
+ (helm-grep-cmd-line :foreground ,fg1 :background ,bg1)
+ (helm-grep-file :foreground ,fg1 :background ,bg1)
+ (helm-grep-finish :foreground ,fg2 :background ,bg1)
+ (helm-grep-lineno :foreground ,fg1 :background ,bg1)
+ (helm-grep-match :foreground nil :background nil :inherit helm-match)
+ (helm-grep-running :foreground ,func :background ,bg1)
+ (helm-header :foreground ,fg2 :background ,bg1 :underline nil :box nil)
+ (helm-moccur-buffer :foreground ,func :background ,bg1)
+ (helm-selection :background ,bg2 :underline nil)
+ (helm-selection-line :background ,bg2)
+ (helm-separator :foreground ,type :background ,bg1)
+ (helm-source-go-package-godoc-description :foreground ,str)
+ (helm-source-header :foreground ,keyword :background ,bg1 :underline nil :weight bold)
+ (helm-time-zone-current :foreground ,builtin :background ,bg1)
+ (helm-time-zone-home :foreground ,type :background ,bg1)
+ (helm-visible-mark :foreground ,bg1 :background ,bg3)
+ ;; highlight-indentation minor mode
+ (highlight-indentation-face :background ,bg2)
+ ;; icomplete
+ (icompletep-determined :foreground ,builtin)
+ ;; ido
+ (ido-first-match :foreground ,keyword :bold t)
+ (ido-only-match :foreground ,warning)
+ (ido-subdir :foreground ,builtin)
+ ;; isearch
+ (isearch :bold t :foreground ,warning :background ,bg3)
+ (isearch-fail :foreground ,bg1 :background ,warning)
+ ;; jde-java
+ (jde-java-font-lock-constant-face :foreground ,const)
+ (jde-java-font-lock-modifier-face :foreground ,key3)
+ (jde-java-font-lock-number-face :foreground ,var)
+ (jde-java-font-lock-package-face :foreground ,var)
+ (jde-java-font-lock-private-face :foreground ,keyword)
+ (jde-java-font-lock-public-face :foreground ,keyword)
+ ;; js2-mode
+ (js2-external-variable :foreground ,type )
+ (js2-function-param :foreground ,const)
+ (js2-jsdoc-html-tag-delimiter :foreground ,str)
+ (js2-jsdoc-html-tag-name :foreground ,key2)
+ (js2-jsdoc-value :foreground ,str)
+ (js2-private-function-call :foreground ,const)
+ (js2-private-member :foreground ,fg3)
+ ;; js3-mode
+ (js3-error-face :underline ,warning)
+ (js3-external-variable-face :foreground ,var)
+ (js3-function-param-face :foreground ,key3)
+ (js3-instance-member-face :foreground ,const)
+ (js3-jsdoc-tag-face :foreground ,keyword)
+ (js3-warning-face :underline ,keyword)
+ ;; magit
+ (magit-branch :foreground ,const :weight bold)
+ (magit-diff-context-highlight :background ,bg3 :foreground ,fg3)
+ (magit-diff-file-header :foreground ,fg2 :background ,bg3)
+ (magit-diffstat-added :foreground ,type)
+ (magit-diffstat-removed :foreground ,var)
+ (magit-hash :foreground ,fg2)
+ (magit-hunk-heading :background ,bg3)
+ (magit-hunk-heading-highlight :background ,bg3)
+ (magit-item-highlight :background ,bg3)
+ (magit-log-author :foreground ,fg3)
+ (magit-process-ng :foreground ,warning :weight bold)
+ (magit-process-ok :foreground ,func :weight bold)
+ (magit-section-heading :foreground ,keyword :weight bold)
+ (magit-section-highlight :background ,bg2)
+ ;; mode-line
+ (mode-line :foreground nil :background ,bg5 :box ,bg5)
+ (mode-line-inactive :foreground ,fg1 :background ,bg2 :box ,bg2)
+ ;; mu4e
+ (mu4e-cited-1-face :foreground ,fg2)
+ (mu4e-cited-7-face :foreground ,fg3)
+ (mu4e-header-marks-face :foreground ,type)
+ (mu4e-view-url-number-face :foreground ,type)
+ ;; org
+ (org-agenda-date :foreground ,rainbow-2 :underline nil)
+ (org-agenda-dimmed-todo-face :foreground ,comment)
+ (org-agenda-done :foreground ,rainbow-6)
+ (org-agenda-structure :foreground ,rainbow-3)
+ (org-block :foreground ,rainbow-5)
+ (org-code :foreground ,rainbow-7)
+ (org-column :background ,bg4)
+ (org-column-title :inherit org-column :weight bold :underline t)
+ (org-date :foreground ,rainbow-2 :underline t)
+ (org-document-info :foreground ,rainbow-8)
+ (org-document-info-keyword :foreground ,comment)
+ (org-document-title :weight bold :foreground ,rainbow-5 :height 1.44)
+ (org-done :foreground ,rainbow-6)
+ (org-ellipsis :foreground ,comment)
+ (org-footnote :foreground ,rainbow-8)
+ (org-formula :foreground ,rainbow-4)
+ (org-headline-done :foreground ,comment :bold nil :strike-through t)
+ (org-hide :foreground ,bg1 :background ,bg1)
+ (org-level-1 :inherit bold :foreground ,rainbow-4 :height 1.3)
+ (org-level-2 :inherit bold :foreground ,rainbow-3 :height 1.1)
+ (org-level-3 :bold nil :foreground ,rainbow-6 :height 1.0)
+ (org-level-4 :bold nil :foreground ,rainbow-7)
+ (org-level-5 :bold nil :foreground ,rainbow-2)
+ (org-level-6 :bold nil :foreground ,rainbow-5)
+ (org-level-7 :bold nil :foreground ,rainbow-8)
+ (org-level-8 :bold nil :foreground ,rainbow-1)
+ (org-link :foreground ,rainbow-2 :underline t)
+ (org-priority :foreground ,rainbow-2)
+ (org-scheduled :foreground ,rainbow-6)
+ (org-scheduled-previously :foreground ,rainbow-7)
+ (org-scheduled-today :foreground ,rainbow-6)
+ (org-sexp-date :foreground ,fg4)
+ (org-special-keyword :foreground ,rainbow-7)
+ (org-table :foreground ,rainbow-3)
+ (org-tag :foreground ,rainbow-4 :bold t :background ,bg2)
+ (org-todo :foreground ,rainbow-5 :bold t :background ,bg2)
+ (org-upcoming-deadline :foreground ,rainbow-7)
+ (org-warning :weight bold :foreground ,rainbow-4)
+ ;; outline
+ (outline-1 :foreground ,rainbow-6)
+ (outline-2 :foreground ,rainbow-3)
+ (outline-3 :foreground ,rainbow-2)
+ (outline-4 :foreground ,rainbow-5)
+ (outline-5 :foreground ,rainbow-5)
+ (outline-6 :foreground ,rainbow-8)
+ ;; powerline
+ (powerline-evil-base-face :foreground ,bg2)
+ (powerline-evil-emacs-face :inherit powerline-evil-base-face :background ,rainbow-7)
+ (powerline-evil-insert-face :inherit powerline-evil-base-face :background ,rainbow-2)
+ (powerline-evil-motion-face :inherit powerline-evil-base-face :background ,rainbow-3)
+ (powerline-evil-normal-face :inherit powerline-evil-base-face :background ,rainbow-6)
+ (powerline-evil-operator-face :inherit powerline-evil-base-face :background ,rainbow-4)
+ (powerline-evil-replace-face :inherit powerline-evil-base-face :background ,rainbow-9)
+ (powerline-evil-visual-face :inherit powerline-evil-base-face :background ,rainbow-5)
+ (powerline-active1 :background ,bg6 :foreground ,fg1)
+ (powerline-active2 :background ,bg6 :foreground ,fg1)
+ (powerline-inactive2 :background ,bg3 :foreground ,fg1)
+ (powerline-inactive2 :background ,bg3 :foreground ,fg1)
+ ;; rainbow-delimiters
+ (rainbow-delimiters-depth-1-face :foreground ,rainbow-1)
+ (rainbow-delimiters-depth-2-face :foreground ,rainbow-2)
+ (rainbow-delimiters-depth-3-face :foreground ,rainbow-3)
+ (rainbow-delimiters-depth-4-face :foreground ,rainbow-4)
+ (rainbow-delimiters-depth-5-face :foreground ,rainbow-5)
+ (rainbow-delimiters-depth-6-face :foreground ,rainbow-6)
+ (rainbow-delimiters-depth-7-face :foreground ,rainbow-7)
+ (rainbow-delimiters-depth-8-face :foreground ,rainbow-8)
+ (rainbow-delimiters-unmatched-face :foreground ,warning)
+ ;; rpm-spec
+ (rpm-spec-dir-face :foreground ,rainbow-6)
+ (rpm-spec-doc-face :foreground ,rainbow-4)
+ (rpm-spec-ghost-face :foreground ,rainbow-3)
+ (rpm-spec-macro-face :foreground ,rainbow-7)
+ (rpm-spec-obsolete-tag-face :inherit font-lock-warning-face)
+ (rpm-spec-package-face :foreground ,rainbow-3)
+ (rpm-spec-section-face :foreground ,rainbow-7)
+ (rpm-spec-tag-face :foreground ,rainbow-2)
+ (rpm-spec-var-face :foreground ,rainbow-10)
+ ;; slime
+ (slime-repl-inputed-output-face :foreground ,type)
+ ;; spam
+ (spam :inherit gnus-summary-normal-read :foreground ,warning :strike-through t :slant oblique)
+ ;; term
+ (term :foreground ,fg1 :background ,bg1)
+ (term-color-black :foreground ,bg3 :background ,bg3)
+ (term-color-blue :foreground ,type :background ,type)
+ (term-color-cyan :foreground ,const :background ,const)
+ (term-color-green :foreground ,func :background ,func)
+ (term-color-magenta :foreground ,keyword :background ,keyword)
+ (term-color-red :foreground ,rainbow-9 :background ,rainbow-9)
+ (term-color-white :foreground ,fg2 :background ,fg2)
+ (term-color-yellow :foreground ,str :background ,str)
+ ;; undo-tree
+ (undo-tree-visualizer-current-face :foreground ,builtin)
+ (undo-tree-visualizer-default-face :foreground ,fg2)
+ (undo-tree-visualizer-register-face :foreground ,type)
+ (undo-tree-visualizer-unmodified-face :foreground ,var)
+ ;; web-mode
+ (web-mode-builtin-face :inherit ,font-lock-builtin-face)
+ (web-mode-comment-face :inherit ,font-lock-comment-face)
+ (web-mode-constant-face :inherit ,font-lock-constant-face)
+ (web-mode-doctype-face :inherit ,font-lock-comment-face)
+ (web-mode-function-name-face :inherit ,font-lock-function-name-face)
+ (web-mode-html-attr-name-face :foreground ,type)
+ (web-mode-html-attr-value-face :foreground ,func)
+ (web-mode-html-tag-face :foreground ,keyword :bold t)
+ (web-mode-keyword-face :foreground ,keyword)
+ (web-mode-string-face :foreground ,str)
+ (web-mode-type-face :inherit ,font-lock-type-face)
+ (web-mode-warning-face :inherit ,font-lock-warning-face)
+ ;; which-func
+ (which-func :inherit ,font-lock-function-name-face)
+ (dired-directory :foreground ,func :weight normal)
+ (dired-flagged :foreground ,keyword)
+ (dired-header :foreground ,fg3 :background ,bg1)
+ (dired-ignored :inherit shadow)
+ (dired-mark :foreground ,var :weight bold)
+ (dired-marked :foreground ,builtin :weight bold)
+ (dired-perm-write :foreground ,fg3 :underline t)
+ (dired-symlink :foreground ,str :weight normal :slant italic)
+ (dired-warning :foreground ,warning :underline t)
+ (diredp-compressed-file-name :foreground ,fg3)
+ (diredp-compressed-file-suffix :foreground ,fg4)
+ (diredp-date-time :foreground ,var)
+ (diredp-deletion-file-name :foreground ,keyword :background ,bg5)
+ (diredp-deletion :foreground ,keyword :weight bold)
+ (diredp-dir-heading :foreground ,fg2 :background ,bg4)
+ (diredp-dir-name :inherit dired-directory)
+ (diredp-dir-priv :inherit dired-directory)
+ (diredp-executable-tag :foreground ,builtin)
+ (diredp-file-name :foreground ,fg1)
+ (diredp-file-suffix :foreground ,fg4)
+ (diredp-flag-mark-line :foreground ,fg2 :slant italic :background ,bg5)
+ (diredp-flag-mark :foreground ,fg2 :weight bold :background ,bg5)
+ (diredp-ignored-file-name :foreground ,fg1)
+ (diredp-mode-line-flagged :foreground ,warning)
+ (diredp-mode-line-marked :foreground ,warning)
+ (diredp-no-priv :foreground ,fg1)
+ (diredp-number :foreground ,const)
+ (diredp-other-priv :foreground ,builtin)
+ (diredp-rare-priv :foreground ,builtin)
+ (diredp-read-priv :foreground ,type)
+ (diredp-write-priv :foreground ,keyword)
+ (diredp-exec-priv :foreground ,str)
+ (diredp-symlink :foreground ,warning)
+ (diredp-link-priv :foreground ,warning)
+ (diredp-autofile-name :foreground ,str)
+ (diredp-tagged-autofile-name :foreground ,str)
+ (icicle-whitespace-highlight :background ,var)
+ (icicle-special-candidate :foreground ,fg2)
+ (icicle-extra-candidate :foreground ,fg2)
+ (icicle-search-main-regexp-others :foreground ,var)
+ (icicle-search-current-input :foreground ,keyword)
+ (icicle-search-context-level-8 :foreground ,warning)
+ (icicle-search-context-level-7 :foreground ,warning)
+ (icicle-search-context-level-6 :foreground ,warning)
+ (icicle-search-context-level-5 :foreground ,warning)
+ (icicle-search-context-level-4 :foreground ,warning)
+ (icicle-search-context-level-3 :foreground ,warning)
+ (icicle-search-context-level-2 :foreground ,warning)
+ (icicle-search-context-level-1 :foreground ,warning)
+ (icicle-search-main-regexp-current :foreground ,fg1)
+ (icicle-saved-candidate :foreground ,fg1)
+ (icicle-proxy-candidate :foreground ,fg1)
+ (icicle-mustmatch-completion :foreground ,type)
+ (icicle-multi-command-completion :foreground ,fg2 :background ,bg2)
+ (icicle-msg-emphasis :foreground ,func)
+ (icicle-mode-line-help :foreground ,fg4)
+ (icicle-match-highlight-minibuffer :foreground ,builtin)
+ (icicle-match-highlight-Completions :foreground ,func)
+ (icicle-key-complete-menu-local :foreground ,fg1)
+ (icicle-key-complete-menu :foreground ,fg1)
+ (icicle-input-completion-fail-lax :foreground ,keyword)
+ (icicle-input-completion-fail :foreground ,keyword)
+ (icicle-historical-candidate-other :foreground ,fg1)
+ (icicle-historical-candidate :foreground ,fg1)
+ (icicle-current-candidate-highlight :foreground ,warning :background ,bg3)
+ (icicle-Completions-instruction-2 :foreground ,fg4)
+ (icicle-Completions-instruction-1 :foreground ,fg4)
+ (icicle-completion :foreground ,var)
+ (icicle-complete-input :foreground ,builtin)
+ (icicle-common-match-highlight-Completions :foreground ,type)
+ (icicle-candidate-part :foreground ,var)
+ (icicle-annotation :foreground ,fg4))))
+
+ (apply #'custom-theme-set-faces
+ 'dracula
+ (let ((color-names (mapcar #'car colors))
+ (graphic-colors (mapcar #'cadr colors))
+ (tty-colors (mapcar #'car (mapcar #'last colors))))
+ (cl-flet* ((expand-for-tty (spec) (cl-progv color-names tty-colors
+ (eval `(backquote ,spec))))
+ (expand-for-graphic (spec) (cl-progv color-names graphic-colors
+ (eval `(backquote ,spec)))))
+ (cl-loop for (face . spec) in faces
+ collect `(,face
+ ((((min-colors 16777216))
+ ,(expand-for-graphic spec))
+ (t
+ ,(expand-for-tty spec)))))))))
+
+;;;###autoload
+(when load-file-name
+ (add-to-list 'custom-theme-load-path
+ (file-name-as-directory (file-name-directory load-file-name))))
+
+(provide-theme 'dracula)
+
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
+
+;;; dracula-theme.el ends here