Patch 8.2.0794
Problem:    Libvterm code lags behind the upstream version.
Solution:   Include revisions 743 - 747.
Files:      src/libvterm/src/state.c, src/libvterm/src/screen.c,
            src/libvterm/src/vterm_internal.h, src/libvterm/include/vterm.h,
            src/libvterm/t/67screen_dbl_wh.test, src/libvterm/t/run-test.pl


*** ../vim-8.2.0793/src/libvterm/src/state.c    2020-05-17 21:50:11.954655960 
+0200
--- src/libvterm/src/state.c    2020-05-18 21:04:09.747822993 +0200
***************
*** 73,85 ****
  
    state->bold_is_highbright = 0;
  
    return state;
  }
  
  INTERNAL void vterm_state_free(VTermState *state)
  {
    vterm_allocator_free(state->vt, state->tabstops);
!   vterm_allocator_free(state->vt, state->lineinfo);
    vterm_allocator_free(state->vt, state->combine_chars);
    vterm_allocator_free(state->vt, state);
  }
--- 73,99 ----
  
    state->bold_is_highbright = 0;
  
+   state->combine_chars_size = 16;
+   state->combine_chars = vterm_allocator_malloc(state->vt, 
state->combine_chars_size * sizeof(state->combine_chars[0]));
+ 
+   state->tabstops = vterm_allocator_malloc(state->vt, (state->cols + 7) / 8);
+ 
+   state->lineinfos[BUFIDX_PRIMARY] = vterm_allocator_malloc(state->vt, 
state->rows * sizeof(VTermLineInfo));
+   state->lineinfo = state->lineinfos[BUFIDX_PRIMARY];
+ 
+   state->encoding_utf8.enc = vterm_lookup_encoding(ENC_UTF8, 'u');
+   if(*state->encoding_utf8.enc->init)
+     (*state->encoding_utf8.enc->init)(state->encoding_utf8.enc, 
state->encoding_utf8.data);
+ 
    return state;
  }
  
  INTERNAL void vterm_state_free(VTermState *state)
  {
    vterm_allocator_free(state->vt, state->tabstops);
!   vterm_allocator_free(state->vt, state->lineinfos[BUFIDX_PRIMARY]);
!   if(state->lineinfos[BUFIDX_ALTSCREEN])
!     vterm_allocator_free(state->vt, state->lineinfos[BUFIDX_ALTSCREEN]);
    vterm_allocator_free(state->vt, state->combine_chars);
    vterm_allocator_free(state->vt, state);
  }
***************
*** 106,120 ****
    // Update lineinfo if full line
    if(rect.start_col == 0 && rect.end_col == state->cols && rightward == 0) {
      int height = rect.end_row - rect.start_row - abs(downward);
  
!     if(downward > 0)
        memmove(state->lineinfo + rect.start_row,
                state->lineinfo + rect.start_row + downward,
                height * sizeof(state->lineinfo[0]));
!     else
        memmove(state->lineinfo + rect.start_row - downward,
                state->lineinfo + rect.start_row,
                height * sizeof(state->lineinfo[0]));
    }
  
    if(state->callbacks && state->callbacks->scrollrect)
--- 120,141 ----
    // Update lineinfo if full line
    if(rect.start_col == 0 && rect.end_col == state->cols && rightward == 0) {
      int height = rect.end_row - rect.start_row - abs(downward);
+     int row;
  
!     if(downward > 0) {
        memmove(state->lineinfo + rect.start_row,
                state->lineinfo + rect.start_row + downward,
                height * sizeof(state->lineinfo[0]));
!       for(row = rect.end_row - downward; row < rect.end_row; row++)
!         state->lineinfo[row] = (VTermLineInfo){ 0 };
!     }
!     else {
        memmove(state->lineinfo + rect.start_row - downward,
                state->lineinfo + rect.start_row,
                height * sizeof(state->lineinfo[0]));
+       for(row = rect.start_row; row < rect.start_row - downward; row++)
+         state->lineinfo[row] = (VTermLineInfo){ 0 };
+     }
    }
  
    if(state->callbacks && state->callbacks->scrollrect)
