branch: elpa/haskell-tng-mode commit f5961e6f73826a2755f9dd5d5a0f6548b989322a Author: Tseen She <ts33n....@gmail.com> Commit: Tseen She <ts33n....@gmail.com>
indentation cycles are really complicated... --- haskell-tng-smie.el | 37 +++++++++++++++++++++++++++---------- test/haskell-tng-indent-test.el | 17 ++++++----------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/haskell-tng-smie.el b/haskell-tng-smie.el index 74d11f8..1e5de6f 100644 --- a/haskell-tng-smie.el +++ b/haskell-tng-smie.el @@ -101,20 +101,31 @@ (and (not (smie-rule-bolp)) (smie-rule-prev-p "else") (smie-rule-parent))))) -(defun haskell-tng:indent-cycle () +(defvar-local haskell-tng-smie:indenting nil + "Stores if the last command was an indentation. + +This works around `this-command' / `last-command' being nil in +the tests and also covering the multitude of indentation commands +that will inevitably call `smie-indent'.") +(defun haskell-tng-smie:indent-invalidation (_beg _end _pre-length) + (setq haskell-tng-smie:indenting nil)) + +(defun haskell-tng-smie:indent-cycle () "Returns the next alternative indentation level from a ring." - (when (and + ;; detecting newline then TAB, or double TAB, is really hard... needs to not + ;; consider double newline. TODO make the detection better. + (message "CHECKING INDENT CYCLE %s" haskell-tng-smie:indenting) + + (if (not haskell-tng-smie:indenting) + (setq haskell-tng-smie:indenting 't) + + (when (and (eq major-mode 'haskell-tng-mode) ;; smie-indent-functions is global (eq this-command last-command) - (or - ;; FIXME detecting double TAB is really hard... - ;;(and (message "THIS=%s LAST=%s" this-command last-command) nil) - (eq this-command #'indent-for-tab-command) - ;; maybe other typical TAB bindings here - )) + nil) ;; TODO implement (message "CALLING INDENT CYCLE FROM %s" this-command) - 2)) + 2))) (defun haskell-tng-smie:setup () (setq-local smie-indent-basic 2) @@ -129,7 +140,13 @@ (add-to-list 'smie-indent-functions - #'haskell-tng:indent-cycle) + #'haskell-tng-smie:indent-cycle) + + ;; FIXME this isn't the correct invalidation as it will fire while cycling + ;; through TAB. + (add-to-list + 'after-change-functions + #'haskell-tng-smie:indent-invalidation) (smie-setup haskell-tng-smie:grammar diff --git a/test/haskell-tng-indent-test.el b/test/haskell-tng-indent-test.el index f0aacd2..75fef90 100644 --- a/test/haskell-tng-indent-test.el +++ b/test/haskell-tng-indent-test.el @@ -40,13 +40,14 @@ (while (not (eobp)) (end-of-line) (let ((indent (list (current-line-string))) - alts tmp-this tmp-last) - (funcall-interactively #'newline-and-indent) + alts) + (call-interactively #'newline-and-indent) (push (current-column) indent) ;; TODO a better way to get the alts - (while (< (length alts) 10) - (funcall-interactively #'indent-for-tab-command) + (while (< (length alts) 1) + (message "LOOPING %s %s" this-command last-command) + (call-interactively #'indent-for-tab-command) (push (current-column) alts)) (setq indent @@ -54,13 +55,7 @@ (append (reverse indent) (reverse alts)))) (push indent indents) - (setq - tmp-this this-command - tmp-last last-command) - (kill-whole-line) - (setq - this-command tmp-this - last-command tmp-last))) + (kill-whole-line))) (reverse indents))) (defun haskell-tng-indent-test:indents-to-string (indents)