1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-03 18:41:25 -08:00

Provide a simple generic indentation engine and use it for Prolog.

* emacs-lisp/smie.el: New file.
* progmodes/prolog.el (prolog-smie-op-levels)
(prolog-smie-indent-rules): New var.
(prolog-mode-variables): Use them to configure SMIE.
(prolog-indent-line, prolog-indent-level): Remove.
This commit is contained in:
Stefan Monnier 2010-05-17 15:27:26 -04:00
parent 16455a8509
commit 5ad4bef575
5 changed files with 769 additions and 64 deletions

View file

@ -98,6 +98,61 @@ When nil, send actual operating system end of file."
(defvar prolog-mode-abbrev-table nil)
(define-abbrev-table 'prolog-mode-abbrev-table ())
(defconst prolog-smie-op-levels
;; Rather than construct the operator levels table from the BNF,
;; we directly provide the operator precedences from GNU Prolog's
;; manual. The only problem is that GNU Prolog's manual uses
;; precedence levels in the opposite sense (higher numbers bind less
;; tightly) than SMIE, so we use negative numbers.
'(("." -10000 -10000)
(":-" -1200 -1200)
("-->" -1200 -1200)
(";" -1100 -1100)
("->" -1050 -1050)
("," -1000 -1000)
("\\+" -900 -900)
("=" -700 -700)
("\\=" -700 -700)
("=.." -700 -700)
("==" -700 -700)
("\\==" -700 -700)
("@<" -700 -700)
("@=<" -700 -700)
("@>" -700 -700)
("@>=" -700 -700)
("is" -700 -700)
("=:=" -700 -700)
("=\\=" -700 -700)
("<" -700 -700)
("=<" -700 -700)
(">" -700 -700)
(">=" -700 -700)
(":" -600 -600)
("+" -500 -500)
("-" -500 -500)
("/\\" -500 -500)
("\\/" -500 -500)
("*" -400 -400)
("/" -400 -400)
("//" -400 -400)
("rem" -400 -400)
("mod" -400 -400)
("<<" -400 -400)
(">>" -400 -400)
("**" -200 -200)
("^" -200 -200)
;; Prefix
;; ("+" 200 200)
;; ("-" 200 200)
;; ("\\" 200 200)
)
"Precedence levels of infix operators.")
(defconst prolog-smie-indent-rules
'((":-")
("->"))
"Prolog indentation rules.")
(defun prolog-mode-variables ()
(make-local-variable 'paragraph-separate)
(setq paragraph-separate (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
@ -105,8 +160,10 @@ When nil, send actual operating system end of file."
(setq paragraph-ignore-fill-prefix t)
(make-local-variable 'imenu-generic-expression)
(setq imenu-generic-expression '((nil "^\\sw+" 0)))
(make-local-variable 'indent-line-function)
(setq indent-line-function 'prolog-indent-line)
(smie-setup prolog-smie-op-levels prolog-smie-indent-rules)
(set (make-local-variable 'forward-sexp-function)
'smie-forward-sexp-command)
(set (make-local-variable 'smie-indent-basic) prolog-indent-width)
(make-local-variable 'comment-start)
(setq comment-start "%")
(make-local-variable 'comment-start-skip)
@ -149,65 +206,6 @@ if that value is non-nil."
nil nil nil
beginning-of-line)))
(defun prolog-indent-line ()
"Indent current line as Prolog code.
With argument, indent any additional lines of the same clause
rigidly along with this one (not yet)."
(interactive "p")
(let ((indent (prolog-indent-level))
(pos (- (point-max) (point))))
(beginning-of-line)
(indent-line-to indent)
(if (> (- (point-max) pos) (point))
(goto-char (- (point-max) pos)))))
(defun prolog-indent-level ()
"Compute Prolog indentation level."
(save-excursion
(beginning-of-line)
(skip-chars-forward " \t")
(cond
((looking-at "%%%") 0) ;Large comment starts
((looking-at "%[^%]") comment-column) ;Small comment starts
((bobp) 0) ;Beginning of buffer
(t
(let ((empty t) ind more less)
(if (looking-at ")")
(setq less t) ;Find close
(setq less nil))
;; See previous indentation
(while empty
(forward-line -1)
(beginning-of-line)
(if (bobp)
(setq empty nil)
(skip-chars-forward " \t")
(if (not (or (looking-at "%[^%]") (looking-at "\n")))
(setq empty nil))))
(if (bobp)
(setq ind 0) ;Beginning of buffer
(setq ind (current-column))) ;Beginning of clause
;; See its beginning
(if (looking-at "%%[^%]")
ind
;; Real prolog code
(if (looking-at "(")
(setq more t) ;Find open
(setq more nil))
;; See its tail
(end-of-prolog-clause)
(or (bobp) (forward-char -1))
(cond ((looking-at "[,(;>]")
(if (and more (looking-at "[^,]"))
(+ ind prolog-indent-width) ;More indentation
(max tab-width ind))) ;Same indentation
((looking-at "-") tab-width) ;TAB
((or less (looking-at "[^.]"))
(max (- ind prolog-indent-width) 0)) ;Less indentation
(t 0)) ;No indentation
)))
)))
(defun end-of-prolog-clause ()
"Go to end of clause in this line."
(beginning-of-line 1)