aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ui.c')
-rw-r--r--src/nvim/ui.c193
1 files changed, 59 insertions, 134 deletions
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 8419951079..ef68b804ba 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -52,14 +52,10 @@ static UI *uis[MAX_UI_COUNT];
static bool ui_ext[kUIExtCount] = { 0 };
static size_t ui_count = 0;
static int row = 0, col = 0;
-static struct {
- int top, bot, left, right;
-} sr;
-static int current_attr_code = -1;
static bool pending_cursor_update = false;
static int busy = 0;
-static int height, width;
-static int old_mode_idx = -1;
+static int mode_idx = SHAPE_IDX_N;
+static bool pending_mode_update = false;
#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
# define UI_LOG(funname, ...)
@@ -89,7 +85,6 @@ static char uilog_last_event[1024] = { 0 };
#ifdef _MSC_VER
# define UI_CALL(funname, ...) \
do { \
- flush_cursor_update(); \
UI_LOG(funname, 0); \
for (size_t i = 0; i < ui_count; i++) { \
UI *ui = uis[i]; \
@@ -99,7 +94,6 @@ static char uilog_last_event[1024] = { 0 };
#else
# define UI_CALL(...) \
do { \
- flush_cursor_update(); \
UI_LOG(__VA_ARGS__, 0); \
for (size_t i = 0; i < ui_count; i++) { \
UI *ui = uis[i]; \
@@ -108,8 +102,8 @@ static char uilog_last_event[1024] = { 0 };
} while (0)
#endif
#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, \
- MORE, MORE, ZERO, ignore)
-#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, ...) a7
+ MORE, MORE, MORE, MORE, MORE, ZERO, ignore)
+#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ...) a10
#define UI_CALL_HELPER(c, ...) UI_CALL_HELPER2(c, __VA_ARGS__)
// Resolves to UI_CALL_MORE or UI_CALL_ZERO.
#define UI_CALL_HELPER2(c, ...) UI_CALL_##c(__VA_ARGS__)
@@ -199,6 +193,9 @@ void ui_refresh(void)
}
row = col = 0;
+ pending_cursor_update = true;
+
+ ui_default_colors_set();
int save_p_lz = p_lz;
p_lz = false; // convince redrawing() to return true ...
@@ -207,13 +204,14 @@ void ui_refresh(void)
for (UIExtension i = 0; (int)i < kUIExtCount; i++) {
ui_ext[i] = ext_widgets[i];
- ui_call_option_set(cstr_as_string((char *)ui_ext_names[i]),
- BOOLEAN_OBJ(ext_widgets[i]));
+ if (i < kUIGlobalCount) {
+ ui_call_option_set(cstr_as_string((char *)ui_ext_names[i]),
+ BOOLEAN_OBJ(ext_widgets[i]));
+ }
}
ui_mode_info_set();
- old_mode_idx = -1;
+ pending_mode_update = true;
ui_cursor_shape();
- current_attr_code = -1;
}
static void ui_refresh_event(void **argv)
@@ -226,25 +224,15 @@ void ui_schedule_refresh(void)
loop_schedule(&main_loop, event_create(ui_refresh_event, 0));
}
-void ui_resize(int new_width, int new_height)
+void ui_resize(int width, int height)
{
- width = new_width;
- height = new_height;
+ ui_call_grid_resize(1, width, height);
+}
- // TODO(bfredl): update default colors when they changed, NOT on resize.
+void ui_default_colors_set(void)
+{
ui_call_default_colors_set(normal_fg, normal_bg, normal_sp,
cterm_normal_fg_color, cterm_normal_bg_color);
-
- // Deprecated:
- UI_CALL(update_fg, (ui->rgb ? normal_fg : cterm_normal_fg_color - 1));
- UI_CALL(update_bg, (ui->rgb ? normal_bg : cterm_normal_bg_color - 1));
- UI_CALL(update_sp, (ui->rgb ? normal_sp : -1));
-
- sr.top = 0;
- sr.bot = height - 1;
- sr.left = 0;
- sr.right = width - 1;
- ui_call_resize(width, height);
}
void ui_busy_start(void)
@@ -269,6 +257,18 @@ void ui_attach_impl(UI *ui)
uis[ui_count++] = ui;
ui_refresh_options();
+
+ for (UIExtension i = kUIGlobalCount; (int)i < kUIExtCount; i++) {
+ ui_set_ext_option(ui, i, ui->ui_ext[i]);
+ }
+
+ bool sent = false;
+ if (ui->ui_ext[kUIHlState]) {
+ sent = highlight_use_hlstate();
+ }
+ if (!sent) {
+ ui_send_all_hls(ui);
+ }
ui_refresh();
}
@@ -302,97 +302,34 @@ void ui_detach_impl(UI *ui)
}
}
-// Set scrolling region for window 'wp'.
-// The region starts 'off' lines from the start of the window.
-// Also set the vertical scroll region for a vertically split window. Always
-// the full width of the window, excluding the vertical separator.
-void ui_set_scroll_region(win_T *wp, int off)
-{
- sr.top = wp->w_winrow + off;
- sr.bot = wp->w_winrow + wp->w_height - 1;
-
- if (wp->w_width != Columns) {
- sr.left = wp->w_wincol;
- sr.right = wp->w_wincol + wp->w_width - 1;
- }
-
- ui_call_set_scroll_region(sr.top, sr.bot, sr.left, sr.right);
-}
-
-// Reset scrolling region to the whole screen.
-void ui_reset_scroll_region(void)
-{
- sr.top = 0;
- sr.bot = (int)Rows - 1;
- sr.left = 0;
- sr.right = (int)Columns - 1;
- ui_call_set_scroll_region(sr.top, sr.bot, sr.left, sr.right);
-}
-
-void ui_set_highlight(int attr_code)
+void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
{
- if (current_attr_code == attr_code) {
+ if (ext < kUIGlobalCount) {
+ ui_refresh();
return;
}
- current_attr_code = attr_code;
-
- HlAttrs attrs = HLATTRS_INIT;
-
- if (attr_code != 0) {
- HlAttrs *aep = syn_attr2entry(attr_code);
- if (aep) {
- attrs = *aep;
- }
+ if (ui->option_set) {
+ ui->option_set(ui, cstr_as_string((char *)ui_ext_names[ext]),
+ BOOLEAN_OBJ(active));
}
-
- UI_CALL(highlight_set, attrs);
-}
-
-void ui_clear_highlight(void)
-{
- ui_set_highlight(0);
}
-void ui_puts(uint8_t *str)
+void ui_line(int row, int startcol, int endcol, int clearcol, int clearattr)
{
- uint8_t *p = str;
- uint8_t c;
-
- while ((c = *p)) {
- if (c < 0x20) {
- abort();
- }
-
- size_t clen = (size_t)mb_ptr2len(p);
- ui_call_put((String){ .data = (char *)p, .size = clen });
- col++;
- if (mb_ptr2cells(p) > 1) {
- // double cell character, blank the next cell
- ui_call_put((String)STRING_INIT);
- col++;
- }
- if (utf_ambiguous_width(utf_ptr2char(p))) {
- pending_cursor_update = true;
- }
- if (col >= width) {
- ui_linefeed();
- }
- p += clen;
-
- if (p_wd) { // 'writedelay': flush & delay each time.
- ui_flush();
- uint64_t wd = (uint64_t)labs(p_wd);
- os_microdelay(wd * 1000u, true);
- }
+ size_t off = LineOffset[row]+(size_t)startcol;
+ UI_CALL(raw_line, 1, row, startcol, endcol, clearcol, clearattr,
+ (const schar_T *)ScreenLines+off, (const sattr_T *)ScreenAttrs+off);
+ if (p_wd) { // 'writedelay': flush & delay each time.
+ int old_row = row, old_col = col;
+ // If'writedelay is active, we set the cursor to highlight what was drawn
+ ui_cursor_goto(row, MIN(clearcol, (int)Columns-1));
+ ui_flush();
+ uint64_t wd = (uint64_t)labs(p_wd);
+ os_microdelay(wd * 1000u, true);
+ ui_cursor_goto(old_row, old_col);
}
}
-void ui_putc(uint8_t c)
-{
- uint8_t buf[2] = {c, 0};
- ui_puts(buf);
-}
-
void ui_cursor_goto(int new_row, int new_col)
{
if (new_row == row && new_col == col) {
@@ -450,30 +387,19 @@ int ui_current_col(void)
void ui_flush(void)
{
cmdline_ui_flush();
- ui_call_flush();
-}
-
-
-void ui_linefeed(void)
-{
- int new_col = 0;
- int new_row = row;
- if (new_row < sr.bot) {
- new_row++;
- } else {
- ui_call_scroll(1);
- }
- ui_cursor_goto(new_row, new_col);
-}
-
-static void flush_cursor_update(void)
-{
if (pending_cursor_update) {
+ ui_call_grid_cursor_goto(1, row, col);
pending_cursor_update = false;
- ui_call_cursor_goto(row, col);
}
+ if (pending_mode_update) {
+ char *full_name = shape_table[mode_idx].full_name;
+ ui_call_mode_change(cstr_as_string(full_name), mode_idx);
+ pending_mode_update = false;
+ }
+ ui_call_flush();
}
+
/// Check if current mode has changed.
/// May update the shape of the cursor.
void ui_cursor_shape(void)
@@ -481,12 +407,11 @@ void ui_cursor_shape(void)
if (!full_screen) {
return;
}
- int mode_idx = cursor_get_mode_idx();
+ int new_mode_idx = cursor_get_mode_idx();
- if (old_mode_idx != mode_idx) {
- old_mode_idx = mode_idx;
- char *full_name = shape_table[mode_idx].full_name;
- ui_call_mode_change(cstr_as_string(full_name), mode_idx);
+ if (new_mode_idx != mode_idx) {
+ mode_idx = new_mode_idx;
+ pending_mode_update = true;
}
conceal_check_cursur_line();
}