Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiline REPL #2092

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/swarm-tui/Swarm/TUI/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ handleREPLEventTyping = \case
-- On any other key event, jump to the bottom of the REPL then handle the event
vScrollToEnd replScroll
case k of
MetaChar 'm' ->
Brick.zoom (uiState . uiGameplay . uiREPL . replPromptEditor) $
handleEditorEvent (Key V.KEnter)
Key V.KEnter -> do
s <- get
let theRepl = s ^. uiState . uiGameplay . uiREPL
Expand Down Expand Up @@ -741,8 +744,8 @@ validateREPLForm s =
let env = s ^. gameState . baseEnv
(theType, errSrcLoc) = case readTerm' defaultParserConfig uinput of
Left err ->
let ((_y1, x1), (_y2, x2), _msg) = showErrorPos err
in (Nothing, Left (SrcLoc x1 x2))
let ((y1, x1), (y2, x2), _msg) = showErrorPos err
in (Nothing, Left (SrcLoc (y2x y1 + x1) (y2x y2 + x2)))
Right Nothing -> (Nothing, Right ())
Right (Just theTerm) -> case processParsedTerm' env theTerm of
Right t -> (Just (t ^. sType), Right ())
Expand All @@ -754,6 +757,8 @@ validateREPLForm s =
where
uinput = s ^. uiState . uiGameplay . uiREPL . replPromptText
replPrompt = s ^. uiState . uiGameplay . uiREPL . replPromptType
uLineCounts = T.length <$> T.lines uinput
y2x n = n + sum (take n uLineCounts)

-- | Update our current position in the REPL history.
adjReplHistIndex :: TimeDir -> AppState -> AppState
Expand Down
4 changes: 2 additions & 2 deletions src/swarm-tui/Swarm/TUI/Model/Repl.hs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ data REPLState = REPLState
}

newREPLEditor :: Text -> Editor Text Name
newREPLEditor t = applyEdit gotoEnd $ editorText REPLInput (Just 1) t
newREPLEditor t = applyEdit gotoEnd $ editorText REPLInput (Just 5) t
where
ls = T.lines t
pos = (length ls - 1, T.length (last ls))
Expand Down Expand Up @@ -360,7 +360,7 @@ replPromptEditor :: Lens' REPLState (Editor Text Name)
replPromptText :: Lens' REPLState Text
replPromptText = lens g s
where
g r = r ^. replPromptEditor . to getEditContents . to T.concat
g r = r ^. replPromptEditor . to getEditContents . to T.unlines
s r t = r & replPromptEditor .~ newREPLEditor t

-- | Whether the prompt text is a valid 'Swarm.Language.Syntax.Term'.
Expand Down
22 changes: 19 additions & 3 deletions src/swarm-tui/Swarm/TUI/View.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,8 @@ drawRecipe me inv (Recipe ins outs reqs time _weight) =
hBox
[ padRight (Pad 1) $ str (show n) -- how many?
, fmtEntityName missing ingr -- name of the input
, padLeft (Pad 1) $ -- a connecting line: ─────┬
, padLeft (Pad 1) $ -- a connecting line: ─────┬ -- a connecting line: ─────┬
-- a connecting line: ─────┬
hBorder
<+> ( joinableBorder (Edges (i /= 0) (i /= inLen - 1) True False) -- ...maybe plus vert ext: │
<=> if i /= inLen - 1
Expand Down Expand Up @@ -1568,13 +1569,28 @@ renderREPLPrompt focus theRepl = ps1 <+> replE
Right () -> txt t
Left NoLoc -> withAttr redAttr (txt t)
Left (SrcLoc s e) | s == e || s >= T.length t -> withAttr redAttr (txt t)
-- TODO: ABSOLUTE HELL OF BUGS, NEEDS LINE NUMBERS
Left (SrcLoc s e) ->
let (validL, (invalid, validR)) = T.splitAt (e - s) <$> T.splitAt s t
in hBox [txt validL, withAttr redAttr (txt invalid), txt validR]
(validLs, validLl) = fromMaybe ([], validL) . unsnoc $ T.splitOn "\n" validL
(validRl, validRs) = fromMaybe (validR, []) . uncons $ T.splitOn "\n" validR
redLines = case T.lines invalid of
[] -> [withAttr redAttr $ txt validLl <+> txt validRl] -- should not happen
[i1] -> [txt validLl <+> withAttr redAttr (txt i1) <+> txt validRl]
[i1, i2] ->
[ txt validLl <+> withAttr redAttr (txt i1)
, withAttr redAttr (txt i2) <+> txt validRl
]
(i1 : iss) ->
[ txt validLl <+> withAttr redAttr (txt i1)
, withAttr redAttr (txt . T.unlines $ init iss)
, withAttr redAttr (txt $ last iss) <+> txt validRl
]
in vBox $ map txt validLs <> redLines <> map txt validRs
ps1 = replPromptAsWidget (T.concat $ getEditContents replEditor) prompt
replE =
renderEditor
(vBox . map color)
(color . T.unlines)
(focusGetCurrent focus `elem` [Nothing, Just (FocusablePanel REPLPanel), Just REPLInput])
replEditor

Expand Down
Loading