├── images
├── logo.png
├── screenshot1.png
├── screenshot-cabal1.png
└── logo.svg
├── cabal-configuration.json
├── test
├── tests
│ ├── InvalidClosingBlockComment.hs
│ ├── MultipleFunDecl.hs
│ ├── Happy2.y
│ ├── GADTTicks.hs
│ ├── Tuples.hs
│ ├── CPP.hs
│ ├── Alex2.x
│ ├── Pipe.hs
│ ├── WildcardExport.hs
│ ├── Forall.hs
│ ├── PragmaComments.hs
│ ├── Arrows.hs
│ ├── Data1.hs
│ ├── SymbolicPatternSynonyms.hs
│ ├── ExportsMagicHash.hs
│ ├── Newtype1.hs
│ ├── QualifiedDo.hs
│ ├── Data2.hs
│ ├── Data3.hs
│ ├── LiterateHaskell.lhs
│ ├── Newtype2.hs
│ ├── Newtype3.hs
│ ├── MultiLineTypeSignatures.hs
│ ├── TypeVsData.hs
│ ├── Specialise.hs
│ ├── NonRecord.hs
│ ├── ImportIndentation.hs
│ ├── Language.hs
│ ├── Fixity.hs
│ ├── CommentLike.hs
│ ├── Prefix.hs
│ ├── EndTypeSig.hs
│ ├── Kinds.hs
│ ├── Keywords.hs
│ ├── QualifiedFields.hs
│ ├── LinearTypes.hs
│ ├── ReservedInComments.hs
│ ├── Role.hs
│ ├── Comments.hs
│ ├── Happy.y
│ ├── Imports.hs
│ ├── NearReserved.hs
│ ├── InfixDataDecl.hs
│ ├── GADTRecord.hs
│ ├── InfixBacktick.hs
│ ├── BlockComments.hs
│ ├── Exports.hs
│ ├── UnusualTypeApplications.hs
│ ├── Alex.x
│ ├── Class.hs
│ ├── Records.hs
│ ├── Fields.hs
│ ├── ADTs.hs
│ ├── OverloadedLabels.hs
│ ├── Haddocks.hs
│ ├── GADTs.hs
│ ├── MultilineDeriving.hs
│ ├── QuasiQuotes.hs
│ ├── TypeSigs.hs
│ ├── MagicHash.hs
│ └── Ticks.hs
├── tickets
│ ├── T0029.hs
│ ├── T0146c.hs
│ ├── T0073b.hs
│ ├── T0151.hs
│ ├── T0120.hs
│ ├── T0170.hs
│ ├── T0150.hs
│ ├── T0043b.hs
│ ├── T0050.hs
│ ├── T0189.y
│ ├── T230.hs
│ ├── T0039.hs
│ ├── T0122.hs
│ ├── T0088.hs
│ ├── T0001.hs
│ ├── T0028.hs
│ ├── T0104.hs
│ ├── T0150b.hs
│ ├── T0043.hs
│ ├── T0051.hs
│ ├── T0018.hs
│ ├── T0108.hs
│ ├── T0163.hs
│ ├── T0071b.hs
│ ├── T0150c.hs
│ ├── T0028b.hs
│ ├── T0172.lhs
│ ├── T0091.hs
│ ├── T0131.hs
│ ├── T0064.hs
│ ├── T0070.hs
│ ├── T0175.hs
│ ├── T0136.hs
│ ├── T0039b.hs
│ ├── T0023.hs
│ ├── T0031.hs
│ ├── T0015.hs
│ ├── T0121.hs
│ ├── T0118.hs
│ ├── T0035.hs
│ ├── T0002.hs
│ ├── T0072b2.hs
│ ├── T0111.hs
│ ├── T0069.hs
│ ├── T0020b.hs
│ ├── T0112.hs
│ ├── T0178.hs
│ ├── T0090.hs
│ ├── T0020.hs
│ ├── T0066.hs
│ ├── T0190.hs
│ ├── T0072a.hs
│ ├── T0089.hs
│ ├── T0038.hs
│ ├── T0073.hs
│ ├── T0146.hs
│ ├── T0102.hs
│ ├── T0030.hs
│ ├── T0071.hs
│ ├── T0116.hs
│ ├── T0146b.hs
│ ├── T0072b3.hs
│ ├── T0167.hs
│ ├── T0157.hs
│ ├── T0182.hs
│ ├── T0132.hs
│ ├── T0156.hs
│ ├── T0072b.hs
│ ├── T0165.hs
│ ├── T0161.hs
│ ├── T0072c.hs
│ └── T0044.hs
├── wontfix
│ ├── MultilineFunDecl.hs
│ └── MultilineGADT.hs
└── test.sh
├── .vscodeignore
├── .gitignore
├── tsconfig.json
├── scope-lists
├── cabal.yaml
├── cabal.md
├── literateHaskell.yaml
├── literateHaskell.md
├── happy.yaml
├── happy.md
├── alex.yaml
├── alex.md
└── refresh.hs
├── syntax-examples
├── alex.x
├── haskell.hs
├── cabal.cabal
├── happy.y
├── embedding.md
└── backpack.hsig
├── .vscode
├── settings.json
├── launch.json
└── tasks.json
├── syntaxes
├── C2Hs.json
├── Hsc2Hs.json
├── codeblock-cabal.json
├── codeblock-haskell.json
├── codeblock-literate-haskell.json
├── literateHaskell.YAML-tmLanguage
├── haddock.YAML-tmLanguage
├── cabal.YAML-tmLanguage
├── happy.YAML-tmLanguage
└── alex.YAML-tmLanguage
├── PULL_REQUEST_TEMPLATE.md
├── DEVELOPMENT.md
├── C2Hs-configuration.json
├── .github
└── workflows
│ └── github-ci.yml
├── haskell-configuration.json
├── Hsc2Hs-configuration.json
├── literate-haskell-configuration.json
├── src
└── extension.ts
├── Makefile
├── webpack.config.js
├── LICENSE
└── README.md
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustusAdam/language-haskell/HEAD/images/logo.png
--------------------------------------------------------------------------------
/images/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustusAdam/language-haskell/HEAD/images/screenshot1.png
--------------------------------------------------------------------------------
/cabal-configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "comments": {
3 | "lineComment": "--",
4 | "blockComment": []
5 | }
6 | }
--------------------------------------------------------------------------------
/images/screenshot-cabal1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JustusAdam/language-haskell/HEAD/images/screenshot-cabal1.png
--------------------------------------------------------------------------------
/test/tests/InvalidClosingBlockComment.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Invalid closing block comment"
2 |
3 | -}
4 | -- ^^ invalid
5 |
--------------------------------------------------------------------------------
/test/tickets/T0029.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "rec keyword"
2 |
3 | f = do
4 | rec a <- go a
5 | -- <~~--- keyword.control.rec.haskell
6 | return a
--------------------------------------------------------------------------------
/test/tickets/T0146c.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Highlighting in multiline data declarations"
2 |
3 | data D
4 | = MethodCall "getDecks" Cards
5 |
--------------------------------------------------------------------------------
/test/tickets/T0073b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Visible kind application"
2 |
3 | type TF l = F @_ @(l :: Nat) A
4 | -- ^ ^ meta.type-application.haskell
--------------------------------------------------------------------------------
/test/tickets/T0151.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Constructors and parentheses"
2 |
3 | fail = S (S Z)
4 | -- ^ ^ ^ constant.other.haskell
5 | success = S (S Z )
6 | -- ^ ^ ^ constant.other.haskell
--------------------------------------------------------------------------------
/test/tickets/T0120.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Infix constructors"
2 |
3 | myTail :: [a] -> [a]
4 | myTail ( a `Cons` as ) = as
5 | -- ^^^^ keyword.operator.function.infix.haskell constant.other.haskell
--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .vscode/**
2 | typings/**
3 | out/test/**
4 | test/**
5 | src/**
6 | **/*.map
7 | .gitignore
8 | tsconfig.json
9 | test.hs
10 | test.cabal
11 | scope-lists/**
12 | syntaxes/*.YAML-tmLanguage
13 | .github/**
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | dist
3 | *.vsix
4 | node_modules
5 | syntaxes/haskell.json
6 | npm-debug.log
7 | syntaxes/cabal.json
8 | syntaxes/literateHaskell.json
9 | syntaxes/alex.json
10 | syntaxes/happy.json
11 | test/*/*.snap
12 | .vscode-test-web
--------------------------------------------------------------------------------
/test/tickets/T0170.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Lists starting with '|'"
2 |
3 | removed as = removeChars ['|', '-'] as
4 | -- ^^^ string.quoted.single.haskell
5 | -- ^^^^^^^^^^^^^ - meta.quasi-quotation.haskell
6 |
--------------------------------------------------------------------------------
/test/tests/MultipleFunDecl.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Declaring several functions"
2 |
3 |
4 |
5 | f1, f2, f3 :: a -> b -> c
6 | -- ^^^^^^^^^^ meta.function.type-declaration.haskell
7 | -- ^^ ^^ ^^ entity.name.function.haskell
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/tickets/T0150.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Pragma after data declaration"
2 |
3 | data D = C
4 |
5 | {-# COMPLETE P #-}
6 | -- ^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
7 | -- ^^^^^^^^^^^^^^^^^^ - comment.block.haskell
8 | pattern P :: A
9 | pattern P = C
--------------------------------------------------------------------------------
/test/tickets/T0043b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Escaped chars"
2 |
3 | chars = [ '\^A', '\^@', '\n' ]
4 | -- ^^^^^ ^^^^^ ^^^^ string.quoted.single.haskell
5 | -- ^^^ ^^^ constant.character.escape.control.haskell
6 | -- ^^ constant.character.escape.haskell
--------------------------------------------------------------------------------
/test/tickets/T0050.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Type-level symbols"
2 |
3 | instance Has Point "of" Int
4 | -- ^^^^ string.quoted.double.haskell
5 |
6 | example = from (Point 1 2) (Get :: Label "of")
7 | -- ^^^^ string.quoted.double.haskell
8 |
--------------------------------------------------------------------------------
/test/tickets/T0189.y:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell.happy" "Happy"
2 |
3 | foo :: { Foo }
4 | : foo { $1 }
5 | -- ^^ variable.parameter.happy
6 |
7 |
8 | fooBar :: { (Foo, Bar) }
9 | : foo bar { ($1, $2) }
10 | -- ^^ ^^ variable.parameter.happy
11 |
--------------------------------------------------------------------------------
/test/tickets/T230.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Exports with magic hash"
2 |
3 | module M
4 | ( T#(f#,C#,(+#),g#)
5 | -- ^ storage.type.haskell
6 | -- ^ ^ entity.name.function.haskell
7 | , Int, Bool
8 | -- ^^^ ^^^^ storage.type.haskell
9 |
10 | )
11 | where
12 |
--------------------------------------------------------------------------------
/test/tests/Happy2.y:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell.happy" "Happy apostrophes etc"
2 |
3 | %_name parse
4 | -- <----- entity.name.directive.happy
5 |
6 | %tokentype' { Token }
7 | -- <---------- entity.name.directive.happy
8 |
9 | %er'o_r'_ { parseError }
10 | -- <-------- entity.name.directive.happy
11 |
--------------------------------------------------------------------------------
/test/tickets/T0039.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "forall keyword in existential types"
2 |
3 | data Exts = forall var . Class var => Exts var
4 | -- ^^^^^^ keyword.other.forall.haskell
5 |
6 | data Exts where
7 | F :: forall var . Class var => Exts var
8 | -- ^^^^^^ keyword.other.forall.haskell
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "esnext",
5 | "outDir": "out",
6 | "sourceMap": true,
7 | "strict": true,
8 | "lib": ["ESNext"],
9 | "rootDir": "."
10 | },
11 | "exclude": [
12 | "node_modules",
13 | "out"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/test/tickets/T0122.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Interaction between constructors and symbols"
2 |
3 | f (A,B) = 3
4 | -- ^ ^ constant.other.haskell
5 | f ( A,B ) = 3
6 | -- ^ ^ constant.other.haskell
7 | f ( A ,B ) = 3
8 | -- ^ ^ constant.other.haskell
9 |
10 | g [X,Y,Z] = 0
11 | -- ^ ^ ^ constant.other.haskell
--------------------------------------------------------------------------------
/test/tickets/T0088.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Non-ASCII unicode text"
2 |
3 | unicöde :: String -> [Char]
4 | -- <------- entity.name.function.haskell
5 | -- <--------------------------- meta.function.type-declaration.haskell
6 | -- <--------------------------- - invalid
7 | unicöde = undefined
8 | -- <------------------- - invalid
--------------------------------------------------------------------------------
/scope-lists/cabal.yaml:
--------------------------------------------------------------------------------
1 | - scope: Cabal
2 | hide: true
3 | - scope: comment.line.double-dash
4 | - scope: constant.numeric.cabal
5 | - scope: entity.name.function.cabal
6 | - scope: entity.name.section.cabal
7 | - scope: keyword.control.cabal
8 | - scope: keyword.operator.cabal
9 | - scope: keyword.other.cabal
10 | - scope: markup.underline.link.cabal
11 |
--------------------------------------------------------------------------------
/test/tickets/T0001.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Multiline type signature"
2 |
3 | dbPageWrapper :: (DashBoardPage p, Monad m) =>
4 | T.Text -> p -> HtmlT m a -> HtmlT m b -> HtmlT m b
5 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.type-declaration.haskell
6 | -- ^^^^^ storage.type.haskell
7 |
8 |
--------------------------------------------------------------------------------
/test/tickets/T0028.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Highlighting do arrow after type signature"
2 |
3 | someFunc :: IO ()
4 | someFunc = do
5 | result <- ioAction
6 | result :: Int <- ioAction
7 | -- ^^ keyword.operator.arrow.left.haskell
8 | ( result :: Int ) <- ioAction
9 | -- ^^ keyword.operator.arrow.left.haskell
10 |
--------------------------------------------------------------------------------
/test/tickets/T0104.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Comments in export lists"
2 |
3 | module StockQuote
4 | -- ( getQuote
5 | -- ^^^^^^^^^^^^^ comment.line.double-dash.haskell
6 | -- ) where
7 | -- ^^^^^^^^^^ comment.line.double-dash.haskell
8 | -- ^^^^^ - keyword.other.where.haskell
9 | where
10 | -- ^^^^^ keyword.other.where.haskell
--------------------------------------------------------------------------------
/test/tickets/T0150b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "LiquidHaskell annotation after data declaration"
2 |
3 | data D = C
4 |
5 | {-@ f :: (Ord a) => xs:[a] -> (IncrList a) @-}
6 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ block.liquidhaskell.haskell
7 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - comment.block.haskell
8 | f :: [a] -> [a]
--------------------------------------------------------------------------------
/test/tickets/T0043.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Escaped strings"
2 |
3 | astring = "\^A \^@ \^_"
4 | -- ^^^^^^^^^^^^^ string.quoted.double.haskell
5 | -- ^^^ ^^^ ^^^ constant.character.escape.control.haskell
6 | anotherstring = "^\\ \n"
7 | -- ^^^^^^^^ string.quoted.double.haskell
8 | -- ^^ ^^ constant.character.escape.haskell
--------------------------------------------------------------------------------
/test/tickets/T0051.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Type-level naturals"
2 |
3 | f :: A 3 -> B 4
4 | -- ^ ^ constant.numeric.integral.decimal.haskell
5 |
6 | let x = (something :: MyLabel 5)
7 | -- ^ constant.numeric.integral.decimal.haskell
8 | g = f @( F 3 + 4 )
9 | -- ^ ^ constant.numeric.integral.decimal.haskell
10 |
--------------------------------------------------------------------------------
/scope-lists/cabal.md:
--------------------------------------------------------------------------------
1 | | Scope Name | Description | Example |
2 | |-|-|-|
3 | | comment.line.double-dash | | |
4 | | constant.numeric.cabal | | |
5 | | entity.name.function.cabal | | |
6 | | entity.name.section.cabal | | |
7 | | keyword.control.cabal | | |
8 | | keyword.operator.cabal | | |
9 | | keyword.other.cabal | | |
10 | | markup.underline.link.cabal | | |
11 |
--------------------------------------------------------------------------------
/test/tests/GADTTicks.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Ticks in GADT constructors"
2 |
3 | data D where
4 | T' :: D
5 | -- ^^ constant.other.haskell
6 | T_'_'_''t :: D
7 | -- ^^^^^^^^^ constant.other.haskell
8 | T_'ttt_'t_' :: D
9 | -- ^^^^^^^^^^^ constant.other.haskell
10 | T'x''' :: D
11 | -- ^^^^^^ constant.other.haskell
--------------------------------------------------------------------------------
/test/tests/Tuples.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Tuple constructors"
2 |
3 | f = (,)
4 | -- ^^^ support.constant.tuple.haskell
5 | f = (, )
6 | -- ^^^ support.constant.tuple.haskell
7 | f = ( ,)
8 | -- ^^^^ support.constant.tuple.haskell
9 | f = ( , , )
10 | -- ^^^^^^^ support.constant.tuple.haskell
11 | f = (, , ,,,)
12 | -- ^^^^^^^^^ support.constant.tuple.haskell
13 |
--------------------------------------------------------------------------------
/test/tickets/T0018.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Module exporting a module"
2 |
3 | module Main
4 | ( module M
5 | -- ^^^^^^ meta.declaration.exports.haskell keyword.other.module.haskell
6 | , M
7 | -- ^ meta.declaration.exports.haskell storage.type.haskell
8 | , foo
9 | -- ^^^ meta.declaration.exports.haskell entity.name.function.haskell
10 | ) where
--------------------------------------------------------------------------------
/test/tests/CPP.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "C preprocessor instructions"
2 |
3 | module M
4 | ( A
5 | , a
6 | #ifdef XYZ
7 | -- <----- meta.preprocessor.c
8 | , bcd
9 | , X
10 | #endif
11 | -- <----- meta.preprocessor.c
12 | )
13 | where
14 |
15 | #if MIN_VERSION_BASE(4,12,0)
16 | -- <-- meta.preprocessor.c
17 | foo :: A
18 | foo = A
19 | #endif
20 | -- <----- meta.preprocessor.c
--------------------------------------------------------------------------------
/test/tickets/T0108.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Correct support for 'signature'"
2 |
3 | signature M where
4 | -- <--------- keyword.other.signature.haskell
5 |
6 | f = do
7 | let signature = Some value
8 | -- ^^^^^^^^^ - keyword.other.signature.haskell
9 | return 0
10 | where
11 | signature = more testing
12 | -- ^^^^^^^^^ - keyword.other.signature.haskell
--------------------------------------------------------------------------------
/test/wontfix/MultilineFunDecl.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Multi-line function type declarations"
2 |
3 |
4 | f
5 | -- <- meta.function.type-declaration.haskell
6 | -- <- entity.name.function.haskell
7 | :: A -> B
8 |
9 |
10 | f
11 | -- <- meta.function.type-declaration.haskell
12 | -- <- entity.name.function.haskell
13 | :: forall a b
14 | . C x
15 | => D a
16 | => E b
17 | -> G
--------------------------------------------------------------------------------
/syntax-examples/alex.x:
--------------------------------------------------------------------------------
1 | {
2 |
3 | module Alex where
4 |
5 | import Foo as Bar
6 | import Baz (bax)
7 |
8 | }
9 |
10 | %wrapper "basic"
11 |
12 | $digit = 0-9
13 | $alpha = [a-zA-Z]
14 |
15 | tokens :-
16 | $white+ ;
17 | $digit+ { Number }
18 | $alpha+ { Ident }
19 |
20 | {
21 |
22 | data Token
23 | = Number
24 | | Ident
25 |
26 | main = undefined
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/scope-lists/literateHaskell.yaml:
--------------------------------------------------------------------------------
1 | - hide: true
2 | scope: Literate Haskell
3 | - scope: meta.embedded.block.haskell.latex
4 | - scope: meta.embedded.haskell
5 | - scope: punctuation.definition.arguments.begin.latex
6 | - scope: punctuation.definition.arguments.end.latex
7 | - scope: punctuation.definition.bird-track.haskell
8 | - scope: punctuation.definition.function.latex
9 | - scope: support.function.be.latex
10 |
--------------------------------------------------------------------------------
/test/tickets/T0163.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "StrictData language pragma"
2 |
3 | {-# LANGUAGE StrictData #-}
4 | -- ^^^^^^^^ keyword.other.preprocessor.pragma.haskell
5 | -- ^^^^^^^^^^ keyword.other.preprocessor.extension.haskell
6 |
7 |
8 | {-# LANGUAGE StrictDataNotAnExtension #-}
9 | -- ^^^^^^^^^^^^^^^^^^^^^^^^ - keyword.other.preprocessor.extension.haskell
10 |
--------------------------------------------------------------------------------
/scope-lists/literateHaskell.md:
--------------------------------------------------------------------------------
1 | | Scope Name | Description | Example |
2 | |-|-|-|
3 | | meta.embedded.block.haskell.latex | | |
4 | | meta.embedded.haskell | | |
5 | | punctuation.definition.arguments.begin.latex | | |
6 | | punctuation.definition.arguments.end.latex | | |
7 | | punctuation.definition.bird-track.haskell | | |
8 | | punctuation.definition.function.latex | | |
9 | | support.function.be.latex | | |
10 |
--------------------------------------------------------------------------------
/test/tickets/T0071b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Ticks in qualified names"
2 |
3 |
4 |
5 | f = A''.B'C.g `DE'.G'H.h` k XY'.A'B.+ z
6 | -- ^^^^^^^^ ^^^^^^^^ ^^^^^^^^ entity.name.namespace.haskell
7 |
8 | type S = A'.B.C'D.E `DE'.G'H.T` L XY'.A'B.+ Z
9 | -- ^^^^^^^^^ ^^^^^^^^ ^^^^^^^^ entity.name.namespace.haskell
10 |
11 | type T = 'A.C + 'B.+ D
12 | -- ^ ^ - entity.name.namespace.haskell
--------------------------------------------------------------------------------
/test/tickets/T0150c.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Haddock comments after data declaration"
2 |
3 | data D = C
4 |
5 | {-| docs docs -}
6 | -- ^^^^^^^^^^^^^^^^ comment.block.documentation.haskell
7 | -- ^^^^^^^^^^^^^^^^ - comment.block.haskell
8 |
9 | data D = C
10 |
11 | -- | docs docs
12 | -- ^^^^^^^^^^^^^^ comment.block.documentation.haskell
13 | -- ^^^^^^^^^^^^^^ - comment.line.double-dash.haskell
--------------------------------------------------------------------------------
/test/tickets/T0028b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Highlighting type signature before do arrow"
2 |
3 | someFunc :: IO ()
4 | someFunc = do
5 | result <- ioAction
6 | result :: Int <- ioAction
7 | -- ^^^ storage.type.haskell
8 | -- ^^ keyword.operator.arrow.left.haskell
9 | ( result :: Int ) <- ioAction
10 | -- ^^^ storage.type.haskell
11 | -- ^^ keyword.operator.arrow.left.haskell
--------------------------------------------------------------------------------
/test/tests/Alex2.x:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell.alex" "Alex apostrophes etc"
2 |
3 | %_wrapper "basic"
4 | -- <-------- entity.name.pragma.alex
5 |
6 | %wrapper' "basic"
7 | -- <-------- entity.name.pragma.alex
8 |
9 | %wrap'pe_r_ "basic"
10 | -- <---------- entity.name.pragma.alex
11 |
12 | $digit' = 0-9
13 | -- <------ entity.name.macro.character-set.alex
14 |
15 | $d'igi_t_ = 0-9
16 | -- <-------- entity.name.macro.character-set.alex
17 |
--------------------------------------------------------------------------------
/test/tests/Pipe.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Using | in types in an ADT"
2 |
3 |
4 | data A = A (T1 || T2) | A { f :: A |-| B }
5 | -- ^^^^ keyword.other.data.haskell
6 | -- ^ keyword.operator.pipe.haskell
7 | -- ^ variable.other.member.definition.haskell
8 | -- ^^ ^^^ storage.type.operator.infix.haskell
9 | -- ^ ^^ ^^ ^ ^ storage.type.haskell
10 |
--------------------------------------------------------------------------------
/test/tickets/T0172.lhs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "text.tex.latex.haskell" "Literate Haskell"
2 |
3 | \begin{code}
4 | -- ^^^^^^^^^^^^ meta.embedded.block.haskell.latex
5 | \ x -> x + x
6 | -- <- keyword.operator.lambda.haskell
7 | -- ^^ keyword.operator.arrow.haskell
8 | -- ^ keyword.operator.infix.haskell
9 | \end{code}
10 |
11 | \ x -> x + x
12 | -- <- - keyword.operator.lambda.haskell
13 | -- ^^ - keyword.operator.arrow.haskell
14 | -- ^ - keyword.operator.infix.haskell
15 |
--------------------------------------------------------------------------------
/test/tickets/T0091.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Indented modules"
2 |
3 | module Foo where
4 |
5 | data Foo where
6 | -- ^^^^ keyword.other.data.haskell
7 | MkFoo :: Foo
8 | -- ^^^^^ constant.other.haskell
9 | -- ^^^ storage.type.haskell
10 |
11 | myFoo :: Foo
12 | -- ^^^^^ entity.name.function.haskell
13 | -- ^^^^^^^^^^^^ meta.function.type-declaration.haskell
14 | -- ^^^^^^^^^^^^ - meta.declaration.data.generalized.haskell
15 | myFoo = foo
16 |
--------------------------------------------------------------------------------
/test/tests/WildcardExport.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Bug with wildcard export consuming a single parenthesis"
2 |
3 | module M
4 | ( S1(..), S2 (..)
5 | -- ^^ ^^ variable.other.member.wildcard.haskell
6 | , T
7 | ( .. , ( ..! ), ( :.. ), P, Q )
8 | -- ^^ variable.other.member.wildcard.haskell
9 | -- ^^ ^^ - variable.other.member.wildcard.haskell
10 | , foo
11 | -- ^^^ entity.name.function.haskell
12 | -- ^^^ - invalid
13 | )
14 | where
15 |
--------------------------------------------------------------------------------
/test/tickets/T0131.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "LiquidHaskell annotations"
2 |
3 | {-@ incr :: x:Nat -> {v:Nat | v > x} @-}
4 | -- <--------------------------------------- block.liquidhaskell.haskell
5 | -- ^^ keyword.operator.double-colon.haskell
6 | -- ^^ keyword.operator.arrow.haskell
7 | -- -------------------------------- - comment.block.haskell
8 | -- ^^^ - keyword.type.operator.haskell
9 | incr :: Int -> Int
10 | incr x = x + 1
11 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "out": true, // set this to true to hide the "out" folder with the compiled JS files
5 | "node_modules": true
6 | },
7 | "search.exclude": {
8 | "out": true // set this to false to include "out" folder in search results
9 | },
10 | "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version
11 | }
12 |
--------------------------------------------------------------------------------
/test/tickets/T0064.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Comments in module exports"
2 |
3 | module M
4 | -- ( f
5 | -- ^ comment.line.double-dash.haskell
6 | -- where
7 | -- ^^^^^ comment.line.double-dash.haskell
8 | where
9 | -- ^^^^^ keyword.other.where.haskell
10 |
11 |
12 | module M
13 | ( f
14 | -- ^ meta.declaration.exports.haskell entity.name.function.haskell
15 | -- g
16 | -- ^ comment.line.double-dash.haskell
17 | ) where
18 | -- ^^^^^ keyword.other.where.haskell
19 |
--------------------------------------------------------------------------------
/test/tickets/T0070.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Custom operators"
2 |
3 | data (:-> )
4 | -- ^^^ storage.type.operator.haskell
5 | data ( :=>) a b c = D
6 | -- ^^^ storage.type.operator.haskell
7 | -- ^ ^ ^ variable.other.generic-type.haskell
8 | -- ^ constant.other.haskell
9 |
10 | f :: a :-> b -> c :=> e
11 | -- ^^^ storage.type.operator.infix.haskell
12 | -- ^^ keyword.operator.arrow.haskell
13 | -- ^^^ storage.type.operator.infix.haskell
14 |
15 |
--------------------------------------------------------------------------------
/test/tests/Forall.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "forall dot over multiple lines"
2 |
3 |
4 |
5 | f :: forall a
6 | -- ^^^^^^ keyword.other.forall.haskell
7 | . b
8 | -- ^ keyword.operator.period.haskell
9 |
10 |
11 | type T :: forall a
12 | -- ^^^^^^ keyword.other.forall.haskell
13 | . b
14 | -- ^ keyword.operator.period.haskell
15 |
16 | type T ( a :: forall b
17 | -- ^^^^^^ keyword.other.forall.haskell
18 | . c ) = D
19 | -- ^ keyword.operator.period.haskell
20 |
--------------------------------------------------------------------------------
/syntax-examples/haskell.hs:
--------------------------------------------------------------------------------
1 |
2 | someFunc :: IO Int
3 | someFunc = do
4 | another argument
5 | arg :: Type
6 | let x = 6 :: Int
7 | a `Infix.Operator.func` b
8 | a `func` b
9 | a :: Bool <- something
10 | if a then b :: Int else g
11 | case (a :: Bool) of
12 | Nothing -> b
13 | return 6
14 | where
15 | ident = 4
16 | ident' = 9
17 |
18 |
19 | anotherFunc arg = do
20 | { let thing = 5>
21 | ; arg <- doSomething 5
22 | ; let thing = 5
23 | ; return 8
24 | }
25 |
--------------------------------------------------------------------------------
/test/tests/PragmaComments.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Comments inside pragma"
2 |
3 | {-# LANGUAGE
4 | -- Type level programming
5 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell
6 | DataKinds, PolyKinds,
7 | -- Generics
8 | -- ^^^^^^^^^^^ comment.line.double-dash.haskell
9 | DeriveGeneric, DeriveAnyClass, DerivingVia
10 | {- Type applications -}
11 | -- ^^^^^^^^^^^^^^^^^^^^^^^ comment.block.haskell
12 | , TypeApplications, AllowAmbiguousTypes
13 | #-}
14 |
--------------------------------------------------------------------------------
/syntaxes/C2Hs.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": [ "chs" ],
3 | "name": "C2Hs",
4 | "scopeName": "source.c2hs",
5 | "patterns": [
6 | {
7 | "begin": "\\{#",
8 | "end": "#\\}",
9 | "beginCaptures": {
10 | "0": {
11 | "name": "punctuation.definition.preprocessor.begin.c2hs"
12 | }
13 | },
14 | "endCaptures": {
15 | "0": {
16 | "name": "punctuation.definition.preprocessor.end.c2hs"
17 | }
18 | },
19 | "name": "meta.preprocessor.c2hs"
20 | },
21 | { "include": "source.haskell" }
22 | ]
23 | }
--------------------------------------------------------------------------------
/test/tickets/T0175.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Unicode forall"
2 |
3 | foo :: (∀ a. Num a => a -> a) -> (Int,Double) -> (Int,Double)
4 | -- ^ keyword.other.forall.haskell
5 | -- ^ keyword.operator.period.haskell
6 | foo f (a,b) = (f a, f b)
7 |
8 | bar :: (forall a. Num a => a -> a) -> (Int,Double) -> (Int,Double)
9 | -- ^^^^^^ keyword.other.forall.haskell
10 | -- ^ keyword.operator.period.haskell
11 | bar f (a,b) = (f a, f b)
12 |
13 | notForall :: x ∀∀ y -> z
14 | -- ^^ - keyword.other.forall.haskell
15 |
--------------------------------------------------------------------------------
/syntax-examples/cabal.cabal:
--------------------------------------------------------------------------------
1 | -- A comment
2 |
3 | name: test-name
4 | author: Someone
5 |
6 | common common
7 | build-depends: base
8 |
9 | library
10 | import: common
11 | build-depends: template-haskell
12 | extra-library-flavours: test
13 | extra-dynamic-library-flavours: test
14 | autogen-includes: test.h
15 | virtual-modules: M
16 | x-my-option-1: test
17 |
18 | library sublib
19 | import: common
20 | visibility: private
21 | hs-source-dirs: src
22 |
23 | executable my-exec
24 | build-depends: test-name, sublib
25 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## For changes related to the grammar
2 |
3 | - Please add a test case.
4 |
5 | - For changes to regular Haskell code simply add a new section to `test/syntax-examples/test.hs`.
6 | Make sure your case has a descriptive comment about what it is covering.
7 |
8 | - When adding foreign definitions, i.e. embeddings, add a new test file for the embedding in
9 | question.
10 |
11 | - Add your changes to the `CHANGELOG.md` file, ideally with a reference to the issue the PR is
12 | fixing. Also feel free to credit yourself there.
13 |
--------------------------------------------------------------------------------
/test/tickets/T0136.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Promotion ticks"
2 |
3 | f :: proxy ( 'CD a b ) -> proxy ( a '`CD` b )
4 | -- ^^ storage.type.haskell
5 | -- ^^ storage.type.infix.haskell
6 | -- ^ ^ keyword.operator.promotion.haskell
7 |
8 | g :: proxy ( '(:< ) a b ) -> proxy ( a ':< b )
9 | -- ^^ storage.type.operator.haskell
10 | -- ^^ storage.type.operator.infix.haskell
11 | -- ^ ^ keyword.operator.promotion.haskell
--------------------------------------------------------------------------------
/syntax-examples/happy.y:
--------------------------------------------------------------------------------
1 | {
2 |
3 | module Happy where
4 |
5 | import Foo as Bar
6 | import Baz (bax)
7 |
8 | }
9 |
10 | %monad { P }
11 |
12 | %name parse
13 | %tokentype { Token }
14 | %error { parseError }
15 |
16 | %token
17 | '+' { PLUS }
18 | num { NUMBER $$ }
19 |
20 | %left '+'
21 |
22 | %%
23 |
24 | value :: { AST }
25 | : value '+' value { Add $1 $3 }
26 | | num { Number $1 }
27 |
28 | {
29 |
30 | data Token
31 | = PLUS
32 | | NUMBER Int
33 |
34 | data AST
35 | = Add AST AST
36 | | Number Int
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/test/tests/Arrows.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Arrow keywords"
2 |
3 | h a b = proc (a, r) -> do rec
4 | -- ^^ keyword.operator.arrow.haskell
5 | -- ^^^^ keyword.control.proc.haskell
6 | -- ^^ keyword.control.do.haskell
7 | -- ^^^ keyword.control.rec.haskell
8 | (f -< (a, r)) `h` \e -> g -< ((a, e), r)
9 | -- ^ keyword.operator.lambda.haskell
10 | -- ^^ keyword.operator.arrow.haskell
11 | -- ^^ ^^ keyword.operator.arrow.left.tail.haskell
--------------------------------------------------------------------------------
/syntaxes/Hsc2Hs.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": [ "hsc" ],
3 | "name": "Hsc2Hs",
4 | "scopeName": "source.hsc",
5 | "patterns": [
6 | {
7 | "begin": "#\\{",
8 | "end": "\\}",
9 | "beginCaptures": {
10 | "0": {
11 | "name": "punctuation.definition.preprocessor.begin.hsc"
12 | }
13 | },
14 | "endCaptures": {
15 | "0": {
16 | "name": "punctuation.definition.preprocessor.end.hsc"
17 | }
18 | },
19 | "name": "meta.preprocessor.hsc"
20 | },
21 | { "include": "source.haskell" }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/DEVELOPMENT.md:
--------------------------------------------------------------------------------
1 | # Developer information
2 |
3 | In version 3.0 the grammar format has changed. For maintenance and conciseness resons we now use YAML as the grammar format. This means when making improvements to the grammar please edit `syntaxes/haskell.YAML-tmLanguage`.
4 |
5 | Since Visual Studio Code does not natively understand yaml grammars we use the `js-yaml` tool to generate `syntaxes/haskell.json`. The task configuration should automatically generate the `syntaxes/haskell.json` file that Visual Studio Code actually loads. Should you experience problems with the task configuration feel free to open a bug report.
6 |
--------------------------------------------------------------------------------
/test/tests/Data1.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Indented data declarations"
2 |
3 | data T = C T
4 |
5 | data T = C T
6 | -- ^^^^ keyword.other.data.haskell
7 | -- ^ keyword.operator.eq.haskell
8 | -- ^ constant.other.haskell
9 | -- ^ ^ storage.type.haskell
10 |
11 |
12 | data instance T = C T
13 | -- ^^^^ keyword.other.data.haskell
14 | -- ^^^^^^^^ keyword.other.instance.haskell
15 | -- ^ keyword.operator.eq.haskell
16 | -- ^ constant.other.haskell
17 | -- ^ ^ storage.type.haskell
18 |
19 |
--------------------------------------------------------------------------------
/test/tests/SymbolicPatternSynonyms.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Symbolic pattern synonyms"
2 |
3 |
4 | pattern (:<..<), (:<=..<=) :: t -> t -> Interval t
5 | -- ^^^^^^^ keyword.other.pattern.haskell
6 | -- ^^^^^ ^^^^^^^ constant.other.operator.haskell
7 | pattern (:<..<) s e = s :<..< e
8 | -- ^^^^^ constant.other.operator.haskell
9 | -- ^^^^^ constant.other.operator.infix.haskell
10 | pattern (:<=..<=) s e = s :<=..<= e
11 | -- ^^^^^^^ constant.other.operator.haskell
12 | -- ^^^^^^^ constant.other.operator.infix.haskell
13 |
--------------------------------------------------------------------------------
/test/tickets/T0039b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "forall dot not parsed as an operator"
2 |
3 | f :: forall a. a
4 | -- ^ keyword.operator.period.haskell
5 | g :: forall a . a -> ( forall b . b ) -> a
6 | -- ^ ^ keyword.operator.period.haskell
7 |
8 | data Exts = forall var . Class var => Exts var
9 | -- ^^^^^^ keyword.other.forall.haskell
10 | -- ^ keyword.operator.period.haskell
11 |
12 | data Exts where
13 | F :: forall var . Class var => Exts var
14 | -- ^^^^^^ keyword.other.forall.haskell
15 | -- ^ keyword.operator.period.haskell
--------------------------------------------------------------------------------
/test/tests/ExportsMagicHash.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Exports with magic hash"
2 |
3 | module M
4 | ( T#(f#,C#,g#)
5 | -- ^ ^ storage.type.haskell
6 | -- ^ ^ entity.name.function.haskell
7 | , pattern P#
8 | -- ^^^^^^^ keyword.other.pattern.haskell
9 | -- ^ constant.other.haskell
10 | , f#, (+#), T#
11 | -- ^ entity.name.function.haskell
12 | -- ^ storage.type.haskell
13 | , type T#
14 | -- ^^^^ keyword.other.type.haskell
15 | -- ^ storage.type.haskell
16 | , type (-#)
17 | -- ^^^^ keyword.other.type.haskell
18 | -- ^^ storage.type.operator.haskell
19 | )
20 | where
21 |
--------------------------------------------------------------------------------
/test/tests/Newtype1.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Indented newtype declarations"
2 |
3 | newtype T = C T
4 |
5 | newtype T = C T
6 | -- ^^^^^^^ keyword.other.newtype.haskell
7 | -- ^ keyword.operator.eq.haskell
8 | -- ^ constant.other.haskell
9 | -- ^ ^ storage.type.haskell
10 |
11 |
12 | newtype instance T = C T
13 | -- ^^^^^^^ keyword.other.newtype.haskell
14 | -- ^^^^^^^^ keyword.other.instance.haskell
15 | -- ^ keyword.operator.eq.haskell
16 | -- ^ constant.other.haskell
17 | -- ^ ^ storage.type.haskell
18 |
19 |
--------------------------------------------------------------------------------
/test/tests/QualifiedDo.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "QualifiedDo"
2 |
3 | {-# LANGUAGE QualifiedDo #-}
4 | -- ^^^^^^^^^^^ keyword.other.preprocessor.extension.haskell
5 |
6 | f :: IO ()
7 | f = do
8 | -- ^^ keyword.control.do.haskell
9 | x <- runMAC $
10 |
11 | MAC.mdo
12 | -- ^^^^ entity.name.namespace.haskell
13 | -- ^^^ keyword.control.mdo.haskell
14 | d <- label "y"
15 | box $
16 |
17 | L.do
18 | -- ^^ entity.name.namespace.haskell
19 | -- ^^ keyword.control.do.haskell
20 | r <- L.f d
21 | L.g r
22 | L.return r
23 |
24 | MAC.return d
25 |
26 | print x
27 |
--------------------------------------------------------------------------------
/test/tickets/T0023.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Empty quasi-quote"
2 |
3 | instance Show NixIndexException where
4 | show (NixEnvFail errCode _ _) = [i||]
5 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
6 | -- ^ entity.name.quasi-quoter.haskell
7 | -- ^^ keyword.operator.quasi-quotation.end.haskell
8 | show ParseNixEnvResError = "Failed to parse the output of nix-env"
9 | -- <------------------------------------------------------------------ - meta.quasi-quotation.haskell
10 |
11 | type S = String
12 |
13 | -- <--------------- -meta.quasi-quotation.haskell
14 |
--------------------------------------------------------------------------------
/test/tickets/T0031.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Keyword identifiers with prime"
2 |
3 | let' = 5
4 | -- <--- - keyword.other.let.haskell
5 | class' = 4
6 | -- <----- - keyword.other.class.haskell
7 | module' = 6
8 | -- <------ - keyword.other.module.haskell
9 | instance' = 3
10 | -- <-------- - keyword.other.instance.haskell
11 | where' = 0
12 | -- <----- - keyword.other.where.haskell
13 | rec' = 6
14 | -- <--- - keyword.other.haskell
15 | import' = 5
16 | -- <------ - meta.import.haskell keyword.other.import.haskell
17 | if' = 6
18 | -- <-- - keyword.control.haskell
19 | else' = 7
20 | -- <---- - keyword.control.haskell
21 | then' = 0
22 | -- <---- - keyword.control.haskell
--------------------------------------------------------------------------------
/test/tickets/T0015.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Deriving for ADTs with sums and records"
2 |
3 | data Feed =
4 | BuildTask {
5 | blokName :: String,
6 | outPathBuild :: FilePath,
7 | relPath :: FilePath,
8 | srcFile :: Files.File
9 | }
10 | deriving Eq
11 | -- <~~-------- meta.deriving.haskell
12 |
13 | data Query
14 | = All
15 | | Some {
16 | feeds :: [String],
17 | cats :: [String],
18 | dates :: QueryDate
19 | }
20 | deriving Read
21 | -- <~~---------- meta.deriving.haskell
22 |
23 |
24 | data QueryDate
25 | = AnyDate
26 | | Between String String
27 | deriving Read
28 | -- <~~---------- meta.deriving.haskell
29 |
--------------------------------------------------------------------------------
/test/tickets/T0121.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Comments in data constructors"
2 |
3 | data Person = Person
4 | { name :: String, -- comment
5 | -- ^^^^^^^^^^ comment.line.double-dash.haskell
6 | sons :: [Person] -- comment
7 | -- ^^^^^^^^^^ comment.line.double-dash.haskell
8 | }
9 |
10 |
11 | {- comment1 -}
12 | -- <------------- comment.block.haskell
13 | {- comment 2 -}
14 | -- <~~------------- comment.block.haskell
15 | data A where {- comment3 -}
16 | -- ^^^^^^^^^^^^^^ comment.block.haskell
17 | {- comment4 -}
18 | -- <~~------------- comment.block.haskell
19 | {- comment5 -}
20 | -- <------------- comment.block.haskell
--------------------------------------------------------------------------------
/test/tickets/T0118.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Record fields with extra spaces"
2 |
3 | data Record a b =
4 | Record
5 | { short :: a
6 | -- ^^^^^ variable.other.member.definition.haskell
7 | -- ^ variable.other.generic-type.haskell
8 | , longer :: b
9 | -- ^^^^^^ variable.other.member.definition.haskell
10 | -- ^ variable.other.generic-type.haskell
11 | , tiny :: a
12 | -- ^^^^ variable.other.member.definition.haskell
13 | -- ^ variable.other.generic-type.haskell
14 | , spacious::b
15 | -- ^^^^^^^^ variable.other.member.definition.haskell
16 | -- ^ variable.other.generic-type.haskell
17 | }
18 |
--------------------------------------------------------------------------------
/test/tests/Data2.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Indented multiline data declarations (= on different line)"
2 |
3 | data T
4 | = C T
5 |
6 | data T
7 | -- ^^^^ keyword.other.data.haskell
8 | -- ^ storage.type.haskell
9 | = C T
10 | -- ^ keyword.operator.eq.haskell
11 | -- ^ constant.other.haskell
12 | -- ^ storage.type.haskell
13 |
14 | data instance T
15 | -- ^^^^ keyword.other.data.haskell
16 | -- ^^^^^^^^ keyword.other.instance.haskell
17 | -- ^ storage.type.haskell
18 | = C T
19 | -- ^ keyword.operator.eq.haskell
20 | -- ^ constant.other.haskell
21 | -- ^ storage.type.haskell
22 |
--------------------------------------------------------------------------------
/test/tests/Data3.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Indented multiline data declarations (= on same line)"
2 |
3 | data T =
4 | C T
5 |
6 | data T =
7 | -- ^^^^ keyword.other.data.haskell
8 | -- ^ storage.type.haskell
9 | -- ^ keyword.operator.eq.haskell
10 | C T
11 | -- ^ constant.other.haskell
12 | -- ^ storage.type.haskell
13 |
14 | data instance T =
15 | -- ^^^^ keyword.other.data.haskell
16 | -- ^^^^^^^^ keyword.other.instance.haskell
17 | -- ^ storage.type.haskell
18 | -- ^ keyword.operator.eq.haskell
19 | C T
20 | -- ^ constant.other.haskell
21 | -- ^ storage.type.haskell
22 |
--------------------------------------------------------------------------------
/test/tests/LiterateHaskell.lhs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "text.tex.latex.haskell" "Literate Haskell"
2 |
3 | > \ x -> x + x
4 | -- <~~- keyword.operator.lambda.haskell
5 | -- ^^ keyword.operator.arrow.haskell
6 | -- ^ keyword.operator.infix.haskell
7 |
8 | \begin{code}
9 | -- <------------ meta.embedded.block.haskell.latex
10 | \ x -> x + x
11 | -- <- keyword.operator.lambda.haskell
12 | -- ^^ keyword.operator.arrow.haskell
13 | -- ^ keyword.operator.infix.haskell
14 | \end{code}
15 | -- <---------- meta.embedded.block.haskell.latex
16 |
17 | \ x -> x + x
18 | -- <- - keyword.operator.lambda.haskell
19 | -- ^^ - keyword.operator.arrow.haskell
20 | -- ^ - keyword.operator.infix.haskell
21 |
--------------------------------------------------------------------------------
/test/tickets/T0035.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Data kind signatures"
2 |
3 | data D (a :: Kind) (b :: k -> [Type]) = D
4 | -- <---- keyword.other.data.haskell
5 | -- ^ variable.other.generic-type.haskell
6 | -- ^^ keyword.operator.double-colon.haskell
7 |
8 | data Tuple (ts :: [Type]) where
9 | -- <---- keyword.other.data.haskell
10 | -- ^^ variable.other.generic-type.haskell
11 | -- ^^ keyword.operator.double-colon.haskell
12 | Nil :: Tuple '[]
13 | Cons :: !t -> !(Tuple ts) -> Tuple (t : ts)
14 |
15 | data GADT2 :: Type -> Type where
16 | -- <---- keyword.other.data.haskell
17 | -- ^^ keyword.operator.double-colon.haskell
18 | C2 :: GADT2 Int
19 |
--------------------------------------------------------------------------------
/C2Hs-configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "comments": {
3 | "lineComment": "--",
4 | "blockComment": ["{-", "-}"]
5 | },
6 | "brackets": [
7 | ["{", "}"],
8 | ["[", "]"],
9 | ["(", ")"]
10 | ],
11 | "autoClosingPairs": [
12 | { "open": "{", "close": "}" },
13 | { "open": "[", "close": "]" },
14 | { "open": "(", "close": ")" },
15 | { "open": "\"", "close": "\"", "notIn": ["string"] },
16 | { "open": "`", "close": "`", "notIn": ["string", "comment"] }
17 | ],
18 | "surroundingPairs": [
19 | ["{", "}"],
20 | ["[", "]"],
21 | ["(", ")"],
22 | ["'", "'"],
23 | ["\"", "\""],
24 | ["`", "`"]
25 | ],
26 | "folding": {
27 | "offSide": true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/tests/Newtype2.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Indented multiline newtype declarations (= on different line)"
2 |
3 | newtype T
4 | = C T
5 |
6 | newtype T
7 | -- ^^^^^^ keyword.other.newtype.haskell
8 | -- ^ storage.type.haskell
9 | = C T
10 | -- ^ keyword.operator.eq.haskell
11 | -- ^ constant.other.haskell
12 | -- ^ storage.type.haskell
13 |
14 | newtype instance T
15 | -- ^^^^^^^ keyword.other.newtype.haskell
16 | -- ^^^^^^^^ keyword.other.instance.haskell
17 | -- ^ storage.type.haskell
18 | = C T
19 | -- ^ keyword.operator.eq.haskell
20 | -- ^ constant.other.haskell
21 | -- ^ storage.type.haskell
22 |
--------------------------------------------------------------------------------
/test/tests/Newtype3.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Indented multiline newtype declarations (= on same line)"
2 |
3 | newtype T =
4 | C T
5 |
6 | newtype T =
7 | -- ^^^^^^^ keyword.other.newtype.haskell
8 | -- ^ storage.type.haskell
9 | -- ^ keyword.operator.eq.haskell
10 | C T
11 | -- ^ constant.other.haskell
12 | -- ^ storage.type.haskell
13 |
14 | newtype instance T =
15 | -- ^^^^^^^ keyword.other.newtype.haskell
16 | -- ^^^^^^^^ keyword.other.instance.haskell
17 | -- ^ storage.type.haskell
18 | -- ^ keyword.operator.eq.haskell
19 | C T
20 | -- ^ constant.other.haskell
21 | -- ^ storage.type.haskell
22 |
--------------------------------------------------------------------------------
/test/tickets/T0002.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Comments in module exports"
2 |
3 | module Module
4 | -- <------ meta.declaration.module.haskell
5 | (
6 | -- main func <- disable highlighting
7 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell
8 | foo
9 | -- ^^^ meta.declaration.exports.haskell entity.name.function.haskell
10 | {- disable, too
11 | -- ^^^^^^^^^^^^ comment.block.haskell
12 | -}
13 | , bar, bar
14 | -- ^^^ meta.declaration.exports.haskell entity.name.function.haskell
15 | -- ^^^ meta.declaration.exports.haskell entity.name.function.haskell
16 | ) {- comm -} where
17 | -- ^^^^ comment.block.haskell
18 | -- ^^^^^ keyword.other.where.haskell
19 |
--------------------------------------------------------------------------------
/test/tests/MultiLineTypeSignatures.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Multi-line type signatures"
2 |
3 | f :: A
4 | -- ^ storage.type.haskell
5 | -> B
6 | -- ^ storage.type.haskell
7 | -> C
8 | -- ^ storage.type.haskell
9 |
10 | f
11 | :: A -> B
12 | -- ^ ^ storage.type.haskell
13 |
14 | f
15 | :: forall a b
16 | -- ^^^^^^ keyword.other.forall.haskell
17 | -- ^ ^ variable.other.generic-type.haskell
18 | . C x
19 | -- ^ storage.type.haskell
20 | -- ^ variable.other.generic-type.haskell
21 | => D a
22 | -- ^ storage.type.haskell
23 | -- ^ variable.other.generic-type.haskell
24 | => E b
25 | -- ^ storage.type.haskell
26 | -- ^ variable.other.generic-type.haskell
27 | -> G
28 | -- ^ storage.type.haskell
--------------------------------------------------------------------------------
/.github/workflows/github-ci.yml:
--------------------------------------------------------------------------------
1 | name: language-haskell CI
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | strategy:
15 | matrix:
16 | node-version: [18.x]
17 |
18 | steps:
19 |
20 | - uses: actions/checkout@v2
21 |
22 | - name: Setup node
23 | uses: actions/setup-node@v1
24 | with:
25 | node-version: ${{ matrix.node-version }}
26 |
27 | - name: Install dependencies
28 | run: npm install -g js-yaml vscode-tmgrammar-test
29 |
30 | - name: Generate grammar JSON files
31 | run: make grammars
32 |
33 | - name: Run tests
34 | run: make test
35 |
--------------------------------------------------------------------------------
/haskell-configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "comments": {
3 | "lineComment": "--",
4 | "blockComment": ["{-", "-}"]
5 | },
6 | "brackets": [
7 | ["{", "}"],
8 | ["[", "]"],
9 | ["(", ")"]
10 | ],
11 | "autoClosingPairs": [
12 | { "open": "{", "close": "}" },
13 | { "open": "[", "close": "]" },
14 | { "open": "(", "close": ")" },
15 | { "open": "\"", "close": "\"", "notIn": ["string"] },
16 | { "open": "`", "close": "`", "notIn": ["string", "comment"] }
17 | ],
18 | "surroundingPairs": [
19 | ["{", "}"],
20 | ["[", "]"],
21 | ["(", ")"],
22 | ["'", "'"],
23 | ["\"", "\""],
24 | ["`", "`"]
25 | ],
26 | "folding": {
27 | "offSide": true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Hsc2Hs-configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "comments": {
3 | "lineComment": "--",
4 | "blockComment": ["{-", "-}"]
5 | },
6 | "brackets": [
7 | ["{", "}"],
8 | ["[", "]"],
9 | ["(", ")"]
10 | ],
11 | "autoClosingPairs": [
12 | { "open": "{", "close": "}" },
13 | { "open": "[", "close": "]" },
14 | { "open": "(", "close": ")" },
15 | { "open": "\"", "close": "\"", "notIn": ["string"] },
16 | { "open": "`", "close": "`", "notIn": ["string", "comment"] }
17 | ],
18 | "surroundingPairs": [
19 | ["{", "}"],
20 | ["[", "]"],
21 | ["(", ")"],
22 | ["'", "'"],
23 | ["\"", "\""],
24 | ["`", "`"]
25 | ],
26 | "folding": {
27 | "offSide": true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/literate-haskell-configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "comments": {
3 | "lineComment": "%",
4 | "blockComment": ["{-", "-}"]
5 | },
6 | "brackets": [
7 | ["{", "}"],
8 | ["[", "]"],
9 | ["(", ")"]
10 | ],
11 | "autoClosingPairs": [
12 | { "open": "{", "close": "}" },
13 | { "open": "[", "close": "]" },
14 | { "open": "(", "close": ")" },
15 | { "open": "\"", "close": "\"", "notIn": ["string"] },
16 | { "open": "`", "close": "`", "notIn": ["string", "comment"] }
17 | ],
18 | "surroundingPairs": [
19 | ["{", "}"],
20 | ["[", "]"],
21 | ["(", ")"],
22 | ["'", "'"],
23 | ["\"", "\""],
24 | ["`", "`"]
25 | ],
26 | "folding": {
27 | "offSide": true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/tests/TypeVsData.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Edge cases for type vs value highlighting"
2 |
3 | fun = do
4 | x :: T -> T <- D ( \ (x :: T) -> D )
5 | -- ^ - variable.other.generic-type.haskell
6 | -- ^ ^ ^ storage.type.haskell
7 | -- ^ ^ constant.other.haskell
8 |
9 | a = D { a = D :: T } D
10 | -- ^ storage.type.haskell
11 | -- ^ ^ ^ constant.other.haskell
12 |
13 | x :: T ->
14 |
15 | -- comment
16 | {-
17 | comment
18 | -}
19 |
20 |
21 | T
22 | -- ^ storage.type.haskell
23 |
24 |
25 | x
26 | :: T ->
27 |
28 | -- comment
29 | {-
30 | comment
31 | -}
32 |
33 |
34 | T
35 | -- ^ storage.type.haskell
36 |
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 |
2 | import vscode = require('vscode');
3 |
4 | const MATCH_NOTHING_RE = /$^/;
5 |
6 | export function activate(context: vscode.ExtensionContext) {
7 |
8 | vscode.languages.setLanguageConfiguration('haskell', {
9 | onEnterRules: [
10 | {
11 | beforeText: vscode.workspace.getConfiguration('haskell').indentationRules.enabled
12 | ? /(\bif\b(?!')(.(?!then))*|\b(then|else|m?do|of|let|in|where)\b(?!')|=|->|>>=|>=>|=<<|(^(data)( |\t)+(\w|')+( |\t)*))( |\t)*$/
13 | : MATCH_NOTHING_RE,
14 | action: { indentAction: vscode.IndentAction.Indent }
15 | }
16 | ],
17 | wordPattern: /([\w'_][\w'_\d]*)|([0-9]+\.[0-9]+([eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)/
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/test/tickets/T0072b2.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Deriving strategies (same line)"
2 |
3 | newtype B = B deriving A via B
4 | -- ^^^^^^^^ keyword.other.deriving.haskell
5 | -- ^^^ keyword.other.deriving.strategy.via.haskell
6 | -- ^ ^ storage.type.haskell
7 | data B = B deriving stock ( Eq, Generic )
8 | -- ^^^^^^^^ keyword.other.deriving.haskell
9 | -- ^^^^^ keyword.other.deriving.strategy.stock.haskell
10 | -- ^^ ^^^^^^^ storage.type.haskell
11 | data B = B deriving anyclass NFData
12 | -- ^^^^^^^^ keyword.other.deriving.haskell
13 | -- ^^^^^^^^ keyword.other.deriving.strategy.anyclass.haskell
14 | -- ^^^^^^ storage.type.haskell
15 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CONVERT=npx js-yaml
2 | VSCE=npx vsce
3 | SYNTAXES=haskell cabal literateHaskell alex happy
4 | JSON_TARGETS=$(addsuffix .json,$(addprefix syntaxes/,$(SYNTAXES)))
5 | SCOPE_LISTS=$(addsuffix .md,$(addprefix scope-lists/,$(SYNTAXES)))
6 |
7 | .PHONY: all test publish package
8 |
9 | all: grammars scopes
10 |
11 | grammars: $(JSON_TARGETS)
12 |
13 | scopes: $(SCOPE_LISTS)
14 |
15 | scope-lists/%.md: scope-lists/%.yaml
16 | scope-lists/refresh.hs md $< $@
17 |
18 | scope-lists/%.yaml: syntaxes/%.YAML-tmLanguage
19 | scope-lists/refresh.hs db $< $@
20 |
21 | test: grammars
22 | cd test && bash test.sh
23 |
24 | %.json: %.YAML-tmLanguage
25 | $(CONVERT) $< > $@
26 |
27 | publish: all
28 | $(VSCE) publish
29 |
30 | package: all
31 | $(VSCE) package
32 |
33 | clean:
34 | rm $(JSON_TARGETS)
--------------------------------------------------------------------------------
/test/tickets/T0111.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Multi line type aliases"
2 |
3 | type T a =
4 | Constr
5 | -- ^^^^^^ storage.type.haskell
6 | a
7 | -- ^ variable.other.generic-type.haskell
8 | Int
9 | -- ^^^ storage.type.haskell
10 |
11 | -- Multi line type alias with infix constructors
12 |
13 | type UserApi = "users" :> Body '[JSON]
14 | -- ^^ storage.type.operator.infix.haskell
15 | :> Post '[JSON]
16 | -- ^^^^ storage.type.haskell
17 | :<|> "users" :> Capture "userid"
18 | -- ^^^^ ^^ storage.type.operator.infix.haskell
19 | -- ^^^^^^^^ string.quoted.double.haskell
20 | :> ReqBody '[JSON]
21 | -- ^^^^^^^ storage.type.haskell
22 |
--------------------------------------------------------------------------------
/test/tickets/T0069.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Parentheses in import and export lists"
2 | module Main (
3 | Foo((+-)), func1
4 | -- ^^ meta.declaration.exports.haskell entity.name.function.infix.haskell
5 | -- ^^^^^ meta.declaration.exports.haskell entity.name.function.haskell
6 | -- ^^^^^ - invalid
7 | , Bar((:->), (:->>)), Baz, func5
8 | -- ^^^ ^^^^ meta.declaration.exports.haskell constant.other.operator.prefix.haskell
9 | -- ^^^ meta.declaration.exports.haskell storage.type.haskell
10 | -- ^^^^^ meta.declaration.exports.haskell entity.name.function.haskell
11 | ) where
12 |
13 | import Data.Sequence ( Seq() )
14 | -- ^^^^^ meta.import.haskell
15 | import Unison.Name
16 | -- <------------------ - invalid
--------------------------------------------------------------------------------
/test/tickets/T0020b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Fields in GADTs"
2 |
3 | data A where
4 | A :: { field1 :: Int, field2 :: Int } -> A
5 | -- ^^^^^^ ^^^^^^ meta.record.definition.haskell variable.other.member.definition.haskell
6 | -- ^^^^^^ ^^^^^^^ - variable.other.generic-type.haskell
7 | -- ^^^ ^^^ meta.record.definition.haskell storage.type.haskell
8 |
9 | data B where
10 | B
11 | :: { field3 :: Bool
12 | -- ^^^^^^ meta.record.definition.haskell variable.other.member.definition.haskell
13 | -- ^^^^^^^ - variable.other.generic-type.haskell
14 | , field4 :: Int
15 | -- ^^^^^^ meta.record.definition.haskell variable.other.member.definition.haskell
16 | -- ^^^^^^^ - variable.other.generic-type.haskell
17 | }
18 | -> B
--------------------------------------------------------------------------------
/test/tickets/T0112.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Case-insensitive deprecation pragmas"
2 |
3 | module Web.Telegram.API.Lens {-# dEPrecatED "use labels from generic-lens instead" #-}
4 | -- ^^^^^^^^^^ keyword.other.preprocessor.pragma.haskell
5 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.haskell
6 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
7 | where
8 |
9 | {-# dEPrecatED foo "use labels from generic-lens instead" #-}
10 | -- ^^^^^^^^^^ keyword.other.preprocessor.pragma.haskell
11 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.haskell
12 | -- <------------------------------------------------------------- meta.preprocessor.haskell
13 |
--------------------------------------------------------------------------------
/test/tickets/T0178.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Multiline type signature in brackets"
2 |
3 | proof :: SomeVeryLongExpression a b
4 | :~: SomeOtherLongExpression c d
5 | -- ^^^ storage.type.operator.infix.haskell
6 | -- ^^^^^^^^^^^^^^^^^^^^^^^ storage.type.haskell
7 | -- ^ ^ variable.other.generic-type.haskell
8 |
9 | quux ( proof :: SomeVeryLongExpression a b
10 | :~: SomeOtherLongExpression c d
11 | -- ^^^ storage.type.operator.infix.haskell
12 | -- ^^^^^^^^^^^^^^^^^^^^^^^ storage.type.haskell
13 | -- ^ ^ variable.other.generic-type.haskell
14 | )
15 |
16 | quux [ x :: a
17 | B c ]
18 | -- ^ storage.type.haskell
19 | -- ^ variable.other.generic-type.haskell
20 |
--------------------------------------------------------------------------------
/test/tests/Specialise.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Specialise pragma"
2 |
3 | {-# SPECIALISE INLINE [~2] foo :: B -> A #-}
4 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
5 | -- ^^^^^^^^^^ ^^^^^^ keyword.other.preprocessor.pragma.haskell
6 | -- ^^^^ meta.inlining-phase.haskell
7 | -- ^ ^ storage.type.haskell
8 |
9 |
10 | instance (Eq a) => Eq (Foo a) where {
11 | {-# SPECIALIZE [1] instance Eq (Foo [(Int, Bar)]) #-}
12 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
13 | -- ^^^^^^^^^^ keyword.other.preprocessor.pragma.haskell
14 | -- ^^^^^^^^ keyword.other.instance.haskell
15 | -- ^^ ^^^ ^^^ ^^^ storage.type.haskell
16 | }
--------------------------------------------------------------------------------
/test/tickets/T0090.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Fixity declarations"
2 |
3 | infixl 6 :+
4 | -- <------ keyword.other.fixity.infixl.haskell
5 | -- ^ constant.numeric.integral.decimal.haskell
6 | -- ^^ constant.other.operator.infix.haskell
7 | infixr 7 //
8 | -- ^ constant.numeric.integral.decimal.haskell
9 | -- <------ keyword.other.fixity.infixr.haskell
10 | -- ^^ keyword.operator.infix.haskell
11 | infix 2 `elem`
12 | -- ^^^^^ keyword.other.fixity.infix.haskell
13 | -- ^ constant.numeric.integral.decimal.haskell
14 | -- ^^^^^^ keyword.operator.function.infix.haskell
15 | infix 0 `Cons`
16 | -- ^^^^^ keyword.other.fixity.infix.haskell
17 | -- ^ constant.numeric.integral.decimal.haskell
18 | -- ^^^^^^ keyword.operator.function.infix.haskell
19 | -- ^^^^ constant.other.haskell
20 |
--------------------------------------------------------------------------------
/test/tests/NonRecord.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Braces not indicating record syntax"
2 |
3 | where {
4 | -- ^^^^^ keyword.other.where.haskell
5 | -- ^ punctuation.brace.haskell
6 | -- ^ - meta.record.haskell
7 | a = A
8 | -- ^^^^^ - meta.record.haskell
9 | -- ^ - variable.other.member.haskell
10 | ; b = B
11 | -- ^^^^^^^^ - meta.record.haskell
12 | -- ^ - variable.other.member.haskell
13 | }
14 | -- ^ punctuation.brace.haskell
15 | -- ^ - meta.record.haskell
16 |
17 |
18 | class C a where { meth :: a }
19 | -- ^ ^ punctuation.brace.haskell
20 | -- ^^^^^^^^^^^^^ - meta.record.haskell
21 | -- ^^^^ - variable.other.member.haskell
22 |
23 | data C :: A -> B -> Type where { C :: A a b }
24 | -- ^^^^^^^^^^^^^^ - meta.record.haskell
25 |
--------------------------------------------------------------------------------
/test/tests/ImportIndentation.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Indentation in imports"
2 |
3 | import
4 | -- ^^^^^^ keyword.other.import.haskell
5 | qualified
6 | -- ^^^^^^^^^ keyword.other.qualified.haskell
7 |
8 |
9 | I
10 | -- ^ entity.name.namespace.haskell
11 |
12 | as
13 | -- ^^ keyword.other.as.haskell
14 |
15 | J
16 | -- ^ entity.name.namespace.haskell
17 | hiding
18 | -- ^^^^^^ keyword.other.hiding.haskell
19 | (
20 | f, A
21 | -- ^ entity.name.function.haskell
22 | -- ^ storage.type.haskell
23 | , B, g, (:<),
24 | -- ^ storage.type.haskell
25 | -- ^ entity.name.function.haskell
26 | -- ^^ storage.type.operator.haskell
27 | (>>>)
28 | -- ^^^ entity.name.function.infix.haskell
29 | )
30 |
--------------------------------------------------------------------------------
/test/tests/Language.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Language pragmas"
2 |
3 | {-# LANGUAGE DataKinds, PolyKinds, TypeFamilyDependencies #-}
4 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
5 | -- ^^^^^^^^ keyword.other.preprocessor.pragma.haskell
6 | -- ^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ keyword.other.preprocessor.extension.haskell
7 | {-# LANGUAGE NoMonomorphismRestriction #-}
8 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
9 | -- ^^^^^^^^ keyword.other.preprocessor.pragma.haskell
10 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^ keyword.other.preprocessor.extension.haskell
11 |
12 | {-# LANGUAGE NullaryTypeClasses #-}
13 | -- ^^^^^^^^^^^^^^^^^^ invalid.deprecated
14 |
15 | {-# LANGUAGE NotAKnownExtension #-}
16 | -- ^^^^^^^^^^^^^^^^^^ - keyword.other.preprocessor.extension.haskell
17 |
--------------------------------------------------------------------------------
/test/tickets/T0020.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Fields in complex ADTs"
2 |
3 |
4 | data T2
5 | = Constr1 Int
6 | | Record2 {
7 | field1 :: Int,
8 | -- ^^^^^^ meta.record.definition.haskell variable.other.member.definition.haskell
9 | -- ^^^ meta.record.definition.haskell storage.type.haskell
10 | field2 :: Int
11 | -- ^^^^^^ meta.record.definition.haskell variable.other.member.definition.haskell
12 | -- ^^^ meta.record.definition.haskell storage.type.haskell
13 | }
14 |
15 |
16 | data T3 = T3
17 | { f1 :: Int
18 | -- ^^ meta.record.definition.haskell variable.other.member.definition.haskell
19 | -- ^^^ meta.record.definition.haskell storage.type.haskell
20 | , f2 :: Int
21 | -- ^^ meta.record.definition.haskell variable.other.member.definition.haskell
22 | -- ^^^ meta.record.definition.haskell storage.type.haskell
23 | }
24 |
--------------------------------------------------------------------------------
/syntaxes/codeblock-cabal.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": [],
3 | "injectionSelector": "L:markup.fenced_code.block.markdown",
4 | "patterns": [
5 | {
6 | "include": "#cabal-code-block"
7 | }
8 | ],
9 | "repository": {
10 | "cabal-code-block": {
11 | "begin": "\\b(cabal)\\b(\\s+[^`~]*)?$",
12 | "end": "(^|\\G)(?=\\s*[`~]{3,}\\s*$)",
13 | "patterns": [
14 | {
15 | "begin": "(^|\\G)(\\s*)(.*)",
16 | "while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)",
17 | "contentName": "meta.embedded.block.cabal",
18 | "patterns": [
19 | {
20 | "include": "source.cabal"
21 | }
22 | ]
23 | }
24 | ]
25 | }
26 | },
27 | "scopeName": "markdown.cabal.codeblock"
28 | }
29 |
--------------------------------------------------------------------------------
/test/tickets/T0066.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Empty typeclass and empty instances"
2 |
3 | class A x where
4 | -- <----- keyword.other.class.haskell
5 | -- <---------- meta.declaration.class.haskell
6 | class B x
7 | -- <----- keyword.other.class.haskell
8 | -- <--------- meta.declaration.class.haskell
9 |
10 | normal :: Int
11 | -- <------ meta.function.type-declaration.haskell entity.name.function.haskell
12 | -- <------------- - invalid
13 |
14 | class C x => Dx
15 | -- <----- keyword.other.class.haskell
16 | -- <--------------- meta.declaration.class.haskell
17 |
18 | instance A x where
19 | -- <-------- keyword.other.instance.haskell
20 | -- <------------- meta.declaration.instance.haskell
21 | instance B x
22 | -- <-------- keyword.other.instance.haskell
23 | -- <------------ meta.declaration.instance.haskell
24 | instance C x => D x
25 | -- <-------- keyword.other.instance.haskell
26 | -- <------------------- meta.declaration.instance.haskell
--------------------------------------------------------------------------------
/syntaxes/codeblock-haskell.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": [],
3 | "injectionSelector": "L:markup.fenced_code.block.markdown",
4 | "patterns": [
5 | {
6 | "include": "#haskell-code-block"
7 | }
8 | ],
9 | "repository": {
10 | "haskell-code-block": {
11 | "begin": "\\b(haskell|hs)\\b(\\s+[^`~]*)?$",
12 | "end": "(^|\\G)(?=\\s*[`~]{3,}\\s*$)",
13 | "patterns": [
14 | {
15 | "begin": "(^|\\G)(\\s*)(.*)",
16 | "while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)",
17 | "contentName": "meta.embedded.block.haskell",
18 | "patterns": [
19 | {
20 | "include": "source.haskell"
21 | }
22 | ]
23 | }
24 | ]
25 | }
26 | },
27 | "scopeName": "markdown.haskell.codeblock"
28 | }
29 |
--------------------------------------------------------------------------------
/test/tests/Fixity.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Fixity declarations"
2 |
3 |
4 | infixl 3 :+
5 | -- ^^^^^^ keyword.other.fixity.infixl.haskell
6 | -- ^ constant.numeric.integral.decimal.haskell
7 | -- ^^ constant.other.operator.infix.haskell
8 |
9 | infixr 7 ---:
10 | -- ^^^^^^ keyword.other.fixity.infixr.haskell
11 | -- ^ constant.numeric.integral.decimal.haskell
12 | -- ^^^^ keyword.operator.infix.haskell
13 |
14 | infix 1 `Cons`
15 | -- ^^^^^ keyword.other.fixity.infix.haskell
16 | -- ^ constant.numeric.integral.decimal.haskell
17 | -- ^^^^ constant.other.haskell
18 | -- ^^^^^^ keyword.operator.function.infix.haskell
19 |
20 | infix 2 <|> -- comment
21 | -- ^^^^^ keyword.other.fixity.infix.haskell
22 | -- ^ constant.numeric.integral.decimal.haskell
23 | -- ^^^ keyword.operator.infix.haskell
24 | -- ^^^^^^^^^^ comment.line.double-dash.haskell
25 |
--------------------------------------------------------------------------------
/test/tests/CommentLike.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Test ending of comment-like blocks"
2 |
3 | {- a b -} a b
4 | -- ^^^^^^^^^ comment.block.haskell
5 | -- ^ ^ - comment.block.haskell
6 |
7 | {-$ a b -} a b
8 | -- ^^^^^^^^^^ comment.block.documentation.haskell
9 | -- ^ ^ - comment.block.documentation.haskell
10 |
11 | {-# SPECIALISE foo :: a -> b #-} c d
12 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
13 | -- ^ ^ - meta.preprocessor.haskell
14 |
15 | {-@ foo :: A -> B @-} c d
16 | -- ^^^^^^^^^^^^^^^^^^^^^ block.liquidhaskell.haskell
17 | -- ^ ^ storage.type.haskell
18 | -- ^ ^ - block.liquidhaskell.haskell
19 |
20 | {-@ type NonEmpty a = {v:[a] | 0 < len v } @-} c d
21 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ block.liquidhaskell.haskell
22 | -- ^ ^ - block.liquidhaskell.haskell
23 |
--------------------------------------------------------------------------------
/test/tests/Prefix.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Reserved prefix operators"
2 |
3 |
4 | data A = A !A | B !B
5 | -- ^ ^ keyword.operator.prefix.bang.haskell
6 |
7 | f ~(x,y) = _
8 | -- ^ keyword.operator.prefix.tilde.haskell
9 | f !(!x,~P(z)) = _
10 | -- ^ ^ keyword.operator.prefix.bang.haskell
11 | -- ^ keyword.operator.prefix.tilde.haskell
12 |
13 | f (a,b)!g
14 | -- ^ - keyword.operator.prefix.bang.haskell
15 |
16 | vec ! 3
17 | -- ^ - keyword.operator.prefix.bang.haskell
18 | vec Vector.! 3
19 | -- ^ - keyword.operator.prefix.bang.haskell
20 | a ~ b
21 | -- ^ - keyword.operator.prefix.tilde.haskell
22 |
23 | -1
24 | -- ^ keyword.operator.prefix.minus.haskell
25 | 1 - 2
26 | -- ^ - keyword.operator.prefix.minus.haskell
27 | -- ^ keyword.operator.infix.haskell
28 | a -+ b
29 | -- ^ - keyword.operator.prefix.minus.haskell
30 | a -#b
31 | -- ^ - keyword.operator.prefix.minus.haskell
32 |
--------------------------------------------------------------------------------
/syntaxes/codeblock-literate-haskell.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": [],
3 | "injectionSelector": "L:markup.fenced_code.block.markdown",
4 | "patterns": [
5 | {
6 | "include": "#lhaskell-code-block"
7 | }
8 | ],
9 | "repository": {
10 | "lhaskell-code-block": {
11 | "begin": "\\b(literate-haskell|lhaskell|lhs)\\b(\\s+[^`~]*)?$",
12 | "end": "(^|\\G)(?=\\s*[`~]{3,}\\s*$)",
13 | "patterns": [
14 | {
15 | "begin": "(^|\\G)(\\s*)(.*)",
16 | "while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)",
17 | "contentName": "meta.embedded.block.lhaskell",
18 | "patterns": [
19 | {
20 | "include": "text.tex.latex.haskell"
21 | }
22 | ]
23 | }
24 | ]
25 | }
26 | },
27 | "scopeName": "markdown.lhaskell.codeblock"
28 | }
29 |
--------------------------------------------------------------------------------
/test/tickets/T0190.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Type variables in foreign import/export"
2 |
3 | foreign import ccall unsafe "memcmp"
4 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.foreign.haskell
5 | memcmp :: Ptr a -> Ptr (b :: ty) -> CSize -> IO CInt
6 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.foreign.haskell
7 | -- ^^^^^^ entity.name.function.haskell
8 | -- ^^ ^^ keyword.operator.double-colon.haskell
9 | -- ^ ^ ^^ - entity.name.function.haskell
10 | -- ^ ^ ^^ variable.other.generic-type.haskell
11 | -- ^^ ^^ ^^ keyword.operator.arrow.haskell
12 | -- ^^^ ^^^ ^^^^^ ^^ ^^^^ storage.type.haskell
13 |
14 | data A a = Mk A a
15 | -- ^^^^ keyword.other.data.haskell
16 | -- ^ ^ storage.type.haskell
17 | -- ^ ^ variable.other.generic-type.haskell
18 | -- ^^ constant.other.haskell
19 |
--------------------------------------------------------------------------------
/test/tickets/T0072a.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Pattern synonyms"
2 |
3 | module Main
4 | ( pattern P ) where
5 | -- ^^^^^^^ meta.declaration.exports.haskell keyword.other.pattern.haskell
6 | -- ^ constant.other.haskell
7 |
8 | import M ( pattern Q )
9 | -- ^^^^^^^ meta.declaration.exports.haskell keyword.other.pattern.haskell
10 | -- ^ constant.other.haskell
11 |
12 |
13 | pattern A :: T
14 | -- <------- keyword.other.pattern.haskell
15 | -- ^ constant.other.haskell
16 | -- ^ storage.type.haskell
17 | pattern (A b) = C
18 | -- <------- keyword.other.pattern.haskell
19 | -- ^ ^ constant.other.haskell
20 |
21 | pattern B :: A -> B
22 | -- <------- keyword.other.pattern.haskell
23 | -- ^ constant.other.haskell
24 | -- ^ ^ storage.type.haskell
25 | -> C
26 | -- ^ storage.type.haskell
27 |
28 | pattern A, B :: T
29 | -- <------- keyword.other.pattern.haskell
30 | -- ^ ^ constant.other.haskell
31 | -- ^ storage.type.haskell
32 |
--------------------------------------------------------------------------------
/test/tickets/T0089.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Standalone deriving statements"
2 |
3 | deriving instance SomeClass => Eq a
4 | -- ^^^^^^^^ keyword.other.deriving.haskell
5 | -- ^^^^^^^^ keyword.other.instance.haskell
6 | -- ^^^^^^^^^ storage.type.haskell
7 | deriving instance Ord a => Ord (Expr a)
8 | -- ^^^^^^^^ keyword.other.deriving.haskell
9 | -- ^^^^^^^^ keyword.other.instance.haskell
10 | -- ^^^^ storage.type.haskell
11 |
12 | normal :: Int
13 | -- ^^^^^^ entity.name.function.haskell
14 | -- ^^^^^^^^^^^^^^ meta.function.type-declaration.haskell
15 |
16 | deriving instance SomeClass => Eq a
17 | -- <-------- keyword.other.deriving.haskell
18 | -- ^^^^^^^^ keyword.other.instance.haskell
19 | -- ^^^^^^^^^ storage.type.haskell
20 | deriving instance Ord a => Ord (Expr a)
21 | -- <-------- keyword.other.deriving.haskell
22 | -- ^^^^^^^^ keyword.other.instance.haskell
23 | -- ^^^^ storage.type.haskell
24 |
--------------------------------------------------------------------------------
/test/tickets/T0038.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Record field names"
2 |
3 | data Data = Data { foo :: Int, bar :: Int }
4 | -- ^^^ meta.record.definition.haskell variable.other.member.definition.haskell
5 | -- ^^^ meta.record.definition.haskell variable.other.member.definition.haskell
6 | data Data = Data {
7 | foo :: Int, bar :: Int
8 | -- ^^^ meta.record.definition.haskell variable.other.member.definition.haskell
9 | -- ^^^ meta.record.definition.haskell variable.other.member.definition.haskell
10 | }
11 | data Data = Data {
12 | foo :: Int,
13 | -- ^^^ meta.record.definition.haskell variable.other.member.definition.haskell
14 | bar :: Int
15 | -- ^^^ meta.record.definition.haskell variable.other.member.definition.haskell
16 | }
17 | data Data = Data {
18 | foo :: Int
19 | -- ^^^ meta.record.definition.haskell variable.other.member.definition.haskell
20 | , bar :: Int
21 | -- ^^^ meta.record.definition.haskell variable.other.member.definition.haskell
22 | }
23 |
--------------------------------------------------------------------------------
/test/tickets/T0073.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Visible type application"
2 |
3 | function =
4 | let l = [] @[( Int, f [ Bool ] )] in
5 | -- ^ meta.type-application.haskell
6 | -- ^^^ storage.type.haskell
7 | -- ^ variable.other.generic-type.haskell
8 | let x = "Hello" @String in
9 | -- ^ meta.type-application.haskell
10 | -- ^^^^^^ storage.type.haskell
11 | let c@(Some pattern) = undefined in
12 | -- ^ - meta.type-application.haskell
13 | -- ^^^^ constant.other.haskell
14 | let g = f @( g ([]) -> String ) in
15 | -- ^ meta.type-application.haskell
16 | -- ^ variable.other.generic-type.haskell
17 | let h = k @_ @a @Int
18 | -- ^ ^ ^ meta.type-application.haskell
19 | let a = b @ c
20 | -- ^ - meta.type-application.haskell
21 | undefined
22 |
23 | g = f @Bool(A)
24 | -- ^ meta.type-application.haskell
25 | -- ^^^^ storage.type.haskell
26 | -- ^ - storage.type.haskell
27 |
--------------------------------------------------------------------------------
/test/tests/EndTypeSig.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Type annotation should end with closing brackets"
2 |
3 |
4 | ( x
5 | :: a b c ) d e f
6 | -- ^ ^ ^ variable.other.generic-type.haskell
7 | -- ^ ^ ^ - variable.other.generic-type.haskell
8 |
9 | (# x
10 | :: a b c #) d e f
11 | -- ^ ^ ^ variable.other.generic-type.haskell
12 | -- ^ ^ ^ - variable.other.generic-type.haskell
13 |
14 | [ x
15 | :: a b c ] d e f
16 | -- ^ ^ ^ variable.other.generic-type.haskell
17 | -- ^ ^ ^ - variable.other.generic-type.haskell
18 |
19 | ( x :: a b c ) d e f
20 | -- ^ ^ ^ variable.other.generic-type.haskell
21 | -- ^ ^ ^ - variable.other.generic-type.haskell
22 |
23 | (# x :: a b c #) d e f
24 | -- ^ ^ ^ variable.other.generic-type.haskell
25 | -- ^ ^ ^ - variable.other.generic-type.haskell
26 |
27 | [ x :: a b c ] d e f
28 | -- ^ ^ ^ variable.other.generic-type.haskell
29 | -- ^ ^ ^ - variable.other.generic-type.haskell
--------------------------------------------------------------------------------
/syntax-examples/embedding.md:
--------------------------------------------------------------------------------
1 | # Test file to see if Haskell is embedded in markdown
2 |
3 |
4 | ```hs
5 | class MyClass a where
6 | aMethod :: a -> String
7 |
8 | main :: IO ()
9 | main = putStrLn "Hello World"
10 | ```
11 |
12 | ```haskell
13 | class MyClass a where
14 | aMethod :: a -> String
15 |
16 | main :: IO ()
17 | main = putStrLn "Hello World"
18 | ```
19 |
20 |
21 | ```lhs
22 | \begin{document}
23 | The surrounding stuff should be comments or perhaps even \LaTeX
24 | > class MyClass a where
25 | > aMethod :: a -> String
26 |
27 | > main :: IO ()
28 | > main = putStrLn "Hello World"
29 | \end{document}
30 | ```
31 |
32 | ```literate-haskell
33 | \begin{document}
34 | The surrounding stuff should be comments or perhaps even \LaTeX
35 | > class MyClass a where
36 | > aMethod :: a -> String
37 |
38 | > main :: IO ()
39 | > main = putStrLn "Hello World"
40 | \end{document}
41 | ```
42 |
43 | ```cabal
44 | name: test
45 | version: 0.5.6.7
46 | library
47 | build-depends:
48 | base == 5.0 || >= 3.0
49 | , mtl
50 | default-extensions:
51 | OverloadedStrings
52 | ```
53 |
--------------------------------------------------------------------------------
/syntaxes/literateHaskell.YAML-tmLanguage:
--------------------------------------------------------------------------------
1 | fileTypes:
2 | - lhs
3 | keyEquivalent: ^~H
4 | name: 'Literate Haskell'
5 | patterns:
6 | - begin: '^\s*((\\)begin)({)code(})(\s*\n)?'
7 | captures:
8 | '1': {name: support.function.be.latex}
9 | '2': {name: punctuation.definition.function.latex}
10 | '3': {name: punctuation.definition.arguments.begin.latex}
11 | '4': {name: punctuation.definition.arguments.end.latex}
12 | contentName: source.haskell.embedded.latex
13 | end: '^((\\)end)({)code(})'
14 | name: meta.embedded.block.haskell.latex
15 | patterns:
16 | - {include: source.haskell}
17 | - begin: '^(> )'
18 | beginCaptures:
19 | '1': {name: punctuation.definition.bird-track.haskell}
20 | comment: 'This breaks type signature detection for now, but it''s better than having no highlighting whatsoever.'
21 | contentName: source.haskell
22 | end: $
23 | name: meta.embedded.haskell
24 | patterns:
25 | - {include: source.haskell}
26 | - include: text.tex.latex
27 | scopeName: text.tex.latex.haskell
28 | uuid: 439807F5-7129-487D-B5DC-95D5272B43DD
29 |
--------------------------------------------------------------------------------
/test/tickets/T0146.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Highlighting in multiline type declarations"
2 |
3 |
4 | type GetDecks =
5 | -- <~~---- keyword.other.type.haskell
6 | -- ^^^^^^^^ storage.type.haskell
7 | -- ^ keyword.operator.eq.haskell
8 | MethodCall "getDecks" Cards
9 | -- ^^^^^^^^^^ ^^^^^ storage.type.haskell
10 |
11 | type GetDecks
12 | -- <~~---- keyword.other.type.haskell
13 | -- ^^^^^^^^ storage.type.haskell
14 | = MethodCall "getDecks" Cards
15 | -- ^ keyword.operator.eq.haskell
16 | -- ^^^^^^^^^^ ^^^^^ storage.type.haskell
17 |
18 |
19 | type GetDecks =
20 | -- <---- keyword.other.type.haskell
21 | -- ^^^^^^^^ storage.type.haskell
22 | -- ^ keyword.operator.eq.haskell
23 | MethodCall "getDecks" Cards
24 | -- <~~--------- storage.type.haskell
25 | -- ^^^^^ storage.type.haskell
26 |
27 | type GetDecks
28 | -- <---- keyword.other.type.haskell
29 | -- ^^^^^^^^ storage.type.haskell
30 | = MethodCall "getDecks" Cards
31 | -- <~~- keyword.operator.eq.haskell
32 | -- ^^^^^^^^^^ ^^^^^ storage.type.haskell
33 |
--------------------------------------------------------------------------------
/test/tests/Kinds.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Kind signatures"
2 |
3 | data D (a :: Kind) (b :: k -> [Type]) = D
4 | -- ^ ^ ^ variable.other.generic-type.haskell
5 | -- ^^^^ ^^^^ storage.type.haskell
6 | -- ^^ ^^ keyword.operator.double-colon.haskell
7 | data D (a :: Kind) (b :: k -> [Type]) where
8 | -- ^ ^ ^ variable.other.generic-type.haskell
9 | -- ^^^^ ^^^^ storage.type.haskell
10 | -- ^^ ^^ keyword.operator.double-colon.haskell
11 |
12 | data D :: k -> [Type] where
13 | -- ^^ keyword.operator.double-colon.haskell
14 | -- ^ variable.other.generic-type.haskell
15 | -- ^^^^ storage.type.haskell
16 |
17 |
18 | colons :: forall (a :: (k :: l)). a -> (x :: a) -> k
19 | -- ^ ^ ^ ^ ^ ^ ^ variable.other.generic-type.haskell
20 | -- ^^ ^^ ^^ keyword.operator.double-colon.haskell
21 | data X ( a :: ( x :: k ) ) :: k
22 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
23 | -- ^^ ^^ ^^ keyword.operator.double-colon.haskell
--------------------------------------------------------------------------------
/test/tickets/T0102.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "GADT constructors"
2 |
3 | data GADT a where
4 | Constr :: A -> B -> GADT a
5 | -- ^^^^^^ constant.other.haskell
6 | -- ^ ^ ^^^^ storage.type.haskell
7 |
8 | data D a where D :: Int -> D String
9 | -- ^ constant.other.haskell
10 | -- ^^^ ^ ^^^^^^ storage.type.haskell
11 |
12 | data Expr a where
13 | I :: Int -> Expr Int
14 | -- ^ constant.other.haskell
15 | -- ^^^ storage.type.haskell
16 | B :: Bool -> Expr Bool
17 | -- ^ constant.other.haskell
18 | -- ^^^^ storage.type.haskell
19 | Add :: Expr Int
20 | -- ^^^ constant.other.haskell
21 | -- ^^^^ storage.type.haskell
22 | -> Expr Int -> Expr Int
23 | -- ^^^^ storage.type.haskell
24 | Mul :: Expr Int
25 | -- ^^^ constant.other.haskell
26 | -- ^^^^ storage.type.haskell
27 | -> Expr Int -> Expr Int
28 | -- ^^^^ storage.type.haskell
29 | Eq
30 | -- ^^ constant.other.haskell
31 | :: Eq a =>
32 | -- ^^ storage.type.haskell
33 | Expr a -> Expr a -> Expr Bool
34 | -- ^^^^ storage.type.haskell
35 |
--------------------------------------------------------------------------------
/syntax-examples/backpack.hsig:
--------------------------------------------------------------------------------
1 | signature Token
2 | ( Token
3 | , Pair
4 | , LayoutMode
5 | , nested
6 | , mismatch
7 | , unmatchedOpening
8 | , unmatchedClosing
9 | , lexicalError
10 | ) where
11 |
12 | import Data.Default
13 | import Data.Ix
14 | import GHC.Generics
15 |
16 | import Relative.Cat
17 | import Relative.Class
18 | import Relative.Delta
19 | import Relative.Located
20 |
21 | data Token
22 | instance Eq Token
23 | instance Ord Token
24 | instance Show Token
25 | instance Read Token
26 | instance Relative Token
27 |
28 | data Pair
29 | instance Eq Pair
30 | instance Ord Pair
31 | instance Show Pair
32 | instance Read Pair
33 | instance Ix Pair
34 | instance Enum Pair
35 | instance Bounded Pair
36 | instance Generic Pair
37 |
38 | data LayoutMode
39 | instance Eq LayoutMode
40 | instance Ord LayoutMode
41 | instance Show LayoutMode
42 | instance Read LayoutMode
43 | instance Default LayoutMode
44 |
45 | nested :: Located Pair -> Cat Token -> Token
46 | mismatch :: Located Pair -> Located Pair -> Cat Token -> Token
47 | unmatchedOpening :: Located Pair -> Token
48 | unmatchedClosing :: Located Pair -> Token
49 | lexicalError :: Delta -> String -> Token
50 |
--------------------------------------------------------------------------------
/test/tickets/T0030.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Qualified infix functions"
2 |
3 | f = item `elem` list
4 | -- ^^^^ keyword.operator.function.infix.haskell
5 | g = item `Qual.member` set
6 | -- ^^^^^^^^^^^ keyword.operator.function.infix.haskell
7 | -- ^^^^^ entity.name.namespace.haskell
8 | -- ^^^^^^ - entity.name.namespace.haskell
9 | g = item `Qual.Fun.member` set
10 | -- ^^^^^^^^^^^^^^^ keyword.operator.function.infix.haskell
11 | -- ^^^^^ entity.name.namespace.haskell
12 | -- ^^^^^^ - entity.name.namespace.haskell
13 |
14 | h =
15 | a `C.A.Constr` b
16 | -- ^^^^^^^^^^^^ keyword.operator.function.infix.haskell
17 | -- ^^^^ entity.name.namespace.haskell
18 | -- ^^^^^^ - entity.name.namespace.haskell
19 | a `C.A.f` b
20 | -- ^^^^^^^ keyword.operator.function.infix.haskell
21 | -- ^^^^ entity.name.namespace.haskell
22 |
23 | a C.A.+ b
24 | ----- ^^^^ entity.name.namespace.haskell
25 | (C.A.*) b c
26 | -- ^^^^ entity.name.namespace.haskell
27 |
28 | a C.A.:& b
29 | -- ^^^^ entity.name.namespace.haskell
30 | (C.A.:+:) b c
31 | -- ^^^^ entity.name.namespace.haskell
32 |
--------------------------------------------------------------------------------
/test/wontfix/MultilineGADT.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Multiline GADT declaration"
2 |
3 | data G (a :: A) b (c :: C) :: Type
4 | -- ^^^^ keyword.other.data.haskell
5 | -- ^ ^ variable.other.generic-type.haskell
6 | -- ^^ ^^ ^^ keyword.operator.double-colon.haskell
7 | -- ^ ^ ^ ^^^^ storage.type.haskell
8 | where
9 | -- ^^^^^^ keyword.other.where.haskell
10 | A :: G a b c
11 | -- ^ constant.other.haskell
12 | -- ^^ keyword.operator.double-colon.haskell
13 | -- ^ storage.type.haskell
14 | -- ^ ^ ^ variable.other.generic-type.haskell
15 | (:&) :: G A B c
16 | -- ^^ constant.other.operator.haskell
17 | -- ^^ keyword.operator.double-colon.haskell
18 | -- ^ ^ ^ storage.type.haskell
19 | -- ^ variable.other.generic-type.haskell
20 | (:!!!!!!!!!!!!!!!!!!!!!!!!)
21 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.operator.haskell
22 | :: a -> b -> G a b c
23 | -- ^^ keyword.operator.double-colon.haskell
24 | -- ^ storage.type.haskell
25 | -- ^ ^ ^ ^ ^ variable.other.generic-type.haskell
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const webpack = require('webpack');
3 |
4 | const webExtensionConfig = {
5 | mode: 'none',
6 | target: 'webworker',
7 | entry: {
8 | extension: './src/extension.ts'
9 | },
10 | output: {
11 | filename: '[name].js',
12 | path: path.join(__dirname, './dist/web'),
13 | libraryTarget: 'commonjs',
14 | devtoolModuleFilenameTemplate: '../../[resource-path]'
15 | },
16 | resolve: {
17 | mainFields: ['browser', 'module', 'main'],
18 | extensions: ['.ts', '.js'],
19 | fallback: {
20 | assert: require.resolve('assert')
21 | }
22 | },
23 | module: {
24 | rules: [
25 | {
26 | test: /\.ts$/,
27 | exclude: /node_modules/,
28 | use: [
29 | {
30 | loader: 'ts-loader'
31 | }
32 | ]
33 | }
34 | ]
35 | },
36 | plugins: [
37 | new webpack.ProvidePlugin({
38 | process: 'process/browser'
39 | })
40 | ],
41 | externals: {
42 | vscode: 'commonjs vscode'
43 | },
44 | performance: {
45 | hints: false
46 | },
47 | devtool: 'nosources-source-map'
48 | };
49 | module.exports = [webExtensionConfig];
--------------------------------------------------------------------------------
/test/tests/Keywords.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Reserved keywords"
2 |
3 | anotherFunc :: MyData -> Int
4 | -- ^^ keyword.operator.double-colon.haskell
5 | -- ^^ keyword.operator.arrow.haskell
6 | anotherFunc arg =
7 | let something = "hello" :: String
8 | -- ^ keyword.operator.eq.haskell
9 | -- ^^ keyword.operator.double-colon.haskell
10 | -- ^^^ keyword.other.let.haskell
11 | in case a :: B of
12 | -- ^^ keyword.other.in.haskell
13 | -- ^^^^ keyword.control.case.haskell
14 | -- ^^ keyword.operator.double-colon.haskell
15 | -- ^^ keyword.control.of.haskell
16 |
17 | Just _ -> do
18 | -- ^^ keyword.operator.arrow.haskell
19 | -- ^^ keyword.control.do.haskell
20 | if a
21 | -- ^^ keyword.control.if.haskell
22 | then b
23 | -- ^^^^ keyword.control.then.haskell
24 | else \cases
25 | -- ^^^^ keyword.control.else.haskell
26 | -- ^^^^^ keyword.control.cases.haskell
27 | arg1 arg2 -> undefined
28 |
29 | where
30 | -- <~~----- keyword.other.where.haskell
31 | expression argument = arg + 7
32 |
--------------------------------------------------------------------------------
/test/tickets/T0071.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Ticks in type constructors"
2 |
3 | data A = ABC (X,X) | ABC'' (X, X)
4 | -- ^^^^^ constant.other.haskell
5 | -- ^^ - string.quoted.single.haskell
6 | pattern ABC' = ABC''
7 | -- ^^^^ ^^^^^ constant.other.haskell
8 | -- ^^^^^^^^^ - string.quoted.single.haskell
9 |
10 | data X = XY'' [X] | XY'''
11 | -- ^^^^ ^^^^^ constant.other.haskell
12 | -- ^^^^^^^^^^^^^^ - string.quoted.single.haskell
13 |
14 | type X'' = 'XY''
15 | -- ^^^ ^^^^ storage.type.haskell
16 | -- ^^^^^^^^^^ - string.quoted.single.haskell
17 |
18 | f'' :: proxy ( 'ABC '( 'XY''','XY'' '[ 'XY''','XY''']) ':-> a )
19 | -- <--- entity.name.function.haskell
20 | -- ^^^ ^^^^^ ^^^^ ^^^^^ ^^^^^ storage.type.haskell
21 | -- <-------------------------------------------------------------- - string.quoted.single.haskell
22 |
23 | g'' :: A
24 | -- <--- entity.name.function.haskell
25 | -- <--- - string.quoted.single.haskell
26 | g'' = ABC''' XY'''
27 | -- ^^^^^^ ^^^^^ constant.other.haskell
28 | -- <------------------- - string.quoted.single.haskell
29 |
30 | type Ticked' '(a,b) = '(a,b)
31 | -- ^^^^^^^ storage.type.haskell
32 | -- ^^^ - string.quoted.single.haskell
33 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "extensionHost",
9 | "request": "launch",
10 | "name": "Launch Extension",
11 | "runtimeExecutable": "${execPath}",
12 | "args": [
13 | "--extensionDevelopmentPath=${workspaceFolder}"
14 | ],
15 | "outFiles": [
16 | "${workspaceFolder}/out/**/*.js"
17 | ],
18 | "preLaunchTask": "compile-all"
19 | },
20 | {
21 | "name": "Run Web Extension in VS Code",
22 | "type": "extensionHost",
23 | "debugWebWorkerHost": true,
24 | "request": "launch",
25 | "args": [
26 | "--extensionDevelopmentPath=${workspaceFolder}",
27 | "--extensionDevelopmentKind=web"
28 | ],
29 | "outFiles": [
30 | "${workspaceFolder}/dist/web/**/*.js"
31 | ],
32 | "preLaunchTask": "npm: watch-web"
33 | }
34 | ]
35 | }
--------------------------------------------------------------------------------
/test/tests/QualifiedFields.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Qualified record fields"
2 |
3 | parserPrefs = OptParse.ParserPrefs
4 | { OptParse.prefMultiSuffix = ""
5 | -- ^^^^^^^^^ entity.name.namespace.haskell
6 | -- ^^^^^^^^^^^^^^^ variable.other.member.haskell
7 | , OptParse.prefDisambiguate = True
8 | -- ^^^^^^^^^ entity.name.namespace.haskell
9 | -- ^^^^^^^^^^^^^^^^ variable.other.member.haskell
10 | , OptParse.prefShowHelpOnError = True
11 | -- ^^^^^^^^^ entity.name.namespace.haskell
12 | -- ^^^^^^^^^^^^^^^^^^^ variable.other.member.haskell
13 | , OptParse.prefShowHelpOnEmpty = False
14 | -- ^^^^^^^^^ entity.name.namespace.haskell
15 | -- ^^^^^^^^^^^^^^^^^^^ variable.other.member.haskell
16 | , OptParse.prefBacktrack = OptParse.Backtrack
17 | -- ^^^^^^^^^ entity.name.namespace.haskell
18 | -- ^^^^^^^^^^^^^ variable.other.member.haskell
19 | , OptParse.prefColumns = 80
20 | -- ^^^^^^^^^ entity.name.namespace.haskell
21 | -- ^^^^^^^^^^^ variable.other.member.haskell
22 | , OptParse.prefHelpLongEquals = False
23 | -- ^^^^^^^^^ entity.name.namespace.haskell
24 | -- ^^^^^^^^^^^^^^^^^^ variable.other.member.haskell
25 | }
--------------------------------------------------------------------------------
/test/tickets/T0116.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Nested comments"
2 |
3 | -- comment
4 | -- ^^^^^^^^^^ comment.line.double-dash.haskell
5 |
6 | -- comment -- comment
7 | -- ^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell
8 |
9 | {- comments
10 | -- ^^^^^^^^^^^ comment.block.haskell
11 |
12 | {- nested comment -}
13 | -- ^^^^^^^^^^^^^^^^^^^^ comment.block.haskell
14 |
15 | more comment
16 | -- ^^^^^^^^^^^^^ comment.block.haskell
17 |
18 | -- comment
19 | -- ^^^^^^^^^^ comment.block.haskell
20 |
21 | -}
22 |
23 | notAComment :: Int
24 | -- ^^^^^^^^^^^^^^^^^^ - comment.line.double-dash.haskell comment.block.haskell
25 |
26 | -- comment {- comment -}
27 | -- ^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell
28 |
29 |
30 | {- comment
31 | -- ^^^^^^^^^^ comment.block.haskell
32 |
33 | {-# PRAGMA #-}
34 | -- ^^^^^^^^^^^^^^ comment.block.haskell
35 |
36 | {-|
37 | commented
38 | -- ^^^^^^^^^ comment.block.haskell
39 | out
40 | docs -}
41 | -- ^^^^^^^ comment.block.haskell
42 |
43 | {-@ liquid haskell @-}
44 | -- ^^^^^^^^^^^^^^^^^^^^^^ comment.block.haskell
45 |
46 | -}
47 | -- <-- comment.block.haskell
48 |
49 | foo :: Bar
50 | -- ^^^^^^^^^^ - comment.line.double-dash.haskell comment.block.haskell
--------------------------------------------------------------------------------
/test/tests/LinearTypes.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "LinearTypes"
2 |
3 | {-# LANGUAGE LinearTypes #-}
4 | -- ^^^^^^^^^^^ keyword.other.preprocessor.extension.haskell
5 |
6 | construct :: a %1 -> T1 a
7 | -- ^ keyword.operator.prefix.modifier.haskell
8 | construct x = MkT1 x
9 |
10 | deconstruct :: T1 a %1 -> a
11 | -- ^ keyword.operator.prefix.modifier.haskell
12 | deconstruct (MkT1 x) = x
13 |
14 | data T2 a b c where
15 | MkT2 :: a -> b %1 -> c %1 -> T2 a b c
16 | -- ^ ^ keyword.operator.prefix.modifier.haskell
17 |
18 | data T3 a m where
19 | MkT3 :: a %m -> T3 a m
20 | -- ^ keyword.operator.prefix.modifier.haskell
21 |
22 |
23 | f2 :: Int %Many -> Bool
24 | -- ^ keyword.operator.prefix.modifier.haskell
25 | f3 :: Int %m -> Bool
26 | -- ^ keyword.operator.prefix.modifier.haskell
27 | f4 :: Int %(m :: Multiplicity) -> Bool
28 | -- ^ keyword.operator.prefix.modifier.haskell
29 |
30 | map :: forall (m :: Multiplicity). (a %m -> b) -> [a] %m -> [b]
31 | -- ^ ^ keyword.operator.prefix.modifier.haskell
32 |
33 | foo :: a % b -> c % d
34 | -- ^ ^ - keyword.operator.prefix.modifier.haskell
35 |
36 | bar :: a %%b -> c %-% d
37 | -- ^^ ^ ^ - keyword.operator.prefix.modifier.haskell
38 |
39 |
--------------------------------------------------------------------------------
/test/tests/ReservedInComments.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Reserved names in comments"
2 |
3 | data A = B -- where
4 | -- ^^^^^^^^ comment.line.double-dash.haskell
5 | -- ^^^^^ - keyword.other.where.haskell
6 | data instance A = B -- where
7 | -- ^^^^^^^^ comment.line.double-dash.haskell
8 | -- ^^^^^ - keyword.other.where.haskell
9 |
10 | data Foo a {- = y -}
11 | -- ^ - keyword.operator.eq.haskell
12 | -- ^^^^^^ comment.block.haskell
13 | = A
14 |
15 | type Foo a {- = A -}
16 | -- ^ - keyword.operator.eq.haskell
17 | -- ^^^^^^ comment.block.haskell
18 | = A
19 |
20 | f {- :: xyz -}
21 | -- ^^ - keyword.operator.double-colon.haskell
22 | -- ^^^^^^^^^ comment.block.haskell
23 | :: A -> B
24 |
25 | f {- :: xyz -}
26 | -- ^^ - keyword.operator.double-colon.haskell
27 | -- ^^^^^^^^^^^^ comment.block.haskell
28 | :: A -> B
29 |
30 | data Foo a -- = y
31 | -- ^ - keyword.operator.eq.haskell
32 | -- ^^^^^^ comment.line.double-dash.haskell
33 | = A
34 |
35 | type Foo a -- = A
36 | -- ^ - keyword.operator.eq.haskell
37 | -- ^^^^^^ comment.line.double-dash.haskell
38 | = A
39 |
40 | f -- :: xyz
41 | -- ^^ - keyword.operator.double-colon.haskell
42 | -- ^^^^^^^^^ comment.line.double-dash.haskell
43 | :: A -> B
44 |
--------------------------------------------------------------------------------
/scope-lists/happy.yaml:
--------------------------------------------------------------------------------
1 | - scope: Haskell Happy
2 | - scope: comment.block
3 | - scope: comment.line
4 | - scope: constant.character.escape.dec.happy
5 | - scope: constant.character.escape.happy
6 | - scope: constant.character.escape.hex.happy
7 | - scope: constant.character.escape.oct.happy
8 | - scope: entity.name.class.happy
9 | - scope: keyword.operator.happy
10 | - scope: keyword.operator.pragma.happy
11 | - scope: keyword.operator.rules.happy
12 | - scope: meta.embedded.haskell
13 | - scope: punctuation.block.begin.happy
14 | - scope: punctuation.block.end.happy
15 | - scope: punctuation.brackets.happy
16 | - scope: punctuation.quote.double.happy
17 | - scope: punctuation.quote.single.happy
18 | - scope: storage.type.happy
19 | - scope: string.quoted.double.happy
20 | - scope: string.quoted.single.happy
21 | - scope: variable.parameter.happy
22 | - scope: keyword.operator.alt.happy
23 | - scope: keyword.operator.rule.happy
24 | - scope: keyword.operator.type.happy
25 | - scope: keyword.operator.separator.happy
26 | - scope: meta.embedded.block.haskell
27 | - scope: variable.parameter.field.happy
28 | - scope: comment.block.happy
29 | - scope: comment.line.happy
30 | - scope: entity.name.directive.happy
31 | - scope: meta.embedded.block.monad.haskell
32 | - scope: punctuation.block.monad.begin.happy
33 | - scope: punctuation.definition.comment.happy
34 | - scope: punctuation.bracket.happy
35 |
--------------------------------------------------------------------------------
/test/tickets/T0146b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Highlighting in multiline type declarations"
2 |
3 |
4 | type instance GetDecks =
5 | -- <~~---- keyword.other.type.haskell
6 | -- ^^^^^^^^ keyword.other.instance.haskell
7 | -- ^^^^^^^^ storage.type.haskell
8 | -- ^ keyword.operator.eq.haskell
9 | MethodCall "getDecks" Cards
10 | -- ^^^^^^^^^^ ^^^^^ storage.type.haskell
11 |
12 | type instance GetDecks
13 | -- <~~---- keyword.other.type.haskell
14 | -- ^^^^^^^^ keyword.other.instance.haskell
15 | -- ^^^^^^^^ storage.type.haskell
16 | = MethodCall "getDecks" Cards
17 | -- ^ keyword.operator.eq.haskell
18 | -- ^^^^^^^^^^ ^^^^^ storage.type.haskell
19 |
20 |
21 | type instance GetDecks =
22 | -- <---- keyword.other.type.haskell
23 | -- ^^^^^^^^ keyword.other.instance.haskell
24 | -- ^^^^^^^^ storage.type.haskell
25 | -- ^ keyword.operator.eq.haskell
26 | MethodCall "getDecks" Cards
27 | -- <~~--------- storage.type.haskell
28 | -- ^^^^^ storage.type.haskell
29 |
30 | type instance GetDecks
31 | -- <---- keyword.other.type.haskell
32 | -- ^^^^^^^^ keyword.other.instance.haskell
33 | -- ^^^^^^^^ storage.type.haskell
34 | = MethodCall "getDecks" Cards
35 | -- <~~- keyword.operator.eq.haskell
36 | -- ^^^^^^^^^^ ^^^^^ storage.type.haskell
37 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "type": "npm",
8 | "script": "compile",
9 | "isBackground": true,
10 | "label": "npm",
11 | "group": {
12 | "kind": "build",
13 | "isDefault": true
14 | },
15 | "presentation": {
16 | "echo": false,
17 | "reveal": "never",
18 | "focus": false,
19 | "panel": "dedicated"
20 | },
21 | "problemMatcher": [
22 | "$tsc"
23 | ]
24 | },
25 | {
26 | "type": "shell",
27 | "label": "make-json",
28 | "command": "make",
29 | "args": [
30 | "all"
31 | ]
32 | },
33 | {
34 | "label": "compile-all",
35 | "dependsOn": [
36 | "npm",
37 | "make-json"
38 | ]
39 | },
40 | {
41 | "type": "npm",
42 | "script": "watch-web",
43 | "group": "build",
44 | "isBackground": true,
45 | "problemMatcher": [
46 | "$ts-webpack-watch"
47 | ]
48 | }
49 | ]
50 | }
--------------------------------------------------------------------------------
/test/tests/Role.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Role annotations"
2 |
3 |
4 | data A n r p where
5 |
6 | type role A nominal representational phantom
7 | -- ^^^^ keyword.other.type.haskell
8 | -- ^^^^ keyword.other.role.haskell
9 | -- ^ storage.type.haskell
10 | -- ^^^^^^^ keyword.other.role.nominal.haskell
11 | -- ^^^^^^^^^^^^^^^^ keyword.other.role.representational.haskell
12 | -- ^^^^^^^ keyword.other.role.phantom.haskell
13 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.role-annotation.haskell
14 |
15 |
16 | type role A
17 | -- ^^^^ keyword.other.type.haskell
18 | -- ^^^^ keyword.other.role.haskell
19 | -- ^ storage.type.haskell
20 | nominal
21 | -- ^^^^^^^ keyword.other.role.nominal.haskell
22 | representational
23 | -- ^^^^^^^^^^^^^^^^ keyword.other.role.representational.haskell
24 | phantom
25 | -- ^^^^^^^ keyword.other.role.phantom.haskell
26 |
27 | type role
28 | -- ^^^^ keyword.other.type.haskell
29 | -- ^^^^ keyword.other.role.haskell
30 | (:&)
31 | -- ^^ storage.type.operator.haskell
32 | nominal
33 | -- ^^^^^^^ keyword.other.role.nominal.haskell
34 | representational
35 | -- ^^^^^^^^^^^^^^^^ keyword.other.role.representational.haskell
36 | phantom
37 | -- ^^^^^^^ keyword.other.role.phantom.haskell
38 |
--------------------------------------------------------------------------------
/scope-lists/happy.md:
--------------------------------------------------------------------------------
1 | | Scope Name | Description | Example |
2 | |-|-|-|
3 | | Haskell Happy | | |
4 | | comment.block | | |
5 | | comment.line | | |
6 | | constant.character.escape.dec.happy | | |
7 | | constant.character.escape.happy | | |
8 | | constant.character.escape.hex.happy | | |
9 | | constant.character.escape.oct.happy | | |
10 | | entity.name.class.happy | | |
11 | | keyword.operator.happy | | |
12 | | keyword.operator.pragma.happy | | |
13 | | keyword.operator.rules.happy | | |
14 | | meta.embedded.haskell | | |
15 | | punctuation.block.begin.happy | | |
16 | | punctuation.block.end.happy | | |
17 | | punctuation.brackets.happy | | |
18 | | punctuation.quote.double.happy | | |
19 | | punctuation.quote.single.happy | | |
20 | | storage.type.happy | | |
21 | | string.quoted.double.happy | | |
22 | | string.quoted.single.happy | | |
23 | | variable.parameter.happy | | |
24 | | keyword.operator.alt.happy | | |
25 | | keyword.operator.rule.happy | | |
26 | | keyword.operator.type.happy | | |
27 | | keyword.operator.separator.happy | | |
28 | | meta.embedded.block.haskell | | |
29 | | variable.parameter.field.happy | | |
30 | | comment.block.happy | | |
31 | | comment.line.happy | | |
32 | | entity.name.directive.happy | | |
33 | | meta.embedded.block.monad.haskell | | |
34 | | punctuation.block.monad.begin.happy | | |
35 | | punctuation.definition.comment.happy | | |
36 | | punctuation.bracket.happy | | |
37 |
--------------------------------------------------------------------------------
/images/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
17 |
--------------------------------------------------------------------------------
/test/tickets/T0072b3.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Deriving via (multiline)"
2 |
3 |
4 | deriving via VariantF ( ApplyAll (EGADT vs) vs )
5 | -- ^^^^^^^^ keyword.other.deriving.haskell
6 | -- ^^^ keyword.other.deriving.strategy.via.haskell
7 | -- ^^^^^^^^ ^^^^^^^ ^^^^ storage.type.haskell
8 | -- ^^ ^^ variable.other.generic-type.haskell
9 | instance BottomUp CodeGen ( ApplyAll (EGADT vs) vs )
10 | -- ^^^^^^^^ keyword.other.instance.haskell
11 | -- ^^^^^^^^ ^^^^^^^ ^^^^^^^^ ^^^^^ storage.type.haskell
12 | -- ^^ variable.other.generic-type.haskell
13 | => CodeGen (EGADT vs)
14 | -- ^^ keyword.operator.big-arrow.haskell
15 | -- ^^^^^^^ ^^^^^ storage.type.haskell
16 | -- ^^ variable.other.generic-type.haskell
17 |
18 | newtype StateMonad b c r = StateMonad (StateT (MyState (Something b c) b) IO r)
19 | deriving (MonadState (MyState (Something b c) b), MonadIO, Monad)
20 | -- ^^^^^^^^ keyword.other.deriving.haskell
21 | -- ^ ^ ^ variable.other.generic-type.haskell
22 | -- ^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^ ^^^^^^^ ^^^^^ storage.type.haskell
23 | via ( State ( s, t ) r )
24 | -- ^^^ keyword.other.deriving.strategy.via.haskell
25 | -- ^^^^^ storage.type.haskell
26 | -- ^ ^ ^ variable.other.generic-type.haskell
27 |
--------------------------------------------------------------------------------
/scope-lists/alex.yaml:
--------------------------------------------------------------------------------
1 | - scope: Haskell Alex
2 | - scope: comment.block
3 | - scope: comment.line
4 | - scope: constant.character.escape.alex
5 | - scope: constant.character.escape.dec.alex
6 | - scope: constant.character.escape.hex.alex
7 | - scope: constant.character.escape.oct.alex
8 | - scope: entity.name.class.alex
9 | - scope: keyword.operator.alex
10 | - scope: keyword.operator.pragma.alex
11 | - scope: keyword.operator.rules.alex
12 | - scope: meta.embedded.haskell
13 | - scope: punctuation.block.begin.alex
14 | - scope: punctuation.block.end.alex
15 | - scope: punctuation.brackets.alex
16 | - scope: storage.type.alex
17 | - scope: string.quoted.double.alex
18 | - scope: variable.parameter.alex
19 | - scope: meta.embedded.block.haskell
20 | - scope: punctuation.quote.double.alex
21 | - scope: punctuation.semicolon.alex
22 | - scope: punctuation.quote.single.alex
23 | - scope: string.quoted.single.alex
24 | - scope: comment.block.alex
25 | - scope: comment.line.alex
26 | - scope: entity.name.macro.character-set.alex
27 | - scope: entity.name.macro.regular-expression.alex
28 | - scope: entity.name.pragma.alex
29 | - scope: meta.block.startcode.alex
30 | - scope: meta.startcode.alex
31 | - scope: punctuation.block.startcode.begin.alex
32 | - scope: punctuation.block.startcode.end.alex
33 | - scope: punctuation.bracket.startcode.alex
34 | - scope: punctuation.comma.startcode.alex
35 | - scope: punctuation.definition.comment.alex
36 | - scope: variable.other.starcode.alex
37 | - scope: variable.other.startcode.alex
38 | - scope: punctuation.bracket.alex
39 |
--------------------------------------------------------------------------------
/test/tests/Comments.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Intervening comments shouldn't affect highlighting"
2 |
3 |
4 | data A
5 | -- ^ storage.type.haskell
6 | -- comment line not gobbled up by the preprocessor
7 | -- <~~-------------------------------------------------- comment.line.double-dash.haskell
8 | = A
9 | -- ^ constant.other.haskell
10 |
11 | newtype B =
12 | -- ^ storage.type.haskell
13 | -- comment line not gobbled up by the preprocessor
14 | -- <~~-------------------------------------------------- comment.line.double-dash.haskell
15 | B
16 | -- ^ constant.other.haskell
17 |
18 | data Foo where
19 | -- comment line not gobbled up by the preprocessor
20 | -- <~~-------------------------------------------------- comment.line.double-dash.haskell
21 | MkFoo :: Foo
22 | -- ^^^^^ constant.other.haskell
23 | -- ^^^ storage.type.haskell
24 |
25 | dbPageWrapper :: (DashBoardPage p, Monad m) =>
26 | -- comment line not gobbled up by the preprocessor
27 | -- <~~-------------------------------------------------- comment.line.double-dash.haskell
28 | T.Text -> p -> HtmlT m a -> HtmlT m b -> HtmlT m b
29 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.type-declaration.haskell
30 | -- ^^^^^ storage.type.haskell
31 |
32 | type T a
33 | -- comment line not gobbled up by the preprocessor
34 | -- <~~-------------------------------------------------- comment.line.double-dash.haskell
35 | = Int
36 | -- ^^^ storage.type.haskell
37 |
--------------------------------------------------------------------------------
/test/tests/Happy.y:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell.happy" "Happy"
2 |
3 | {
4 | -- <- meta.embedded.block.haskell
5 | module Happy where
6 | -- <------ keyword.other.module.haskell
7 | -- ^^^^ meta.declaration.module.haskell
8 | }
9 | -- <- meta.embedded.block.haskell
10 |
11 | %monad { P }
12 | -- <------ entity.name.directive.happy
13 | -- ^ punctuation.block.begin.happy
14 | -- ^ punctuation.block.end.happy
15 |
16 | %name parse
17 | %tokentype { Token }
18 | %error { parseError }
19 |
20 | %token
21 | '(' { OPEN_PAREN }
22 | ')' { CLOSE_PAREN }
23 | '+' { PLUS }
24 | -- ^^^ string.quoted.single.happy
25 | -- ^ ^ punctuation.quote.single.happy
26 | num { NUMBER $$ }
27 |
28 | %left '+'
29 |
30 | -- comment {-
31 | %%
32 | -- <-- keyword.operator.separator.happy
33 | -- <-- - comment.block.happy
34 | -- comment -}
35 |
36 | value :: { AST }
37 | -- ^^ keyword.operator.type.happy
38 | : value '+' value { Add $1 $3 }
39 | -- ^ keyword.operator.rule.happy
40 | | num { Number $1 }
41 | -- ^ keyword.operator.alt.happy
42 | | '(' value ')' {% pure $2 }
43 | -- ^^ punctuation.block.monad.begin.happy
44 | | '(' ')' {%% someErr }
45 | -- ^^^ punctuation.block.monad.begin.happy
46 | | ')' '(' {%^ someOtherErr }
47 | -- ^^^ punctuation.block.monad.begin.happy
48 |
49 | {
50 |
51 | data Token
52 | = OPEN_PAREN
53 | | CLOSE_PAREN
54 | | PLUS
55 | | NUMBER Int
56 |
57 | data AST
58 | = Add AST AST
59 | | Number Int
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017 Justus Adam
2 |
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 |
11 | * Redistributions in binary form must reproduce the above
12 | copyright notice, this list of conditions and the following
13 | disclaimer in the documentation and/or other materials provided
14 | with the distribution.
15 |
16 | * Neither the name of Justus Adam nor the names of other
17 | contributors may be used to endorse or promote products derived
18 | from this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
--------------------------------------------------------------------------------
/test/tests/Imports.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Imports"
2 |
3 | import M
4 | ( T(f,C,g)
5 | -- ^ storage.type.haskell
6 | -- ^ ^ entity.name.function.haskell
7 | , S((:<..<), .. )
8 | -- ^ storage.type.haskell
9 | -- ^^ - variable.other.member.wildcard.haskell
10 | -- ^^^^^ constant.other.operator.prefix.haskell
11 | -- ^^ variable.other.member.wildcard.haskell
12 | , (:->)((:>))
13 | -- ^^^ storage.type.operator.haskell
14 | -- ^^ constant.other.operator.prefix.haskell
15 | , (:<>)(C,a,D,E)
16 | -- ^^^ storage.type.operator.haskell
17 | , A((<>), (:>>))
18 | -- ^ storage.type.haskell
19 | -- ^^^ constant.other.operator.prefix.haskell
20 | , f
21 | -- ^ entity.name.function.haskell
22 | , pattern P
23 | -- ^^^^^^^ keyword.other.pattern.haskell
24 | -- ^ constant.other.haskell
25 | , pattern (:| )
26 | -- ^^^^^^^ keyword.other.pattern.haskell
27 | -- ^^ constant.other.operator.prefix.haskell
28 | , pattern -- Q,)
29 | -- ^^^^^^^ keyword.other.pattern.haskell
30 | Q
31 | -- ^ constant.other.haskell
32 | , f, T
33 | -- ^ entity.name.function.haskell
34 | -- ^ storage.type.haskell
35 | , type T
36 | -- ^^^^ keyword.other.type.haskell
37 | -- ^ storage.type.haskell
38 | , type (:- )
39 | -- ^^^^ keyword.other.type.haskell
40 | -- ^^ storage.type.operator.haskell
41 | , type (<+>)
42 | -- ^^^^ keyword.other.type.haskell
43 | -- ^^^ storage.type.operator.haskell
44 | , type {- T -}
45 | -- ^^^^ keyword.other.type.haskell
46 | (<->)
47 | -- ^^^ storage.type.operator.haskell
48 | )
49 |
--------------------------------------------------------------------------------
/test/tests/NearReserved.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Issues surrounding reserved operators"
2 |
3 | type a ==> b = a --> b
4 | -- ^ keyword.operator.eq.haskell
5 | -- ^^^ - keyword.operator.eq.haskell
6 | -- ^^^ ^^^ - keyword.operator.arrow.haskell
7 | type family a ==> b = a --> b
8 | -- ^ keyword.operator.eq.haskell
9 | -- ^^^ - keyword.operator.eq.haskell keyword.operator.big-arrow.haskell
10 | -- ^^^ - keyword.operator.arrow.haskell
11 | data a ==> b = a :== b
12 | -- ^ keyword.operator.eq.haskell
13 | -- ^^^ - keyword.operator.eq.haskell keyword.operator.big-arrow.haskell
14 | -- ^^^ - keyword.operator.eq.haskell
15 | data a :==> b where
16 | -- ^^^^ - keyword.operator.eq.haskell keyword.operator.big-arrow.haskell
17 | (::: ) :: a ::: b -> c :==> d
18 | -- ^^^^ ^^^ - keyword.operator.double-colon.haskell
19 | -- ^^^^ - keyword.operator.eq.haskell keyword.operator.big-arrow.haskell
20 |
21 | f :: a ::: b =| c --> d -> e ==> b
22 | -- ^^^ - keyword.operator.double-colon.haskell
23 | -- ^ ^^ - keyword.operator.eq.haskell
24 | -- ^^ - keyword.operator.arrow.haskell
25 | -- ^^ - keyword.operator.big-arrow.haskell
26 |
27 | ( -:: ) :: a -> a -> a
28 | -- <------- - keyword.operator.double-colon.haskell
29 | a -:: b = a
30 | -- <~~--- - keyword.operator.double-colon.haskell
31 |
32 | (:::) :: a -> a -> a
33 | -- <~--- - keyword.operator.double-colon.haskell
34 | a ::: b = a
35 | -- <~~--- - keyword.operator.double-colon.haskell
36 |
--------------------------------------------------------------------------------
/scope-lists/alex.md:
--------------------------------------------------------------------------------
1 | | Scope Name | Description | Example |
2 | |-|-|-|
3 | | Haskell Alex | | |
4 | | comment.block | | |
5 | | comment.line | | |
6 | | constant.character.escape.alex | | |
7 | | constant.character.escape.dec.alex | | |
8 | | constant.character.escape.hex.alex | | |
9 | | constant.character.escape.oct.alex | | |
10 | | entity.name.class.alex | | |
11 | | keyword.operator.alex | | |
12 | | keyword.operator.pragma.alex | | |
13 | | keyword.operator.rules.alex | | |
14 | | meta.embedded.haskell | | |
15 | | punctuation.block.begin.alex | | |
16 | | punctuation.block.end.alex | | |
17 | | punctuation.brackets.alex | | |
18 | | storage.type.alex | | |
19 | | string.quoted.double.alex | | |
20 | | variable.parameter.alex | | |
21 | | meta.embedded.block.haskell | | |
22 | | punctuation.quote.double.alex | | |
23 | | punctuation.semicolon.alex | | |
24 | | punctuation.quote.single.alex | | |
25 | | string.quoted.single.alex | | |
26 | | comment.block.alex | | |
27 | | comment.line.alex | | |
28 | | entity.name.macro.character-set.alex | | |
29 | | entity.name.macro.regular-expression.alex | | |
30 | | entity.name.pragma.alex | | |
31 | | meta.block.startcode.alex | | |
32 | | meta.startcode.alex | | |
33 | | punctuation.block.startcode.begin.alex | | |
34 | | punctuation.block.startcode.end.alex | | |
35 | | punctuation.bracket.startcode.alex | | |
36 | | punctuation.comma.startcode.alex | | |
37 | | punctuation.definition.comment.alex | | |
38 | | variable.other.starcode.alex | | |
39 | | variable.other.startcode.alex | | |
40 | | punctuation.bracket.alex | | |
41 |
--------------------------------------------------------------------------------
/test/tests/InfixDataDecl.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Infix data declarations"
2 |
3 |
4 | data A a b = ( T b c ( d e ) f ) `C` '[ A b, C, D [ e, f ] g ]
5 | -- ^^^^ keyword.other.data.haskell
6 | -- ^ keyword.operator.eq.haskell
7 | -- ^ ^ punctuation.paren.haskell
8 | -- ^ constant.other.infix.haskell
9 | -- ^ ^ punctuation.backtick.haskell
10 | -- ^ keyword.operator.promotion.haskell
11 | -- ^ ^ ^ ^ ^ storage.type.haskell
12 | -- ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ variable.other.generic-type.haskell
13 | -- ^ ^ punctuation.bracket.haskell
14 |
15 |
16 | data A a b = '[ X, y, Z ] `C` D e
17 | -- ^^^^ keyword.other.data.haskell
18 | -- ^ keyword.operator.eq.haskell
19 | -- ^ keyword.operator.promotion.haskell
20 | -- ^ constant.other.infix.haskell
21 | -- ^ ^ punctuation.backtick.haskell
22 | -- ^ ^ ^ storage.type.haskell
23 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
24 |
25 | data A a b = ABC.D `C` GH
26 | -- ^^^^ keyword.other.data.haskell
27 | -- ^ keyword.operator.eq.haskell
28 | -- ^^^^ entity.name.namespace.haskell
29 | -- ^ constant.other.infix.haskell
30 | -- ^ ^ punctuation.backtick.haskell
31 | -- ^ ^^ storage.type.haskell
32 |
--------------------------------------------------------------------------------
/test/tests/GADTRecord.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "GADT record syntax"
2 |
3 | data D :: A -> B -> Type where
4 | C :: { fld1 :: A, (&) :: B } -> D a b
5 | -- ^ constant.other.haskell
6 | -- ^^^^ ^ variable.other.member.definition.haskell
7 | -- ^ ^ punctuation.brace.haskell
8 | -- ^ ^ ^ storage.type.haskell
9 |
10 |
11 | data D a where
12 | C :: { fld :: forall (a :: B). C a => T a }
13 | -- ^ constant.other.haskell
14 | -- ^^^ variable.other.member.definition.haskell
15 | -- ^ ^ ^ storage.type.haskell
16 | -- ^ ^ ^ variable.other.generic-type.haskell
17 |
18 | data (!!!) :: Type where
19 | (:<>) :: { fld1 :: A, (&) :: B } -> (!!!)
20 | -- ^^^ constant.other.operator.prefix.haskell
21 | -- ^^^^ ^ variable.other.member.definition.haskell
22 | -- ^ ^ punctuation.brace.haskell
23 | -- ^ ^ storage.type.haskell
24 | -- ^^^ storage.type.operator.haskell
25 |
26 | data D :: A -> B -> Type where { C :: { fld1 :: A, (&) :: B } -> D a b }
27 | -- ^ constant.other.haskell
28 | -- ^^^^ ^ variable.other.member.definition.haskell
29 | -- ^ ^ punctuation.brace.haskell
30 | -- ^ ^ ^ storage.type.haskell
31 |
32 | foo :: A
33 | -- ^^^^^^^^ - meta.declaration.data.generalized.haskell
34 | -- ^^^ entity.name.function.haskell
35 | -- ^ storage.type.haskell
36 |
--------------------------------------------------------------------------------
/test/tickets/T0167.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Interaction between record fields and context arrows"
2 |
3 | data BuilderType = Builder
4 | { (>>=) :: forall m a b. Unrestricted.Monad m => m a -> (a -> m b) -> m b
5 | -- ^^^ variable.other.member.definition.haskell
6 | -- ^^ keyword.operator.double-colon.haskell
7 | -- ^^^^^^ keyword.other.forall.haskell
8 | -- ^ keyword.operator.period.haskell
9 | -- ^^ keyword.operator.big-arrow
10 | , (>>) :: forall m b . Unrestricted.Monad m => m () -> m b -> m b
11 | -- ^^ variable.other.member.definition.haskell
12 | -- ^^ keyword.operator.double-colon.haskell
13 | -- ^^^^^^ keyword.other.forall.haskell
14 | -- ^ keyword.operator.period.haskell
15 | -- ^^ keyword.operator.big-arrow
16 | , fail :: forall m a . Unrestricted.MonadFail m => String -> m a
17 | -- ^^^^ variable.other.member.definition.haskell
18 | -- ^^ keyword.operator.double-colon.haskell
19 | -- ^^^^^^ keyword.other.forall.haskell
20 | -- ^ keyword.operator.period.haskell
21 | -- ^^ keyword.operator.big-arrow
22 | , return :: forall m a . Unrestricted.Monad m => a -> m a
23 | -- ^^^^^^ variable.other.member.definition.haskell
24 | -- ^^ keyword.operator.double-colon.haskell
25 | -- ^^^^^^ keyword.other.forall.haskell
26 | -- ^ keyword.operator.period.haskell
27 | -- ^^ keyword.operator.big-arrow
28 | }
29 |
--------------------------------------------------------------------------------
/test/tests/InfixBacktick.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Backticked infix operators"
2 |
3 |
4 | a `foo` b
5 | -- ^^^ keyword.operator.function.infix.haskell
6 | -- ^^^ - constant.other.haskell
7 | -- ^ ^ punctuation.backtick.haskell
8 | a `_foo'` b
9 | -- ^^^^^ keyword.operator.function.infix.haskell
10 | -- ^^^^^ - constant.other.haskell
11 | -- ^ ^ punctuation.backtick.haskell
12 | a `ABC.foo` b
13 | -- ^^^^ entity.name.namespace.haskell
14 | -- ^^^ keyword.operator.function.infix.haskell
15 | -- ^^^ - constant.other.haskell
16 | -- ^ ^ punctuation.backtick.haskell
17 | a `ABC._foo'` b
18 | -- ^^^^ entity.name.namespace.haskell
19 | -- ^^^^^ keyword.operator.function.infix.haskell
20 | -- ^^^^^ - constant.other.haskell
21 | -- ^ ^ punctuation.backtick.haskell
22 |
23 | a `A` b
24 | -- ^ keyword.operator.function.infix.haskell
25 | -- ^ constant.other.haskell
26 | -- ^ ^ punctuation.backtick.haskell
27 | a `ABC.A_'` b
28 | -- ^^^^ entity.name.namespace.haskell
29 | -- ^^^ keyword.operator.function.infix.haskell
30 | -- ^^^ constant.other.haskell
31 | -- ^ ^ punctuation.backtick.haskell
32 | f :: a `A` b
33 | -- ^ storage.type.infix.haskell
34 | -- ^ ^ punctuation.backtick.haskell
35 | f :: a '`A` b
36 | -- ^ keyword.operator.promotion.haskell
37 | -- ^ storage.type.infix.haskell
38 | -- ^ ^ punctuation.backtick.haskell
39 | f :: a `ABC.A` b
40 | -- ^^^^ entity.name.namespace.haskell
41 | -- ^ storage.type.infix.haskell
42 | -- ^ ^ punctuation.backtick.haskell
43 | f :: a '`ABC.A` b
44 | -- ^ keyword.operator.promotion.haskell
45 | -- ^^^^ entity.name.namespace.haskell
46 | -- ^ storage.type.infix.haskell
47 | -- ^ ^ punctuation.backtick.haskell
48 |
--------------------------------------------------------------------------------
/test/tests/BlockComments.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Intervening block comments shouldn't affect highlighting"
2 |
3 |
4 | data A
5 | -- ^ storage.type.haskell
6 | {- comment line not gobbled up by the preprocessor
7 | over multiple lines -}
8 | -- <~~---------------------- comment.block.haskell
9 | = A
10 | -- ^ constant.other.haskell
11 |
12 | data B =
13 | -- ^ storage.type.haskell
14 | {- comment line not gobbled up by the preprocessor -}
15 | -- <~~----------------------------------------------------- comment.block.haskell
16 | B
17 | -- ^ constant.other.haskell
18 |
19 | newtype A =
20 | -- ^ storage.type.haskell
21 | {- comment line not gobbled up by the preprocessor
22 | over multiple lines -}
23 | -- <~~---------------------- comment.block.haskell
24 | A
25 | -- ^ constant.other.haskell
26 |
27 | newtype B =
28 | -- ^ storage.type.haskell
29 | {- comment line not gobbled up by the preprocessor -}
30 | -- <~~----------------------------------------------------- comment.block.haskell
31 | B
32 | -- ^ constant.other.haskell
33 |
34 |
35 | data Foo where
36 | {- comment line not gobbled up by the preprocessor
37 | over multiple lines -}
38 | -- <---------------------- comment.block.haskell
39 | MkFoo :: Foo
40 | -- ^^^^^ constant.other.haskell
41 | -- ^^^ storage.type.haskell
42 |
43 | dbPageWrapper :: (DashBoardPage p, Monad m) =>
44 | {- comment line not gobbled up by the preprocessor
45 | over
46 | multiple
47 | lines -}
48 | -- <~----------- comment.block.haskell
49 | T.Text -> p -> HtmlT m a -> HtmlT m b -> HtmlT m b
50 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.type-declaration.haskell
51 | -- ^^^^^ storage.type.haskell
52 |
53 | type T a
54 | {- comment line not gobbled up by the preprocessor
55 | over multiple
56 | lines -}
57 | -- <-------- comment.block.haskell
58 | = Int
59 | -- ^^^ storage.type.haskell
60 |
--------------------------------------------------------------------------------
/test/tests/Exports.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Exports"
2 |
3 | module M
4 | ( T(f,C,g)
5 | -- ^ storage.type.haskell
6 | -- ^ ^ entity.name.function.haskell
7 | , S((:<..<), .. )
8 | -- ^ storage.type.haskell
9 | -- ^^ - variable.other.member.wildcard.haskell
10 | -- ^^^^^ constant.other.operator.prefix.haskell
11 | -- ^^ variable.other.member.wildcard.haskell
12 | , (:->)((:>))
13 | -- ^^^ storage.type.operator.haskell
14 | -- ^^ constant.other.operator.prefix.haskell
15 | , (:<>)(C,a,D,E)
16 | -- ^^^ storage.type.operator.haskell
17 | , A((<>), (:>>))
18 | -- ^ storage.type.haskell
19 | -- ^^^ constant.other.operator.prefix.haskell
20 | , f
21 | -- ^ entity.name.function.haskell
22 | , pattern P
23 | -- ^^^^^^^ keyword.other.pattern.haskell
24 | -- ^ constant.other.haskell
25 | , pattern (:|)
26 | -- ^^^^^^^ keyword.other.pattern.haskell
27 | -- ^^ constant.other.operator.prefix.haskell
28 | , pattern -- Q,)
29 | -- ^^^^^^^ keyword.other.pattern.haskell
30 | Q
31 | -- ^ constant.other.haskell
32 | , f, T
33 | -- ^ entity.name.function.haskell
34 | -- ^ storage.type.haskell
35 | , type T
36 | -- ^^^^ keyword.other.type.haskell
37 | -- ^ storage.type.haskell
38 | , type (:-)
39 | -- ^^^^ keyword.other.type.haskell
40 | -- ^^ storage.type.operator.haskell
41 | , type (<+>)
42 | -- ^^^^ keyword.other.type.haskell
43 | -- ^^^ storage.type.operator.haskell
44 | , type {- T -}
45 | -- ^^^^ keyword.other.type.haskell
46 | (<->)
47 | -- ^^^ storage.type.operator.haskell
48 | , type (Qualified.<->)
49 | -- ^^^^ keyword.other.type.haskell
50 | -- ^^^^^^^^^^ entity.name.namespace.haskell
51 | -- ^^^ storage.type.operator.haskell
52 | , type Qualified.T
53 | -- ^^^^ keyword.other.type.haskell
54 | -- ^^^^^^^^^^ entity.name.namespace.haskell
55 | -- ^ storage.type.haskell
56 | )
57 | where
58 | -- ^^^^^ keyword.other.where.haskell
59 |
--------------------------------------------------------------------------------
/test/tests/UnusualTypeApplications.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Unusual type applications"
2 |
3 |
4 | f = g @A
5 | -- ^ keyword.operator.prefix.at.haskell
6 | -- ^^ meta.type-application.haskell
7 | f = [g]@A
8 | -- ^ keyword.operator.prefix.at.haskell
9 | -- ^^ meta.type-application.haskell
10 | f = {g}@A
11 | -- ^ keyword.operator.prefix.at.haskell
12 | -- ^^ meta.type-application.haskell
13 | f = g,@A
14 | -- ^ keyword.operator.prefix.at.haskell
15 | -- ^^ meta.type-application.haskell
16 | f = g;@A
17 | -- ^ keyword.operator.prefix.at.haskell
18 | -- ^^ meta.type-application.haskell
19 | f = g @(A B C)
20 | -- ^ keyword.operator.prefix.at.haskell
21 | -- ^^^^^^^^ meta.type-application.haskell
22 | f = g @'[A B, C]
23 | -- ^ keyword.operator.prefix.at.haskell
24 | -- ^^^^^^^^^^ meta.type-application.haskell
25 |
26 | f = g @'A
27 | -- ^ keyword.operator.prefix.at.haskell
28 | -- ^^^ meta.type-application.haskell
29 |
30 | f = g @()
31 | -- ^ keyword.operator.prefix.at.haskell
32 | -- ^^ support.constant.unit.haskell
33 |
34 | f = g @( )
35 | -- ^ keyword.operator.prefix.at.haskell
36 | -- ^^^^^^ support.constant.unit.haskell
37 |
38 | f = g @123
39 | -- ^ keyword.operator.prefix.at.haskell
40 | -- ^^^^^^^^^^ meta.type-application.haskell
41 |
42 | f = g @"abc c\" de"
43 | -- ^ keyword.operator.prefix.at.haskell
44 | -- ^^^^^^^^^^^^^ meta.type-application.haskell
45 |
46 | f = g@A
47 | -- ^ - keyword.operator.prefix.at.haskell
48 | -- ^^ - meta.type-application.haskell
49 | f = +@A
50 | -- ^ - keyword.operator.prefix.at.haskell
51 | -- ^^ - meta.type-application.haskell
52 | f = g@@A
53 | -- ^^ - keyword.operator.prefix.at.haskell
54 | -- ^^ - meta.type-application.haskell
55 | f = g @@A
56 | -- ^^ - keyword.operator.prefix.at.haskell
57 | -- ^^ - meta.type-application.haskell
58 | f = g @!A
59 | -- ^ - keyword.operator.prefix.at.haskell
60 | -- ^^ - meta.type-application.haskell
61 | f = (g)@A
62 | -- ^ - keyword.operator.prefix.at.haskell
63 | -- ^^ - meta.type-application.haskell
64 |
--------------------------------------------------------------------------------
/test/tests/Alex.x:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell.alex" "Alex"
2 |
3 | {
4 | -- <- meta.embedded.block.haskell
5 | module Alex where
6 | -- <------ keyword.other.module.haskell
7 | -- ^^^^ meta.declaration.module.haskell
8 | }
9 | -- <- meta.embedded.block.haskell
10 |
11 | %wrapper "basic"
12 | -- <-------- entity.name.pragma.alex
13 | -- ^^^^^^^ string.quoted.double.alex
14 | -- ^ ^ punctuation.quote.double.alex
15 |
16 | $digit = 0-9
17 | -- <------ entity.name.macro.character-set.alex
18 | -- ^ ^ keyword.operator.alex
19 | $alpha = [a-zA-Z]
20 | -- ^ ^ punctuation.bracket.alex
21 |
22 | @foobar = foo | bar
23 | -- <------- entity.name.macro.regular-expression.alex
24 | -- ^ ^ keyword.operator.alex
25 |
26 | -- comment {-
27 | tokens :-
28 | -- ^^ keyword.operator.rules.alex
29 | -- <--------- - comment.block.alex
30 | -- comment -}
31 | <0> $white+ ;
32 | -- <-- meta.startcode.alex
33 | -- <- punctuation.bracket.startcode.alex
34 | -- <~~- punctuation.bracket.startcode.alex
35 | -- ^ punctuation.semicolon.alex
36 | <0> $digit+ { NUMBER }
37 | -- ^ punctuation.block.begin.alex
38 | -- ^ punctuation.block.end.alex
39 | <0,1> $alpha+ { IDENT }
40 | --^ punctuation.comma.startcode.alex
41 | {
42 | -- <------------------------ meta.block.startcode.alex
43 | -- <- punctuation.bracket.startcode.alex
44 | -- ^ variable.other.startcode.0.alex
45 | -- ^^^ ^^^ ^^^^^ variable.other.startcode.alex
46 | -- ^ punctuation.bracket.startcode.alex
47 | -- ^ punctuation.block.startcode.begin.alex
48 | \n ;
49 | -- ^ punctuation.semicolon.alex
50 | @foobar { FOO }
51 | -- ^^^^^^^ - source.haskell
52 | }
53 | -- <- punctuation.block.startcode.end.alex
54 |
55 | {-
56 | -- <- punctuation.definition.comment.alex
57 | {-
58 | nested comment
59 | -- <----------------- comment.block.alex
60 | -}
61 | -}
62 |
63 |
64 | {
65 |
66 | data Token
67 | = NUMBER
68 | | IDENT
69 | | FOO
70 |
71 | main = undefined
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/test/tickets/T0157.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Specialise pragma"
2 |
3 | {-# SPECIALIZE [0] hammeredLookup :: [(Widget, value)] -> Widget -> value #-} hammeredLookup
4 | -- ^^^^^^^^^^ keyword.other.preprocessor.pragma.haskell
5 | -- ^^^^^^ ^^^^^^ storage.type.haskell
6 | -- ^^^^^ ^^^^^ variable.other.generic-type.haskell
7 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
8 | -- ^^^^^^^^^^^^^^ - meta.preprocessor.haskell
9 |
10 |
11 | {-# SPECIALISE INLINE (!:) :: Arr (a, b) -> Int -> (a, b) #-}
12 | -- ^^^^^^^^^^ keyword.other.preprocessor.pragma.haskell
13 | -- ^^ entity.name.function.infix.haskell
14 | -- ^^^ ^^^ storage.type.haskell
15 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
16 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
17 |
18 | {-# SPECIALIZE INLINE [~2] (!:) :: Arr (a, b) -> Int -> (a, b) #-}
19 | -- ^^^^^^^^^^ keyword.other.preprocessor.pragma.haskell
20 | -- ^^^^^^ keyword.other.preprocessor.pragma.haskell
21 | -- ^^ entity.name.function.infix.haskell
22 | -- ^^^ ^^^ storage.type.haskell
23 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
24 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
25 |
26 | instance (Eq a) => Eq (Foo a) where {
27 | {-# SPECIALISE [1] instance Eq (Foo [(Int, Bar)]) #-}
28 | -- ^^^^^^^^^^ keyword.other.preprocessor.pragma.haskell
29 | -- ^^^^^^^^ keyword.other.instance.haskell
30 | -- ^^ ^^^ ^^^ ^^^ storage.type.haskell
31 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/test/tests/Class.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Class declarations"
2 |
3 |
4 | class C a where
5 | -- ^^^^^ keyword.other.class.haskell
6 | -- ^ storage.type.haskell
7 | -- ^ variable.other.generic-type.haskell
8 | -- ^^^^^ keyword.other.where.haskell
9 | meth :: a b
10 | -- ^^^^ entity.name.function.haskell
11 | -- ^ ^ variable.other.generic-type.haskell
12 |
13 |
14 | class ( C a, D a )
15 | -- ^^^^^ keyword.other.class.haskell
16 | -- ^ ^ storage.type.haskell
17 | -- ^ ^ variable.other.generic-type.haskell
18 | {- comment -}
19 | => E ( A b c )
20 | -- ^^ keyword.operator.big-arrow.haskell
21 | -- ^ ^ storage.type.haskell
22 | -- ^ ^ variable.other.generic-type.haskell
23 | where
24 | -- ^^^^^ keyword.other.where.haskell
25 | method :: a b
26 | -- ^^^^^^ entity.name.function.haskell
27 | -- ^ ^ variable.other.generic-type.haskell
28 |
29 |
30 | class C ( a :: k ) =>
31 | -- ^^^^^ keyword.other.class.haskell
32 | -- ^^ keyword.operator.big-arrow.haskell
33 | G
34 | -- ^ storage.type.haskell
35 | (a :: k)
36 | -- ^ ^ variable.other.generic-type.haskell
37 | (b :: L k)
38 | -- ^ storage.type.haskell
39 | -- ^ ^ variable.other.generic-type.haskell
40 | where
41 | -- ^^^^^ keyword.other.where.haskell
42 |
43 | () :: T k -> T (L k) -> A
44 | -- ^^^ entity.name.function.infix.haskell
45 | -- ^ ^ variable.other.generic-type.haskell
46 | -- ^ ^ ^ ^ storage.type.haskell
47 |
48 |
49 | class G a where
50 | -- ^^^^^ keyword.other.class.haskell
51 | -- ^ storage.type.haskell
52 | -- ^ variable.other.generic-type.haskell
53 | -- ^^^^^ keyword.other.where.haskell
54 |
55 | foo :: A
56 | -- ^^^ meta.function.type-declaration.haskell
57 | -- ^^^ entity.name.function.haskell
58 | -- ^^^^^^^^ - meta.declaration.class.haskell
59 |
60 | class G a
61 | -- ^^^^^ keyword.other.class.haskell
62 | -- ^ storage.type.haskell
63 | -- ^ variable.other.generic-type.haskell
--------------------------------------------------------------------------------
/test/tests/Records.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Special record syntax"
2 |
3 | data Rec = Rec { a, b :: AB a b, c :: C, (:+) :: (:-) }
4 | -- ^^^ constant.other.haskell
5 | -- ^^ ^ storage.type.haskell
6 | -- ^ ^ variable.other.generic-type.haskell
7 | -- ^ ^ ^ ^^ variable.other.member.definition.haskell
8 | -- ^^ storage.type.operator.haskell
9 |
10 | f :: Rec -> T
11 | f record@( Rec { a = A, b = b, (:+) = (:-), c, .. } )
12 | -- ^^^ constant.other.haskell
13 | -- ^ keyword.operator.infix.tight.at.haskell
14 | -- ^ ^^ - variable.other.member.haskell
15 | -- ^ ^ ^^ ^ variable.other.member.haskell
16 | -- ^^ variable.other.member.wildcard.haskell
17 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.record.haskell
18 |
19 | f :: Rec -> Rec
20 | f x = x { a = A, b = b, (:+) = (:-), c, .. }
21 | -- ^ ^^ - variable.other.member.haskell
22 | -- ^ ^ ^^ ^ variable.other.member.haskell
23 | -- ^^ variable.other.member.wildcard.haskell
24 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.record.haskell
25 |
26 | f val@( pattern )
27 | -- ^ keyword.operator.infix.tight.at.haskell
28 | f val_@( pattern )
29 | -- ^ keyword.operator.infix.tight.at.haskell
30 | f val'@( pattern )
31 | -- ^ keyword.operator.infix.tight.at.haskell
32 | f (+)@(g)
33 | -- ^ keyword.operator.infix.tight.at.haskell
34 |
35 | f@@g
36 | -- ^^ -keyword.operator.infix.tight.at.haskell
37 |
38 | f (+)@@(g)
39 | -- ^^ -keyword.operator.infix.tight.at.haskell
40 |
41 | f a@+b
42 | -- ^ -keyword.operator.infix.tight.at.haskell
43 |
44 |
45 | f = \case { "A" -> Just "a"; b -> Nothing }
46 | -- ^^^^^ keyword.control.lambda-case.haskell
47 | -- ^^^ ^^^ string.quoted.double.haskell
48 | -- ^ ^ - variable.other.member.haskell
49 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - meta.record.haskell
50 |
--------------------------------------------------------------------------------
/test/tests/Fields.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Record fields"
2 |
3 | data Rec = Rec
4 | { fld1 :: F, -- }
5 | -- ^^^^ variable.other.member.definition.haskell
6 | -- ^^ keyword.operator.double-colon.haskell
7 | -- ^ storage.type.haskell
8 | -- ^^^^ comment.line.double-dash.haskell
9 | fld2 :: F
10 | -- <---- variable.other.member.definition.haskell
11 | -- ^^ keyword.operator.double-colon.haskell
12 | -- ^ storage.type.haskell
13 | , fld3
14 | -- ^^^^ variable.other.member.definition.haskell
15 | :: F
16 | -- <-- keyword.operator.double-colon.haskell
17 | -- ^ storage.type.haskell
18 | , fld4 :: F, -- no :: F, no :: F }
19 | -- ^^^^ variable.other.member.definition.haskell
20 | -- ^^ keyword.operator.double-colon.haskell
21 | -- ^ storage.type.haskell
22 | fld5 :: F -- , no :: F} ,
23 | -- <~~---- variable.other.member.definition.haskell
24 | -- ^ storage.type.haskell
25 | }
26 |
27 |
28 | data Rec = Rec
29 | { (& ) :: F, -- }
30 | -- ^ variable.other.member.definition.haskell
31 | -- ^^ keyword.operator.double-colon.haskell
32 | -- ^ storage.type.haskell
33 | -- ^^^^ comment.line.double-dash.haskell
34 | (<>) :: F
35 | -- <~-- variable.other.member.definition.haskell
36 | -- ^^ keyword.operator.double-colon.haskell
37 | -- ^ storage.type.haskell
38 | , ( !!)
39 | -- ^^ variable.other.member.definition.haskell
40 | :: F, (+::) :: F
41 | -- <-- keyword.operator.double-colon.haskell
42 | -- ^ storage.type.haskell
43 | -- ^^^ variable.other.member.definition.haskell
44 | -- ^^ keyword.operator.double-colon.haskell
45 | -- ^ storage.type.haskell
46 | , ( ++ ) :: F, -- no :: F, no :: F }
47 | -- ^^ variable.other.member.definition.haskell
48 | -- ^^ keyword.operator.double-colon.haskell
49 | -- ^ storage.type.haskell
50 | (!::) :: F -- , no :: F} ,
51 | -- <~~~--- variable.other.member.definition.haskell
52 | -- ^ storage.type.haskell
53 | }
54 |
55 |
56 | data Rec3 = Rec3 {}
57 | -- ^^ meta.record.definition.haskell
58 |
59 | data Rec4 = Rec4
60 | {
61 | -- <~~- meta.record.definition.haskell
62 | }
63 | -- <- meta.record.definition.haskell
64 |
--------------------------------------------------------------------------------
/test/tests/ADTs.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "ADTs"
2 |
3 | data T = C
4 | -- ^^^^ keyword.other.data.haskell
5 | -- ^ storage.type.haskell
6 | -- ^ constant.other.haskell
7 | T
8 | -- ^ storage.type.haskell
9 |
10 | data T =
11 | -- ^^^^ keyword.other.data.haskell
12 | -- ^ storage.type.haskell
13 | C
14 | -- ^ constant.other.haskell
15 | T
16 | -- ^ storage.type.haskell
17 | data T
18 | -- ^^^^ keyword.other.data.haskell
19 | -- ^ storage.type.haskell
20 | = C
21 | -- ^ constant.other.haskell
22 | T
23 | -- ^ storage.type.haskell
24 | data T
25 | -- ^^^^ keyword.other.data.haskell
26 | -- ^ storage.type.haskell
27 | = C T
28 | -- ^ constant.other.haskell
29 | -- ^ storage.type.haskell
30 | data T
31 | -- ^^^^ keyword.other.data.haskell
32 | -- ^ storage.type.haskell
33 | =
34 | C
35 | -- ^ constant.other.haskell
36 | T
37 | -- ^ storage.type.haskell
38 |
39 | data D = C1 T1 | C2 T2
40 | -- ^^^^ keyword.other.data.haskell
41 | -- ^ ^^ ^^ storage.type.haskell
42 | -- ^ keyword.operator.eq.haskell
43 | -- ^ keyword.operator.pipe.haskell
44 | | C3 T3
45 | -- ^ keyword.operator.pipe.haskell
46 | -- ^^ storage.type.haskell
47 |
48 |
49 | data D2
50 | -- ^^^^ keyword.other.data.haskell
51 | = C3 T3
52 | -- ^ keyword.operator.eq.haskell
53 | -- ^^ constant.other.haskell
54 | -- ^^ storage.type.haskell
55 | | C4 T4
56 | -- ^^ constant.other.haskell
57 | -- ^^ storage.type.haskell
58 | -- ^ keyword.operator.pipe.haskell
59 |
60 | data D3 = C5 { f5 :: T5, g5 :: T5 } | C6 T6
61 | -- ^^^^ keyword.other.data.haskell
62 | -- ^ keyword.operator.eq.haskell
63 | -- ^^ ^^ variable.other.member.definition.haskell
64 | -- ^^ ^^ ^^ storage.type.haskell
65 | -- ^ keyword.operator.pipe.haskell
66 | -- ^^ ^^ constant.other.haskell
67 | | C7 { f7 :: T7 }
68 | -- ^ keyword.operator.pipe.haskell
69 | -- ^^ variable.other.member.definition.haskell
70 | -- ^^ storage.type.haskell
71 |
--------------------------------------------------------------------------------
/test/tickets/T0182.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Prefix symbolic data constructors"
2 |
3 | data Prop = None -- ^ @_@
4 | -- ^^^^ storage.type.haskell
5 | -- ^ keyword.operator.eq.haskell
6 | -- ^^^^ constant.other.haskell
7 | -- ^^^^^^^^ comment.line.documentation.haskell
8 | | T -- ^ True
9 | -- ^ keyword.operator.pipe.haskell
10 | -- ^ constant.other.haskell
11 | -- ^^^^^^^^^ comment.line.documentation.haskell
12 | | F -- ^ False
13 | -- ^ keyword.operator.pipe.haskell
14 | -- ^ constant.other.haskell
15 | -- ^^^^^^^^^^ comment.line.documentation.haskell
16 | | Atom String -- ^ prop
17 | -- ^ keyword.operator.pipe.haskell
18 | -- ^^^^ constant.other.haskell
19 | -- ^^^^^^ storage.type.haskell
20 | -- ^^^^^^^^^ comment.line.documentation.haskell
21 | | Not Prop -- ^ negate
22 | -- ^ keyword.operator.pipe.haskell
23 | -- ^^^ constant.other.haskell
24 | -- ^^^^ storage.type.haskell
25 | -- ^^^^^^^^^^^ comment.line.documentation.haskell
26 | | (:/\) Prop Prop -- ^ and
27 | -- ^ keyword.operator.pipe.haskell
28 | -- ^^^ constant.other.operator.prefix.haskell
29 | -- ^^^^ ^^^^ storage.type.haskell
30 | -- ^^^^^^^^ comment.line.documentation.haskell
31 | | (:\/) Prop Prop -- ^ or
32 | -- ^ keyword.operator.pipe.haskell
33 | -- ^^^ constant.other.operator.prefix.haskell
34 | -- ^^^^ ^^^^ storage.type.haskell
35 | -- ^^^^^^^ comment.line.documentation.haskell
36 | | (:->) Prop Prop -- ^ imply
37 | -- ^ keyword.operator.pipe.haskell
38 | -- ^^^ constant.other.operator.prefix.haskell
39 | -- ^^^^ ^^^^ storage.type.haskell
40 | -- ^^^^^^^^^^ comment.line.documentation.haskell
41 | | (:<->) Prop Prop -- ^ <->
42 | -- ^ keyword.operator.pipe.haskell
43 | -- ^^^^ constant.other.operator.prefix.haskell
44 | -- ^^^^ ^^^^ storage.type.haskell
45 | -- ^^^^^^^^ comment.line.documentation.haskell
46 |
--------------------------------------------------------------------------------
/test/tests/OverloadedLabels.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "OverloadedLabels"
2 |
3 |
4 | document = #html [#head [#title [get #title page]], #body [#p ["x=1"] ["Hello!"]]]
5 | -- ^ ^ ^ ^ ^ ^ keyword.operator.prefix.hash.haskell
6 | -- ^^^^^ ^^^^^ ^^^^^^ ^^^^^^ ^^^^^ ^^ entity.name.label.haskell
7 | where page = (#title := "something")
8 | -- ^ keyword.operator.prefix.hash.haskell
9 | -- ^^^^^^ entity.name.label.haskell
10 |
11 | test #a
12 | -- ^ keyword.operator.prefix.hash.haskell
13 | -- ^^ entity.name.label.haskell
14 | test #number17
15 | -- ^ keyword.operator.prefix.hash.haskell
16 | -- ^^^^^^^^^ entity.name.label.haskell
17 | test #do
18 | -- ^ keyword.operator.prefix.hash.haskell
19 | -- ^^^ entity.name.label.haskell
20 | test #type
21 | -- ^ keyword.operator.prefix.hash.haskell
22 | -- ^^^^^ entity.name.label.haskell
23 | test #Foo
24 | -- ^ keyword.operator.prefix.hash.haskell
25 | -- ^^^^ entity.name.label.haskell
26 | test #"Foo"
27 | -- ^ keyword.operator.prefix.hash.haskell
28 | -- ^^^^^^ entity.name.label.haskell
29 | test #3
30 | -- ^ keyword.operator.prefix.hash.haskell
31 | -- ^^ entity.name.label.haskell
32 | test #"3"
33 | -- ^ keyword.operator.prefix.hash.haskell
34 | -- ^^^^ entity.name.label.haskell
35 | test #199.4
36 | -- ^ keyword.operator.prefix.hash.haskell
37 | -- ^^^^^^ entity.name.label.haskell
38 | test #17a23b
39 | -- ^ keyword.operator.prefix.hash.haskell
40 | -- ^^^^^^^ entity.name.label.haskell
41 | test #"The quick brown fox"
42 | -- ^ keyword.operator.prefix.hash.haskell
43 | -- ^^^^^^^^^^^^^^^^^^^^^^ entity.name.label.haskell
44 | test #f'a'
45 | -- ^ keyword.operator.prefix.hash.haskell
46 | -- ^^^^^ entity.name.label.haskell
47 | test #'a'
48 | -- ^ keyword.operator.prefix.hash.haskell
49 | -- ^^^^ entity.name.label.haskell
50 | test #":"
51 | -- ^ keyword.operator.prefix.hash.haskell
52 | -- ^^^^ entity.name.label.haskell
53 | test #'
54 | -- ^ keyword.operator.prefix.hash.haskell
55 | -- ^^ entity.name.label.haskell
56 | test #"\""
57 | -- ^ keyword.operator.prefix.hash.haskell
58 | -- ^^^^^ entity.name.label.haskell
--------------------------------------------------------------------------------
/test/tickets/T0132.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Symbolic type constructors and operators"
2 |
3 | data C a b = C a b
4 | -- <---- keyword.other.data.haskell
5 | -- ^ storage.type.haskell
6 | -- ^ constant.other.haskell
7 |
8 | data a `D` b = a `D` b
9 | -- <---- keyword.other.data.haskell
10 | -- ^ storage.type.infix.haskell
11 | -- ^ constant.other.infix.haskell
12 |
13 | data a `E` b where
14 | -- <---- keyword.other.data.haskell
15 | -- ^ storage.type.infix.haskell
16 |
17 | data (:>) a b = (:>) a b
18 | -- <---- keyword.other.data.haskell
19 | -- ^^ storage.type.operator.haskell
20 | -- ^^ constant.other.operator.prefix.haskell
21 |
22 | data a :< b = a :< b
23 | -- <---- keyword.other.data.haskell
24 | -- ^^ storage.type.operator.infix.haskell
25 | -- ^^ constant.other.operator.infix.haskell
26 | -- ^^ ^^ - keyword.operator.haskell
27 | -- ^^ ^^ - keyword.operator.infix.haskell
28 |
29 | data a := b = a := b
30 | -- <---- keyword.other.data.haskell
31 | -- ^^ storage.type.operator.infix.haskell
32 | -- ^^ constant.other.operator.infix.haskell
33 | -- ^^ ^^ - keyword.operator.haskell
34 | -- ^^ ^^ - keyword.operator.infix.haskell
35 |
36 | data (:<>) a b where
37 | -- <---- keyword.other.data.haskell
38 | (:<>) :: a -> b -> (:<>) a b
39 | -- ^^^ constant.other.operator.prefix.haskell
40 | -- ^^^ storage.type.operator.haskell
41 |
42 | data a :>< b where
43 | -- <---- keyword.other.data.haskell
44 | -- ^^^ storage.type.operator.infix.haskell
45 |
46 |
47 | type F a b = C a b
48 | -- <---- keyword.other.type.haskell
49 | -- ^ ^ storage.type.haskell
50 |
51 | type a `G` b = a `D` b
52 | -- <---- keyword.other.type.haskell
53 | -- ^ ^ storage.type.infix.haskell
54 |
55 | type (<<) a b = a <> b
56 | -- <---- keyword.other.type.haskell
57 | -- ^^ storage.type.operator.haskell
58 | -- ^^ storage.type.operator.infix.haskell
59 |
60 | type (:>>) a b = a :> b
61 | -- <---- keyword.other.type.haskell
62 | -- ^^^ storage.type.operator.haskell
63 | -- ^^ storage.type.operator.infix.haskell
64 |
65 | type a :<< b = a :< b
66 | -- <---- keyword.other.type.haskell
67 | -- ^^^ ^^ storage.type.operator.infix.haskell
68 |
69 | type a :== b = a := b
70 | -- <---- keyword.other.type.haskell
71 | -- ^^^ ^^ storage.type.operator.infix.haskell
72 | -- ^^^ ^^ - keyword.operator.haskell
73 |
--------------------------------------------------------------------------------
/test/tickets/T0156.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Non keywords"
2 |
3 | patternFoo :: A
4 | -- <------- - keyword.other.pattern.haskell
5 | patternFoo = A
6 | -- <------- - keyword.other.pattern.haskell
7 |
8 | typeFoo :: A
9 | -- <---- - keyword.other.type.haskell
10 | typeFoo = A
11 | -- <---- - keyword.other.type.haskell
12 |
13 | dataFoo :: A
14 | -- <---- - keyword.other.data.haskell
15 | dataFoo = A
16 | -- <---- - keyword.other.data.haskell
17 |
18 | newtypeFoo :: A
19 | -- <------- - keyword.other.newtype.haskell
20 | newtypeFoo = A
21 | -- <------- - keyword.other.newtype.haskell
22 |
23 | foreignFoo :: A
24 | -- <------- - keyword.other.foreign.haskell
25 | foreignFoo = A
26 | -- <------- - keyword.other.foreign.haskell
27 |
28 | moduleFoo :: A
29 | -- <------ - keyword.other.module.haskell
30 | moduleFoo = A
31 | -- <------ - keyword.other.module.haskell
32 |
33 | classFoo :: A
34 | -- <----- - keyword.other.class.haskell
35 | classFoo = A
36 | -- <----- - keyword.other.class.haskell
37 |
38 | instanceFoo :: A
39 | -- <-------- - keyword.other.instance.haskell
40 | instanceFoo = A
41 | -- <-------- - keyword.other.instance.haskell
42 |
43 | importFoo :: A
44 | -- <------ - keyword.other.import.haskell
45 | importFoo = A
46 | -- <------ - keyword.other.import.haskell
47 |
48 | exportFoo :: A
49 | -- <------ - keyword.other.export.haskell
50 | exportFoo = A
51 | -- <------ - keyword.other.export.haskell
52 |
53 | whereFoo :: A
54 | -- <----- - keyword.other.where.haskell
55 | whereFoo = A
56 | -- <----- - keyword.other.where.haskell
57 |
58 | derivingFoo :: A
59 | -- <-------- - keyword.other.deriving.haskell
60 | derivingFoo = A
61 | -- <-------- - keyword.other.eriving.haskell
62 |
63 | viaFoo :: A
64 | -- <--- - keyword.other.deriving-strategy.via.haskell
65 | viaFoo = A
66 | -- <--- - keyword.other.deriving-strategy.via.haskell
67 |
68 | defaultFoo :: A
69 | -- <------- - keyword.other.default.haskell
70 | defaultFoo = A
71 | -- <------- - keyword.other.default.haskell
72 |
73 | letFoo :: A
74 | -- <--- - keyword.other.let.haskell
75 | letFoo = A
76 | -- <--- - keyword.other.let.haskell
77 |
78 | inFoo :: A
79 | -- <-- - keyword.other.in.haskell
80 | inFoo = A
81 | -- <-- - keyword.other.in.haskell
82 |
83 | doFoo :: A
84 | -- <-- - keyword.other.do.haskell
85 | doFoo = A
86 | -- <-- - keyword.other.do.haskell
87 |
88 | forallFoo :: forallFoo A
89 | -- <------ ^^^^^^ - keyword.other.forall.haskell
90 | -- ^^^^^^^^^ variable.other.generic-type.haskell
91 | forallFoo = A
92 | -- <------ - keyword.other.forall.haskell
93 |
--------------------------------------------------------------------------------
/test/tickets/T0072b.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Deriving via and deriving strategies"
2 |
3 | deriving via (A b c) instance C a
4 | -- <------- keyword.other.deriving.haskell
5 | -- ^^^ keyword.other.deriving.strategy.via.haskell
6 | -- ^^^^^^^^ keyword.other.instance.haskell
7 | -- ^ ^ storage.type.haskell
8 | -- ^ ^ ^ variable.other.generic-type.haskell
9 |
10 | deriving via Base a instance C ( Total a )
11 | -- <------- keyword.other.deriving.haskell
12 | -- ^^^ keyword.other.deriving.strategy.via.haskell
13 | -- ^^^^^^^^ keyword.other.instance.haskell
14 | -- ^^^^ ^ ^^^^^ storage.type.haskell
15 | -- ^ ^ variable.other.generic-type.haskell
16 |
17 | deriving via '(F A, B) instance R '(A, G B)
18 | -- <------- keyword.other.deriving.haskell
19 | -- ^^^ keyword.other.deriving.strategy.via.haskell
20 | -- ^^^^^^^^ keyword.other.instance.haskell
21 | -- ^ ^ ^ ^ ^ ^ ^ storage.type.haskell
22 |
23 |
24 | data B = B
25 | deriving A via B
26 | -- ^^^^^^^^ keyword.other.deriving.haskell
27 | -- ^^^ keyword.other.deriving.strategy.via.haskell
28 | -- ^ ^ storage.type.haskell
29 | deriving stock ( Eq, Generic )
30 | -- ^^^^^^^^ keyword.other.deriving.haskell
31 | -- ^^^^^ keyword.other.deriving.strategy.stock.haskell
32 | -- ^^ ^^^^^^^ storage.type.haskell
33 | deriving anyclass NFData
34 | -- ^^^^^^^^ keyword.other.deriving.haskell
35 | -- ^^^^^^^^ keyword.other.deriving.strategy.anyclass.haskell
36 | -- ^^^^^^ storage.type.haskell
37 |
38 | newtype N a = MkN a
39 | deriving stock instance Show ( N Int )
40 | -- <------- keyword.other.deriving.haskell
41 | -- ^^^^^ keyword.other.deriving.strategy.stock.haskell
42 | -- ^^^^^^^^ keyword.other.instance.haskell
43 | -- ^^^^ storage.type.haskell
44 | deriving newtype instance Eq ( N Int )
45 | -- <------- keyword.other.deriving.haskell
46 | -- ^^^^^^^ keyword.other.deriving.strategy.newtype.haskell
47 | -- ^^^^^^^^ keyword.other.instance.haskell
48 | -- ^^ storage.type.haskell
49 |
50 | newtype StateMonad b c r = StateMonad (StateT (MyState (Something b c) b) IO r)
51 | deriving (MonadState (MyState (Something b c) b), MonadIO, Monad)
52 | -- ^^^^^^^^ keyword.other.deriving.haskell
53 | -- ^^^^^^^^^^ ^^^^^^^ ^^^^^ storage.type.haskell
54 | -- ^ ^ ^ variable.other.generic-type.haskell
--------------------------------------------------------------------------------
/test/tests/Haddocks.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Haddock documentation"
2 |
3 | {-# OPTIONS_HADDOCK ignore-exports #-}
4 | -- ^^^^^^^^^^^^^^^ keyword.other.preprocessor.haskell
5 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell
6 |
7 |
8 | -- | Doc
9 | -- ^^^ comment.block.documentation.haskell
10 |
11 | {-| doc
12 | -- ^^^ comment.block.documentation.haskell
13 | doc
14 | -- ^^^ comment.block.documentation.haskell
15 | doc -}
16 | -- ^^^ comment.block.documentation.haskell
17 |
18 | {- | also doc -}
19 | -- ^^^^^^^^^^^^^^^^ comment.block.documentation.haskell
20 |
21 | -- | docs
22 | -- ^^^^^^ comment.block.documentation.haskell
23 | -- $ docs
24 | -- ^^^^^^ comment.block.documentation.haskell
25 | -- ^ docs
26 | -- ^^^^^^ comment.block.documentation.haskell
27 | -- * docs
28 | -- ^^^^^^ comment.block.documentation.haskell
29 | a --| notDocs
30 | -- ^^^^^^^^^^^^^ - comment.block.documentation.haskell
31 | a --$ notDocs
32 | -- ^^^^^^^^^^^^^ - comment.block.documentation.haskell
33 | a --^ notDocs
34 | -- ^^^^^^^^^^^^^ - comment.block.documentation.haskell
35 | a --* notDocs
36 | -- ^^^^^^^^^^^^^ - comment.block.documentation.haskell
37 | -- | notDocs
38 | -- ^^^^^^^^^ - comment.block.documentation.haskell
39 | -- $ notDocs
40 | -- ^^^^^^^^^ - comment.block.documentation.haskell
41 | -- ^ notDocs
42 | -- ^^^^^^^^^ - comment.block.documentation.haskell
43 | -- * notDocs
44 | -- ^^^^^^^^^ - comment.block.documentation.haskell
45 | {-| docs -}
46 | -- ^^^^^^^^^^^ comment.block.documentation.haskell
47 | {-$ docs -}
48 | -- ^^^^^^^^^^^ comment.block.documentation.haskell
49 | {-^ docs -}
50 | -- ^^^^^^^^^^^ comment.block.documentation.haskell
51 | {-* docs -}
52 | -- ^^^^^^^^^^^ comment.block.documentation.haskell
53 | {- | docs -}
54 | -- ^^^^^^^^^^^^ comment.block.documentation.haskell
55 | {- $ docs -}
56 | -- ^^^^^^^^^^^^ comment.block.documentation.haskell
57 | {- ^ docs -}
58 | -- ^^^^^^^^^^^^ comment.block.documentation.haskell
59 | {- * docs -}
60 | -- ^^^^^^^^^^^^ comment.block.documentation.haskell
61 |
62 | -- | docs
63 | -- ^^^^^^^^^ comment.block.documentation.haskell
64 | -- continuing docs
65 | -- ^^^^^^^^^^^^^^^^^^ comment.block.documentation.haskell
66 | -- still docs
67 | -- ^^^^^^^^^^^^^ comment.block.documentation.haskell
68 | -- no longer docs
69 | -- ^^^^^^^^^^^^^^ - comment.block.documentation.haskell
70 |
71 | g :: a -- ^ doc
72 | -- ^^^ comment.line.documentation.haskell
73 | -> b --^ notDoc
74 | -- ^^^^^^^^^^^ - comment.line.documentation.haskell comment.block.documentation.haskell
75 | -> c
76 |
--------------------------------------------------------------------------------
/syntaxes/haddock.YAML-tmLanguage:
--------------------------------------------------------------------------------
1 | fileTypes: []
2 | name: Haddock
3 | patterns: []
4 | repository:
5 | module_description:
6 | match: |
7 | (?x)
8 | ^\s*(?:--)?\s*
9 | ( Module | Description | Copyright | Maintainer | Stability
10 | | License | Portability
11 | )\s*(:)'
12 | captures:
13 | '1': {name: keyword.other.haddock}
14 | '2': {name: keyword.operator.haddock}
15 | list:
16 | match: '^\s*(?:--\s+)?([-*])\s'
17 | captures:
18 | '1': {name: punctuation.list.begin.haddock}
19 | enumeration:
20 | match: '^\s*(?:--\s+)?(\(\d\)|\d\.)\s'
21 | captures:
22 | '1': {name: punctuation.list.begin.haddock}
23 | definition:
24 | match: '^\s*(?:--\s+)?(\[.*?\]:)\s'
25 | captures:
26 | '1': {name: markup.list.definition.haddock}
27 | markup:
28 | patterns:
29 | - include: '#italic'
30 | - include: '#bold'
31 | - include: '#ref'
32 | birdtracks:
33 | begin: '^(\s*(?:--\s+)?)>'
34 | end: '-}|^(?!\1>)'
35 | patterns:
36 | - include: source.haskell
37 | fenced_code:
38 | begin: '@'
39 | end: '@|-}'
40 | patterns:
41 | - include: '#markup'
42 | example:
43 | match: '^\s*(?:--\s+)?(>>>)(.*)$'
44 | captures:
45 | '1': {name: markup.raw}
46 | '2': { include: source.haskell }
47 | prop:
48 | match: '^\s*(?:--\s+)?(prop>)(.*)$'
49 | captures:
50 | '1': {name: markup.raw}
51 | '2': { include: source.haskell }
52 | ref:
53 | patterns:
54 | - match: '(?<=\s)[''`]([\w_\p{Lt}][\w_\p{Lt}\p{Nd}''])[''`](?=\s|$)'
55 | captures:
56 | '1': {name: markup.underline.link.ref.haddock}
57 | - match: '(?<=\s)"(\p{Lu}[\w_\p{Lt}\p{Nd}''])"(?=\s|$)'
58 | captures:
59 | '1': {name: markup.underline.link.ref.module.haddock}
60 |
61 | italic:
62 | begin: '(?'
76 | name: markup.underline.link.haddock
77 | - match: '!?\[(.*?)\]\((.*?)\)'
78 | captures:
79 | '1': {name: string.other.link.title.haddock}
80 | '2': {name: markup.underline.link.haddock}
81 |
82 | anchor:
83 | match: '\#[\w]+\#|"\w+#\w+"'
84 | name: string.other.anchor.haddock
85 |
86 | headings:
87 | match: '^\s*(?:--\s+)?=+(.+)$'
88 | name: markup.heading.haddock
89 | captures:
90 | '1': {name: punctuation.definition.heading.haddock}
91 | '2':
92 | name: entity.name.section.haddock
93 | patterns:
94 | include: '#markup'
95 |
96 | scopeName: source.haddock
97 |
--------------------------------------------------------------------------------
/test/tests/GADTs.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "GADTs"
2 |
3 | data G :: a -> (b :: B) -> c -> Type where
4 | -- ^^^^ keyword.other.data.haskell
5 | -- ^^ ^^ keyword.operator.double-colon.haskell
6 | -- ^ ^ ^ variable.other.generic-type.haskell
7 | -- ^^ ^^ ^^ keyword.operator.arrow.haskell
8 | -- ^ ^ ^^^^ storage.type.haskell
9 | -- ^^^^^^ keyword.other.where.haskell
10 | A :: G A b c
11 | -- ^ constant.other.haskell
12 | -- ^^ keyword.operator.double-colon.haskell
13 | -- ^ ^ storage.type.haskell
14 | -- ^ ^ variable.other.generic-type.haskell
15 | B :: a -> b -> G a B C
16 | -- ^ constant.other.haskell
17 | -- ^^ keyword.operator.double-colon.haskell
18 | -- ^ ^ ^ variable.other.generic-type.haskell
19 | -- ^ ^ ^ storage.type.haskell
20 |
21 | (:&) :: G A B C
22 | -- ^^ constant.other.operator.prefix.haskell
23 | -- ^^ keyword.operator.double-colon.haskell
24 | -- ^ ^ ^ ^ storage.type.haskell
25 |
26 |
27 | data (a :: A) `G` (c :: C) :: Type where
28 | -- ^^^^ keyword.other.data.haskell
29 | -- ^ ^ variable.other.generic-type.haskell
30 | -- ^ storage.type.infix.haskell
31 | -- ^^ ^^ ^^ keyword.operator.double-colon.haskell
32 | -- ^ ^ ^^^^ storage.type.haskell
33 | -- ^^^^^^ keyword.other.where.haskell
34 |
35 | data (:&) a b where
36 | -- ^^^^ keyword.other.data.haskell
37 | -- ^^ storage.type.operator.haskell
38 | -- ^ ^ variable.other.generic-type.haskell
39 | -- ^^^^^^ keyword.other.where.haskell
40 |
41 | data (:&) :: a -> b -> Type where
42 | -- ^^^^ keyword.other.data.haskell
43 | -- ^^ storage.type.operator.haskell
44 | -- ^^ keyword.operator.double-colon.haskell
45 | -- ^ ^ variable.other.generic-type.haskell
46 | -- ^^ ^^ keyword.operator.arrow.haskell
47 | -- ^^^^ storage.type.haskell
48 | -- ^^^^^^ keyword.other.where.haskell
49 |
50 |
51 | data (a :: A) :& (b :: B) :: Type where
52 | -- ^^^^ keyword.other.data.haskell
53 | -- ^^ storage.type.operator.infix.haskell
54 | -- ^ ^ variable.other.generic-type.haskell
55 | -- ^^ ^^ ^^ keyword.operator.double-colon.haskell
56 | -- ^ ^ ^^^^ storage.type.haskell
57 | -- ^^^^^^ keyword.other.where.haskell
58 |
59 | data a :& b where
60 | -- ^^^^ keyword.other.data.haskell
61 | -- ^^ storage.type.operator.infix.haskell
62 | -- ^ ^ variable.other.generic-type.haskell
63 | -- ^^^^^^ keyword.other.where.haskell
64 |
--------------------------------------------------------------------------------
/syntaxes/cabal.YAML-tmLanguage:
--------------------------------------------------------------------------------
1 | fileTypes:
2 | - cabal
3 | name: Cabal
4 | patterns:
5 | - name: keyword.other.cabal
6 | match: |
7 | (?ix)(\n|^)
8 | ( name
9 | | version
10 | | cabal-version
11 | | build-type
12 | | license(-file)?
13 | | copyright
14 | | author
15 | | maintainer
16 | | stability
17 | | homepage
18 | | bug-reports
19 | | package-url
20 | | synopsis
21 | | data-(files|dir)
22 | | description
23 | | category
24 | | extra-(source|doc|tmp)-files
25 | | tested-with
26 | ):
27 | - name: keyword.other.cabal
28 | match: |
29 | (?ix)^[ \t]+
30 | ( (build(-tool)?|pkgconfig|setup)-depends
31 | | (hs-source|include|extra-(lib|frameworks))-dirs
32 | | ((other|default)-)?extensions
33 | | build-tools
34 | | buildable
35 | | ((install|autogen)-)?includes
36 | | (c(xx)?|js)-sources
37 | | extra-
38 | ( ((ghci|bundled)-)?libraries
39 | | (dynamic-)?library-flavours
40 | )
41 | | (cmm|cxx|cc|cpp|ld|ghc(-(prof|shared))?)-options
42 | | (asm|cmm)-(sources|options)
43 | | other-languages
44 | | default-language
45 | | frameworks
46 | | default
47 | | manual
48 | | location
49 | | branch
50 | | tag
51 | | subdir
52 | | exposed(-modules)?
53 | | (other|virtual|autogen|reexported)-modules
54 | | visibility
55 | | main-is
56 | | type
57 | | test-module
58 | | description
59 | | mixins
60 | | import
61 | | signatures
62 | | scope
63 | | lib-version-(version|linux)
64 | | mod-def-file
65 | | options
66 | | x-\w[1-9\w_-]*
67 | ):
68 | - name: keyword.operator.cabal
69 | match: '(==|>=|<=|<|>|^>=|\|\||&&|!)'
70 | - name: constant.numeric.cabal
71 | match: '(?<=[^\w])\d+(\.\d+)*(\.\*)?'
72 | - name: markup.underline.link.cabal
73 | match: '\w+:/(/[\w._\-\d%])+(\?[\w.+_\-\d%]+)(&[\w._+\-\d%]+)*'
74 | - name: entity.name.section.cabal
75 | match: |
76 | ^(?ix:
77 | ( library
78 | | custom-setup
79 | )
80 | )$
81 | - match: |
82 | ^(?ix:
83 | ( executable
84 | | flag
85 | | test-suite
86 | | benchmark
87 | | common
88 | | source-repository
89 | | library
90 | | foreign-library
91 | )
92 | )( |\t)+([\w\-_]+)$
93 | captures:
94 | '1': {name: entity.name.section.cabal}
95 | '3': {name: entity.name.function.cabal}
96 | - name: keyword.control.cabal
97 | match: '^[ \t]*(if|elif|else)'
98 | - name: comment.line.double-dash
99 | match: '^\s*--.*$'
100 | scopeName: source.cabal
101 | uuid: 5eb56f02-df11-40b2-b6d5-fa444522416c
102 |
--------------------------------------------------------------------------------
/scope-lists/refresh.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env stack
2 | -- stack script --resolver lts-15.12 --package aeson --package yaml --package filepath --package directory --package unordered-containers --package text
3 |
4 | {-
5 | This file is used to generate a database of scope keys used in
6 | -}
7 |
8 | {-# LANGUAGE LambdaCase, OverloadedStrings, GeneralizedNewtypeDeriving, RecordWildCards #-}
9 |
10 | import Data.Yaml
11 | import System.Environment
12 | import System.FilePath
13 | import System.Directory
14 | import qualified Data.Text as T
15 | import qualified Data.Text.IO as T
16 | import qualified Data.HashMap.Strict as M
17 | import qualified Data.HashSet as S
18 | import Data.Foldable (toList)
19 | import Data.Maybe
20 | import Data.List (sort)
21 |
22 | newtype Names = Names { names :: S.HashSet T.Text }
23 | deriving (Monoid, Semigroup)
24 |
25 | add :: T.Text -> Names -> Names
26 | add n = Names . S.insert n . names
27 |
28 | instance FromJSON Names where
29 | parseJSON = \case
30 | Object o -> do
31 | new <- o .:? "name"
32 | recursed <- mconcat <$> mapM parseJSON (M.elems o)
33 | pure $ maybe id add new recursed
34 | Array vs -> mconcat . toList <$> traverse parseJSON vs
35 | _ -> pure mempty
36 |
37 | data Info = Info { iname :: T.Text, idesc :: Maybe T.Text, iexample :: Maybe T.Text, ihide :: Bool }
38 |
39 | instance FromJSON Info where
40 | parseJSON = withObject "Info must be an object" $ \o ->
41 | Info <$> o .: "scope" <*> o.:? "description" <*> o .:? "example" <*> o .:? "hide" .!= False
42 |
43 | instance ToJSON Info where
44 | toJSON Info{..} = object $
45 | "description" .?= idesc $ "example" .?= iexample $ "hide" .?= (if ihide then Just ihide else Nothing) $ ["scope" .= iname]
46 | where
47 | _ .?= Nothing = id
48 | a .?= Just b = (a .= b : )
49 |
50 | toInfo :: Names -> [Info]
51 | toInfo = map (\name -> Info name Nothing Nothing False) . sort . toList . names
52 |
53 | toNames :: [Info] -> Names
54 | toNames = Names . S.fromList . map iname
55 |
56 | mergeInfo :: [Info] -> Names -> [Info]
57 | mergeInfo ext (Names n) = ext <> toInfo (Names $ n `S.difference` names (toNames ext))
58 |
59 | toMarkdown :: [Info] -> T.Text
60 | toMarkdown info = T.unlines $
61 | "| Scope Name | Description | Example |"
62 | : "|-|-|-|"
63 | : map (\Info{..} -> "| " <> iname <> " | " <> fromMaybe "" idesc <> " | " <> fromMaybe "" iexample <> " |") ( filter (not . ihide) info)
64 |
65 | main =
66 | getArgs >>= \case
67 | ["db",target, out] -> refreshDb target out
68 | ["md", target, out] -> makeMarkdown target out
69 |
70 | where
71 | refreshDb syntax outFile = do
72 | fromGrammar <- decodeFileThrow syntax
73 | old <-
74 | doesFileExist outFile >>= \case
75 | True -> Just <$> decodeFileThrow outFile
76 | _ -> pure Nothing
77 |
78 | encodeFile outFile $ maybe toInfo mergeInfo old fromGrammar
79 | makeMarkdown db md = decodeFileThrow db >>= T.writeFile md . toMarkdown
80 |
--------------------------------------------------------------------------------
/test/tests/MultilineDeriving.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Multiline deriving"
2 |
3 |
4 | deriving stock instance
5 | -- ^^^^^^^^ keyword.other.deriving.haskell
6 | -- ^^^^^ keyword.other.deriving.strategy.stock.haskell
7 | -- ^^^^^^^^ keyword.other.instance.haskell
8 | ( A b c
9 | -- ^ storage.type.haskell
10 | , D e f
11 | -- ^ ^ variable.other.generic-type.haskell
12 | )
13 | => C b c e f
14 | -- ^^ keyword.operator.big-arrow.haskell
15 | -- ^ storage.type.haskell
16 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
17 |
18 | deriving anyclass
19 | -- ^^^^^^^^ keyword.other.deriving.haskell
20 | -- ^^^^^^^^ keyword.other.deriving.strategy.anyclass.haskell
21 | instance
22 | -- ^^^^^^^^ keyword.other.instance.haskell
23 | ( A b c
24 | -- ^ storage.type.haskell
25 | , D e f
26 | -- ^ ^ variable.other.generic-type.haskell
27 | )
28 | => C b c e f
29 | -- ^^ keyword.operator.big-arrow.haskell
30 | -- ^ storage.type.haskell
31 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
32 |
33 |
34 | deriving
35 | -- ^^^^^^^^ keyword.other.deriving.haskell
36 | via X y z
37 | -- ^^^ keyword.other.deriving.strategy.via.haskell
38 | -- ^ storage.type.haskell
39 | -- ^ ^ variable.other.generic-type.haskell
40 | instance
41 | -- ^^^^^^^^ keyword.other.instance.haskell
42 | ( A b c
43 | -- ^ storage.type.haskell
44 | , D e f
45 | -- ^ ^ variable.other.generic-type.haskell
46 | )
47 | => C b c e f
48 | -- ^^ keyword.operator.big-arrow.haskell
49 | -- ^ storage.type.haskell
50 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
51 |
52 |
53 | deriving
54 | -- ^^^^^^^^ keyword.other.deriving.haskell
55 | via ( X y z )
56 | -- ^^^ keyword.other.deriving.strategy.via.haskell
57 | instance
58 | -- ^^^^^^^^ keyword.other.instance.haskell
59 | ( A b c
60 | -- ^ storage.type.haskell
61 | , D e f
62 | -- ^ ^ variable.other.generic-type.haskell
63 | )
64 | => C b c e f
65 | -- ^^ keyword.operator.big-arrow.haskell
66 | -- ^ storage.type.haskell
67 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
68 |
69 |
70 | data AB = AB deriving stock Eq
71 | -- ^^^^^^^^ keyword.other.deriving.haskell
72 | -- ^^^^^ keyword.other.deriving.strategy.stock.haskell
73 | -- ^^ storage.type.haskell
74 | deriving
75 | -- ^^^^^^^^ keyword.other.deriving.haskell
76 | ( C x y z )
77 | -- ^ storage.type.haskell
78 | -- ^ ^ ^ variable.other.generic-type.haskell
79 | via
80 | -- ^^^ keyword.other.deriving.strategy.via.haskell
81 | XY
82 | -- ^^ storage.type.haskell
83 |
--------------------------------------------------------------------------------
/test/tickets/T0165.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Data constructor constraint arrow in comment"
2 |
3 | data D = C {- ( f :: X => X ) -} X
4 | -- ^ constant.other.haskell
5 | -- ^^ - keyword.operator.big-arrow.haskell
6 | -- ^^^^^^^^^^ comment.block.haskell
7 | -- ^ ^ storage.type.haskell
8 | -- ^ ^ - constant.other.haskell
9 |
10 | data D =C {- f :: X => X -} X
11 | -- ^ constant.other.haskell
12 | -- ^^ - keyword.operator.big-arrow.haskell
13 | -- ^^^^^^^^^^ comment.block.haskell
14 | -- ^ ^ storage.type.haskell
15 | -- ^ ^ - constant.other.haskell
16 |
17 | data D =C{- => X -} x => X
18 | -- ^ constant.other.haskell
19 | -- ^^ - keyword.operator.big-arrow.haskell
20 | -- ^^^^^^^^^^ comment.block.haskell
21 | -- ^ ^ storage.type.haskell
22 | -- ^ ^ - constant.other.haskell
23 |
24 | data D = C {- xxx -} => X
25 | -- ^ ^ storage.type.haskell
26 | -- ^^^^^^^^^ comment.block.haskell
27 | -- ^ constant.other.haskell
28 |
29 | data D = C-- => X
30 | -- ^ storage.type.haskell
31 | -- ^ constant.other.haskell
32 | -- ^^ - keyword.operator.big-arrow.haskell
33 | -- ^^^^^^^ comment.line.double-dash.haskell
34 | -- ^^^^^^^^^^ comment.block.haskell
35 | -- ^ - constant.other.haskell
36 |
37 | data D = C -- => X
38 | -- ^ storage.type.haskell
39 | -- ^ constant.other.haskell
40 | -- ^^ - keyword.operator.big-arrow.haskell
41 | -- ^^^^^^^ comment.line.double-dash.haskell
42 | -- ^^^^^^^^^^ comment.block.haskell
43 | -- ^ - constant.other.haskell
44 |
45 | data QCInst -- A much simplified version of ClsInst
46 | -- See Note [Quantified constraints] in GHC.Tc.Solver.Canonical
47 | = QCI { qci_ev :: CtEvidence -- Always of type forall tvs. context => ty
48 | -- ^^^ constant.other.haskell
49 | -- ^^^^^^ variable.other.member.definition.haskel
50 | -- ^^ keyword.operator.double-colon.haskell
51 | -- ^^^^^^^^^^ storage.type.haskell
52 | -- ^^ - keyword.operator.big-arrow.haskell
53 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell
54 |
55 | -- Always Given
56 | , qci_tvs :: [TcTyVar] -- The tvs
57 | -- ^^^^^^^ variable.other.member.definition.haskel
58 | , qci_pred :: TcPredType -- The ty
59 | -- ^^^^^^^^ variable.other.member.definition.haskel
60 | , qci_pend_sc :: Bool -- Same as cc_pend_sc flag in CDictCan
61 | -- ^^^^^^^^^^^ variable.other.member.definition.haskel
62 | -- Invariant: True => qci_pred is a ClassPred
63 | }
64 |
--------------------------------------------------------------------------------
/test/tests/QuasiQuotes.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Quasi quotes"
2 |
3 |
4 | [e| A + B + C |]
5 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
6 | -- ^ entity.name.quasi-quoter.haskell
7 | -- ^ ^ ^ constant.other.haskell
8 | -- ^ ^ keyword.operator.infix.haskell
9 | -- ^^ keyword.operator.quasi-quotation.end.haskell
10 | -- ^^^^^^^^^^^^^^^^ meta.quasi-quotation.haskell
11 |
12 | [|| A + B + C ||]
13 | -- ^^^ keyword.operator.quasi-quotation.begin.haskell
14 | -- ^ ^ ^ constant.other.haskell
15 | -- ^ ^ keyword.operator.infix.haskell
16 | -- ^^^ keyword.operator.quasi-quotation.end.haskell
17 | -- ^^^^^^^^^^^^^^^^^ meta.quasi-quotation.haskell
18 |
19 | [p| A |]
20 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
21 | -- ^ entity.name.quasi-quoter.haskell
22 | -- ^ constant.other.haskell
23 | -- ^^ keyword.operator.quasi-quotation.end.haskell
24 | -- ^^^^^^^^ meta.quasi-quotation.haskell
25 |
26 |
27 | [t| A -> B -> C |]
28 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
29 | -- ^ entity.name.quasi-quoter.haskell
30 | -- ^ ^ ^ storage.type.haskell
31 | -- ^^ ^^ keyword.operator.arrow.haskell
32 | -- ^^ keyword.operator.quasi-quotation.end.haskell
33 | -- ^^^^^^^^^^^^^^^^^^ meta.quasi-quotation.haskell
34 |
35 |
36 | [r|\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}|]
37 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
38 | -- ^ entity.name.quasi-quoter.haskell
39 | -- ^^ keyword.operator.quasi-quotation.end.haskell
40 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.quasi-quotation.haskell
41 |
42 |
43 | [i|| A |]
44 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
45 | -- ^ entity.name.quasi-quoter.haskell
46 | -- ^^^^ meta.quasi-quotation.haskell meta.embedded.block.i
47 | -- ^^ keyword.operator.quasi-quotation.end.haskell
48 | -- ^^^^^^^^^ meta.quasi-quotation.haskell
49 |
50 | [$html|
51 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
52 | -- ^^^^ entity.name.quasi-quoter.haskell
53 | -- ^ keyword.operator.prefix.dollar.haskell
54 | -- ^^^^^^^ meta.quasi-quotation.haskell
55 |
56 |
57 | -- ^^^^^^ meta.quasi-quotation.haskell
58 | -- ^^^^^^ meta.embedded.block.html
59 | |]
60 | -- ^^ keyword.operator.quasi-quotation.end.haskell
61 | -- ^^ meta.quasi-quotation.haskell
62 |
63 | [Mod.xml| |]
64 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
65 | -- ^^^^ entity.name.namespace.haskell
66 | -- ^^^ entity.name.quasi-quoter.haskell
67 | -- ^^ keyword.operator.quasi-quotation.end.haskell
68 | -- ^^^^^^^^^^^^^^^^^^^^ meta.quasi-quotation.haskell
69 | -- ^^^^^^^ meta.embedded.block.xml
70 |
71 | [a'|'xyz|]
72 | -- ^^ entity.name.quasi-quoter.haskell
73 | -- ^ ^ keyword.operator.quasi-quotation.begin.haskell
74 | -- ^^ keyword.operator.quasi-quotation.end.haskell
75 | -- ^^^^^^^^^^ meta.quasi-quotation.haskell
76 |
77 | [ v | v <- [0..1] ]
78 | -- ^^^^^^^^^^^^^^^^^^^ - meta.quasi-quotation.haskell
--------------------------------------------------------------------------------
/test/tickets/T0161.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Data constructor highlighting"
2 |
3 | data Foo a = (:>) a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
4 | -- ^^^^ keyword.other.data.haskell
5 | -- ^ keyword.operator.eq.haskell
6 | -- ^^ constant.other.operator.prefix.haskell
7 | -- ^ ^ ^ ^ ^ ^ ^ variable.other.generic-type.haskell
8 |
9 | data Foo a = (:>) `C` ( S, O ) deriving ( Show, Ord )
10 | -- ^^^^ keyword.other.data.haskell
11 | -- ^ variable.other.generic-type.haskell
12 | -- ^ keyword.operator.eq.haskell
13 | -- ^^ storage.type.operator.haskell
14 | -- ^^ - constant.other.operator.haskell
15 | -- ^ constant.other.infix.haskell
16 | -- ^^^^^^^^ keyword.other.deriving.haskell
17 | -- ^^^ ^ ^ ^^^^ ^^^ storage.type.haskell
18 |
19 | data Foo a = (:>) Bar a deriving ( Show, Ord )
20 | -- ^^^^ keyword.other.data.haskell
21 | -- ^ keyword.operator.eq.haskell
22 | -- ^^ constant.other.operator.prefix.haskell
23 | -- ^ ^ variable.other.generic-type.haskell
24 | -- ^^^^^^^^ keyword.other.deriving.haskell
25 | -- ^^^ ^^^ ^^^^ ^^^ storage.type.haskell
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Haskell Syntax Highlighting Support
2 |
3 |
4 | Syntax highlighting support for Haskell and associated languages (e.g. Cabal, Happy and Alex) in Visual Studio Code.
5 |
6 | ## Syntax highlighting
7 |
8 | Adds syntax highlighting support for Haskell (.hs and .lhs). This is a (now heavily) modified version of
9 | the syntax file from the [Haskell TextMate bundle](https://github.com/textmate/haskell.tmbundle).
10 | Additionally there is support for Cabal files (.cabal) via a concoction of my own.
11 |
12 | Also adds automatic indentation after `where`, `do`, `->` etc. and surrounding brackets (`[]`, `{}` etc)
13 |
14 | 
15 |
16 | 
17 |
18 | ## Bugs
19 |
20 | If you happen to notice bugs or have suggestions for improvements visit the [issue
21 | section](https://github.com/JustusAdam/language-haskell/issues) of the
22 | [repository](https://github.com/JustusAdam/language-haskell).
23 |
24 | ## Themes
25 |
26 | This extension provides TextMate scopes for use in syntax highlighting, but the colours displayed
27 | depend on the theme being used.
28 | Unfortunately many themes have incomplete support for the different TextMate scopes, and as a
29 | result different tokens can end up with identical colours.
30 |
31 | For a theme that supports all the scopes provided by this extension, see the
32 | [Groovy Lambda theme](https://github.com/sheaf/groovy-lambda).
33 |
34 | ## Theme authors
35 |
36 | I recently realized that I am woefully unaware of whether there are any themes with Haskell-specific
37 | rules and how changes to this extension affect such themes. If you are a theme author that wishes to
38 | use Haskell specific rules, or are aware of a theme with Haskell specific rules, feel free to get in
39 | touch.
40 |
41 | With version `3.0.0` some new tm scopes were added, such that now record and GADT definitions can be
42 | distinguished. Let me know if there are any questions about the scope assignment in this
43 | extension or if there are further scope assigments you'd like to see added.
44 |
45 | We now publish an automatically generated, complete list of the textmate scopes
46 | used in our grammars. You can find the lists of scopes in the
47 | [scope-lists](/scope-lists) directory.
48 |
49 | ## Contributing
50 |
51 | This project currently uses the `YAML-tmLanguage` format for language grammars (Haskell, Cabal, alex, happy, ...).
52 | The grammars can be found in the `syntaxes` directory.
53 | To generate `JSON` grammars (which is the format VS Code expects), we use the Node package `js-yaml` (requires `npx` in PATH):
54 |
55 | ```sh
56 | npx js-yaml haskell.YAML-tmLanguage > haskell.json
57 | ```
58 |
59 | For testing, we use the Node package `vscode-tmgrammar-test`. For instance, to generate/check
60 | the scopes of a Haskell source file, run:
61 |
62 | ```sh
63 | npx vscode-tmgrammar-test "-s" "source.haskell" "-g" "syntaxes/haskell.json" "-t" "myTestFile.hs"
64 | ```
65 |
66 |
67 | To run the test-suite, simply call `make test`.
68 | This will build the grammar files and run `vscode-tmgrammar-test` on all the files in the testsuite.
69 |
--------------------------------------------------------------------------------
/syntaxes/happy.YAML-tmLanguage:
--------------------------------------------------------------------------------
1 | fileTypes:
2 | - y
3 | name: Haskell Happy
4 | patterns:
5 | - include: "#comments"
6 | - include: "#blocks"
7 | - include: "#syntax"
8 | - include: "#strings"
9 | repository:
10 | block_comment:
11 | applyEndPatternLast: 1
12 | begin: "{-"
13 | captures:
14 | '0': { name: punctuation.definition.comment.happy }
15 | end: "-}"
16 | name: comment.block.happy
17 | patterns:
18 | - include: "#block_comment"
19 | comments:
20 | patterns:
21 | - name: comment.line.happy
22 | match: '\-\-.*$'
23 | - include: "#block_comment"
24 | blocks:
25 | patterns:
26 | - name: meta.embedded.block.monad.haskell
27 | begin: "{%[%^]?"
28 | beginCaptures:
29 | "0": { name: punctuation.block.monad.begin.happy }
30 | end: "}"
31 | endCaptures:
32 | "0": { name: punctuation.block.end.happy }
33 | patterns:
34 | - include: source.haskell
35 | - name: meta.embedded.block.haskell
36 | begin: "{"
37 | beginCaptures:
38 | "0": { name: punctuation.block.begin.happy }
39 | end: "}"
40 | endCaptures:
41 | "0": { name: punctuation.block.end.happy }
42 | patterns:
43 | - name: variable.parameter.happy
44 | match: \$\d+
45 | - name: variable.parameter.field.happy
46 | match: \$\$
47 | - include: source.haskell
48 | syntax:
49 | patterns:
50 | - name: entity.name.directive.happy
51 | match: \%([\p{Ll}\p{Lu}_][\p{Ll}_\p{Lu}\p{Lt}\p{Nd}\.']*)
52 | - name: constant.character.escape.hex.happy
53 | match: \\x[\da-fA-F]+
54 | - name: constant.character.escape.oct.happy
55 | match: \\o[0-7]+
56 | - name: constant.character.escape.dec.happy
57 | match: \\\d+
58 | - name: constant.character.escape.happy
59 | match: \\.
60 | - name: punctuation.bracket.happy
61 | match: "[\\[\\]]"
62 | - name: keyword.operator.happy
63 | match: "[-^=\\.*]"
64 | - name: keyword.operator.type.happy
65 | match: "::"
66 | - name: keyword.operator.rule.happy
67 | match: ":"
68 | - name: keyword.operator.alt.happy
69 | match: \|
70 | - name: keyword.operator.separator.happy
71 | match: \%\%
72 | strings:
73 | patterns:
74 | - name: string.quoted.double.happy
75 | begin: '"'
76 | beginCaptures:
77 | "0": { name: punctuation.quote.double.happy }
78 | end: '"'
79 | endCaptures:
80 | "0": { name: punctuation.quote.double.happy }
81 | patterns:
82 | - name: constant.character.escape.happy
83 | match: \\.
84 | - name: string.quoted.single.happy
85 | begin: "'"
86 | beginCaptures:
87 | "0": { name: punctuation.quote.single.happy }
88 | end: "'"
89 | endCaptures:
90 | "0": { name: punctuation.quote.single.happy }
91 | patterns:
92 | - name: constant.character.escape.happy
93 | match: \\.
94 | scopeName: source.haskell.happy
95 |
--------------------------------------------------------------------------------
/test/tests/TypeSigs.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Type signatures in various positions"
2 |
3 | f :: ( x :: Int ) -> Int
4 | -- <~~-- ^^ keyword.operator.double-colon.haskell
5 | -- ^^ keyword.operator.arrow.haskell
6 | -- ^^^ ^^^ storage.type.haskell
7 | f x = do
8 | -- ^ keyword.operator.eq.haskell
9 | let x :: Int
10 | -- ^^ keyword.operator.double-colon.haskell
11 | -- ^^^ storage.type.haskell
12 | x = A
13 | -- ^ keyword.operator.eq.haskell
14 | -- ^ constant.other.haskell
15 | let
16 | y :: Int
17 | -- ^^ keyword.operator.double-colon.haskell
18 | -- ^^^ storage.type.haskell
19 | y = A
20 | -- ^ keyword.operator.eq.haskell
21 | -- ^ constant.other.haskell
22 | z :: Int = A
23 | -- ^^ keyword.operator.double-colon.haskell
24 | -- ^^^ storage.type.haskell
25 | -- ^ keyword.operator.eq.haskell
26 | -- ^ constant.other.haskell
27 | z :: Int == A
28 | -- ^^ keyword.operator.double-colon.haskell
29 | -- ^^^ storage.type.haskell
30 | -- ^^ storage.type.operator.infix.haskell
31 | -- ^^ - keyword.operator.eq.haskell
32 | -- ^ storage.type.haskell
33 | ( w :: Int ) = A
34 | -- ^^ keyword.operator.double-colon.haskell
35 | -- ^^^ storage.type.haskell
36 | -- ^ keyword.operator.eq.haskell
37 | -- ^ constant.other.haskell
38 | x :: Int <- A
39 | -- ^^ keyword.operator.double-colon.haskell
40 | -- ^^^ storage.type.haskell
41 | -- ^^ keyword.operator.arrow.left.haskell
42 | -- ^ constant.other.haskell
43 | x :: Int <-- A
44 | -- ^^ keyword.operator.double-colon.haskell
45 | -- ^^^ storage.type.operator.infix.haskell
46 | -- ^^^ - keyword.operator.arrow.left.haskell
47 | -- ^^^ ^ storage.type.haskell
48 | --
49 | ( x :: Int ) <- A
50 | -- ^^ keyword.operator.double-colon.haskell
51 | -- ^^^ storage.type.haskell
52 | -- ^^ keyword.operator.arrow.left.haskell
53 | -- ^ constant.other.haskell
54 | case x :: Int of
55 | -- ^^ keyword.operator.double-colon.haskell
56 | -- ^^^ storage.type.haskell
57 | ( 2 :: Int ) -> A
58 | -- ^^ keyword.operator.double-colon.haskell
59 | -- ^^^ storage.type.haskell
60 | -- ^^ keyword.operator.arrow.haskell
61 | -- ^ constant.other.haskell
62 | where x :: Int
63 | -- ^^ keyword.operator.double-colon.haskell
64 | -- ^^^ storage.type.haskell
65 | x = A
66 | -- ^ keyword.operator.eq.haskell
67 | -- ^ constant.other.haskell
68 | where
69 | y :: Int
70 | -- ^^ keyword.operator.double-colon.haskell
71 | -- ^^^ storage.type.haskell
72 | y = 3
73 | -- ^ keyword.operator.eq.haskell
74 |
75 | type T ( x :: Int ) :: ( k :: D x )
76 | -- ^^ ^^ ^^ keyword.operator.double-colon.haskell
77 | -- ^ ^^^ ^ storage.type.haskell
78 | -- ^ ^ ^ variable.other.generic-type.haskell
79 | type T x = X :: D x
80 | -- ^^ keyword.operator.double-colon.haskell
81 | -- ^ ^ ^ storage.type.haskell
82 | -- ^ ^ variable.other.generic-type.haskell
83 |
--------------------------------------------------------------------------------
/test/tests/MagicHash.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Magic hash/unboxed tuples"
2 |
3 |
4 |
5 | module M ( Int#, (+#), type Word#, pattern I# ) where
6 | -- ^ ^ ^ ^ keyword.operator.postfix.hash.haskell
7 | import GHC.Exts ( Int#, (+#), type Word#, pattern I# )
8 | -- ^ ^ ^ keyword.operator.postfix.hash.haskell
9 |
10 |
11 | f :: (# Word8#, Int8#, Bool# #) -> (# Word8#, Int8#, Bool# #)
12 | -- ^ ^ ^ ^ ^ ^ keyword.operator.postfix.hash.haskell
13 | -- ^ ^ ^ ^ keyword.operator.hash.haskell
14 |
15 | f (# a, b, c #) = (# a, b, c #)
16 | -- ^ ^ ^ ^ keyword.operator.hash.haskell
17 |
18 | g :: (##)
19 | -- ^^ keyword.operator.hash.haskell
20 | -- ^^^^ support.constant.unit.unboxed.haskell
21 | g = (##)
22 | -- ^^ keyword.operator.hash.haskell
23 | -- ^^^^ constant.language.unit.unboxed.haskell
24 |
25 | a # b # c
26 | -- ^ ^ - keyword.operator.hash.haskell keyword.operator.postfix.hash.haskell
27 | -- ^ ^ keyword.operator.infix.haskell
28 |
29 | f :: A # B # c
30 | -- ^ ^ - keyword.operator.hash.haskell keyword.operator.postfix.hash.haskell
31 | -- ^ ^ storage.type.operator.infix.haskell
32 |
33 | f :: A -## b
34 | -- ^^ keyword.operator.postfix.hash.haskell
35 | -- ^ - keyword.operator.prefix.minus.haskell
36 |
37 | g = a +## b
38 | -- ^^ keyword.operator.postfix.hash.haskell
39 |
40 | f :: A ## b
41 | -- ^^ - keyword.operator.hash.haskell keyword.operator.postfix.hash.haskell
42 | -- ^^ storage.type.operator.infix.haskell
43 |
44 | g = a ## b
45 | -- ^^ - keyword.operator.hash.haskell keyword.operator.postfix.hash.haskell
46 | -- ^^ keyword.operator.infix.haskell
47 |
48 |
49 | one## :: Word8#
50 | -- ^^^^^ entity.name.function.haskell
51 | -- ^^ ^ keyword.operator.postfix.hash.haskell
52 |
53 | one## = 1##
54 | -- ^^ ^^ keyword.operator.postfix.hash.haskell
55 |
56 | foo# :: Addr#
57 | -- ^^^^ entity.name.function.haskell
58 | -- ^ ^ keyword.operator.postfix.hash.haskell
59 | foo# = "foo"#
60 | -- ^ ^ keyword.operator.postfix.hash.haskell
61 |
62 | (=#=#) :: Int# -> Int# -> Bool#
63 | -- ^^^^ entity.name.function.haskell
64 | -- ^ - keyword.operator.postfix.hash.haskell
65 | -- ^ keyword.operator.postfix.hash.haskell
66 | a =#=# b = a =#=# b
67 | -- ^ ^ - keyword.operator.postfix.hash.haskell
68 | -- ^ ^ keyword.operator.postfix.hash.haskell
69 |
70 |
71 |
72 | type family Tuple# xs = t | t -> xs where
73 | -- ^ keyword.operator.postfix.hash.haskell
74 | Tuple# '[] = (##)
75 | -- ^ keyword.operator.postfix.hash.haskell
76 | -- ^^ keyword.operator.hash.haskell
77 | Tuple# '[a] = (# a #)
78 | -- ^ keyword.operator.postfix.hash.haskell
79 | -- ^ ^ keyword.operator.hash.haskell
80 | Tuple# '[a,b] = (# a,b #)
81 | -- ^ keyword.operator.postfix.hash.haskell
82 | -- ^ ^ keyword.operator.hash.haskell
83 |
--------------------------------------------------------------------------------
/test/tickets/T0072c.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Type/data families and instances"
2 |
3 | type family CTF1 a b where
4 | -- <---- keyword.other.type.haskell
5 | -- ^^^^^^ keyword.other.family.haskell
6 | -- ^^^^ storage.type.haskell
7 | -- ^ ^ variable.other.generic-type.haskell
8 | CTF1 a b = D a
9 | -- ^^^^ ^ storage.type.haskell
10 | -- ^ ^ ^ variable.other.generic-type.haskell
11 | type family CTF2 (a :: k) :: B where
12 | -- <---- keyword.other.type.haskell
13 | -- ^^^^^^ keyword.other.family.haskell
14 | -- ^ ^ variable.other.generic-type.haskell
15 | -- ^^^^ ^ storage.type.haskell
16 |
17 | type family CTF3 (a :: A) = (r :: A) | r -> a where
18 | -- <---- keyword.other.type.haskell
19 | -- ^^^^^^ keyword.other.family.haskell
20 | -- ^ keyword.operator.eq.haskell
21 | -- ^ ^ storage.type.haskell
22 | -- ^ keyword.operator.pipe.haskell
23 | -- ^ ^ ^ ^ variable.other.generic-type.haskell
24 | -- ^^^^^ keyword.other.where.haskell
25 |
26 | type family CTF4
27 | -- <---- keyword.other.type.haskell
28 | -- ^^^^^^ keyword.other.family.haskell
29 | (a :: A)
30 | -- ^ variable.other.generic-type.haskell
31 | -- ^ storage.type.haskell
32 | (b :: B)
33 | -- ^ variable.other.generic-type.haskell
34 | -- ^ storage.type.haskell
35 | = (r :: A)
36 | -- ^ keyword.operator.eq.haskell
37 | -- ^ variable.other.generic-type.haskell
38 | -- ^ storage.type.haskell
39 | | r -> a b
40 | -- ^ ^ ^ variable.other.generic-type.haskell
41 | -- ^ keyword.operator.pipe.haskell
42 | where
43 | -- ^^^^^ keyword.other.where.haskell
44 |
45 | type family OTF a b
46 | -- <---- keyword.other.type.haskell
47 | -- ^^^^^^ keyword.other.family.haskell
48 | -- ^^^ storage.type.haskell
49 | -- ^ ^ variable.other.generic-type.haskell
50 | type instance OTF (a,a) c = (a,c)
51 | -- <---- keyword.other.type.haskell
52 | -- ^^^^^^^^ keyword.other.instance.haskell
53 | -- ^^^ storage.type.haskell
54 | -- ^ ^ ^ ^ ^ variable.other.generic-type.haskell
55 | type instance
56 | -- <---- keyword.other.type.haskell
57 | -- ^^^^^^^^ keyword.other.instance.haskell
58 | OTF (Int, Bool) = Char
59 | -- ^^^ ^^^ ^^^^ ^^^^ storage.type.haskell
60 | -- ^ keyword.operator.eq.haskell
61 |
62 | data family DF (x :: Bool)
63 | -- <---- keyword.other.data.haskell
64 | -- ^^^^^^ keyword.other.family.haskell
65 | -- ^ variable.other.generic-type.haskell
66 | -- ^^^^ storage.type.haskell
67 | newtype instance DF 'True = DCTrue Int
68 | -- <------- keyword.other.newtype.haskell
69 | -- ^^^^^^^^ keyword.other.instance.haskell
70 | -- ^^ storage.type.haskell
71 | -- ^^^^^^ constant.other.haskell
72 | -- ^^^ storage.type.haskell
73 | data instance DF 'False where
74 | -- <---- keyword.other.data.haskell
75 | -- ^^^^^^^^ keyword.other.instance.haskell
76 | -- ^^ ^^^^^ storage.type.haskell
77 | DCFalse :: Float -> DF 'False
78 | -- ^^^^^^^ constant.other.haskell
79 | -- ^^^^^ ^^ ^^^^^ storage.type.haskell
80 |
--------------------------------------------------------------------------------
/test/tests/Ticks.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Ticks in various positions"
2 |
3 |
4 | x = Tt_'_.T_'__t' T'D_'.C T_'ttt_'t_' T'x T_x T_'_
5 | -- ^^^^^^ ^^^^^^ entity.name.namespace.haskell
6 | -- ^^^^^^^ ^ ^^^^^^^^^^^ ^^^ ^^^ ^^^^ constant.other.haskell
7 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - invalid
8 | x = a `Tt_'_.T_'__t'` b `T'D_'.C` c `T_'ttt_'t_'` d `T'x` e `T_x` f `T_'_`
9 | -- ^^^^^^ ^^^^^^ entity.name.namespace.haskell
10 | -- ^^^^^^^ ^ ^^^^^^^^^^^ ^^^ ^^^ ^^^^ constant.other.haskell
11 | -- ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - entity.name.namespace.haskell constant.other.haskell
12 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - invalid
13 | x = 'T' '_'
14 | -- ^^^ ^^^ string.quoted.single.haskell
15 | -- ^^^^^^^ - invalid
16 |
17 | type T = Tt'.T_'__t' 'TD'.C 'Tt'T.T.T' T_'ttt_'t_' 'T T'x T_x T_'_
18 | -- ^^^^ ^^^^ ^^^^^^^ entity.name.namespace.haskell
19 | -- ^ ^ ^ keyword.operator.promotion.haskell
20 | -- ^^^^^^^ ^ ^^ ^^^^^^^^^^^ ^ ^^^ ^^^ ^^^^ storage.type.haskell
21 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - invalid
22 | type T = a `Tt'.T_'__t'` b '`TD'.C` c '`Tt'T.T.T'` d `T_'ttt_'t_'` e '`T` f `T'x` g `T_x` h `T_'_`
23 | -- ^^^^ ^^^^ ^^^^^^^ entity.name.namespace.haskell
24 | -- ^ ^ ^ keyword.operator.promotion.haskell
25 | -- ^^^^^^^ ^ ^^ ^^^^^^^^^^^ ^ ^^^ ^^^ ^^^^ storage.type.infix.haskell
26 | -- ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - entity.name.namespace.haskell constant.other.haskell
27 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - invalid
28 | type T = '(F, (B,G.C,'[A,B,C]))
29 | -- ^ ^ ^ ^ ^ ^ storage.type.haskell
30 | -- ^^ entity.name.namespace.haskell
31 | -- ^ ^ keyword.operator.promotion.haskell
32 |
33 | type T = '() '[]
34 | -- ^ ^ keyword.operator.promotion.haskell
35 | -- ^^ support.constant.unit.haskell
36 | -- ^^ support.constant.empty-list.haskell
37 |
38 | type T = T.'C
39 | -- ^^ - entity.name.namespace.haskell
40 | -- ^ storage.type.operator.infix.haskell
41 | -- ^ keyword.operator.promotion.haskell
42 | -- ^ ^ storage.type.haskell
43 |
44 | type T = '(:+) '(AC.:+) 'AC.:++ 'AC.++
45 | -- ^ ^ ^ keyword.operator.promotion.haskell
46 | -- ^^^ ^^^ entity.name.namespace.haskell
47 | -- ^^ ^^ storage.type.operator.haskell
48 | -- ^^^ ^^ storage.type.operator.infix.haskell
49 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - invalid
50 |
51 | type T = _t'_a'
52 | -- ^^^^^^ variable.other.generic-type.haskell
53 | -- ^^^^^^ - invalid
54 | type T = " a ' b ' c 'de' f'g''' 'a'"
55 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.haskell
56 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - invalid
57 |
58 | type T = '_'_t_a'
59 | -- ^^^ invalid
60 | type T = 'T'x
61 | -- ^^^ invalid
62 | type T = '_'
63 | -- ^^^ invalid
64 | type T = '_'
65 | -- ^^^ invalid
66 |
--------------------------------------------------------------------------------
/syntaxes/alex.YAML-tmLanguage:
--------------------------------------------------------------------------------
1 | fileTypes:
2 | - x
3 | name: Haskell Alex
4 | patterns:
5 | - include: "#comments"
6 | - include: "#blocks"
7 | - include: "#syntax"
8 | - include: "#strings"
9 | repository:
10 | block_comment:
11 | applyEndPatternLast: 1
12 | begin: "{-"
13 | captures:
14 | '0': {name: punctuation.definition.comment.alex}
15 | end: "-}"
16 | name: comment.block.alex
17 | patterns:
18 | - include: "#block_comment"
19 | comments:
20 | patterns:
21 | - name: comment.line.alex
22 | match: '\-\-.*$'
23 | - include: "#block_comment"
24 | startcode:
25 | patterns:
26 | - name: variable.other.startcode.0.alex
27 | match: '0'
28 | - name: variable.other.startcode.alex
29 | match: ([\p{Ll}\p{Lu}_][\p{Ll}_\p{Lu}\p{Lt}\p{Nd}\.']*)
30 | - name: punctuation.comma.startcode.alex
31 | match: ','
32 | blocks:
33 | patterns:
34 | - name: meta.block.startcode.alex
35 | begin: (<)([\p{Ll}_\p{Lu}\p{Lt}\p{Nd}\.'\s,]*)(>)\s*(\{)
36 | beginCaptures:
37 | "1": { name: punctuation.bracket.startcode.alex }
38 | "2":
39 | patterns:
40 | - include: '#startcode'
41 | "3": { name: punctuation.bracket.startcode.alex }
42 | "4": { name: punctuation.block.startcode.begin.alex }
43 | end: "}"
44 | endCaptures:
45 | "0": { name: punctuation.block.startcode.end.alex }
46 | patterns:
47 | - include: source.haskell.alex
48 | - name: meta.embedded.block.haskell
49 | begin: "{"
50 | beginCaptures:
51 | "0": { name: punctuation.block.begin.alex }
52 | end: "}"
53 | endCaptures:
54 | "0": { name: punctuation.block.end.alex }
55 | patterns:
56 | - include: source.haskell
57 |
58 | syntax:
59 | patterns:
60 | - name: entity.name.pragma.alex
61 | match: \%([\p{Ll}\p{Lu}_][\p{Ll}_\p{Lu}\p{Lt}\p{Nd}\.']*)
62 | - name: entity.name.macro.character-set.alex
63 | match: \$([\p{Ll}\p{Lu}_][\p{Ll}_\p{Lu}\p{Lt}\p{Nd}\.']*)
64 | - name: entity.name.macro.regular-expression.alex
65 | match: \@([\p{Ll}\p{Lu}_][\p{Ll}_\p{Lu}\p{Lt}\p{Nd}\.']*)
66 | - name: constant.character.escape.hex.alex
67 | match: \\x[\da-fA-F]+
68 | - name: constant.character.escape.oct.alex
69 | match: \\o[0-7]+
70 | - name: constant.character.escape.dec.alex
71 | match: \\\d+
72 | - name: constant.character.escape.alex
73 | match: \\.
74 | - name: punctuation.bracket.alex
75 | match: "[\\[\\]]"
76 | - name: keyword.operator.rules.alex
77 | match: :-
78 | - name: keyword.operator.alex
79 | match: "[-^=\\.*\\|]"
80 | - name: punctuation.semicolon.alex
81 | match: \;
82 | - name: meta.startcode.alex
83 | match: (<)([\p{Ll}_\p{Lu}\p{Lt}\p{Nd}\.'\s,]*)(>)
84 | captures:
85 | "1": { name: punctuation.bracket.startcode.alex }
86 | "2":
87 | patterns:
88 | - include: '#startcode'
89 | "3": { name: punctuation.bracket.startcode.alex }
90 | strings:
91 | patterns:
92 | - name: string.quoted.double.alex
93 | begin: '"'
94 | beginCaptures:
95 | "0": { name: punctuation.quote.double.alex }
96 | end: '"'
97 | endCaptures:
98 | "0": { name: punctuation.quote.double.alex }
99 | patterns:
100 | - name: constant.character.escape.alex
101 | match: \\.
102 | - name: string.quoted.single.alex
103 | begin: "'"
104 | beginCaptures:
105 | "0": { name: punctuation.quote.single.alex }
106 | end: "'"
107 | endCaptures:
108 | "0": { name: punctuation.quote.single.alex }
109 | patterns:
110 | - name: constant.character.escape.alex
111 | match: \\.
112 | scopeName: source.haskell.alex
113 |
--------------------------------------------------------------------------------
/test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | baseDir=$(dirname "$PWD")
4 | echo "Running tests from base directory $baseDir"
5 |
6 | # Arrays containing full test filepaths.
7 | named=("$PWD"/tests/*)
8 | tickets=("$PWD"/tickets/*)
9 |
10 | # Arrays containing filenames of broken tests.
11 | namedBroken=()
12 | ticketsBroken=(
13 | "T0153.hs"
14 | "T0165.hs"
15 | "T0167.hs"
16 | "T0178.hs"
17 | "T0189.y"
18 | "T230.hs"
19 | )
20 |
21 | # Colours used to display test outputs.
22 | RED='\033[0;31m'
23 | MAGENTA='\033[0;35m'
24 | YELLOW='\033[1;33m'
25 | GREEN='\033[0;32m'
26 | NC='\033[0m'
27 |
28 | # 'runTests' runs the 'vscode-tmgrammar-test' command on all test files in a directory,
29 | # reporting which tests had unexpected outcomes.
30 | #
31 | # runTests
32 | # :: [ FilePath ] -- ^ $1: array of tests to be run.
33 | # -> [ TestName ] -- ^ $2: array of filenames in this directory for tests that are expected to fail.
34 | # -> MArray s TestName -- ^ $3: array of tests that unexpectedly failed (this function appends these to the array)
35 | # -> MArray s TestName -- ^ $4: array of tests that unexpectedly passed (this function appends these to the array).
36 | # -> ST s ExitCode -- ^ Exit code: 0 if no unexpected outcomes, 1 otherwise.
37 | runTests () {
38 |
39 | local -n dir=$1
40 | local -n expectedFails=$2
41 | local -n fails=$3
42 | local -n passes=$4
43 |
44 | syntaxes=()
45 | source=""
46 |
47 | for filepath in "${dir[@]}"
48 | do
49 | file=$(basename -- "$filepath")
50 | ext="${file##*.}"
51 | name="${file%.*}"
52 |
53 | # Check whether the test is expected to fail.
54 | expectBroken=0
55 | for broken in "${expectedFails[@]}"
56 | do
57 | if [ "$broken" == "$file" ]
58 | then
59 | expectBroken=1
60 | fi
61 | done
62 |
63 | # Set the appropriate syntax file for the test.
64 | case $ext in
65 |
66 | "hs" | "hs-boot" | "hsig" )
67 | syntaxes=( "$baseDir/syntaxes/haskell.json" )
68 | ;;
69 |
70 | "cabal" )
71 | syntaxes=( "$baseDir/syntaxes/cabal.json" )
72 | ;;
73 |
74 | "lhs" )
75 | syntaxes=( "$baseDir/syntaxes/haskell.json" "$baseDir/syntaxes/literateHaskell.json" )
76 | ;;
77 |
78 | "x" )
79 | syntaxes=( "$baseDir/syntaxes/alex.json" "$baseDir/syntaxes/haskell.json" )
80 | ;;
81 |
82 | "y" )
83 | syntaxes=( "$baseDir/syntaxes/happy.json" "$baseDir/syntaxes/haskell.json" )
84 | ;;
85 |
86 | * )
87 | syntaxes=()
88 | ;;
89 |
90 | esac
91 |
92 | if [ ${#syntaxes[@]} -eq 0 ]
93 | then
94 | echo "runTests: $file has unsupported file extension '$ext', ignoring"
95 | else
96 | specifySyntaxes=""
97 | for i in ${syntaxes[*]}; do
98 | specifySyntaxes="$specifySyntaxes -g $i"
99 | done
100 | # Run the test.
101 | result=$(npx vscode-tmgrammar-test $specifySyntaxes "$filepath")
102 | # Check test result by inspecting the exit code of the previous command.
103 | status=$?
104 | if [ $status -eq 0 ]
105 | then
106 | if [ $expectBroken -eq 0 ]
107 | then
108 | echo -e "${GREEN}Pass (expected)${NC} $file"
109 | else
110 | passes+=("$name")
111 | echo -e "${MAGENTA}Pass (unexpected)${NC} $file"
112 | fi
113 | else
114 | if [ $expectBroken -eq 0 ]
115 | then
116 | fails+=("$name")
117 | echo -e "${RED}Fail (unexpected)${NC} $file"
118 | echo -e "$result"
119 | else
120 | echo -e "${YELLOW}Fail (expected)${NC} $file"
121 | fi
122 | fi
123 | fi
124 | done
125 | }
126 |
127 | # Initialise arrays of tests with unexpected results.
128 | unexpectedFails=()
129 | unexpectedPasses=()
130 |
131 | # Run the named tests (in the 'tests' folder).
132 | runTests named namedBroken unexpectedFails unexpectedPasses
133 | # Run the ticket tests (in the 'tickets' folder).
134 | runTests tickets ticketsBroken unexpectedFails unexpectedPasses
135 |
136 | # Return the appropriate exit code.
137 | if [ ${#unexpectedFails[@]} -eq 0 ] && [ ${#unexpectedPasses[@]} -eq 0 ]
138 | then
139 | # No unexpected test outcomes.
140 | exit 0
141 | else
142 | # Unexpected test outcomes.
143 | exit 1
144 | fi
145 |
--------------------------------------------------------------------------------
/test/tickets/T0044.hs:
--------------------------------------------------------------------------------
1 | -- SYNTAX TEST "source.haskell" "Foreign import/export"
2 |
3 | -- Should work for indented modules
4 |
5 | foreign import jvm "string.h strlen"
6 | -- ^^^^^^^ keyword.other.foreign.haskell
7 | -- ^^^^^^ keyword.other.import.haskell
8 | -- ^^^ keyword.other.calling-convention.jvm.haskell
9 | -- ^^^^^^^^^^^^^^^ entity.name.foreign.haskell string.quoted.double.haskell
10 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.foreign.haskell
11 | cstrlen :: Ptr CChar -> IO CSize
12 | -- ^^^^^^^ entity.name.function.haskell
13 | -- ^^ keyword.operator.double-colon.haskell
14 | -- ^^^ ^^^^ ^^ ^^^^^ storage.type.haskell
15 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.foreign.haskell
16 |
17 | foreign export stdcall "string.h strlen" foo :: Ptr CInt
18 | -- ^^^^^^^ keyword.other.foreign.haskell
19 | -- ^^^^^^ keyword.other.export.haskell
20 | -- ^^^^^^^ keyword.other.calling-convention.stdcall.haskell
21 | -- ^^^^^^^^^^^^^^^ entity.name.foreign.haskell string.quoted.double.haskell
22 | -- ^^^ entity.name.function.haskell
23 | -- ^^ keyword.operator.double-colon.haskell
24 | -- ^^^ ^^^^ storage.type.haskell
25 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export.foreign.haskell
26 |
27 | foreign import ccall safe "string.h strlen"
28 | -- <------- keyword.other.foreign.haskell
29 | -- ^^^^^^ keyword.other.import.haskell
30 | -- ^^^^^ keyword.other.calling-convention.ccall.haskell
31 | -- ^^^^ keyword.other.safety.safe.haskell
32 | -- ^^^^^^^^^^^^^^^^^ string.quoted.double.haskell
33 | -- <-------------------------------------- meta.import.foreign.haskell
34 |
35 | cstrlen :: Ptr CChar -> IO CSize
36 | -- ^^^^^^^ entity.name.function.haskell
37 | -- ^^^ ^^^^^ ^^ ^^^^^ storage.type.haskell
38 | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.foreign.haskell
39 |
40 | foreign export cplusplus "string.h strlen" foo :: Ptr CInt
41 | -- <------- keyword.other.foreign.haskell
42 | -- ^^^^^^ keyword.other.export.haskell
43 | -- ^^^^^^^^^ keyword.other.calling-convention.cplusplus.haskell
44 | -- ^^^^^^^^^^^^^^ entity.name.foreign.haskell string.quoted.double.haskell
45 | -- ^^^ entity.name.function.haskell
46 | -- ^^ keyword.operator.double-colon.haskell
47 | -- ^^^ ^^^^ storage.type.haskell
48 | -- <----------------------------------------------------------- meta.export.foreign.haskell
49 |
50 | foreign export ccall "addInt" (+) :: Int -> Int -> Int
51 | -- <------- keyword.other.foreign.haskell
52 | -- ^^^^^^ keyword.other.export.haskell
53 | -- ^^^^^ keyword.other.calling-convention.ccall.haskell
54 | -- ^^^^^^ entity.name.foreign.haskell string.quoted.double.haskell
55 | -- ^ entity.name.function.infix.haskell
56 | -- ^^ keyword.operator.double-colon.haskell
57 | -- ^^^ ^^^ ^^^ storage.type.haskell
58 | -- <---------------------------------------------------------- meta.export.foreign.haskell
59 | foreign export prim interruptible "addFloat" (+) :: Float -> Float -> Float
60 | -- <------- keyword.other.foreign.haskell
61 | -- ^^^^^^ keyword.other.export.haskell
62 | -- ^^^^^^^^^^^^^ keyword.other.safety.interruptible.haskell
63 | -- ^^^^^^^^ entity.name.foreign.haskell string.quoted.double.haskell
64 | -- ^ entity.name.function.infix.haskell
65 | -- ^^ keyword.operator.double-colon.haskell
66 | -- ^^^^^ ^^^^^ ^^^^^ storage.type.haskell
67 | -- <--------------------------------------------------------------------------- meta.export.foreign.haskell
68 |
69 |
70 |
71 | foreign export ccall safe :: Int -> Int
72 | -- ^^^^ - keyword.other.safety.safe.haskell
73 | -- ^^^^ entity.name.function.haskell
74 |
75 | foreign export ccall "unsafe" unsafe :: Int -> Int
76 | -- ^^^^^^ entity.name.foreign.haskell string.quoted.double.haskell
77 | -- ^^^^^^ - keyword.other.safety.unsafe.haskell
78 | -- ^^^^^^ entity.name.function.haskell
--------------------------------------------------------------------------------