branch: elpa/haskell-tng-mode commit e1c0f0ae407feb6e29cdf29a50c849c99848766f Author: Tseen She <ts33n....@gmail.com> Commit: Tseen She <ts33n....@gmail.com>
allow indentation option to be tested --- haskell-tng-mode.el | 3 +- haskell-tng-smie.el | 29 +++ test/haskell-tng-indent-test.el | 56 ++--- test/src/indentation-options.hs | 31 +++ test/src/indentation-options.hs.append.indent | 64 ++++++ test/src/indentation-options.hs.insert.indent | 62 ++++++ test/src/indentation.hs.reindent | 304 -------------------------- 7 files changed, 216 insertions(+), 333 deletions(-) diff --git a/haskell-tng-mode.el b/haskell-tng-mode.el index 86594bc..3acda8a 100644 --- a/haskell-tng-mode.el +++ b/haskell-tng-mode.el @@ -30,7 +30,8 @@ "Integration with `prettify-symbols' giving the impression of UnicodeSyntax. Load `prettify-symbols-mode' in `haskell-tng-mode-hook'." - :type 'listp) + :type 'listp + :group 'haskell-tng) ;; optional dependency on projectile for TAGS management (defvar projectile-tags-command) diff --git a/haskell-tng-smie.el b/haskell-tng-smie.el index fdab67e..8375515 100644 --- a/haskell-tng-smie.el +++ b/haskell-tng-smie.el @@ -30,6 +30,35 @@ (require 'haskell-tng-font-lock) (require 'haskell-tng-lexer) +;; TODO implement +(defcustom haskell-tng-indent-aligntypes nil + "Whether to align arrows to their parent :: declaration. + +For example, nil and t, respectively: + +foobar :: Monad m + => A + +foobar :: Monad m + => A" + :type 'booleanp + :group 'haskell-tng) + +;; TODO implement +(defcustom haskell-tng-indent-typelead 3 + "Leading spaces in a trailing type signature, relative to type arrows. +For example 3 and 1 are respectively: + +foobar3 :: + Monad m + => A + +foobar1 :: + ( Monad m ) + => A" + :type 'integerp + :group 'haskell-tng) + ;; https://www.gnu.org/software/emacs/manual/html_mono/elisp.html#SMIE-Grammar ;; https://www.haskell.org/onlinereport/haskell2010/haskellch3.html ;; https://gitlab.haskell.org/ghc/ghc/blob/master/compiler/parser/Parser.y diff --git a/test/haskell-tng-indent-test.el b/test/haskell-tng-indent-test.el index 4c0e51c..907ba0f 100644 --- a/test/haskell-tng-indent-test.el +++ b/test/haskell-tng-indent-test.el @@ -19,8 +19,6 @@ ;; TODO ImplicitParams in type signatures (without parens) ;; TODO if/then/else -;; TODO reindenting needs attention, it's all over the radar - ;; Three indentation regression tests are possible: ;; ;; 1. newline-and-indent with the rest of the file deleted (append) @@ -34,36 +32,35 @@ ;; ;; Test 1 involves a lot of buffer refreshing and will be very slow. -(ert-deftest haskell-tng-append-indent-file-tests () - (should (have-expected-append-indent (testdata "src/indentation.hs"))) - - ;;(should (have-expected-append-indent (testdata "src/layout.hs"))) - - ;; this test is slow - ;; (require 'profiler) - ;; (profiler-start 'cpu) - ;; (should (have-expected-append-indent (testdata "src/medley.hs"))) - ;; (profiler-report) - ;; (profiler-report-write-profile "indentation.profile") - ;; (profiler-stop) - ;; (profiler-find-profile "../indentation.profile") - ) -(ert-deftest haskell-tng-indent-file-tests () - (should (have-expected-insert-indent (testdata "src/indentation.hs"))) +;; ;; this test is slow and is a useful benchmark +;; (ert-deftest haskell-tng-append-indent-file-tests () +;; (require 'profiler) +;; (profiler-start 'cpu) +;; (should (have-expected-append-indent (testdata "src/medley.hs"))) +;; (profiler-report) +;; (profiler-report-write-profile "indentation.profile") +;; (profiler-stop) +;; (profiler-find-profile "../indentation.profile")) - ;; (should (have-expected-insert-indent (testdata "src/layout.hs"))) - ;; (should (have-expected-insert-indent (testdata "src/medley.hs"))) - ) +(ert-deftest haskell-tng-append-indent-file-tests:indentation () + (should (have-expected-append-indent (testdata "src/indentation.hs")))) +(ert-deftest haskell-tng-append-indent-file-tests:options () + (let ((haskell-tng-indent-aligntypes t) + (haskell-tng-indent-typelead 1)) + (should (have-expected-append-indent (testdata "src/indentation-options.hs"))))) -(ert-deftest haskell-tng-reindent-file-tests () - (should (have-expected-reindent (testdata "src/indentation.hs"))) - - ;; (should (have-expected-reindent (testdata "src/layout.hs"))) - ;; (should (have-expected-reindent (testdata "src/medley.hs"))) - ) +(ert-deftest haskell-tng-insert-indent-file-tests:indentation () + (should (have-expected-insert-indent (testdata "src/indentation.hs")))) +(ert-deftest haskell-tng-insert-indent-file-tests:options () + (let ((haskell-tng-indent-aligntypes t) + (haskell-tng-indent-typelead 1)) + (should (have-expected-insert-indent (testdata "src/indentation-options.hs"))))) +;; TODO reindenting needs attention, it's all over the radar +;; (ert-deftest haskell-tng-reindent-file-tests () +;; (should (have-expected-reindent (testdata "src/indentation.hs")))) (defun haskell-tng-indent-test:work (mode) "MODE can be 'insert, 'reindent, or 'append." @@ -78,7 +75,10 @@ ;; SMIE doesn't request forward tokens from the lexer when the point is ;; at point-max, so add some whitespace at the end. ;; - ;; TODO fix the bug properly, in SMIE + ;; TODO fix the bug properly, in SMIE. + ;; + ;; TODO maybe we can have a better workaround by presenting tokens -1 + ;; from the end and enforcing a trailing newline. (save-excursion (insert "\n\n")))) (while (pcase mode diff --git a/test/src/indentation-options.hs b/test/src/indentation-options.hs new file mode 100644 index 0000000..843e2c5 --- /dev/null +++ b/test/src/indentation-options.hs @@ -0,0 +1,31 @@ +-- | Indentation scenarios to test indentation options. +module Indentation where + +typesig :: a -> b -> c + +types1 :: + Monad m + => a + -> b + -> c + +types2 :: + ( Monad m ) + => a + -> b + -> c + +types3 :: (Monad m, MemberLogger m) + => a + -> b + -> c + +types4 :: Monad m + => (?log :: HasLogger m) + => a + -> b + -> c + +types5 :: (Monad m, MonadReader Foo m) => + (?log :: HasLogger m) => + a -> b -> c diff --git a/test/src/indentation-options.hs.append.indent b/test/src/indentation-options.hs.append.indent new file mode 100644 index 0000000..6a69025 --- /dev/null +++ b/test/src/indentation-options.hs.append.indent @@ -0,0 +1,64 @@ +-- | Indentation scenarios to test indentation options. +v +module Indentation where +v + +v +typesig :: a -> b -> c +v + +v +types1 :: +1 v + Monad m +2 v 1 + => a +1 v 2 + -> b +v 1 2 + -> c +v 1 2 + +v 1 2 +types2 :: +1 v + ( Monad m ) +2 v1 + => a +1 v2 + -> b +v 12 + -> c +v 12 + +v 12 +types3 :: (Monad m, MemberLogger m) +1 v + => a +1 v + -> b +v 1 + -> c +v 1 + +v 1 +types4 :: Monad m +1 v + => (?log :: HasLogger m) +1 v + => a +1 v + -> b +v 1 + -> c +v 1 + +v 1 +types5 :: (Monad m, MonadReader Foo m) => +1 v + (?log :: HasLogger m) => +1 v + a -> b -> c +v 1 + +v 1 \ No newline at end of file diff --git a/test/src/indentation-options.hs.insert.indent b/test/src/indentation-options.hs.insert.indent new file mode 100644 index 0000000..5395984 --- /dev/null +++ b/test/src/indentation-options.hs.insert.indent @@ -0,0 +1,62 @@ +-- | Indentation scenarios to test indentation options. +v +module Indentation where +v + +v +typesig :: a -> b -> c +v + +v +types1 :: +1 v + Monad m +2 v 1 + => a +1 v 2 + -> b +2 1 v + -> c +v 1 2 + +v 1 2 +types2 :: +2 1 v + ( Monad m ) +2 v1 + => a +1 v2 + -> b +2 13 v + -> c +v 12 + +v 12 +types3 :: (Monad m, MemberLogger m) +2 1 v + => a +1 v + -> b +2 1 v + -> c +v 1 + +v 1 +types4 :: Monad m +2 1 v + => (?log :: HasLogger m) +1 v + => a +1 v + -> b +2 1 v + -> c +v 1 + +v 1 +types5 :: (Monad m, MonadReader Foo m) => +2 v1 + (?log :: HasLogger m) => +1 v + a -> b -> c +v 1 \ No newline at end of file diff --git a/test/src/indentation.hs.reindent b/test/src/indentation.hs.reindent deleted file mode 100644 index 2219848..0000000 --- a/test/src/indentation.hs.reindent +++ /dev/null @@ -1,304 +0,0 @@ -v --- | Idealised indentation scenarios. -v --- -v --- Bugs and unexpected behaviour in (re-)indentation may be documented here. -v --- -v --- Lines marked "manual correction" indicate where we expect the user to -v --- re-indent because it goes against our prediction. In some of these cases, -v --- we could improve the guess with semantic information (e.g. if we know that -v --- the RHS of a bind is only partially applied, then we probably mean to -v --- continue that line instead of start a new one). -v -module Indentation where -v - -v -import Foo.Bar -v 1 -import Foo.Baz hiding ( gaz, -2 1 v - baz -2 v 1 - ) -v 1 2 - -v 1 2 3 -basic_do = do -1 v 2 - foo <- blah blah blah -v 2 1 - bar <- blah blah -2 1 v - blah -- manual correction -2 1 v - blah -- manual correction -v 1 2 - sideeffect -v 2 1 3 - sideeffect' blah -v 2 3 1 - let baz = blah blah -3 2 1 4 v - blah -- manual correction -v 3 1 4 2 - gaz = blah -v 3 2 14 5 - haz = -3 1 2 v4 5 - blah -2 v 3 14 5 - pure faz -- manual correction -1 v 2 34 5 - -v 2 13 45 6 -nested_do = -- manual correction -v 1 - do foo <- blah -v 2 1 3 - do bar <- blah -- same level as foo -v 2 1 4 3 - baz -- same level as bar -1 2 v 3 4 - -v 1 2 3 4 -nested_where a b = foo a b -2 v 1 - where -- manual correction -1 v - foo = bar baz -- indented -v 1 - baz = blah blah -- same level as foo -2 v 1 - where -- manual correction -1 2 v - gaz a = blah -- indented -v 2 1 - faz = blah -- same level as gaz -1 2 v - -v 1 2 3 -let_in a b = let -1 v - blah = bloo -v 1 - wobble _ = fish -v 2 1 - in -2 1 v - flibble blah -1 v 2 - -v 2 3 1 -implicit_let foo bar = -v 1 - let ?foo = foo -v 1 2 - ?bar = bar -v 1 - in rar -v 1 2 - -v 1 2 -case_of wibble = case wibble of -2 v 1 - Nothing -> -2 1 v - "" -v 2 1 - Just fish -> -2 1 v - fish -1 v 2 - -v 1 2 -lambda_case = \case -1 v - Nothing -> "" -v 1 - Just fish -> fish -1 v - -v 1 -dollars f Nothing = f $ -1 v - "" "" -1 v - "" -v 1 -dollars f (Just a) = f $ \s -> -1 v - a -v 1 - -v 1 -not_dollars = do -1 v 2 - db' <- liftIO $ readMVar db -v 2 1 3 - shouldGoHere <$> -2 1 v 3 - here -1 v 2 3 - -v 2 3 4 1 -data Wibble = Wibble Int -1 v - | Wobble Int -1 v - | Vibble Int -v 1 - -v 1 2 -data Record1 = Record1 { -1 v - fieldA :: String -v 1 -, fieldB :: String -v -} -v - -v 1 -data Record2 = Record2 -2 1 v - { fieldA :: String -1 v - , fieldB :: String -1 v - } -v 1 - -v 2 1 -data Record3 = Record3 String Text -1 v - deriving (Show) -v 1 - -v 1 -data Record4 = Record3 String Text deriving (Show) -v - -v 1 -lists1 = [ foo -1 v - , bar -2 v 1 - , [ blah -2 1 v - , blah -2 1 v - , blah ] -2 v 1 - ] -v 1 2 - -v 1 2 3 -lists2 = [ -1 v - foo -v 1 -, bar -v -] -v - -v 1 -lists3 = [ foo , -1 v - bar ] -v 1 - -v 12 -tuples1 = ( foo -1 v - , bar -2 v 1 - , ( blah -2 1 v - , blah -2 1 v - , blah ) -2 v 1 - ) -v 1 2 - -v 1 2 3 -tuples2 = ( -1 v - foo -v 1 -, bar -v -) -v - -v 1 -tuples3 = ( foo , -1 v - bar ) -v 1 - -v 1 -typesig :: a -> b -> c -v - -v 1 -types1 :: -2 1 v - Monad m -2 v 1 - => a -1 v 2 - -> b -1 v 2 - -> c -v 1 2 - -v 21 3 -types2 :: -2 1 v - ( Monad m ) -2 v1 - => a -1 v2 - -> b -1 v2 - -> c -v 12 - -v 12 -types3 :: (Monad m, MemberLogger m) -2 1 v - => a -1 v - -> b -1 v - -> c -v 1 - -v 2 1 -types4 :: Monad m -2 1 v - => (?log :: HasLogger m) -1 v - => a -1 v - -> b -1 v - -> c -v 1 - -v 2 1 -types5 :: (Monad m, MonadReader Foo m) => -2 v1 - (?log :: HasLogger m) => -1 v - a -> b -> c \ No newline at end of file