mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 13:15:09 -07:00
Merge pull request #25513 from bfredl/cleangrid
refactor(grid): get rid of unbatched grid_puts and grid_putchar
This commit is contained in:
commit
4e4ad4312e
@ -3330,5 +3330,6 @@ static void win_put_linebuf(win_T *wp, int row, int coloff, int endcol, int clea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grid_adjust(&grid, &row, &coloff);
|
||||||
grid_put_linebuf(grid, row, coloff, 0, endcol, clear_width, wp->w_p_rl, bg_attr, wrap, false);
|
grid_put_linebuf(grid, row, coloff, 0, endcol, clear_width, wp->w_p_rl, bg_attr, wrap, false);
|
||||||
}
|
}
|
||||||
|
@ -2382,26 +2382,20 @@ static void win_update(win_T *wp, DecorProviders *providers)
|
|||||||
wp->w_botline = lnum;
|
wp->w_botline = lnum;
|
||||||
wp->w_filler_rows = wp->w_grid.rows - srow;
|
wp->w_filler_rows = wp->w_grid.rows - srow;
|
||||||
} else if (dy_flags & DY_TRUNCATE) { // 'display' has "truncate"
|
} else if (dy_flags & DY_TRUNCATE) { // 'display' has "truncate"
|
||||||
int scr_row = wp->w_grid.rows - 1;
|
|
||||||
int symbol = wp->w_p_fcs_chars.lastline;
|
|
||||||
char fillbuf[12]; // 2 characters of 6 bytes
|
|
||||||
int charlen = utf_char2bytes(symbol, &fillbuf[0]);
|
|
||||||
utf_char2bytes(symbol, &fillbuf[charlen]);
|
|
||||||
|
|
||||||
// Last line isn't finished: Display "@@@" in the last screen line.
|
// Last line isn't finished: Display "@@@" in the last screen line.
|
||||||
grid_puts(&wp->w_grid, fillbuf, MIN(wp->w_grid.cols, 2) * charlen, scr_row, 0, at_attr);
|
grid_line_start(&wp->w_grid, wp->w_grid.rows - 1);
|
||||||
grid_fill(&wp->w_grid, scr_row, scr_row + 1, 2, wp->w_grid.cols, symbol, ' ', at_attr);
|
grid_line_fill(0, MIN(wp->w_grid.cols, 3), wp->w_p_fcs_chars.lastline, at_attr);
|
||||||
|
grid_line_fill(3, wp->w_grid.cols, ' ', at_attr);
|
||||||
|
grid_line_flush();
|
||||||
set_empty_rows(wp, srow);
|
set_empty_rows(wp, srow);
|
||||||
wp->w_botline = lnum;
|
wp->w_botline = lnum;
|
||||||
} else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline"
|
} else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline"
|
||||||
int start_col = wp->w_grid.cols - 3;
|
|
||||||
int symbol = wp->w_p_fcs_chars.lastline;
|
|
||||||
|
|
||||||
// Last line isn't finished: Display "@@@" at the end.
|
// Last line isn't finished: Display "@@@" at the end.
|
||||||
// TODO(bfredl): this display ">@@@" when ">" was a left-halve
|
// TODO(bfredl): this display ">@@@" when ">" was a left-halve
|
||||||
// maybe "@@@@" is preferred when this happens.
|
// maybe "@@@@" is preferred when this happens.
|
||||||
grid_line_start(&wp->w_grid, wp->w_grid.rows - 1);
|
grid_line_start(&wp->w_grid, wp->w_grid.rows - 1);
|
||||||
grid_line_fill(MAX(start_col, 0), wp->w_grid.cols, symbol, at_attr);
|
grid_line_fill(MAX(wp->w_grid.cols - 3, 0), wp->w_grid.cols,
|
||||||
|
wp->w_p_fcs_chars.lastline, at_attr);
|
||||||
grid_line_flush();
|
grid_line_flush();
|
||||||
set_empty_rows(wp, srow);
|
set_empty_rows(wp, srow);
|
||||||
wp->w_botline = lnum;
|
wp->w_botline = lnum;
|
||||||
|
@ -1412,11 +1412,11 @@ static void ins_ctrl_v(void)
|
|||||||
// Put a character directly onto the screen. It's not stored in a buffer.
|
// Put a character directly onto the screen. It's not stored in a buffer.
|
||||||
// Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
|
// Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
|
||||||
static int pc_status;
|
static int pc_status;
|
||||||
#define PC_STATUS_UNSET 0 // pc_bytes was not set
|
#define PC_STATUS_UNSET 0 // nothing was put on screen
|
||||||
#define PC_STATUS_RIGHT 1 // right half of double-wide char
|
#define PC_STATUS_RIGHT 1 // right half of double-wide char
|
||||||
#define PC_STATUS_LEFT 2 // left half of double-wide char
|
#define PC_STATUS_LEFT 2 // left half of double-wide char
|
||||||
#define PC_STATUS_SET 3 // pc_bytes was filled
|
#define PC_STATUS_SET 3 // pc_schar was filled
|
||||||
static char pc_bytes[MB_MAXBYTES + 1]; // saved bytes
|
static schar_T pc_schar; // saved char
|
||||||
static int pc_attr;
|
static int pc_attr;
|
||||||
static int pc_row;
|
static int pc_row;
|
||||||
static int pc_col;
|
static int pc_col;
|
||||||
@ -1433,31 +1433,34 @@ void edit_putchar(int c, bool highlight)
|
|||||||
attr = 0;
|
attr = 0;
|
||||||
}
|
}
|
||||||
pc_row = curwin->w_wrow;
|
pc_row = curwin->w_wrow;
|
||||||
pc_col = 0;
|
|
||||||
pc_status = PC_STATUS_UNSET;
|
pc_status = PC_STATUS_UNSET;
|
||||||
|
grid_line_start(&curwin->w_grid, pc_row);
|
||||||
if (curwin->w_p_rl) {
|
if (curwin->w_p_rl) {
|
||||||
pc_col += curwin->w_grid.cols - 1 - curwin->w_wcol;
|
pc_col = curwin->w_grid.cols - 1 - curwin->w_wcol;
|
||||||
const int fix_col = grid_fix_col(&curwin->w_grid, pc_col, pc_row);
|
|
||||||
|
|
||||||
if (fix_col != pc_col) {
|
if (grid_line_getchar(pc_col, NULL) == NUL) {
|
||||||
grid_putchar(&curwin->w_grid, ' ', pc_row, fix_col, attr);
|
grid_line_put_schar(pc_col - 1, schar_from_ascii(' '), attr);
|
||||||
curwin->w_wcol--;
|
curwin->w_wcol--;
|
||||||
pc_status = PC_STATUS_RIGHT;
|
pc_status = PC_STATUS_RIGHT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pc_col += curwin->w_wcol;
|
pc_col = curwin->w_wcol;
|
||||||
if (grid_lefthalve(&curwin->w_grid, pc_row, pc_col)) {
|
|
||||||
|
if (grid_line_getchar(pc_col + 1, NULL) == NUL) {
|
||||||
|
// pc_col is the left half of a double-width char
|
||||||
pc_status = PC_STATUS_LEFT;
|
pc_status = PC_STATUS_LEFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the character to be able to put it back
|
// save the character to be able to put it back
|
||||||
if (pc_status == PC_STATUS_UNSET) {
|
if (pc_status == PC_STATUS_UNSET) {
|
||||||
// TODO(bfredl): save the schar_T instead
|
pc_schar = grid_line_getchar(pc_col, &pc_attr);
|
||||||
grid_getbytes(&curwin->w_grid, pc_row, pc_col, pc_bytes, &pc_attr);
|
|
||||||
pc_status = PC_STATUS_SET;
|
pc_status = PC_STATUS_SET;
|
||||||
}
|
}
|
||||||
grid_putchar(&curwin->w_grid, c, pc_row, pc_col, attr);
|
|
||||||
|
char buf[MB_MAXBYTES + 1];
|
||||||
|
grid_line_puts(pc_col, buf, utf_char2bytes(c, buf), attr);
|
||||||
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1537,7 +1540,10 @@ void edit_unputchar(void)
|
|||||||
if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) {
|
if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) {
|
||||||
redrawWinline(curwin, curwin->w_cursor.lnum);
|
redrawWinline(curwin, curwin->w_cursor.lnum);
|
||||||
} else {
|
} else {
|
||||||
grid_puts(&curwin->w_grid, pc_bytes, -1, pc_row, pc_col, pc_attr);
|
// TODO(bfredl): this could be smarter and also handle the dubyawidth case
|
||||||
|
grid_line_start(&curwin->w_grid, pc_row);
|
||||||
|
grid_line_put_schar(pc_col, pc_schar, pc_attr);
|
||||||
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6885,7 +6885,7 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
c = -1;
|
c = -1;
|
||||||
} else {
|
} else {
|
||||||
char buf[MB_MAXBYTES + 1];
|
char buf[MB_MAXBYTES + 1];
|
||||||
grid_getbytes(grid, row, col, buf, NULL);
|
schar_get(buf, grid_getchar(grid, row, col, NULL));
|
||||||
c = utf_ptr2char(buf);
|
c = utf_ptr2char(buf);
|
||||||
}
|
}
|
||||||
rettv->vval.v_number = c;
|
rettv->vval.v_number = c;
|
||||||
@ -6906,7 +6906,7 @@ static void f_screenchars(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char buf[MB_MAXBYTES + 1];
|
char buf[MB_MAXBYTES + 1];
|
||||||
grid_getbytes(grid, row, col, buf, NULL);
|
schar_get(buf, grid_getchar(grid, row, col, NULL));
|
||||||
int pcc[MAX_MCO];
|
int pcc[MAX_MCO];
|
||||||
int c = utfc_ptr2char(buf, pcc);
|
int c = utfc_ptr2char(buf, pcc);
|
||||||
int composing_len = 0;
|
int composing_len = 0;
|
||||||
@ -6951,7 +6951,7 @@ static void f_screenstring(typval_T *argvars, typval_T *rettv, EvalFuncData fptr
|
|||||||
}
|
}
|
||||||
|
|
||||||
char buf[MB_MAXBYTES + 1];
|
char buf[MB_MAXBYTES + 1];
|
||||||
grid_getbytes(grid, row, col, buf, NULL);
|
schar_get(buf, grid_getchar(grid, row, col, NULL));
|
||||||
rettv->vval.v_string = xstrdup(buf);
|
rettv->vval.v_string = xstrdup(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
152
src/nvim/grid.c
152
src/nvim/grid.c
@ -201,65 +201,23 @@ static bool grid_invalid_row(ScreenGrid *grid, int row)
|
|||||||
return grid->attrs[grid->line_offset[row]] < 0;
|
return grid->attrs[grid->line_offset[row]] < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return number of display cells for char at grid->chars[off].
|
|
||||||
/// We make sure that the offset used is less than "max_off".
|
|
||||||
static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off)
|
|
||||||
{
|
|
||||||
return (off + 1 < max_off && grid->chars[off + 1] == 0) ? 2 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return true if the character at "row"/"col" on the screen is the left side
|
|
||||||
/// of a double-width character.
|
|
||||||
///
|
|
||||||
/// Caller must make sure "row" and "col" are not invalid!
|
|
||||||
bool grid_lefthalve(ScreenGrid *grid, int row, int col)
|
|
||||||
{
|
|
||||||
grid_adjust(&grid, &row, &col);
|
|
||||||
|
|
||||||
return grid_off2cells(grid, grid->line_offset[row] + (size_t)col,
|
|
||||||
grid->line_offset[row] + (size_t)grid->cols) > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Correct a position on the screen, if it's the right half of a double-wide
|
|
||||||
/// char move it to the left half. Returns the corrected column.
|
|
||||||
int grid_fix_col(ScreenGrid *grid, int col, int row)
|
|
||||||
{
|
|
||||||
int coloff = 0;
|
|
||||||
grid_adjust(&grid, &row, &coloff);
|
|
||||||
|
|
||||||
col += coloff;
|
|
||||||
if (grid->chars != NULL && col > 0
|
|
||||||
&& grid->chars[grid->line_offset[row] + (size_t)col] == 0) {
|
|
||||||
return col - 1 - coloff;
|
|
||||||
}
|
|
||||||
return col - coloff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// output a single character directly to the grid
|
|
||||||
void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr)
|
|
||||||
{
|
|
||||||
char buf[MB_MAXBYTES + 1];
|
|
||||||
|
|
||||||
grid_puts(grid, buf, utf_char2bytes(c, buf), row, col, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a single character directly from grid.chars into "bytes", which must
|
/// Get a single character directly from grid.chars into "bytes", which must
|
||||||
/// have a size of "MB_MAXBYTES + 1".
|
/// have a size of "MB_MAXBYTES + 1".
|
||||||
/// If "attrp" is not NULL, return the character's attribute in "*attrp".
|
/// If "attrp" is not NULL, return the character's attribute in "*attrp".
|
||||||
void grid_getbytes(ScreenGrid *grid, int row, int col, char *bytes, int *attrp)
|
schar_T grid_getchar(ScreenGrid *grid, int row, int col, int *attrp)
|
||||||
{
|
{
|
||||||
grid_adjust(&grid, &row, &col);
|
grid_adjust(&grid, &row, &col);
|
||||||
|
|
||||||
// safety check
|
// safety check
|
||||||
if (grid->chars == NULL || row >= grid->rows || col >= grid->cols) {
|
if (grid->chars == NULL || row >= grid->rows || col >= grid->cols) {
|
||||||
return;
|
return NUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t off = grid->line_offset[row] + (size_t)col;
|
size_t off = grid->line_offset[row] + (size_t)col;
|
||||||
if (attrp != NULL) {
|
if (attrp != NULL) {
|
||||||
*attrp = grid->attrs[off];
|
*attrp = grid->attrs[off];
|
||||||
}
|
}
|
||||||
schar_get(bytes, grid->chars[off]);
|
return grid->chars[off];
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScreenGrid *grid_line_grid = NULL;
|
static ScreenGrid *grid_line_grid = NULL;
|
||||||
@ -269,38 +227,6 @@ static int grid_line_maxcol = 0;
|
|||||||
static int grid_line_first = INT_MAX;
|
static int grid_line_first = INT_MAX;
|
||||||
static int grid_line_last = 0;
|
static int grid_line_last = 0;
|
||||||
|
|
||||||
/// put string 'text' on the window grid at position 'row' and 'col', with
|
|
||||||
/// attributes 'attr', and update contents of 'grid'
|
|
||||||
/// @param textlen length of string or -1 to use strlen(text)
|
|
||||||
/// Note: only outputs within one row!
|
|
||||||
int grid_puts(ScreenGrid *grid, const char *text, int textlen, int row, int col, int attr)
|
|
||||||
{
|
|
||||||
grid_line_start(grid, row);
|
|
||||||
|
|
||||||
// Safety check. The check for negative row and column is to fix issue
|
|
||||||
// vim/vim#4102. TODO(neovim): find out why row/col could be negative.
|
|
||||||
int off_col = grid_line_coloff + col;
|
|
||||||
if (grid_line_grid->chars == NULL
|
|
||||||
|| grid_line_row >= grid_line_grid->rows || grid_line_row < 0
|
|
||||||
|| off_col >= grid_line_grid->cols || off_col < 0) {
|
|
||||||
if (rdb_flags & RDB_INVALID) {
|
|
||||||
abort();
|
|
||||||
} else {
|
|
||||||
grid_line_grid = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int len = grid_line_puts(col, text, textlen, attr);
|
|
||||||
if (grid_line_last > grid_line_first) {
|
|
||||||
// TODO(bfredl): this is bullshit. message.c should manage its own cursor movements
|
|
||||||
int col_pos = MIN(grid_line_coloff + grid_line_last, grid_line_grid->cols - 1);
|
|
||||||
ui_grid_cursor_goto(grid_line_grid->handle, grid_line_row, col_pos);
|
|
||||||
}
|
|
||||||
grid_line_flush();
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Start a group of grid_line_puts calls that builds a single grid line.
|
/// Start a group of grid_line_puts calls that builds a single grid line.
|
||||||
///
|
///
|
||||||
/// Must be matched with a grid_line_flush call before moving to
|
/// Must be matched with a grid_line_flush call before moving to
|
||||||
@ -318,6 +244,25 @@ void grid_line_start(ScreenGrid *grid, int row)
|
|||||||
grid_line_last = 0;
|
grid_line_last = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get present char from current rendered screen line
|
||||||
|
///
|
||||||
|
/// This indicates what already is on screen, not the pending render buffer.
|
||||||
|
///
|
||||||
|
/// @return char or space if out of bounds
|
||||||
|
schar_T grid_line_getchar(int col, int *attr)
|
||||||
|
{
|
||||||
|
if (col < grid_line_maxcol) {
|
||||||
|
size_t off = grid_line_grid->line_offset[grid_line_row] + (size_t)col;
|
||||||
|
if (attr != NULL) {
|
||||||
|
*attr = grid_line_grid->attrs[off];
|
||||||
|
}
|
||||||
|
return grid_line_grid->chars[off];
|
||||||
|
} else {
|
||||||
|
// NUL is a very special value (right-half of double width), space is True Neutral™
|
||||||
|
return schar_from_ascii(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void grid_line_put_schar(int col, schar_T schar, int attr)
|
void grid_line_put_schar(int col, schar_T schar, int attr)
|
||||||
{
|
{
|
||||||
assert(grid_line_grid);
|
assert(grid_line_grid);
|
||||||
@ -331,8 +276,13 @@ void grid_line_put_schar(int col, schar_T schar, int attr)
|
|||||||
linebuf_vcol[col] = -1;
|
linebuf_vcol[col] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// like grid_puts(), but output "text[len]". When "len" is -1 output up to
|
/// Put string "text" at "col" position relative to the grid line from the
|
||||||
/// a NUL.
|
/// recent grid_line_start() call.
|
||||||
|
///
|
||||||
|
/// @param textlen length of string or -1 to use strlen(text)
|
||||||
|
/// Note: only outputs within one row!
|
||||||
|
///
|
||||||
|
/// @return number of grid cells used
|
||||||
int grid_line_puts(int col, const char *text, int textlen, int attr)
|
int grid_line_puts(int col, const char *text, int textlen, int attr)
|
||||||
{
|
{
|
||||||
const char *ptr = text;
|
const char *ptr = text;
|
||||||
@ -435,8 +385,16 @@ void grid_line_fill(int start_col, int end_col, int c, int attr)
|
|||||||
linebuf_attr[col] = attr;
|
linebuf_attr[col] = attr;
|
||||||
linebuf_vcol[col] = -1;
|
linebuf_vcol[col] = -1;
|
||||||
}
|
}
|
||||||
|
if (start_col < end_col) {
|
||||||
grid_line_first = MIN(grid_line_first, start_col);
|
grid_line_first = MIN(grid_line_first, start_col);
|
||||||
grid_line_last = MAX(grid_line_last, end_col);
|
grid_line_last = MAX(grid_line_last, end_col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// move the cursor to a position in a currently rendered line.
|
||||||
|
void grid_line_cursor_goto(int col)
|
||||||
|
{
|
||||||
|
ui_grid_cursor_goto(grid_line_grid->handle, grid_line_row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// End a group of grid_line_puts calls and send the screen buffer to the UI layer.
|
/// End a group of grid_line_puts calls and send the screen buffer to the UI layer.
|
||||||
@ -500,27 +458,29 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int row = start_row; row < end_row; row++) {
|
for (int row = start_row; row < end_row; row++) {
|
||||||
|
int dirty_first = INT_MAX;
|
||||||
|
int dirty_last = 0;
|
||||||
|
size_t lineoff = grid->line_offset[row];
|
||||||
|
|
||||||
// When drawing over the right half of a double-wide char clear
|
// When drawing over the right half of a double-wide char clear
|
||||||
// out the left half. When drawing over the left half of a
|
// out the left half. When drawing over the left half of a
|
||||||
// double wide-char clear out the right half. Only needed in a
|
// double wide-char clear out the right half. Only needed in a
|
||||||
// terminal.
|
// terminal.
|
||||||
if (start_col > 0 && grid_fix_col(grid, start_col, row) != start_col) {
|
if (start_col > 0 && grid->chars[lineoff + (size_t)start_col] == NUL) {
|
||||||
grid_puts(grid, " ", 1, row, start_col - 1, 0);
|
size_t off = lineoff + (size_t)start_col - 1;
|
||||||
|
grid->chars[off] = schar_from_ascii(' ');
|
||||||
|
grid->attrs[off] = attr;
|
||||||
|
dirty_first = start_col - 1;
|
||||||
}
|
}
|
||||||
if (end_col < grid->cols
|
if (end_col < grid->cols && grid->chars[lineoff + (size_t)end_col] == NUL) {
|
||||||
&& grid_fix_col(grid, end_col, row) != end_col) {
|
size_t off = lineoff + (size_t)end_col;
|
||||||
grid_puts(grid, " ", 1, row, end_col, 0);
|
grid->chars[off] = schar_from_ascii(' ');
|
||||||
|
grid->attrs[off] = attr;
|
||||||
|
dirty_last = end_col + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if grid was resized (in ext_multigrid mode), the UI has no redraw updates
|
|
||||||
// for the newly resized grid. It is better mark everything as dirty and
|
|
||||||
// send all the updates.
|
|
||||||
int dirty_first = INT_MAX;
|
|
||||||
int dirty_last = 0;
|
|
||||||
|
|
||||||
int col = start_col;
|
int col = start_col;
|
||||||
sc = schar_from_char(c1);
|
sc = schar_from_char(c1);
|
||||||
size_t lineoff = grid->line_offset[row];
|
|
||||||
for (col = start_col; col < end_col; col++) {
|
for (col = start_col; col < end_col; col++) {
|
||||||
size_t off = lineoff + (size_t)col;
|
size_t off = lineoff + (size_t)col;
|
||||||
if (grid->chars[off] != sc || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) {
|
if (grid->chars[off] != sc || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) {
|
||||||
@ -600,8 +560,6 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
|
|||||||
endcol = grid->cols;
|
endcol = grid->cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_adjust(&grid, &row, &coloff);
|
|
||||||
|
|
||||||
// Safety check. Avoids clang warnings down the call stack.
|
// Safety check. Avoids clang warnings down the call stack.
|
||||||
if (grid->chars == NULL || row >= grid->rows || coloff >= grid->cols) {
|
if (grid->chars == NULL || row >= grid->rows || coloff >= grid->cols) {
|
||||||
DLOG("invalid state, skipped");
|
DLOG("invalid state, skipped");
|
||||||
@ -662,12 +620,8 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
|
|||||||
// the right half of the old character.
|
// the right half of the old character.
|
||||||
// Also required when writing the right half of a double-width
|
// Also required when writing the right half of a double-width
|
||||||
// char over the left half of an existing one
|
// char over the left half of an existing one
|
||||||
if (col + char_cells == endcol
|
if (col + char_cells == endcol && off + (size_t)char_cells < max_off_to
|
||||||
&& ((char_cells == 1
|
&& grid->chars[off + (size_t)char_cells] == NUL) {
|
||||||
&& grid_off2cells(grid, off, max_off_to) > 1)
|
|
||||||
|| (char_cells == 2
|
|
||||||
&& grid_off2cells(grid, off, max_off_to) == 1
|
|
||||||
&& grid_off2cells(grid, off + 1, max_off_to) > 1))) {
|
|
||||||
clear_next = true;
|
clear_next = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2959,15 +2959,15 @@ void os_msg(const char *str)
|
|||||||
|
|
||||||
void msg_moremsg(int full)
|
void msg_moremsg(int full)
|
||||||
{
|
{
|
||||||
int attr;
|
int attr = hl_combine_attr(HL_ATTR(HLF_MSG), HL_ATTR(HLF_M));
|
||||||
char *s = _("-- More --");
|
grid_line_start(&msg_grid_adj, Rows - 1);
|
||||||
|
int len = grid_line_puts(0, _("-- More --"), -1, attr);
|
||||||
attr = hl_combine_attr(HL_ATTR(HLF_MSG), HL_ATTR(HLF_M));
|
|
||||||
grid_puts(&msg_grid_adj, s, -1, Rows - 1, 0, attr);
|
|
||||||
if (full) {
|
if (full) {
|
||||||
grid_puts(&msg_grid_adj, _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), -1,
|
len += grid_line_puts(len, _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "),
|
||||||
Rows - 1, vim_strsize(s), attr);
|
-1, attr);
|
||||||
}
|
}
|
||||||
|
grid_line_cursor_goto(len);
|
||||||
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Repeat the message for the current mode: MODE_ASKMORE, MODE_EXTERNCMD,
|
/// Repeat the message for the current mode: MODE_ASKMORE, MODE_EXTERNCMD,
|
||||||
|
@ -182,7 +182,9 @@ void win_redr_status(win_T *wp)
|
|||||||
attr = win_hl_attr(wp, HLF_C);
|
attr = win_hl_attr(wp, HLF_C);
|
||||||
fillchar = wp->w_p_fcs_chars.vert;
|
fillchar = wp->w_p_fcs_chars.vert;
|
||||||
}
|
}
|
||||||
grid_putchar(&default_grid, fillchar, W_ENDROW(wp), W_ENDCOL(wp), attr);
|
grid_line_start(&default_grid, W_ENDROW(wp));
|
||||||
|
grid_line_put_schar(W_ENDCOL(wp), schar_from_char(fillchar), attr);
|
||||||
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
busy = false;
|
busy = false;
|
||||||
}
|
}
|
||||||
|
@ -532,7 +532,7 @@ void ui_comp_raw_line(Integer grid, Integer row, Integer startcol, Integer endco
|
|||||||
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);
|
compose_line(row, startcol, clearcol, flags);
|
||||||
} else {
|
} else {
|
||||||
compose_debug(row, row + 1, startcol, endcol, dbghl_normal, false);
|
compose_debug(row, row + 1, startcol, endcol, dbghl_normal, endcol >= clearcol);
|
||||||
compose_debug(row, row + 1, endcol, clearcol, dbghl_clear, true);
|
compose_debug(row, row + 1, endcol, clearcol, dbghl_clear, true);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (int i = 0; i < endcol - startcol; i++) {
|
for (int i = 0; i < endcol - startcol; i++) {
|
||||||
|
@ -2827,7 +2827,7 @@ void intro_message(int colon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*mesg != NUL) {
|
if (*mesg != NUL) {
|
||||||
do_intro_line(row, mesg, 0);
|
do_intro_line((int)row, mesg, 0);
|
||||||
}
|
}
|
||||||
row++;
|
row++;
|
||||||
|
|
||||||
@ -2838,14 +2838,13 @@ void intro_message(int colon)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_intro_line(long row, char *mesg, int attr)
|
static void do_intro_line(int row, char *mesg, int attr)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int l;
|
int l;
|
||||||
int clen;
|
|
||||||
|
|
||||||
// Center the message horizontally.
|
// Center the message horizontally.
|
||||||
long col = vim_strsize(mesg);
|
int col = vim_strsize(mesg);
|
||||||
|
|
||||||
col = (Columns - col) / 2;
|
col = (Columns - col) / 2;
|
||||||
|
|
||||||
@ -2853,21 +2852,18 @@ static void do_intro_line(long row, char *mesg, int attr)
|
|||||||
col = 0;
|
col = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grid_line_start(&default_grid, row);
|
||||||
// Split up in parts to highlight <> items differently.
|
// Split up in parts to highlight <> items differently.
|
||||||
for (p = mesg; *p != NUL; p += l) {
|
for (p = mesg; *p != NUL; p += l) {
|
||||||
clen = 0;
|
|
||||||
|
|
||||||
for (l = 0;
|
for (l = 0;
|
||||||
p[l] != NUL && (l == 0 || (p[l] != '<' && p[l - 1] != '>'));
|
p[l] != NUL && (l == 0 || (p[l] != '<' && p[l - 1] != '>'));
|
||||||
l++) {
|
l++) {
|
||||||
clen += ptr2cells(p + l);
|
|
||||||
l += utfc_ptr2len(p + l) - 1;
|
l += utfc_ptr2len(p + l) - 1;
|
||||||
}
|
}
|
||||||
assert(row <= INT_MAX && col <= INT_MAX);
|
assert(row <= INT_MAX && col <= INT_MAX);
|
||||||
grid_puts(&default_grid, p, l, (int)row, (int)col,
|
col += grid_line_puts(col, p, l, *p == '<' ? HL_ATTR(HLF_8) : attr);
|
||||||
*p == '<' ? HL_ATTR(HLF_8) : attr);
|
|
||||||
col += clen;
|
|
||||||
}
|
}
|
||||||
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ":intro": clear screen, display intro screen and wait for return.
|
/// ":intro": clear screen, display intro screen and wait for return.
|
||||||
|
@ -1366,7 +1366,7 @@ describe('ui/ext_messages', function()
|
|||||||
|
|
||||||
feed(":intro<cr>")
|
feed(":intro<cr>")
|
||||||
screen:expect{grid=[[
|
screen:expect{grid=[[
|
||||||
|
|
^ |
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
|
Loading…
Reference in New Issue
Block a user