diff --git a/vlib/term/ui/input.v b/vlib/term/ui/input.v index d43b3f3f9e..6a3e2f510d 100644 --- a/vlib/term/ui/input.v +++ b/vlib/term/ui/input.v @@ -168,6 +168,7 @@ mut: read_buf []byte print_buf []byte paused bool + enable_su bool pub mut: frame_count u64 window_width int diff --git a/vlib/term/ui/termios_nix.c.v b/vlib/term/ui/termios_nix.c.v index fa6043c583..7a5572fe45 100644 --- a/vlib/term/ui/termios_nix.c.v +++ b/vlib/term/ui/termios_nix.c.v @@ -75,13 +75,31 @@ fn (mut ctx Context) termios_setup() { print('\x1b]0;$ctx.cfg.window_title\x07') } + C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios) + // feature-test the SU spec + sx, sy := get_cursor_position() + print('$bsu$esu') + ex, ey := get_cursor_position() + + if sx == ex && sy == ey { + // the terminal either ignored or handled the sequence properly, enable SU + ctx.enable_su = true + } else { + ctx.draw_line(sx, sy, ex, ey) + ctx.set_cursor_position(sx, sy) + ctx.flush() + } // Prevent stdin from blocking by making its read time 0 termios.c_cc[C.VTIME] = 0 termios.c_cc[C.VMIN] = 0 C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios) + // enable mouse input print('\x1b[?1003h\x1b[?1006h') if ctx.cfg.use_alternate_buffer { + // switch to the alternate buffer print('\x1b[?1049h') + // clear the terminal and set the cursor to the origin + print('\x1b[2J\x1b[3J\x1b[1;1H') } ctx.termios = termios ctx.window_height, ctx.window_width = get_terminal_size() @@ -126,9 +144,41 @@ fn (mut ctx Context) termios_setup() { c.event(event) } }) + os.flush() } +fn get_cursor_position() (int, int) { + print('\033[6n') + // ESC [ YYY `;` XXX `R` + mut reading_x, mut reading_y := false, false + mut x, mut y := 0, 0 + for i := 0; i < 15 ; i++ { + ch := int(C.getchar()) + b := byte(ch) + i++ + // state management: + if b == `R` { + break + } else if b == `[` { + reading_y = true + reading_x = false + continue + } else if b == `;` { + reading_y = false + reading_x = true + continue + } + // converting string vals to ints: + if reading_x { + x = x * 10 + b - byte(`0`) + } else if reading_y { + y = y * 10 + b - byte(`0`) + } + } + return x, y +} + fn termios_reset() { C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH /* C.TCSANOW ?? */, &termios_at_startup) print('\x1b[?1003l\x1b[?1006l\x1b[?25h') diff --git a/vlib/term/ui/ui.v b/vlib/term/ui/ui.v index 166b69e3f9..54b098e94a 100644 --- a/vlib/term/ui/ui.v +++ b/vlib/term/ui/ui.v @@ -1,6 +1,5 @@ module ui -import os import strings pub struct Color { @@ -19,7 +18,6 @@ pub fn (c Color) hex() string { const ( bsu = '\x1bP=1s\x1b\\' esu = '\x1bP=2s\x1b\\' - vno_bsu_esu = os.getenv('VNO_BSU_ESU').len>0 ) [inline] @@ -34,13 +32,13 @@ pub fn (mut ctx Context) flush() { // TODO } $else { // TODO: Diff the previous frame against this one, and only render things that changed? - if vno_bsu_esu { + if !ctx.enable_su { C.write(C.STDOUT_FILENO, ctx.print_buf.data, ctx.print_buf.len) } else { C.write(C.STDOUT_FILENO, bsu.str, bsu.len) C.write(C.STDOUT_FILENO, ctx.print_buf.data, ctx.print_buf.len) C.write(C.STDOUT_FILENO, esu.str, esu.len) - } + } ctx.print_buf.clear() } }