emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/forth-mode 162b79f005: Better indentation in the presence


From: ELPA Syncer
Subject: [nongnu] elpa/forth-mode 162b79f005: Better indentation in the presence of POSTPONE.
Date: Wed, 29 Jun 2022 02:00:14 -0400 (EDT)

branch: elpa/forth-mode
commit 162b79f005a64b1f91e60b8f4c022d1d90cd3d95
Author: Helmut Eller <eller.helmut@gmail.com>
Commit: Lars Brinkhoff <lars@nocrew.org>

    Better indentation in the presence of POSTPONE.
    
    Make the SMIE lexer aware of POSTPONE, so that indentation isn't so
    easily messed up when POSTPONE quotes IF or other words relevant to
    indentation.
    
    * forth-smie.el (forth-smie--backward-token)
      (forth-smie--backward-token): Look at the next two words, so that we
      can recognize "POSTPONE IF" as a single token.
      (forth-smie--backward-word, forth-smie--forward-word): New helpers.
      (forth-smie--parsing-word-regexp): New precomputed regexp.
    
    * test/tests.el (forth-indent-postpone, forth-smie-backward-token)
      (forth-smie-forward-token): New tests.
      (forth-assert-backward-token,forth-assert-forward-token): New
      helpers.
---
 forth-smie.el | 40 ++++++++++++++++++++++++------
 test/tests.el | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 111 insertions(+), 9 deletions(-)

