Skip to content

Commit 51ceb2b

Browse files
committed
UI: Don't persist screens after they quit unless explicitly requested
1 parent 4b031af commit 51ceb2b

11 files changed

Lines changed: 81 additions & 34 deletions

File tree

packages/hix/lib/Hix/Data/Monad.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ data AppResources =
3434
target :: OutputTarget,
3535
theme :: Theme,
3636
tui :: TuiHandlers M,
37-
context :: [AppContext]
37+
context :: [AppContext],
38+
persistentUi :: Bool
3839
}
3940
deriving stock (Generic)
4041

packages/hix/lib/Hix/Managed/Data/ReleaseConfig.hs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ data ReleaseConfig =
6464
merge :: Bool,
6565
-- | Use the global Cabal configuration file instead of hermetic @/dev/null@.
6666
-- This allows using credentials configured in @~\/.cabal\/config@ but sacrifices reproducibility.
67-
globalCabalConfig :: Bool
67+
globalCabalConfig :: Bool,
68+
-- | Keep the Brick UI screens rendered on the terminal after they are completed.
69+
-- When 'False' (default), the cursor is reset to overwrite the UI and a log message is printed instead.
70+
persistentUi :: Bool
6871
}
6972
deriving stock (Eq, Show)
7073

@@ -85,5 +88,6 @@ instance Default ReleaseConfig where
8588
forceVersion = False,
8689
check = False,
8790
merge = False,
88-
globalCabalConfig = False
91+
globalCabalConfig = False,
92+
persistentUi = False
8993
}

packages/hix/lib/Hix/Managed/Handlers/ReleaseUi/DistTargets/Run.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ chooseDistTargetsNe debug checksPassed packages = do
4545
render,
4646
startEvent = unit,
4747
debug,
48-
initialContext = uiDistTargets checksPassed packages
48+
initialContext = uiDistTargets checksPassed packages,
49+
screenLog = "Completed distribution target selection"
4950
}
5051

5152
chooseDistTargets ::

packages/hix/lib/Hix/Managed/Handlers/ReleaseUi/UploadTargets/Run.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module Hix.Managed.Handlers.ReleaseUi.UploadTargets.Run where
22

3+
import Exon (exon)
4+
35
import Hix.Class.Map (nList)
46
import Hix.Data.Monad (M)
57
import Hix.Data.PackageName (LocalPackage)
@@ -47,7 +49,8 @@ chooseUploadTargetsNe debug stage packages = do
4749
render,
4850
startEvent = unit,
4951
debug,
50-
initialContext = uiUploadTargets stage packages
52+
initialContext = uiUploadTargets stage packages,
53+
screenLog = [exon|Completed #{showP stage} target selection|]
5154
}
5255

5356
chooseUploadTargets ::

packages/hix/lib/Hix/Managed/Handlers/ReleaseUi/VersionProblems/Run.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ chooseVersionProblems debug problems = do
3838
render,
3939
startEvent = unit,
4040
debug,
41-
initialContext = uiVersionProblems problems
41+
initialContext = uiVersionProblems problems,
42+
screenLog = "Completed version problem review"
4243
}

packages/hix/lib/Hix/Managed/Handlers/ReleaseUi/Versions/Run.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@ chooseVersions debug sharedVersion targets = do
4141
render,
4242
startEvent = unit,
4343
debug,
44-
initialContext = uiVersions sharedVersion targets
44+
initialContext = uiVersions sharedVersion targets,
45+
screenLog = "Completed version selection"
4546
}

packages/hix/lib/Hix/Managed/Release.hs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Exon (exon)
44
import Path (Abs, File, Path)
55

66
import Hix.Class.Map (nMap, nNull, nSize)
7+
import qualified Hix.Data.Monad as AppResources
78
import Hix.Data.Monad (AppResources (..), M, appRes)
89
import Hix.Data.Options (ReleaseOptions (..))
910
import Hix.Data.PackageName (LocalPackage)
@@ -36,7 +37,7 @@ import qualified Hix.Managed.Release.Report as Report
3637
import Hix.Managed.Release.Staged (ReleaseStage (..))
3738
import Hix.Managed.Release.StateVersions (updateStateVersions)
3839
import Hix.Managed.Release.Validation (ProblematicVersion, findProblematicVersions, validateVersionsBatch)
39-
import Hix.Monad (appContext, ask, clientError)
40+
import Hix.Monad (appContext, ask, clientError, local)
4041
import Hix.Pretty (showP)
4142

4243
-- | Handle post-upload activities: execute hooks and commit git changes.
@@ -185,6 +186,7 @@ releaseCli options = do
185186
context <- jsonOrQueryProd ContextRelease options.context
186187
cabal <- cabalConfig context.hackage options.cabal
187188
handlers <- Release.handlersProd options cabal
188-
release handlers options.config context >>= \case
189-
ReleaseStage {state = ReleaseState {termination = Termination _}} -> clientError "Release failed."
190-
_ -> unit
189+
local (\ res -> res {AppResources.persistentUi = options.config.persistentUi}) do
190+
release handlers options.config context >>= \case
191+
ReleaseStage {state = ReleaseState {termination = Termination _}} -> clientError "Release failed."
192+
_ -> unit

packages/hix/lib/Hix/Monad/Run.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ runMTuiWith tui GlobalOptions {..} ma =
3535
context = [],
3636
cwd = resolvedCwd,
3737
root = resolvedRoot,
38+
persistentUi = True,
3839
..
3940
}
4041
ExceptT (runMUsing resources ma)

