- :elem, in which case the function should return either:
- the offset to use to indent function arguments (ARG = `arg')
- the basic indentation step (ARG = `basic').
+ - the token to use (when ARG = `empty-line-token') when we don't know how
+ to indent an empty line.
- :list-intro, in which case ARG is a token and the function should return
non-nil if TOKEN is followed by a list of expressions (not separated by any
token) rather than an expression.
(+ (smie-indent-virtual) (smie-indent--offset 'basic))) ;
(t (smie-indent-virtual)))))) ;An infix.
+(defun smie-indent-empty-line ()
+ "Indentation rule when there's nothing yet on the line."
+ ;; Without this rule, SMIE assumes that an empty line will be filled with an
+ ;; argument (since it falls back to smie-indent-sexps), which tends
+ ;; to indent far too deeply.
+ (when (eolp)
+ (let ((token (or (funcall smie-rules-function :elem 'empty-line-token)
+ ;; FIXME: Should we default to ";"?
+ ;; ";"
+ )))
+ (when (assoc token smie-grammar)
+ (smie-indent-keyword token)))))
+
(defun smie-indent-exps ()
;; Indentation of sequences of simple expressions without
;; intervening keywords or operators. E.g. "a b c" or "g (balbla) f".
smie-indent-comment smie-indent-comment-continue smie-indent-comment-close
smie-indent-comment-inside smie-indent-inside-string
smie-indent-keyword smie-indent-after-keyword
- smie-indent-exps)
+ smie-indent-empty-line smie-indent-exps)
"Functions to compute the indentation.
Each function is called with no argument, shouldn't move point, and should
return either nil if it has no opinion, or an integer representing the column
(concat (unless (eq comment-use-syntax t)
;; `syntax-ppss' will detect escaping.
"\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)")
- "\\(\\s<+\\|"
+ "\\(?:\\s<+\\|"
(regexp-quote (comment-string-strip comment-start t t))
;; Let's not allow any \s- but only [ \t] since \n
;; might be both a comment-end marker and \s-.
(defun prolog-smie-rules (kind token)
(pcase (cons kind token)
(`(:elem . basic) prolog-indent-width)
+ ;; The list of arguments can never be on a separate line!
+ (`(:list-intro . ,_) t)
+ ;; When we don't know how to indent an empty line, assume the most
+ ;; likely token will be ";".
+ (`(:elem . empty-line-token) ";")
(`(:after . ".") '(column . 0)) ;; To work around smie-closer-alist.
;; Allow indentation of if-then-else as:
;; ( test
(setq-local comment-start "%")
(setq-local comment-end "")
(setq-local comment-add 1)
- (setq-local comment-start-skip "\\(?:/\\*+ *\\|%%+ *\\)")
+ (setq-local comment-start-skip "\\(?:/\\*+ *\\|%+ *\\)")
(setq-local parens-require-spaces nil)
;; Initialize Prolog system specific variables
(dolist (var '(prolog-keywords prolog-types prolog-mode-specificators