summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.1333
blob: c279b72c56d180a50f344c0c2197d1b56c51a245 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
To: vim_dev@googlegroups.com
Subject: Patch 8.1.1333
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 8.1.1333
Problem:    Text properties don't always move after changes.
Solution:   Update properties before reporting changes to listeners. Move text
            property when splitting a line.
Files:	    src/change.c, src/ex_cmds.c, src/textprop.c,
            src/proto/textprop.pro, src/testdir/test_textprop.vim


*** ../vim-8.1.1332/src/change.c	2019-05-14 21:20:32.597441034 +0200
--- src/change.c	2019-05-15 22:14:42.293974215 +0200
***************
*** 641,652 ****
      void
  inserted_bytes(linenr_T lnum, colnr_T col, int added UNUSED)
  {
-     changed_bytes(lnum, col);
- 
  #ifdef FEAT_TEXT_PROP
      if (curbuf->b_has_textprop && added != 0)
  	adjust_prop_columns(lnum, col, added);
  #endif
  }
  
  /*
--- 641,652 ----
      void
  inserted_bytes(linenr_T lnum, colnr_T col, int added UNUSED)
  {
  #ifdef FEAT_TEXT_PROP
      if (curbuf->b_has_textprop && added != 0)
  	adjust_prop_columns(lnum, col, added);
  #endif
+ 
+     changed_bytes(lnum, col);
  }
  
  /*
***************
*** 2133,2138 ****
--- 2133,2144 ----
  	    )
  	    mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
  	did_append = TRUE;
+ #ifdef FEAT_TEXT_PROP
+ 	if ((State & INSERT) && !(State & VREPLACE_FLAG))
+ 	    // properties after the split move to the next line
+ 	    adjust_props_for_split(curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ 						  curwin->w_cursor.col + 1, 0);
+ #endif
      }
      else
      {
*** ../vim-8.1.1332/src/ex_cmds.c	2019-05-09 15:12:45.168723969 +0200
--- src/ex_cmds.c	2019-05-15 22:02:51.794417449 +0200
***************
*** 5728,5734 ****
  				last_line = lnum + 1;
  			    }
  #ifdef FEAT_TEXT_PROP
! 			    adjust_props_for_split(lnum, plen, 1);
  #endif
  			    // all line numbers increase
  			    ++sub_firstlnum;
--- 5728,5734 ----
  				last_line = lnum + 1;
  			    }
  #ifdef FEAT_TEXT_PROP
! 			    adjust_props_for_split(lnum + 1, lnum, plen, 1);
  #endif
  			    // all line numbers increase
  			    ++sub_firstlnum;
*** ../vim-8.1.1332/src/textprop.c	2019-05-05 16:33:44.490168111 +0200
--- src/textprop.c	2019-05-15 22:42:36.048949732 +0200
***************
*** 8,25 ****
   */
  
  /*
!  * Text properties implementation.
!  *
!  * Text properties are attached to the text.  They move with the text when
!  * text is inserted/deleted.
!  *
!  * Text properties have a user specified ID number, which can be unique.
!  * Text properties have a type, which can be used to specify highlighting.
   *
   * TODO:
   * - When using 'cursorline' attributes should be merged. (#3912)
   * - Adjust text property column and length when text is inserted/deleted.
   *   -> a :substitute with a multi-line match
   *   -> search for changed_bytes() from misc1.c
   * - Perhaps we only need TP_FLAG_CONT_NEXT and can drop TP_FLAG_CONT_PREV?
   * - Add an arrray for global_proptypes, to quickly lookup a prop type by ID
--- 8,22 ----
   */
  
  /*
!  * Text properties implementation.  See ":help text-properties".
   *
   * TODO:
   * - When using 'cursorline' attributes should be merged. (#3912)
   * - Adjust text property column and length when text is inserted/deleted.
+  *   -> splitting a line can create a zero-length property.  Don't highlight it
+  *      and extend it when inserting text.
   *   -> a :substitute with a multi-line match
+  *   -> join two lines, also with BS in Insert mode
   *   -> search for changed_bytes() from misc1.c
   * - Perhaps we only need TP_FLAG_CONT_NEXT and can drop TP_FLAG_CONT_PREV?
   * - Add an arrray for global_proptypes, to quickly lookup a prop type by ID
***************
*** 28,35 ****
   *   the index, like DB_MARKED?
   * - Also test line2byte() with many lines, so that ml_updatechunk() is taken
   *   into account.
-  * - Add mechanism to keep track of changed lines, so that plugin can update
-  *   text properties in these.
   * - Perhaps have a window-local option to disable highlighting from text
   *   properties?
   */
