~exitb/retrofit

ec589557b9539bce76bf88b7989d7bf6cb26f6f6 — exitb 1 year, 10 months ago bb493ee
Better handling of EraseInDisplay and other ANSI sequences
1 files changed, 63 insertions(+), 15 deletions(-)

M src/adapter.rs
M src/adapter.rs => src/adapter.rs +63 -15
@@ 363,6 363,13 @@ where
        }

        self.fill_line();

        self.push_code(AnsiCode::ControlSequence {
            introducer: ControlSequenceIntroducer::SelectGraphicRendition,
            parameters: self
                .brush
                .render(self.parameters.truecolor, self.parameters.ice_colors),
        });
    }

    fn finish(&mut self) {


@@ 504,33 511,64 @@ where
                        false
                    }
                    ControlSequenceIntroducer::EraseInDisplay => {
                        /* We need to prevent passing on the regular clear screen, as that
                        would pollute non-black terminals with black or colored portions
                        of the screen.  The course of action is then to:
                         - clear the graphic rendition mode
                         - clear the screen to its native colors
                         - set the cursor at top left corner
                         - set the previous graphic rendition
                         - fill the virtual screen with desired color
                         - bring the cursor back to the top left */

                        if parameters.as_slice() != [2] {
                            return Err(Error::EraseInDisplayUnsupportedParameter(parameters));
                        }

                        let difference = if let Some(height) = self.parameters.height {
                            if self.position.line > height as usize {
                                height as usize
                            } else {
                                self.position.line
                        let current_brush = self.brush.clone();

                        self.push_code(AnsiCode::ControlSequence {
                            introducer: ControlSequenceIntroducer::SelectGraphicRendition,
                            parameters: vec![],
                        });

                        self.push_code(AnsiCode::ControlSequence {
                            introducer: ControlSequenceIntroducer::EraseInDisplay,
                            parameters: vec![2],
                        });

                        self.push_code(AnsiCode::ControlSequence {
                            introducer: ControlSequenceIntroducer::CursorPosition,
                            parameters: vec![],
                        });

                        self.position = Position::new();

                        self.push_code(AnsiCode::ControlSequence {
                            introducer: ControlSequenceIntroducer::SelectGraphicRendition,
                            parameters: current_brush
                                .render(self.parameters.truecolor, self.parameters.ice_colors),
                        });

                        let height = self.parameters.height.unwrap_or(25);

                        for _ in 0..height {
                            for _ in 0..self.parameters.width {
                                self.push_code(AnsiCode::Printable(' '));
                            }
                        } else {
                            self.position.line
                        };

                            self.push_code(AnsiCode::ControlCharacter('\n'));
                        }

                        self.push_code(AnsiCode::ControlSequence {
                            introducer: ControlSequenceIntroducer::CursorUp,
                            parameters: vec![difference as u16],
                            parameters: vec![height],
                        });

                        self.position.line -= difference;
                        self.push_code(AnsiCode::ControlCharacter('\r'));
                        self.position.column = 0;

                        true
                        false
                    }
                    ControlSequenceIntroducer::CursorPosition => {
                        self.position.line = match parameters.get(0) {
                        let new_line = match parameters.get(0) {
                            Some(0) | None => 0,
                            Some(n) => *n as usize - 1,
                        };


@@ 540,6 578,16 @@ where
                            Some(n) => n - 1,
                        };

                        if new_line > self.position.line {
                            let lines_to_create = new_line - self.position.line;

                            for _ in 0..lines_to_create {
                                self.new_line();
                            }
                        } else {
                            self.position.line = new_line;
                        }

                        self.push_code(AnsiCode::ControlSequence {
                            introducer: ControlSequenceIntroducer::CursorPosition,
                            parameters: vec![