]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/sml-mode/sml-mode.el
Merge commit '7c14dedc79bf0c6eaad5bf50b80ea80dd721afdc' from company
[gnu-emacs-elpa] / packages / sml-mode / sml-mode.el
index c564b39bf00ab1fd1056f14be7f645b4d4948f3d..ac6ad2f9e08fe4883c1c1510714b58620f616623 100644 (file)
@@ -1,9 +1,9 @@
 ;;; sml-mode.el --- Major mode for editing (Standard) ML  -*- lexical-binding: t; coding: utf-8 -*-
 
-;; Copyright (C) 1989,1999,2000,2004,2007,2010-2013  Free Software Foundation, Inc.
+;; Copyright (C) 1989,1999,2000,2004,2007,2010-2014  Free Software Foundation, Inc.
 
 ;; Maintainer: (Stefan Monnier) <monnier@iro.umontreal.ca>
-;; Version: 6.3
+;; Version: 6.5
 ;; Keywords: SML
 ;; Author:     Lars Bo Nielsen
 ;;             Olin Shivers
@@ -446,6 +446,8 @@ Regexp match data 0 points to the chars."
               (decls "nonfix" decls)
               (decls "abstype" decls)
               (decls "datatype" decls)
+              (decls "include" decls)
+              (decls "sharing" decls)
               (decls "exception" decls)
               (decls "fun" decls)
               (decls "val" decls))
@@ -466,7 +468,7 @@ Regexp match data 0 points to the chars."
      '((assoc "->") (assoc "*"))
      '((assoc "val" "fun" "type" "datatype" "abstype" "open" "infix" "infixr"
               "nonfix" "functor" "signature" "structure" "exception"
-              ;; "local"
+              "include" "sharing" "local"
               )
        (assoc "and"))
      '((assoc "orelse") (assoc "andalso") (nonassoc ":"))
@@ -485,6 +487,30 @@ Regexp match data 0 points to the chars."
 
 (defvar sml-indent-separator-outdent 2)
 
+(defun sml--rightalign-and-p ()
+  (when sml-rightalign-and
+    ;; Only right-align the "and" if the intervening code is more deeply
+    ;; indented, to avoid things like:
+    ;; datatype foo
+    ;;   = Foo of int
+    ;;      and bar = Bar of string
+    (save-excursion
+      (let ((max (line-end-position 0))
+            (data (smie-backward-sexp "and"))
+            (startcol (save-excursion
+                        (forward-comment (- (point)))
+                        (current-column)))
+            (mincol (current-column)))
+        (save-excursion
+          (search-forward "=" max t)
+          (forward-line 1)
+          (if (< (point) max) (setq max (point))))
+        (while (and (<= (point) max) (not (eobp)))
+          (skip-chars-forward " \t")
+          (setq mincol (current-column))
+          (forward-line 1))
+        (>= mincol startcol)))))
+
 (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
@@ -494,6 +520,7 @@ Regexp match data 0 points to the chars."
              (basic sml-indent-level)
              (args  sml-indent-args)))
     (:list-intro (member token '("fn")))
+    (:close-all t)
     (:after
      (cond
       ((equal token "struct") 0)
@@ -514,7 +541,7 @@ Regexp match data 0 points to the chars."
       ((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" "(" "[" "{"))
+      ((member token '("let" "(" "[" "{")) ; "struct"? "sig"?
        (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.
@@ -525,12 +552,12 @@ Regexp match data 0 points to the chars."
       ((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 "datatype") (if (sml--rightalign-and-p) 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)))
+        ((smie-rule-parent-p "structure" "signature" "functor") 0)))
       ;; Indent an expression starting with "local" as if it were starting
       ;; with "fun".
       ((equal token "local") (smie-indent-keyword "fun"))
@@ -562,31 +589,9 @@ Assumes point is right before the = sign."
   ;; 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))))
-               )))))
+  (save-excursion
+    (let ((res (smie-backward-sexp "=")))
+      (member (nth 2 res) `(":" ,@sml-=-starter-syms)))))
 
 (defun sml-smie-non-nested-of-p ()
   ;; FIXME: Maybe datatype-|-p makes this nested-of business unnecessary.
@@ -656,7 +661,7 @@ Assumes point is right before the | symbol."
 ;;;; Imenu support
 ;;;;
 
-(defvar sml-imenu-regexp
+(defconst sml-imenu-regexp
   (concat "^[ \t]*\\(let[ \t]+\\)?"
          (regexp-opt (append sml-module-head-syms
                              '("and" "fun" "datatype" "abstype" "type")) t)
@@ -678,9 +683,9 @@ Assumes point is right before the | symbol."
              (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")))
+                   (when (search-forward "=" nil t)
+                      (forward-comment (point-max))
+                      (looking-at "sig\\|struct")))
            (push (cons (concat (make-string (/ column 2) ?\ ) name) location)
                  alist)))))
     alist))