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

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

[nongnu] elpa/haskell-tng-mode 01ea0b8 103/385: heuristic alternative in


From: ELPA Syncer
Subject: [nongnu] elpa/haskell-tng-mode 01ea0b8 103/385: heuristic alternative indentation levels
Date: Tue, 5 Oct 2021 23:59:10 -0400 (EDT)

branch: elpa/haskell-tng-mode
commit 01ea0b83d5130d85e036a84fc862e108fa61e820
Author: Tseen She <ts33n.sh3@gmail.com>
Commit: Tseen She <ts33n.sh3@gmail.com>

    heuristic alternative indentation levels
---
 haskell-tng-rx.el                |   3 +
 haskell-tng-smie.el              |  57 +++++----
 test/haskell-tng-indent-test.el  |  57 ++++-----
 test/src/layout.hs.insert.indent |  36 +++---
 test/src/medley.hs.insert.indent | 266 +++++++++++++++++++--------------------
 5 files changed, 216 insertions(+), 203 deletions(-)

diff --git a/haskell-tng-rx.el b/haskell-tng-rx.el
index 165da7e..d8cac08 100644
--- a/haskell-tng-rx.el
+++ b/haskell-tng-rx.el
@@ -44,6 +44,7 @@ give false positives." `(|
     (: ,(if hack
             '(| symbol-start word-end point)
           '(| symbol-start word-end))
+       ;; EXT:UnicodeSyntax (also grammar)
        (| ".." "::" ":" "=" "|" "<-" "->" "@" "~" "=>")
        ,(if hack
             '(| symbol-end word-start point)
@@ -89,6 +90,8 @@ give false positives." `(|
   (rx-to-string `(: word-start ,haskell-tng:rx:varid)))
 (defconst haskell-tng:regexp:symid
   (rx-to-string haskell-tng:rx:symid))
+(defconst haskell-tng:regexp:toplevel
+  (rx-to-string haskell-tng:rx:toplevel))
 
 (provide 'haskell-tng-rx)
 ;;; haskell-tng-rx.el ends here
diff --git a/haskell-tng-smie.el b/haskell-tng-smie.el
index 6139fbc..bfec21e 100644
--- a/haskell-tng-smie.el
+++ b/haskell-tng-smie.el
@@ -62,13 +62,13 @@
 
       ;; WLDOs
       (wldo
-       (block "where" block)
-       ("let" block "in")
-       ("do" block)
-       ("case" id "of" block))
-      (block
-       ("{" block "}")
-       (block ";" block)
+       (blk "where" blk)
+       ("let" blk "in")
+       ("do" blk)
+       ("case" id "of" blk))
+      (blk
+       ("{" blk "}")
+       (blk ";" blk)
        (id "=" id)
        (id "<-" id)
        (id "->" id)
@@ -90,7 +90,7 @@
 ;; 
https://github.com/elixir-editors/emacs-elixir/blob/master/test/test-helper.el#L52-L63
 (defun haskell-tng-smie:rules (method arg)
   ;; see docs for `smie-rules-function'
-  ;; TODO implement indentation
+  ;; FIXME implement prime indentation
   (pcase (cons method arg)
     (`(:elem . basic) smie-indent-basic)
     (`(,_ . ",") (smie-rule-separator method))
@@ -101,7 +101,7 @@
      (and (not (smie-rule-bolp)) (smie-rule-prev-p "else")
           (smie-rule-parent)))))
 
-(defconst haskell-tng-smie:dont-cycle '(newline-and-indent)
+(defconst haskell-tng-smie:return '(newline-and-indent)
   "Users with custom newlines should add their command.")
 
 (defvar-local haskell-tng-smie:indentations nil)
@@ -110,26 +110,39 @@
   ;; There is a design choice here: either we compute all the indentation 
levels
   ;; (including a recursive call to `smie-indent-calculate') and put them into 
a
   ;; ring that we cycle, or we push/pop with recalculation. We choose the
-  ;; latter, because cache invalidation is unclear for the former
-  (if (or (not (eq this-command last-command))
-          (member this-command haskell-tng-smie:dont-cycle))
+  ;; latter, because cache invalidation is easier.
+  (if (member this-command haskell-tng-smie:return)
       (setq haskell-tng-smie:indentations nil)
-
-    (when (null haskell-tng-smie:indentations)
+    (when (and
+           (null haskell-tng-smie:indentations)
+           (or
+            ;; TAB+TAB and RETURN+TAB
+            (eq this-command last-command)
+            (member last-command haskell-tng-smie:return)))
       ;; avoid recalculating the prime indentation level
       (let ((prime (current-column)))
         (setq haskell-tng-smie:indentations
-              (append (-remove-item prime (haskell-tng-smie:indent-alts))
-                      (list prime)))))
-
-    (pop haskell-tng-smie:indentations)))
+              (append
+               ;; TODO backtab, does the cycle in reverse (use a local flag)
+               (-remove-item prime (haskell-tng-smie:indent-alts))
+               (list prime))))))
+  (pop haskell-tng-smie:indentations))
 
 (defun haskell-tng-smie:indent-alts ()
   "Returns a list of alternative indentation levels for the
-  current line."
-  ;; FIXME implement
-  '(2)
- )
+current line."
+  (save-excursion
+    (let ((end (line-number-at-pos))
+          indents)
+      (when (re-search-backward haskell-tng:regexp:toplevel nil t)
+        (while (< (line-number-at-pos) end)
+          ;; TODO add positions of WLDOS
+          ;; TODO special cases for import (unless grammar handles it)
+          ;; TODO special cases for multiple whitespaces (implies alignment)
+          ;; TODO end +- 2
+          (push (current-indentation) indents)
+          (forward-line))
+        (-distinct (-sort '< indents))))))
 
 (defun haskell-tng-smie:setup ()
   (setq-local smie-indent-basic 2)
diff --git a/test/haskell-tng-indent-test.el b/test/haskell-tng-indent-test.el
index 536e12e..10622bb 100644
--- a/test/haskell-tng-indent-test.el
+++ b/test/haskell-tng-indent-test.el
@@ -40,26 +40,25 @@
   (let (indents)
     (while (not (eobp))
       (end-of-line)
-      (let ((indent (list (current-line-string)))
-            alts)
-        ;; simulating the command loop is necessary for this-command and
-        ;; last-command to work correctly.
-        (ert-simulate-command '(newline-and-indent))
-        (push (current-column) indent)
-
-        ;; FIXME a better way to get the full cycle of alts, with a limit
-        (while (< (length alts) 2)
-          (ert-simulate-command '(indent-for-tab-command))
-          (push (current-column) alts))
-
-        (setq indent
-              (delete-dups
-               (append (reverse indent) (reverse alts))))
-
-        (push indent indents)
-        ;; unfortunately killing resets this-command so we don't test double
-        ;; newline insertions, which could accidentally trigger alts only.
-        (kill-whole-line)))
+      ;; the command loop is necessary for this/last-command
+      (cl-flet ((RET ()
+                     (ert-simulate-command '(newline-and-indent))
+                     (current-column))
+                (TAB ()
+                     (ert-simulate-command '(indent-for-tab-command))
+                     (current-column)))
+
+        (let ((line (current-line-string))
+              (prime (RET))
+              alts)
+          (while (and (TAB)
+                      (not (eq (current-column) prime))
+                      (not (member (current-column) alts)))
+            (push (current-column) alts))
+          (push `(,line . (,prime . ,(reverse alts))) indents)
+          ;; unfortunately killing resets this-command so we don't test double
+          ;; newline insertions, which could accidentally trigger alts only.
+          (kill-whole-line))))
     (reverse indents)))
 
 (defun haskell-tng-indent-test:indents-to-string (indents)
@@ -78,16 +77,14 @@ of integer alternative indentations."
          (alts (cddr indent))
          (widest (-max (cdr indent)))
          repr)
