feat: ":write!" skips "file changed" warning #18665

Problem:
Cannot opt-out of "WARNING: The file has been changed since reading
it!!!", even with ":write!".

Solution:
Change ":write!" to skip the warning.

closes #7270
This commit is contained in:
Louis Sven Goulet 2022-09-24 21:57:10 -04:00 committed by GitHub
parent c7cf1232a7
commit 2a3cb0893b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 5 deletions

View File

@ -941,7 +941,7 @@ WRITING WITH MULTIPLE BUFFERS *buffer-write*
Vim will warn you if you try to overwrite a file that has been changed
elsewhere. See |timestamp|.
elsewhere (unless "!" was used). See |timestamp|.
*backup* *E207* *E506* *E507* *E508* *E509* *E510*
If you write to an existing file (but do not append) while the 'backup',
@ -1481,8 +1481,8 @@ doing something there and closing it should be OK (if there are no side
effects from other autocommands). Closing unrelated windows and buffers will
get you into trouble.
Before writing a file the timestamp is checked. If it has changed, Vim will
ask if you really want to overwrite the file:
Before writing a file, the timestamp is checked (unless "!" was used).
If it has changed, Vim will ask if you really want to overwrite the file:
WARNING: The file has been changed since reading it!!!
Do you really want to write to it (y/n)?

View File

@ -372,6 +372,7 @@ Lua interface (|lua.txt|):
Commands:
|:doautocmd| does not warn about "No matching autocommands".
|:wincmd| accepts a count.
`:write!` does not show a prompt if the file was updated externally.
Command line completion:
The meanings of arrow keys do not change depending on 'wildoptions'.

View File

@ -2536,8 +2536,8 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
goto fail;
}
// Check if the timestamp hasn't changed since reading the file.
if (overwriting) {
// If 'forceit' is false, check if the timestamp hasn't changed since reading the file.
if (overwriting && !forceit) {
retval = check_mtime(buf, &file_info_old);
if (retval == FAIL) {
goto fail;

View File

@ -23,6 +23,8 @@ local iswin = helpers.iswin
local assert_alive = helpers.assert_alive
local expect_exit = helpers.expect_exit
local write_file = helpers.write_file
local Screen = require('test.functional.ui.screen')
local feed_command = helpers.feed_command
local uname = helpers.uname
describe('fileio', function()
@ -36,6 +38,7 @@ describe('fileio', function()
os.remove('Xtest_startup_file2')
os.remove('Xtest_тест.md')
os.remove('Xtest-u8-int-max')
os.remove('Xtest-overwrite-forced')
rmdir('Xtest_startup_swapdir')
rmdir('Xtest_backupdir')
end)
@ -151,6 +154,61 @@ describe('fileio', function()
command('edit ++enc=utf32 Xtest-u8-int-max')
assert_alive()
end)
it(':w! does not show "file has been changed" warning', function()
clear()
write_file("Xtest-overwrite-forced", 'foobar')
command('set nofixendofline')
local screen = Screen.new(40,4)
screen:set_default_attr_ids({
[1] = {bold = true, foreground = Screen.colors.Blue1},
[2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
[3] = {bold = true, foreground = Screen.colors.SeaGreen4}
})
screen:attach()
command("set display-=msgsep shortmess-=F")
command("e Xtest-overwrite-forced")
screen:expect([[
^foobar |
{1:~ }|
{1:~ }|
"Xtest-overwrite-forced" [noeol] 1L, 6B |
]])
-- Get current unix time.
local cur_unix_time = os.time(os.date("!*t"))
local future_time = cur_unix_time + 999999
-- Set the file's access/update time to be
-- greater than the time at which it was created.
local uv = require("luv")
uv.fs_utime('Xtest-overwrite-forced', future_time, future_time)
-- use async feed_command because nvim basically hangs on the prompt
feed_command("w")
screen:expect([[
{2:WARNING: The file has been changed since}|
{2: reading it!!!} |
{3:Do you really want to write to it (y/n)^?}|
|
]])
feed("n")
feed("<cr>")
screen:expect([[
^foobar |
{1:~ }|
{1:~ }|
|
]])
-- Use a screen test because the warning does not set v:errmsg.
command("w!")
screen:expect([[
^foobar |
{1:~ }|
{1:~ }|
<erwrite-forced" [noeol] 1L, 6B written |
]])
end)
end)
describe('tmpdir', function()