Patch 9.0.0772
Problem:    The libvterm code is outdated.
Solution:   Include libvterm changes from revision 790 to 801.
Files:      src/libvterm/README, src/libvterm/doc/seqs.txt,
            src/libvterm/include/vterm.h, src/libvterm/src/screen.c,
            src/libvterm/src/state.c, src/libvterm/src/vterm.c,
            src/libvterm/src/vterm_internal.h, src/libvterm/t/run-test.pl,
            src/libvterm/t/harness.c, src/libvterm/t/26state_query.test,
            src/libvterm/t/60screen_ascii.test,
            src/libvterm/t/61screen_unicode.test,
            src/libvterm/t/62screen_damage.test,
            src/libvterm/t/63screen_resize.test,
            src/libvterm/t/65screen_protect.test


*** ../vim-9.0.0771/src/libvterm/README 2020-06-27 12:39:23.000000000 +0100
--- src/libvterm/README 2022-10-16 13:12:56.608222700 +0100
***************
*** 8,14 ****
  
  Modifications:
  - Add a .gitignore file.
! - Convert from C99 to C90.
  - Other changes to support embedding in Vim.
  
  To get the latest version of libvterm you need the "bzr" command and do:
--- 8,14 ----
  
  Modifications:
  - Add a .gitignore file.
! - Convert some code from C99 to C90.
  - Other changes to support embedding in Vim.
  
  To get the latest version of libvterm you need the "bzr" command and do:
*** ../vim-9.0.0771/src/libvterm/doc/seqs.txt   2021-11-24 17:50:42.000000000 
+0000
--- src/libvterm/doc/seqs.txt   2022-10-16 14:14:14.970839152 +0100
***************
*** 132,137 ****
--- 132,138 ----
             1 or 2       =   block
             3 or 4       =   underline
             5 or 6       =   I-beam to left
+    x   CSI > q          = XTVERSION, request version string
   23x   CSI " q          = DECSCA, select character attributes
  123x   CSI r            = DECSTBM
     x   CSI s            = DECSLRM
*** ../vim-9.0.0771/src/libvterm/include/vterm.h        2021-11-24 
18:52:29.000000000 +0000
--- src/libvterm/include/vterm.h        2022-10-16 13:58:51.121728059 +0100
***************
*** 26,31 ****
--- 26,36 ----
  #define VTERM_CHECK_VERSION \
          vterm_check_version(VTERM_VERSION_MAJOR, VTERM_VERSION_MINOR)
  
+ /* Any cell can contain at most one basic printing character and 5 combining
+  * characters. This number could be changed but will be ABI-incompatible if
+  * you do */
+ #define VTERM_MAX_CHARS_PER_CELL 6
+ 
  typedef struct VTerm VTerm;
  typedef struct VTermState VTermState;
  typedef struct VTermScreen VTermScreen;
***************
*** 297,302 ****
--- 302,308 ----
   */
  typedef struct {
    VTermPos pos;                /* current cursor position */
+   VTermLineInfo *lineinfos[2]; /* [1] may be NULL */
  } VTermStateFields;
  
  typedef struct {
***************
*** 306,316 ****
--- 312,341 ----
    void  (*free)(void *ptr, void *allocdata);
  } VTermAllocatorFunctions;
  
+ /* A convenient shortcut for default cases */
  void vterm_check_version(int major, int minor);
  
+ struct VTermBuilder {
+   int ver; /* currently unused but reserved for some sort of ABI version flag 
*/
+ 
+   int rows, cols;
+ 
+   const VTermAllocatorFunctions *allocator;
+   void *allocdata;
+ 
+   /* Override default sizes for various structures */
+   size_t outbuffer_len;  /* default: 4096 */
+   size_t tmpbuffer_len;  /* default: 4096 */
+ };
+ 
+ VTerm *vterm_build(const struct VTermBuilder *builder);
+ 
+ /* A convenient shortcut for default cases */
  // Allocate and initialize a new terminal with default allocators.
  VTerm *vterm_new(int rows, int cols);
  
+ /* These shortcuts are generally discouraged in favour of just using 
vterm_build() */
+ 
  // Allocate and initialize a new terminal with specified allocators.
  VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions 
*funcs, void *allocdata);
  
***************
*** 507,513 ****
  };
  
  typedef struct {
- #define VTERM_MAX_CHARS_PER_CELL 6
    uint32_t chars[VTERM_MAX_CHARS_PER_CELL];
    char     width;
    VTermScreenCellAttrs attrs;
--- 532,537 ----
*** ../vim-9.0.0771/src/libvterm/src/screen.c   2021-11-24 17:05:36.000000000 
+0000
--- src/libvterm/src/screen.c   2022-10-16 14:02:23.772851011 +0100
***************
*** 502,508 ****
--- 502,511 ----
    int old_cols = screen->cols;
  
    ScreenCell *old_buffer = screen->buffers[bufidx];
+   VTermLineInfo *old_lineinfo = statefields->lineinfos[bufidx];
+ 
    ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, 
sizeof(ScreenCell) * new_rows * new_cols);
+   VTermLineInfo *new_lineinfo = vterm_allocator_malloc(screen->vt, 
sizeof(new_lineinfo[0]) * new_rows);
  
    // Find the final row of old buffer content
    int old_row = old_rows - 1;
***************
*** 515,520 ****
--- 518,525 ----
      for( ; col < new_cols; col++)
        clearcell(screen, &new_buffer[new_row * new_cols + col]);
  
+     new_lineinfo[new_row] = old_lineinfo[old_row];
+ 
      old_row--;
      new_row--;
  
***************
*** 584,598 ****
      /* Scroll new rows back up to the top and fill in blanks at the bottom */
      int moverows = new_rows - new_row - 1;
      memmove(&new_buffer[0], &new_buffer[(new_row + 1) * new_cols], moverows * 
new_cols * sizeof(ScreenCell));
  
!     for(new_row = moverows; new_row < new_rows; new_row++)
        for(col = 0; col < new_cols; col++)
          clearcell(screen, &new_buffer[new_row * new_cols + col]);
    }
  
    vterm_allocator_free(screen->vt, old_buffer);
    screen->buffers[bufidx] = new_buffer;
  
    return;
  
    /* REFLOW TODO:
--- 589,609 ----
      /* Scroll new rows back up to the top and fill in blanks at the bottom */
      int moverows = new_rows - new_row - 1;
      memmove(&new_buffer[0], &new_buffer[(new_row + 1) * new_cols], moverows * 
new_cols * sizeof(ScreenCell));
+     memmove(&new_lineinfo[0], &new_lineinfo[new_row + 1], moverows * 
sizeof(new_lineinfo[0]));
  
!     for(new_row = moverows; new_row < new_rows; new_row++) {
        for(col = 0; col < new_cols; col++)
          clearcell(screen, &new_buffer[new_row * new_cols + col]);
+       new_lineinfo[new_row] = (VTermLineInfo){ 0 };
+     }
    }
  
    vterm_allocator_free(screen->vt, old_buffer);
    screen->buffers[bufidx] = new_buffer;
  
+   vterm_allocator_free(screen->vt, old_lineinfo);
+   statefields->lineinfos[bufidx] = new_lineinfo;
+ 
    return;
  
    /* REFLOW TODO:
***************
*** 606,611 ****
--- 617,623 ----
  
    int altscreen_active = (screen->buffers[BUFIDX_ALTSCREEN] && screen->buffer 
== screen->buffers[BUFIDX_ALTSCREEN]);
  
+   int old_rows = screen->rows;
    int old_cols = screen->cols;
  
    if(new_cols > old_cols) {
***************
*** 619,624 ****
--- 631,647 ----
    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);
+   else if(new_rows != old_rows) {
+     /* We don't need a full resize of the altscreen because it isn't enabled
+      * but we should at least keep the lineinfo the right size */
+     vterm_allocator_free(screen->vt, fields->lineinfos[BUFIDX_ALTSCREEN]);
+ 
+     VTermLineInfo *new_lineinfo = vterm_allocator_malloc(screen->vt, 
sizeof(new_lineinfo[0]) * new_rows);
+     for(int row = 0; row < new_rows; row++)
+       new_lineinfo[row] = (VTermLineInfo){ 0 };
+ 
+     fields->lineinfos[BUFIDX_ALTSCREEN] = new_lineinfo;
+   }
  
    screen->buffer = altscreen_active ? screen->buffers[BUFIDX_ALTSCREEN] : 
screen->buffers[BUFIDX_PRIMARY];
  
*** ../vim-9.0.0771/src/libvterm/src/state.c    2021-11-24 19:51:32.000000000 
+0000
--- src/libvterm/src/state.c    2022-10-16 14:19:02.362212476 +0100
***************
*** 280,286 ****
  static int on_text(const char bytes[], size_t len, void *user)
  {
    VTermState *state = user;
-   uint32_t *codepoints;
    int npoints = 0;
    size_t eaten = 0;
    VTermEncodingInstance *encoding;
--- 280,285 ----
***************
*** 290,298 ****
  
    // We'll have at most len codepoints, plus one from a previous incomplete
    // sequence.
!   codepoints = vterm_allocator_malloc(state->vt, (len + 1) * 
sizeof(uint32_t));
!   if (codepoints == NULL)
!     return 0;
  
    encoding =
      state->gsingle_set     ? &state->encoding[state->gsingle_set] :
--- 289,296 ----
  
    // We'll have at most len codepoints, plus one from a previous incomplete
    // sequence.
!   uint32_t *codepoints = (uint32_t *)(state->vt->tmpbuffer);
!   size_t maxpoints = (state->vt->tmpbuffer_len) / sizeof(uint32_t);
  
    encoding =
      state->gsingle_set     ? &state->encoding[state->gsingle_set] :
***************
*** 301,307 ****
                               &state->encoding[state->gr_set];
  
    (*encoding->enc->decode)(encoding->enc, encoding->data,
!       codepoints, &npoints, state->gsingle_set ? 1 : (int)len,
        bytes, &eaten, len);
  
    /* There's a chance an encoding (e.g. UTF-8) hasn't found enough bytes yet
--- 299,305 ----
                               &state->encoding[state->gr_set];
  
    (*encoding->enc->decode)(encoding->enc, encoding->data,
!       codepoints, &npoints, state->gsingle_set ? 1 : (int)maxpoints,
        bytes, &eaten, len);
  
    /* There's a chance an encoding (e.g. UTF-8) hasn't found enough bytes yet
***************
*** 309,315 ****
     */
    if(!npoints)
    {
-     vterm_allocator_free(state->vt, codepoints);
      return (int)eaten;
    }
  
--- 307,312 ----
***************
*** 363,375 ****
      int glyph_starts = i;
      int glyph_ends;
      int width = 0;
-     uint32_t *chars;
  
!     for(glyph_ends = i + 1; glyph_ends < npoints; glyph_ends++)
        if(!vterm_unicode_is_combining(codepoints[glyph_ends]))
          break;
  
!     chars = vterm_allocator_malloc(state->vt, (glyph_ends - glyph_starts + 1) 
* sizeof(uint32_t));
      if (chars == NULL)
        break;
  
--- 360,373 ----
      int glyph_starts = i;
      int glyph_ends;
      int width = 0;
  
!     for(glyph_ends = i + 1;
!         (glyph_ends < npoints) && (glyph_ends < glyph_starts + 
VTERM_MAX_CHARS_PER_CELL);
!         glyph_ends++)
        if(!vterm_unicode_is_combining(codepoints[glyph_ends]))
          break;
  
!     uint32_t *chars = vterm_allocator_malloc(state->vt, 
(VTERM_MAX_CHARS_PER_CELL + 1) * sizeof(uint32_t));
      if (chars == NULL)
        break;
  
***************
*** 461,467 ****
    }
  #endif
  
-   vterm_allocator_free(state->vt, codepoints);
    return (int)eaten;
  }
  
--- 459,464 ----
***************
*** 952,957 ****
--- 949,960 ----
    vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "?%d;%d$y", num, reply ? 
1 : 2);
  }
  
+ static void request_version_string(VTermState *state)
+ {
+   vterm_push_output_sprintf_str(state->vt, C1_DCS, TRUE, ">|libvterm(%d.%d)",
+       VTERM_VERSION_MAJOR, VTERM_VERSION_MINOR);
+ }
+ 
  static int on_csi(const char *leader, const long args[], int argcount, const 
char *intermed, char command, void *user)
  {
    VTermState *state = user;
***************
*** 1423,1428 ****
--- 1426,1435 ----
      request_dec_mode(state, CSI_ARG(args[0]));
      break;
  
+   case LEADER('>', 0x71): // XTVERSION - xterm query version string
+     request_version_string(state);
+     break;
+ 
    case INTERMED(' ', 0x71): // DECSCUSR - DEC set cursor shape
      val = CSI_ARG_OR(args[0], 1);
  
***************
*** 2018,2050 ****
      state->tabstops = newtabstops;
    }
  
