blob: fd6b02d93a2f2e148a68ce9b0946ade5c30e8836 [file] [log] [blame]
Bram Moolenaarb40c2572019-10-19 21:01:05 +02001" Tests for the writefile() function and some :write commands.
Bram Moolenaar19a16692016-09-01 22:19:47 +02002
Bram Moolenaarea3db912020-02-02 15:32:13 +01003source check.vim
Bram Moolenaar494e9062020-05-31 21:28:02 +02004source term_util.vim
Bram Moolenaarea3db912020-02-02 15:32:13 +01005
Bram Moolenaar8cf91282017-06-13 19:38:37 +02006func Test_writefile()
Bram Moolenaar19a16692016-09-01 22:19:47 +02007 let f = tempname()
8 call writefile(["over","written"], f, "b")
9 call writefile(["hello","world"], f, "b")
10 call writefile(["!", "good"], f, "a")
11 call writefile(["morning"], f, "ab")
12 call writefile(["", "vimmers"], f, "ab")
13 let l = readfile(f)
14 call assert_equal("hello", l[0])
15 call assert_equal("world!", l[1])
16 call assert_equal("good", l[2])
17 call assert_equal("morning", l[3])
18 call assert_equal("vimmers", l[4])
19 call delete(f)
Bram Moolenaar18a2b872020-03-19 13:08:45 +010020
Bram Moolenaarb18b4962022-09-02 21:55:50 +010021 call assert_fails('call writefile("text", "Xwffile")', 'E475: Invalid argument: writefile() first argument must be a List or a Blob')
Bram Moolenaar8cf91282017-06-13 19:38:37 +020022endfunc
23
Bram Moolenaarb40c2572019-10-19 21:01:05 +020024func Test_writefile_ignore_regexp_error()
25 write Xt[z-a]est.txt
26 call delete('Xt[z-a]est.txt')
27endfunc
28
Bram Moolenaar8cf91282017-06-13 19:38:37 +020029func Test_writefile_fails_gently()
Bram Moolenaarb18b4962022-09-02 21:55:50 +010030 call assert_fails('call writefile(["test"], "Xwffile", [])', 'E730:')
31 call assert_false(filereadable("Xwffile"))
32 call delete("Xwffile")
Bram Moolenaar8cf91282017-06-13 19:38:37 +020033
Bram Moolenaarb18b4962022-09-02 21:55:50 +010034 call assert_fails('call writefile(["test", [], [], [], "tset"], "Xwffile")', 'E730:')
35 call assert_false(filereadable("Xwffile"))
36 call delete("Xwffile")
Bram Moolenaar8cf91282017-06-13 19:38:37 +020037
Bram Moolenaarb18b4962022-09-02 21:55:50 +010038 call assert_fails('call writefile([], "Xwffile", [])', 'E730:')
39 call assert_false(filereadable("Xwffile"))
40 call delete("Xwffile")
Bram Moolenaar8cf91282017-06-13 19:38:37 +020041
42 call assert_fails('call writefile([], [])', 'E730:')
43endfunc
Bram Moolenaare6bf6552017-06-27 22:11:51 +020044
45func Test_writefile_fails_conversion()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020046 CheckFeature iconv
47 if has('sun')
48 throw 'Skipped: does not work on SunOS'
Bram Moolenaare6bf6552017-06-27 22:11:51 +020049 endif
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020050 " Without a backup file the write won't happen if there is a conversion
51 " error.
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020052 set nobackup nowritebackup backupdir=. backupskip=
Bram Moolenaare6bf6552017-06-27 22:11:51 +020053 new
54 let contents = ["line one", "line two"]
Bram Moolenaarb18b4962022-09-02 21:55:50 +010055 call writefile(contents, 'Xwfcfile')
56 edit Xwfcfile
Bram Moolenaare6bf6552017-06-27 22:11:51 +020057 call setline(1, ["first line", "cannot convert \u010b", "third line"])
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020058 call assert_fails('write ++enc=cp932', 'E513:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010059 call assert_equal(contents, readfile('Xwfcfile'))
Bram Moolenaare6bf6552017-06-27 22:11:51 +020060
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020061 " With 'backupcopy' set, if there is a conversion error, the backup file is
62 " still created.
63 set backupcopy=yes writebackup& backup&
Bram Moolenaarb18b4962022-09-02 21:55:50 +010064 call delete('Xwfcfile' .. &backupext)
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020065 call assert_fails('write ++enc=cp932', 'E513:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010066 call assert_equal(contents, readfile('Xwfcfile'))
67 call assert_equal(contents, readfile('Xwfcfile' .. &backupext))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020068 set backupcopy&
69 %bw!
70
71 " Conversion error during write
72 new
73 call setline(1, ["\U10000000"])
Bram Moolenaarb18b4962022-09-02 21:55:50 +010074 let output = execute('write! ++enc=utf-16 Xwfcfile')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020075 call assert_match('CONVERSION ERROR', output)
Bram Moolenaarb18b4962022-09-02 21:55:50 +010076 let output = execute('write! ++enc=ucs-2 Xwfcfile')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020077 call assert_match('CONVERSION ERROR', output)
Dominique Pelleb40ad4f2022-09-04 21:29:46 +010078 call delete('Xwfcfilz~')
79 call delete('Xwfcfily~')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020080 %bw!
81
Bram Moolenaarb18b4962022-09-02 21:55:50 +010082 call delete('Xwfcfile')
83 call delete('Xwfcfile' .. &backupext)
Bram Moolenaare6bf6552017-06-27 22:11:51 +020084 bwipe!
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020085 set backup& writebackup& backupdir&vim backupskip&vim
Bram Moolenaare6bf6552017-06-27 22:11:51 +020086endfunc
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +020087
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020088func Test_writefile_fails_conversion2()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020089 CheckFeature iconv
90 if has('sun')
91 throw 'Skipped: does not work on SunOS'
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020092 endif
93 " With a backup file the write happens even if there is a conversion error,
94 " but then the backup file must remain
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020095 set nobackup writebackup backupdir=. backupskip=
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020096 let contents = ["line one", "line two"]
Bram Moolenaarb18b4962022-09-02 21:55:50 +010097 call writefile(contents, 'Xwf2file_conversion_err')
98 edit Xwf2file_conversion_err
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020099 call setline(1, ["first line", "cannot convert \u010b", "third line"])
100 set fileencoding=latin1
101 let output = execute('write')
102 call assert_match('CONVERSION ERROR', output)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100103 call assert_equal(contents, readfile('Xwf2file_conversion_err~'))
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +0200104
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100105 call delete('Xwf2file_conversion_err')
106 call delete('Xwf2file_conversion_err~')
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +0200107 bwipe!
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +0200108 set backup& writebackup& backupdir&vim backupskip&vim
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +0200109endfunc
110
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200111func SetFlag(timer)
112 let g:flag = 1
113endfunc
114
115func Test_write_quit_split()
116 " Prevent exiting by splitting window on file write.
117 augroup testgroup
118 autocmd BufWritePre * split
119 augroup END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100120 e! Xwqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200121 call setline(1, 'nothing')
122 wq
123
124 if has('timers')
125 " timer will not run if "exiting" is still set
126 let g:flag = 0
127 call timer_start(1, 'SetFlag')
128 sleep 50m
129 call assert_equal(1, g:flag)
130 unlet g:flag
131 endif
132 au! testgroup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100133 bwipe Xwqsfile
134 call delete('Xwqsfile')
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200135endfunc
136
137func Test_nowrite_quit_split()
138 " Prevent exiting by opening a help window.
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100139 e! Xnqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200140 help
141 wincmd w
142 exe winnr() . 'q'
143
144 if has('timers')
145 " timer will not run if "exiting" is still set
146 let g:flag = 0
147 call timer_start(1, 'SetFlag')
148 sleep 50m
149 call assert_equal(1, g:flag)
150 unlet g:flag
151 endif
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100152 bwipe Xnqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200153endfunc
Bram Moolenaar7567d0b2017-11-16 23:04:15 +0100154
155func Test_writefile_sync_arg()
156 " This doesn't check if fsync() works, only that the argument is accepted.
157 call writefile(['one'], 'Xtest', 's')
158 call writefile(['two'], 'Xtest', 'S')
159 call delete('Xtest')
160endfunc
Bram Moolenaar83799a72017-11-25 17:24:09 +0100161
162func Test_writefile_sync_dev_stdout()
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200163 CheckUnix
Bram Moolenaar9980b372018-04-21 20:12:35 +0200164 if filewritable('/dev/stdout')
165 " Just check that this doesn't cause an error.
166 call writefile(['one'], '/dev/stdout')
167 else
168 throw 'Skipped: /dev/stdout is not writable'
169 endif
Bram Moolenaar83799a72017-11-25 17:24:09 +0100170endfunc
Bram Moolenaar8c9e7b02018-08-30 13:07:17 +0200171
172func Test_writefile_autowrite()
173 set autowrite
174 new
175 next Xa Xb Xc
176 call setline(1, 'aaa')
177 next
178 call assert_equal(['aaa'], readfile('Xa'))
179 call setline(1, 'bbb')
180 call assert_fails('edit XX')
181 call assert_false(filereadable('Xb'))
182
183 set autowriteall
184 edit XX
185 call assert_equal(['bbb'], readfile('Xb'))
186
187 bwipe!
188 call delete('Xa')
189 call delete('Xb')
190 set noautowrite
191endfunc
192
193func Test_writefile_autowrite_nowrite()
194 set autowrite
195 new
196 next Xa Xb Xc
197 set buftype=nowrite
198 call setline(1, 'aaa')
199 let buf = bufnr('%')
200 " buffer contents silently lost
201 edit XX
202 call assert_false(filereadable('Xa'))
203 rewind
204 call assert_equal('', getline(1))
205
206 bwipe!
207 set noautowrite
208endfunc
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100209
210" Test for ':w !<cmd>' to pipe lines from the current buffer to an external
211" command.
212func Test_write_pipe_to_cmd()
Bram Moolenaarea3db912020-02-02 15:32:13 +0100213 CheckUnix
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100214 new
215 call setline(1, ['L1', 'L2', 'L3', 'L4'])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100216 2,3w !cat > Xptfile
217 call assert_equal(['L2', 'L3'], readfile('Xptfile'))
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100218 close!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100219 call delete('Xptfile')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100220endfunc
221
222" Test for :saveas
223func Test_saveas()
224 call assert_fails('saveas', 'E471:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100225 call writefile(['L1'], 'Xsafile')
226 new Xsafile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100227 new
228 call setline(1, ['L1'])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100229 call assert_fails('saveas Xsafile', 'E139:')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100230 close!
231 enew | only
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100232 call delete('Xsafile')
Dominique Pellebd9e7962021-08-09 21:04:44 +0200233
234 " :saveas should detect and set the file type.
235 syntax on
236 saveas! Xsaveas.pl
237 call assert_equal('perl', &filetype)
238 syntax off
239 %bw!
240 call delete('Xsaveas.pl')
Bram Moolenaar500a1f92022-09-20 11:49:10 +0100241
242 " :saveas fails for "nofile" buffer
243 set buftype=nofile
244 call assert_fails('saveas Xsafile', 'E676: No matching autocommands for buftype=nofile buffer')
245
246 bwipe!
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100247endfunc
248
249func Test_write_errors()
250 " Test for writing partial buffer
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100251 call writefile(['L1', 'L2', 'L3'], 'Xwefile')
252 new Xwefile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100253 call assert_fails('1,2write', 'E140:')
254 close!
255
Bram Moolenaar4f5776c2020-02-12 22:15:19 +0100256 call assert_fails('w > Xtest', 'E494:')
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +0100257
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100258 " Try to overwrite a directory
259 if has('unix')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100260 call mkdir('Xwerdir1')
261 call assert_fails('write Xwerdir1', 'E17:')
262 call delete('Xwerdir1', 'd')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100263 endif
264
265 " Test for :wall for a buffer with no name
266 enew | only
267 call setline(1, ['L1'])
268 call assert_fails('wall', 'E141:')
269 enew!
270
271 " Test for writing a 'readonly' file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100272 new Xwefile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100273 set readonly
274 call assert_fails('write', 'E45:')
275 close
276
277 " Test for writing to a read-only file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100278 new Xwefile
279 call setfperm('Xwefile', 'r--r--r--')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100280 call assert_fails('write', 'E505:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100281 call setfperm('Xwefile', 'rw-rw-rw-')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100282 close
283
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100284 call delete('Xwefile')
Bram Moolenaar99fa7212020-04-26 15:59:55 +0200285
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100286 call writefile(test_null_list(), 'Xwefile')
287 call assert_false(filereadable('Xwefile'))
288 call writefile(test_null_blob(), 'Xwefile')
289 call assert_false(filereadable('Xwefile'))
Bram Moolenaar99fa7212020-04-26 15:59:55 +0200290 call assert_fails('call writefile([], "")', 'E482:')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200291
292 " very long file name
293 let long_fname = repeat('n', 5000)
294 call assert_fails('exe "w " .. long_fname', 'E75:')
295 call assert_fails('call writefile([], long_fname)', 'E482:')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200296
297 " Test for writing to a block device on Unix-like systems
298 if has('unix') && getfperm('/dev/loop0') != ''
299 \ && getftype('/dev/loop0') == 'bdev' && !IsRoot()
300 new
301 edit /dev/loop0
Bram Moolenaar50157ef2021-05-15 23:21:05 +0200302 call assert_fails('write', 'E503: ')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200303 call assert_fails('write!', 'E503: ')
304 close!
305 endif
Bram Moolenaar494e9062020-05-31 21:28:02 +0200306endfunc
307
308" Test for writing to a file which is modified after Vim read it
309func Test_write_file_mtime()
310 CheckEnglish
311 CheckRunVimInTerminal
312
313 " First read the file into a buffer
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100314 call writefile(["Line1", "Line2"], 'Xwfmfile')
315 let old_ftime = getftime('Xwfmfile')
316 let buf = RunVimInTerminal('Xwfmfile', #{rows : 10})
Bram Moolenaar733d2592020-08-20 18:59:06 +0200317 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200318 call term_sendkeys(buf, ":set noswapfile\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200319 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200320
321 " Modify the file directly. Make sure the file modification time is
322 " different. Note that on Linux/Unix, the file is considered modified
323 " outside, only if the difference is 2 seconds or more
324 sleep 1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100325 call writefile(["Line3", "Line4"], 'Xwfmfile')
326 let new_ftime = getftime('Xwfmfile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200327 while new_ftime - old_ftime < 2
328 sleep 100m
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100329 call writefile(["Line3", "Line4"], 'Xwfmfile')
330 let new_ftime = getftime('Xwfmfile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200331 endwhile
332
333 " Try to overwrite the file and check for the prompt
334 call term_sendkeys(buf, ":w\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200335 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200336 call WaitForAssert({-> assert_equal("WARNING: The file has been changed since reading it!!!", term_getline(buf, 9))})
337 call assert_equal("Do you really want to write to it (y/n)?",
338 \ term_getline(buf, 10))
339 call term_sendkeys(buf, "n\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200340 call TermWait(buf)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100341 call assert_equal(new_ftime, getftime('Xwfmfile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200342 call term_sendkeys(buf, ":w\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200343 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200344 call term_sendkeys(buf, "y\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200345 call TermWait(buf)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100346 call WaitForAssert({-> assert_equal('Line2', readfile('Xwfmfile')[1])})
Bram Moolenaar494e9062020-05-31 21:28:02 +0200347
348 " clean up
349 call StopVimInTerminal(buf)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100350 call delete('Xwfmfile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200351endfunc
352
353" Test for an autocmd unloading a buffer during a write command
354func Test_write_autocmd_unloadbuf_lockmark()
355 augroup WriteTest
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100356 autocmd BufWritePre Xwaufile enew | write
Bram Moolenaar494e9062020-05-31 21:28:02 +0200357 augroup END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100358 e Xwaufile
Bram Moolenaare2e40752020-09-04 21:18:46 +0200359 call assert_fails('lockmarks write', ['E32:', 'E203:'])
Bram Moolenaar494e9062020-05-31 21:28:02 +0200360 augroup WriteTest
361 au!
362 augroup END
363 augroup! WriteTest
364endfunc
365
366" Test for writing a buffer with 'acwrite' but without autocmds
367func Test_write_acwrite_error()
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100368 new Xwaefile
Bram Moolenaar494e9062020-05-31 21:28:02 +0200369 call setline(1, ['line1', 'line2', 'line3'])
370 set buftype=acwrite
371 call assert_fails('write', 'E676:')
372 call assert_fails('1,2write!', 'E676:')
373 call assert_fails('w >>', 'E676:')
374 close!
375endfunc
376
377" Test for adding and removing lines from an autocmd when writing a buffer
378func Test_write_autocmd_add_remove_lines()
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100379 new Xwaafile
Bram Moolenaar494e9062020-05-31 21:28:02 +0200380 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
381
382 " Autocmd deleting lines from the file when writing a partial file
383 augroup WriteTest2
384 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100385 autocmd FileWritePre Xwaafile 1,2d
Bram Moolenaar494e9062020-05-31 21:28:02 +0200386 augroup END
387 call assert_fails('2,3w!', 'E204:')
388
389 " Autocmd adding lines to a file when writing a partial file
390 augroup WriteTest2
391 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100392 autocmd FileWritePre Xwaafile call append(0, ['xxx', 'yyy'])
Bram Moolenaar494e9062020-05-31 21:28:02 +0200393 augroup END
394 %d
395 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
396 1,2w!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100397 call assert_equal(['xxx', 'yyy', 'aaa', 'bbb'], readfile('Xwaafile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200398
399 " Autocmd deleting lines from the file when writing the whole file
400 augroup WriteTest2
401 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100402 autocmd BufWritePre Xwaafile 1,2d
Bram Moolenaar494e9062020-05-31 21:28:02 +0200403 augroup END
404 %d
405 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
406 w
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100407 call assert_equal(['ccc', 'ddd'], readfile('Xwaafile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200408
409 augroup WriteTest2
410 au!
411 augroup END
412 augroup! WriteTest2
413
414 close!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100415 call delete('Xwaafile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200416endfunc
417
418" Test for writing to a readonly file
419func Test_write_readonly()
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100420 call writefile([], 'Xwrofile')
421 call setfperm('Xwrofile', "r--------")
422 edit Xwrofile
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200423 set noreadonly backupskip=
Bram Moolenaar494e9062020-05-31 21:28:02 +0200424 call assert_fails('write', 'E505:')
425 let save_cpo = &cpo
426 set cpo+=W
427 call assert_fails('write!', 'E504:')
428 let &cpo = save_cpo
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200429 call setline(1, ['line1'])
430 write!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100431 call assert_equal(['line1'], readfile('Xwrofile'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200432
433 " Auto-saving a readonly file should fail with 'autowriteall'
434 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100435 e Xwrofile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200436 set noreadonly autowriteall
437 call setline(1, ['aaaa'])
438 call assert_fails('n', 'E505:')
439 set cpo+=W
440 call assert_fails('n', 'E504:')
441 set cpo-=W
442 set autowriteall&
443
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200444 set backupskip&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100445 call delete('Xwrofile')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200446 %bw!
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100447endfunc
448
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200449" Test for 'patchmode'
450func Test_patchmode()
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100451 call writefile(['one'], 'Xpafile')
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200452 set patchmode=.orig nobackup backupskip= writebackup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100453 new Xpafile
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200454 call setline(1, 'two')
455 " first write should create the .orig file
456 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100457 call assert_equal(['one'], readfile('Xpafile.orig'))
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200458 call setline(1, 'three')
459 " subsequent writes should not create/modify the .orig file
460 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100461 call assert_equal(['one'], readfile('Xpafile.orig'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200462
463 " use 'patchmode' with 'nobackup' and 'nowritebackup' to create an empty
464 " original file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100465 call delete('Xpafile')
466 call delete('Xpafile.orig')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200467 %bw!
468 set patchmode=.orig nobackup nowritebackup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100469 edit Xpafile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200470 call setline(1, ['xxx'])
471 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100472 call assert_equal(['xxx'], readfile('Xpafile'))
473 call assert_equal([], readfile('Xpafile.orig'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200474
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200475 set patchmode& backup& backupskip& writebackup&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100476 call delete('Xpafile')
477 call delete('Xpafile.orig')
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200478endfunc
479
480" Test for writing to a file in a readonly directory
Bram Moolenaarf9a65502021-03-05 20:47:44 +0100481" NOTE: if you run tests as root this will fail. Don't run tests as root!
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200482func Test_write_readonly_dir()
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200483 " On MS-Windows, modifying files in a read-only directory is allowed.
484 CheckUnix
Bram Moolenaar17709e22021-03-19 14:38:12 +0100485 " Root can do it too.
486 CheckNotRoot
487
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100488 call mkdir('Xrodir/')
489 call writefile(['one'], 'Xrodir/Xfile1')
490 call setfperm('Xrodir', 'r-xr--r--')
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200491 " try to create a new file in the directory
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100492 new Xrodir/Xfile2
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200493 call setline(1, 'two')
494 call assert_fails('write', 'E212:')
495 " try to create a backup file in the directory
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100496 edit! Xrodir/Xfile1
497 set backupdir=./Xrodir backupskip=
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200498 set patchmode=.orig
499 call assert_fails('write', 'E509:')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100500 call setfperm('Xrodir', 'rwxr--r--')
501 call delete('Xrodir', 'rf')
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200502 set backupdir& backupskip& patchmode&
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200503endfunc
504
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200505" Test for writing a file using invalid file encoding
506func Test_write_invalid_encoding()
507 new
508 call setline(1, 'abc')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100509 call assert_fails('write ++enc=axbyc Xiefile', 'E213:')
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200510 close!
511endfunc
512
Bram Moolenaar622b3562020-07-27 20:02:41 +0200513" Tests for reading and writing files with conversion for Win32.
514func Test_write_file_encoding()
515 CheckMSWindows
516 let save_encoding = &encoding
517 let save_fileencodings = &fileencodings
K.Takataf883d902021-05-30 18:04:19 +0200518 set encoding=latin1 fileencodings&
Bram Moolenaar622b3562020-07-27 20:02:41 +0200519 let text =<< trim END
520 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
521 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
522 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
523 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100524 call writefile(text, 'Xwfefile')
525 edit Xwfefile
Bram Moolenaar622b3562020-07-27 20:02:41 +0200526
527 " write tests:
528 " combine three values for 'encoding' with three values for 'fileencoding'
529 " also write files for read tests
530 call cursor(1, 1)
531 set encoding=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100532 .w! ++enc=utf-8 Xwfetest
533 .w ++enc=cp1251 >> Xwfetest
534 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200535 .w! ++enc=utf-8 Xutf8
536 let expected =<< trim END
537 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
538 1 utf-8 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
539 1 utf-8 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
540 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100541 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200542
543 call cursor(2, 1)
544 set encoding=cp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100545 .w! ++enc=utf-8 Xwfetest
546 .w ++enc=cp1251 >> Xwfetest
547 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200548 .w! ++enc=cp1251 Xcp1251
549 let expected =<< trim END
550 2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
551 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
552 2 cp1251 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
553 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100554 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200555
556 call cursor(3, 1)
557 set encoding=cp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100558 .w! ++enc=utf-8 Xwfetest
559 .w ++enc=cp1251 >> Xwfetest
560 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200561 .w! ++enc=cp866 Xcp866
562 let expected =<< trim END
563 3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
564 3 cp866 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
565 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
566 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100567 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200568
569 " read three 'fileencoding's with utf-8 'encoding'
570 set encoding=utf-8 fencs=utf-8,cp1251
571 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100572 .w! ++enc=utf-8 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200573 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100574 .w ++enc=utf-8 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200575 set fencs=utf-8,cp866
576 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100577 .w ++enc=utf-8 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200578 let expected =<< trim END
579 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
580 2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
581 3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
582 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100583 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200584
585 " read three 'fileencoding's with cp1251 'encoding'
586 set encoding=utf-8 fencs=utf-8,cp1251
587 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100588 .w! ++enc=cp1251 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200589 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100590 .w ++enc=cp1251 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200591 set fencs=utf-8,cp866
592 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100593 .w ++enc=cp1251 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200594 let expected =<< trim END
595 1 utf-8 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
596 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
597 3 cp866 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
598 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100599 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200600
601 " read three 'fileencoding's with cp866 'encoding'
602 set encoding=cp866 fencs=utf-8,cp1251
603 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100604 .w! ++enc=cp866 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200605 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100606 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200607 set fencs=utf-8,cp866
608 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100609 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200610 let expected =<< trim END
611 1 utf-8 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
612 2 cp1251 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
613 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
614 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100615 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200616
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100617 call delete('Xwfefile')
618 call delete('Xwfetest')
Bram Moolenaar622b3562020-07-27 20:02:41 +0200619 call delete('Xutf8')
620 call delete('Xcp1251')
621 call delete('Xcp866')
622 let &encoding = save_encoding
623 let &fileencodings = save_fileencodings
624 %bw!
625endfunc
626
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200627" Test for writing and reading a file starting with a BOM.
628" Byte Order Mark (BOM) character for various encodings is below:
629" UTF-8 : EF BB BF
630" UTF-16 (BE): FE FF
631" UTF-16 (LE): FF FE
632" UTF-32 (BE): 00 00 FE FF
633" UTF-32 (LE): FF FE 00 00
634func Test_readwrite_file_with_bom()
635 let utf8_bom = "\xEF\xBB\xBF"
636 let utf16be_bom = "\xFE\xFF"
637 let utf16le_bom = "\xFF\xFE"
638 let utf32be_bom = "\n\n\xFE\xFF"
639 let utf32le_bom = "\xFF\xFE\n\n"
640 let save_fileencoding = &fileencoding
641 set cpoptions+=S
642
643 " Check that editing a latin1 file doesn't see a BOM
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100644 call writefile(["\xFE\xFElatin-1"], 'Xrwtest1')
645 edit Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200646 call assert_equal('latin1', &fileencoding)
647 call assert_equal(0, &bomb)
648 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100649 write Xrwfile2
650 call assert_equal(["\xFE\xFElatin-1", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200651 set bomb fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100652 write Xrwtest3
653 call assert_equal(["\xFE\xFElatin-1", ''], readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200654 set bomb&
655
656 " Check utf-8 BOM
657 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100658 call writefile([utf8_bom .. "utf-8"], 'Xrwtest1')
659 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200660 call assert_equal('utf-8', &fileencoding)
661 call assert_equal(1, &bomb)
662 call assert_equal('utf-8', getline(1))
663 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100664 write! Xrwfile2
665 call assert_equal(['utf-8', ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200666 set fenc=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100667 w! Xrwtest3
668 call assert_equal([utf8_bom .. "utf-8", ''], readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200669
670 " Check utf-8 with an error (will fall back to latin-1)
671 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100672 call writefile([utf8_bom .. "utf-8\x80err"], 'Xrwtest1')
673 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200674 call assert_equal('latin1', &fileencoding)
675 call assert_equal(0, &bomb)
676 call assert_equal("\xC3\xAF\xC2\xBB\xC2\xBFutf-8\xC2\x80err", getline(1))
677 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100678 write! Xrwfile2
679 call assert_equal([utf8_bom .. "utf-8\x80err", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200680 set fenc=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100681 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200682 call assert_equal(["\xC3\xAF\xC2\xBB\xC2\xBFutf-8\xC2\x80err", ''],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100683 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200684
685 " Check ucs-2 BOM
686 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100687 call writefile([utf16be_bom .. "\nu\nc\ns\n-\n2\n"], 'Xrwtest1')
688 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200689 call assert_equal('utf-16', &fileencoding)
690 call assert_equal(1, &bomb)
691 call assert_equal('ucs-2', getline(1))
692 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100693 write! Xrwfile2
694 call assert_equal(["ucs-2", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200695 set fenc=ucs-2
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100696 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200697 call assert_equal([utf16be_bom .. "\nu\nc\ns\n-\n2\n", ''],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100698 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200699
700 " Check ucs-2le BOM
701 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100702 call writefile([utf16le_bom .. "u\nc\ns\n-\n2\nl\ne\n"], 'Xrwtest1')
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200703 " Need to add a NUL byte after the NL byte
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100704 call writefile(0z00, 'Xrwtest1', 'a')
705 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200706 call assert_equal('utf-16le', &fileencoding)
707 call assert_equal(1, &bomb)
708 call assert_equal('ucs-2le', getline(1))
709 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100710 write! Xrwfile2
711 call assert_equal(["ucs-2le", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200712 set fenc=ucs-2le
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100713 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200714 call assert_equal([utf16le_bom .. "u\nc\ns\n-\n2\nl\ne\n", "\n"],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100715 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200716
717 " Check ucs-4 BOM
718 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100719 call writefile([utf32be_bom .. "\n\n\nu\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\n"], 'Xrwtest1')
720 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200721 call assert_equal('ucs-4', &fileencoding)
722 call assert_equal(1, &bomb)
723 call assert_equal('ucs-4', getline(1))
724 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100725 write! Xrwfile2
726 call assert_equal(["ucs-4", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200727 set fenc=ucs-4
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100728 w! Xrwtest3
729 call assert_equal([utf32be_bom .. "\n\n\nu\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\n", ''], readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200730
731 " Check ucs-4le BOM
732 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100733 call writefile([utf32le_bom .. "u\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\nl\n\n\ne\n\n\n"], 'Xrwtest1')
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200734 " Need to add three NUL bytes after the NL byte
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100735 call writefile(0z000000, 'Xrwtest1', 'a')
736 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200737 call assert_equal('ucs-4le', &fileencoding)
738 call assert_equal(1, &bomb)
739 call assert_equal('ucs-4le', getline(1))
740 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100741 write! Xrwfile2
742 call assert_equal(["ucs-4le", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200743 set fenc=ucs-4le
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100744 w! Xrwtest3
745 call assert_equal([utf32le_bom .. "u\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\nl\n\n\ne\n\n\n", "\n\n\n"], readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200746
747 set cpoptions-=S
748 let &fileencoding = save_fileencoding
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100749 call delete('Xrwtest1')
750 call delete('Xrwfile2')
751 call delete('Xrwtest3')
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200752 %bw!
753endfunc
754
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100755func Test_read_write_bin()
756 " write file missing EOL
757 call writefile(['noeol'], "XNoEolSetEol", 'bS')
758 call assert_equal(0z6E6F656F6C, readfile('XNoEolSetEol', 'B'))
759
760 " when file is read 'eol' is off
Bram Moolenaar16204962020-12-23 22:40:11 +0100761 set nofixeol
762 e! ++ff=unix XNoEolSetEol
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100763 call assert_equal(0, &eol)
764
765 " writing with 'eol' set adds the newline
766 setlocal eol
767 w
768 call assert_equal(0z6E6F656F6C0A, readfile('XNoEolSetEol', 'B'))
769
770 call delete('XNoEolSetEol')
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200771 set ff& fixeol&
Bram Moolenaarbd318552020-12-23 20:55:15 +0100772 bwipe! XNoEolSetEol
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100773endfunc
774
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200775" Test for the 'backupcopy' option when writing files
776func Test_backupcopy()
777 CheckUnix
778 set backupskip=
779 " With the default 'backupcopy' setting, saving a symbolic link file
780 " should not break the link.
781 set backupcopy&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100782 call writefile(['1111'], 'Xbcfile1')
783 silent !ln -s Xbcfile1 Xbcfile2
784 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200785 call setline(1, ['2222'])
786 write
787 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100788 call assert_equal(['2222'], readfile('Xbcfile1'))
789 call assert_equal('Xbcfile1', resolve('Xbcfile2'))
790 call assert_equal('link', getftype('Xbcfile2'))
791 call delete('Xbcfile1')
792 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200793
794 " With the 'backupcopy' set to 'breaksymlink', saving a symbolic link file
795 " should break the link.
796 set backupcopy=yes,breaksymlink
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100797 call writefile(['1111'], 'Xbcfile1')
798 silent !ln -s Xbcfile1 Xbcfile2
799 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200800 call setline(1, ['2222'])
801 write
802 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100803 call assert_equal(['1111'], readfile('Xbcfile1'))
804 call assert_equal(['2222'], readfile('Xbcfile2'))
805 call assert_equal('Xbcfile2', resolve('Xbcfile2'))
806 call assert_equal('file', getftype('Xbcfile2'))
807 call delete('Xbcfile1')
808 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200809 set backupcopy&
810
811 " With the default 'backupcopy' setting, saving a hard link file
812 " should not break the link.
813 set backupcopy&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100814 call writefile(['1111'], 'Xbcfile1')
815 silent !ln Xbcfile1 Xbcfile2
816 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200817 call setline(1, ['2222'])
818 write
819 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100820 call assert_equal(['2222'], readfile('Xbcfile1'))
821 call delete('Xbcfile1')
822 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200823
824 " With the 'backupcopy' set to 'breaksymlink', saving a hard link file
825 " should break the link.
826 set backupcopy=yes,breakhardlink
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100827 call writefile(['1111'], 'Xbcfile1')
828 silent !ln Xbcfile1 Xbcfile2
829 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200830 call setline(1, ['2222'])
831 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100832 call assert_equal(['1111'], readfile('Xbcfile1'))
833 call assert_equal(['2222'], readfile('Xbcfile2'))
834 call delete('Xbcfile1')
835 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200836
837 " If a backup file is already present, then a slightly modified filename
838 " should be used as the backup file. Try with 'backupcopy' set to 'yes' and
839 " 'no'.
840 %bw
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100841 call writefile(['aaaa'], 'Xbcfile')
842 call writefile(['bbbb'], 'Xbcfile.bak')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200843 set backupcopy=yes backupext=.bak
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100844 new Xbcfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200845 call setline(1, ['cccc'])
846 write
847 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100848 call assert_equal(['cccc'], readfile('Xbcfile'))
849 call assert_equal(['bbbb'], readfile('Xbcfile.bak'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200850 set backupcopy=no backupext=.bak
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100851 new Xbcfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200852 call setline(1, ['dddd'])
853 write
854 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100855 call assert_equal(['dddd'], readfile('Xbcfile'))
856 call assert_equal(['bbbb'], readfile('Xbcfile.bak'))
857 call delete('Xbcfile')
858 call delete('Xbcfile.bak')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200859
860 " Write to a device file (in Unix-like systems) which cannot be backed up.
861 if has('unix')
862 set writebackup backupcopy=yes nobackup
863 new
864 call setline(1, ['aaaa'])
865 let output = execute('write! /dev/null')
866 call assert_match('"/dev/null" \[Device]', output)
867 close
868 set writebackup backupcopy=no nobackup
869 new
870 call setline(1, ['aaaa'])
871 let output = execute('write! /dev/null')
872 call assert_match('"/dev/null" \[Device]', output)
873 close
874 set backup writebackup& backupcopy&
875 new
876 call setline(1, ['aaaa'])
877 let output = execute('write! /dev/null')
878 call assert_match('"/dev/null" \[Device]', output)
879 close
880 endif
881
882 set backupcopy& backupskip& backupext& backup&
883endfunc
884
885" Test for writing a file with 'encoding' set to 'utf-16'
886func Test_write_utf16()
887 new
888 call setline(1, ["\U00010001"])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100889 write ++enc=utf-16 Xw16file
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200890 bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100891 call assert_equal(0zD800DC01, readfile('Xw16file', 'B')[0:3])
892 call delete('Xw16file')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200893endfunc
894
895" Test for trying to save a backup file when the backup file is a symbolic
896" link to the original file. The backup file should not be modified.
897func Test_write_backup_symlink()
898 CheckUnix
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000899 call mkdir('Xbackup')
900 let save_backupdir = &backupdir
901 set backupdir=.,./Xbackup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100902 call writefile(['1111'], 'Xwbsfile')
903 silent !ln -s Xwbsfile Xwbsfile.bak
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200904
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100905 new Xwbsfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200906 set backup backupcopy=yes backupext=.bak
907 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100908 call assert_equal('link', getftype('Xwbsfile.bak'))
909 call assert_equal('Xwbsfile', resolve('Xwbsfile.bak'))
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000910 " backup file should be created in the 'backup' directory
911 if !has('bsd')
912 " This check fails on FreeBSD
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100913 call assert_true(filereadable('./Xbackup/Xwbsfile.bak'))
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000914 endif
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200915 set backup& backupcopy& backupext&
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000916 %bw
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200917
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100918 call delete('Xwbsfile')
919 call delete('Xwbsfile.bak')
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000920 call delete('Xbackup', 'rf')
921 let &backupdir = save_backupdir
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200922endfunc
923
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200924" Test for ':write ++bin' and ':write ++nobin'
925func Test_write_binary_file()
926 " create a file without an eol/eof character
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100927 call writefile(0z616161, 'Xwbfile1', 'b')
928 new Xwbfile1
929 write ++bin Xwbfile2
930 write ++nobin Xwbfile3
931 call assert_equal(0z616161, readblob('Xwbfile2'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200932 if has('win32')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100933 call assert_equal(0z6161610D.0A, readblob('Xwbfile3'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200934 else
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100935 call assert_equal(0z6161610A, readblob('Xwbfile3'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200936 endif
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100937 call delete('Xwbfile1')
938 call delete('Xwbfile2')
939 call delete('Xwbfile3')
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200940endfunc
941
Bram Moolenaar806a2732022-09-04 15:40:36 +0100942func DoWriteDefer()
943 call writefile(['some text'], 'XdeferDelete', 'D')
944 call assert_equal(['some text'], readfile('XdeferDelete'))
945endfunc
946
947def DefWriteDefer()
948 writefile(['some text'], 'XdefdeferDelete', 'D')
949 assert_equal(['some text'], readfile('XdefdeferDelete'))
950enddef
951
952func Test_write_with_deferred_delete()
953 call DoWriteDefer()
954 call assert_equal('', glob('XdeferDelete'))
955 call DefWriteDefer()
956 call assert_equal('', glob('XdefdeferDelete'))
957endfunc
958
Bram Moolenaar6f14da12022-09-07 21:30:44 +0100959func DoWriteFile()
960 call writefile(['text'], 'Xthefile', 'D')
961 cd ..
962endfunc
963
964func Test_write_defer_delete_chdir()
965 let dir = getcwd()
966 call DoWriteFile()
967 call assert_notequal(dir, getcwd())
968 call chdir(dir)
969 call assert_equal('', glob('Xthefile'))
970endfunc
971
Bram Moolenaar1174b012021-05-29 14:30:43 +0200972" Check that buffer is written before triggering QuitPre
973func Test_wq_quitpre_autocommand()
974 edit Xsomefile
975 call setline(1, 'hello')
976 split
977 let g:seq = []
978 augroup Testing
979 au QuitPre * call add(g:seq, 'QuitPre - ' .. (&modified ? 'modified' : 'not modified'))
980 au BufWritePost * call add(g:seq, 'written')
981 augroup END
982 wq
983 call assert_equal(['written', 'QuitPre - not modified'], g:seq)
984
985 augroup Testing
986 au!
987 augroup END
988 bwipe!
989 unlet g:seq
990 call delete('Xsomefile')
991endfunc
992
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100993" vim: shiftwidth=2 sts=2 expandtab