branch: elpa/haskell-tng-mode commit 5306ae2b918cda092ffd781cd408c1286061b6e9 Author: Tseen She <ts33n....@gmail.com> Commit: Tseen She <ts33n....@gmail.com>
fix type faces with constraints --- haskell-tng-compile.el | 3 + haskell-tng-util.el | 2 +- test/haskell-tng-font-lock-test.el | 9 ++ test/src/indentation-options1.hs.faceup | 9 ++ test/src/indentation-options2.hs.faceup | 15 ++++ test/src/indentation.hs.faceup | 147 ++++++++++++++++++++++++++++++++ 6 files changed, 184 insertions(+), 1 deletion(-) diff --git a/haskell-tng-compile.el b/haskell-tng-compile.el index e06e69f..6b1600a 100644 --- a/haskell-tng-compile.el +++ b/haskell-tng-compile.el @@ -18,6 +18,8 @@ ;; TODO set compilation-directory when opening the file ;; TODO set compilation-environment to include TASTY envvars +;; TODO support long running (ghcid) compile buffers +;; TODO generic flycheck integration https://emacs.stackexchange.com/questions/51894 (defvar haskell-tng-compilation-error-regexp-alist (let ((file '(: (group (+ any) ".hs"))) @@ -116,6 +118,7 @@ will cause the subsequent call to prompt." (ansi-color-apply-on-region compilation-filter-start (point-max))) (define-compilation-mode haskell-tng-compilation-mode "haskell-tng-compilation" + ;; TODO add a hook to detect ghcid recompiles and clear the buffer (add-hook 'compilation-filter-hook 'haskell-tng--compile-ansi-color nil t)) diff --git a/haskell-tng-util.el b/haskell-tng-util.el index 46b7f44..041cec6 100644 --- a/haskell-tng-util.el +++ b/haskell-tng-util.el @@ -39,7 +39,7 @@ ;; trivial, should just be called as an inline regexp (save-excursion (goto-char (or pos (point))) - (re-search-forward (rx (| "<-" "=")) nil t))) + (re-search-forward (rx (| "<-" "=") symbol-end) nil t))) (defun haskell-tng--util-next-where (&optional pos) ;; trivial, should just be called as an inline regexp diff --git a/test/haskell-tng-font-lock-test.el b/test/haskell-tng-font-lock-test.el index f931ab4..291a68e 100644 --- a/test/haskell-tng-font-lock-test.el +++ b/test/haskell-tng-font-lock-test.el @@ -24,4 +24,13 @@ (ert-deftest haskell-tng-font-lock-file-tests:layout () (should (have-expected-faces (testdata "src/layout.hs")))) +(ert-deftest haskell-tng-font-lock-file-tests:indentation () + (should (have-expected-faces (testdata "src/indentation.hs")))) + +(ert-deftest haskell-tng-font-lock-file-tests:indentation1 () + (should (have-expected-faces (testdata "src/indentation-options1.hs")))) + +(ert-deftest haskell-tng-font-lock-file-tests:indentation2 () + (should (have-expected-faces (testdata "src/indentation-options2.hs")))) + ;;; haskell-tng-font-lock-test.el ends here diff --git a/test/src/indentation-options1.hs.faceup b/test/src/indentation-options1.hs.faceup new file mode 100644 index 0000000..6476e9e --- /dev/null +++ b/test/src/indentation-options1.hs.faceup @@ -0,0 +1,9 @@ +«m:-- »«x:| Indentation scenarios to test indentation options. +»«:haskell-tng-keyword-face:module» «:haskell-tng-module-face:Indentation» «:haskell-tng-keyword-face:where» + +types4 «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: + »«:haskell-tng-keyword-face:(»«:haskell-tng-type-face: Monad m »«:haskell-tng-keyword-face:)»«:haskell-tng-type-face: + »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: a + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: b + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: c +» \ No newline at end of file diff --git a/test/src/indentation-options2.hs.faceup b/test/src/indentation-options2.hs.faceup new file mode 100644 index 0000000..ea8d94e --- /dev/null +++ b/test/src/indentation-options2.hs.faceup @@ -0,0 +1,15 @@ +«m:-- »«x:| Indentation scenarios to test indentation options. +»«:haskell-tng-keyword-face:module» «:haskell-tng-module-face:Indentation» «:haskell-tng-keyword-face:where» + +types5 «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: Monad m + »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: »«:haskell-tng-keyword-face:(»«:haskell-tng-type-face:?log »«:haskell-tng-keyword-face:::»«:haskell-tng-type-face: HasLogger m»«:haskell-tng-keyword-face:)»«:haskell-tng-type-face: + »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: a + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: b + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: c +» +types6 «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: + »«:haskell-tng-keyword-face:(»«:haskell-tng-type-face: Monad m »«:haskell-tng-keyword-face:)»«:haskell-tng-type-face: + »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: a + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: b + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: c +» \ No newline at end of file diff --git a/test/src/indentation.hs.faceup b/test/src/indentation.hs.faceup new file mode 100644 index 0000000..78d6621 --- /dev/null +++ b/test/src/indentation.hs.faceup @@ -0,0 +1,147 @@ +«m:-- »«x:| Idealised indentation scenarios. +»«m:--»«x: +»«m:-- »«x:Bugs and unexpected behaviour in (re-)indentation may be documented here. +»«m:--»«x: +»«m:-- »«x:Lines marked "manual correction" indicate where we expect the user to +»«m:-- »«x:re-indent because it goes against our prediction. In some of these cases, +»«m:-- »«x:we could improve the guess with semantic information (e.g. if we know that +»«m:-- »«x:the RHS of a bind is only partially applied, then we probably mean to +»«m:-- »«x:continue that line instead of start a new one). +»«:haskell-tng-keyword-face:module» «:haskell-tng-module-face:Indentation» «:haskell-tng-keyword-face:where» + +«:haskell-tng-keyword-face:import» «:haskell-tng-module-face:Foo.Bar» +«:haskell-tng-keyword-face:import» «:haskell-tng-module-face:Foo.Baz» «:haskell-tng-keyword-face:hiding» «:haskell-tng-keyword-face:(» gaz«:haskell-tng-keyword-face:,» + baz + «:haskell-tng-keyword-face:)» + +basic_do «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:do» + foo «:haskell-tng-keyword-face:<-» blah blah blah + bar «:haskell-tng-keyword-face:<-» blah blah + blah «m:-- »«x:manual correction +» blah «m:-- »«x:manual correction +» sideeffect + sideeffect' blah + «:haskell-tng-keyword-face:let» baz «:haskell-tng-keyword-face:=» blah blah + blah «m:-- »«x:manual correction +» gaz «:haskell-tng-keyword-face:=» blah + haz «:haskell-tng-keyword-face:=» + blah + pure faz «m:-- »«x:manual correction +» +nested_do «:haskell-tng-keyword-face:=» «m:-- »«x:manual correction +» «:haskell-tng-keyword-face:do» foo «:haskell-tng-keyword-face:<-» blah + «:haskell-tng-keyword-face:do» bar «:haskell-tng-keyword-face:<-» blah «m:-- »«x:same level as foo +» baz «m:-- »«x:same level as bar +» +nested_where a b «:haskell-tng-keyword-face:=» foo a b + «:haskell-tng-keyword-face:where» «m:-- »«x:manual correction +» foo «:haskell-tng-keyword-face:=» bar baz «m:-- »«x:indented +» baz «:haskell-tng-keyword-face:=» blah blah «m:-- »«x:same level as foo +» «:haskell-tng-keyword-face:where» «m:-- »«x:manual correction +» gaz a «:haskell-tng-keyword-face:=» blah «m:-- »«x:indented +» faz «:haskell-tng-keyword-face:=» blah «m:-- »«x:same level as gaz +» +let_in a b «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:let» + blah «:haskell-tng-keyword-face:=» bloo + wobble «:haskell-tng-keyword-face:_» «:haskell-tng-keyword-face:=» fish + «:haskell-tng-keyword-face:in» + flibble blah + +implicit_let foo bar «:haskell-tng-keyword-face:=» + «:haskell-tng-keyword-face:let» ?foo «:haskell-tng-keyword-face:=» foo + ?bar «:haskell-tng-keyword-face:=» bar + «:haskell-tng-keyword-face:in» rar + +case_of wibble «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:case» wibble «:haskell-tng-keyword-face:of» + «:haskell-tng-conid-face:Nothing» «:haskell-tng-keyword-face:->» + «s:""» + «:haskell-tng-conid-face:Just» fish «:haskell-tng-keyword-face:->» + fish + +lambda_case «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:\case» + «:haskell-tng-conid-face:Nothing» «:haskell-tng-keyword-face:->» «s:""» + «:haskell-tng-conid-face:Just» fish «:haskell-tng-keyword-face:->» fish + +dollars f «:haskell-tng-conid-face:Nothing» «:haskell-tng-keyword-face:=» f $ + «s:""» «s:""» + «s:""» +dollars f «:haskell-tng-keyword-face:(»«:haskell-tng-conid-face:Just» a«:haskell-tng-keyword-face:)» «:haskell-tng-keyword-face:=» f $ «:haskell-tng-keyword-face:\»s «:haskell-tng-keyword-face:->» + a + +not_dollars «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:do» + db' «:haskell-tng-keyword-face:<-» liftIO $ readMVar db + shouldGoHere <$> + here + +«:haskell-tng-keyword-face:data»«:haskell-tng-type-face: Wibble »«:haskell-tng-keyword-face:=» «:haskell-tng-conid-face:Wibble» «:haskell-tng-conid-face:Int» + «:haskell-tng-keyword-face:|» «:haskell-tng-conid-face:Wobble» «:haskell-tng-conid-face:Int» + «:haskell-tng-keyword-face:|» «:haskell-tng-conid-face:Vibble» «:haskell-tng-conid-face:Int» + +«:haskell-tng-keyword-face:data»«:haskell-tng-type-face: Record1 »«:haskell-tng-keyword-face:=» «:haskell-tng-conid-face:Record1» «:haskell-tng-keyword-face:{» + fieldA «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: String +»«:haskell-tng-keyword-face:,» fieldB «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: String +»«:haskell-tng-keyword-face:}» + +«:haskell-tng-keyword-face:data»«:haskell-tng-type-face: Record2 »«:haskell-tng-keyword-face:=» «:haskell-tng-conid-face:Record2» + «:haskell-tng-keyword-face:{» fieldA «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: String +» «:haskell-tng-keyword-face:,» fieldB «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: String +» «:haskell-tng-keyword-face:}» + +«:haskell-tng-keyword-face:data»«:haskell-tng-type-face: Record3 »«:haskell-tng-keyword-face:=» «:haskell-tng-conid-face:Record3» «:haskell-tng-conid-face:String» «:haskell-tng-conid-face:Text» + «:haskell-tng-keyword-face:deriving» «:haskell-tng-keyword-face:(»«:haskell-tng-type-face:Show»«:haskell-tng-keyword-face:)» + +«:haskell-tng-keyword-face:data»«:haskell-tng-type-face: Record4 »«:haskell-tng-keyword-face:=» «:haskell-tng-conid-face:Record3» «:haskell-tng-conid-face:String» «:haskell-tng-conid-face:Text» «:haskell-tng-keyword-face:deriving» «:haskell-tng-keyword-face:(»«:haskell-tng-type-face:Show»«:haskell-tng-keyword-face:)» + +lists1 «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:[» foo + «:haskell-tng-keyword-face:,» bar + «:haskell-tng-keyword-face:,» «:haskell-tng-keyword-face:[» blah + «:haskell-tng-keyword-face:,» blah + «:haskell-tng-keyword-face:,» blah «:haskell-tng-keyword-face:]» + «:haskell-tng-keyword-face:]» + +lists2 «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:[» + foo +«:haskell-tng-keyword-face:,» bar +«:haskell-tng-keyword-face:]» + +lists3 «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:[» foo «:haskell-tng-keyword-face:,» + bar «:haskell-tng-keyword-face:]» + +tuples1 «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:(» foo + «:haskell-tng-keyword-face:,» bar + «:haskell-tng-keyword-face:,» «:haskell-tng-keyword-face:(» blah + «:haskell-tng-keyword-face:,» blah + «:haskell-tng-keyword-face:,» blah «:haskell-tng-keyword-face:)» + «:haskell-tng-keyword-face:)» + +tuples2 «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:(» + foo +«:haskell-tng-keyword-face:,» bar +«:haskell-tng-keyword-face:)» + +tuples3 «:haskell-tng-keyword-face:=» «:haskell-tng-keyword-face:(» foo «:haskell-tng-keyword-face:,» + bar «:haskell-tng-keyword-face:)» + +typesig «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: a »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: b »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: c +» +types1 «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: + Monad m + »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: a + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: b + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: c +» +types2 «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: »«:haskell-tng-keyword-face:(»«:haskell-tng-type-face:Monad m»«:haskell-tng-keyword-face:,»«:haskell-tng-type-face: MemberLogger m»«:haskell-tng-keyword-face:)»«:haskell-tng-type-face: + »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: a + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: b + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: c +» +types2b + «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: »«:haskell-tng-keyword-face:(»«:haskell-tng-type-face:Monad m»«:haskell-tng-keyword-face:,»«:haskell-tng-type-face: MemberLogger m»«:haskell-tng-keyword-face:)»«:haskell-tng-type-face: + »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: a + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: b + »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: c +» +types3 «:haskell-tng-keyword-face:::»«:haskell-tng-type-face: »«:haskell-tng-keyword-face:(»«:haskell-tng-type-face:Monad m»«:haskell-tng-keyword-face:,»«:haskell-tng-type-face: MonadReader Foo m»«:haskell-tng-keyword-face:)»«:haskell-tng-type-face: »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: + »«:haskell-tng-keyword-face:(»«:haskell-tng-type-face:?log »«:haskell-tng-keyword-face:::»«:haskell-tng-type-face: HasLogger m»«:haskell-tng-keyword-face:)»«:haskell-tng-type-face: »«:haskell-tng-keyword-face:=>»«:haskell-tng-type-face: + a »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: b »«:haskell-tng-keyword-face:->»«:haskell-tng-type-face: c +» \ No newline at end of file