--- 25,30 ----
***************
*** 1033,1044 ****
  
  /*
   * Adjust text properties for a line that was split in two.
!  * "lnum" is the newly inserted line.  The text properties are now on the line
!  * below it.  "kept" is the number of bytes kept in the first line, while
   * "deleted" is the number of bytes deleted.
   */
      void
! adjust_props_for_split(linenr_T lnum, int kept, int deleted)
  {
      char_u	*props;
      int		count;
--- 1028,1044 ----
  
  /*
   * Adjust text properties for a line that was split in two.
!  * "lnum_props" is the line that has the properties from before the split.
!  * "lnum_top" is the top line.
!  * "kept" is the number of bytes kept in the first line, while
   * "deleted" is the number of bytes deleted.
   */
      void
! adjust_props_for_split(
! 	linenr_T lnum_props,
! 	linenr_T lnum_top,
! 	int kept,
! 	int deleted)
  {
      char_u	*props;
      int		count;
***************
*** 1049,1059 ****
  
      if (!curbuf->b_has_textprop)
  	return;
!     count = get_text_props(curbuf, lnum + 1, &props, FALSE);
      ga_init2(&prevprop, sizeof(textprop_T), 10);
      ga_init2(&nextprop, sizeof(textprop_T), 10);
  
-     // Get the text properties, which are at "lnum + 1".
      // Keep the relevant ones in the first line, reducing the length if needed.
      // Copy the ones that include the split to the second line.
      // Move the ones after the split to the second line.
--- 1049,1060 ----
  
      if (!curbuf->b_has_textprop)
  	return;
! 
!     // Get the text properties from "lnum_props".
!     count = get_text_props(curbuf, lnum_props, &props, FALSE);
      ga_init2(&prevprop, sizeof(textprop_T), 10);
      ga_init2(&nextprop, sizeof(textprop_T), 10);
  
      // Keep the relevant ones in the first line, reducing the length if needed.
      // Copy the ones that include the split to the second line.
      // Move the ones after the split to the second line.
***************
*** 1089,1098 ****
  	}
      }
  
!     set_text_props(lnum, prevprop.ga_data, prevprop.ga_len * sizeof(textprop_T));
      ga_clear(&prevprop);
! 
!     set_text_props(lnum + 1, nextprop.ga_data, nextprop.ga_len * sizeof(textprop_T));
      ga_clear(&nextprop);
  }
  
--- 1090,1100 ----
  	}
      }
  
!     set_text_props(lnum_top, prevprop.ga_data,
! 					 prevprop.ga_len * sizeof(textprop_T));
      ga_clear(&prevprop);
!     set_text_props(lnum_top + 1, nextprop.ga_data,
! 					 nextprop.ga_len * sizeof(textprop_T));
      ga_clear(&nextprop);
  }
  
*** ../vim-8.1.1332/src/proto/textprop.pro	2019-01-04 23:09:45.249360567 +0100
--- src/proto/textprop.pro	2019-05-15 22:05:41.925276920 +0200
***************
*** 14,18 ****
  void clear_global_prop_types(void);
  void clear_buf_prop_types(buf_T *buf);
  void adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added);
! void adjust_props_for_split(linenr_T lnum, int kept, int deleted);
  /* vim: set ft=c : */