-   if(rows != state->rows) {
-     int bufidx;
-     for(bufidx = BUFIDX_PRIMARY; bufidx <= BUFIDX_ALTSCREEN; bufidx++) {
-       int row;
-       VTermLineInfo *oldlineinfo = state->lineinfos[bufidx];
-       VTermLineInfo *newlineinfo;
-       if(!oldlineinfo)
-         continue;
- 
-       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++) {
-       VTermLineInfo lineInfo = {0x0};
-       newlineinfo[row] = lineInfo;
-       }
- 
-       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;
    state->cols = cols;
  
--- 2025,2030 ----
***************
*** 2054,2064 ****
      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;
--- 2034,2077 ----
      UBOUND(state->scrollregion_right, state->cols);
  
    fields.pos = state->pos;
+   fields.lineinfos[0] = state->lineinfos[0];
+   fields.lineinfos[1] = state->lineinfos[1];
  
!   if(state->callbacks && state->callbacks->resize) {
      (*state->callbacks->resize)(rows, cols, &fields, state->cbdata);
  
!     state->pos = fields.pos;
! 
!     state->lineinfos[0] = fields.lineinfos[0];
!     state->lineinfos[1] = fields.lineinfos[1];
!   }
!   else {
!     if(rows != state->rows) {
!       for(int bufidx = BUFIDX_PRIMARY; bufidx <= BUFIDX_ALTSCREEN; bufidx++) {
!         VTermLineInfo *oldlineinfo = state->lineinfos[bufidx];
!         if(!oldlineinfo)
!           continue;
! 
!         VTermLineInfo *newlineinfo = vterm_allocator_malloc(state->vt, rows * 
sizeof(VTermLineInfo));
! 
!         int row;
!         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];
  
    if(state->at_phantom && state->pos.col < cols-1) {
      state->at_phantom = 0;
*** ../vim-9.0.0771/src/libvterm/src/vterm.c    2021-11-24 19:05:46.000000000 
+0000
--- src/libvterm/src/vterm.c    2022-10-16 13:44:39.105012986 +0100
***************
*** 34,54 ****
  
  VTerm *vterm_new(int rows, int cols)
  {
!   return vterm_new_with_allocator(rows, cols, &default_allocator, NULL);
  }
  
  VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions 
*funcs, void *allocdata)
  {
    /* Need to bootstrap using the allocator function directly */
!   VTerm *vt = (*funcs->malloc)(sizeof(VTerm), allocdata);
  
!   if (vt == NULL)
!     return NULL;
!   vt->allocator = funcs;
!   vt->allocdata = allocdata;
  
!   vt->rows = rows;
!   vt->cols = cols;
  
    vt->parser.state = NORMAL;
  
--- 34,72 ----
  
  VTerm *vterm_new(int rows, int cols)
  {
!   struct VTermBuilder builder;
!   memset(&builder, 0, sizeof(builder));
!   builder.rows = rows;
!   builder.cols = cols;
!   return vterm_build(&builder);
  }
  
  VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions 
*funcs, void *allocdata)
  {
+   struct VTermBuilder builder;
+   memset(&builder, 0, sizeof(builder));
+   builder.rows = rows;
+   builder.cols = cols;
+   builder.allocator = funcs;
+   builder.allocdata = allocdata;
+   return vterm_build(&builder);
+ }
+ 
+ /* A handy macro for defaulting values out of builder fields */
+ #define DEFAULT(v, def)  ((v) ? (v) : (def))
+ 
+ VTerm *vterm_build(const struct VTermBuilder *builder)
+ {
+   const VTermAllocatorFunctions *allocator = DEFAULT(builder->allocator, 
&default_allocator);
+ 
    /* Need to bootstrap using the allocator function directly */
!   VTerm *vt = (*allocator->malloc)(sizeof(VTerm), builder->allocdata);
  
!   vt->allocator = allocator;
!   vt->allocdata = builder->allocdata;
  
!   vt->rows = builder->rows;
!   vt->cols = builder->cols;
  
    vt->parser.state = NORMAL;
  
***************
*** 58,68 ****
    vt->outfunc = NULL;
    vt->outdata = NULL;
  
!   vt->outbuffer_len = 200;
    vt->outbuffer_cur = 0;
    vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len);
  
!   vt->tmpbuffer_len = 64;
    vt->tmpbuffer = vterm_allocator_malloc(vt, vt->tmpbuffer_len);
  
    if (vt->tmpbuffer == NULL
--- 76,86 ----
    vt->outfunc = NULL;
    vt->outdata = NULL;
  
!   vt->outbuffer_len = DEFAULT(builder->outbuffer_len, 4096);
    vt->outbuffer_cur = 0;
    vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len);
  
!   vt->tmpbuffer_len = DEFAULT(builder->tmpbuffer_len, 4096);
    vt->tmpbuffer = vterm_allocator_malloc(vt, vt->tmpbuffer_len);
  
    if (vt->tmpbuffer == NULL
*** ../vim-9.0.0771/src/libvterm/src/vterm_internal.h   2022-06-09 
20:49:49.000000000 +0100
--- src/libvterm/src/vterm_internal.h   2022-10-16 13:17:52.015914850 +0100
***************
*** 182,188 ****
  
  struct VTerm
  {
!   VTermAllocatorFunctions *allocator;
    void *allocdata;
  
    int rows;
--- 182,188 ----
  
  struct VTerm
  {
!   const VTermAllocatorFunctions *allocator;
    void *allocdata;
  
    int rows;
*** ../vim-9.0.0771/src/libvterm/t/run-test.pl  2021-11-24 18:52:34.000000000 
+0000
--- src/libvterm/t/run-test.pl  2022-10-16 14:12:02.019152479 +0100
***************
*** 139,155 ****
     # ?screen_row assertion is emulated here
     elsif( $line =~ s/^\?screen_row\s+(\d+)\s*=\s*// ) {
        my $row = $1;
!       my $row1 = $row + 1;
!       my $want = eval($line);
  
        do_onetest if defined $command;
  
!       # TODO: may not be 80
!       $hin->print( "\?screen_chars $row,0,$row1,80\n" );
        my $response = <$hout>;
        chomp $response;
  
!       $response = pack "C*", map hex, split m/,/, $response;
        if( $response ne $want ) {
           print "# line $linenum: Assert ?screen_row $row failed:\n" .
                 "# Expected: $want\n" .
--- 139,161 ----
     # ?screen_row assertion is emulated here
     elsif( $line =~ s/^\?screen_row\s+(\d+)\s*=\s*// ) {
        my $row = $1;
!       my $want;
! 
!       if( $line =~ m/^"/ ) {
!          $want = eval($line);
!       }
!       else {
!          # Turn 0xDD,0xDD,... directly into bytes
!          $want = pack "C*", map { hex } split m/,/, $line;
!       }
  
        do_onetest if defined $command;
  
!       $hin->print( "\?screen_chars $row\n" );
        my $response = <$hout>;
        chomp $response;
  
!       $response = pack "C*", map { hex } split m/,/, $response;
        if( $response ne $want ) {
           print "# line $linenum: Assert ?screen_row $row failed:\n" .
                 "# Expected: $want\n" .
*** ../vim-9.0.0771/src/libvterm/t/harness.c    2021-11-24 18:55:23.000000000 
+0000
--- src/libvterm/t/harness.c    2022-10-16 14:11:17.515261625 +0100
***************
*** 1001,1007 ****
          size_t len;
          while(linep[0] == ' ')
            linep++;
!         if(sscanf(linep, "%d,%d,%d,%d", &rect.start_row, &rect.start_col, 
&rect.end_row, &rect.end_col) < 4) {
            printf("! screen_chars unrecognised input\n");
            goto abort_line;
          }
--- 1001,1014 ----
          size_t len;
          while(linep[0] == ' ')
            linep++;
!         if(sscanf(linep, "%d,%d,%d,%d", &rect.start_row, &rect.start_col, 
&rect.end_row, &rect.end_col) == 4)
!           ; // fine
!         else if(sscanf(linep, "%d", &rect.start_row) == 1) {
!           rect.end_row = rect.start_row + 1;
!           rect.start_col = 0;
!           vterm_get_size(vt, NULL, &rect.end_col);
!         }
!         else {
            printf("! screen_chars unrecognised input\n");
            goto abort_line;
          }
*** ../vim-9.0.0771/src/libvterm/t/26state_query.test   2020-05-21 
18:29:03.000000000 +0100
--- src/libvterm/t/26state_query.test   2022-10-16 14:30:52.531785293 +0100
***************
*** 6,11 ****
--- 6,16 ----
  PUSH "\e[c"
    output "\e[?1;2c"
  
+ !XTVERSION
+ RESET
+ PUSH "\e[>q"
+   output "\eP>|libvterm(0.2)\e\\"
+ 
  !DSR
  RESET
  PUSH "\e[5n"
***************
*** 57,62 ****
    output "\x{9b}0n"
  PUSH "\e F"
  
! !Truncation on attempted buffer overflow
! PUSH "\e[6n" x 30
!   output "\e[10;10R" x 25
--- 62,67 ----
    output "\x{9b}0n"
  PUSH "\e F"
  
! #!Truncation on attempted buffer overflow
! #PUSH "\e[6n" x 30
! #  output "\e[10;10R" x 25
*** ../vim-9.0.0771/src/libvterm/t/60screen_ascii.test  2020-05-18 
20:32:56.000000000 +0100
--- src/libvterm/t/60screen_ascii.test  2022-10-16 14:12:47.047044313 +0100
***************
*** 18,28 ****
    ?screen_eol 0,3 = 1
  PUSH "\e[H"
    movecursor 0,0
!   ?screen_chars 0,0,1,80 = "ABC"
    ?screen_text 0,0,1,80 = 0x41,0x42,0x43
  PUSH "E"
    movecursor 0,1
!   ?screen_chars 0,0,1,80 = "EBC"
    ?screen_text 0,0,1,80 = 0x45,0x42,0x43
  
  WANTSCREEN -c
--- 18,28 ----
    ?screen_eol 0,3 = 1
  PUSH "\e[H"
    movecursor 0,0
!   ?screen_row 0 = "ABC"
    ?screen_text 0,0,1,80 = 0x41,0x42,0x43
  PUSH "E"
    movecursor 0,1
!   ?screen_row 0 = "EBC"
    ?screen_text 0,0,1,80 = 0x45,0x42,0x43
  
  WANTSCREEN -c
***************
*** 30,43 ****
  !Erase
  RESET
  PUSH "ABCDE\e[H\e[K"
!   ?screen_chars 0,0,1,80 = 
    ?screen_text 0,0,1,80 = 
  
  !Copycell
  RESET
  PUSH "ABC\e[H\e[@"
  PUSH "1"
!   ?screen_chars 0,0,1,80 = "1ABC"
  
  RESET
  PUSH "ABC\e[H\e[P"
--- 30,43 ----
  !Erase
  RESET
  PUSH "ABCDE\e[H\e[K"
!   ?screen_row 0 = ""
    ?screen_text 0,0,1,80 = 
  
  !Copycell
  RESET
  PUSH "ABC\e[H\e[@"
  PUSH "1"
!   ?screen_row 0 = "1ABC"
  
  RESET
  PUSH "ABC\e[H\e[P"
***************
*** 48,54 ****
  !Space padding
  RESET
  PUSH "Hello\e[CWorld"
!   ?screen_chars 0,0,1,80 = "Hello World"
    ?screen_text 0,0,1,80 = 
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64
  
  !Linefeed padding
--- 48,54 ----
  !Space padding
  RESET
  PUSH "Hello\e[CWorld"
!   ?screen_row 0 = "Hello World"
    ?screen_text 0,0,1,80 = 
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64
  
  !Linefeed padding
***************
*** 60,69 ****
  !Altscreen
  RESET
  PUSH "P"
!   ?screen_chars 0,0,1,80 = "P"
  PUSH "\e[?1049h"
!   ?screen_chars 0,0,1,80 = 
  PUSH "\e[2K\e[HA"
!   ?screen_chars 0,0,1,80 = "A"
  PUSH "\e[?1049l"
!   ?screen_chars 0,0,1,80 = "P"
--- 60,69 ----
  !Altscreen
  RESET
  PUSH "P"
!   ?screen_row 0 = "P"
  PUSH "\e[?1049h"
!   ?screen_row 0 = ""
  PUSH "\e[2K\e[HA"
!   ?screen_row 0 = "A"
  PUSH "\e[?1049l"
!   ?screen_row 0 = "P"
*** ../vim-9.0.0771/src/libvterm/t/61screen_unicode.test        2020-01-26 
20:53:39.000000000 +0000
--- src/libvterm/t/61screen_unicode.test        2022-10-16 14:12:47.047044313 
+0100
***************
*** 7,13 ****
  # U+00E9 = 0xC3 0xA9  name: LATIN SMALL LETTER E WITH ACUTE
  RESET
  PUSH "\xC3\x81\xC3\xA9"
!   ?screen_chars 0,0,1,80 = 0xc1,0xe9
    ?screen_text 0,0,1,80 = 0xc3,0x81,0xc3,0xa9
    ?screen_cell 0,0 = {0xc1} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
  
--- 7,13 ----
  # U+00E9 = 0xC3 0xA9  name: LATIN SMALL LETTER E WITH ACUTE
  RESET
  PUSH "\xC3\x81\xC3\xA9"
!   ?screen_row 0 = 0xc1,0xe9
    ?screen_text 0,0,1,80 = 0xc3,0x81,0xc3,0xa9
    ?screen_cell 0,0 = {0xc1} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
  
***************
*** 16,22 ****
  RESET
  PUSH "0123\e[H"
  PUSH "\xEF\xBC\x90"
!   ?screen_chars 0,0,1,80 = 0xff10,0x32,0x33
    ?screen_text 0,0,1,80 = 0xef,0xbc,0x90,0x32,0x33
    ?screen_cell 0,0 = {0xff10} width=2 attrs={} fg=rgb(240,240,240) 
bg=rgb(0,0,0)
  
--- 16,22 ----
  RESET
  PUSH "0123\e[H"
  PUSH "\xEF\xBC\x90"
!   ?screen_row 0 = 0xff10,0x32,0x33
    ?screen_text 0,0,1,80 = 0xef,0xbc,0x90,0x32,0x33
    ?screen_cell 0,0 = {0xff10} width=2 attrs={} fg=rgb(240,240,240) 
bg=rgb(0,0,0)
  
***************
*** 25,31 ****
  RESET
  PUSH "0123\e[H"
  PUSH "e\xCC\x81"
!   ?screen_chars 0,0,1,80 = 0x65,0x301,0x31,0x32,0x33
    ?screen_text 0,0,1,80 = 0x65,0xcc,0x81,0x31,0x32,0x33
    ?screen_cell 0,0 = {0x65,0x301} width=1 attrs={} fg=rgb(240,240,240) 
bg=rgb(0,0,0)
  
--- 25,31 ----
  RESET
  PUSH "0123\e[H"
  PUSH "e\xCC\x81"
!   ?screen_row 0 = 0x65,0x301,0x31,0x32,0x33
    ?screen_text 0,0,1,80 = 0x65,0xcc,0x81,0x31,0x32,0x33
    ?screen_cell 0,0 = {0x65,0x301} width=1 attrs={} fg=rgb(240,240,240) 
bg=rgb(0,0,0)
  
*** ../vim-9.0.0771/src/libvterm/t/62screen_damage.test 2020-05-18 
20:32:56.000000000 +0100
--- src/libvterm/t/62screen_damage.test 2022-10-16 14:12:47.047044313 +0100
***************
*** 152,155 ****
  DAMAGEFLUSH
    moverect 1..25,0..80 -> 0..24,0..80
    damage 24..25,0..80
!   ?screen_chars 23,0,24,5 = "ABE"
--- 152,155 ----
  DAMAGEFLUSH
    moverect 1..25,0..80 -> 0..24,0..80
    damage 24..25,0..80
!   ?screen_row 23 = "ABE"
*** ../vim-9.0.0771/src/libvterm/t/63screen_resize.test 2020-06-27 
17:10:29.000000000 +0100
--- src/libvterm/t/63screen_resize.test 2022-10-16 14:12:47.047044313 +0100
***************
*** 28,47 ****
  RESET
  RESIZE 25,80
  PUSH "Top\e[10HLine 10"
!   ?screen_chars 0,0,1,80 = "Top"
!   ?screen_chars 9,0,10,80 = "Line 10"
    ?cursor = 9,7
  RESIZE 20,80
!   ?screen_chars 0,0,1,80 = "Top"
!   ?screen_chars 9,0,10,80 = "Line 10"
    ?cursor = 9,7
  
  !Resize shorter with content must scroll
  RESET
  RESIZE 25,80
  PUSH "Top\e[25HLine 25\e[15H"
!   ?screen_chars 0,0,1,80 = "Top"
!   ?screen_chars 24,0,25,80 = "Line 25"
    ?cursor = 14,0
  WANTSCREEN b
  RESIZE 20,80
--- 28,47 ----
  RESET
  RESIZE 25,80
  PUSH "Top\e[10HLine 10"
!   ?screen_row 0 = "Top"
!   ?screen_row 9 = "Line 10"
    ?cursor = 9,7
  RESIZE 20,80
!   ?screen_row 0 = "Top"
!   ?screen_row 9 = "Line 10"
    ?cursor = 9,7
  
  !Resize shorter with content must scroll
  RESET
  RESIZE 25,80
  PUSH "Top\e[25HLine 25\e[15H"
!   ?screen_row 0 = "Top"
!   ?screen_row 24 = "Line 25"
    ?cursor = 14,0
  WANTSCREEN b
  RESIZE 20,80
***************
*** 50,57 ****
    sb_pushline 80 =
    sb_pushline 80 =
    sb_pushline 80 =
!   ?screen_chars 0,0,1,80 = 
!   ?screen_chars 19,0,20,80 = "Line 25"
    ?cursor = 9,0
  
  !Resize shorter does not lose line with cursor
--- 50,57 ----
    sb_pushline 80 =
    sb_pushline 80 =
    sb_pushline 80 =
!   ?screen_row 0  = ""
!   ?screen_row 19 = "Line 25"
    ?cursor = 9,0
  
  !Resize shorter does not lose line with cursor
***************
*** 62,72 ****
  WANTSCREEN b
  PUSH "\e[24HLine 24\r\nLine 25\r\n"
    sb_pushline 80 =
!   ?screen_chars 23,0,24,10 = "Line 25"
    ?cursor = 24,0
  RESIZE 24,80
    sb_pushline 80 =
!   ?screen_chars 22,0,23,10 = "Line 25"
    ?cursor = 23,0
  
  !Resize shorter does not send the cursor to a negative row
--- 62,72 ----
  WANTSCREEN b
  PUSH "\e[24HLine 24\r\nLine 25\r\n"
    sb_pushline 80 =
!   ?screen_row 23 = "Line 25"
    ?cursor = 24,0
  RESIZE 24,80
    sb_pushline 80 =
!   ?screen_row 22 = "Line 25"
    ?cursor = 23,0
  
  !Resize shorter does not send the cursor to a negative row
***************
*** 90,97 ****
  WANTSCREEN -b
  RESIZE 25,80
  PUSH "Line 1\e[25HBottom\e[15H"
!   ?screen_chars 0,0,1,80 = "Line 1"
!   ?screen_chars 24,0,25,80 = "Bottom"
    ?cursor = 14,0
  WANTSCREEN b
  RESIZE 30,80
--- 90,97 ----
  WANTSCREEN -b
  RESIZE 25,80
  PUSH "Line 1\e[25HBottom\e[15H"
!   ?screen_row 0  = "Line 1"
!   ?screen_row 24 = "Bottom"
    ?cursor = 14,0
  WANTSCREEN b
  RESIZE 30,80
***************
*** 100,108 ****
    sb_popline 80
    sb_popline 80
    sb_popline 80
!   ?screen_chars 0,0,1,80 = "ABCDE"
!   ?screen_chars 5,0,6,80 = "Line 1"
!   ?screen_chars 29,0,30,80 = "Bottom"
    ?cursor = 19,0
  WANTSCREEN -b
  
--- 100,108 ----
    sb_popline 80
    sb_popline 80
    sb_popline 80
!   ?screen_row 0  = "ABCDE"
!   ?screen_row 5  = "Line 1"
!   ?screen_row 29 = "Bottom"
    ?cursor = 19,0
  WANTSCREEN -b
  
***************
*** 112,117 ****
  RESIZE 25,80
  PUSH "Main screen\e[?1049h\e[HAlt screen"
  RESIZE 30,80
!   ?screen_chars 0,0,1,3 = "Alt"
  PUSH "\e[?1049l"
!   ?screen_chars 0,0,1,3 = "Mai"
--- 112,117 ----
  RESIZE 25,80
  PUSH "Main screen\e[?1049h\e[HAlt screen"
  RESIZE 30,80
!   ?screen_row 0 = "Alt screen"
  PUSH "\e[?1049l"
!   ?screen_row 0 = "Main screen"
*** ../vim-9.0.0771/src/libvterm/t/65screen_protect.test        2017-06-24 
15:44:02.000000000 +0100
--- src/libvterm/t/65screen_protect.test        2022-10-16 14:12:47.047044313 
+0100
***************
*** 4,16 ****
  !Selective erase
  RESET
  PUSH "A\e[1\"qB\e[\"qC"
!   ?screen_chars 0,0,1,3 = 0x41,0x42,0x43
  PUSH "\e[G\e[?J"
!   ?screen_chars 0,0,1,3 = 0x20,0x42
  
  !Non-selective erase
  RESET
  PUSH "A\e[1\"qB\e[\"qC"
!   ?screen_chars 0,0,1,3 = 0x41,0x42,0x43
  PUSH "\e[G\e[J"
!   ?screen_chars 0,0,1,3 = 
--- 4,16 ----
  !Selective erase
  RESET
  PUSH "A\e[1\"qB\e[\"qC"
!   ?screen_row 0 = "ABC"
  PUSH "\e[G\e[?J"
!   ?screen_row 0 = " B"
  
  !Non-selective erase
  RESET
  PUSH "A\e[1\"qB\e[\"qC"
!   ?screen_row 0 = "ABC"
  PUSH "\e[G\e[J"
!   ?screen_row 0 = ""
*** ../vim-9.0.0771/src/version.c       2022-10-16 12:49:08.591842875 +0100
--- src/version.c       2022-10-16 14:31:20.075914233 +0100
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     772,
  /**/

-- 
It is illegal for anyone to try and stop a child from playfully jumping over
puddles of water.
                [real standing law in California, United States of America]

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20221016133632.7D48A1C05ED%40moolenaar.net.

Raspunde prin e-mail lui