blob: 140b2ee0375cca47c6aa2d15b1542ff9c3a9faef [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()
Bram Moolenaardb4c9472022-10-15 22:06:06 +01008 call writefile(["over", "written"], f, "bD")
9 call writefile(["hello", "world"], f, "b")
Bram Moolenaar19a16692016-09-01 22:19:47 +020010 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])
Bram Moolenaar18a2b872020-03-19 13:08:45 +010019
Bram Moolenaarb18b4962022-09-02 21:55:50 +010020 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 +020021endfunc
22
Bram Moolenaarb40c2572019-10-19 21:01:05 +020023func Test_writefile_ignore_regexp_error()
24 write Xt[z-a]est.txt
25 call delete('Xt[z-a]est.txt')
26endfunc
27
Bram Moolenaar8cf91282017-06-13 19:38:37 +020028func Test_writefile_fails_gently()
Bram Moolenaarb18b4962022-09-02 21:55:50 +010029 call assert_fails('call writefile(["test"], "Xwffile", [])', 'E730:')
30 call assert_false(filereadable("Xwffile"))
31 call delete("Xwffile")
Bram Moolenaar8cf91282017-06-13 19:38:37 +020032
Bram Moolenaarb18b4962022-09-02 21:55:50 +010033 call assert_fails('call writefile(["test", [], [], [], "tset"], "Xwffile")', 'E730:')
34 call assert_false(filereadable("Xwffile"))
35 call delete("Xwffile")
Bram Moolenaar8cf91282017-06-13 19:38:37 +020036
Bram Moolenaarb18b4962022-09-02 21:55:50 +010037 call assert_fails('call writefile([], "Xwffile", [])', 'E730:')
38 call assert_false(filereadable("Xwffile"))
39 call delete("Xwffile")
Bram Moolenaar8cf91282017-06-13 19:38:37 +020040
41 call assert_fails('call writefile([], [])', 'E730:')
42endfunc
Bram Moolenaare6bf6552017-06-27 22:11:51 +020043
44func Test_writefile_fails_conversion()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020045 CheckFeature iconv
46 if has('sun')
47 throw 'Skipped: does not work on SunOS'
Bram Moolenaare6bf6552017-06-27 22:11:51 +020048 endif
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020049 " Without a backup file the write won't happen if there is a conversion
50 " error.
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020051 set nobackup nowritebackup backupdir=. backupskip=
Bram Moolenaare6bf6552017-06-27 22:11:51 +020052 new
53 let contents = ["line one", "line two"]
Bram Moolenaardb4c9472022-10-15 22:06:06 +010054 call writefile(contents, 'Xwfcfile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010055 edit Xwfcfile
Bram Moolenaare6bf6552017-06-27 22:11:51 +020056 call setline(1, ["first line", "cannot convert \u010b", "third line"])
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020057 call assert_fails('write ++enc=cp932', 'E513:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010058 call assert_equal(contents, readfile('Xwfcfile'))
Bram Moolenaare6bf6552017-06-27 22:11:51 +020059
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020060 " With 'backupcopy' set, if there is a conversion error, the backup file is
61 " still created.
62 set backupcopy=yes writebackup& backup&
Bram Moolenaarb18b4962022-09-02 21:55:50 +010063 call delete('Xwfcfile' .. &backupext)
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020064 call assert_fails('write ++enc=cp932', 'E513:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010065 call assert_equal(contents, readfile('Xwfcfile'))
66 call assert_equal(contents, readfile('Xwfcfile' .. &backupext))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020067 set backupcopy&
68 %bw!
69
70 " Conversion error during write
71 new
72 call setline(1, ["\U10000000"])
Bram Moolenaarb18b4962022-09-02 21:55:50 +010073 let output = execute('write! ++enc=utf-16 Xwfcfile')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020074 call assert_match('CONVERSION ERROR', output)
Bram Moolenaarb18b4962022-09-02 21:55:50 +010075 let output = execute('write! ++enc=ucs-2 Xwfcfile')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020076 call assert_match('CONVERSION ERROR', output)
Dominique Pelleb40ad4f2022-09-04 21:29:46 +010077 call delete('Xwfcfilz~')
78 call delete('Xwfcfily~')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020079 %bw!
80
Bram Moolenaarb18b4962022-09-02 21:55:50 +010081 call delete('Xwfcfile' .. &backupext)
Bram Moolenaare6bf6552017-06-27 22:11:51 +020082 bwipe!
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020083 set backup& writebackup& backupdir&vim backupskip&vim
Bram Moolenaare6bf6552017-06-27 22:11:51 +020084endfunc
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +020085
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020086func Test_writefile_fails_conversion2()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020087 CheckFeature iconv
88 if has('sun')
89 throw 'Skipped: does not work on SunOS'
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020090 endif
91 " With a backup file the write happens even if there is a conversion error,
92 " but then the backup file must remain
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020093 set nobackup writebackup backupdir=. backupskip=
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020094 let contents = ["line one", "line two"]
Bram Moolenaardb4c9472022-10-15 22:06:06 +010095 call writefile(contents, 'Xwf2file_conversion_err', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010096 edit Xwf2file_conversion_err
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020097 call setline(1, ["first line", "cannot convert \u010b", "third line"])
98 set fileencoding=latin1
99 let output = execute('write')
100 call assert_match('CONVERSION ERROR', output)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100101 call assert_equal(contents, readfile('Xwf2file_conversion_err~'))
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +0200102
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100103 call delete('Xwf2file_conversion_err~')
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +0200104 bwipe!
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +0200105 set backup& writebackup& backupdir&vim backupskip&vim
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +0200106endfunc
107
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200108func SetFlag(timer)
109 let g:flag = 1
110endfunc
111
112func Test_write_quit_split()
113 " Prevent exiting by splitting window on file write.
114 augroup testgroup
115 autocmd BufWritePre * split
116 augroup END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100117 e! Xwqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200118 call setline(1, 'nothing')
119 wq
120
121 if has('timers')
122 " timer will not run if "exiting" is still set
123 let g:flag = 0
124 call timer_start(1, 'SetFlag')
125 sleep 50m
126 call assert_equal(1, g:flag)
127 unlet g:flag
128 endif
129 au! testgroup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100130 bwipe Xwqsfile
131 call delete('Xwqsfile')
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200132endfunc
133
134func Test_nowrite_quit_split()
135 " Prevent exiting by opening a help window.
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100136 e! Xnqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200137 help
138 wincmd w
139 exe winnr() . 'q'
140
141 if has('timers')
142 " timer will not run if "exiting" is still set
143 let g:flag = 0
144 call timer_start(1, 'SetFlag')
145 sleep 50m
146 call assert_equal(1, g:flag)
147 unlet g:flag
148 endif
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100149 bwipe Xnqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200150endfunc
Bram Moolenaar7567d0b2017-11-16 23:04:15 +0100151
152func Test_writefile_sync_arg()
153 " This doesn't check if fsync() works, only that the argument is accepted.
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100154 call writefile(['one'], 'Xtest', 'sD')
Bram Moolenaar7567d0b2017-11-16 23:04:15 +0100155 call writefile(['two'], 'Xtest', 'S')
Bram Moolenaar7567d0b2017-11-16 23:04:15 +0100156endfunc
Bram Moolenaar83799a72017-11-25 17:24:09 +0100157
158func Test_writefile_sync_dev_stdout()
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200159 CheckUnix
Bram Moolenaar9980b372018-04-21 20:12:35 +0200160 if filewritable('/dev/stdout')
161 " Just check that this doesn't cause an error.
162 call writefile(['one'], '/dev/stdout')
163 else
164 throw 'Skipped: /dev/stdout is not writable'
165 endif
Bram Moolenaar83799a72017-11-25 17:24:09 +0100166endfunc
Bram Moolenaar8c9e7b02018-08-30 13:07:17 +0200167
168func Test_writefile_autowrite()
169 set autowrite
170 new
171 next Xa Xb Xc
172 call setline(1, 'aaa')
173 next
174 call assert_equal(['aaa'], readfile('Xa'))
175 call setline(1, 'bbb')
176 call assert_fails('edit XX')
177 call assert_false(filereadable('Xb'))
178
179 set autowriteall
180 edit XX
181 call assert_equal(['bbb'], readfile('Xb'))
182
183 bwipe!
184 call delete('Xa')
185 call delete('Xb')
186 set noautowrite
187endfunc
188
189func Test_writefile_autowrite_nowrite()
190 set autowrite
191 new
192 next Xa Xb Xc
193 set buftype=nowrite
194 call setline(1, 'aaa')
195 let buf = bufnr('%')
196 " buffer contents silently lost
197 edit XX
198 call assert_false(filereadable('Xa'))
199 rewind
200 call assert_equal('', getline(1))
201
202 bwipe!
203 set noautowrite
204endfunc
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100205
206" Test for ':w !<cmd>' to pipe lines from the current buffer to an external
207" command.
208func Test_write_pipe_to_cmd()
Bram Moolenaarea3db912020-02-02 15:32:13 +0100209 CheckUnix
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100210 new
211 call setline(1, ['L1', 'L2', 'L3', 'L4'])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100212 2,3w !cat > Xptfile
213 call assert_equal(['L2', 'L3'], readfile('Xptfile'))
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100214 close!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100215 call delete('Xptfile')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100216endfunc
217
218" Test for :saveas
219func Test_saveas()
220 call assert_fails('saveas', 'E471:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100221 call writefile(['L1'], 'Xsafile')
222 new Xsafile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100223 new
224 call setline(1, ['L1'])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100225 call assert_fails('saveas Xsafile', 'E139:')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100226 close!
227 enew | only
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100228 call delete('Xsafile')
Dominique Pellebd9e7962021-08-09 21:04:44 +0200229
230 " :saveas should detect and set the file type.
231 syntax on
232 saveas! Xsaveas.pl
233 call assert_equal('perl', &filetype)
234 syntax off
235 %bw!
236 call delete('Xsaveas.pl')
Bram Moolenaar500a1f92022-09-20 11:49:10 +0100237
238 " :saveas fails for "nofile" buffer
239 set buftype=nofile
240 call assert_fails('saveas Xsafile', 'E676: No matching autocommands for buftype=nofile buffer')
241
242 bwipe!
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100243endfunc
244
245func Test_write_errors()
246 " Test for writing partial buffer
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100247 call writefile(['L1', 'L2', 'L3'], 'Xwefile')
248 new Xwefile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100249 call assert_fails('1,2write', 'E140:')
250 close!
251
Bram Moolenaar4f5776c2020-02-12 22:15:19 +0100252 call assert_fails('w > Xtest', 'E494:')
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +0100253
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100254 " Try to overwrite a directory
255 if has('unix')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100256 call mkdir('Xwerdir1')
257 call assert_fails('write Xwerdir1', 'E17:')
258 call delete('Xwerdir1', 'd')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100259 endif
260
261 " Test for :wall for a buffer with no name
262 enew | only
263 call setline(1, ['L1'])
264 call assert_fails('wall', 'E141:')
265 enew!
266
267 " Test for writing a 'readonly' file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100268 new Xwefile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100269 set readonly
270 call assert_fails('write', 'E45:')
271 close
272
273 " Test for writing to a read-only file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100274 new Xwefile
275 call setfperm('Xwefile', 'r--r--r--')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100276 call assert_fails('write', 'E505:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100277 call setfperm('Xwefile', 'rw-rw-rw-')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100278 close
279
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100280 call delete('Xwefile')
Bram Moolenaar99fa7212020-04-26 15:59:55 +0200281
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100282 call writefile(test_null_list(), 'Xwefile')
283 call assert_false(filereadable('Xwefile'))
284 call writefile(test_null_blob(), 'Xwefile')
285 call assert_false(filereadable('Xwefile'))
Bram Moolenaar99fa7212020-04-26 15:59:55 +0200286 call assert_fails('call writefile([], "")', 'E482:')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200287
288 " very long file name
289 let long_fname = repeat('n', 5000)
290 call assert_fails('exe "w " .. long_fname', 'E75:')
291 call assert_fails('call writefile([], long_fname)', 'E482:')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200292
293 " Test for writing to a block device on Unix-like systems
294 if has('unix') && getfperm('/dev/loop0') != ''
295 \ && getftype('/dev/loop0') == 'bdev' && !IsRoot()
296 new
297 edit /dev/loop0
Bram Moolenaar50157ef2021-05-15 23:21:05 +0200298 call assert_fails('write', 'E503: ')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200299 call assert_fails('write!', 'E503: ')
300 close!
301 endif
Bram Moolenaar494e9062020-05-31 21:28:02 +0200302endfunc
303
304" Test for writing to a file which is modified after Vim read it
305func Test_write_file_mtime()
306 CheckEnglish
307 CheckRunVimInTerminal
308
309 " First read the file into a buffer
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100310 call writefile(["Line1", "Line2"], 'Xwfmfile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100311 let old_ftime = getftime('Xwfmfile')
312 let buf = RunVimInTerminal('Xwfmfile', #{rows : 10})
Bram Moolenaar733d2592020-08-20 18:59:06 +0200313 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200314 call term_sendkeys(buf, ":set noswapfile\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200315 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200316
317 " Modify the file directly. Make sure the file modification time is
318 " different. Note that on Linux/Unix, the file is considered modified
319 " outside, only if the difference is 2 seconds or more
320 sleep 1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100321 call writefile(["Line3", "Line4"], 'Xwfmfile')
322 let new_ftime = getftime('Xwfmfile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200323 while new_ftime - old_ftime < 2
324 sleep 100m
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 endwhile
328
329 " Try to overwrite the file and check for the prompt
330 call term_sendkeys(buf, ":w\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200331 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200332 call WaitForAssert({-> assert_equal("WARNING: The file has been changed since reading it!!!", term_getline(buf, 9))})
333 call assert_equal("Do you really want to write to it (y/n)?",
334 \ term_getline(buf, 10))
335 call term_sendkeys(buf, "n\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200336 call TermWait(buf)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100337 call assert_equal(new_ftime, getftime('Xwfmfile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200338 call term_sendkeys(buf, ":w\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200339 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200340 call term_sendkeys(buf, "y\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200341 call TermWait(buf)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100342 call WaitForAssert({-> assert_equal('Line2', readfile('Xwfmfile')[1])})
Bram Moolenaar494e9062020-05-31 21:28:02 +0200343
344 " clean up
345 call StopVimInTerminal(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200346endfunc
347
348" Test for an autocmd unloading a buffer during a write command
349func Test_write_autocmd_unloadbuf_lockmark()
350 augroup WriteTest
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100351 autocmd BufWritePre Xwaufile enew | write
Bram Moolenaar494e9062020-05-31 21:28:02 +0200352 augroup END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100353 e Xwaufile
Bram Moolenaare2e40752020-09-04 21:18:46 +0200354 call assert_fails('lockmarks write', ['E32:', 'E203:'])
Bram Moolenaar494e9062020-05-31 21:28:02 +0200355 augroup WriteTest
356 au!
357 augroup END
358 augroup! WriteTest
359endfunc
360
361" Test for writing a buffer with 'acwrite' but without autocmds
362func Test_write_acwrite_error()
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100363 new Xwaefile
Bram Moolenaar494e9062020-05-31 21:28:02 +0200364 call setline(1, ['line1', 'line2', 'line3'])
365 set buftype=acwrite
366 call assert_fails('write', 'E676:')
367 call assert_fails('1,2write!', 'E676:')
368 call assert_fails('w >>', 'E676:')
369 close!
370endfunc
371
372" Test for adding and removing lines from an autocmd when writing a buffer
373func Test_write_autocmd_add_remove_lines()
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100374 new Xwaafile
Bram Moolenaar494e9062020-05-31 21:28:02 +0200375 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
376
377 " Autocmd deleting lines from the file when writing a partial file
378 augroup WriteTest2
379 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100380 autocmd FileWritePre Xwaafile 1,2d
Bram Moolenaar494e9062020-05-31 21:28:02 +0200381 augroup END
382 call assert_fails('2,3w!', 'E204:')
383
384 " Autocmd adding lines to a file when writing a partial file
385 augroup WriteTest2
386 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100387 autocmd FileWritePre Xwaafile call append(0, ['xxx', 'yyy'])
Bram Moolenaar494e9062020-05-31 21:28:02 +0200388 augroup END
389 %d
390 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
391 1,2w!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100392 call assert_equal(['xxx', 'yyy', 'aaa', 'bbb'], readfile('Xwaafile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200393
394 " Autocmd deleting lines from the file when writing the whole file
395 augroup WriteTest2
396 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100397 autocmd BufWritePre Xwaafile 1,2d
Bram Moolenaar494e9062020-05-31 21:28:02 +0200398 augroup END
399 %d
400 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
401 w
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100402 call assert_equal(['ccc', 'ddd'], readfile('Xwaafile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200403
404 augroup WriteTest2
405 au!
406 augroup END
407 augroup! WriteTest2
408
409 close!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100410 call delete('Xwaafile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200411endfunc
412
413" Test for writing to a readonly file
414func Test_write_readonly()
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100415 call writefile([], 'Xwrofile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100416 call setfperm('Xwrofile', "r--------")
417 edit Xwrofile
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200418 set noreadonly backupskip=
Bram Moolenaar494e9062020-05-31 21:28:02 +0200419 call assert_fails('write', 'E505:')
420 let save_cpo = &cpo
421 set cpo+=W
422 call assert_fails('write!', 'E504:')
423 let &cpo = save_cpo
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200424 call setline(1, ['line1'])
425 write!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100426 call assert_equal(['line1'], readfile('Xwrofile'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200427
428 " Auto-saving a readonly file should fail with 'autowriteall'
429 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100430 e Xwrofile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200431 set noreadonly autowriteall
432 call setline(1, ['aaaa'])
433 call assert_fails('n', 'E505:')
434 set cpo+=W
435 call assert_fails('n', 'E504:')
436 set cpo-=W
437 set autowriteall&
438
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200439 set backupskip&
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200440 %bw!
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100441endfunc
442
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200443" Test for 'patchmode'
444func Test_patchmode()
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100445 call writefile(['one'], 'Xpafile', 'D')
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200446 set patchmode=.orig nobackup backupskip= writebackup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100447 new Xpafile
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200448 call setline(1, 'two')
449 " first write should create the .orig file
450 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100451 call assert_equal(['one'], readfile('Xpafile.orig'))
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200452 call setline(1, 'three')
453 " subsequent writes should not create/modify the .orig file
454 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100455 call assert_equal(['one'], readfile('Xpafile.orig'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200456
457 " use 'patchmode' with 'nobackup' and 'nowritebackup' to create an empty
458 " original file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100459 call delete('Xpafile')
460 call delete('Xpafile.orig')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200461 %bw!
462 set patchmode=.orig nobackup nowritebackup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100463 edit Xpafile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200464 call setline(1, ['xxx'])
465 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100466 call assert_equal(['xxx'], readfile('Xpafile'))
467 call assert_equal([], readfile('Xpafile.orig'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200468
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200469 set patchmode& backup& backupskip& writebackup&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100470 call delete('Xpafile.orig')
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200471endfunc
472
473" Test for writing to a file in a readonly directory
Bram Moolenaarf9a65502021-03-05 20:47:44 +0100474" NOTE: if you run tests as root this will fail. Don't run tests as root!
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200475func Test_write_readonly_dir()
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200476 " On MS-Windows, modifying files in a read-only directory is allowed.
477 CheckUnix
Bram Moolenaar17709e22021-03-19 14:38:12 +0100478 " Root can do it too.
479 CheckNotRoot
480
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100481 call mkdir('Xrodir/', 'R')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100482 call writefile(['one'], 'Xrodir/Xfile1')
483 call setfperm('Xrodir', 'r-xr--r--')
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200484 " try to create a new file in the directory
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100485 new Xrodir/Xfile2
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200486 call setline(1, 'two')
487 call assert_fails('write', 'E212:')
488 " try to create a backup file in the directory
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100489 edit! Xrodir/Xfile1
490 set backupdir=./Xrodir backupskip=
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200491 set patchmode=.orig
492 call assert_fails('write', 'E509:')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100493 call setfperm('Xrodir', 'rwxr--r--')
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200494 set backupdir& backupskip& patchmode&
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200495endfunc
496
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200497" Test for writing a file using invalid file encoding
498func Test_write_invalid_encoding()
499 new
500 call setline(1, 'abc')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100501 call assert_fails('write ++enc=axbyc Xiefile', 'E213:')
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200502 close!
503endfunc
504
Bram Moolenaar622b3562020-07-27 20:02:41 +0200505" Tests for reading and writing files with conversion for Win32.
506func Test_write_file_encoding()
507 CheckMSWindows
508 let save_encoding = &encoding
509 let save_fileencodings = &fileencodings
K.Takataf883d902021-05-30 18:04:19 +0200510 set encoding=latin1 fileencodings&
Bram Moolenaar622b3562020-07-27 20:02:41 +0200511 let text =<< trim END
512 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
513 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
514 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
515 END
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100516 call writefile(text, 'Xwfefile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100517 edit Xwfefile
Bram Moolenaar622b3562020-07-27 20:02:41 +0200518
519 " write tests:
520 " combine three values for 'encoding' with three values for 'fileencoding'
521 " also write files for read tests
522 call cursor(1, 1)
523 set encoding=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100524 .w! ++enc=utf-8 Xwfetest
525 .w ++enc=cp1251 >> Xwfetest
526 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200527 .w! ++enc=utf-8 Xutf8
528 let expected =<< trim END
529 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
530 1 utf-8 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
531 1 utf-8 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
532 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100533 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200534
535 call cursor(2, 1)
536 set encoding=cp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100537 .w! ++enc=utf-8 Xwfetest
538 .w ++enc=cp1251 >> Xwfetest
539 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200540 .w! ++enc=cp1251 Xcp1251
541 let expected =<< trim END
542 2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
543 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
544 2 cp1251 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
545 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100546 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200547
548 call cursor(3, 1)
549 set encoding=cp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100550 .w! ++enc=utf-8 Xwfetest
551 .w ++enc=cp1251 >> Xwfetest
552 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200553 .w! ++enc=cp866 Xcp866
554 let expected =<< trim END
555 3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
556 3 cp866 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
557 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
558 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100559 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200560
561 " read three 'fileencoding's with utf-8 'encoding'
562 set encoding=utf-8 fencs=utf-8,cp1251
563 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100564 .w! ++enc=utf-8 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200565 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100566 .w ++enc=utf-8 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200567 set fencs=utf-8,cp866
568 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100569 .w ++enc=utf-8 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200570 let expected =<< trim END
571 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
572 2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
573 3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
574 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100575 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200576
577 " read three 'fileencoding's with cp1251 'encoding'
578 set encoding=utf-8 fencs=utf-8,cp1251
579 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100580 .w! ++enc=cp1251 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200581 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100582 .w ++enc=cp1251 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200583 set fencs=utf-8,cp866
584 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100585 .w ++enc=cp1251 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200586 let expected =<< trim END
587 1 utf-8 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
588 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
589 3 cp866 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
590 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100591 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200592
593 " read three 'fileencoding's with cp866 'encoding'
594 set encoding=cp866 fencs=utf-8,cp1251
595 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100596 .w! ++enc=cp866 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200597 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100598 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200599 set fencs=utf-8,cp866
600 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100601 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200602 let expected =<< trim END
603 1 utf-8 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
604 2 cp1251 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
605 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
606 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100607 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200608
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100609 call delete('Xwfetest')
Bram Moolenaar622b3562020-07-27 20:02:41 +0200610 call delete('Xutf8')
611 call delete('Xcp1251')
612 call delete('Xcp866')
613 let &encoding = save_encoding
614 let &fileencodings = save_fileencodings
615 %bw!
616endfunc
617
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200618" Test for writing and reading a file starting with a BOM.
619" Byte Order Mark (BOM) character for various encodings is below:
620" UTF-8 : EF BB BF
621" UTF-16 (BE): FE FF
622" UTF-16 (LE): FF FE
623" UTF-32 (BE): 00 00 FE FF
624" UTF-32 (LE): FF FE 00 00
625func Test_readwrite_file_with_bom()
626 let utf8_bom = "\xEF\xBB\xBF"
627 let utf16be_bom = "\xFE\xFF"
628 let utf16le_bom = "\xFF\xFE"
629 let utf32be_bom = "\n\n\xFE\xFF"
630 let utf32le_bom = "\xFF\xFE\n\n"
631 let save_fileencoding = &fileencoding
632 set cpoptions+=S
633
634 " Check that editing a latin1 file doesn't see a BOM
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100635 call writefile(["\xFE\xFElatin-1"], 'Xrwtest1', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100636 edit Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200637 call assert_equal('latin1', &fileencoding)
638 call assert_equal(0, &bomb)
639 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100640 write Xrwfile2
641 call assert_equal(["\xFE\xFElatin-1", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200642 set bomb fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100643 write Xrwtest3
644 call assert_equal(["\xFE\xFElatin-1", ''], readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200645 set bomb&
646
647 " Check utf-8 BOM
648 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100649 call writefile([utf8_bom .. "utf-8"], 'Xrwtest1')
650 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200651 call assert_equal('utf-8', &fileencoding)
652 call assert_equal(1, &bomb)
653 call assert_equal('utf-8', getline(1))
654 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100655 write! Xrwfile2
656 call assert_equal(['utf-8', ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200657 set fenc=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100658 w! Xrwtest3
659 call assert_equal([utf8_bom .. "utf-8", ''], readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200660
661 " Check utf-8 with an error (will fall back to latin-1)
662 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100663 call writefile([utf8_bom .. "utf-8\x80err"], 'Xrwtest1')
664 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200665 call assert_equal('latin1', &fileencoding)
666 call assert_equal(0, &bomb)
667 call assert_equal("\xC3\xAF\xC2\xBB\xC2\xBFutf-8\xC2\x80err", getline(1))
668 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100669 write! Xrwfile2
670 call assert_equal([utf8_bom .. "utf-8\x80err", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200671 set fenc=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100672 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200673 call assert_equal(["\xC3\xAF\xC2\xBB\xC2\xBFutf-8\xC2\x80err", ''],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100674 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200675
676 " Check ucs-2 BOM
677 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100678 call writefile([utf16be_bom .. "\nu\nc\ns\n-\n2\n"], 'Xrwtest1')
679 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200680 call assert_equal('utf-16', &fileencoding)
681 call assert_equal(1, &bomb)
682 call assert_equal('ucs-2', getline(1))
683 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100684 write! Xrwfile2
685 call assert_equal(["ucs-2", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200686 set fenc=ucs-2
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100687 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200688 call assert_equal([utf16be_bom .. "\nu\nc\ns\n-\n2\n", ''],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100689 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200690
691 " Check ucs-2le BOM
692 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100693 call writefile([utf16le_bom .. "u\nc\ns\n-\n2\nl\ne\n"], 'Xrwtest1')
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200694 " Need to add a NUL byte after the NL byte
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100695 call writefile(0z00, 'Xrwtest1', 'a')
696 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200697 call assert_equal('utf-16le', &fileencoding)
698 call assert_equal(1, &bomb)
699 call assert_equal('ucs-2le', getline(1))
700 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100701 write! Xrwfile2
702 call assert_equal(["ucs-2le", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200703 set fenc=ucs-2le
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100704 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200705 call assert_equal([utf16le_bom .. "u\nc\ns\n-\n2\nl\ne\n", "\n"],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100706 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200707
708 " Check ucs-4 BOM
709 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100710 call writefile([utf32be_bom .. "\n\n\nu\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\n"], 'Xrwtest1')
711 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200712 call assert_equal('ucs-4', &fileencoding)
713 call assert_equal(1, &bomb)
714 call assert_equal('ucs-4', getline(1))
715 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100716 write! Xrwfile2
717 call assert_equal(["ucs-4", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200718 set fenc=ucs-4
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100719 w! Xrwtest3
720 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 +0200721
722 " Check ucs-4le BOM
723 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100724 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 +0200725 " Need to add three NUL bytes after the NL byte
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100726 call writefile(0z000000, 'Xrwtest1', 'a')
727 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200728 call assert_equal('ucs-4le', &fileencoding)
729 call assert_equal(1, &bomb)
730 call assert_equal('ucs-4le', getline(1))
731 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100732 write! Xrwfile2
733 call assert_equal(["ucs-4le", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200734 set fenc=ucs-4le
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100735 w! Xrwtest3
736 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 +0200737
738 set cpoptions-=S
739 let &fileencoding = save_fileencoding
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100740 call delete('Xrwfile2')
741 call delete('Xrwtest3')
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200742 %bw!
743endfunc
744
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100745func Test_read_write_bin()
746 " write file missing EOL
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100747 call writefile(['noeol'], "XNoEolSetEol", 'bSD')
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100748 call assert_equal(0z6E6F656F6C, readfile('XNoEolSetEol', 'B'))
749
750 " when file is read 'eol' is off
Bram Moolenaar16204962020-12-23 22:40:11 +0100751 set nofixeol
752 e! ++ff=unix XNoEolSetEol
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100753 call assert_equal(0, &eol)
754
755 " writing with 'eol' set adds the newline
756 setlocal eol
757 w
758 call assert_equal(0z6E6F656F6C0A, readfile('XNoEolSetEol', 'B'))
759
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200760 set ff& fixeol&
Bram Moolenaarbd318552020-12-23 20:55:15 +0100761 bwipe! XNoEolSetEol
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100762endfunc
763
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200764" Test for the 'backupcopy' option when writing files
765func Test_backupcopy()
766 CheckUnix
767 set backupskip=
768 " With the default 'backupcopy' setting, saving a symbolic link file
769 " should not break the link.
770 set backupcopy&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100771 call writefile(['1111'], 'Xbcfile1')
772 silent !ln -s Xbcfile1 Xbcfile2
773 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200774 call setline(1, ['2222'])
775 write
776 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100777 call assert_equal(['2222'], readfile('Xbcfile1'))
778 call assert_equal('Xbcfile1', resolve('Xbcfile2'))
779 call assert_equal('link', getftype('Xbcfile2'))
780 call delete('Xbcfile1')
781 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200782
783 " With the 'backupcopy' set to 'breaksymlink', saving a symbolic link file
784 " should break the link.
785 set backupcopy=yes,breaksymlink
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100786 call writefile(['1111'], 'Xbcfile1')
787 silent !ln -s Xbcfile1 Xbcfile2
788 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200789 call setline(1, ['2222'])
790 write
791 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100792 call assert_equal(['1111'], readfile('Xbcfile1'))
793 call assert_equal(['2222'], readfile('Xbcfile2'))
794 call assert_equal('Xbcfile2', resolve('Xbcfile2'))
795 call assert_equal('file', getftype('Xbcfile2'))
796 call delete('Xbcfile1')
797 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200798 set backupcopy&
799
800 " With the default 'backupcopy' setting, saving a hard link file
801 " should not break the link.
802 set backupcopy&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100803 call writefile(['1111'], 'Xbcfile1')
804 silent !ln Xbcfile1 Xbcfile2
805 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200806 call setline(1, ['2222'])
807 write
808 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100809 call assert_equal(['2222'], readfile('Xbcfile1'))
810 call delete('Xbcfile1')
811 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200812
813 " With the 'backupcopy' set to 'breaksymlink', saving a hard link file
814 " should break the link.
815 set backupcopy=yes,breakhardlink
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100816 call writefile(['1111'], 'Xbcfile1')
817 silent !ln Xbcfile1 Xbcfile2
818 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200819 call setline(1, ['2222'])
820 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100821 call assert_equal(['1111'], readfile('Xbcfile1'))
822 call assert_equal(['2222'], readfile('Xbcfile2'))
823 call delete('Xbcfile1')
824 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200825
826 " If a backup file is already present, then a slightly modified filename
827 " should be used as the backup file. Try with 'backupcopy' set to 'yes' and
828 " 'no'.
829 %bw
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100830 call writefile(['aaaa'], 'Xbcfile')
831 call writefile(['bbbb'], 'Xbcfile.bak')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200832 set backupcopy=yes backupext=.bak
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100833 new Xbcfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200834 call setline(1, ['cccc'])
835 write
836 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100837 call assert_equal(['cccc'], readfile('Xbcfile'))
838 call assert_equal(['bbbb'], readfile('Xbcfile.bak'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200839 set backupcopy=no backupext=.bak
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100840 new Xbcfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200841 call setline(1, ['dddd'])
842 write
843 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100844 call assert_equal(['dddd'], readfile('Xbcfile'))
845 call assert_equal(['bbbb'], readfile('Xbcfile.bak'))
846 call delete('Xbcfile')
847 call delete('Xbcfile.bak')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200848
849 " Write to a device file (in Unix-like systems) which cannot be backed up.
850 if has('unix')
851 set writebackup backupcopy=yes nobackup
852 new
853 call setline(1, ['aaaa'])
854 let output = execute('write! /dev/null')
855 call assert_match('"/dev/null" \[Device]', output)
856 close
857 set writebackup backupcopy=no nobackup
858 new
859 call setline(1, ['aaaa'])
860 let output = execute('write! /dev/null')
861 call assert_match('"/dev/null" \[Device]', output)
862 close
863 set backup writebackup& backupcopy&
864 new
865 call setline(1, ['aaaa'])
866 let output = execute('write! /dev/null')
867 call assert_match('"/dev/null" \[Device]', output)
868 close
869 endif
870
871 set backupcopy& backupskip& backupext& backup&
872endfunc
873
874" Test for writing a file with 'encoding' set to 'utf-16'
875func Test_write_utf16()
876 new
877 call setline(1, ["\U00010001"])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100878 write ++enc=utf-16 Xw16file
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200879 bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100880 call assert_equal(0zD800DC01, readfile('Xw16file', 'B')[0:3])
881 call delete('Xw16file')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200882endfunc
883
884" Test for trying to save a backup file when the backup file is a symbolic
885" link to the original file. The backup file should not be modified.
886func Test_write_backup_symlink()
887 CheckUnix
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000888 call mkdir('Xbackup')
889 let save_backupdir = &backupdir
890 set backupdir=.,./Xbackup
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100891 call writefile(['1111'], 'Xwbsfile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100892 silent !ln -s Xwbsfile Xwbsfile.bak
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200893
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100894 new Xwbsfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200895 set backup backupcopy=yes backupext=.bak
896 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100897 call assert_equal('link', getftype('Xwbsfile.bak'))
898 call assert_equal('Xwbsfile', resolve('Xwbsfile.bak'))
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000899 " backup file should be created in the 'backup' directory
900 if !has('bsd')
901 " This check fails on FreeBSD
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100902 call assert_true(filereadable('./Xbackup/Xwbsfile.bak'))
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000903 endif
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200904 set backup& backupcopy& backupext&
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000905 %bw
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200906
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100907 call delete('Xwbsfile.bak')
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000908 call delete('Xbackup', 'rf')
909 let &backupdir = save_backupdir
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200910endfunc
911
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200912" Test for ':write ++bin' and ':write ++nobin'
913func Test_write_binary_file()
914 " create a file without an eol/eof character
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100915 call writefile(0z616161, 'Xwbfile1', 'bD')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100916 new Xwbfile1
917 write ++bin Xwbfile2
918 write ++nobin Xwbfile3
919 call assert_equal(0z616161, readblob('Xwbfile2'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200920 if has('win32')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100921 call assert_equal(0z6161610D.0A, readblob('Xwbfile3'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200922 else
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100923 call assert_equal(0z6161610A, readblob('Xwbfile3'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200924 endif
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100925 call delete('Xwbfile2')
926 call delete('Xwbfile3')
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200927endfunc
928
Bram Moolenaar806a2732022-09-04 15:40:36 +0100929func DoWriteDefer()
930 call writefile(['some text'], 'XdeferDelete', 'D')
931 call assert_equal(['some text'], readfile('XdeferDelete'))
932endfunc
933
934def DefWriteDefer()
935 writefile(['some text'], 'XdefdeferDelete', 'D')
936 assert_equal(['some text'], readfile('XdefdeferDelete'))
937enddef
938
939func Test_write_with_deferred_delete()
940 call DoWriteDefer()
941 call assert_equal('', glob('XdeferDelete'))
942 call DefWriteDefer()
943 call assert_equal('', glob('XdefdeferDelete'))
944endfunc
945
Bram Moolenaar6f14da12022-09-07 21:30:44 +0100946func DoWriteFile()
947 call writefile(['text'], 'Xthefile', 'D')
948 cd ..
949endfunc
950
951func Test_write_defer_delete_chdir()
952 let dir = getcwd()
953 call DoWriteFile()
954 call assert_notequal(dir, getcwd())
955 call chdir(dir)
956 call assert_equal('', glob('Xthefile'))
957endfunc
958
Bram Moolenaar1174b012021-05-29 14:30:43 +0200959" Check that buffer is written before triggering QuitPre
960func Test_wq_quitpre_autocommand()
961 edit Xsomefile
962 call setline(1, 'hello')
963 split
964 let g:seq = []
965 augroup Testing
966 au QuitPre * call add(g:seq, 'QuitPre - ' .. (&modified ? 'modified' : 'not modified'))
967 au BufWritePost * call add(g:seq, 'written')
968 augroup END
969 wq
970 call assert_equal(['written', 'QuitPre - not modified'], g:seq)
971
972 augroup Testing
973 au!
974 augroup END
975 bwipe!
976 unlet g:seq
977 call delete('Xsomefile')
978endfunc
979
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100980" vim: shiftwidth=2 sts=2 expandtab