From bebc6910d33513059b522e0937a075ea27efa6bc Mon Sep 17 00:00:00 2001 From: Petros Pateros Date: Wed, 9 Jun 2021 23:03:10 +0300 Subject: [PATCH] ui: use the terminal's cursor closes #462: change cursor style on focus closes #927: Allow different cursor shapes --- ui-terminal-curses.c | 4 +--- ui-terminal-vt100.c | 12 ++---------- ui-terminal.c | 21 ++++++++++++++++++++- vis.c | 4 +++- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/ui-terminal-curses.c b/ui-terminal-curses.c index e9f726bda..45e8f9e1b 100644 --- a/ui-terminal-curses.c +++ b/ui-terminal-curses.c @@ -229,6 +229,7 @@ static void ui_curses_blit(UiTerm *tui) { cell++; } } + move(tui->row, tui->col); wnoutrefresh(stdscr); if (tui->doupdate) doupdate(); @@ -244,7 +245,6 @@ static bool ui_curses_resize(UiTerm *tui, int width, int height) { } static void ui_curses_save(UiTerm *tui, bool fscr) { - curs_set(1); if (fscr) { def_prog_mode(); endwin(); @@ -256,7 +256,6 @@ static void ui_curses_save(UiTerm *tui, bool fscr) { static void ui_curses_restore(UiTerm *tui) { reset_prog_mode(); wclear(stdscr); - curs_set(0); } static int ui_curses_colors(Ui *ui) { @@ -276,7 +275,6 @@ static bool ui_curses_init(UiTerm *tui, char *term) { nonl(); keypad(stdscr, TRUE); meta(stdscr, TRUE); - curs_set(0); return true; } diff --git a/ui-terminal-vt100.c b/ui-terminal-vt100.c index 33ad7fb06..2d1577873 100644 --- a/ui-terminal-vt100.c +++ b/ui-terminal-vt100.c @@ -12,8 +12,6 @@ * * - CSI ? 1049 h Save cursor and use Alternate Screen Buffer (DECSET) * - CSI ? 1049 l Use Normal Screen Buffer and restore cursor (DECRST) - * - CSI ? 25 l Hide Cursor (DECTCEM) - * - CSI ? 25 h Show Cursor (DECTCEM) * - CSI 2 J Erase in Display (ED) * - CSI row ; column H Cursor Position (CUP) * - CSI ... m Character Attributes (SGR) @@ -97,10 +95,6 @@ static void screen_alternate(bool alternate) { output_literal(alternate ? "\x1b[?1049h" : "\x1b[0m" "\x1b[?1049l" "\x1b[0m" ); } -static void cursor_visible(bool visible) { - output_literal(visible ? "\x1b[?25h" : "\x1b[?25l"); -} - static void ui_vt100_blit(UiTerm *tui) { Buffer *buf = &((UiVt100*)tui)->buf; buffer_clear(buf); @@ -163,6 +157,8 @@ static void ui_vt100_blit(UiTerm *tui) { cell++; } } + /* move cursor to the expected location */ + buffer_appendf(buf, "\x1b[%d;%dH", tui->row + 1, tui->col + 1); output(buffer_content(buf), buffer_length0(buf)); } @@ -173,11 +169,9 @@ static bool ui_vt100_resize(UiTerm *tui, int width, int height) { } static void ui_vt100_save(UiTerm *tui, bool fscr) { - cursor_visible(true); } static void ui_vt100_restore(UiTerm *tui) { - cursor_visible(false); } static int ui_vt100_colors(Ui *ui) { @@ -188,13 +182,11 @@ static int ui_vt100_colors(Ui *ui) { static void ui_vt100_suspend(UiTerm *tui) { if (!tui->termkey) return; termkey_stop(tui->termkey); - cursor_visible(true); screen_alternate(false); } static void ui_vt100_resume(UiTerm *tui) { screen_alternate(true); - cursor_visible(false); termkey_start(tui->termkey); } diff --git a/ui-terminal.c b/ui-terminal.c index babc5a68f..59ed1fc8e 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -41,6 +41,7 @@ typedef struct { UiTermWin *selwin; /* the currently selected layout */ char info[MAX_WIDTH]; /* info message displayed at the bottom of the screen */ int width, height; /* terminal dimensions available for all windows */ + int row, col; /* 0-based position of cursor in the terminal */ enum UiLayout layout; /* whether windows are displayed horizontally or vertically */ TermKey *termkey; /* libtermkey instance to handle keyboard input (stdin or /dev/tty) */ size_t ids; /* bit mask of in use window ids */ @@ -357,8 +358,26 @@ static void ui_draw(Ui *ui) { debug("ui-draw\n"); UiTerm *tui = (UiTerm*)ui; ui_arrange(ui, tui->layout); - for (UiTermWin *win = tui->windows; win; win = win->next) + int dx = 0, dy = 0; + for (UiTermWin *win = tui->windows; win; win = win->next) { ui_window_draw((UiWin*)win); + if (win == tui->selwin || win->win->parent) { + View *view = win->win->view; + view_coord_get(view, view_cursor_get(view), NULL, &tui->row, &tui->col); + tui->col += win->sidebar_width; + tui->row += dy; + if (!win->win->parent) + tui->col += dx; + else if (tui->layout == UI_LAYOUT_VERTICAL) + tui->row += win->prev->height; + } + if (tui->layout == UI_LAYOUT_HORIZONTAL) + dy += win->height; + else if (win->win->parent) + dy += win->prev->height; + else + dx += win->width + 1; /* +1 for the |'s */ + } if (tui->info[0]) ui_draw_string(tui, 0, tui->height-1, tui->info, NULL, UI_STYLE_INFO); ui_term_backend_blit(tui); diff --git a/vis.c b/vis.c index a26bccb2a..d3cb9cbc4 100644 --- a/vis.c +++ b/vis.c @@ -363,6 +363,8 @@ static void window_draw_selection(View *view, Selection *cur, CellStyle *style) view_coord_get(view, sel.end, &end_line, NULL, &end_col); if (!start_line && !end_line) return; + if (end_col - start_col <= 1 && !view_selections_anchored(cur)) + return; if (!start_line) { start_line = view_lines_first(view); start_col = 0; @@ -440,7 +442,7 @@ static void window_draw_selections(Win *win) { window_draw_cursor(win, s, &style_cursor, &style_selection); } window_draw_selection(win->view, sel, &style_selection); - window_draw_cursor(win, sel, &style_cursor_primary, &style_selection); + window_draw_cursor_matching(win, sel, &style_cursor_primary); for (Selection *s = view_selections_next(sel); s; s = view_selections_next(s)) { window_draw_selection(win->view, s, &style_selection); size_t pos = view_cursors_pos(s);