refactor(grid): reimplement 'rightleft' as a post-processing step

problem: checks for wp->w_p_rl are all over the place, making simple
things like "advance column one cell" incredibly complicated.

solution: always fill linebuf_char[] using an incrementing counter,
and then mirror the buffer as a post-processing step

This was "easier" that I first feared, because the stupid but simple
workaround for things like keeping linenumbers still left-right,
e.g. "mirror them and them mirror them once more" is more or less
what vim did already. So let's just keep doing that.
This commit is contained in:
bfredl
2023-11-03 20:25:52 +01:00
parent acc646ad8f
commit 83db9115af
4 changed files with 97 additions and 199 deletions

View File

@@ -477,14 +477,21 @@ void grid_line_mirror(void)
if (grid_line_first >= grid_line_last) {
return;
}
linebuf_mirror(&grid_line_first, &grid_line_last, grid_line_maxcol);
}
size_t n = (size_t)(grid_line_last - grid_line_first);
int mirror = grid_line_maxcol - 1; // Mirrors are more fun than television.
void linebuf_mirror(int *firstp, int *lastp, int maxcol)
{
int first = *firstp;
int last = *lastp;
size_t n = (size_t)(last - first);
int mirror = maxcol - 1; // Mirrors are more fun than television.
schar_T *scratch_char = (schar_T *)linebuf_scratch;
memcpy(scratch_char + grid_line_first, linebuf_char + grid_line_first, n * sizeof(schar_T));
for (int col = grid_line_first; col < grid_line_last; col++) {
memcpy(scratch_char + first, linebuf_char + first, n * sizeof(schar_T));
for (int col = first; col < last; col++) {
int rev = mirror - col;
if (col + 1 < grid_line_last && scratch_char[col + 1] == 0) {
if (col + 1 < last && scratch_char[col + 1] == 0) {
linebuf_char[rev - 1] = scratch_char[col];
linebuf_char[rev] = 0;
col++;
@@ -495,20 +502,19 @@ void grid_line_mirror(void)
// for attr and vcol: assumes doublewidth chars are self-consistent
sattr_T *scratch_attr = (sattr_T *)linebuf_scratch;
memcpy(scratch_attr + grid_line_first, linebuf_attr + grid_line_first, n * sizeof(sattr_T));
for (int col = grid_line_first; col < grid_line_last; col++) {
memcpy(scratch_attr + first, linebuf_attr + first, n * sizeof(sattr_T));
for (int col = first; col < last; col++) {
linebuf_attr[mirror - col] = scratch_attr[col];
}
colnr_T *scratch_vcol = (colnr_T *)linebuf_scratch;
memcpy(scratch_vcol + grid_line_first, linebuf_vcol + grid_line_first, n * sizeof(colnr_T));
for (int col = grid_line_first; col < grid_line_last; col++) {
memcpy(scratch_vcol + first, linebuf_vcol + first, n * sizeof(colnr_T));
for (int col = first; col < last; col++) {
linebuf_vcol[mirror - col] = scratch_vcol[col];
}
int grid_line_last_copy = grid_line_last;
grid_line_last = grid_line_maxcol - grid_line_first;
grid_line_first = grid_line_maxcol - grid_line_last_copy;
*lastp = maxcol - first;
*firstp = maxcol - last;
}
/// End a group of grid_line_puts calls and send the screen buffer to the UI layer.
@@ -698,10 +704,10 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
}
}
col = endcol + 1;
endcol = (clear_width > 0 ? clear_width : -clear_width);
endcol = clear_width;
}
if (p_arshape && !p_tbidi) {
if (p_arshape && !p_tbidi && endcol > col) {
line_do_arabic_shape(linebuf_char + col, endcol - col);
}