-    (list line
-          (s-join ""
-           (reverse
-            (dotimes (i (+ 1 widest) repr)
-              (push
-               (cond
-                ((eq i prime) "v")
-                ((member i alts) ".")
-                (t " "))
-               repr)))))))
+    (--dotimes (+ 1 widest)
+      (push
+       (cond
+        ((eq it prime) "v")
+        ((member it alts) ".")
+        (t " "))
+       repr))
+    (list line (s-join "" (reverse repr)))))
 
 (defun have-expected-newline-indent-insert (file)
   (haskell-tng-testutils:assert-file-contents
diff --git a/test/src/layout.hs.insert.indent b/test/src/layout.hs.insert.indent
index ad57c30..a0aa39a 100644
--- a/test/src/layout.hs.insert.indent
+++ b/test/src/layout.hs.insert.indent
@@ -1,38 +1,38 @@
 -- Figure 2.1 from the Haskell2010 report
-v .
+v
 module AStack( Stack, push, pop, top, size ) where
-v .
+v
 data Stack a = Empty
-  .              v
+.                v
              | MkStack a (Stack a)
-  .          v
+.            v
 
-v .
+v            .
 push :: a -> Stack a -> Stack a
-v .
+v
 push x s = MkStack x s
-  .                v
+.                  v
 
-v .
+v
 size :: Stack a -> Int
-v .
+v
 size s = length (stkToLst s)  where
-v .
+v
            stkToLst  Empty         = []
-  .                                    v
+.          .                           v
            stkToLst (MkStack x s)  = x:xs where xs = stkToLst s
-  .                                                           v
+.          .                                                  v
 
-  .                                                           v
+.          .                                                  v
 pop :: Stack a -> (a, Stack a)
-v .
+v
 pop (MkStack x s)
-  . v
+.   v
   = (x, case s of r -> i r where i x = x) -- (pop Empty) is an error
-  .   v
+. .   v
 
 v .
 top :: Stack a -> a
-v .
+v
 top (MkStack x s) = x                     -- (top Empty) is an error
-v .
\ No newline at end of file
+v
\ No newline at end of file
diff --git a/test/src/medley.hs.insert.indent b/test/src/medley.hs.insert.indent
index 99b97b2..475b574 100644
--- a/test/src/medley.hs.insert.indent
+++ b/test/src/medley.hs.insert.indent
@@ -1,274 +1,274 @@
 {-# LANGUAGE OverloadedStrings   #-}
-v .
+v
 {-# LANGUAGE ScopedTypeVariables #-}
-v .
+v
 
-v .
+v
 -- | This file is a medley of various constructs and some corner cases
-v .
+v
 module Foo.Bar.Main
-  .            v
+.              v
   ( Wibble(..), Wobble(Wobb, (!!!)), Woo
-  .                                    v
+. .                                    v
   -- * Operations
-  .                                    v
+. .                                    v
   , getFooByBar, getWibbleByWobble
-  .                v
+. .                v
   , module Bloo.Foo
-  .             v
+. .             v
   ) where
 v .
 
 v .
 import           Control.Applicative (many, optional, pure, (<*>), (<|>))
-v .
+v
 import           Data.Foldable       (traverse_)
-v .
+v
 import           Data.Functor        ((<$>))
-v .
+v
 import           Data.List           (intercalate)
-v .
+v
 import           Data.Monoid         ((<>))
-v .
+v
 import qualified Options.Monad
-v .
+v
 import  qualified  Options.Applicative  as  Opts
-v .
+v
 import qualified Options.Divisible -- wibble (wobble)
-  .    v
+.      v
    as Div
-v .
+v  .
 import qualified ProfFile.App        hiding (as, hiding, qualified)
-v .
+v
 import           ProfFile.App        (as, hiding, qualified)
-v .
+v
 import           ProfFile.App        hiding (as, hiding, qualified)
-v .
+v
 import qualified ProfFile.App        (as, hiding, qualified)
-v .
+v
 import           System.Exit         (ExitCode (..), exitFailure, qualified,
-  .                                   v
+.                                     v
                                       Typey,
-  .                                   v
+.                                     v
                                       wibble,
-  .                                   v
+.                                     v
                                       Wibble)
-v .
+v                                     .
 import           System.FilePath     (replaceExtension, Foo(Bar, (:<))
-  .                                   v
+.                                     v
 import           System.IO           (IOMode (..), hClose, hGetContents,
-  .                                   v
+.                                     v
                                       hPutStr, hPutStrLn, openFile, stderr,
-  .                                   v
+.                                     v
                                       stdout, MoarTypey)
-v .
+v                                     .
 import           System.Process      (CreateProcess (..), StdStream (..),
-  .                                   v
+.                                     v
                                       createProcess, proc, waitForProcess)
-  .                     v
+.                       v             .
 
-  .                     v
+.                       v             .
 -- some chars that should be propertized
-v .
+v                                     .
 chars = ['c', '\n', '\'']
-  .       v
+.         v
 
-v .
+v
 difficult = foo' 'a' 2
-  .              v
+.                v
 
-v .
+v
 foo = "wobble (wibble)"
-  .     v
+.       v
 
-v .
+v
 class Get a s where
-  .                                   v
+.                                     v
   get :: Set s -> a
-  .                 v
+. .                 v
 
-  v
+. v
 instance {-# OVERLAPS #-} Get a (a ': s) where
-  v
+. v
   get (Ext a _) = a
-  .                 v
+. .                 v
 
-  v
+. v
 instance {-# OVERLAPPABLE #-} Get a s => Get a (b ': s) where
-  v
+. v
   get (Ext _ xs) = get xs
-  .                    v
+. .                    v
 
-  v
+. v
 data Options = Options
-  .              v
+.                v
   { optionsReportType      :: ReportType
-  .                        v
+. .                        v
   , optionsProfFile        :: Maybe FilePath
-  .                        v
+. .                        v
   , optionsOutputFile      :: Maybe FilePath
-  .                        v
+. .                        v
   , optionsFlamegraphFlags :: [String]
-  .                        v
+. .                        v
   } deriving (Eq, Show)
-  v
+. v
 
 v .
 class  (Eq a) => Ord a  where
-  v
+. v
   (<), (<=), (>=), (>)  :: a -> a -> Bool
-  .                                    v
+. .                                    v
   max @Foo, min        :: a -> a -> a
-  .                                   v
+. .                                   v
 
-  v
+. v
 instance (Eq a) => Eq (Tree a) where
-  v
+. v
   Leaf a         == Leaf b          =  a == b
-  .                                           v
+. .                                           v
   (Branch l1 r1) == (Branch l2 r2)  =  (l1==l2) && (r1==r2)
-  .                                                  v
+. .                                                  v
   _              == _               =  False
-  .                                      v
+. .                                      v
 
-  v
+. v
 data ReportType = Alloc   -- ^ Report allocations, percent
-  .                 v
+.                   v
                 | Entries -- ^ Report entries, number
-  .             v
+.               v
                 | Time    -- ^ Report time spent in closure, percent
-  .             v
+.               v
                 | Ticks   -- ^ Report ticks, number
-  .             v
+.               v
                 | Bytes   -- ^ Report bytes allocated, number
-  .             v
+.               v
                 deriving (Eq, Show)
-  .             v
+.               v
 
-v .
+v               .
 type family G a where
-  v
+. v
   G Int = Bool
-  .         v
+. .         v
   G a   = Char
-  .         v
+. .         v
 
-  v
+. v
 data Flobble = Flobble
-  .              v
+.                v
   deriving (Eq) via (NonNegative (Large Int))
-  v
+. v
   deriving stock (Floo)
-  v
+. v
   deriving anyclass (WibblyWoo, OtherlyWoo)
-  v
+. v
 
 v .
 newtype Flobby = Flobby
-  .                v
+.                  v
 
-v .
+v
 foo ::
-  . v
+.   v
  Wibble -- wibble
- v.
+.v
     -> Wobble -- wobble
-  .      v
+..  .    v
     -> Wobble -- wobble
-  .      v
+..  .    v
     -> Wobble -- wobble
-  .      v
+..  .    v
     -> (wob :: Wobble)
-  .      v
+..  .    v
     -> (Wobble -- wobble
-  .       v
+..  .     v
     a b c)
-  .      v
+..  .    v
 
-v .
+v.  .
 (foo :: (Wibble Wobble)) foo
-  .                      v
+..  .                    v
 
-v .
+v.  .
 newtype TestApp
-  .     v
+.       v
    (logger :: TestLogger)
-  .v
+.  v
    (scribe :: TestScribe)
-  .v
+.  v
    config
-  .v
+.  v
    a
-  .v
+.  v
    = TestApp a
-  .          v
+.  .         v
 
-v .
+v  .
 optionsParser :: Opts.Parser Options
-v .
+v
 optionsParser = Options
-  .               v
+.                 v
   <$> (Opts.flag' Alloc (Opts.long "alloc" <> Opts.help "wibble")
-  .               v
+. .               v
        <|> Opts.flag' Entries (Opts.long "entry" <> Opts.help "wobble")
-  .                   v
+. .    .              v
        <|> Opts.flag' Bytes   (Opts.long "bytes" <> Opts.help "i'm a fish"))
-  .     v
+. .    .v
   <*> optional
-  .     v
+. .    .v
         (Opts.strArgument
-  .             v
+. .    ..       v
           (Opts.metavar "MY-FILE" <>
-  .             v
+. .    .. .     v
            Opts.help "meh"))
-  .     v
+. .    .v ..
 
-  .   v
+. .   v.. ..
 type PhantomThing
-  .  v
+.    v
 
-v .
+v
 type SomeApi =
-  v
+. v
        "thing" :> Capture "bar" Index :> QueryParam "wibble" Text
-  .            v
+.      .       v
                                                :> QueryParam "wobble" Natural
-  .                                            v
+.      .                                       v
                                                :> Header TracingHeader 
TracingId
-  .                                            v
+.      .                                       v
                                                :> ThingHeader
-  .                                            v
+.      .                                       v
                                                :> Get '[JSON] (The ReadResult)
-  .                                            v
+.      .                                       v
   :<|> "thing" :> ReqBody '[JSON] Request
-  v
+. v    .                                       .
                       :> Header TracingHeader TracingId
-  .                   v
+. .    .              v                        .
                       :> SpecialHeader
-  .                   v
+. .    .              v                        .
                       :> Post '[JSON] (The Response)
-  .                   v
+. .    .              v                        .
 
-v .
+v .    .              .                        .
 deriving instance FromJSONKey StateName
-v .
+v
 deriving anyclass instance FromJSON Base
-v .
+v
 deriving newtype instance FromJSON Treble
-  .      v
+.        v
 
-v .
+v
 foo = bar
-  .     v
+.       v
   where baz = _
-  .             v
+. .             v
   -- checking that comments are ignored in layout
-  .             v
+. .             v
   -- and that a starting syntax entry is ok
-  .             v
+. .             v
         (+) = _
-  .             v
+. .     .       v
 
-  .     v
+. .     v
 test = 1 `shouldBe` 1
-  .                                   v
\ No newline at end of file
+.                                     v
\ No newline at end of file



reply via email to

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