***************
*** 1701,1707 ****
  {
    VTermState *state = user;
    VTermPos oldpos = state->pos;
!   VTermPos delta = { 0, 0 };
  
    if(cols != state->cols) {
      int col;
--- 1722,1728 ----
  {
    VTermState *state = user;
    VTermPos oldpos = state->pos;
!   VTermStateFields fields;
  
    if(cols != state->cols) {
      int col;
***************
*** 1731,1752 ****
    }
  
    if(rows != state->rows) {
!     int row;
!     VTermLineInfo *newlineinfo = vterm_allocator_malloc(state->vt, rows * 
sizeof(VTermLineInfo));
!     if (newlineinfo == NULL)
!       return 0;
  
!     for(row = 0; row < state->rows && row < rows; row++) {
!       newlineinfo[row] = state->lineinfo[row];
!     }
  
!     for( ; row < rows; row++) {
!       newlineinfo[row].doublewidth = 0;
!       newlineinfo[row].doubleheight = 0;
      }
  
!     vterm_allocator_free(state->vt, state->lineinfo);
!     state->lineinfo = newlineinfo;
    }
  
    state->rows = rows;
--- 1752,1780 ----
    }
  
    if(rows != state->rows) {
!     for(int bufidx = BUFIDX_PRIMARY; bufidx <= BUFIDX_ALTSCREEN; bufidx++) {
!       int row;
!       VTermLineInfo *oldlineinfo = state->lineinfos[bufidx];
!       if(!oldlineinfo)
!         continue;
  
!       VTermLineInfo *newlineinfo = vterm_allocator_malloc(state->vt, rows * 
sizeof(VTermLineInfo));
! 
!       for(row = 0; row < state->rows && row < rows; row++) {
!         newlineinfo[row] = oldlineinfo[row];
!       }
! 
!       for( ; row < rows; row++) {
!         newlineinfo[row] = (VTermLineInfo){
!           .doublewidth = 0,
!         };
!       }
  
!       vterm_allocator_free(state->vt, state->lineinfos[bufidx]);
!       state->lineinfos[bufidx] = newlineinfo;
      }
  
!     state->lineinfo = state->lineinfos[state->mode.alt_screen ? 
BUFIDX_ALTSCREEN : BUFIDX_PRIMARY];
    }
  
    state->rows = rows;
***************
*** 1757,1773 ****
    if(state->scrollregion_right > -1)
      UBOUND(state->scrollregion_right, state->cols);
  
    if(state->callbacks && state->callbacks->resize)
!     (*state->callbacks->resize)(rows, cols, &delta, state->cbdata);
  
    if(state->at_phantom && state->pos.col < cols-1) {
      state->at_phantom = 0;
      state->pos.col++;
    }
  
-   state->pos.row += delta.row;
-   state->pos.col += delta.col;
- 
    if(state->pos.row >= rows)
      state->pos.row = rows - 1;
    if(state->pos.col >= cols)
--- 1785,1802 ----
    if(state->scrollregion_right > -1)
      UBOUND(state->scrollregion_right, state->cols);
  
+   fields.pos = state->pos;
+ 
    if(state->callbacks && state->callbacks->resize)
!     (*state->callbacks->resize)(rows, cols, &fields, state->cbdata);
! 
!   state->pos = fields.pos;
  
    if(state->at_phantom && state->pos.col < cols-1) {
      state->at_phantom = 0;
      state->pos.col++;
    }
  
    if(state->pos.row >= rows)
      state->pos.row = rows - 1;
    if(state->pos.col >= cols)
***************
*** 1803,1819 ****
      return NULL;
    vt->state = state;
  
-   state->combine_chars_size = 16;
-   state->combine_chars = vterm_allocator_malloc(state->vt, 
state->combine_chars_size * sizeof(state->combine_chars[0]));
- 
-   state->tabstops = vterm_allocator_malloc(state->vt, (state->cols + 7) / 8);
- 
-   state->lineinfo = vterm_allocator_malloc(state->vt, state->rows * 
sizeof(VTermLineInfo));
- 
-   state->encoding_utf8.enc = vterm_lookup_encoding(ENC_UTF8, 'u');
-   if(*state->encoding_utf8.enc->init != NULL)
-     (*state->encoding_utf8.enc->init)(state->encoding_utf8.enc, 
state->encoding_utf8.data);
- 
    vterm_parser_set_callbacks(vt, &parser_callbacks, state);
  
    return state;
--- 1832,1837 ----
***************
*** 1976,1981 ****
--- 1994,2002 ----
      return 1;
    case VTERM_PROP_ALTSCREEN:
      state->mode.alt_screen = val->boolean;
+     if(state->mode.alt_screen && !state->lineinfos[BUFIDX_ALTSCREEN])
+       state->lineinfos[BUFIDX_ALTSCREEN] = vterm_allocator_malloc(state->vt, 
state->rows * sizeof(VTermLineInfo));
+     state->lineinfo = state->lineinfos[state->mode.alt_screen ? 
BUFIDX_ALTSCREEN : BUFIDX_PRIMARY];
      if(state->mode.alt_screen) {
        VTermRect rect = {0, 0, 0, 0};
        rect.end_row = state->rows;
*** ../vim-8.2.0793/src/libvterm/src/screen.c   2020-05-17 23:00:48.782969093 
+0200
--- src/libvterm/src/screen.c   2020-05-18 20:58:33.872732161 +0200
***************
*** 56,63 ****
    int global_reverse;
  
    // Primary and Altscreen. buffers[1] is lazily allocated as needed
- #define BUFIDX_PRIMARY   0
- #define BUFIDX_ALTSCREEN 1
    ScreenCell *buffers[2];
  
    // buffer will == buffers[0] or buffers[1], depending on altscreen
--- 56,61 ----
***************
*** 481,487 ****
    return 0;
  }
  
! static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int 
new_cols, int active, VTermPos *delta)
  {
    int old_rows = screen->rows;
    int old_cols = screen->cols;
--- 479,485 ----
    return 0;
  }
  
! static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int 
new_cols, int active, VTermStateFields *statefields)
  {
    int old_rows = screen->rows;
    int old_cols = screen->cols;
***************
*** 524,531 ****
      int row;
      for(row = 0; row <= old_row; row++)
        sb_pushline_from_row(screen, row);
!     if(delta)
!       delta->row -= (old_row + 1);
    }
    if(new_row >= 0 && bufidx == BUFIDX_PRIMARY &&
        screen->callbacks && screen->callbacks->sb_popline) {
--- 522,529 ----
      int row;
      for(row = 0; row <= old_row; row++)
        sb_pushline_from_row(screen, row);
!     if(active)
!       statefields->pos.row -= (old_row + 1);
    }
    if(new_row >= 0 && bufidx == BUFIDX_PRIMARY &&
        screen->callbacks && screen->callbacks->sb_popline) {
***************
*** 563,570 ****
        }
        new_row--;
  
