Mercurial > emacs
changeset 108797:d674108e8753
Provide hooks to use a different tokenizer in SMIE.
* lisp/emacs-lisp/smie.el (smie-forward-token-function)
(smie-backward-token-function): New vars.
(smie-backward-sexp, smie-forward-sexp)
(smie-indent-hanging-p, smie-indent-calculate): Use them.
(smie-default-backward-token): Rename from smie-backward-token and
skip comments.
(smie-default-forward-token): Rename from smie-forward-token and
skip comments.
(smie-next-sexp): Handle nil results from next-token.
(smie-indent-calculate): Add a new case for special `fixindent' comments.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Thu, 27 May 2010 00:41:36 -0400 |
parents | 7a3558eb670e |
children | dedcf813aa69 |
files | lisp/ChangeLog lisp/emacs-lisp/smie.el |
diffstat | 2 files changed, 59 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/ChangeLog Wed May 26 10:19:15 2010 -0400 +++ b/lisp/ChangeLog Thu May 27 00:41:36 2010 -0400 @@ -1,3 +1,16 @@ +2010-05-27 Stefan Monnier <monnier@iro.umontreal.ca> + + * emacs-lisp/smie.el (smie-forward-token-function) + (smie-backward-token-function): New vars. + (smie-backward-sexp, smie-forward-sexp) + (smie-indent-hanging-p, smie-indent-calculate): Use them. + (smie-default-backward-token): Rename from smie-backward-token and + skip comments. + (smie-default-forward-token): Rename from smie-forward-token and + skip comments. + (smie-next-sexp): Handle nil results from next-token. + (smie-indent-calculate): Add a new case for special `fixindent' comments. + 2010-05-26 Stefan Monnier <monnier@iro.umontreal.ca> * progmodes/ada-xref.el (ada-gnat-parse-gpr):
--- a/lisp/emacs-lisp/smie.el Wed May 26 10:19:15 2010 -0400 +++ b/lisp/emacs-lisp/smie.el Thu May 27 00:41:36 2010 -0400 @@ -294,18 +294,30 @@ Each element is of the form (TOKEN LEFT-LEVEL RIGHT-LEVEL). Parsing is done using an operator precedence parser.") +(defvar smie-forward-token-function 'smie-default-forward-token + "Function to scan forward for the next token. +Called with no argument should return a token and move to its end. +If no token is found, return nil or the empty string. +It can return nil when bumping into a parenthesis, which lets SMIE +use syntax-tables to handle them in efficient C code.") + +(defvar smie-backward-token-function 'smie-default-backward-token + "Function to scan backward the previous token. +Same calling convention as `smie-forward-token-function' except +it should move backward to the beginning of the previous token.") + (defalias 'smie-op-left 'car) (defalias 'smie-op-right 'cadr) -(defun smie-backward-token () - ;; FIXME: This may be an OK default but probably needs a hook. +(defun smie-default-backward-token () + (forward-comment (- (point))) (buffer-substring (point) (progn (if (zerop (skip-syntax-backward ".")) (skip-syntax-backward "w_'")) (point)))) -(defun smie-forward-token () - ;; FIXME: This may be an OK default but probably needs a hook. +(defun smie-default-forward-token () + (forward-comment (point-max)) (buffer-substring (point) (progn (if (zerop (skip-syntax-forward ".")) (skip-syntax-forward "w_'")) @@ -352,7 +364,7 @@ (cond ((null toklevels) - (when (equal token "") + (when (zerop (length token)) (condition-case err (progn (goto-char pos) (funcall next-sexp 1) nil) (scan-error (throw 'return (list t (caddr err))))) @@ -409,7 +421,7 @@ (nil POS TOKEN): we skipped over a paren-like pair. nil: we skipped over an identifier, matched parentheses, ..." (smie-next-sexp - (lambda () (forward-comment (- (point-max))) (smie-backward-token)) + (indirect-function smie-backward-token-function) (indirect-function 'backward-sexp) (indirect-function 'smie-op-left) (indirect-function 'smie-op-right) @@ -427,7 +439,7 @@ (nil POS TOKEN): we skipped over a paren-like pair. nil: we skipped over an identifier, matched parentheses, ..." (smie-next-sexp - (lambda () (forward-comment (point-max)) (smie-forward-token)) + (indirect-function smie-forward-token-function) (indirect-function 'forward-sexp) (indirect-function 'smie-op-right) (indirect-function 'smie-op-left) @@ -486,10 +498,14 @@ A nil offset defaults to `smie-indent-basic'.") (defun smie-indent-hanging-p () - ;; A Hanging keyword is one that's at the end of a line except it's not at + ;; A hanging keyword is one that's at the end of a line except it's not at ;; the beginning of a line. - (and (save-excursion (smie-forward-token) - (skip-chars-forward " \t") (eolp)) + (and (save-excursion + (when (zerop (length (funcall smie-forward-token-function))) + ;; Could be an open-paren. + (forward-char 1)) + (skip-chars-forward " \t") + (eolp)) (save-excursion (skip-chars-backward " \t") (not (bolp))))) (defun smie-bolp () @@ -518,9 +534,18 @@ (and virtual (if (eq virtual :hanging) (not (smie-indent-hanging-p)) (smie-bolp)) (current-column)) + ;; Obey the `fixindent' special comment. + (when (save-excursion + (comment-normalize-vars) + (re-search-forward (concat comment-start-skip + "fixindent" + comment-end-skip) + ;; 1+ to account for the \n comment termination. + (1+ (line-end-position)) t)) + (current-column)) ;; Start the file at column 0. (save-excursion - (forward-comment (- (point-max))) + (forward-comment (- (point))) (if (bobp) 0)) ;; Align close paren with opening paren. (save-excursion @@ -537,7 +562,7 @@ ;; (e.g. "of" with "case", or "in" with "let"). (save-excursion (let* ((pos (point)) - (token (smie-forward-token)) + (token (funcall smie-forward-token-function)) (toklevels (cdr (assoc token smie-op-levels)))) (when (car toklevels) (let ((res (smie-backward-sexp 'halfsexp)) tmp) @@ -555,8 +580,7 @@ ;; So as to align with the earliest appropriate place. (smie-indent-calculate :bolp)) ((equal token (save-excursion - (forward-comment (- (point-max))) - (smie-backward-token))) + (funcall smie-backward-token-function))) ;; in cases such as "fn x => fn y => fn z =>", ;; jump back to the very first fn. ;; FIXME: should we only do that for special tokens like "=>"? @@ -574,7 +598,8 @@ (forward-comment (point-max)) (skip-chars-forward " \t\r\n") (smie-indent-calculate nil))) - ;; Indentation inside a comment. + ;; indentation inside a comment. + ;; FIXME: Hey, this is not generic!! (and (looking-at "\\*") (nth 4 (syntax-ppss)) (let ((ppss (syntax-ppss))) (save-excursion @@ -586,8 +611,7 @@ (current-column)))))) ;; Indentation right after a special keyword. (save-excursion - (let* ((tok (progn (forward-comment (- (point-max))) - (smie-backward-token))) + (let* ((tok (funcall smie-backward-token-function)) (tokinfo (assoc tok smie-indent-rules)) (toklevel (assoc tok smie-op-levels))) (when (or tokinfo (and toklevel (null (cadr toklevel)))) @@ -613,8 +637,7 @@ ;; Figure out if the atom we just skipped is an argument rather ;; than a function. (setq arg (or (null (car (smie-backward-sexp))) - (member (progn (forward-comment (- (point-max))) - (smie-backward-token)) + (member (funcall smie-backward-token-function) (cdr (assoc 'list-intro smie-indent-rules)))))) (cond ((and arg positions) @@ -637,11 +660,12 @@ (current-column))) ((and (null arg) (null positions)) ;; We're the function itself. Not sure what to do here yet. + ;; FIXME: This should not be possible, because it should mean + ;; we're right after some special token. (if virtual (current-column) (save-excursion (let* ((pos (point)) - (tok (progn (forward-comment (- (point-max))) - (smie-backward-token))) + (tok (funcall smie-backward-token-function)) (toklevels (cdr (assoc tok smie-op-levels)))) (cond ((numberp (car toklevels)) @@ -669,7 +693,7 @@ ;; For other cases.... hmm... we'll see when we get there. ))))) ((null positions) - (smie-backward-token) + (funcall smie-backward-token-function) (+ (smie-indent-offset 'args) (smie-indent-calculate :bolp))) ((car (smie-backward-sexp)) ;; No arg stands on its own line, but the function does: