Write parser for lens configs
This commit is contained in:
parent
6dff8afead
commit
c769528092
|
@ -1,55 +1,62 @@
|
||||||
physical
|
physical
|
||||||
block
|
block
|
||||||
0 1
|
key 0 1
|
||||||
1 0.5
|
key 1 0.5
|
||||||
2 0
|
key 2 0
|
||||||
3 0.5
|
key 3 0.5
|
||||||
4 1
|
key 4 1
|
||||||
|
end
|
||||||
|
|
||||||
block
|
block
|
||||||
place 0 0
|
place 0 0
|
||||||
place 7 0
|
place 7 0
|
||||||
|
end
|
||||||
|
|
||||||
place 0 0
|
place 0 0
|
||||||
place 0 1
|
place 0 1
|
||||||
place 0 2
|
place 0 2
|
||||||
|
|
||||||
block
|
block
|
||||||
0 0
|
key 0 0
|
||||||
1 0
|
key 1 0
|
||||||
|
end
|
||||||
|
|
||||||
place 3.5 4.5 0.2617993878 4 5
|
place 3.5 4.5 0.2617993878 4 5
|
||||||
place 6.5 4.5 -0.2617993878 8 5
|
place 6.5 4.5 -0.2617993878 8 5
|
||||||
|
|
||||||
section
|
section
|
||||||
keyboard
|
action 🟥 🌈 sticky-switch red
|
||||||
action 🟥 🌈 sticky-switch red
|
action 🟦 🌈 sticky-switch blue
|
||||||
action 🟦 🌈 sticky-switch blue
|
action 🟪 ⚔️ sticky-switch purple
|
||||||
action 🟪 ⚔️ sticky-switch purple
|
|
||||||
|
|
||||||
|
layergroup
|
||||||
layer main center
|
layer main center
|
||||||
Q W F P B J L U Y :
|
Q W F P B J L U Y :
|
||||||
A R S T G M N E I O
|
A R S T G M N E I O
|
||||||
X C D V Z K H , . '
|
X C D V Z K H , . '
|
||||||
🟥 ␣ ⇧ 🟦
|
🟥 ␣ ⇧ 🟦
|
||||||
|
end
|
||||||
|
|
||||||
layer red topright #0b00d9
|
layer red topright #0b00d9
|
||||||
1 2 3 4 ⚔️ 🏠 ⏬ ⏫ end 🗑️
|
1 2 3 4 ⚔️ ⏪ ⏬ ⏫ ⏩ 🗑️
|
||||||
5 6 7 8 ⚔️ ◄ ▼ ▲ ► ⚔️
|
5 6 7 8 ⚔️ ◄ ▼ ▲ ► ⚔️
|
||||||
9 0 ⚔️ ⚔️ ⚔️ ⚔️ ⚔️ ⚔️ ⚔️ ⚔️
|
9 0 ⚔️ ⚔️ ⚔️ ⚔️ ⚔️ ⚔️ ⚔️ ⚔️
|
||||||
⚔️ ⚔️ ⚔️ 🟪
|
⚔️ ⚔️ ⚔️ 🟪
|
||||||
|
end
|
||||||
|
|
||||||
layer blue topleft #b80034
|
layer blue topleft #b80034
|
||||||
! @ [ ( % ^ & * ~ `
|
! @ [ ( % ^ & * ~ `
|
||||||
< { ] ) ? - _ / = ;
|
< { ] ) ? - _ / = ;
|
||||||
> } $ ? ⚔️ — | \ + "
|
> } $ ? ⚔️ — | \ + "
|
||||||
🟪 ⚔️ ⚔️ ⚔️
|
🟪 ⚔️ ⚔️ ⚔️
|
||||||
|
end
|
||||||
|
|
||||||
layer purple bottomleft #660099
|
layer purple bottomleft #660099
|
||||||
f1 f2 f3 f4 f5 😱 copy ⏩ 🔊 🔆
|
f1 f2 f3 f4 f5 😱 copy ⏩ 🔊 🔆
|
||||||
f6 f7 f8 f9 f10 ↩️ 📋 ⏯️ 🔉 🔅
|
f6 f7 f8 f9 f10 ↩️ 📋 ⏯️ 🔉 🔅
|
||||||
f11 f12 f4 ⚔️ ⚔️ 🎮 ✂️ ⏪ 🔇 ⚔️
|
f11 f12 f4 ⚔️ ⚔️ 🎮 ✂️ ⏪ 🔇 ⚔️
|
||||||
⚔️ ⚔️ ⚔️ ⚔️
|
⚔️ ⚔️ ⚔️ ⚔️
|
||||||
|
end
|
||||||
|
|
||||||
section
|
section
|
||||||
columns 2
|
columns 2
|
||||||
|
|
|
@ -3,15 +3,23 @@ workspace:
|
||||||
layout-lens:
|
layout-lens:
|
||||||
path: ./
|
path: ./
|
||||||
dependencies:
|
dependencies:
|
||||||
|
- aff
|
||||||
- colors
|
- colors
|
||||||
- console
|
- console
|
||||||
|
- debug
|
||||||
- debugged
|
- debugged
|
||||||
- effect
|
- effect
|
||||||
- maybe
|
- maybe
|
||||||
|
- node-fs
|
||||||
- prelude
|
- prelude
|
||||||
|
- string-parsers
|
||||||
|
- strings
|
||||||
- tuples
|
- tuples
|
||||||
|
- unordered-collections
|
||||||
test_dependencies: []
|
test_dependencies: []
|
||||||
build_plan:
|
build_plan:
|
||||||
|
- aff
|
||||||
|
- arraybuffer-types
|
||||||
- arrays
|
- arrays
|
||||||
- bifunctors
|
- bifunctors
|
||||||
- colors
|
- colors
|
||||||
|
@ -20,6 +28,7 @@ workspace:
|
||||||
- contravariant
|
- contravariant
|
||||||
- control
|
- control
|
||||||
- datetime
|
- datetime
|
||||||
|
- debug
|
||||||
- debugged
|
- debugged
|
||||||
- distributive
|
- distributive
|
||||||
- effect
|
- effect
|
||||||
|
@ -29,20 +38,30 @@ workspace:
|
||||||
- exists
|
- exists
|
||||||
- fixed-points
|
- fixed-points
|
||||||
- foldable-traversable
|
- foldable-traversable
|
||||||
|
- foreign
|
||||||
- functions
|
- functions
|
||||||
- functors
|
- functors
|
||||||
- gen
|
- gen
|
||||||
- identity
|
- identity
|
||||||
- integers
|
- integers
|
||||||
- invariant
|
- invariant
|
||||||
|
- js-date
|
||||||
- lazy
|
- lazy
|
||||||
- lists
|
- lists
|
||||||
- maybe
|
- maybe
|
||||||
- newtype
|
- newtype
|
||||||
|
- node-buffer
|
||||||
|
- node-event-emitter
|
||||||
|
- node-fs
|
||||||
|
- node-path
|
||||||
|
- node-streams
|
||||||
- nonempty
|
- nonempty
|
||||||
|
- now
|
||||||
|
- nullable
|
||||||
- numbers
|
- numbers
|
||||||
- ordered-collections
|
- ordered-collections
|
||||||
- orders
|
- orders
|
||||||
|
- parallel
|
||||||
- partial
|
- partial
|
||||||
- prelude
|
- prelude
|
||||||
- profunctor
|
- profunctor
|
||||||
|
@ -50,6 +69,7 @@ workspace:
|
||||||
- refs
|
- refs
|
||||||
- safe-coerce
|
- safe-coerce
|
||||||
- st
|
- st
|
||||||
|
- string-parsers
|
||||||
- strings
|
- strings
|
||||||
- tailrec
|
- tailrec
|
||||||
- transformers
|
- transformers
|
||||||
|
@ -544,6 +564,33 @@ workspace:
|
||||||
git: https://github.com/mateiadrielrafael/purescript-debugged.git
|
git: https://github.com/mateiadrielrafael/purescript-debugged.git
|
||||||
ref: 0d5a4149279129f10c8fe2a3ef280b9fde4d5116
|
ref: 0d5a4149279129f10c8fe2a3ef280b9fde4d5116
|
||||||
packages:
|
packages:
|
||||||
|
aff:
|
||||||
|
type: registry
|
||||||
|
version: 7.1.0
|
||||||
|
integrity: sha256-7hOC6uQO9XBAI5FD8F33ChLjFAiZVfd4BJMqlMh7TNU=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- bifunctors
|
||||||
|
- control
|
||||||
|
- datetime
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- exceptions
|
||||||
|
- foldable-traversable
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- parallel
|
||||||
|
- prelude
|
||||||
|
- refs
|
||||||
|
- tailrec
|
||||||
|
- transformers
|
||||||
|
- unsafe-coerce
|
||||||
|
arraybuffer-types:
|
||||||
|
type: registry
|
||||||
|
version: 3.0.2
|
||||||
|
integrity: sha256-mQKokysYVkooS4uXbO+yovmV/s8b138Ws3zQvOwIHRA=
|
||||||
|
dependencies: []
|
||||||
arrays:
|
arrays:
|
||||||
type: registry
|
type: registry
|
||||||
version: 7.3.0
|
version: 7.3.0
|
||||||
|
@ -637,6 +684,13 @@ packages:
|
||||||
- partial
|
- partial
|
||||||
- prelude
|
- prelude
|
||||||
- tuples
|
- tuples
|
||||||
|
debug:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.2
|
||||||
|
integrity: sha256-vmkYFuXYuELBzeauvgHG6E6Kf/Hp1dAnxwE9ByHfwSg=
|
||||||
|
dependencies:
|
||||||
|
- functions
|
||||||
|
- prelude
|
||||||
debugged:
|
debugged:
|
||||||
type: git
|
type: git
|
||||||
url: https://github.com/mateiadrielrafael/purescript-debugged.git
|
url: https://github.com/mateiadrielrafael/purescript-debugged.git
|
||||||
|
@ -742,6 +796,20 @@ packages:
|
||||||
- orders
|
- orders
|
||||||
- prelude
|
- prelude
|
||||||
- tuples
|
- tuples
|
||||||
|
foreign:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-1ORiqoS3HW+qfwSZAppHPWy4/6AQysxZ2t29jcdUMNA=
|
||||||
|
dependencies:
|
||||||
|
- either
|
||||||
|
- functions
|
||||||
|
- identity
|
||||||
|
- integers
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- prelude
|
||||||
|
- strings
|
||||||
|
- transformers
|
||||||
functions:
|
functions:
|
||||||
type: registry
|
type: registry
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
|
@ -805,6 +873,17 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
- control
|
- control
|
||||||
- prelude
|
- prelude
|
||||||
|
js-date:
|
||||||
|
type: registry
|
||||||
|
version: 8.0.0
|
||||||
|
integrity: sha256-6TVF4DWg5JL+jRAsoMssYw8rgOVALMUHT1CuNZt8NRo=
|
||||||
|
dependencies:
|
||||||
|
- datetime
|
||||||
|
- effect
|
||||||
|
- exceptions
|
||||||
|
- foreign
|
||||||
|
- integers
|
||||||
|
- now
|
||||||
lazy:
|
lazy:
|
||||||
type: registry
|
type: registry
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
|
@ -847,6 +926,70 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
- prelude
|
- prelude
|
||||||
- safe-coerce
|
- safe-coerce
|
||||||
|
node-buffer:
|
||||||
|
type: registry
|
||||||
|
version: 9.0.0
|
||||||
|
integrity: sha256-PWE2DJ5ruBLCmeA/fUiuySEFmUJ/VuRfyrnCuVZBlu4=
|
||||||
|
dependencies:
|
||||||
|
- arraybuffer-types
|
||||||
|
- effect
|
||||||
|
- maybe
|
||||||
|
- nullable
|
||||||
|
- st
|
||||||
|
- unsafe-coerce
|
||||||
|
node-event-emitter:
|
||||||
|
type: registry
|
||||||
|
version: 3.0.0
|
||||||
|
integrity: sha256-Qw0MjsT4xRH2j2i4K8JmRjcMKnH5z1Cw39t00q4LE4w=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
|
- nullable
|
||||||
|
- prelude
|
||||||
|
- unsafe-coerce
|
||||||
|
node-fs:
|
||||||
|
type: registry
|
||||||
|
version: 9.1.0
|
||||||
|
integrity: sha256-TzhvGdrwcM0bazDvrWSqh+M/H8GKYf1Na6aGm2Qg4+c=
|
||||||
|
dependencies:
|
||||||
|
- datetime
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- enums
|
||||||
|
- exceptions
|
||||||
|
- functions
|
||||||
|
- integers
|
||||||
|
- js-date
|
||||||
|
- maybe
|
||||||
|
- node-buffer
|
||||||
|
- node-path
|
||||||
|
- node-streams
|
||||||
|
- nullable
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- strings
|
||||||
|
- unsafe-coerce
|
||||||
|
node-path:
|
||||||
|
type: registry
|
||||||
|
version: 5.0.0
|
||||||
|
integrity: sha256-pd82nQ+2l5UThzaxPdKttgDt7xlsgIDLpPG0yxDEdyE=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
node-streams:
|
||||||
|
type: registry
|
||||||
|
version: 9.0.0
|
||||||
|
integrity: sha256-2n6dq7YWleTDmD1Kur/ul7Cn08IvWrScgPf+0PgX2TQ=
|
||||||
|
dependencies:
|
||||||
|
- aff
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- exceptions
|
||||||
|
- node-buffer
|
||||||
|
- node-event-emitter
|
||||||
|
- nullable
|
||||||
|
- prelude
|
||||||
nonempty:
|
nonempty:
|
||||||
type: registry
|
type: registry
|
||||||
version: 7.0.0
|
version: 7.0.0
|
||||||
|
@ -858,6 +1001,21 @@ packages:
|
||||||
- prelude
|
- prelude
|
||||||
- tuples
|
- tuples
|
||||||
- unfoldable
|
- unfoldable
|
||||||
|
now:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-xZ7x37ZMREfs6GCDw/h+FaKHV/3sPWmtqBZRGTxybQY=
|
||||||
|
dependencies:
|
||||||
|
- datetime
|
||||||
|
- effect
|
||||||
|
nullable:
|
||||||
|
type: registry
|
||||||
|
version: 6.0.0
|
||||||
|
integrity: sha256-yiGBVl3AD+Guy4kNWWeN+zl1gCiJK+oeIFtZtPCw4+o=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
numbers:
|
numbers:
|
||||||
type: registry
|
type: registry
|
||||||
version: 9.0.1
|
version: 9.0.1
|
||||||
|
@ -888,6 +1046,22 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
- newtype
|
- newtype
|
||||||
- prelude
|
- prelude
|
||||||
|
parallel:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-gUC9i4Txnx9K9RcMLsjujbwZz6BB1bnE2MLvw4GIw5o=
|
||||||
|
dependencies:
|
||||||
|
- control
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- foldable-traversable
|
||||||
|
- functors
|
||||||
|
- maybe
|
||||||
|
- newtype
|
||||||
|
- prelude
|
||||||
|
- profunctor
|
||||||
|
- refs
|
||||||
|
- transformers
|
||||||
partial:
|
partial:
|
||||||
type: registry
|
type: registry
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
|
@ -941,6 +1115,21 @@ packages:
|
||||||
- prelude
|
- prelude
|
||||||
- tailrec
|
- tailrec
|
||||||
- unsafe-coerce
|
- unsafe-coerce
|
||||||
|
string-parsers:
|
||||||
|
type: registry
|
||||||
|
version: 8.0.0
|
||||||
|
integrity: sha256-9ATYh0S54ERoR+uhkCM59wBRvW/6zv6geHJ0TmcI644=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- bifunctors
|
||||||
|
- control
|
||||||
|
- either
|
||||||
|
- foldable-traversable
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- prelude
|
||||||
|
- strings
|
||||||
|
- tailrec
|
||||||
strings:
|
strings:
|
||||||
type: registry
|
type: registry
|
||||||
version: 6.0.1
|
version: 6.0.1
|
||||||
|
|
|
@ -7,8 +7,13 @@ package:
|
||||||
- tuples
|
- tuples
|
||||||
- maybe
|
- maybe
|
||||||
- debugged
|
- debugged
|
||||||
|
- debug
|
||||||
- colors
|
- colors
|
||||||
- unordered-collections
|
- unordered-collections
|
||||||
|
- string-parsers
|
||||||
|
- node-fs
|
||||||
|
- aff
|
||||||
|
- strings
|
||||||
test:
|
test:
|
||||||
main: Test.Main
|
main: Test.Main
|
||||||
dependencies: []
|
dependencies: []
|
||||||
|
|
|
@ -10,6 +10,9 @@ derive instance Generic LayerVisualPosition _
|
||||||
instance Debug LayerVisualPosition where
|
instance Debug LayerVisualPosition where
|
||||||
debug = genericDebug
|
debug = genericDebug
|
||||||
|
|
||||||
|
instance Show LayerVisualPosition where
|
||||||
|
show = genericShow
|
||||||
|
|
||||||
instance Hashable LayerVisualPosition where
|
instance Hashable LayerVisualPosition where
|
||||||
hash Center = 0
|
hash Center = 0
|
||||||
hash TopLeft = 1
|
hash TopLeft = 1
|
||||||
|
|
|
@ -38,6 +38,9 @@ newtype RawLayer = RawLayer
|
||||||
, keys :: Array RawKeySymbol
|
, keys :: Array RawKeySymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layerName :: RawLayer -> String
|
||||||
|
layerName (RawLayer { name }) = name
|
||||||
|
|
||||||
data RawElement
|
data RawElement
|
||||||
= RawLayerGroup (HashMap LayerVisualPosition RawLayer)
|
= RawLayerGroup (HashMap LayerVisualPosition RawLayer)
|
||||||
| RawChordGroup (Array RawChord)
|
| RawChordGroup (Array RawChord)
|
||||||
|
@ -47,6 +50,9 @@ newtype RawSection = RawSection
|
||||||
, elements :: Array RawElement
|
, elements :: Array RawElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sectionElements :: RawSection -> Array RawElement
|
||||||
|
sectionElements (RawSection { elements }) = elements
|
||||||
|
|
||||||
data RawActionDisplay
|
data RawActionDisplay
|
||||||
= DisplaySymbol RawKeySymbol
|
= DisplaySymbol RawKeySymbol
|
||||||
| DisplayLayerColor
|
| DisplayLayerColor
|
||||||
|
@ -56,15 +62,14 @@ data RawActionEffect
|
||||||
| StickyLayerSwitch String
|
| StickyLayerSwitch String
|
||||||
|
|
||||||
newtype RawAction = RawAction
|
newtype RawAction = RawAction
|
||||||
{ name :: String
|
{ display :: RawActionDisplay
|
||||||
, visualSymbol :: RawActionDisplay
|
|
||||||
, effect :: RawActionEffect
|
, effect :: RawActionEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
newtype RawConfig = RawConfig
|
newtype RawConfig = RawConfig
|
||||||
{ physical :: RawPhysical
|
{ physical :: RawPhysical
|
||||||
, actions :: Array RawAction
|
, actions :: HashMap String RawAction
|
||||||
, sections :: RawSection
|
, sections :: Array RawSection
|
||||||
}
|
}
|
||||||
|
|
||||||
derive instance Eq RawPhysicalActionStep
|
derive instance Eq RawPhysicalActionStep
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
module Main where
|
module Main where
|
||||||
|
|
||||||
import Prelude
|
import LayoutLens.Prelude
|
||||||
|
|
||||||
import Effect (Effect)
|
import LayoutLens.Parser (parseConfig)
|
||||||
import Effect.Console (log)
|
import Node.Encoding (Encoding(..))
|
||||||
|
import Node.FS.Aff (readTextFile)
|
||||||
|
|
||||||
main :: Effect Unit
|
main :: Effect Unit
|
||||||
main = do
|
main = launchAff_ do
|
||||||
log "🍝"
|
file <- readTextFile UTF8 "../keyboards/qmk/ferris-sweep/config.lens"
|
||||||
|
case parseConfig file of
|
||||||
|
Left err -> log err
|
||||||
|
Right result -> log
|
||||||
|
$ prettyPrintWith
|
||||||
|
defaultPrettyPrintOptions { maxDepth = Nothing }
|
||||||
|
$ debug result
|
||||||
|
|
264
layout-lens/src/Parser.purs
Normal file
264
layout-lens/src/Parser.purs
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
module LayoutLens.Parser (parseConfig) where
|
||||||
|
|
||||||
|
import LayoutLens.Prelude hiding (string)
|
||||||
|
|
||||||
|
import Data.Array as Array
|
||||||
|
import Data.HashMap as HM
|
||||||
|
import Data.HashSet as HS
|
||||||
|
import Data.Int as Int
|
||||||
|
import Data.Number as Number
|
||||||
|
import Data.String.CodeUnits as String
|
||||||
|
import LayoutLens.Data.Config (LayerVisualPosition(..))
|
||||||
|
import LayoutLens.Data.RawConfig (RawAction(..), RawActionDisplay(..), RawActionEffect(..), RawChord(..), RawConfig(..), RawElement(..), RawKeySymbol(..), RawLayer(..), RawPhysical(..), RawPhysicalActionStep(..), RawPhysicalStep(..), RawSection(..), layerName, sectionElements)
|
||||||
|
import LayoutLens.Data.Vec2 (Radians(..), Vec2(..))
|
||||||
|
import Safe.Coerce (coerce)
|
||||||
|
import StringParser (Parser, printParserError, runParser)
|
||||||
|
import StringParser as P
|
||||||
|
|
||||||
|
-- {{{ Base combinators
|
||||||
|
singleNewline :: Parser Unit
|
||||||
|
singleNewline = void $ flip P.withError "failed to match single newline" $ P.regex "\n"
|
||||||
|
|
||||||
|
iws :: Parser Unit
|
||||||
|
iws = void $ flip P.withError "failed to match one or more inline whitespace" $ P.regex "[ \t]+"
|
||||||
|
|
||||||
|
oiws :: Parser Unit
|
||||||
|
oiws = void $ flip P.withError "failed to match zero or more inline whitespace" $ P.regex "[ \t]*"
|
||||||
|
|
||||||
|
ows :: Parser Unit
|
||||||
|
ows = void $ flip P.withError "failed to match zero or more whitespace" $ P.regex "[ \t\n]*"
|
||||||
|
|
||||||
|
ws :: Parser Unit
|
||||||
|
ws = void $ flip P.withError "failed to match one or more whitespace" $ P.regex "[ \t\n]+"
|
||||||
|
|
||||||
|
newline :: Parser Unit
|
||||||
|
newline = void $ P.many1 (P.try $ (oiws *> singleNewline)) *> oiws
|
||||||
|
|
||||||
|
manyLines :: forall a. Parser a -> Parser (Array a)
|
||||||
|
manyLines p = Array.fromFoldable <$> P.many (p <* ows)
|
||||||
|
|
||||||
|
tok :: forall a. Parser a -> Parser a
|
||||||
|
tok p = iws *> p
|
||||||
|
|
||||||
|
number :: Parser Number
|
||||||
|
number = do
|
||||||
|
string <- flip P.withError "failed to match real" $ P.regex "[-+]?[0-9]*\\.?[0-9]+"
|
||||||
|
case Number.fromString string of
|
||||||
|
Just num -> pure num
|
||||||
|
Nothing -> P.fail $ "Invalid number " <> string
|
||||||
|
|
||||||
|
nat :: Parser Int
|
||||||
|
nat = do
|
||||||
|
string <- flip P.withError "failed to match natural" $ P.regex "[0-9]+"
|
||||||
|
case Int.fromString string of
|
||||||
|
Just num -> pure num
|
||||||
|
Nothing -> P.fail $ "Invalid natural " <> string
|
||||||
|
|
||||||
|
vec2 :: Parser Vec2
|
||||||
|
vec2 = Vec2 <$> (iws *> number) <*> (iws *> number)
|
||||||
|
|
||||||
|
radians :: Parser Radians
|
||||||
|
radians = Radians <$> (iws *> number)
|
||||||
|
|
||||||
|
name :: Parser String
|
||||||
|
name = ows *> P.try do
|
||||||
|
result <- P.regex "\\S+"
|
||||||
|
when (Array.elem result kws) $
|
||||||
|
P.fail "Names cannot be keywords"
|
||||||
|
pure result
|
||||||
|
where
|
||||||
|
kws = [ "layergroup", "chordgroup" ]
|
||||||
|
|
||||||
|
color :: Parser Color
|
||||||
|
color = do
|
||||||
|
string <- flip P.withError "failed to match hexstring" $ P.regex "#[0-9a-fA-F]{6}"
|
||||||
|
case fromHexString string of
|
||||||
|
Just color -> pure color
|
||||||
|
Nothing -> P.fail $ "Invalid color " <> string
|
||||||
|
|
||||||
|
string :: String -> Parser Unit
|
||||||
|
string s = oiws <* P.string s
|
||||||
|
|
||||||
|
noDuplicates :: String -> Array String -> Parser Unit
|
||||||
|
noDuplicates what arr =
|
||||||
|
void $
|
||||||
|
Array.foldM
|
||||||
|
( \prev name -> do
|
||||||
|
when (HS.member name prev) do
|
||||||
|
P.fail $ what <> " " <> name <> " defined multiple times"
|
||||||
|
pure $ HS.insert name prev
|
||||||
|
)
|
||||||
|
HS.empty
|
||||||
|
arr
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
physical :: Parser RawPhysical
|
||||||
|
physical = do
|
||||||
|
string "physical" *> newline
|
||||||
|
RawPhysical <$> manyLines (block <|> (PhysicalAction <$> actionStep))
|
||||||
|
where
|
||||||
|
block :: Parser RawPhysicalStep
|
||||||
|
block = do
|
||||||
|
string "block" *> newline
|
||||||
|
steps <- manyLines actionStep
|
||||||
|
string "end"
|
||||||
|
pure $ Block steps
|
||||||
|
|
||||||
|
actionStep :: Parser RawPhysicalActionStep
|
||||||
|
actionStep = place <|> point
|
||||||
|
|
||||||
|
place :: Parser RawPhysicalActionStep
|
||||||
|
place = flip P.withError "failed to parse 'place' command" do
|
||||||
|
string "place"
|
||||||
|
offset <- vec2
|
||||||
|
rotateBy /\ rotateAround <- P.option (Radians 0.0 /\ offset) do
|
||||||
|
angle <- radians
|
||||||
|
around <- P.option offset vec2
|
||||||
|
pure $ angle /\ around
|
||||||
|
pure $ Place { offset, rotateBy, rotateAround }
|
||||||
|
|
||||||
|
point :: Parser RawPhysicalActionStep
|
||||||
|
point = do
|
||||||
|
string "key"
|
||||||
|
position <- vec2
|
||||||
|
arguments <- Array.fromFoldable <$> P.many (iws *> number)
|
||||||
|
let size = Vec2 1.0 1.0
|
||||||
|
let rotateBy = Radians 0.0
|
||||||
|
let rotateAround = position
|
||||||
|
case arguments of
|
||||||
|
[] -> pure $ Point { position, size, rotateBy, rotateAround }
|
||||||
|
[ angle ] -> pure $ Point { position, size, rotateAround, rotateBy: Radians angle }
|
||||||
|
[ sx, sy ] -> pure $ Point { position, rotateBy, rotateAround, size: Vec2 sx sy }
|
||||||
|
[ sx, sy, angle ] -> pure $ Point
|
||||||
|
{ position
|
||||||
|
, rotateAround
|
||||||
|
, size: Vec2 sx sy
|
||||||
|
, rotateBy: Radians angle
|
||||||
|
}
|
||||||
|
[ sx, sy, angle, rx, ry ] -> pure $ Point
|
||||||
|
{ position
|
||||||
|
, size: Vec2 sx sy
|
||||||
|
, rotateBy: Radians angle
|
||||||
|
, rotateAround: Vec2 rx ry
|
||||||
|
}
|
||||||
|
_ -> P.fail "Too many arguments provided to point"
|
||||||
|
|
||||||
|
layer :: Parser (LayerVisualPosition /\ RawLayer)
|
||||||
|
layer = do
|
||||||
|
string "layer"
|
||||||
|
layerName <- tok name
|
||||||
|
position <- tok $ oneOf
|
||||||
|
[ string "center" $> Center
|
||||||
|
, string "topleft" $> TopLeft
|
||||||
|
, string "topright" $> TopRight
|
||||||
|
, string "bottomleft" $> BottomLeft
|
||||||
|
, string "bottomright" $> BottomRight
|
||||||
|
]
|
||||||
|
textColor <- P.optionMaybe $ tok color
|
||||||
|
newline
|
||||||
|
keys <- Array.fromFoldable
|
||||||
|
<$> P.many1Till
|
||||||
|
(rawKeySymbol <* ws)
|
||||||
|
(string "end")
|
||||||
|
pure $ position /\ RawLayer { name: layerName, keys, textColor }
|
||||||
|
|
||||||
|
layergroup :: Parser RawElement
|
||||||
|
layergroup = do
|
||||||
|
string "layergroup" *> newline
|
||||||
|
layers <- manyLines layer
|
||||||
|
noDuplicates "Layer" $ (show <<< fst) <$> layers
|
||||||
|
pure $ RawLayerGroup $ coerce $ Array.foldMap
|
||||||
|
(\(name /\ value) -> HM.singleton name $ wrapInto @(First RawLayer) value)
|
||||||
|
layers
|
||||||
|
|
||||||
|
chord :: Parser RawChord
|
||||||
|
chord = do
|
||||||
|
from <- Array.fromFoldable <$> P.manyTill
|
||||||
|
(rawKeySymbol <* iws)
|
||||||
|
(P.string "=>")
|
||||||
|
|
||||||
|
to <- tok $ Array.fromFoldable <$> P.manyTill
|
||||||
|
(rawKeySymbol <* iws)
|
||||||
|
(P.lookAhead color)
|
||||||
|
|
||||||
|
fill <- color
|
||||||
|
fontSizeModifier <- P.option 1.0 $ tok number
|
||||||
|
pure $ RawChord { from, to, fill, fontSizeModifier }
|
||||||
|
|
||||||
|
chordgroup :: Parser RawElement
|
||||||
|
chordgroup = do
|
||||||
|
string "chordgroup" *> newline
|
||||||
|
c <- RawChordGroup <$> manyLines chord
|
||||||
|
pure c
|
||||||
|
|
||||||
|
type NamedRawAction = String /\ RawAction
|
||||||
|
|
||||||
|
rawKeySymbol :: Parser RawKeySymbol
|
||||||
|
rawKeySymbol = RawKeySymbol <$> name
|
||||||
|
|
||||||
|
action :: Parser NamedRawAction
|
||||||
|
action = do
|
||||||
|
string "action"
|
||||||
|
actionName <- tok name
|
||||||
|
display <- tok $ oneOf
|
||||||
|
[ DisplayLayerColor <$ string "🌈"
|
||||||
|
, DisplaySymbol <$> rawKeySymbol
|
||||||
|
]
|
||||||
|
effect <- tok $ oneOf
|
||||||
|
[ string "switch" *> (LayerSwitch <$> tok name)
|
||||||
|
, string "sticky-switch" *> (StickyLayerSwitch <$> tok name)
|
||||||
|
]
|
||||||
|
pure $ actionName /\ RawAction { display, effect }
|
||||||
|
|
||||||
|
section :: Parser (Array NamedRawAction /\ RawSection)
|
||||||
|
section = do
|
||||||
|
string "section" *> newline
|
||||||
|
actions /\ columnCounts /\ elements <- map fold $ manyLines $ oneOf
|
||||||
|
[ action <#> \action -> [ action ] /\ [] /\ []
|
||||||
|
, parseColumns <#> \amount -> [] /\ [ amount ] /\ []
|
||||||
|
, layergroup <|> chordgroup <#> \element -> [] /\ [] /\ [ element ]
|
||||||
|
]
|
||||||
|
|
||||||
|
columns <- case columnCounts of
|
||||||
|
[] -> pure 1
|
||||||
|
[ single ] -> pure single
|
||||||
|
_ -> P.fail $ "Column count defined multiple times " <> show columnCounts
|
||||||
|
|
||||||
|
pure $ actions /\ RawSection { columns, elements }
|
||||||
|
where
|
||||||
|
parseColumns :: Parser Int
|
||||||
|
parseColumns = P.string "columns" *> tok nat
|
||||||
|
|
||||||
|
config :: Parser RawConfig
|
||||||
|
config = do
|
||||||
|
physical <- physical
|
||||||
|
sections <- ows *> manyLines section <* ows <* P.eof
|
||||||
|
|
||||||
|
sections
|
||||||
|
>>= fst
|
||||||
|
<#> fst
|
||||||
|
# noDuplicates "Action"
|
||||||
|
|
||||||
|
sections
|
||||||
|
<#> snd
|
||||||
|
>>= sectionElements
|
||||||
|
>>= case _ of
|
||||||
|
RawLayerGroup layers -> layerName <$> HM.values layers
|
||||||
|
RawChordGroup _ -> []
|
||||||
|
# noDuplicates "Layer"
|
||||||
|
|
||||||
|
pure $ RawConfig
|
||||||
|
{ physical
|
||||||
|
, sections: sections <#> snd
|
||||||
|
, actions: sections
|
||||||
|
>>= fst
|
||||||
|
# Array.foldMap
|
||||||
|
(\(name /\ action) -> HM.singleton name $ wrapInto @(First _) action)
|
||||||
|
# coerce
|
||||||
|
}
|
||||||
|
|
||||||
|
parseConfig :: String -> Either String RawConfig
|
||||||
|
parseConfig input = case runParser config input of
|
||||||
|
Left err -> Left $ fold [ printParserError err, "\n", String.slice (err.pos) (err.pos + 30) input ]
|
||||||
|
Right result -> Right result
|
|
@ -12,18 +12,47 @@ module LayoutLens.Prelude
|
||||||
, module Data.HashMap
|
, module Data.HashMap
|
||||||
, module Data.HashSet
|
, module Data.HashSet
|
||||||
, module Data.Hashable
|
, module Data.Hashable
|
||||||
|
, module Control.Monad.Reader
|
||||||
|
, module Control.Alternative
|
||||||
|
, module Data.Foldable
|
||||||
|
, module Data.Show.Generic
|
||||||
|
, module Data.Either
|
||||||
|
, module Effect.Aff
|
||||||
|
, module Safe.Coerce
|
||||||
|
, module Data.Newtype
|
||||||
|
, module Data.Semigroup.First
|
||||||
|
, wrapInto
|
||||||
|
, unimplemented
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
import Data.Maybe (Maybe(..), fromJust, fromMaybe, fromMaybe', isJust, isNothing, maybe, maybe', optional)
|
|
||||||
import Data.Tuple (Tuple(..), curry, fst, snd, swap, uncurry)
|
|
||||||
import Data.Tuple.Nested (type (/\), T10, T11, T2, T3, T4, T5, T6, T7, T8, T9, Tuple1, Tuple10, Tuple2, Tuple3, Tuple4, Tuple5, Tuple6, Tuple7, Tuple8, Tuple9, curry1, curry10, curry2, curry3, curry4, curry5, curry6, curry7, curry8, curry9, get1, get10, get2, get3, get4, get5, get6, get7, get8, get9, over1, over10, over2, over3, over4, over5, over6, over7, over8, over9, tuple1, tuple10, tuple2, tuple3, tuple4, tuple5, tuple6, tuple7, tuple8, tuple9, uncurry1, uncurry10, uncurry2, uncurry3, uncurry4, uncurry5, uncurry6, uncurry7, uncurry8, uncurry9, (/\))
|
|
||||||
import Effect (Effect, forE, foreachE, untilE, whileE)
|
|
||||||
import Effect.Class (class MonadEffect, liftEffect)
|
|
||||||
import Effect.Class.Console (clear, error, errorShow, group, groupCollapsed, groupEnd, grouped, info, infoShow, log, logShow, time, timeEnd, timeLog, warn, warnShow)
|
|
||||||
import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), NoConstructors, Product(..), Sum(..), from, repOf, to)
|
|
||||||
import Data.Debug (class Debug, class DebugRowList, class GenericDebug, class GenericDebugArgs, DiffOptions, PrettyPrintOptions, Repr, ReprDelta, array, assoc, boolean, char, collection, constructor, debug, debugRowList, defaultDiffOptions, defaultPrettyPrintOptions, diff, diffRepr, diffReprWith, genericDebug, genericDebug', genericDebugArgs, int, number, opaque, opaqueLiteral, opaque_, prettyPrint, prettyPrintDelta, prettyPrintDeltaWith, prettyPrintWith, record, string)
|
|
||||||
import Color (Color, ColorSpace(..), Interpolator, black, brightness, complementary, contrast, cssStringHSLA, cssStringRGBA, darken, desaturate, distance, fromHexString, fromInt, graytone, hsl, hsla, hsv, hsva, isLight, isReadable, lab, lch, lighten, luminance, mix, mixCubehelix, rgb, rgb', rgba, rgba', rotateHue, saturate, textColor, toGray, toHSLA, toHSVA, toHexString, toLCh, toLab, toRGBA, toRGBA', toXYZ, white, xyz)
|
import Color (Color, ColorSpace(..), Interpolator, black, brightness, complementary, contrast, cssStringHSLA, cssStringRGBA, darken, desaturate, distance, fromHexString, fromInt, graytone, hsl, hsla, hsv, hsva, isLight, isReadable, lab, lch, lighten, luminance, mix, mixCubehelix, rgb, rgb', rgba, rgba', rotateHue, saturate, textColor, toGray, toHSLA, toHSVA, toHexString, toLCh, toLab, toRGBA, toRGBA', toXYZ, white, xyz)
|
||||||
|
import Control.Alternative (class Alt, class Alternative, empty, (<|>))
|
||||||
|
import Control.Monad.Reader (Reader, ReaderT, runReader, runReaderT, ask, asks, local)
|
||||||
|
import Data.Debug (class Debug, class DebugRowList, class GenericDebug, class GenericDebugArgs, DiffOptions, PrettyPrintOptions, Repr, ReprDelta, array, assoc, boolean, char, collection, constructor, debug, debugRowList, defaultDiffOptions, defaultPrettyPrintOptions, diff, diffRepr, diffReprWith, genericDebug, genericDebug', genericDebugArgs, opaque, opaqueLiteral, opaque_, prettyPrint, prettyPrintDelta, prettyPrintDeltaWith, prettyPrintWith, record, string)
|
||||||
|
import Data.Either (Either(..), blush, choose, either, fromLeft, fromLeft', fromRight, fromRight', hush, isLeft, isRight, note, note')
|
||||||
|
import Data.Foldable (class Foldable, all, and, any, elem, find, findMap, fold, foldM, foldMap, foldMapDefaultL, foldMapDefaultR, foldl, foldlDefault, foldr, foldrDefault, for_, indexl, indexr, intercalate, length, lookup, maximum, maximumBy, minimum, minimumBy, notElem, null, oneOf, oneOfMap, or, product, sequence_, sum, surround, surroundMap, traverse_)
|
||||||
|
import Data.Generic.Rep (class Generic, Argument(..), Constructor(..), NoArguments(..), NoConstructors, Product(..), Sum(..), from, repOf, to)
|
||||||
import Data.HashMap (HashMap)
|
import Data.HashMap (HashMap)
|
||||||
import Data.HashSet (HashSet)
|
import Data.HashSet (HashSet)
|
||||||
import Data.Hashable (class Hashable)
|
import Data.Hashable (class Hashable)
|
||||||
|
import Data.Maybe (Maybe(..), fromJust, fromMaybe, fromMaybe', isJust, isNothing, maybe, maybe', optional)
|
||||||
|
import Data.Newtype (class Newtype, wrap)
|
||||||
|
import Data.Show.Generic (genericShow)
|
||||||
|
import Data.Tuple (Tuple(..), curry, fst, snd, swap, uncurry)
|
||||||
|
import Data.Tuple.Nested (type (/\), T10, T11, T2, T3, T4, T5, T6, T7, T8, T9, Tuple1, Tuple10, Tuple2, Tuple3, Tuple4, Tuple5, Tuple6, Tuple7, Tuple8, Tuple9, curry1, curry10, curry2, curry3, curry4, curry5, curry6, curry7, curry8, curry9, get1, get10, get2, get3, get4, get5, get6, get7, get8, get9, over1, over10, over2, over3, over4, over5, over6, over7, over8, over9, tuple1, tuple10, tuple2, tuple3, tuple4, tuple5, tuple6, tuple7, tuple8, tuple9, uncurry1, uncurry10, uncurry2, uncurry3, uncurry4, uncurry5, uncurry6, uncurry7, uncurry8, uncurry9, (/\))
|
||||||
|
import Effect (Effect, forE, foreachE, untilE, whileE)
|
||||||
|
import Effect.Aff (Aff, BracketConditions, Canceler(..), Error, Fiber, Milliseconds(..), ParAff, apathize, attempt, bracket, cancelWith, catchError, delay, effectCanceler, error, fiberCanceler, finally, forkAff, generalBracket, invincible, joinFiber, killFiber, launchAff, launchAff_, launchSuspendedAff, makeAff, message, never, nonCanceler, parallel, runAff, runAff_, runSuspendedAff, sequential, supervise, suspendAff, throwError, try)
|
||||||
|
import Effect.Class (class MonadEffect, liftEffect)
|
||||||
|
import Effect.Class.Console (clear, group, groupCollapsed, groupEnd, grouped, info, infoShow, log, logShow, time, timeEnd, timeLog, warn, warnShow)
|
||||||
|
import Effect.Exception.Unsafe (unsafeThrow)
|
||||||
|
import Prim.TypeError (class Warn, Text)
|
||||||
|
import Safe.Coerce (class Coercible, coerce)
|
||||||
|
import Data.Semigroup.First (First(..))
|
||||||
|
|
||||||
|
unimplemented :: forall a. Warn (Text "unimplemenet") => a
|
||||||
|
unimplemented = unsafeThrow "unimplemented"
|
||||||
|
|
||||||
|
wrapInto :: forall a @t. Newtype t a => a -> t
|
||||||
|
wrapInto = wrap
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
set iskeyword+=-
|
set iskeyword+=-
|
||||||
|
|
||||||
syntax keyword lensKeyword physical section keyboard layer chordgroup block
|
syntax keyword lensKeyword physical section layergroup layer chordgroup block end
|
||||||
syntax keyword lensAction sticky-switch switch
|
syntax keyword lensAction sticky-switch switch
|
||||||
syntax keyword lensFunction columns place action
|
syntax keyword lensFunction columns place action key
|
||||||
syntax keyword lensLayerName center topleft topright bottomleft bottomright
|
syntax keyword lensLayerName center topleft topright bottomleft bottomright
|
||||||
|
|
||||||
syntax match lensComment "\v--.*$"
|
syntax match lensComment "\v--.*$"
|
||||||
|
|
Loading…
Reference in a new issue