blob: 51c55d2c7f812d3a8151463618fe0fab1e35fb5a [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 Moolenaar8cf91282017-06-13 19:38:37 +02003func Test_writefile()
Bram Moolenaar19a16692016-09-01 22:19:47 +02004 let f = tempname()
Bram Moolenaardb4c9472022-10-15 22:06:06 +01005 call writefile(["over", "written"], f, "bD")
6 call writefile(["hello", "world"], f, "b")
Bram Moolenaar19a16692016-09-01 22:19:47 +02007 call writefile(["!", "good"], f, "a")
8 call writefile(["morning"], f, "ab")
9 call writefile(["", "vimmers"], f, "ab")
10 let l = readfile(f)
11 call assert_equal("hello", l[0])
12 call assert_equal("world!", l[1])
13 call assert_equal("good", l[2])
14 call assert_equal("morning", l[3])
15 call assert_equal("vimmers", l[4])
Bram Moolenaar18a2b872020-03-19 13:08:45 +010016
Bram Moolenaarb18b4962022-09-02 21:55:50 +010017 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 +020018endfunc
19
Bram Moolenaarb40c2572019-10-19 21:01:05 +020020func Test_writefile_ignore_regexp_error()
21 write Xt[z-a]est.txt
22 call delete('Xt[z-a]est.txt')
23endfunc
24
Bram Moolenaar8cf91282017-06-13 19:38:37 +020025func Test_writefile_fails_gently()
Bram Moolenaarb18b4962022-09-02 21:55:50 +010026 call assert_fails('call writefile(["test"], "Xwffile", [])', 'E730:')
27 call assert_false(filereadable("Xwffile"))
28 call delete("Xwffile")
Bram Moolenaar8cf91282017-06-13 19:38:37 +020029
Bram Moolenaarb18b4962022-09-02 21:55:50 +010030 call assert_fails('call writefile(["test", [], [], [], "tset"], "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([], "Xwffile", [])', 'E730:')
35 call assert_false(filereadable("Xwffile"))
36 call delete("Xwffile")
Bram Moolenaar8cf91282017-06-13 19:38:37 +020037
38 call assert_fails('call writefile([], [])', 'E730:')
39endfunc
Bram Moolenaare6bf6552017-06-27 22:11:51 +020040
41func Test_writefile_fails_conversion()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020042 CheckFeature iconv
43 if has('sun')
44 throw 'Skipped: does not work on SunOS'
Bram Moolenaare6bf6552017-06-27 22:11:51 +020045 endif
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020046 " Without a backup file the write won't happen if there is a conversion
47 " error.
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020048 set nobackup nowritebackup backupdir=. backupskip=
Bram Moolenaare6bf6552017-06-27 22:11:51 +020049 new
50 let contents = ["line one", "line two"]
Bram Moolenaardb4c9472022-10-15 22:06:06 +010051 call writefile(contents, 'Xwfcfile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010052 edit Xwfcfile
Bram Moolenaare6bf6552017-06-27 22:11:51 +020053 call setline(1, ["first line", "cannot convert \u010b", "third line"])
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020054 call assert_fails('write ++enc=cp932', 'E513:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010055 call assert_equal(contents, readfile('Xwfcfile'))
Bram Moolenaare6bf6552017-06-27 22:11:51 +020056
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020057 " With 'backupcopy' set, if there is a conversion error, the backup file is
58 " still created.
59 set backupcopy=yes writebackup& backup&
Bram Moolenaarb18b4962022-09-02 21:55:50 +010060 call delete('Xwfcfile' .. &backupext)
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020061 call assert_fails('write ++enc=cp932', 'E513:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010062 call assert_equal(contents, readfile('Xwfcfile'))
63 call assert_equal(contents, readfile('Xwfcfile' .. &backupext))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020064 set backupcopy&
65 %bw!
66
67 " Conversion error during write
68 new
69 call setline(1, ["\U10000000"])
Bram Moolenaarb18b4962022-09-02 21:55:50 +010070 let output = execute('write! ++enc=utf-16 Xwfcfile')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020071 call assert_match('CONVERSION ERROR', output)
Bram Moolenaarb18b4962022-09-02 21:55:50 +010072 let output = execute('write! ++enc=ucs-2 Xwfcfile')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020073 call assert_match('CONVERSION ERROR', output)
Dominique Pelleb40ad4f2022-09-04 21:29:46 +010074 call delete('Xwfcfilz~')
75 call delete('Xwfcfily~')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +020076 %bw!
77
Bram Moolenaarb18b4962022-09-02 21:55:50 +010078 call delete('Xwfcfile' .. &backupext)
Bram Moolenaare6bf6552017-06-27 22:11:51 +020079 bwipe!
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020080 set backup& writebackup& backupdir&vim backupskip&vim
Bram Moolenaare6bf6552017-06-27 22:11:51 +020081endfunc
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +020082
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020083func Test_writefile_fails_conversion2()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +020084 CheckFeature iconv
85 if has('sun')
86 throw 'Skipped: does not work on SunOS'
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020087 endif
88 " With a backup file the write happens even if there is a conversion error,
89 " but then the backup file must remain
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +020090 set nobackup writebackup backupdir=. backupskip=
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020091 let contents = ["line one", "line two"]
Bram Moolenaardb4c9472022-10-15 22:06:06 +010092 call writefile(contents, 'Xwf2file_conversion_err', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +010093 edit Xwf2file_conversion_err
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020094 call setline(1, ["first line", "cannot convert \u010b", "third line"])
95 set fileencoding=latin1
96 let output = execute('write')
97 call assert_match('CONVERSION ERROR', output)
Bram Moolenaarb18b4962022-09-02 21:55:50 +010098 call assert_equal(contents, readfile('Xwf2file_conversion_err~'))
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +020099
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100100 call delete('Xwf2file_conversion_err~')
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +0200101 bwipe!
Bram Moolenaarc28cb5b2019-05-31 20:42:09 +0200102 set backup& writebackup& backupdir&vim backupskip&vim
Bram Moolenaarcf0bfd92019-05-18 18:52:04 +0200103endfunc
104
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200105func SetFlag(timer)
106 let g:flag = 1
107endfunc
108
109func Test_write_quit_split()
110 " Prevent exiting by splitting window on file write.
111 augroup testgroup
112 autocmd BufWritePre * split
113 augroup END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100114 e! Xwqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200115 call setline(1, 'nothing')
116 wq
117
118 if has('timers')
119 " timer will not run if "exiting" is still set
120 let g:flag = 0
121 call timer_start(1, 'SetFlag')
122 sleep 50m
123 call assert_equal(1, g:flag)
124 unlet g:flag
125 endif
126 au! testgroup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100127 bwipe Xwqsfile
128 call delete('Xwqsfile')
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200129endfunc
130
131func Test_nowrite_quit_split()
132 " Prevent exiting by opening a help window.
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100133 e! Xnqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200134 help
135 wincmd w
136 exe winnr() . 'q'
137
138 if has('timers')
139 " timer will not run if "exiting" is still set
140 let g:flag = 0
141 call timer_start(1, 'SetFlag')
142 sleep 50m
143 call assert_equal(1, g:flag)
144 unlet g:flag
145 endif
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100146 bwipe Xnqsfile
Bram Moolenaar2c33d7b2017-10-14 16:06:20 +0200147endfunc
Bram Moolenaar7567d0b2017-11-16 23:04:15 +0100148
149func Test_writefile_sync_arg()
150 " This doesn't check if fsync() works, only that the argument is accepted.
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100151 call writefile(['one'], 'Xtest', 'sD')
Bram Moolenaar7567d0b2017-11-16 23:04:15 +0100152 call writefile(['two'], 'Xtest', 'S')
Bram Moolenaar7567d0b2017-11-16 23:04:15 +0100153endfunc
Bram Moolenaar83799a72017-11-25 17:24:09 +0100154
155func Test_writefile_sync_dev_stdout()
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200156 CheckUnix
Bram Moolenaar9980b372018-04-21 20:12:35 +0200157 if filewritable('/dev/stdout')
158 " Just check that this doesn't cause an error.
159 call writefile(['one'], '/dev/stdout')
160 else
161 throw 'Skipped: /dev/stdout is not writable'
162 endif
Bram Moolenaar83799a72017-11-25 17:24:09 +0100163endfunc
Bram Moolenaar8c9e7b02018-08-30 13:07:17 +0200164
165func Test_writefile_autowrite()
166 set autowrite
167 new
168 next Xa Xb Xc
169 call setline(1, 'aaa')
170 next
171 call assert_equal(['aaa'], readfile('Xa'))
172 call setline(1, 'bbb')
173 call assert_fails('edit XX')
174 call assert_false(filereadable('Xb'))
175
176 set autowriteall
177 edit XX
178 call assert_equal(['bbb'], readfile('Xb'))
179
180 bwipe!
181 call delete('Xa')
182 call delete('Xb')
183 set noautowrite
184endfunc
185
186func Test_writefile_autowrite_nowrite()
187 set autowrite
188 new
189 next Xa Xb Xc
190 set buftype=nowrite
191 call setline(1, 'aaa')
192 let buf = bufnr('%')
193 " buffer contents silently lost
194 edit XX
195 call assert_false(filereadable('Xa'))
196 rewind
197 call assert_equal('', getline(1))
198
199 bwipe!
200 set noautowrite
201endfunc
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100202
203" Test for ':w !<cmd>' to pipe lines from the current buffer to an external
204" command.
205func Test_write_pipe_to_cmd()
Bram Moolenaarea3db912020-02-02 15:32:13 +0100206 CheckUnix
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100207 new
208 call setline(1, ['L1', 'L2', 'L3', 'L4'])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100209 2,3w !cat > Xptfile
210 call assert_equal(['L2', 'L3'], readfile('Xptfile'))
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100211 close!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100212 call delete('Xptfile')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100213endfunc
214
215" Test for :saveas
216func Test_saveas()
217 call assert_fails('saveas', 'E471:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100218 call writefile(['L1'], 'Xsafile')
219 new Xsafile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100220 new
221 call setline(1, ['L1'])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100222 call assert_fails('saveas Xsafile', 'E139:')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100223 close!
224 enew | only
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100225 call delete('Xsafile')
Dominique Pellebd9e7962021-08-09 21:04:44 +0200226
227 " :saveas should detect and set the file type.
228 syntax on
229 saveas! Xsaveas.pl
230 call assert_equal('perl', &filetype)
231 syntax off
232 %bw!
233 call delete('Xsaveas.pl')
Bram Moolenaar500a1f92022-09-20 11:49:10 +0100234
235 " :saveas fails for "nofile" buffer
236 set buftype=nofile
237 call assert_fails('saveas Xsafile', 'E676: No matching autocommands for buftype=nofile buffer')
238
239 bwipe!
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100240endfunc
241
242func Test_write_errors()
243 " Test for writing partial buffer
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100244 call writefile(['L1', 'L2', 'L3'], 'Xwefile')
245 new Xwefile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100246 call assert_fails('1,2write', 'E140:')
247 close!
248
Bram Moolenaar4f5776c2020-02-12 22:15:19 +0100249 call assert_fails('w > Xtest', 'E494:')
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +0100250
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100251 " Try to overwrite a directory
252 if has('unix')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100253 call mkdir('Xwerdir1')
254 call assert_fails('write Xwerdir1', 'E17:')
255 call delete('Xwerdir1', 'd')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100256 endif
257
258 " Test for :wall for a buffer with no name
259 enew | only
260 call setline(1, ['L1'])
261 call assert_fails('wall', 'E141:')
262 enew!
263
264 " Test for writing a 'readonly' file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100265 new Xwefile
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100266 set readonly
267 call assert_fails('write', 'E45:')
268 close
269
270 " Test for writing to a read-only file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100271 new Xwefile
272 call setfperm('Xwefile', 'r--r--r--')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100273 call assert_fails('write', 'E505:')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100274 call setfperm('Xwefile', 'rw-rw-rw-')
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100275 close
276
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100277 call delete('Xwefile')
Bram Moolenaar99fa7212020-04-26 15:59:55 +0200278
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100279 call writefile(test_null_list(), 'Xwefile')
280 call assert_false(filereadable('Xwefile'))
281 call writefile(test_null_blob(), 'Xwefile')
282 call assert_false(filereadable('Xwefile'))
Bram Moolenaar99fa7212020-04-26 15:59:55 +0200283 call assert_fails('call writefile([], "")', 'E482:')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200284
285 " very long file name
286 let long_fname = repeat('n', 5000)
287 call assert_fails('exe "w " .. long_fname', 'E75:')
288 call assert_fails('call writefile([], long_fname)', 'E482:')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200289
290 " Test for writing to a block device on Unix-like systems
291 if has('unix') && getfperm('/dev/loop0') != ''
292 \ && getftype('/dev/loop0') == 'bdev' && !IsRoot()
293 new
294 edit /dev/loop0
Bram Moolenaar50157ef2021-05-15 23:21:05 +0200295 call assert_fails('write', 'E503: ')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200296 call assert_fails('write!', 'E503: ')
297 close!
298 endif
Bram Moolenaar494e9062020-05-31 21:28:02 +0200299endfunc
300
301" Test for writing to a file which is modified after Vim read it
302func Test_write_file_mtime()
303 CheckEnglish
304 CheckRunVimInTerminal
305
306 " First read the file into a buffer
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100307 call writefile(["Line1", "Line2"], 'Xwfmfile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100308 let old_ftime = getftime('Xwfmfile')
309 let buf = RunVimInTerminal('Xwfmfile', #{rows : 10})
Bram Moolenaar733d2592020-08-20 18:59:06 +0200310 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200311 call term_sendkeys(buf, ":set noswapfile\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200312 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200313
314 " Modify the file directly. Make sure the file modification time is
315 " different. Note that on Linux/Unix, the file is considered modified
316 " outside, only if the difference is 2 seconds or more
317 sleep 1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100318 call writefile(["Line3", "Line4"], 'Xwfmfile')
319 let new_ftime = getftime('Xwfmfile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200320 while new_ftime - old_ftime < 2
321 sleep 100m
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100322 call writefile(["Line3", "Line4"], 'Xwfmfile')
323 let new_ftime = getftime('Xwfmfile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200324 endwhile
325
326 " Try to overwrite the file and check for the prompt
327 call term_sendkeys(buf, ":w\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200328 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200329 call WaitForAssert({-> assert_equal("WARNING: The file has been changed since reading it!!!", term_getline(buf, 9))})
330 call assert_equal("Do you really want to write to it (y/n)?",
331 \ term_getline(buf, 10))
332 call term_sendkeys(buf, "n\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200333 call TermWait(buf)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100334 call assert_equal(new_ftime, getftime('Xwfmfile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200335 call term_sendkeys(buf, ":w\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200336 call TermWait(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200337 call term_sendkeys(buf, "y\<CR>")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200338 call TermWait(buf)
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100339 call WaitForAssert({-> assert_equal('Line2', readfile('Xwfmfile')[1])})
Bram Moolenaar494e9062020-05-31 21:28:02 +0200340
341 " clean up
342 call StopVimInTerminal(buf)
Bram Moolenaar494e9062020-05-31 21:28:02 +0200343endfunc
344
345" Test for an autocmd unloading a buffer during a write command
346func Test_write_autocmd_unloadbuf_lockmark()
347 augroup WriteTest
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100348 autocmd BufWritePre Xwaufile enew | write
Bram Moolenaar494e9062020-05-31 21:28:02 +0200349 augroup END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100350 e Xwaufile
Bram Moolenaare2e40752020-09-04 21:18:46 +0200351 call assert_fails('lockmarks write', ['E32:', 'E203:'])
Bram Moolenaar494e9062020-05-31 21:28:02 +0200352 augroup WriteTest
353 au!
354 augroup END
355 augroup! WriteTest
356endfunc
357
358" Test for writing a buffer with 'acwrite' but without autocmds
359func Test_write_acwrite_error()
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100360 new Xwaefile
Bram Moolenaar494e9062020-05-31 21:28:02 +0200361 call setline(1, ['line1', 'line2', 'line3'])
362 set buftype=acwrite
363 call assert_fails('write', 'E676:')
364 call assert_fails('1,2write!', 'E676:')
365 call assert_fails('w >>', 'E676:')
366 close!
367endfunc
368
369" Test for adding and removing lines from an autocmd when writing a buffer
370func Test_write_autocmd_add_remove_lines()
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100371 new Xwaafile
Bram Moolenaar494e9062020-05-31 21:28:02 +0200372 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
373
374 " Autocmd deleting lines from the file when writing a partial file
375 augroup WriteTest2
376 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100377 autocmd FileWritePre Xwaafile 1,2d
Bram Moolenaar494e9062020-05-31 21:28:02 +0200378 augroup END
379 call assert_fails('2,3w!', 'E204:')
380
381 " Autocmd adding lines to a file when writing a partial file
382 augroup WriteTest2
383 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100384 autocmd FileWritePre Xwaafile call append(0, ['xxx', 'yyy'])
Bram Moolenaar494e9062020-05-31 21:28:02 +0200385 augroup END
386 %d
387 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
388 1,2w!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100389 call assert_equal(['xxx', 'yyy', 'aaa', 'bbb'], readfile('Xwaafile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200390
391 " Autocmd deleting lines from the file when writing the whole file
392 augroup WriteTest2
393 au!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100394 autocmd BufWritePre Xwaafile 1,2d
Bram Moolenaar494e9062020-05-31 21:28:02 +0200395 augroup END
396 %d
397 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
398 w
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100399 call assert_equal(['ccc', 'ddd'], readfile('Xwaafile'))
Bram Moolenaar494e9062020-05-31 21:28:02 +0200400
401 augroup WriteTest2
402 au!
403 augroup END
404 augroup! WriteTest2
405
406 close!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100407 call delete('Xwaafile')
Bram Moolenaar494e9062020-05-31 21:28:02 +0200408endfunc
409
410" Test for writing to a readonly file
411func Test_write_readonly()
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100412 call writefile([], 'Xwrofile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100413 call setfperm('Xwrofile', "r--------")
414 edit Xwrofile
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200415 set noreadonly backupskip=
Bram Moolenaar494e9062020-05-31 21:28:02 +0200416 call assert_fails('write', 'E505:')
417 let save_cpo = &cpo
418 set cpo+=W
419 call assert_fails('write!', 'E504:')
420 let &cpo = save_cpo
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200421 call setline(1, ['line1'])
422 write!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100423 call assert_equal(['line1'], readfile('Xwrofile'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200424
425 " Auto-saving a readonly file should fail with 'autowriteall'
426 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100427 e Xwrofile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200428 set noreadonly autowriteall
429 call setline(1, ['aaaa'])
430 call assert_fails('n', 'E505:')
431 set cpo+=W
432 call assert_fails('n', 'E504:')
433 set cpo-=W
434 set autowriteall&
435
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200436 set backupskip&
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200437 %bw!
Bram Moolenaar5d98dc22020-01-29 21:57:34 +0100438endfunc
439
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200440" Test for 'patchmode'
441func Test_patchmode()
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100442 call writefile(['one'], 'Xpafile', 'D')
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200443 set patchmode=.orig nobackup backupskip= writebackup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100444 new Xpafile
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200445 call setline(1, 'two')
446 " first write should create the .orig file
447 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100448 call assert_equal(['one'], readfile('Xpafile.orig'))
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200449 call setline(1, 'three')
450 " subsequent writes should not create/modify the .orig file
451 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100452 call assert_equal(['one'], readfile('Xpafile.orig'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200453
454 " use 'patchmode' with 'nobackup' and 'nowritebackup' to create an empty
455 " original file
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100456 call delete('Xpafile')
457 call delete('Xpafile.orig')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200458 %bw!
459 set patchmode=.orig nobackup nowritebackup
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100460 edit Xpafile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200461 call setline(1, ['xxx'])
462 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100463 call assert_equal(['xxx'], readfile('Xpafile'))
464 call assert_equal([], readfile('Xpafile.orig'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200465
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200466 set patchmode& backup& backupskip& writebackup&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100467 call delete('Xpafile.orig')
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200468endfunc
469
470" Test for writing to a file in a readonly directory
Bram Moolenaarf9a65502021-03-05 20:47:44 +0100471" NOTE: if you run tests as root this will fail. Don't run tests as root!
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200472func Test_write_readonly_dir()
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200473 " On MS-Windows, modifying files in a read-only directory is allowed.
474 CheckUnix
Bram Moolenaar17709e22021-03-19 14:38:12 +0100475 " Root can do it too.
476 CheckNotRoot
477
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100478 call mkdir('Xrodir/', 'R')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100479 call writefile(['one'], 'Xrodir/Xfile1')
480 call setfperm('Xrodir', 'r-xr--r--')
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200481 " try to create a new file in the directory
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100482 new Xrodir/Xfile2
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200483 call setline(1, 'two')
484 call assert_fails('write', 'E212:')
485 " try to create a backup file in the directory
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100486 edit! Xrodir/Xfile1
487 set backupdir=./Xrodir backupskip=
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200488 set patchmode=.orig
489 call assert_fails('write', 'E509:')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100490 call setfperm('Xrodir', 'rwxr--r--')
Bram Moolenaarb86abad2020-08-01 16:08:19 +0200491 set backupdir& backupskip& patchmode&
Bram Moolenaar1de5f7c2020-06-11 19:22:43 +0200492endfunc
493
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200494" Test for writing a file using invalid file encoding
495func Test_write_invalid_encoding()
496 new
497 call setline(1, 'abc')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100498 call assert_fails('write ++enc=axbyc Xiefile', 'E213:')
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200499 close!
500endfunc
501
Bram Moolenaar622b3562020-07-27 20:02:41 +0200502" Tests for reading and writing files with conversion for Win32.
503func Test_write_file_encoding()
504 CheckMSWindows
505 let save_encoding = &encoding
506 let save_fileencodings = &fileencodings
K.Takataf883d902021-05-30 18:04:19 +0200507 set encoding=latin1 fileencodings&
Bram Moolenaar622b3562020-07-27 20:02:41 +0200508 let text =<< trim END
509 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
510 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
511 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
512 END
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100513 call writefile(text, 'Xwfefile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100514 edit Xwfefile
Bram Moolenaar622b3562020-07-27 20:02:41 +0200515
516 " write tests:
517 " combine three values for 'encoding' with three values for 'fileencoding'
518 " also write files for read tests
519 call cursor(1, 1)
520 set encoding=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100521 .w! ++enc=utf-8 Xwfetest
522 .w ++enc=cp1251 >> Xwfetest
523 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200524 .w! ++enc=utf-8 Xutf8
525 let expected =<< trim END
526 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
527 1 utf-8 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
528 1 utf-8 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
529 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100530 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200531
532 call cursor(2, 1)
533 set encoding=cp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100534 .w! ++enc=utf-8 Xwfetest
535 .w ++enc=cp1251 >> Xwfetest
536 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200537 .w! ++enc=cp1251 Xcp1251
538 let expected =<< trim END
539 2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
540 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
541 2 cp1251 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
542 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100543 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200544
545 call cursor(3, 1)
546 set encoding=cp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100547 .w! ++enc=utf-8 Xwfetest
548 .w ++enc=cp1251 >> Xwfetest
549 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200550 .w! ++enc=cp866 Xcp866
551 let expected =<< trim END
552 3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
553 3 cp866 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
554 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
555 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100556 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200557
558 " read three 'fileencoding's with utf-8 'encoding'
559 set encoding=utf-8 fencs=utf-8,cp1251
560 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100561 .w! ++enc=utf-8 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200562 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100563 .w ++enc=utf-8 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200564 set fencs=utf-8,cp866
565 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100566 .w ++enc=utf-8 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200567 let expected =<< trim END
568 1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
569 2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
570 3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01
571 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100572 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200573
574 " read three 'fileencoding's with cp1251 'encoding'
575 set encoding=utf-8 fencs=utf-8,cp1251
576 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100577 .w! ++enc=cp1251 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200578 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100579 .w ++enc=cp1251 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200580 set fencs=utf-8,cp866
581 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100582 .w ++enc=cp1251 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200583 let expected =<< trim END
584 1 utf-8 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
585 2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
586 3 cp866 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
587 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100588 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200589
590 " read three 'fileencoding's with cp866 'encoding'
591 set encoding=cp866 fencs=utf-8,cp1251
592 e Xutf8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100593 .w! ++enc=cp866 Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200594 e Xcp1251
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100595 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200596 set fencs=utf-8,cp866
597 e Xcp866
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100598 .w ++enc=cp866 >> Xwfetest
Bram Moolenaar622b3562020-07-27 20:02:41 +0200599 let expected =<< trim END
600 1 utf-8 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
601 2 cp1251 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
602 3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
603 END
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100604 call assert_equal(expected, readfile('Xwfetest'))
Bram Moolenaar622b3562020-07-27 20:02:41 +0200605
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100606 call delete('Xwfetest')
Bram Moolenaar622b3562020-07-27 20:02:41 +0200607 call delete('Xutf8')
608 call delete('Xcp1251')
609 call delete('Xcp866')
610 let &encoding = save_encoding
611 let &fileencodings = save_fileencodings
612 %bw!
613endfunc
614
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200615" Test for writing and reading a file starting with a BOM.
616" Byte Order Mark (BOM) character for various encodings is below:
617" UTF-8 : EF BB BF
618" UTF-16 (BE): FE FF
619" UTF-16 (LE): FF FE
620" UTF-32 (BE): 00 00 FE FF
621" UTF-32 (LE): FF FE 00 00
622func Test_readwrite_file_with_bom()
623 let utf8_bom = "\xEF\xBB\xBF"
624 let utf16be_bom = "\xFE\xFF"
625 let utf16le_bom = "\xFF\xFE"
626 let utf32be_bom = "\n\n\xFE\xFF"
627 let utf32le_bom = "\xFF\xFE\n\n"
628 let save_fileencoding = &fileencoding
629 set cpoptions+=S
630
631 " Check that editing a latin1 file doesn't see a BOM
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100632 call writefile(["\xFE\xFElatin-1"], 'Xrwtest1', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100633 edit Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200634 call assert_equal('latin1', &fileencoding)
635 call assert_equal(0, &bomb)
636 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100637 write Xrwfile2
638 call assert_equal(["\xFE\xFElatin-1", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200639 set bomb fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100640 write Xrwtest3
641 call assert_equal(["\xFE\xFElatin-1", ''], readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200642 set bomb&
643
644 " Check utf-8 BOM
645 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100646 call writefile([utf8_bom .. "utf-8"], 'Xrwtest1')
647 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200648 call assert_equal('utf-8', &fileencoding)
649 call assert_equal(1, &bomb)
650 call assert_equal('utf-8', getline(1))
651 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100652 write! Xrwfile2
653 call assert_equal(['utf-8', ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200654 set fenc=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100655 w! Xrwtest3
656 call assert_equal([utf8_bom .. "utf-8", ''], readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200657
658 " Check utf-8 with an error (will fall back to latin-1)
659 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100660 call writefile([utf8_bom .. "utf-8\x80err"], 'Xrwtest1')
661 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200662 call assert_equal('latin1', &fileencoding)
663 call assert_equal(0, &bomb)
664 call assert_equal("\xC3\xAF\xC2\xBB\xC2\xBFutf-8\xC2\x80err", getline(1))
665 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100666 write! Xrwfile2
667 call assert_equal([utf8_bom .. "utf-8\x80err", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200668 set fenc=utf-8
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100669 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200670 call assert_equal(["\xC3\xAF\xC2\xBB\xC2\xBFutf-8\xC2\x80err", ''],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100671 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200672
673 " Check ucs-2 BOM
674 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100675 call writefile([utf16be_bom .. "\nu\nc\ns\n-\n2\n"], 'Xrwtest1')
676 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200677 call assert_equal('utf-16', &fileencoding)
678 call assert_equal(1, &bomb)
679 call assert_equal('ucs-2', getline(1))
680 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100681 write! Xrwfile2
682 call assert_equal(["ucs-2", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200683 set fenc=ucs-2
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100684 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200685 call assert_equal([utf16be_bom .. "\nu\nc\ns\n-\n2\n", ''],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100686 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200687
688 " Check ucs-2le BOM
689 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100690 call writefile([utf16le_bom .. "u\nc\ns\n-\n2\nl\ne\n"], 'Xrwtest1')
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200691 " Need to add a NUL byte after the NL byte
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100692 call writefile(0z00, 'Xrwtest1', 'a')
693 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200694 call assert_equal('utf-16le', &fileencoding)
695 call assert_equal(1, &bomb)
696 call assert_equal('ucs-2le', getline(1))
697 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100698 write! Xrwfile2
699 call assert_equal(["ucs-2le", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200700 set fenc=ucs-2le
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100701 w! Xrwtest3
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200702 call assert_equal([utf16le_bom .. "u\nc\ns\n-\n2\nl\ne\n", "\n"],
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100703 \ readfile('Xrwtest3', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200704
705 " Check ucs-4 BOM
706 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100707 call writefile([utf32be_bom .. "\n\n\nu\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\n"], 'Xrwtest1')
708 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200709 call assert_equal('ucs-4', &fileencoding)
710 call assert_equal(1, &bomb)
711 call assert_equal('ucs-4', getline(1))
712 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100713 write! Xrwfile2
714 call assert_equal(["ucs-4", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200715 set fenc=ucs-4
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100716 w! Xrwtest3
717 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 +0200718
719 " Check ucs-4le BOM
720 %bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100721 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 +0200722 " Need to add three NUL bytes after the NL byte
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100723 call writefile(0z000000, 'Xrwtest1', 'a')
724 edit! Xrwtest1
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200725 call assert_equal('ucs-4le', &fileencoding)
726 call assert_equal(1, &bomb)
727 call assert_equal('ucs-4le', getline(1))
728 set fenc=latin1
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100729 write! Xrwfile2
730 call assert_equal(["ucs-4le", ''], readfile('Xrwfile2', 'b'))
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200731 set fenc=ucs-4le
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100732 w! Xrwtest3
733 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 +0200734
735 set cpoptions-=S
736 let &fileencoding = save_fileencoding
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100737 call delete('Xrwfile2')
738 call delete('Xrwtest3')
Bram Moolenaarb61ef012020-07-29 16:08:21 +0200739 %bw!
740endfunc
741
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100742func Test_read_write_bin()
743 " write file missing EOL
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100744 call writefile(['noeol'], "XNoEolSetEol", 'bSD')
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100745 call assert_equal(0z6E6F656F6C, readfile('XNoEolSetEol', 'B'))
746
747 " when file is read 'eol' is off
Bram Moolenaar16204962020-12-23 22:40:11 +0100748 set nofixeol
749 e! ++ff=unix XNoEolSetEol
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100750 call assert_equal(0, &eol)
751
752 " writing with 'eol' set adds the newline
753 setlocal eol
754 w
755 call assert_equal(0z6E6F656F6C0A, readfile('XNoEolSetEol', 'B'))
756
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200757 set ff& fixeol&
Bram Moolenaarbd318552020-12-23 20:55:15 +0100758 bwipe! XNoEolSetEol
Bram Moolenaarb3c8b1d2020-12-23 18:54:57 +0100759endfunc
760
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200761" Test for the 'backupcopy' option when writing files
762func Test_backupcopy()
763 CheckUnix
764 set backupskip=
765 " With the default 'backupcopy' setting, saving a symbolic link file
766 " should not break the link.
767 set backupcopy&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100768 call writefile(['1111'], 'Xbcfile1')
769 silent !ln -s Xbcfile1 Xbcfile2
770 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200771 call setline(1, ['2222'])
772 write
773 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100774 call assert_equal(['2222'], readfile('Xbcfile1'))
775 call assert_equal('Xbcfile1', resolve('Xbcfile2'))
776 call assert_equal('link', getftype('Xbcfile2'))
777 call delete('Xbcfile1')
778 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200779
780 " With the 'backupcopy' set to 'breaksymlink', saving a symbolic link file
781 " should break the link.
782 set backupcopy=yes,breaksymlink
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100783 call writefile(['1111'], 'Xbcfile1')
784 silent !ln -s Xbcfile1 Xbcfile2
785 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200786 call setline(1, ['2222'])
787 write
788 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100789 call assert_equal(['1111'], readfile('Xbcfile1'))
790 call assert_equal(['2222'], readfile('Xbcfile2'))
791 call assert_equal('Xbcfile2', resolve('Xbcfile2'))
792 call assert_equal('file', getftype('Xbcfile2'))
793 call delete('Xbcfile1')
794 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200795 set backupcopy&
796
797 " With the default 'backupcopy' setting, saving a hard link file
798 " should not break the link.
799 set backupcopy&
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100800 call writefile(['1111'], 'Xbcfile1')
801 silent !ln Xbcfile1 Xbcfile2
802 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200803 call setline(1, ['2222'])
804 write
805 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100806 call assert_equal(['2222'], readfile('Xbcfile1'))
807 call delete('Xbcfile1')
808 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200809
810 " With the 'backupcopy' set to 'breaksymlink', saving a hard link file
811 " should break the link.
812 set backupcopy=yes,breakhardlink
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100813 call writefile(['1111'], 'Xbcfile1')
814 silent !ln Xbcfile1 Xbcfile2
815 new Xbcfile2
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200816 call setline(1, ['2222'])
817 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100818 call assert_equal(['1111'], readfile('Xbcfile1'))
819 call assert_equal(['2222'], readfile('Xbcfile2'))
820 call delete('Xbcfile1')
821 call delete('Xbcfile2')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200822
823 " If a backup file is already present, then a slightly modified filename
824 " should be used as the backup file. Try with 'backupcopy' set to 'yes' and
825 " 'no'.
826 %bw
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100827 call writefile(['aaaa'], 'Xbcfile')
828 call writefile(['bbbb'], 'Xbcfile.bak')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200829 set backupcopy=yes backupext=.bak
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100830 new Xbcfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200831 call setline(1, ['cccc'])
832 write
833 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100834 call assert_equal(['cccc'], readfile('Xbcfile'))
835 call assert_equal(['bbbb'], readfile('Xbcfile.bak'))
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200836 set backupcopy=no backupext=.bak
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100837 new Xbcfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200838 call setline(1, ['dddd'])
839 write
840 close
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100841 call assert_equal(['dddd'], readfile('Xbcfile'))
842 call assert_equal(['bbbb'], readfile('Xbcfile.bak'))
843 call delete('Xbcfile')
844 call delete('Xbcfile.bak')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200845
846 " Write to a device file (in Unix-like systems) which cannot be backed up.
847 if has('unix')
848 set writebackup backupcopy=yes nobackup
849 new
850 call setline(1, ['aaaa'])
851 let output = execute('write! /dev/null')
852 call assert_match('"/dev/null" \[Device]', output)
853 close
854 set writebackup backupcopy=no nobackup
855 new
856 call setline(1, ['aaaa'])
857 let output = execute('write! /dev/null')
858 call assert_match('"/dev/null" \[Device]', output)
859 close
860 set backup writebackup& backupcopy&
861 new
862 call setline(1, ['aaaa'])
863 let output = execute('write! /dev/null')
864 call assert_match('"/dev/null" \[Device]', output)
865 close
866 endif
867
868 set backupcopy& backupskip& backupext& backup&
869endfunc
870
871" Test for writing a file with 'encoding' set to 'utf-16'
872func Test_write_utf16()
873 new
874 call setline(1, ["\U00010001"])
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100875 write ++enc=utf-16 Xw16file
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200876 bw!
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100877 call assert_equal(0zD800DC01, readfile('Xw16file', 'B')[0:3])
878 call delete('Xw16file')
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200879endfunc
880
881" Test for trying to save a backup file when the backup file is a symbolic
882" link to the original file. The backup file should not be modified.
883func Test_write_backup_symlink()
884 CheckUnix
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000885 call mkdir('Xbackup')
886 let save_backupdir = &backupdir
887 set backupdir=.,./Xbackup
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100888 call writefile(['1111'], 'Xwbsfile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100889 silent !ln -s Xwbsfile Xwbsfile.bak
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200890
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100891 new Xwbsfile
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200892 set backup backupcopy=yes backupext=.bak
893 write
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100894 call assert_equal('link', getftype('Xwbsfile.bak'))
895 call assert_equal('Xwbsfile', resolve('Xwbsfile.bak'))
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000896 " backup file should be created in the 'backup' directory
897 if !has('bsd')
898 " This check fails on FreeBSD
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100899 call assert_true(filereadable('./Xbackup/Xwbsfile.bak'))
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000900 endif
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200901 set backup& backupcopy& backupext&
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000902 %bw
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200903
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100904 call delete('Xwbsfile.bak')
Bram Moolenaar6e2e2cc2022-03-14 19:24:46 +0000905 call delete('Xbackup', 'rf')
906 let &backupdir = save_backupdir
Yegappan Lakshmanan36f96a52021-05-13 18:33:16 +0200907endfunc
908
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200909" Test for ':write ++bin' and ':write ++nobin'
910func Test_write_binary_file()
911 " create a file without an eol/eof character
Bram Moolenaardb4c9472022-10-15 22:06:06 +0100912 call writefile(0z616161, 'Xwbfile1', 'bD')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100913 new Xwbfile1
914 write ++bin Xwbfile2
915 write ++nobin Xwbfile3
916 call assert_equal(0z616161, readblob('Xwbfile2'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200917 if has('win32')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100918 call assert_equal(0z6161610D.0A, readblob('Xwbfile3'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200919 else
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100920 call assert_equal(0z6161610A, readblob('Xwbfile3'))
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200921 endif
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100922 call delete('Xwbfile2')
923 call delete('Xwbfile3')
Yegappan Lakshmanan46aa6f92021-05-19 17:15:04 +0200924endfunc
925
Bram Moolenaar806a2732022-09-04 15:40:36 +0100926func DoWriteDefer()
927 call writefile(['some text'], 'XdeferDelete', 'D')
928 call assert_equal(['some text'], readfile('XdeferDelete'))
929endfunc
930
931def DefWriteDefer()
932 writefile(['some text'], 'XdefdeferDelete', 'D')
933 assert_equal(['some text'], readfile('XdefdeferDelete'))
934enddef
935
936func Test_write_with_deferred_delete()
937 call DoWriteDefer()
938 call assert_equal('', glob('XdeferDelete'))
939 call DefWriteDefer()
940 call assert_equal('', glob('XdefdeferDelete'))
941endfunc
942
Bram Moolenaar6f14da12022-09-07 21:30:44 +0100943func DoWriteFile()
944 call writefile(['text'], 'Xthefile', 'D')
945 cd ..
946endfunc
947
948func Test_write_defer_delete_chdir()
949 let dir = getcwd()
950 call DoWriteFile()
951 call assert_notequal(dir, getcwd())
952 call chdir(dir)
953 call assert_equal('', glob('Xthefile'))
954endfunc
955
Bram Moolenaar1174b012021-05-29 14:30:43 +0200956" Check that buffer is written before triggering QuitPre
957func Test_wq_quitpre_autocommand()
958 edit Xsomefile
959 call setline(1, 'hello')
960 split
961 let g:seq = []
962 augroup Testing
963 au QuitPre * call add(g:seq, 'QuitPre - ' .. (&modified ? 'modified' : 'not modified'))
964 au BufWritePost * call add(g:seq, 'written')
965 augroup END
966 wq
967 call assert_equal(['written', 'QuitPre - not modified'], g:seq)
968
969 augroup Testing
970 au!
971 augroup END
972 bwipe!
973 unlet g:seq
974 call delete('Xsomefile')
975endfunc
976
Christian Brabandte085dfd2023-09-30 12:49:18 +0200977func Test_write_with_xattr_support()
978 CheckLinux
zeertzjq6de4e582023-09-30 14:19:14 +0200979 CheckFeature xattr
Christian Brabandte085dfd2023-09-30 12:49:18 +0200980 CheckExecutable setfattr
981
982 let contents = ["file with xattrs", "line two"]
983 call writefile(contents, 'Xwattr.txt', 'D')
984 " write a couple of xattr
985 call system('setfattr -n user.cookie -v chocolate Xwattr.txt')
986 call system('setfattr -n user.frieda -v bar Xwattr.txt')
987 call system('setfattr -n user.empty Xwattr.txt')
988
989 set backupcopy=no writebackup& backup&
990 sp Xwattr.txt
991 w
992 $r! getfattr -d %
993 let expected = ['file with xattrs', 'line two', '# file: Xwattr.txt', 'user.cookie="chocolate"', 'user.empty=""', 'user.frieda="bar"', '']
994 call assert_equal(expected, getline(1,'$'))
995
996 set backupcopy&
997 bw!
Christian Brabandte085dfd2023-09-30 12:49:18 +0200998endfunc
999
Bram Moolenaar5d98dc22020-01-29 21:57:34 +01001000" vim: shiftwidth=2 sts=2 expandtab