blob: 3dc6bb3c884f7f3ff70a2fd872021cc464692b3b [file] [log] [blame]
Bram Moolenaar4d585022016-04-14 19:50:22 +02001" Test for matchadd() and conceal feature
Bram Moolenaarb0f94c12019-06-13 22:19:53 +02002
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
4CheckFeature conceal
Bram Moolenaar4d585022016-04-14 19:50:22 +02005
6if !has('gui_running') && has('unix')
7 set term=ansi
8endif
9
Bram Moolenaar5f73ef82018-02-27 21:09:30 +010010source shared.vim
Bram Moolenaarcbee6352019-11-12 20:49:15 +010011source term_util.vim
12source view_util.vim
Bram Moolenaar4d585022016-04-14 19:50:22 +020013
Bram Moolenaar1e115362019-01-09 23:01:02 +010014func Test_simple_matchadd()
Bram Moolenaar4d585022016-04-14 19:50:22 +020015 new
16
17 1put='# This is a Test'
18 " 1234567890123456
19 let expect = '# This is a Test'
20
21 call cursor(1, 1)
22 call matchadd('Conceal', '\%2l ')
23 redraw!
24 let lnum = 2
Bram Moolenaar5f73ef82018-02-27 21:09:30 +010025 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +020026 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
27 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
28 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
29 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
30 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
31 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
32
33 quit!
Bram Moolenaar1e115362019-01-09 23:01:02 +010034endfunc
Bram Moolenaar4d585022016-04-14 19:50:22 +020035
Bram Moolenaar1e115362019-01-09 23:01:02 +010036func Test_simple_matchadd_and_conceal()
Bram Moolenaar4d585022016-04-14 19:50:22 +020037 new
38 setlocal concealcursor=n conceallevel=1
39
40 1put='# This is a Test'
41 " 1234567890123456
42 let expect = '#XThisXisXaXTest'
43
44 call cursor(1, 1)
45 call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
46 redraw!
47 let lnum = 2
Bram Moolenaar5f73ef82018-02-27 21:09:30 +010048 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +020049 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
50 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
51 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
52 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
53 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
54
55 quit!
Bram Moolenaar1e115362019-01-09 23:01:02 +010056endfunc
Bram Moolenaar4d585022016-04-14 19:50:22 +020057
Bram Moolenaar1e115362019-01-09 23:01:02 +010058func Test_matchadd_and_conceallevel_3()
Bram Moolenaar4d585022016-04-14 19:50:22 +020059 new
60
61 setlocal conceallevel=3
62 " set filetype and :syntax on to change screenattr()
63 setlocal filetype=conf
64 syntax on
65
Bram Moolenaar211dd3f2020-06-25 20:07:04 +020066 1put='# This is a Test $'
67 " 1234567890123
68 let expect = '#ThisisaTest$'
Bram Moolenaar4d585022016-04-14 19:50:22 +020069
70 call cursor(1, 1)
71 call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
72 redraw!
73 let lnum = 2
Bram Moolenaar5f73ef82018-02-27 21:09:30 +010074 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +020075 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2))
Bram Moolenaar211dd3f2020-06-25 20:07:04 +020076 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 7))
77 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 10))
78 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 12))
79 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 13))
80 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 14))
Bram Moolenaar4d585022016-04-14 19:50:22 +020081 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 16))
82
83 " more matchadd()
Bram Moolenaar211dd3f2020-06-25 20:07:04 +020084 " 12345678901234
85 let expect = '#Thisisa Test$'
Bram Moolenaar4d585022016-04-14 19:50:22 +020086
87 call matchadd('ErrorMsg', '\%2l Test', 20, -1, {'conceal': 'X'})
88 redraw!
Bram Moolenaar5f73ef82018-02-27 21:09:30 +010089 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +020090 call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 2))
Bram Moolenaar211dd3f2020-06-25 20:07:04 +020091 call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 7))
Bram Moolenaar4d585022016-04-14 19:50:22 +020092 call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 10))
Bram Moolenaar211dd3f2020-06-25 20:07:04 +020093 call assert_equal(screenattr(lnum, 10), screenattr(lnum, 13))
94 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 14))
Bram Moolenaar4d585022016-04-14 19:50:22 +020095 call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 16))
96 call assert_notequal(screenattr(lnum, 10), screenattr(lnum, 16))
97
98 syntax off
99 quit!
Bram Moolenaar1e115362019-01-09 23:01:02 +0100100endfunc
Bram Moolenaar4d585022016-04-14 19:50:22 +0200101
Bram Moolenaar1e115362019-01-09 23:01:02 +0100102func Test_default_conceal_char()
Bram Moolenaar4d585022016-04-14 19:50:22 +0200103 new
104 setlocal concealcursor=n conceallevel=1
105
106 1put='# This is a Test'
107 " 1234567890123456
108 let expect = '# This is a Test'
109
110 call cursor(1, 1)
111 call matchadd('Conceal', '\%2l ', 10, -1, {})
112 redraw!
113 let lnum = 2
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100114 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200115 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
116 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
117 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
118 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
119 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
120
121 " 1234567890123456
122 let expect = '#+This+is+a+Test'
123 let listchars_save = &listchars
124 set listchars=conceal:+
125 redraw!
126
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100127 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200128 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
129 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
130 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
131 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
132 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
133
134 let &listchars = listchars_save
135 quit!
Bram Moolenaar1e115362019-01-09 23:01:02 +0100136endfunc
Bram Moolenaar4d585022016-04-14 19:50:22 +0200137
Bram Moolenaar1e115362019-01-09 23:01:02 +0100138func Test_syn_and_match_conceal()
Bram Moolenaar4d585022016-04-14 19:50:22 +0200139 new
140 setlocal concealcursor=n conceallevel=1
141
Bram Moolenaar211dd3f2020-06-25 20:07:04 +0200142 1put='# This is a Test '
Bram Moolenaar4d585022016-04-14 19:50:22 +0200143
Bram Moolenaar4d585022016-04-14 19:50:22 +0200144 let lnum = 2
Bram Moolenaar211dd3f2020-06-25 20:07:04 +0200145 call cursor(1, 1)
146
147 " 123456789012345678
148 let expect = '#ZThisZisZaZTestZZ'
149 call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
150 syntax match MyConceal /\%2l / conceal containedin=ALL
151 hi MyConceal ctermbg=4 ctermfg=2
152 redraw!
153
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100154 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200155 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
156 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
157 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
158 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
159 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
160
Bram Moolenaar211dd3f2020-06-25 20:07:04 +0200161 syntax clear MyConceal
162 syntax match MyConceal /\%2l / conceal containedin=ALL cchar=*
163 redraw!
164
165 call assert_equal(expect, Screenline(lnum))
166 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
167 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
168 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
169 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
170 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
171
172 " 123456789012345678
173 let expect = '#*This*is*a*Test**'
Bram Moolenaar4d585022016-04-14 19:50:22 +0200174 call clearmatches()
175 redraw!
176
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100177 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200178 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
179 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
180 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
181 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
182 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
183
Bram Moolenaar211dd3f2020-06-25 20:07:04 +0200184 " 123456789012345678
185 let expect = '#*ThisXis*a*Test**'
186 call matchadd('Conceal', '\%2l\%7c ', 10, -1, {'conceal': 'X'})
187 redraw!
188
189 call assert_equal(expect, Screenline(lnum))
190 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
191 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
192 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
193 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
194 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
195
196 " 123456789012345678
197 let expect = '#*ThisXis*a*Test**'
198 call matchadd('ErrorMsg', '\%2l Test', 20, -1)
199 redraw!
200
201 call assert_equal(expect, Screenline(lnum))
202 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
203 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
204 call assert_notequal(screenattr(lnum, 12), screenattr(lnum, 13))
205 call assert_equal(screenattr(lnum, 13), screenattr(lnum, 16))
206 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 17))
207 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 18))
208 call assert_notequal(screenattr(lnum, 18), screenattr(lnum, 19))
209
210 " 123456789012345678
211 let expect = '# ThisXis a Test'
212 syntax clear MyConceal
213 syntax match MyConceal /\%2l / conceal containedin=ALL
214 redraw!
215
216 call assert_equal(expect, Screenline(lnum))
217 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
218 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
219 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 12))
220 call assert_notequal(screenattr(lnum, 12), screenattr(lnum, 13))
221 call assert_equal(screenattr(lnum, 13), screenattr(lnum, 16))
222 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 17))
223 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 18))
224 call assert_notequal(screenattr(lnum, 18), screenattr(lnum, 19))
225
Bram Moolenaar4d585022016-04-14 19:50:22 +0200226 syntax off
227 quit!
Bram Moolenaar1e115362019-01-09 23:01:02 +0100228endfunc
Bram Moolenaar4d585022016-04-14 19:50:22 +0200229
Bram Moolenaar1e115362019-01-09 23:01:02 +0100230func Test_clearmatches()
Bram Moolenaar4d585022016-04-14 19:50:22 +0200231 new
232 setlocal concealcursor=n conceallevel=1
233
234 1put='# This is a Test'
235 " 1234567890123456
236 let expect = '# This is a Test'
237
238 call cursor(1, 1)
239 call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
240 let a = getmatches()
241 call clearmatches()
242 redraw!
243
244 let lnum = 2
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100245 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200246 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2))
247 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
248 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
249 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
250 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
251
252 " reset match using setmatches()
253 " 1234567890123456
254 let expect = '#ZThisZisZaZTest'
255 call setmatches(a)
256 redraw!
257
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100258 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200259 call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
260 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
261 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
262 call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
263 call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
264 call assert_equal({'group': 'Conceal', 'pattern': '\%2l ', 'priority': 10, 'id': a[0].id, 'conceal': 'Z'}, a[0])
265
266 quit!
Bram Moolenaar1e115362019-01-09 23:01:02 +0100267endfunc
Bram Moolenaar4d585022016-04-14 19:50:22 +0200268
Bram Moolenaar1e115362019-01-09 23:01:02 +0100269func Test_using_matchaddpos()
Bram Moolenaar4d585022016-04-14 19:50:22 +0200270 new
271 setlocal concealcursor=n conceallevel=1
272 " set filetype and :syntax on to change screenattr()
273 setlocal filetype=conf
274 syntax on
275
276 1put='# This is a Test'
277 " 1234567890123456
278 let expect = '#Pis a Test'
279
280 call cursor(1, 1)
281 call matchaddpos('Conceal', [[2,2,6]], 10, -1, {'conceal': 'P'})
282 let a = getmatches()
283 redraw!
284
285 let lnum = 2
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100286 call assert_equal(expect, Screenline(lnum))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200287 call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 2))
288 call assert_notequal(screenattr(lnum, 2) , screenattr(lnum, 7))
289 call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 7))
290 call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 10))
291 call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 12))
292 call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 16))
293 call assert_equal(screenattr(lnum, 12), screenattr(lnum, 16))
294 call assert_equal({'group': 'Conceal', 'id': a[0].id, 'priority': 10, 'pos1': [2, 2, 6], 'conceal': 'P'}, a[0])
295
296 syntax off
297 quit!
Bram Moolenaar1e115362019-01-09 23:01:02 +0100298endfunc
Bram Moolenaar4d585022016-04-14 19:50:22 +0200299
Bram Moolenaar1e115362019-01-09 23:01:02 +0100300func Test_matchadd_repeat_conceal_with_syntax_off()
Bram Moolenaar4d585022016-04-14 19:50:22 +0200301 new
302
303 " To test targets in the same line string is replaced with conceal char
304 " correctly, repeat 'TARGET'
305 1put ='TARGET_TARGETTARGET'
306 call cursor(1, 1)
307 redraw
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100308 call assert_equal('TARGET_TARGETTARGET', Screenline(2))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200309
310 setlocal conceallevel=2
311 call matchadd('Conceal', 'TARGET', 10, -1, {'conceal': 't'})
312
313 redraw
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100314 call assert_equal('t_tt', Screenline(2))
Bram Moolenaar4d585022016-04-14 19:50:22 +0200315
316 quit!
Bram Moolenaar1e115362019-01-09 23:01:02 +0100317endfunc
Bram Moolenaar2f979122016-10-27 17:27:44 +0200318
Bram Moolenaar1e115362019-01-09 23:01:02 +0100319func Test_matchadd_and_syn_conceal()
Bram Moolenaar2f979122016-10-27 17:27:44 +0200320 new
321 let cnt='Inductive bool : Type := | true : bool | false : bool.'
322 let expect = 'Inductive - : Type := | true : - | false : -.'
323 0put =cnt
324 " set filetype and :syntax on to change screenattr()
325 set cole=1 cocu=nv
326 hi link CheckedByCoq WarningMsg
327 syntax on
328 syntax keyword coqKwd bool conceal cchar=-
329 redraw!
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100330 call assert_equal(expect, Screenline(1))
Bram Moolenaar2f979122016-10-27 17:27:44 +0200331 call assert_notequal(screenattr(1, 10) , screenattr(1, 11))
332 call assert_notequal(screenattr(1, 11) , screenattr(1, 12))
333 call assert_equal(screenattr(1, 11) , screenattr(1, 32))
334 call matchadd('CheckedByCoq', '\%<2l\%>9c\%<16c')
Bram Moolenaar35a1f592016-10-28 22:10:27 +0200335 redraw!
Bram Moolenaar5f73ef82018-02-27 21:09:30 +0100336 call assert_equal(expect, Screenline(1))
Bram Moolenaar2f979122016-10-27 17:27:44 +0200337 call assert_notequal(screenattr(1, 10) , screenattr(1, 11))
338 call assert_notequal(screenattr(1, 11) , screenattr(1, 12))
339 call assert_equal(screenattr(1, 11) , screenattr(1, 32))
Bram Moolenaar1e115362019-01-09 23:01:02 +0100340endfunc
Bram Moolenaarcbee6352019-11-12 20:49:15 +0100341
342func Test_cursor_column_in_concealed_line_after_window_scroll()
343 CheckRunVimInTerminal
344
345 " Test for issue #5012 fix.
346 " For a concealed line with cursor, there should be no window's cursor
347 " position invalidation during win_update() after scrolling attempt that is
348 " not successful and no real topline change happens. The invalidation would
349 " cause a window's cursor position recalc outside of win_line() where it's
350 " not possible to take conceal into account.
351 let lines =<< trim END
352 3split
353 let m = matchadd('Conceal', '=')
354 setl conceallevel=2 concealcursor=nc
355 normal gg
356 "==expr==
357 END
358 call writefile(lines, 'Xcolesearch')
359 let buf = RunVimInTerminal('Xcolesearch', {})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200360 call TermWait(buf, 50)
Bram Moolenaarcbee6352019-11-12 20:49:15 +0100361
362 " Jump to something that is beyond the bottom of the window,
363 " so there's a scroll down.
364 call term_sendkeys(buf, ":so %\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200365 call TermWait(buf, 50)
Bram Moolenaarcbee6352019-11-12 20:49:15 +0100366 call term_sendkeys(buf, "/expr\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200367 call TermWait(buf, 50)
Bram Moolenaarcbee6352019-11-12 20:49:15 +0100368
369 " Are the concealed parts of the current line really hidden?
370 let cursor_row = term_scrape(buf, '.')->map({_, e -> e.chars})->join('')
371 call assert_equal('"expr', cursor_row)
372
373 " BugFix check: Is the window's cursor column properly updated for hidden
374 " parts of the current line?
375 call assert_equal(2, term_getcursor(buf)[1])
376
377 call StopVimInTerminal(buf)
378 call delete('Xcolesearch')
379endfunc
Bram Moolenaar08f23632019-11-16 14:19:33 +0100380
381func Test_cursor_column_in_concealed_line_after_leftcol_change()
382 CheckRunVimInTerminal
383
384 " Test for issue #5214 fix.
385 let lines =<< trim END
386 0put = 'ab' .. repeat('-', &columns) .. 'c'
387 call matchadd('Conceal', '-')
388 set nowrap ss=0 cole=3 cocu=n
389 END
390 call writefile(lines, 'Xcurs-columns')
391 let buf = RunVimInTerminal('-S Xcurs-columns', {})
392
393 " Go to the end of the line (3 columns beyond the end of the screen).
394 " Horizontal scroll would center the cursor in the screen line, but conceal
395 " makes it go to screen column 1.
396 call term_sendkeys(buf, "$")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200397 call TermWait(buf)
Bram Moolenaar08f23632019-11-16 14:19:33 +0100398
399 " Are the concealed parts of the current line really hidden?
Bram Moolenaar1f9a0282019-12-07 17:22:04 +0100400 call WaitForAssert({-> assert_equal('c', term_getline(buf, '.'))})
Bram Moolenaar08f23632019-11-16 14:19:33 +0100401
402 " BugFix check: Is the window's cursor column properly updated for conceal?
403 call assert_equal(1, term_getcursor(buf)[1])
404
405 call StopVimInTerminal(buf)
406 call delete('Xcurs-columns')
407endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200408
409" vim: shiftwidth=2 sts=2 expandtab