Patch 8.2.0324
Problem:    Text property not updated correctly when inserting/deleting.
Solution:   Use the right column when deleting. Make zero-width text
            properties respect start_incl and end_incl. (Axel Forsman,
            closes #5696, closes #5679)
Files:      src/change.c, src/textprop.c, src/testdir/test_listener.vim,
            src/testdir/test_textprop.vim


*** ../vim-8.2.0323/src/change.c        2020-01-01 16:18:33.204997405 +0100
--- src/change.c        2020-02-26 21:30:39.696404345 +0100
***************
*** 1301,1307 ****
  #endif
  
      // mark the buffer as changed and prepare for displaying
!     inserted_bytes(lnum, curwin->w_cursor.col, -count);
  
      return OK;
  }
--- 1301,1307 ----
  #endif
  
      // mark the buffer as changed and prepare for displaying
!     inserted_bytes(lnum, col, -count);
  
      return OK;
  }
*** ../vim-8.2.0323/src/textprop.c      2020-01-10 19:56:42.774995632 +0100
--- src/textprop.c      2020-02-26 21:47:14.650393448 +0100
***************
*** 1232,1238 ****
  {
      int               proplen;
      char_u    *props;
-     textprop_T        tmp_prop;
      proptype_T  *pt;
      int               dirty = FALSE;
      int               ri, wi;
--- 1232,1237 ----
***************
*** 1249,1310 ****
      wi = 0; // write index
      for (ri = 0; ri < proplen; ++ri)
      {
!       int start_incl;
  
!       mch_memmove(&tmp_prop, props + ri * sizeof(textprop_T),
!                                                          sizeof(textprop_T));
!       pt = text_prop_type_by_id(curbuf, tmp_prop.tp_type);
!       start_incl = (flags & APC_SUBSTITUTE) ||
!                      (pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL));
! 
!       if (bytes_added > 0
!               && (tmp_prop.tp_col >= col + (start_incl ? 2 : 1)))
        {
!           tmp_prop.tp_col += bytes_added;
!           // Save for undo if requested and not done yet.
!           if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
!               u_savesub(lnum);
!           dirty = TRUE;
        }
!       else if (bytes_added <= 0 && (tmp_prop.tp_col > col + 1))
        {
            int len_changed = FALSE;
  
!           if (tmp_prop.tp_col + bytes_added < col + 1)
            {
!               tmp_prop.tp_len += (tmp_prop.tp_col - 1 - col) + bytes_added;
!               tmp_prop.tp_col = col + 1;
                len_changed = TRUE;
            }
            else
!               tmp_prop.tp_col += bytes_added;
            // Save for undo if requested and not done yet.
            if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
                u_savesub(lnum);
            dirty = TRUE;
!           if (len_changed && tmp_prop.tp_len <= 0)
!               continue;  // drop this text property
        }
!       else if (tmp_prop.tp_len > 0
!               && tmp_prop.tp_col + tmp_prop.tp_len > col
!                      + ((pt != NULL && (pt->pt_flags & PT_FLAG_INS_END_INCL))
!                                                                     ? 0 : 1))
        {
!           int after = col - bytes_added
!                                    - (tmp_prop.tp_col - 1 + tmp_prop.tp_len);
            if (after > 0)
!               tmp_prop.tp_len += bytes_added + after;
            else
!               tmp_prop.tp_len += bytes_added;
            // Save for undo if requested and not done yet.
            if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
                u_savesub(lnum);
            dirty = TRUE;
!           if (tmp_prop.tp_len <= 0)
                continue;  // drop this text property
        }
!       mch_memmove(props + wi * sizeof(textprop_T), &tmp_prop,
!                                                          sizeof(textprop_T));
        ++wi;
      }
      if (dirty)
--- 1248,1327 ----
      wi = 0; // write index
      for (ri = 0; ri < proplen; ++ri)
      {
!       textprop_T      prop;
!       int             start_incl, end_incl;
!       int             can_drop;
! 
!       mch_memmove(&prop, props + ri * sizeof(textprop_T), sizeof(textprop_T));
!       pt = text_prop_type_by_id(curbuf, prop.tp_type);
!       start_incl = (pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL))
!                                                  || (flags & APC_SUBSTITUTE);
!       end_incl = (pt != NULL && (pt->pt_flags & PT_FLAG_INS_END_INCL));
!       // Do not drop zero-width props if they later can increase in size
!       can_drop = !(start_incl || end_incl);
  
!       if (bytes_added > 0)
        {
!           if (col + 1 <= prop.tp_col
!                             - (start_incl || (prop.tp_len == 0 && end_incl)))
!           {
!               // Change is entirely before the text property: Only shift
!               prop.tp_col += bytes_added;
!               // Save for undo if requested and not done yet.
!               if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
!                   u_savesub(lnum);
!               dirty = TRUE;
!           }
!           else if (col + 1 < prop.tp_col + prop.tp_len + end_incl)
!           {
!               // Insertion was inside text property
!               prop.tp_len += bytes_added;
!               // Save for undo if requested and not done yet.
!               if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
!                   u_savesub(lnum);
!               dirty = TRUE;
!           }
        }
