(eval-when-compile (require 'cl))
(require 'sml-defs)
-(require 'sml-oldindent)
-
-(defvar sml-use-smie t)
-
(require 'smie nil 'noerror)
-(unless (and sml-use-smie (fboundp 'smie-setup))
- (require 'sml-oldindent))
(condition-case nil (require 'skeleton) (error nil))
:type '(integer))
(defcustom sml-indent-args sml-indent-level
- "*Indentation of args placed on a separate line."
+ "Indentation of args placed on a separate line."
:group 'sml
:type '(integer))
;; seems nicer...")
(defcustom sml-electric-semi-mode nil
- "*If non-nil, `\;' will self insert, reindent the line, and do a newline.
+ "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] \;)."
:group 'sml
: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.
;;; Indentation with SMIE
+(defvar sml-use-smie t)
+(unless (and sml-use-smie (fboundp 'smie-setup))
+ (require 'sml-oldindent))
+
(defconst sml-smie-grammar
(when (fboundp 'smie-prec2->grammar)
;; We have several problem areas where SML's syntax can't be handled by an
Assumes point is right before the | symbol."
(save-excursion
(forward-char 1) ;Skip the |.
- (sml-smie-forward-token-1) ;Skip the tag.
- (member (sml-smie-forward-token-1)
- '("|" "of" "in" "datatype" "and" "exception" "abstype" "infix"
- "infixr" "nonfix" "local" "val" "fun" "structure" "functor"
- "signature"))))
+ (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))
;;;###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 fundamental-mode "SML"
+(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 '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))
-(defvar comment-quote-nested)
-
(defun sml-mode-variables ()
(set-syntax-table sml-mode-syntax-table)
(setq local-abbrev-table sml-mode-abbrev-table)
;; Setup indentation and sexp-navigation.
- (cond
- ((and sml-use-smie (fboundp 'smie-setup))
+ (when (fboundp 'smie-setup)
(smie-setup sml-smie-grammar #'sml-smie-rules
:backward-token #'sml-smie-backward-token
:forward-token #'sml-smie-forward-token))
- (t
+ (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 '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) " *)")
(insert "| ")
(let ((text
(save-excursion
- (funcall forward-sexp-function -1)
- (let ((sym (save-excursion (sml-smie-backward-token))))
+ (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 "|") "") ;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
If variable `sml-electric-semi-mode' is t, indent the current line, insert
a newline, and indent."
(interactive)
- (insert "\;")
+ (self-insert-command 1)
(if sml-electric-semi-mode
(reindent-then-newline-and-indent)))
(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 ()
- (while (and (not (bobp)) (sml-backward-arg))
- (sml-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-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)))
(defun sml-defuse-symdata-at-point ()
(save-excursion
(sml-smie-forward-token)
- (let ((symname (sml-backward-sym)))
+ (let ((symname (sml-smie-backward-token)))
(if (equal symname "op")
(save-excursion (setq symname (sml-smie-forward-token))))
(when (string-match "op " symname)
(skip-syntax-forward " ")
(- (current-column) 2))))))
;; default to SML rules
- (sml-calculate-indentation))))
+ (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))