mirror of
https://github.com/unisonweb/unison.git
synced 2024-09-23 08:18:04 +03:00
Tweaks to Doc AST following feedback from Simon
Also added Pretty.table (untested)
This commit is contained in:
parent
270fc5cb69
commit
71d6837ec1
13
doc2.u
13
doc2.u
@ -1,16 +1,17 @@
|
||||
{-
|
||||
- [x] Debug the lexer/parser combination
|
||||
- [x] Implement display logic for doc type (Unison side)
|
||||
- [ ] Add to IOSource
|
||||
- [ ] Implement display logic for new doc type in DisplayValues
|
||||
- [x] Add to IOSource
|
||||
- [x] Implement display logic for new doc type in DisplayValues
|
||||
- [x] (Later) docs command should look for foo.doc if nothing is linked, or just have it do: display foo.doc
|
||||
- [x] (Later) Instant docs preview
|
||||
- [x] Review with Simon, Rúnar, to see if we're missing any elements
|
||||
- [x] Add missing element types to syntax tree
|
||||
- [ ] Write illustrative transcript (and possibly separate tests)
|
||||
- [ ] Review with Simon, Rúnar, to see if we're missing any elements
|
||||
- [ ] PR writeup
|
||||
- [ ] (Later) Pretty-printer should reverse the syntax
|
||||
- [ ] (Later) docs command should look for foo.doc if nothing is linked, or just have it do: display foo.doc
|
||||
- [ ] (Later) Top level types should allow anon doc blocks
|
||||
- [ ] (Later) Remove backticks syntax
|
||||
- [ ] (Later) Instant docs preview
|
||||
- [ ] (Later) Remove old doc, rename Doc2 to Doc
|
||||
-}
|
||||
|
||||
@ -283,7 +284,7 @@ _italics_ or *italics*
|
||||
|
||||
[The Unison website](https://unisonweb.org)
|
||||
|
||||
A link to a term: {Some}. A link to a type {type List}.
|
||||
A link to a term: {Some}. [A named link to the ''List'' type]({type List}).
|
||||
'''
|
||||
|
||||
Renders as:
|
||||
|
@ -6,6 +6,7 @@ module Unison.CommandLine.DisplayValues where
|
||||
|
||||
import Unison.Prelude
|
||||
|
||||
import Data.Foldable (foldrM)
|
||||
import Unison.Reference (Reference)
|
||||
import Unison.Referent (Referent)
|
||||
import Unison.Term (Term)
|
||||
@ -92,33 +93,43 @@ displayPretty pped terms typeOf eval types tm = go tm
|
||||
p <- go p
|
||||
pure $ initial <> P.indentAfterNewline afterNl p
|
||||
DD.PrettyAppend _ ps -> mconcat . toList <$> traverse go ps
|
||||
DD.PrettyTable _ rows ->
|
||||
let f :: Term v () -> [[Pretty]] -> m [[Pretty]]
|
||||
f (Term.List' (toList -> row)) rows = (:) <$> traverse go row <*> pure rows
|
||||
f _row rows = pure rows
|
||||
in P.table <$> foldrM f [] rows
|
||||
tm -> displayTerm pped terms typeOf eval types tm
|
||||
|
||||
goSrc es = do
|
||||
let tys = [ ref | DD.EitherLeft' (Term.TypeLink' ref) <- toList es ]
|
||||
toRef (Term.Ref' r) = Just r
|
||||
toRef (Term.RequestOrCtor' r _) = Just r
|
||||
toRef _ = Nothing
|
||||
tms = [ ref | DD.EitherRight' (DD.Doc2Term (toRef -> Just ref)) <- toList es ]
|
||||
typeMap <- let
|
||||
-- todo: populate the variable names / kind once BuiltinObject supports that
|
||||
go ref@(Reference.Builtin _) = pure (ref, DO.BuiltinObject)
|
||||
go ref = (ref,) <$> do
|
||||
decl <- types ref
|
||||
let missing = DO.MissingObject (SH.unsafeFromText $ Reference.toText ref)
|
||||
pure $ maybe missing DO.UserObject decl
|
||||
in Map.fromList <$> traverse go tys
|
||||
termMap <- let
|
||||
-- todo: populate the type signature once BuiltinObject supports that
|
||||
go ref@(Reference.Builtin _) = pure (ref, DO.BuiltinObject)
|
||||
go ref = (ref,) <$> do
|
||||
tm <- terms ref
|
||||
let missing = DO.MissingObject (SH.unsafeFromText $ Reference.toText ref)
|
||||
pure $ maybe missing DO.UserObject tm
|
||||
in Map.fromList <$> traverse go tms
|
||||
pure . P.indentN 4 $ OutputMessages.displayDefinitions' pped typeMap termMap
|
||||
|
||||
goSpecial = \case
|
||||
|
||||
DD.Doc2SpecialFormFoldedSource (Term.List' es) -> goSrc es
|
||||
|
||||
-- Source [Either Link.Type Doc2.Term]
|
||||
DD.Doc2SpecialFormSource (Term.List' es) -> do
|
||||
let tys = [ ref | DD.EitherLeft' (Term.TypeLink' ref) <- toList es ]
|
||||
toRef (Term.Ref' r) = Just r
|
||||
toRef (Term.RequestOrCtor' r _) = Just r
|
||||
toRef _ = Nothing
|
||||
tms = [ ref | DD.EitherRight' (DD.Doc2Term (toRef -> Just ref)) <- toList es ]
|
||||
typeMap <- let
|
||||
-- todo: populate the variable names / kind once BuiltinObject supports that
|
||||
go ref@(Reference.Builtin _) = pure (ref, DO.BuiltinObject)
|
||||
go ref = (ref,) <$> do
|
||||
decl <- types ref
|
||||
let missing = DO.MissingObject (SH.unsafeFromText $ Reference.toText ref)
|
||||
pure $ maybe missing DO.UserObject decl
|
||||
in Map.fromList <$> traverse go tys
|
||||
termMap <- let
|
||||
-- todo: populate the type signature once BuiltinObject supports that
|
||||
go ref@(Reference.Builtin _) = pure (ref, DO.BuiltinObject)
|
||||
go ref = (ref,) <$> do
|
||||
tm <- terms ref
|
||||
let missing = DO.MissingObject (SH.unsafeFromText $ Reference.toText ref)
|
||||
pure $ maybe missing DO.UserObject tm
|
||||
in Map.fromList <$> traverse go tms
|
||||
pure . P.indentN 4 $ OutputMessages.displayDefinitions' pped typeMap termMap
|
||||
DD.Doc2SpecialFormSource (Term.List' es) -> goSrc es
|
||||
|
||||
-- Example Nat Doc2.Term
|
||||
-- Examples like `foo x y` are encoded as `Example 2 (_ x y -> foo)`, where
|
||||
|
@ -326,8 +326,10 @@ lexemes' eof = P.optional space >> do
|
||||
atDoc = src <|> eval <|> signature <|> inlineSignature
|
||||
where
|
||||
comma = lit "," <* CP.space
|
||||
src = wrap "syntax.doc.source" $ do
|
||||
_ <- lit "@source" *> (lit " {" <|> lit "{") *> CP.space
|
||||
src = src' "syntax.doc.source" "@source" <|>
|
||||
src' "syntax.doc.foldedSource" "@foldedSource"
|
||||
src' name atName = wrap name $ do
|
||||
_ <- lit atName *> (lit " {" <|> lit "{") *> CP.space
|
||||
s <- join <$> P.sepBy1 (typeLink <|> termLink) comma
|
||||
_ <- lit "}"
|
||||
pure s
|
||||
|
@ -143,6 +143,7 @@ consoleTextRef = typeNamed "ConsoleText"
|
||||
|
||||
pattern Doc2SpecialFormRef <- ((== doc2SpecialFormRef) -> True)
|
||||
doc2SpecialFormSourceId = constructorNamed doc2SpecialFormRef "Doc2.SpecialForm.Source"
|
||||
doc2SpecialFormFoldedSourceId = constructorNamed doc2SpecialFormRef "Doc2.SpecialForm.FoldedSource"
|
||||
doc2SpecialFormExampleId = constructorNamed doc2SpecialFormRef "Doc2.SpecialForm.Example"
|
||||
doc2SpecialFormLinkId = constructorNamed doc2SpecialFormRef "Doc2.SpecialForm.Link"
|
||||
doc2SpecialFormSignatureId = constructorNamed doc2SpecialFormRef "Doc2.SpecialForm.Signature"
|
||||
@ -153,6 +154,7 @@ doc2SpecialFormEmbedId = constructorNamed doc2SpecialFormRef "Doc2.SpecialForm.E
|
||||
doc2SpecialFormInlineEmbedId = constructorNamed doc2SpecialFormRef "Doc2.SpecialForm.InlineEmbed"
|
||||
|
||||
pattern Doc2SpecialFormSource tm <- Term.App' (Term.Constructor' Doc2SpecialFormRef ((==) doc2SpecialFormSourceId -> True)) tm
|
||||
pattern Doc2SpecialFormFoldedSource tm <- Term.App' (Term.Constructor' Doc2SpecialFormRef ((==) doc2SpecialFormFoldedSourceId -> True)) tm
|
||||
pattern Doc2SpecialFormExample n tm <- Term.Apps' (Term.Constructor' Doc2SpecialFormRef ((==) doc2SpecialFormExampleId -> True)) [Term.Nat' n, tm]
|
||||
pattern Doc2SpecialFormLink tm <- Term.App' (Term.Constructor' Doc2SpecialFormRef ((==) doc2SpecialFormLinkId -> True)) tm
|
||||
pattern Doc2SpecialFormSignature tm <- Term.App' (Term.Constructor' Doc2SpecialFormRef ((==) doc2SpecialFormSignatureId -> True)) tm
|
||||
@ -170,25 +172,6 @@ pattern Doc2Example vs body <- Term.App' _term (Term.App' _any (Term.LamNamed' _
|
||||
pattern Doc2Term body <- Term.App' _term (Term.App' _any (Term.LamNamed' _ body))
|
||||
|
||||
pattern Doc2Ref <- ((== doc2Ref) -> True)
|
||||
doc2WordId = constructorNamed doc2Ref "Doc2.Word"
|
||||
doc2CodeId = constructorNamed doc2Ref "Doc2.Code"
|
||||
doc2CodeBlockId = constructorNamed doc2Ref "Doc2.CodeBlock"
|
||||
doc2BoldId = constructorNamed doc2Ref "Doc2.Bold"
|
||||
doc2ItalicId = constructorNamed doc2Ref "Doc2.Italic"
|
||||
doc2StrikethroughId = constructorNamed doc2Ref "Doc2.Strikethrough"
|
||||
doc2StyleId = constructorNamed doc2Ref "Doc2.Style"
|
||||
doc2BlockquoteId = constructorNamed doc2Ref "Doc2.Blockquote"
|
||||
doc2BlanklineId = constructorNamed doc2Ref "Doc2.Blankline"
|
||||
doc2SectionBreakId = constructorNamed doc2Ref "Doc2.SectionBreak"
|
||||
doc2AsideId = constructorNamed doc2Ref "Doc2.Aside"
|
||||
doc2CalloutId = constructorNamed doc2Ref "Doc2.Callout"
|
||||
doc2FoldedId = constructorNamed doc2Ref "Doc2.Folded"
|
||||
doc2PargraphId = constructorNamed doc2Ref "Doc2.Pargraph"
|
||||
doc2BulletedListId = constructorNamed doc2Ref "Doc2.BulletedList"
|
||||
doc2NumberedListId = constructorNamed doc2Ref "Doc2.NumberedList"
|
||||
doc2SectionId = constructorNamed doc2Ref "Doc2.Section"
|
||||
doc2SpecialId = constructorNamed doc2Ref "Doc2.Special"
|
||||
doc2DocsId = constructorNamed doc2Ref "Doc2.Docs"
|
||||
|
||||
pattern Doc2TermRef <- ((== doc2TermRef) -> True)
|
||||
|
||||
@ -200,6 +183,7 @@ prettyWrapId = constructorNamed prettyAnnotatedRef "Pretty.Annotated.Wrap"
|
||||
prettyOrElseId = constructorNamed prettyAnnotatedRef "Pretty.Annotated.OrElse"
|
||||
prettyIndentId = constructorNamed prettyAnnotatedRef "Pretty.Annotated.Indent"
|
||||
prettyAppendId = constructorNamed prettyAnnotatedRef "Pretty.Annotated.Append"
|
||||
prettyTableId = constructorNamed prettyAnnotatedRef "Pretty.Annotated.Table"
|
||||
|
||||
pattern PrettyEmpty ann <- Term.App' (Term.Constructor' PrettyAnnotatedRef ((==) prettyEmptyId -> True)) ann
|
||||
pattern PrettyGroup ann tm <- Term.Apps' (Term.Constructor' PrettyAnnotatedRef ((==) prettyGroupId -> True)) [ann, tm]
|
||||
@ -207,6 +191,7 @@ pattern PrettyLit ann tm <- Term.Apps' (Term.Constructor' PrettyAnnotatedRef ((=
|
||||
pattern PrettyWrap ann tm <- Term.Apps' (Term.Constructor' PrettyAnnotatedRef ((==) prettyWrapId -> True)) [ann, tm]
|
||||
pattern PrettyIndent ann i0 i1 tm <- Term.Apps' (Term.Constructor' PrettyAnnotatedRef ((==) prettyIndentId -> True)) [ann, i0, i1, tm]
|
||||
pattern PrettyOrElse ann p1 p2 <- Term.Apps' (Term.Constructor' PrettyAnnotatedRef ((==) prettyOrElseId -> True)) [ann, p1, p2]
|
||||
pattern PrettyTable ann rows <- Term.Apps' (Term.Constructor' PrettyAnnotatedRef ((==) prettyOrElseId -> True)) [ann, Term.List' rows]
|
||||
pattern PrettyAppend ann tms <- Term.Apps' (Term.Constructor' PrettyAnnotatedRef ((==) prettyAppendId -> True)) [ann, Term.List' tms]
|
||||
|
||||
pattern PrettyRef <- ((== prettyRef) -> True)
|
||||
@ -694,6 +679,8 @@ Doc2.term a = Doc2.Term.Term (Any a)
|
||||
|
||||
unique[da70bff6431da17fa515f3d18ded11852b6a745f] type Doc2.SpecialForm
|
||||
= Source [Either Link.Type Doc2.Term]
|
||||
-- like Source, but starts out folded
|
||||
| FoldedSource [Either Link.Type Doc2.Term]
|
||||
| Example Nat Doc2.Term
|
||||
| Link (Either Link.Type Doc2.Term)
|
||||
| Signature [Doc2.Term]
|
||||
@ -714,16 +701,25 @@ unique[b7a4fb87e34569319591130bf3ec6e24c9955b6a] type Doc2
|
||||
| Style Doc2 Doc2
|
||||
| Blockquote Doc2
|
||||
| Blankline
|
||||
| Linebreak
|
||||
| SectionBreak
|
||||
| Aside (Optional Doc2) Doc2
|
||||
-- callout icon content
|
||||
-- Tooltip inner tooltipContent
|
||||
| Tooltip Doc2 Doc2
|
||||
-- Aside asideContent
|
||||
| Aside Doc2
|
||||
-- Callout icon content
|
||||
| Callout (Optional Doc2) Doc2
|
||||
-- Table rows
|
||||
| Table [[Doc2]]
|
||||
-- Folded isFolded summary details
|
||||
| Folded Boolean Doc2 Doc2
|
||||
| Paragraph [Doc2]
|
||||
| BulletedList [Doc2]
|
||||
| NumberedList Nat [Doc2]
|
||||
| Section Doc2 [Doc2]
|
||||
| NamedLink Doc2 Doc2
|
||||
-- image alt text link caption
|
||||
| Image Doc2 Doc2 (Optional Doc2)
|
||||
| Special Doc2.SpecialForm
|
||||
| Docs [Doc2]
|
||||
|
||||
@ -733,6 +729,8 @@ unique[d7b2ced8c08b2c6e54050d1f5acedef3395f293d] type Pretty.Annotated w txt
|
||||
| Lit w txt
|
||||
| Wrap w (Pretty.Annotated w txt)
|
||||
| OrElse w (Pretty.Annotated w txt) (Pretty.Annotated w txt)
|
||||
-- table rows
|
||||
| Table w [[Pretty.Annotated w txt]]
|
||||
-- Indent _ initialIndent indentAfterNewline p prefixes the first
|
||||
-- line of `p` with `initialIndent`, and subsequent lines by `indentAfterNewline`.
|
||||
| Indent w (Pretty.Annotated w txt) (Pretty.Annotated w txt) (Pretty.Annotated w txt)
|
||||
@ -799,6 +797,9 @@ Pretty.indent' initialIndent indentAfterNewline p =
|
||||
(Pretty.get indentAfterNewline)
|
||||
(Pretty.get p))
|
||||
|
||||
Pretty.table : [[Pretty txt]] -> Pretty txt
|
||||
Pretty.table rows = Pretty (Annotated.Table () (List.map (List.map Pretty.get) rows))
|
||||
|
||||
Pretty.append : Pretty txt -> Pretty txt -> Pretty txt
|
||||
Pretty.append p1 p2 =
|
||||
use Pretty.Annotated Empty Append
|
||||
@ -838,6 +839,7 @@ syntax.doc.embedTypeLink typ =
|
||||
guid = "b7a4fb87e34569319591130bf3ec6e24"
|
||||
Left typ
|
||||
syntax.doc.source t = Special (Source t)
|
||||
syntax.doc.foldedSource t = Special (FoldedSource t)
|
||||
syntax.doc.signature ts = Special (Signature ts)
|
||||
syntax.doc.inlineSignature t = Special (InlineSignature t)
|
||||
syntax.doc.inlineEval e = Special (InlineEval (Doc2.term e))
|
||||
@ -903,12 +905,14 @@ syntax.doc.formatConsole d =
|
||||
Style _ d -> go d
|
||||
Blockquote d -> Pretty.indent (lit "> ") (go d)
|
||||
Blankline -> lit "\n\n"
|
||||
Linebreak -> lit "\n"
|
||||
SectionBreak -> lit "܍"
|
||||
Aside None d -> Pretty.indent (lit " | ") (go d)
|
||||
Aside (Some title) d ->
|
||||
Pretty.indent (lit " | ") (go (Doc2.Bold title) <> nl <> nl <> go d)
|
||||
Callout icon d -> go (Aside icon d) --
|
||||
Folded _ _closed open -> go open
|
||||
Tooltip inner _ -> go inner
|
||||
Aside d -> Pretty.indent (lit " | ") (go d)
|
||||
Callout None d -> go (Aside d)
|
||||
Callout (Some icon) d -> go (Aside (Section icon [d]))
|
||||
Doc2.Table rows -> Pretty.table (List.map (List.map go) rows)
|
||||
Folded _ summary details -> go summary <> go details
|
||||
Paragraph ds -> Pretty.wrap (Pretty.join (List.map go ds))
|
||||
BulletedList ds ->
|
||||
item d = Pretty.indent' (lit "* ") (lit " ") (go d)
|
||||
@ -930,6 +934,8 @@ syntax.doc.formatConsole d =
|
||||
Pretty.sepBy (nl <> nl) (t +: subs)
|
||||
Docs ds -> Pretty.join (List.map go ds)
|
||||
NamedLink name _target -> map ConsoleText.Underline (go name)
|
||||
Image alt _link (Some caption) -> Pretty.sepBy nl [go alt, go (Italic caption)]
|
||||
Image alt _link None -> go alt
|
||||
Special sf -> Pretty.lit (Left sf)
|
||||
go d
|
||||
|]
|
||||
|
@ -446,6 +446,7 @@ doc2Block =
|
||||
"syntax.doc.paragraph" -> variadic
|
||||
"syntax.doc.signature" -> variadic
|
||||
"syntax.doc.source" -> variadic
|
||||
"syntax.doc.foldedSource" -> variadic
|
||||
"syntax.doc.bulletedList" -> variadic
|
||||
"syntax.doc.numberedList" -> do
|
||||
nitems@((n,_):_) <- P.some nitem <* closeBlock
|
||||
|
@ -90,6 +90,7 @@ module Unison.Util.Pretty (
|
||||
string,
|
||||
surroundCommas,
|
||||
syntaxToColor,
|
||||
table,
|
||||
text,
|
||||
toANSI,
|
||||
toAnsiUnbroken,
|
||||
@ -520,6 +521,20 @@ excerptColumn2 max cols = case max of
|
||||
_ -> column2 cols
|
||||
where len = length cols
|
||||
|
||||
table :: (IsString s, LL.ListLike s Char) => [[Pretty s]] -> Pretty s
|
||||
table rows = lines (table' rows)
|
||||
|
||||
table' :: (IsString s, LL.ListLike s Char) => [[Pretty s]] -> [Pretty s]
|
||||
table' [] = mempty
|
||||
table' rows = case maximum (Prelude.length <$> rows) of
|
||||
1 -> rows >>= \case
|
||||
[] -> [mempty]
|
||||
hd : _ -> [hd]
|
||||
_ -> let
|
||||
colHd = [ h | (h:_) <- rows ]
|
||||
colTl = [ t | (_:t) <- rows ]
|
||||
in align (colHd `zip` table' colTl)
|
||||
|
||||
column2
|
||||
:: (LL.ListLike s Char, IsString s) => [(Pretty s, Pretty s)] -> Pretty s
|
||||
column2 = column2sep ""
|
||||
|
Loading…
Reference in New Issue
Block a user