aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ui_compositor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ui_compositor.c')
-rw-r--r--src/nvim/ui_compositor.c190
1 files changed, 100 insertions, 90 deletions
diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c
index d7becb4fd4..5df70d0d8e 100644
--- a/src/nvim/ui_compositor.c
+++ b/src/nvim/ui_compositor.c
@@ -14,6 +14,7 @@
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/highlight.h"
+#include "nvim/highlight_group.h"
#include "nvim/lib/kvec.h"
#include "nvim/log.h"
#include "nvim/lua/executor.h"
@@ -23,7 +24,6 @@
#include "nvim/os/os.h"
#include "nvim/popupmnu.h"
#include "nvim/screen.h"
-#include "nvim/syntax.h"
#include "nvim/ugrid.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
@@ -138,19 +138,19 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
// use it.
grid->comp_disabled = true;
compose_area(grid->comp_row, row,
- grid->comp_col, grid->comp_col + grid->Columns);
+ grid->comp_col, grid->comp_col + grid->cols);
if (grid->comp_col < col) {
compose_area(MAX(row, grid->comp_row),
- MIN(row+height, grid->comp_row+grid->Rows),
+ MIN(row + height, grid->comp_row + grid->rows),
grid->comp_col, col);
}
- if (col+width < grid->comp_col+grid->Columns) {
+ if (col + width < grid->comp_col + grid->cols) {
compose_area(MAX(row, grid->comp_row),
- MIN(row+height, grid->comp_row+grid->Rows),
- col+width, grid->comp_col+grid->Columns);
+ MIN(row + height, grid->comp_row + grid->rows),
+ col + width, grid->comp_col + grid->cols);
}
- compose_area(row+height, grid->comp_row+grid->Rows,
- grid->comp_col, grid->comp_col + grid->Columns);
+ compose_area(row + height, grid->comp_row + grid->rows,
+ grid->comp_col, grid->comp_col + grid->cols);
grid->comp_disabled = false;
}
grid->comp_row = row;
@@ -166,19 +166,19 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
#endif
size_t insert_at = kv_size(layers);
- while (insert_at > 0 && kv_A(layers, insert_at-1)->zindex > grid->zindex) {
+ while (insert_at > 0 && kv_A(layers, insert_at - 1)->zindex > grid->zindex) {
insert_at--;
}
- if (curwin && kv_A(layers, insert_at-1) == &curwin->w_grid_alloc
- && kv_A(layers, insert_at-1)->zindex == grid->zindex
+ if (curwin && kv_A(layers, insert_at - 1) == &curwin->w_grid_alloc
+ && kv_A(layers, insert_at - 1)->zindex == grid->zindex
&& !on_top) {
insert_at--;
}
// not found: new grid
kv_pushp(layers);
- for (size_t i = kv_size(layers)-1; i > insert_at; i--) {
- kv_A(layers, i) = kv_A(layers, i-1);
+ for (size_t i = kv_size(layers) - 1; i > insert_at; i--) {
+ kv_A(layers, i) = kv_A(layers, i - 1);
kv_A(layers, i)->comp_index = i;
}
kv_A(layers, insert_at) = grid;
@@ -188,8 +188,8 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
grid->comp_index = insert_at;
}
if (moved && valid && ui_comp_should_draw()) {
- compose_area(grid->comp_row, grid->comp_row+grid->Rows,
- grid->comp_col, grid->comp_col+grid->Columns);
+ compose_area(grid->comp_row, grid->comp_row + grid->rows,
+ grid->comp_col, grid->comp_col + grid->cols);
}
return moved;
}
@@ -206,8 +206,8 @@ void ui_comp_remove_grid(ScreenGrid *grid)
curgrid = &default_grid;
}
- for (size_t i = grid->comp_index; i < kv_size(layers)-1; i++) {
- kv_A(layers, i) = kv_A(layers, i+1);
+ for (size_t i = grid->comp_index; i < kv_size(layers) - 1; i++) {
+ kv_A(layers, i) = kv_A(layers, i + 1);
kv_A(layers, i)->comp_index = i;
}
(void)kv_pop(layers);
@@ -241,7 +241,7 @@ static void ui_comp_raise_grid(ScreenGrid *grid, size_t new_index)
{
size_t old_index = grid->comp_index;
for (size_t i = old_index; i < new_index; i++) {
- kv_A(layers, i) = kv_A(layers, i+1);
+ kv_A(layers, i) = kv_A(layers, i + 1);
kv_A(layers, i)->comp_index = i;
}
kv_A(layers, new_index) = grid;
@@ -249,10 +249,10 @@ static void ui_comp_raise_grid(ScreenGrid *grid, size_t new_index)
for (size_t i = old_index; i < new_index; i++) {
ScreenGrid *grid2 = kv_A(layers, i);
int startcol = MAX(grid->comp_col, grid2->comp_col);
- int endcol = MIN(grid->comp_col+grid->Columns,
- grid2->comp_col+grid2->Columns);
+ int endcol = MIN(grid->comp_col + grid->cols,
+ grid2->comp_col + grid2->cols);
compose_area(MAX(grid->comp_row, grid2->comp_row),
- MIN(grid->comp_row+grid->Rows, grid2->comp_row+grid2->Rows),
+ MIN(grid->comp_row + grid->rows, grid2->comp_row + grid2->rows),
startcol, endcol);
}
}
@@ -262,13 +262,13 @@ static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle, Integer r, Int
if (!ui_comp_should_draw() || !ui_comp_set_grid((int)grid_handle)) {
return;
}
- int cursor_row = curgrid->comp_row+(int)r;
- int cursor_col = curgrid->comp_col+(int)c;
+ int cursor_row = curgrid->comp_row + (int)r;
+ int cursor_col = curgrid->comp_col + (int)c;
// TODO(bfredl): maybe not the best time to do this, for efficiency we
// should configure all grids before entering win_update()
if (curgrid != &default_grid) {
- size_t new_index = kv_size(layers)-1;
+ size_t new_index = kv_size(layers) - 1;
while (new_index > 1 && kv_A(layers, new_index)->zindex > curgrid->zindex) {
new_index--;
@@ -279,7 +279,7 @@ static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle, Integer r, Int
}
}
- if (cursor_col >= default_grid.Columns || cursor_row >= default_grid.Rows) {
+ if (cursor_col >= default_grid.cols || cursor_row >= default_grid.rows) {
// TODO(bfredl): this happens with 'writedelay', refactor?
// abort();
return;
@@ -289,17 +289,30 @@ static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle, Integer r, Int
ScreenGrid *ui_comp_mouse_focus(int row, int col)
{
- for (ssize_t i = (ssize_t)kv_size(layers)-1; i > 0; i--) {
+ for (ssize_t i = (ssize_t)kv_size(layers) - 1; i > 0; i--) {
ScreenGrid *grid = kv_A(layers, i);
if (grid->focusable
- && row >= grid->comp_row && row < grid->comp_row+grid->Rows
- && col >= grid->comp_col && col < grid->comp_col+grid->Columns) {
+ && row >= grid->comp_row && row < grid->comp_row + grid->rows
+ && col >= grid->comp_col && col < grid->comp_col + grid->cols) {
return grid;
}
}
return NULL;
}
+/// Compute which grid is on top at supplied screen coordinates
+ScreenGrid *ui_comp_get_grid_at_coord(int row, int col)
+{
+ for (ssize_t i = (ssize_t)kv_size(layers) - 1; i > 0; i--) {
+ ScreenGrid *grid = kv_A(layers, i);
+ if (row >= grid->comp_row && row < grid->comp_row + grid->rows
+ && col >= grid->comp_col && col < grid->comp_col + grid->cols) {
+ return grid;
+ }
+ }
+ return &default_grid;
+}
+
/// Baseline implementation. This is always correct, but we can sometimes
/// do something more efficient (where efficiency means smaller deltas to
/// the downstream UI.)
@@ -315,7 +328,7 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
startcol--;
skipstart = 1;
}
- if (endcol < default_grid.Columns && (flags & kLineFlagInvalid)) {
+ if (endcol < default_grid.cols && (flags & kLineFlagInvalid)) {
endcol++;
skipend = 1;
}
@@ -323,9 +336,9 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
int col = (int)startcol;
ScreenGrid *grid = NULL;
schar_T *bg_line = &default_grid.chars[default_grid.line_offset[row]
- +(size_t)startcol];
+ + (size_t)startcol];
sattr_T *bg_attrs = &default_grid.attrs[default_grid.line_offset[row]
- +(size_t)startcol];
+ + (size_t)startcol];
int grid_width, grid_height;
while (col < endcol) {
@@ -337,8 +350,8 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
// first check to see if any grids have pending updates to width/height,
// to ensure that we don't accidentally put any characters into `linebuf`
// that have been invalidated.
- grid_width = MIN(g->Columns, g->comp_width);
- grid_height = MIN(g->Rows, g->comp_height);
+ grid_width = MIN(g->cols, g->comp_width);
+ grid_height = MIN(g->rows, g->comp_height);
if (g->comp_row > row || row >= g->comp_row + grid_height
|| g->comp_disabled) {
continue;
@@ -354,8 +367,8 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
assert(grid != NULL);
assert(until > col);
- assert(until <= default_grid.Columns);
- size_t n = (size_t)(until-col);
+ assert(until <= default_grid.cols);
+ size_t n = (size_t)(until - col);
if (row == msg_sep_row && grid->comp_index <= msg_grid.comp_index) {
// TODO(bfredl): when we implement borders around floating windows, then
@@ -363,18 +376,18 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
grid = &msg_grid;
sattr_T msg_sep_attr = (sattr_T)HL_ATTR(HLF_MSGSEP);
for (int i = col; i < until; i++) {
- memcpy(linebuf[i-startcol], msg_sep_char, sizeof(*linebuf));
- attrbuf[i-startcol] = msg_sep_attr;
+ memcpy(linebuf[i - startcol], msg_sep_char, sizeof(*linebuf));
+ attrbuf[i - startcol] = msg_sep_attr;
}
} else {
- size_t off = grid->line_offset[row-grid->comp_row]
- + (size_t)(col-grid->comp_col);
- memcpy(linebuf+(col-startcol), grid->chars+off, n * sizeof(*linebuf));
- memcpy(attrbuf+(col-startcol), grid->attrs+off, n * sizeof(*attrbuf));
- if (grid->comp_col+grid->Columns > until
- && grid->chars[off+n][0] == NUL) {
- linebuf[until-1-startcol][0] = ' ';
- linebuf[until-1-startcol][1] = '\0';
+ size_t off = grid->line_offset[row - grid->comp_row]
+ + (size_t)(col - grid->comp_col);
+ memcpy(linebuf + (col - startcol), grid->chars + off, n * sizeof(*linebuf));
+ memcpy(attrbuf + (col - startcol), grid->attrs + off, n * sizeof(*attrbuf));
+ if (grid->comp_col + grid->cols > until
+ && grid->chars[off + n][0] == NUL) {
+ linebuf[until - 1 - startcol][0] = ' ';
+ linebuf[until - 1 - startcol][1] = '\0';
if (col == startcol && n == 1) {
skipstart = 0;
}
@@ -384,18 +397,18 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
// 'pumblend' and 'winblend'
if (grid->blending) {
int width;
- for (int i = col-(int)startcol; i < until-startcol; i += width) {
+ for (int i = col - (int)startcol; i < until - startcol; i += width) {
width = 1;
// negative space
bool thru = strequal((char *)linebuf[i], " ") && bg_line[i][0] != NUL;
- if (i+1 < endcol-startcol && bg_line[i+1][0] == NUL) {
+ if (i + 1 < endcol - startcol && bg_line[i + 1][0] == NUL) {
width = 2;
- thru &= strequal((char *)linebuf[i+1], " ");
+ thru &= strequal((char *)linebuf[i + 1], " ");
}
attrbuf[i] = (sattr_T)hl_blend_attrs(bg_attrs[i], attrbuf[i], &thru);
if (width == 2) {
- attrbuf[i+1] = (sattr_T)hl_blend_attrs(bg_attrs[i+1],
- attrbuf[i+1], &thru);
+ attrbuf[i + 1] = (sattr_T)hl_blend_attrs(bg_attrs[i + 1],
+ attrbuf[i + 1], &thru);
}
if (thru) {
memcpy(linebuf + i, bg_line + i, (size_t)width * sizeof(linebuf[i]));
@@ -405,19 +418,19 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
// Tricky: if overlap caused a doublewidth char to get cut-off, must
// replace the visible half with a space.
- if (linebuf[col-startcol][0] == NUL) {
- linebuf[col-startcol][0] = ' ';
- linebuf[col-startcol][1] = NUL;
- if (col == endcol-1) {
+ if (linebuf[col - startcol][0] == NUL) {
+ linebuf[col - startcol][0] = ' ';
+ linebuf[col - startcol][1] = NUL;
+ if (col == endcol - 1) {
skipend = 0;
}
- } else if (n > 1 && linebuf[col-startcol+1][0] == NUL) {
+ } else if (n > 1 && linebuf[col - startcol + 1][0] == NUL) {
skipstart = 0;
}
col = until;
}
- if (linebuf[endcol-startcol-1][0] == NUL) {
+ if (linebuf[endcol - startcol - 1][0] == NUL) {
skipend = 0;
}
@@ -430,7 +443,7 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
flags = flags & ~kLineFlagWrap;
}
- for (int i = skipstart; i < (endcol-skipend)-startcol; i++) {
+ for (int i = skipstart; i < (endcol - skipend) - startcol; i++) {
if (attrbuf[i] < 0) {
if (rdb_flags & RDB_INVALID) {
abort();
@@ -439,10 +452,10 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag
}
}
}
- ui_composed_call_raw_line(1, row, startcol+skipstart,
- endcol-skipend, endcol-skipend, 0, flags,
- (const schar_T *)linebuf+skipstart,
- (const sattr_T *)attrbuf+skipstart);
+ ui_composed_call_raw_line(1, row, startcol + skipstart,
+ endcol - skipend, endcol - skipend, 0, flags,
+ (const schar_T *)linebuf + skipstart,
+ (const sattr_T *)attrbuf + skipstart);
}
static void compose_debug(Integer startrow, Integer endrow, Integer startcol, Integer endcol,
@@ -452,8 +465,8 @@ static void compose_debug(Integer startrow, Integer endrow, Integer startcol, In
return;
}
- endrow = MIN(endrow, default_grid.Rows);
- endcol = MIN(endcol, default_grid.Columns);
+ endrow = MIN(endrow, default_grid.rows);
+ endcol = MIN(endcol, default_grid.cols);
int attr = syn_id2attr(syn_id);
for (int row = (int)startrow; row < endrow; row++) {
@@ -462,9 +475,8 @@ static void compose_debug(Integer startrow, Integer endrow, Integer startcol, In
(const sattr_T *)attrbuf);
}
-
if (delay) {
- debug_delay(endrow-startrow);
+ debug_delay(endrow - startrow);
}
}
@@ -476,12 +488,11 @@ static void debug_delay(Integer lines)
os_microdelay(factor * wd * 1000u, true);
}
-
static void compose_area(Integer startrow, Integer endrow, Integer startcol, Integer endcol)
{
compose_debug(startrow, endrow, startcol, endcol, dbghl_recompose, true);
- endrow = MIN(endrow, default_grid.Rows);
- endcol = MIN(endcol, default_grid.Columns);
+ endrow = MIN(endrow, default_grid.rows);
+ endcol = MIN(endcol, default_grid.cols);
if (endcol <= startcol) {
return;
}
@@ -497,8 +508,8 @@ static void compose_area(Integer startrow, Integer endrow, Integer startcol, Int
void ui_comp_compose_grid(ScreenGrid *grid)
{
if (ui_comp_should_draw()) {
- compose_area(grid->comp_row, grid->comp_row+grid->Rows,
- grid->comp_col, grid->comp_col+grid->Columns);
+ compose_area(grid->comp_row, grid->comp_row + grid->rows,
+ grid->comp_col, grid->comp_col + grid->cols);
}
}
@@ -523,17 +534,17 @@ static void ui_comp_raw_line(UI *ui, Integer grid, Integer row, Integer startcol
// TODO(bfredl): this should not really be necessary. But on some condition
// when resizing nvim, a window will be attempted to be drawn on the older
// and possibly larger global screen size.
- if (row >= default_grid.Rows) {
+ if (row >= default_grid.rows) {
DLOG("compositor: invalid row %" PRId64 " on grid %" PRId64, row, grid);
return;
}
- if (clearcol > default_grid.Columns) {
+ if (clearcol > default_grid.cols) {
DLOG("compositor: invalid last column %" PRId64 " on grid %" PRId64,
clearcol, grid);
- if (startcol >= default_grid.Columns) {
+ if (startcol >= default_grid.cols) {
return;
}
- clearcol = default_grid.Columns;
+ clearcol = default_grid.cols;
endcol = MIN(endcol, clearcol);
}
@@ -541,13 +552,13 @@ static void ui_comp_raw_line(UI *ui, Integer grid, Integer row, Integer startcol
// TODO(bfredl): eventually should just fix compose_line to respect clearing
// and optimize it for uncovered lines.
if (flags & kLineFlagInvalid || covered || curgrid->blending) {
- compose_debug(row, row+1, startcol, clearcol, dbghl_composed, true);
+ compose_debug(row, row + 1, startcol, clearcol, dbghl_composed, true);
compose_line(row, startcol, clearcol, flags);
} else {
- compose_debug(row, row+1, startcol, endcol, dbghl_normal, false);
- compose_debug(row, row+1, endcol, clearcol, dbghl_clear, true);
+ compose_debug(row, row + 1, startcol, endcol, dbghl_normal, false);
+ compose_debug(row, row + 1, endcol, clearcol, dbghl_clear, true);
#ifndef NDEBUG
- for (int i = 0; i < endcol-startcol; i++) {
+ for (int i = 0; i < endcol - startcol; i++) {
assert(attrs[i] >= 0);
}
#endif
@@ -572,7 +583,7 @@ static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, Boolean scrol
{
msg_grid.comp_row = (int)row;
if (scrolled && row > 0) {
- msg_sep_row = (int)row-1;
+ msg_sep_row = (int)row - 1;
if (sep_char.data) {
STRLCPY(msg_sep_char, sep_char.data, sizeof(msg_sep_char));
}
@@ -581,19 +592,19 @@ static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, Boolean scrol
}
if (row > msg_current_row && ui_comp_should_draw()) {
- compose_area(MAX(msg_current_row-1, 0), row, 0, default_grid.Columns);
+ compose_area(MAX(msg_current_row - 1, 0), row, 0, default_grid.cols);
} else if (row < msg_current_row && ui_comp_should_draw()
&& msg_current_row < Rows) {
int delta = msg_current_row - (int)row;
if (msg_grid.blending) {
- int first_row = MAX((int)row-(scrolled?1:0), 0);
- compose_area(first_row, Rows-delta, 0, Columns);
+ int first_row = MAX((int)row - (scrolled?1:0), 0);
+ compose_area(first_row, Rows - delta, 0, Columns);
} else {
// scroll separator together with message text
- int first_row = MAX((int)row-(msg_was_scrolled?1:0), 0);
+ int first_row = MAX((int)row - (msg_was_scrolled?1:0), 0);
ui_composed_call_grid_scroll(1, first_row, Rows, 0, Columns, delta, 0);
if (scrolled && !msg_was_scrolled && row > 0) {
- compose_area(row-1, row, 0, Columns);
+ compose_area(row - 1, row, 0, Columns);
}
}
}
@@ -607,9 +618,9 @@ static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, Boolean scrol
/// TODO(bfredl): currently this only handles message row
static bool curgrid_covered_above(int row)
{
- bool above_msg = (kv_A(layers, kv_size(layers)-1) == &msg_grid
- && row < msg_current_row-(msg_was_scrolled?1:0));
- return kv_size(layers)-(above_msg?1:0) > curgrid->comp_index+1;
+ bool above_msg = (kv_A(layers, kv_size(layers) - 1) == &msg_grid
+ && row < msg_current_row - (msg_was_scrolled?1:0));
+ return kv_size(layers) - (above_msg?1:0) > curgrid->comp_index + 1;
}
static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot, Integer left,
@@ -634,8 +645,8 @@ static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot,
// row, where the latter might scroll invalid space created by the first.
// ideally win_update() should keep track of this itself and not scroll
// the invalid space.
- if (curgrid->attrs[curgrid->line_offset[r-curgrid->comp_row]
- +left-curgrid->comp_col] >= 0) {
+ if (curgrid->attrs[curgrid->line_offset[r - curgrid->comp_row]
+ + (size_t)left - (size_t)curgrid->comp_col] >= 0) {
compose_line(r, left, right, 0);
}
}
@@ -665,4 +676,3 @@ static void ui_comp_grid_resize(UI *ui, Integer grid, Integer width, Integer hei
}
}
}
-