Skip to content

Commit

Permalink
Add support for Feliz style (#930)
Browse files Browse the repository at this point in the history
* Support Feliz style

* Refactored Feliz expressions. Fixes #927

* Added SingleArgumentWebMode to schema.json

* Bump to alpha 011
  • Loading branch information
nojaf authored Jun 25, 2020
1 parent d962694 commit db526ab
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 24 deletions.
2 changes: 1 addition & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### 4.0.0-alpha-010 - 06/2020
### 4.0.0-alpha-011 - 06/2020
* WIP for [#705](https://github.com/fsprojects/fantomas/issues/705)
* FCS 36

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
<GenerateProgramFile>false</GenerateProgramFile>
<Version>4.0.0-alpha-010</Version>
<Version>4.0.0-alpha-011</Version>
<NoWarn>FS0988</NoWarn>
</PropertyGroup>
<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Fantomas.CoreGlobalTool/Fantomas.CoreGlobalTool.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
<ToolCommandName>fantomas</ToolCommandName>
<PackAsTool>True</PackAsTool>
<Version>4.0.0-alpha-010</Version>
<Version>4.0.0-alpha-011</Version>
<AssemblyName>fantomas-tool</AssemblyName>
</PropertyGroup>
<ItemGroup>
Expand Down
142 changes: 142 additions & 0 deletions src/Fantomas.Tests/ElmishTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -569,3 +569,145 @@ let view dispatch model =
]
]
"""

[<Test>]
let ``short feliz element`` () =
formatSourceString false """let a =
Html.h1 [ prop.text "some title" ]
""" config
|> prepend newline
|> should equal """
let a = Html.h1 [ prop.text "some title" ]
"""

[<Test>]
let ``multiline feliz element`` () =
formatSourceString false """let a =
Html.button [
prop.style [ style.marginLeft 5 ]
prop.onClick (fun _ -> setCount(count - 1))
prop.text "Decrement"
]
""" { config with SingleArgumentWebMode = true }
|> prepend newline
|> should equal """
let a =
Html.button [
prop.style [ style.marginLeft 5 ]
prop.onClick (fun _ -> setCount (count - 1))
prop.text "Decrement"
]
"""

[<Test>]
let ``nested feliz elements`` () =
formatSourceString false """let a =
Html.div [
Html.h1 [ prop.text "short" ]
Html.button [
prop.style [ style.marginRight 5 ]
prop.onClick (fun _ -> setCount(count + 1))
prop.text "Increment"
]
]
""" { config with SingleArgumentWebMode = true }
|> prepend newline
|> should equal """
let a =
Html.div [
Html.h1 [ prop.text "short" ]
Html.button [
prop.style [ style.marginRight 5 ]
prop.onClick (fun _ -> setCount (count + 1))
prop.text "Increment"
]
]
"""

[<Test>]
let ``feliz counter sample`` () =
formatSourceString false """module App
open Feliz
let counter = React.functionComponent(fun () ->
let (count, setCount) = React.useState(0)
Html.div [
Html.button [
prop.style [ style.marginRight 5 ]
prop.onClick (fun _ -> setCount(count + 1))
prop.text "Increment"
]
Html.button [
prop.style [ style.marginLeft 5 ]
prop.onClick (fun _ -> setCount(count - 1))
prop.text "Decrement"
]
Html.h1 count
])
open Browser.Dom
ReactDOM.render(counter, document.getElementById "root")
""" { config with SingleArgumentWebMode = true }
|> prepend newline
|> should equal """
module App
open Feliz
let counter =
React.functionComponent (fun () ->
let (count, setCount) = React.useState (0)
Html.div [
Html.button [
prop.style [ style.marginRight 5 ]
prop.onClick (fun _ -> setCount (count + 1))
prop.text "Increment"
]
Html.button [
prop.style [ style.marginLeft 5 ]
prop.onClick (fun _ -> setCount (count - 1))
prop.text "Decrement"
]
Html.h1 count
])
open Browser.Dom
ReactDOM.render (counter, document.getElementById "root")
"""

[<Test>]
let ``feliz syntax`` () =
formatSourceString false """
Html.h1 42
Html.div "Hello there!"
Html.div [ Html.h1 "So lightweight" ]
Html.ul [
Html.li "One"
Html.li [ Html.strong "Two" ]
Html.li [ Html.em "Three" ]
]
""" { config with SingleArgumentWebMode = true }
|> prepend newline
|> should equal """
Html.h1 42
Html.div "Hello there!"
Html.div [ Html.h1 "So lightweight" ]
Html.ul [
Html.li "One"
Html.li [ Html.strong "Two" ]
Html.li [ Html.em "Three" ]
]
"""
2 changes: 1 addition & 1 deletion src/Fantomas.Tests/Fantomas.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\netfx.props" />
<PropertyGroup>
<Version>4.0.0-alpha-010</Version>
<Version>4.0.0-alpha-011</Version>
<NoWarn>FS0988</NoWarn>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
Expand Down
54 changes: 39 additions & 15 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -825,23 +825,47 @@ and genExpr astContext synExpr =
let sepCloseT = tokN synExpr.Range "RPAREN" sepCloseT

match synExpr with
| ElmishReactWithoutChildren(identifier, attributes) ->
| ElmishReactWithoutChildren(identifier, isArray, children) ->
fun ctx ->
let maxRemainingArrayLength = ctx.Config.MaxElmishWidth - identifier.Length
let ctx' =
{ ctx with Config = { ctx.Config with
MaxArrayOrListWidth = maxRemainingArrayLength
// override user setting to get original fantomas formatting
MultilineBlockBracketsOnSameColumn = false } }
(!- identifier
+> sepSpace
+> genExpr astContext attributes
+> fun cty ->
// reset the config with original values
{ cty with Config = { cty.Config with
MaxArrayOrListWidth = ctx.Config.MaxArrayOrListWidth
MultilineBlockBracketsOnSameColumn = ctx.Config.MultilineBlockBracketsOnSameColumn } }) ctx'
let shortExpression =
let noChildren =
ifElse isArray sepOpenAFixed sepOpenLFixed
+> ifElse isArray sepCloseAFixed sepCloseLFixed

let genChildren =
ifElse isArray sepOpenA sepOpenL
+> col sepSemi children (genExpr astContext)
+> ifElse isArray sepCloseA sepCloseL

!- identifier
+> sepSpace
+> ifElse (List.isEmpty children) noChildren genChildren

let elmishExpression =
!- identifier
+> sepSpace
+> ifElse isArray sepOpenA sepOpenL
+> atCurrentColumn (col sepNln children (genExpr astContext))
+> ifElse isArray sepCloseA sepCloseL

let felizExpression =
atCurrentColumn (!- identifier
+> sepSpace
+> ifElse isArray sepOpenAFixed sepOpenLFixed
+> indent
+> sepNln
+> col sepNln children (genExpr astContext)
+> unindent
+> sepNln
+> ifElse isArray sepCloseAFixed sepCloseLFixed)

let multilineExpression = ifElse ctx.Config.SingleArgumentWebMode felizExpression elmishExpression

isShortExpression
ctx.Config.MaxElmishWidth
shortExpression
multilineExpression
ctx

| ElmishReactWithChildren((identifier,_,_), attributes, (isArray,children)) ->
let genChildren isShort =
Expand Down
2 changes: 1 addition & 1 deletion src/Fantomas/Fantomas.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Import Project="..\netfx.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>4.0.0-alpha-010</Version>
<Version>4.0.0-alpha-011</Version>
<Description>Source code formatter for F#</Description>
</PropertyGroup>
<ItemGroup>
Expand Down
2 changes: 2 additions & 0 deletions src/Fantomas/FormatConfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type FormatConfig =
NewlineBetweenTypeDefinitionAndMembers: bool
KeepIfThenInSameLine : bool
MaxElmishWidth: Num
SingleArgumentWebMode: bool
/// Prettyprinting based on ASTs only
StrictMode : bool }

Expand Down Expand Up @@ -65,6 +66,7 @@ type FormatConfig =
MultilineBlockBracketsOnSameColumn = false
KeepIfThenInSameLine = false
MaxElmishWidth = 40
SingleArgumentWebMode = false
NewlineBetweenTypeDefinitionAndMembers = false
StrictMode = false }

Expand Down
7 changes: 3 additions & 4 deletions src/Fantomas/SourceParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,10 +1427,9 @@ let isFunctionBinding (p: SynPat) =

let (|ElmishReactWithoutChildren|_|) e =
match e with
| App(OptVar(ident,_,_), [ArrayOrList(_) as attributes]) ->
Some(ident, attributes)
| App(OptVar(ident,_,_), [ArrayOrListOfSeqExpr(_, CompExpr(_, Sequentials _)) as attributes]) ->
Some(ident, attributes)
| App(OptVar(ident,_,_), [ArrayOrList(isArray, children, _)])
| App(OptVar(ident,_,_), [ArrayOrListOfSeqExpr(isArray, CompExpr(_, Sequentials children))]) ->
Some(ident, isArray, children)
| _ ->
None

Expand Down
3 changes: 3 additions & 0 deletions src/Fantomas/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@
"MaxElmishWidth": {
"type": "integer"
},
"SingleArgumentWebMode": {
"type": "boolean"
},
"StrictMode": {
"type": "boolean"
}
Expand Down

0 comments on commit db526ab

Please sign in to comment.