--- 14,18 ----
  void clear_global_prop_types(void);
  void clear_buf_prop_types(buf_T *buf);
  void adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added);
! void adjust_props_for_split(linenr_T lnum_props, linenr_T lnum_top, int kept, int deleted);
  /* vim: set ft=c : */
*** ../vim-8.1.1332/src/testdir/test_textprop.vim	2019-05-05 15:47:37.825923529 +0200
--- src/testdir/test_textprop.vim	2019-05-15 22:41:42.505209936 +0200
***************
*** 151,156 ****
--- 151,157 ----
  
  func SetupOneLine()
    call setline(1, 'xonex xtwoxx')
+   normal gg0
    call AddPropTypes()
    call prop_add(1, 2, {'length': 3, 'id': 11, 'type': 'one'})
    call prop_add(1, 8, {'length': 3, 'id': 12, 'type': 'two'})
***************
*** 271,276 ****
--- 272,337 ----
    bwipe!
    set bs&
  endfunc
+ 
+ func Test_prop_open_line()
+   new
+ 
+   " open new line, props stay in top line
+   let expected = SetupOneLine() " 'xonex xtwoxx'
+   exe "normal o\<Esc>"
+   call assert_equal('xonex xtwoxx', getline(1))
+   call assert_equal('', getline(2))
+   call assert_equal(expected, prop_list(1))
+   call DeletePropTypes()
+ 
+   " move all props to next line
+   let expected = SetupOneLine() " 'xonex xtwoxx'
+   exe "normal 0i\<CR>\<Esc>"
+   call assert_equal('', getline(1))
+   call assert_equal('xonex xtwoxx', getline(2))
+   call assert_equal(expected, prop_list(2))
+   call DeletePropTypes()
+ 
+   " split just before prop, move all props to next line
+   let expected = SetupOneLine() " 'xonex xtwoxx'
+   exe "normal 0li\<CR>\<Esc>"
+   call assert_equal('x', getline(1))
+   call assert_equal('onex xtwoxx', getline(2))
+   let expected[0].col -= 1
+   let expected[1].col -= 1
+   call assert_equal(expected, prop_list(2))
+   call DeletePropTypes()
+ 
+   " split inside prop, split first prop
+   let expected = SetupOneLine() " 'xonex xtwoxx'
+   exe "normal 0lli\<CR>\<Esc>"
+   call assert_equal('xo', getline(1))
+   call assert_equal('nex xtwoxx', getline(2))
+   let exp_first = [deepcopy(expected[0])]
+   let exp_first[0].length = 1
+   call assert_equal(exp_first, prop_list(1))
+   let expected[0].col = 1
+   let expected[0].length = 2
+   let expected[1].col -= 2
+   call assert_equal(expected, prop_list(2))
+   call DeletePropTypes()
+ 
+   " split just after first prop, empty prop and second prop move to next line
+   let expected = SetupOneLine() " 'xonex xtwoxx'
+   exe "normal 0fea\<CR>\<Esc>"
+   call assert_equal('xone', getline(1))
+   call assert_equal('x xtwoxx', getline(2))
+   let exp_first = expected[0:0]
+   call assert_equal(exp_first, prop_list(1))
+   let expected[0].col = 1
+   let expected[0].length = 0
+   let expected[1].col -= 4
+   call assert_equal(expected, prop_list(2))
+   call DeletePropTypes()
+ 
+   bwipe!
+   set bs&
+ endfunc
  
  func Test_prop_clear()
    new
*** ../vim-8.1.1332/src/version.c	2019-05-14 21:20:32.597441034 +0200
--- src/version.c	2019-05-15 22:44:49.468290481 +0200
***************
*** 769,770 ****
--- 769,772 ----
  {   /* Add new patch number below this line */
+ /**/
+     1333,
  /**/

-- 
BLACK KNIGHT: I'm invincible!
ARTHUR:       You're a looney.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- Bram@Moolenaar.net -- 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    ///