packages/hix/lib/Hix/Options.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ releaseConfigParser = do
509509
check <- switch (long "check" <> help "Run flake checks before uploading")
510510
merge <- switch (long "merge" <> help "Merge the release branch back into the initial branch after successful uploads")
511511
globalCabalConfig <- switch (long "global-cabal-config" <> help "Use the global Cabal config for Hackage servers in addition to the flake config")
512+
persistentUi <- switch (long "persistent-ui" <> help "Keep interactive UI screens visible on the terminal after completion")
512513
pure ReleaseConfig {candidates = selectCandidates publish candidatesSpec, ..}
513514
where
514515
versionHelp = "New version or increment (super|major|minor|patch)"

packages/hix/lib/Hix/Terminal/State.hs

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@ module Hix.Terminal.State where
22

33
import Control.Monad.Catch (bracket)
44
import Data.IORef (IORef, newIORef, readIORef)
5-
import System.Console.ANSI (hHideCursor, hSaveCursor, hSetCursorColumn, hSetCursorPosition, hShowCursor)
5+
import System.Console.ANSI (
6+
hClearLine,
7+
hCursorDown,
8+
hHideCursor,
9+
hSaveCursor,
10+
hSetCursorColumn,
11+
hSetCursorPosition,
12+
hShowCursor,
13+
)
614
import System.IO (BufferMode (..), Handle, hFlush, hGetBuffering, hPutStr, hSetBuffering, hSetEcho, stdin)
715
import System.Posix (Fd)
816

9-
import Hix.Data.Monad (M)
17+
import Hix.Data.Monad (AppResources (..), M, appRes)
1018
import Hix.Error (ignoringIOErrors)
1119
import Hix.Monad (appContextVerboseIO)
1220
import Hix.Terminal.Geometry (runRender, terminalGeometry)
@@ -58,37 +66,56 @@ hInitializeTerminal tuiState = do
5866
stateRef <- newOutputState tuiState
5967
pure (bufMode, stateRef)
6068

61-
-- | After a Brick app exits, move the cursor below the rendered area so subsequent output
62-
-- (log messages, next UI) doesn't overwrite the previous content.
63-
repositionCursor :: Handle -> IORef OutputState -> IO ()
64-
repositionCursor hOut stateRef = do
69+
-- | After a Brick app exits, reposition the cursor.
70+
--
71+
-- When @persistent@ is 'True', move below the rendered area so subsequent output doesn't
72+
-- overwrite the previous content.
73+
--
74+
-- When @persistent@ is 'False', move back to the first line of the rendered area and clear
75+
-- the lines so the next output starts where the UI was.
76+
repositionCursor :: Bool -> Handle -> IORef OutputState -> IO ()
77+
repositionCursor persistent hOut stateRef = do
6578
OutputState {firstLine, lastRenderHeight} <- readIORef stateRef
6679
when (lastRenderHeight > 0) do
67-
-- Move to the last rendered line and emit a newline.
68-
-- This works even when the cursor is at the bottom of the terminal,
69-
-- where hSetCursorPosition would be clamped and fail to advance.
70-
let lastLine = firstLine + lastRenderHeight - 1
71-
hSetCursorPosition hOut lastLine 0
72-
hPutStr hOut "\n"
73-
hFlush hOut
80+
if persistent
81+
then do
82+
-- Move to the last rendered line and emit a newline.
83+
-- This works even when the cursor is at the bottom of the terminal,
84+
-- where hSetCursorPosition would be clamped and fail to advance.
85+
let lastLine = firstLine + lastRenderHeight - 1
86+
hSetCursorPosition hOut lastLine 0
87+
hPutStr hOut "\n"
88+
hFlush hOut
89+
else do
90+
-- Move back to the first line and clear the rendered area.
91+
hSetCursorPosition hOut firstLine 0
92+
replicateM_ lastRenderHeight do
93+
hClearLine hOut
94+
hCursorDown hOut 1
95+
hSetCursorPosition hOut firstLine 0
96+
hFlush hOut
7497

7598
hResetTerminal ::
99+
Bool ->
76100
IORef VtyTuiResources ->
77101
(BufferMode, IORef OutputState) ->
78102
IO ()
79-
hResetTerminal tuiState (hInMode, stateRef) = do
103+
hResetTerminal persistent tuiState (hInMode, stateRef) = do
80104
VtyTuiResources {hIn, hOut} <- readIORef tuiState
81-
ignoringIOErrors $ repositionCursor hOut stateRef
82-
ignoringIOErrors $ hShowCursor hOut
83-
ignoringIOErrors $ hFlush hOut
84-
ignoringIOErrors $ hSetEcho hIn True
85-
ignoringIOErrors $ hSetBuffering hIn hInMode
105+
traverse_ @[] ignoringIOErrors [
106+
repositionCursor persistent hOut stateRef,
107+
hShowCursor hOut,
108+
hFlush hOut,
109+
hSetEcho hIn True,
110+
hSetBuffering hIn hInMode
111+
]
86112

87113
bracketTerminal ::
88114
IORef VtyTuiResources ->
89115
(IORef OutputState -> IO a) ->
90116
M a
91-
bracketTerminal tuiState use =
117+
bracketTerminal tuiState use = do
118+
persistent <- appRes.persistentUi
92119
appContextVerboseIO "running brick app" do
93-
bracket (hInitializeTerminal tuiState) (hResetTerminal tuiState) \ (_, stateRef) ->
120+
bracket (hInitializeTerminal tuiState) (hResetTerminal persistent tuiState) \ (_, stateRef) ->
94121
use stateRef

0 commit comments

Comments
 (0)