!       if(delta)
!         delta->row++;
      }
    }
  
--- 561,568 ----
        }
        new_row--;
  
!       if(active)
!         statefields->pos.row++;
      }
    }
  
***************
*** 590,596 ****
     */
  }
  
! static int resize(int new_rows, int new_cols, VTermPos *delta, void *user)
  {
    VTermScreen *screen = user;
  
--- 588,594 ----
     */
  }
  
! static int resize(int new_rows, int new_cols, VTermStateFields *fields, void 
*user)
  {
    VTermScreen *screen = user;
  
***************
*** 606,614 ****
      screen->sb_buffer = vterm_allocator_malloc(screen->vt, 
sizeof(VTermScreenCell) * new_cols);
    }
  
!   resize_buffer(screen, 0, new_rows, new_cols, !altscreen_active, 
altscreen_active ? NULL : delta);
    if(screen->buffers[BUFIDX_ALTSCREEN])
!     resize_buffer(screen, 1, new_rows, new_cols, altscreen_active, 
altscreen_active ? delta : NULL);
  
    screen->buffer = altscreen_active ? screen->buffers[BUFIDX_ALTSCREEN] : 
screen->buffers[BUFIDX_PRIMARY];
  
--- 604,612 ----
      screen->sb_buffer = vterm_allocator_malloc(screen->vt, 
sizeof(VTermScreenCell) * new_cols);
    }
  
!   resize_buffer(screen, 0, new_rows, new_cols, !altscreen_active, fields);
    if(screen->buffers[BUFIDX_ALTSCREEN])
!     resize_buffer(screen, 1, new_rows, new_cols, altscreen_active, fields);
  
    screen->buffer = altscreen_active ? screen->buffers[BUFIDX_ALTSCREEN] : 
screen->buffers[BUFIDX_PRIMARY];
  
*** ../vim-8.2.0793/src/libvterm/src/vterm_internal.h   2020-05-17 
21:50:11.954655960 +0200
--- src/libvterm/src/vterm_internal.h   2020-05-18 20:49:20.050168168 +0200
***************
*** 32,37 ****
--- 32,40 ----
  #define CSI_ARGS_MAX 16
  #define CSI_LEADER_MAX 16
  
+ #define BUFIDX_PRIMARY   0
+ #define BUFIDX_ALTSCREEN 1
+ 
  typedef struct VTermEncoding VTermEncoding;
  
  typedef struct {
***************
*** 92,97 ****
--- 95,104 ----
    // Bitvector of tab stops
    unsigned char *tabstops;
  
+   /* Primary and Altscreen; lineinfos[1] is lazily allocated as needed */
+   VTermLineInfo *lineinfos[2];
+ 
+   /* lineinfo will == lineinfos[0] or lineinfos[1], depending on altscreen */
    VTermLineInfo *lineinfo;
  #define ROWWIDTH(state,row) ((state)->lineinfo[(row)].doublewidth ? 
((state)->cols / 2) : (state)->cols)
  #define THISROWWIDTH(state) ROWWIDTH(state, (state)->pos.row)
