[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
- [nongnu] elpa/haskell-tng-mode 2a2afee 064/385: cache invalidation and tests for layout invalidation, (continued)
- [nongnu] elpa/haskell-tng-mode 2a2afee 064/385: cache invalidation and tests for layout invalidation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3ca869f 067/385: code reorganisation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 0ffb885 071/385: a thought, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 79aeb82 076/385: most of the grammar, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 7eaef51 078/385: optimisation in the sexp test, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode cb0f3d2 082/385: starting indentation rules, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode cfbdae1 084/385: simplify the lexer assertion language, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 0c5acb7 087/385: lexer and grammar supports symid, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 6c520bc 093/385: fixes for type level lists, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode f085f16 097/385: indentation regression tests, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 01ea0b8 103/385: heuristic alternative indentation levels,
ELPA Syncer <=
- [nongnu] elpa/haskell-tng-mode c20ea4f 096/385: infix varid as symid, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode bfe859a 095/385: notes about lexers, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 0506391 109/385: module ... where indents to 0, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode d9bbcdd 111/385: next steps, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 6cf67bf 105/385: indentation can't handle mismatched parens, don't test for it, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 25b15eb 102/385: indentation alternatives wiring, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode e023657 107/385: SMIE wishlist, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 497214b 119/385: syntax tests and bugfixes, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode df5d2c5 122/385: better whitespace gap detection, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3b7cd02 123/385: some todos, ELPA Syncer, 2021/10/06