mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	tui: Do some deferred wrap on iTerm2.
Partly undo 8ab08a65ba3bc9a44741a2ec9aa81fbcc77467fb. Further testing by Enrico Ghirardi suggests limiting the non-deferred automatic wrap to only the bottom line, whose rightmost column is not printed for iTerm.
This commit is contained in:
		| @@ -91,6 +91,7 @@ typedef struct { | |||||||
|   bool can_set_lr_margin; |   bool can_set_lr_margin; | ||||||
|   bool can_set_left_right_margin; |   bool can_set_left_right_margin; | ||||||
|   bool immediate_wrap_after_last_column; |   bool immediate_wrap_after_last_column; | ||||||
|  |   bool no_bottom_right_corner; | ||||||
|   bool mouse_enabled; |   bool mouse_enabled; | ||||||
|   bool busy; |   bool busy; | ||||||
|   cursorentry_T cursor_shapes[SHAPE_IDX_COUNT]; |   cursorentry_T cursor_shapes[SHAPE_IDX_COUNT]; | ||||||
| @@ -201,10 +202,11 @@ static void terminfo_start(UI *ui) | |||||||
|   data->can_set_left_right_margin = |   data->can_set_left_right_margin = | ||||||
|     !!unibi_get_str(data->ut, unibi_set_left_margin_parm) |     !!unibi_get_str(data->ut, unibi_set_left_margin_parm) | ||||||
|     && !!unibi_get_str(data->ut, unibi_set_right_margin_parm); |     && !!unibi_get_str(data->ut, unibi_set_right_margin_parm); | ||||||
|   data->immediate_wrap_after_last_column = |   data->no_bottom_right_corner = | ||||||
|     terminfo_is_term_family(term, "iterm") |     terminfo_is_term_family(term, "iterm") | ||||||
|     || terminfo_is_term_family(term, "interix") |  | ||||||
|     || (terminfo_is_term_family(term, "xterm") && iterm_env); |     || (terminfo_is_term_family(term, "xterm") && iterm_env); | ||||||
|  |   data->immediate_wrap_after_last_column = | ||||||
|  |     terminfo_is_term_family(term, "interix"); | ||||||
|   // Set 't_Co' from the result of unibilium & fix_terminfo. |   // Set 't_Co' from the result of unibilium & fix_terminfo. | ||||||
|   t_colors = unibi_get_num(data->ut, unibi_max_colors); |   t_colors = unibi_get_num(data->ut, unibi_max_colors); | ||||||
|   // Enter alternate screen and clear |   // Enter alternate screen and clear | ||||||
| @@ -414,20 +416,43 @@ static void update_attrs(UI *ui, HlAttrs attrs) | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void final_column_wrap(UI *ui) | ||||||
|  | { | ||||||
|  |   TUIData *data = ui->data; | ||||||
|  |   UGrid *grid = &data->grid; | ||||||
|  |   if (grid->col == ui->width) { | ||||||
|  |     grid->col = 0; | ||||||
|  |     if (grid->row < ui->height) { | ||||||
|  |       grid->row++; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// It is undocumented, but in the majority of terminals and terminal emulators | ||||||
|  | /// printing at the right margin does not cause an automatic wrap until the | ||||||
|  | /// next character is printed, holding the cursor in place until then. | ||||||
| static void print_cell(UI *ui, UCell *ptr) | static void print_cell(UI *ui, UCell *ptr) | ||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   UGrid *grid = &data->grid; |   UGrid *grid = &data->grid; | ||||||
|   if (data->immediate_wrap_after_last_column |   if (data->no_bottom_right_corner | ||||||
|       && grid->row >= ui->height - 1 |       && grid->row >= ui->height - 1 | ||||||
|       && grid->col >= ui->width - 1) { |       && grid->col >= ui->width - 1) { | ||||||
|     // This (rare) kind of terminal simply cannot print in this corner without |     // This (rare) kind of terminal simply cannot print in this corner without | ||||||
|     // scrolling the entire screen up a line, which we do not want to happen. |     // scrolling the entire screen up a line, which we do not want to happen. | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |   if (!data->immediate_wrap_after_last_column) { | ||||||
|  |     // Printing the next character finally advances the cursor. | ||||||
|  |     final_column_wrap(ui); | ||||||
|  |   } | ||||||
|   update_attrs(ui, ptr->attrs); |   update_attrs(ui, ptr->attrs); | ||||||
|   out(ui, ptr->data, strlen(ptr->data)); |   out(ui, ptr->data, strlen(ptr->data)); | ||||||
|   grid->col++; |   grid->col++; | ||||||
|  |   if (data->immediate_wrap_after_last_column) { | ||||||
|  |     // Printing at the right margin immediately advances the cursor. | ||||||
|  |     final_column_wrap(ui); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool cheap_to_print(UI *ui, int row, int col, int next) | static bool cheap_to_print(UI *ui, int row, int col, int next) | ||||||
| @@ -450,25 +475,6 @@ static bool cheap_to_print(UI *ui, int row, int col, int next) | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| /// The behaviour that this is checking for the absence of is undocumented, |  | ||||||
| /// but is implemented in the majority of terminals and terminal emulators. |  | ||||||
| /// Printing at the right margin does not cause an automatic wrap until the |  | ||||||
| /// next character is printed, holding the cursor in place until then. |  | ||||||
| static void check_final_column_wrap(UI *ui) |  | ||||||
| { |  | ||||||
|   TUIData *data = ui->data; |  | ||||||
|   if (!data->immediate_wrap_after_last_column) { |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   UGrid *grid = &data->grid; |  | ||||||
|   if (grid->col == ui->width) { |  | ||||||
|     grid->col = 0; |  | ||||||
|     if (grid->row < ui->height) { |  | ||||||
|       grid->row++; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// This optimizes several cases where it is cheaper to do something other | /// This optimizes several cases where it is cheaper to do something other | ||||||
| /// than send a full cursor positioning control sequence.  However, there are | /// than send a full cursor positioning control sequence.  However, there are | ||||||
| /// some further optimizations that may seem obvious but that will not work. | /// some further optimizations that may seem obvious but that will not work. | ||||||
| @@ -506,7 +512,6 @@ static void cursor_goto(UI *ui, int row, int col) | |||||||
|         UGRID_FOREACH_CELL(grid, grid->row, grid->row, |         UGRID_FOREACH_CELL(grid, grid->row, grid->row, | ||||||
|           grid->col, col - 1, { |           grid->col, col - 1, { | ||||||
|           print_cell(ui, cell); |           print_cell(ui, cell); | ||||||
|           check_final_column_wrap(ui); |  | ||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|   } |   } | ||||||
| @@ -614,7 +619,6 @@ static void clear_region(UI *ui, int top, int bot, int left, int right) | |||||||
|     UGRID_FOREACH_CELL(grid, top, bot, left, right, { |     UGRID_FOREACH_CELL(grid, top, bot, left, right, { | ||||||
|       cursor_goto(ui, row, col); |       cursor_goto(ui, row, col); | ||||||
|       print_cell(ui, cell); |       print_cell(ui, cell); | ||||||
|       check_final_column_wrap(ui); |  | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -937,7 +941,6 @@ static void tui_put(UI *ui, String text) | |||||||
|   // we have to undo what it has just done before doing it right. |   // we have to undo what it has just done before doing it right. | ||||||
|   grid->col--; |   grid->col--; | ||||||
|   print_cell(ui, cell); |   print_cell(ui, cell); | ||||||
|   check_final_column_wrap(ui); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_bell(UI *ui) | static void tui_bell(UI *ui) | ||||||
| @@ -990,7 +993,6 @@ static void tui_flush(UI *ui) | |||||||
|     UGRID_FOREACH_CELL(grid, r.top, r.bot, r.left, r.right, { |     UGRID_FOREACH_CELL(grid, r.top, r.bot, r.left, r.right, { | ||||||
|       cursor_goto(ui, row, col); |       cursor_goto(ui, row, col); | ||||||
|       print_cell(ui, cell); |       print_cell(ui, cell); | ||||||
|       check_final_column_wrap(ui); |  | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1265,6 +1267,9 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, | |||||||
|       unibi_set_if_empty(ut, unibi_set_left_margin_parm, "\x1b[%i%p1%ds"); |       unibi_set_if_empty(ut, unibi_set_left_margin_parm, "\x1b[%i%p1%ds"); | ||||||
|       unibi_set_if_empty(ut, unibi_set_right_margin_parm, "\x1b[%i;%p2%ds"); |       unibi_set_if_empty(ut, unibi_set_right_margin_parm, "\x1b[%i;%p2%ds"); | ||||||
|     } |     } | ||||||
|  |     if (iterm_pretending_xterm) { | ||||||
|  |       unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m"); | ||||||
|  |     } | ||||||
|   } else if (rxvt) { |   } else if (rxvt) { | ||||||
|     unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m"); |     unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m"); | ||||||
|     unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]2"); |     unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]2"); | ||||||
| @@ -1284,7 +1289,15 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, | |||||||
|   } else if (putty) { |   } else if (putty) { | ||||||
|     // No bugs in the vanilla terminfo for our purposes. |     // No bugs in the vanilla terminfo for our purposes. | ||||||
|   } else if (iterm) { |   } else if (iterm) { | ||||||
|  |     unibi_set_str(ut, unibi_enter_ca_mode, "\x1b[?1049h"); | ||||||
|  |     unibi_set_str(ut, unibi_exit_ca_mode, "\x1b[?1049l"); | ||||||
|  |     unibi_set_if_empty(ut, unibi_set_tb_margin, "\x1b[%i%p1%d;%p2%dr"); | ||||||
|  |     unibi_set_if_empty(ut, unibi_orig_pair, "\x1b[39;49m"); | ||||||
|  |     unibi_set_if_empty(ut, unibi_enter_dim_mode, "\x1b[2m"); | ||||||
|     unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m"); |     unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m"); | ||||||
|  |     unibi_set_if_empty(ut, unibi_exit_italics_mode, "\x1b[23m"); | ||||||
|  |     unibi_set_if_empty(ut, unibi_exit_underline_mode, "\x1b[24m"); | ||||||
|  |     unibi_set_if_empty(ut, unibi_exit_standout_mode, "\x1b[27m"); | ||||||
|   } else if (st) { |   } else if (st) { | ||||||
|     // No bugs in the vanilla terminfo for our purposes. |     // No bugs in the vanilla terminfo for our purposes. | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jonathan de Boyne Pollard
					Jonathan de Boyne Pollard