diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/ui.c | 3 | ||||
-rw-r--r-- | src/nvim/event/defs.h | 2 | ||||
-rw-r--r-- | src/nvim/screen.c | 57 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 18 | ||||
-rw-r--r-- | src/nvim/ui.c | 39 | ||||
-rw-r--r-- | src/nvim/ui.h | 2 | ||||
-rw-r--r-- | src/nvim/ui_bridge.c | 12 |
7 files changed, 60 insertions, 73 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 76e3927820..509032892b 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -424,7 +424,8 @@ static void remote_ui_put(UI *ui, const char *cell) static void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol, Integer clearcol, Integer clearattr, - const schar_T *chunk, const sattr_T *attrs) + Boolean wrap, const schar_T *chunk, + const sattr_T *attrs) { UIData *data = ui->data; if (ui->ui_ext[kUINewgrid]) { diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index 55b2d277bb..fdd4f17d5c 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -4,7 +4,7 @@ #include <assert.h> #include <stdarg.h> -#define EVENT_HANDLER_MAX_ARGC 9 +#define EVENT_HANDLER_MAX_ARGC 10 typedef void (*argv_callback)(void **argv); typedef struct message { diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 91840026a5..59e0ec2193 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2012,7 +2012,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T } screen_line(row + wp->w_winrow, wp->w_wincol, wp->w_width, - wp->w_width, false, wp, wp->w_hl_attr_normal); + wp->w_width, false, wp, wp->w_hl_attr_normal, false); /* * Update w_cline_height and w_cline_folded if the cursor line was @@ -2900,7 +2900,7 @@ win_line ( && filler_todo <= 0 ) { screen_line(screen_row, wp->w_wincol, col, -wp->w_width, wp->w_p_rl, wp, - wp->w_hl_attr_normal); + wp->w_hl_attr_normal, false); // Pretend we have finished updating the window. Except when // 'cursorcolumn' is set. if (wp->w_p_cuc) { @@ -3996,7 +3996,7 @@ win_line ( } } screen_line(screen_row, wp->w_wincol, col, wp->w_width, wp->w_p_rl, wp, - wp->w_hl_attr_normal); + wp->w_hl_attr_normal, false); row++; /* @@ -4204,8 +4204,22 @@ win_line ( || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str) || (n_extra != 0 && (c_extra != NUL || *p_extra != NUL))) ) { + bool wrap = wp->w_p_wrap // Wrapping enabled. + && filler_todo <= 0 // Not drawing diff filler lines. + && lcs_eol_one != -1 // Haven't printed the lcs_eol character. + && row != endrow - 1 // Not the last line being displayed. + && wp->w_width == Columns // Window spans the width of the screen. + && !wp->w_p_rl; // Not right-to-left. screen_line(screen_row, wp->w_wincol, col - boguscols, - wp->w_width, wp->w_p_rl, wp, wp->w_hl_attr_normal); + wp->w_width, wp->w_p_rl, wp, wp->w_hl_attr_normal, wrap); + if (wrap) { + // Force a redraw of the first column of the next line. + ScreenAttrs[LineOffset[screen_row + 1]] = -1; + + // Remember that the line wraps, used for modeless copy. + LineWraps[screen_row] = true; + } + boguscols = 0; ++row; ++screen_row; @@ -4232,28 +4246,6 @@ win_line ( break; } - if (ui_current_row() == screen_row - 1 - && filler_todo <= 0 - && wp->w_width == Columns) { - /* Remember that the line wraps, used for modeless copy. */ - LineWraps[screen_row - 1] = TRUE; - - // Special trick to make copy/paste of wrapped lines work with - // xterm/screen: write an extra character beyond the end of - // the line. This will work with all terminal types - // (regardless of the xn,am settings). - // Only do this if the cursor is on the current line - // (something has been written in it). - // Don't do this for double-width characters. - // Don't do this for a window not at the right screen border. - if (utf_off2cells(LineOffset[screen_row], - LineOffset[screen_row] + screen_Columns) != 2 - && utf_off2cells(LineOffset[screen_row - 1] + (int)Columns - 2, - LineOffset[screen_row] + screen_Columns) != 2) { - ui_add_linewrap(screen_row - 1); - } - } - col = 0; off = (unsigned)(current_ScreenLine - ScreenLines); if (wp->w_p_rl) { @@ -4319,9 +4311,11 @@ static int char_needs_redraw(int off_from, int off_to, int cols) * "rlflag" is TRUE in a rightleft window: * When TRUE and "clear_width" > 0, clear columns 0 to "endcol" * When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width" + * If "wrap" is true, then hint to the UI that "row" contains a line + * which has wrapped into the next row. */ -static void screen_line(int row, int coloff, int endcol, - int clear_width, int rlflag, win_T *wp, int bg_attr) +static void screen_line(int row, int coloff, int endcol, int clear_width, + int rlflag, win_T *wp, int bg_attr, bool wrap) { unsigned off_from; unsigned off_to; @@ -4482,7 +4476,7 @@ static void screen_line(int row, int coloff, int endcol, } if (clear_end > start_dirty) { ui_line(row, coloff+start_dirty, coloff+end_dirty, coloff+clear_end, - bg_attr); + bg_attr, wrap); } } @@ -5442,7 +5436,8 @@ void screen_puts_line_flush(bool set_cursor) if (set_cursor) { ui_cursor_goto(put_dirty_row, put_dirty_last); } - ui_line(put_dirty_row, put_dirty_first, put_dirty_last, put_dirty_last, 0); + ui_line(put_dirty_row, put_dirty_first, put_dirty_last, put_dirty_last, 0, + false); put_dirty_first = -1; put_dirty_last = 0; } @@ -5801,7 +5796,7 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, put_dirty_last = MAX(put_dirty_last, dirty_last); } else { int last = c2 != ' ' ? dirty_last : dirty_first + (c1 != ' '); - ui_line(row, dirty_first, last, dirty_last, attr); + ui_line(row, dirty_first, last, dirty_last, attr, false); } } diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 0781b03965..841294aaad 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1191,7 +1191,8 @@ static void tui_option_set(UI *ui, String name, Object value) static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol, Integer endcol, Integer clearcol, Integer clearattr, - const schar_T *chunk, const sattr_T *attrs) + Boolean wrap, const schar_T *chunk, + const sattr_T *attrs) { TUIData *data = ui->data; UGrid *grid = &data->grid; @@ -1212,6 +1213,21 @@ static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol, clear_region(ui, (int)linerow, (int)linerow, (int)endcol, (int)clearcol-1, cl_attrs); } + + if (wrap && ui->width == grid->width && linerow + 1 < grid->height) { + // Only do line wrapping if the grid width is equal to the terminal + // width and the line continuation is within the grid. + + if (endcol != grid->width) { + // Print the last cell of the row, if we haven't already done so. + cursor_goto(ui, (int)linerow, grid->width - 1); + print_cell(ui, &grid->cells[linerow][grid->width - 1]); + } + + // Wrap the cursor over to the next line. The next line will be + // printed immediately without an intervening newline. + final_column_wrap(ui); + } } static void invalidate(UI *ui, int top, int bot, int left, int right) diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 07aa032a50..e291111f82 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -80,7 +80,7 @@ static char uilog_last_event[1024] = { 0 }; #endif // UI_CALL invokes a function on all registered UI instances. The functions can -// have 0-5 arguments (configurable by SELECT_NTH). +// have 0-10 arguments (configurable by SELECT_NTH). // // See http://stackoverflow.com/a/11172679 for how it works. #ifdef _MSC_VER @@ -102,9 +102,9 @@ static char uilog_last_event[1024] = { 0 }; } \ } while (0) #endif -#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, \ - MORE, MORE, MORE, MORE, MORE, ZERO, ignore) -#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ...) a10 +#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, MORE, MORE, \ + MORE, MORE, MORE, MORE, ZERO, ignore) +#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11 #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__) @@ -315,10 +315,11 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active) } } -void ui_line(int row, int startcol, int endcol, int clearcol, int clearattr) +void ui_line(int row, int startcol, int endcol, int clearcol, int clearattr, + bool wrap) { size_t off = LineOffset[row]+(size_t)startcol; - UI_CALL(raw_line, 1, row, startcol, endcol, clearcol, clearattr, + UI_CALL(raw_line, 1, row, startcol, endcol, clearcol, clearattr, wrap, (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; @@ -341,32 +342,6 @@ void ui_cursor_goto(int new_row, int new_col) pending_cursor_update = true; } -void ui_add_linewrap(int row) -{ - // TODO(bfredl): check that this actually still works - // and move to TUI module in that case. -#if 0 - // First make sure we are at the end of the screen line, - // then output the same character again to let the - // terminal know about the wrap. If the terminal doesn't - // auto-wrap, we overwrite the character. - if (ui_current_col() != Columns) { - screen_char(LineOffset[row] + (unsigned)Columns - 1, row, - (int)(Columns - 1)); - } - - // When there is a multi-byte character, just output a - // space to keep it simple. */ - if (ScreenLines[LineOffset[row] + (Columns - 1)][1] != 0) { - ui_putc(' '); - } else { - ui_puts(ScreenLines[LineOffset[row] + (Columns - 1)]); - } - // force a redraw of the first char on the next line - ScreenAttrs[LineOffset[row+1]] = (sattr_T)-1; -#endif -} - void ui_mode_info_set(void) { pending_mode_info_update = true; diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 584d8a77c6..df489f569f 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -47,7 +47,7 @@ struct ui_t { // in to the public grid_line format. void (*raw_line)(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol, Integer clearcol, Integer clearattr, - const schar_T *chunk, const sattr_T *attrs); + Boolean wrap, const schar_T *chunk, const sattr_T *attrs); void (*event)(UI *ui, char *name, Array args, bool *args_consumed); void (*stop)(UI *ui); void (*inspect)(UI *ui, Dictionary *info); diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index a96a24bde7..ebd4651f4d 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -152,24 +152,24 @@ static void ui_bridge_raw_line_event(void **argv) UI *ui = UI(argv[0]); ui->raw_line(ui, PTR2INT(argv[1]), PTR2INT(argv[2]), PTR2INT(argv[3]), PTR2INT(argv[4]), PTR2INT(argv[5]), PTR2INT(argv[6]), - argv[7], argv[8]); - xfree(argv[7]); + PTR2INT(argv[7]), argv[8], argv[9]); xfree(argv[8]); + xfree(argv[9]); } static void ui_bridge_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol, Integer clearcol, Integer clearattr, - const schar_T *chunk, const sattr_T *attrs) + Boolean wrap, const schar_T *chunk, + const sattr_T *attrs) { size_t ncol = (size_t)(endcol-startcol); schar_T *c = xmemdup(chunk, ncol * sizeof(schar_T)); sattr_T *hl = xmemdup(attrs, ncol * sizeof(sattr_T)); - UI_BRIDGE_CALL(ui, raw_line, 9, ui, INT2PTR(grid), INT2PTR(row), + UI_BRIDGE_CALL(ui, raw_line, 10, ui, INT2PTR(grid), INT2PTR(row), INT2PTR(startcol), INT2PTR(endcol), INT2PTR(clearcol), - INT2PTR(clearattr), c, hl); + INT2PTR(clearattr), INT2PTR(wrap), c, hl); } - static void ui_bridge_suspend(UI *b) { UIBridgeData *data = (UIBridgeData *)b; |