diff --git a/forth-smie.el b/forth-smie.el
index df6678151d..077f387894 100644
--- a/forth-smie.el
+++ b/forth-smie.el
@@ -75,19 +75,43 @@ This variable can also be set in .dir-locals.el, e.g.:
     (`(:list-intro . ,_) t)
     (_ nil)))
 
+(defconst forth-smie--parsing-word-regexp
+  (eval-when-compile
+    (concat "^"
+           (regexp-opt '("postpone" "[']" "[char]"))
+           "$")))
+
+(defun forth-smie--forward-word ()
+  (let* ((start (progn (skip-syntax-forward " ") (point)))
+        (end (progn (skip-syntax-forward "w_") (point))))
+    (buffer-substring-no-properties start end)))
+
+(defun forth-smie--backward-word ()
+  (let* ((end (progn (skip-syntax-backward " ") (point)))
+        (start (progn (skip-syntax-backward "w_") (point))))
+    (buffer-substring-no-properties start end)))
+
 (defun forth-smie--forward-token ()
   (forward-comment (point-max))
-  (downcase (buffer-substring-no-properties
-            (point)
-            (progn (skip-syntax-forward "w_")
-                   (point)))))
+  (let* ((word1 (downcase (forth-smie--forward-word)))
+        (pos1 (point))
+        (word2 (downcase (forth-smie--forward-word))))
+    (cond ((string-match forth-smie--parsing-word-regexp word1)
+          (list word1 word2))
+         (t
+          (goto-char pos1)
+          word1))))
 
 (defun forth-smie--backward-token ()
   (forward-comment (- (point)))
-  (downcase (buffer-substring-no-properties
-            (point)
-            (progn (skip-syntax-backward "w_")
-                   (point)))))
+  (let* ((word1 (downcase (forth-smie--backward-word)))
+        (pos1 (point))
+        (word2 (downcase (forth-smie--backward-word))))
+    (cond ((string-match forth-smie--parsing-word-regexp word2)
+          (list word2 word1))
+         (t
+          (goto-char pos1)
+          word1))))
 
 (defun forth-smie-setup ()
   (smie-setup (forth-smie--grammar) #'forth-smie--indentation-rules
diff --git a/test/tests.el b/test/tests.el
index 94a87d2d12..039319d41b 100644
--- a/test/tests.el
+++ b/test/tests.el
@@ -120,6 +120,22 @@ The whitespace before and including \"|\" on each line is 
removed."
         (progn . ,body)
         (kill-process proc))))
 
+(defun forth-assert-backward-token (content token)
+  (cl-destructuring-bind (content pos1 pos2) (forth-strip-|-and-¹² content)
+    (forth-with-temp-buffer content
+      (goto-char pos1)
+      (let ((token2 (forth-smie--backward-token)))
+       (should (equal token2 token))
+       (should (= (point) pos2))))))
+
+(defun forth-assert-forward-token (content token)
+  (cl-destructuring-bind (content pos1 pos2) (forth-strip-|-and-¹² content)
+    (forth-with-temp-buffer content
+      (goto-char pos1)
+      (let ((token2 (forth-smie--forward-token)))
+       (should (equal token2 token))
+       (should (= (point) pos2))))))
+
 (ert-deftest forth-paren-comment-font-lock ()
   (forth-assert-face "→( )" font-lock-comment-delimiter-face)
   (forth-assert-face "→.( )" font-lock-comment-face)
@@ -306,10 +322,44 @@ The whitespace before and including \"|\" on each line is 
removed."
    |    ;
    |execute"))
 
+(ert-deftest forth-indent-postpone ()
+  (forth-should-indent
+   ": foo
+   |  postpone :
+   |  42 postpone literal
+   |  postpone ;
+   |;")
+  (forth-should-indent
+   ": foo
+   |  POSTPONE :
+   |  42 POSTPONE literal
+   |  postpone ;
+   |;")
+  (forth-should-indent
+   ": foo
+   |  postpone if
+   |  if
+   |    postpone then
+   |  else
+   |    postpone then
+   |  then
+   |;")
+  (forth-should-indent
+   ": foo
+   |  ['] :
+   |  if
+   |    postpone ;
+   |  else
+   |    postpone recurse postpone ;
+   |  then
+   |;")
+  )
+
 (ert-deftest forth-sexp-movements ()
   (forth-assert-forward-sexp " ¹: foo bar ;² \ x")
   (forth-assert-forward-sexp " ¹:noname foo bar ;² \ x")
-  (forth-assert-forward-sexp " ¹if drop exit else 1+ then² bar "))
+  (forth-assert-forward-sexp " ¹if drop exit else 1+ then² bar ")
+  (forth-assert-forward-sexp " : foo ¹postpone if² postpone then ;"))
 
 ;; IDEA: give the filename in "include filename" string syntax.
 (ert-deftest forth-word-movements ()
@@ -386,3 +436,31 @@ The whitespace before and including \"|\" on each line is 
removed."
      "2c→"
      "2Constant→"
      #'completion-at-point)))
+
+(ert-deftest forth-smie-backward-token ()
+  (forth-assert-backward-token "²foo¹" "foo")
+  (forth-assert-backward-token "²foo-bar¹" "foo-bar")
+  (forth-assert-backward-token "  ²foo-bar  ¹baz" "foo-bar")
+  (forth-assert-backward-token " ²?#!-+  ¹" "?#!-+")
+  (forth-assert-backward-token " ²foo ( x y ) ¹" "foo")
+  (forth-assert-backward-token " foo \ x ²y  ¹" "y")
+  (forth-assert-backward-token " ²postpone foo¹" '("postpone" "foo"))
+  (forth-assert-backward-token " ²[']   foo ¹" '("[']" "foo"))
+  (forth-assert-backward-token " ²[char]  : ¹" '("[char]" ":"))
+  ;; We're mostly interested in getting indentation inside colon
+  ;; definitions right, so here we don't treat ' as parsing word.
+  (forth-assert-backward-token " ' ²foo¹" "foo")
+  (forth-assert-backward-token " : ²foo¹" "foo"))
+
+(ert-deftest forth-smie-forward-token ()
+  (forth-assert-forward-token "¹foo²" "foo")
+  (forth-assert-forward-token "¹foo-bar²" "foo-bar")
+  (forth-assert-forward-token "  ¹foo-bar²  baz" "foo-bar")
+  (forth-assert-forward-token " ¹?#!-+²  " "?#!-+")
+  (forth-assert-forward-token " ¹foo² ( x y )" "foo")
+  (forth-assert-forward-token " foo \ x ¹y² " "y")
+  (forth-assert-forward-token " ¹postpone foo²" '("postpone" "foo"))
+  (forth-assert-forward-token " ¹ [']   foo² " '("[']" "foo"))
+  (forth-assert-forward-token " ¹[char]  :² " '("[char]" ":"))
+  (forth-assert-forward-token " ¹'² foo" "'")
+  (forth-assert-forward-token " ¹:² foo" ":"))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]