*** ../vim-8.2.0793/src/libvterm/include/vterm.h        2020-05-17 
22:27:36.728262245 +0200
--- src/libvterm/include/vterm.h        2020-05-18 21:05:45.327553399 +0200
***************
*** 268,273 ****
--- 268,282 ----
  // State layer
  // -----------
  
+ /* Copies of VTermState fields that the 'resize' callback might have reason to
+  * edit. 'resize' callback gets total control of these fields and may
+  * free-and-reallocate them if required. They will be copied back from the
+  * struct after the callback has returned.
+  */
+ typedef struct {
+   VTermPos pos;                /* current cursor position */
+ } VTermStateFields;
+ 
  typedef struct {
    int (*putglyph)(VTermGlyphInfo *info, VTermPos pos, void *user);
    int (*movecursor)(VTermPos pos, VTermPos oldpos, int visible, void *user);
***************
*** 280,286 ****
    // was accepted, 0 otherwise.
    int (*settermprop)(VTermProp prop, VTermValue *val, void *user);
    int (*bell)(void *user);
!   int (*resize)(int rows, int cols, VTermPos *delta, void *user);
    int (*setlineinfo)(int row, const VTermLineInfo *newinfo, const 
VTermLineInfo *oldinfo, void *user);
  } VTermStateCallbacks;
  
--- 289,295 ----
    // was accepted, 0 otherwise.
    int (*settermprop)(VTermProp prop, VTermValue *val, void *user);
    int (*bell)(void *user);
!   int (*resize)(int rows, int cols, VTermStateFields *fields, void *user);
    int (*setlineinfo)(int row, const VTermLineInfo *newinfo, const 
VTermLineInfo *oldinfo, void *user);
  } VTermStateCallbacks;
  
*** ../vim-8.2.0793/src/libvterm/t/67screen_dbl_wh.test 2020-05-17 
16:28:47.087869402 +0200
--- src/libvterm/t/67screen_dbl_wh.test 2020-05-18 21:03:12.755981839 +0200
***************
*** 30,32 ****
--- 30,38 ----
    ?screen_cell 0,0 = {0x61} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
  PUSH "\e#6"
    ?screen_cell 0,0 = {0x61} width=1 attrs={} dwl fg=rgb(240,240,240) 
bg=rgb(0,0,0)
+ 
+ !DWL doesn't spill over on scroll
+ RESET
+ PUSH "\e[25H\e#6Final\r\n"
+   ?screen_cell 23,0 = {0x46} width=1 attrs={} dwl fg=rgb(240,240,240) 
bg=rgb(0,0,0)
+   ?screen_cell 24,0 = {} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
*** ../vim-8.2.0793/src/libvterm/t/run-test.pl  2020-05-17 22:27:36.728262245 
+0200
--- src/libvterm/t/run-test.pl  2020-05-18 21:11:03.134635839 +0200
***************
*** 140,153 ****
        }
     }
     # Assertions start with '?'
!    elsif( $line =~ s/^\?([a-z]+.*?=)\s+// ) {
        do_onetest if defined $command;
  
        my ( $assertion ) = $1 =~ m/^(.*)\s+=/;
  
        $hin->print( "\?$assertion\n" );
        my $response = <$hout>; defined $response or wait, die "Test harness 
failed - $?\n";
!       chomp $response;
  
        if( $response ne $line ) {
           print "# Assert $assertion failed:\n" .
--- 140,153 ----
        }
     }
     # Assertions start with '?'
!    elsif( $line =~ s/^\?([a-z]+.*?=)\s*// ) {
        do_onetest if defined $command;
  
        my ( $assertion ) = $1 =~ m/^(.*)\s+=/;
  
        $hin->print( "\?$assertion\n" );
        my $response = <$hout>; defined $response or wait, die "Test harness 
failed - $?\n";
!       chomp $response; $response =~ s/^\s+|\s+$//g;
  
        if( $response ne $line ) {
           print "# Assert $assertion failed:\n" .
*** ../vim-8.2.0793/src/version.c       2020-05-18 20:16:56.617319687 +0200
--- src/version.c       2020-05-18 20:45:11.442967633 +0200
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     794,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
132. You come back and check this list every half-hour.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202005181913.04IJDUcW015268%40masaka.moolenaar.net.

Raspunde prin e-mail lui