!       else if (prop.tp_col > col + 1)
        {
            int len_changed = FALSE;
  
!           if (prop.tp_col + bytes_added < col + 1)
            {
!               prop.tp_len += (prop.tp_col - 1 - col) + bytes_added;
!               prop.tp_col = col + 1;
                len_changed = TRUE;
            }
            else
!               prop.tp_col += bytes_added;
            // Save for undo if requested and not done yet.
            if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
                u_savesub(lnum);
            dirty = TRUE;
!           if (len_changed && prop.tp_len <= 0)
!           {
!               prop.tp_len = 0;
!               if (can_drop)
!                   continue;  // drop this text property
!           }
        }
!       else if (prop.tp_len > 0 && prop.tp_col + prop.tp_len > col)
        {
!           int after = col - bytes_added - (prop.tp_col - 1 + prop.tp_len);
! 
            if (after > 0)
!               prop.tp_len += bytes_added + after;
            else
!               prop.tp_len += bytes_added;
            // Save for undo if requested and not done yet.
            if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
                u_savesub(lnum);
            dirty = TRUE;
!           if (prop.tp_len <= 0 && can_drop)
                continue;  // drop this text property
        }
! 
!       mch_memmove(props + wi * sizeof(textprop_T), &prop, sizeof(textprop_T));
        ++wi;
      }
      if (dirty)
*** ../vim-8.2.0323/src/testdir/test_listener.vim       2020-01-03 
20:59:55.847158293 +0100
--- src/testdir/test_listener.vim       2020-02-26 21:30:39.696404345 +0100
***************
*** 326,328 ****
--- 326,341 ----
    bwipe!
    delfunc Listener
  endfunc
+ 
+ func Test_col_after_deletion_moved_cur()
+       func Listener(bufnr, start, end, added, changes)
+     call assert_equal([#{lnum: 1, end: 2, added: 0, col: 2}], a:changes)
+       endfunc
+       new
+       call setline(1, ['foo'])
+       let lid = listener_add('Listener')
+       call feedkeys("lD", 'xt')
+   call listener_flush()
+       bwipe!
+       delfunc Listener
+ endfunc
*** ../vim-8.2.0323/src/testdir/test_textprop.vim       2020-01-13 
20:40:47.694773941 +0100
--- src/testdir/test_textprop.vim       2020-02-26 21:43:43.762965932 +0100
***************
*** 6,13 ****
  
  source screendump.vim
  
- " test length zero
- 
  func Test_proptype_global()
    call prop_type_add('comment', {'highlight': 'Directory', 'priority': 123, 
'start_incl': 1, 'end_incl': 1})
    let proptypes = prop_type_list()
--- 6,11 ----
***************
*** 233,245 ****
  
    " Prop without length or end column is zero length
    call prop_clear(1)
!   call prop_add(1, 5, {'type': 'two'})
!   let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 
'end': 1}]
    call assert_equal(expected, prop_list(1))
  
    call assert_fails("call prop_add(1, 5, {'type': 'two', 'bufnr': 234343})", 
'E158:')
  
    call DeletePropTypes()
    bwipe!
  endfunc
  
--- 231,250 ----
  
    " Prop without length or end column is zero length
    call prop_clear(1)
!   call prop_type_add('included', {'start_incl': 1, 'end_incl': 1})
!   call prop_add(1, 5, #{type: 'included'})
!   let expected = [#{col: 5, length: 0, type: 'included', id: 0, start: 1, 
end: 1}]
!   call assert_equal(expected, prop_list(1))
! 
!   " Inserting text makes the prop bigger.
!   exe "normal 5|ixx\<Esc>"
!   let expected = [#{col: 5, length: 2, type: 'included', id: 0, start: 1, 
end: 1}]
    call assert_equal(expected, prop_list(1))
  
    call assert_fails("call prop_add(1, 5, {'type': 'two', 'bufnr': 234343})", 
'E158:')
  
    call DeletePropTypes()
+   call prop_type_delete('included')
    bwipe!
  endfunc
  
*** ../vim-8.2.0323/src/version.c       2020-02-26 21:24:19.157582116 +0100
--- src/version.c       2020-02-26 21:33:38.852232085 +0100
***************
*** 740,741 ****
--- 740,743 ----
  {   /* Add new patch number below this line */
+ /**/
+     324,
  /**/

-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

 /// 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/202002262106.01QL6gYb009858%40masaka.moolenaar.net.

Raspunde prin e-mail lui