diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2026-05-24 10:42:39 +0200 |
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2026-05-24 11:05:36 +0200 |
| commit | 791c532682578c0dd1a0e3779f36ccfbced93d60 (patch) | |
| tree | 979f2ada553f905c5626085337a790a6f4688a2a /main | |
| parent | 98922becf64e361d87d8092c59d3c53362d21c2d (diff) | |
Terminal: functions to update lines
Diffstat (limited to 'main')
| -rw-r--r-- | main/Terminal.hs | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/main/Terminal.hs b/main/Terminal.hs index 89444e6..b516f93 100644 --- a/main/Terminal.hs +++ b/main/Terminal.hs @@ -13,6 +13,8 @@ module Terminal ( TerminalLine, printLine, + updateLine, + updateLinePart, printBottomLines, clearBottomLines, @@ -55,10 +57,12 @@ data Terminal = Terminal , termHistory :: TVar [ String ] , termHistoryPos :: TVar Int , termHistoryStash :: TVar ( String, String ) + , termBottomIndex :: TVar Int } data TerminalLine = TerminalLine { tlTerminal :: Terminal + , tlLineIndex :: Int , tlLineCount :: Int } @@ -102,6 +106,7 @@ initTerminal termCompletionFunc = do termHistory <- newTVarIO [] termHistoryPos <- newTVarIO 0 termHistoryStash <- newTVarIO ( "", "" ) + termBottomIndex <- newTVarIO 0 return Terminal {..} bracketSet :: IO a -> (a -> IO b) -> a -> IO c -> IO c @@ -166,7 +171,9 @@ getInputLine term@Terminal {..} handleResult = do writeTVar termHistoryPos 0 ( x, clear ) <- case handleResult mbLine of - KeepPrompt x -> return ( x, \statusLen -> AnsiText $ "\ESC[" <> T.pack (show statusLen) <> "G\ESC[1K\n\ESC[J" ) + KeepPrompt x -> do + atomically $ writeTVar termBottomIndex . (+ 1) =<< readTVar termBottomIndex + return ( x, \statusLen -> AnsiText $ "\ESC[" <> T.pack (show statusLen) <> "G\ESC[1K\n\ESC[J" ) ErasePrompt x -> return ( x, \_ -> AnsiText "\r\ESC[J" ) when termAnsi $ do withMVar termLock $ \_ -> do @@ -390,9 +397,31 @@ printLine tlTerminal@Terminal {..} str = do else do T.putStr $ renderPlainText $ endWithNewline str + tlLineIndex <- atomically $ do + bindex <- readTVar termBottomIndex + writeTVar termBottomIndex $ bindex + tlLineCount + return bindex + hFlush stdout return TerminalLine {..} +updateLine :: TerminalLine -> FormattedText -> IO () +updateLine tl str = updateLinePart tl 0 (str <> "\ESC[K") + +updateLinePart :: TerminalLine -> Int -> FormattedText -> IO () +updateLinePart TerminalLine {..} offset str = do + let Terminal {..} = tlTerminal + when termAnsi $ do + withMVar termLock $ \_ -> do + let updLineCount = formattedTextHeight str + bindex <- atomically $ readTVar termBottomIndex + putAnsi $ mconcat + [ AnsiText $ "\ESC[s\ESC[" <> T.pack (show (bindex - tlLineIndex)) <> "F\ESC[" <> T.pack (show (offset + 1)) <> "G" + , renderAnsiText str + , mconcat $ replicate (tlLineCount - updLineCount) $ AnsiText "\r\ESC[K" + , AnsiText $ "\ESC[u" + ] + printBottomLines :: Terminal -> String -> IO () printBottomLines Terminal { termAnsi = False } _ = do |