Skip to content

Commit

Permalink
Try to prevent more flickering
Browse files Browse the repository at this point in the history
  • Loading branch information
maralorn committed Nov 28, 2024
1 parent 980a31a commit da6cbce
Showing 1 changed file with 36 additions and 27 deletions.
63 changes: 36 additions & 27 deletions lib/NOM/IO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ runUpdate output_builder_var state_var refresh_display_var updater input = do
modifyTVar' output_builder_var (log_output :)
modifyTVar' refresh_display_var (|| display_changed)

-- https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec
startAtomicUpdate :: Builder.Builder
startAtomicUpdate = "\x1b[?2026h"

endAtomicUpdate :: Builder.Builder
endAtomicUpdate = "\x1b[?2026l"

writeStateToScreen ::
forall state.
Bool ->
Expand Down Expand Up @@ -126,34 +133,36 @@ writeStateToScreen pad printed_lines_var nom_state_var nix_output_buffer_var ref
output =
toStrict
. Builder.toLazyByteString
$
-- when we clear the line, but don‘t use cursorUpLine, the cursor needs to be moved to the start for printing.
-- we do that before clearing because we can
memptyIfFalse (last_printed_line_count == 1) (Builder.stringUtf8 $ Terminal.setCursorColumnCode 0)
<>
-- Clear last output from screen.
-- First we clear the current line, if we have written on it.
memptyIfFalse (last_printed_line_count > 0) (Builder.stringUtf8 Terminal.clearLineCode)
<>
-- Then, if necessary we, move up and clear more lines.
stimesMonoid
(max (last_printed_line_count - 1) 0)
( Builder.stringUtf8 (Terminal.cursorUpLineCode 1) -- Moves cursor one line up and to the beginning of the line.
<> Builder.stringUtf8 Terminal.clearLineCode -- We are avoiding to use clearFromCursorToScreenEnd
-- because it apparently triggers a flush on some terminals.
)
<>
-- Insert the output to write to the screen.
( output_to_print_with_newline_annotations & foldMap \(newline, line) ->
( case newline of
StayInLine -> mempty
MoveToNextLine -> Builder.stringUtf8 (Terminal.cursorDownLineCode 1)
PrintNewLine -> Builder.byteString "\n"
$ startAtomicUpdate
<>
-- when we clear the line, but don‘t use cursorUpLine, the cursor needs to be moved to the start for printing.
-- we do that before clearing because we can
memptyIfFalse (last_printed_line_count == 1) (Builder.stringUtf8 $ Terminal.setCursorColumnCode 0)
<>
-- Clear last output from screen.
-- First we clear the current line, if we have written on it.
memptyIfFalse (last_printed_line_count > 0) (Builder.stringUtf8 Terminal.clearLineCode)
<>
-- Then, if necessary we, move up and clear more lines.
stimesMonoid
(max (last_printed_line_count - 1) 0)
( Builder.stringUtf8 (Terminal.cursorUpLineCode 1) -- Moves cursor one line up and to the beginning of the line.
<> Builder.stringUtf8 Terminal.clearLineCode -- We are avoiding to use clearFromCursorToScreenEnd
-- because it apparently triggers a flush on some terminals.
)
<> Builder.byteString line
)
-- Corner case: If nom is not outputting anything but we are printing output from nix, then we want to append a newline
<> memptyIfFalse (nom_output_length == 0 && nix_output_length > 0) Builder.byteString "\n"
<>
-- Insert the output to write to the screen.
( output_to_print_with_newline_annotations & foldMap \(newline, line) ->
( case newline of
StayInLine -> mempty
MoveToNextLine -> Builder.stringUtf8 (Terminal.cursorDownLineCode 1)
PrintNewLine -> Builder.byteString "\n"
)
<> Builder.byteString line
)
-- Corner case: If nom is not outputting anything but we are printing output from nix, then we want to append a newline
<> memptyIfFalse (nom_output_length == 0 && nix_output_length > 0) Builder.byteString "\n"
<> endAtomicUpdate

-- Actually write to the buffer. We do this all in one step and with a strict
-- ByteString so that everything is precalculated and the actual put is
Expand Down

0 comments on commit da6cbce

Please sign in to comment.