-;;; sml-oldindent.el --- Old navigation and indentation functions for SML
+;;; sml-oldindent.el --- Navigation and indentation for SML without SMIE
-;; Copyright (C) 1999, 2000, 2004, 2007, 2010 Stefan Monnier <monnier@gnu.org>
+;; 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
(eval-when-compile (require 'cl))
(require 'sml-defs)
-;;; First code previously help in sml-util.el and sml-defs.el.
-
-(require 'cl) ;for `reduce'
(defun sml-preproc-alist (al)
"Expand an alist AL where keys can be lists of keys into a normal one."
- (reduce (lambda (x al)
- (let ((k (car x))
- (v (cdr x)))
- (if (consp k)
- (append (mapcar (lambda (y) (cons y v)) k) al)
- (cons x al))))
- al
- :initial-value nil
- :from-end t))
-
-
+ (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
(defconst sml-agglomerate-re "\\<else[ \t]+if\\>"
"Regexp of compound symbols (pairs of symbols to be considered as one).")
-;;; Then, the buffer navigation (formerly sml-move.el).
-
(defvar sml-internal-syntax-table
(let ((st (make-syntax-table sml-mode-syntax-table)))
(modify-syntax-entry ?_ "w" st)
t))
;;;
-;; read a symbol, including the special "op <sym>" case
+;;; Read a symbol, including the special "op <sym>" case
;;;
(defmacro sml-move-read (&rest body)
(defun sml-backward-arg () (sml-backward-sexp 1000))
(defun sml-forward-arg () (sml-forward-sexp 1000))
-;;; Then the indentation code (previously in sml-mode.el).
+(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."
(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-indent-arg)
(sml-indent-default))))))
-(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))))
-
(defsubst sml-bolp ()
(save-excursion (skip-chars-backward " \t|") (bolp)))
(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."
(if (member sym '(";" "d=")) (setq sym nil))
(if sym (sml-get-sym-indent sym)
;; FIXME: this can take a *long* time !!
- (setq sym (sml-find-matching-starter sml-starters-syms))
+ (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-delegated-indent))))
(defun sml-indent-pipe ()
- (let ((sym (sml-find-matching-starter sml-pipeheads
- (sml-op-prec "|" 'back))))
+ (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))
(current-column)))
-(defun sml-find-matching-starter (syms &optional prec)
+(defun sml-old-find-matching-starter (syms &optional prec)
(let (sym)
(ignore-errors
(while
(not (or (member sym syms) (bobp)))))
(if (member sym syms) sym))))
-(provide 'sml-move)
+(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