mirror of
https://github.com/neovim/neovim.git
synced 2026-05-24 05:40:08 +00:00
vim-patch:9.1.2024: 'fsync' option cannot be set per buffer (#37129)
Problem: 'fsync' option cannot be set per buffer
Solution: Make 'fsync' option global-local
(glepnir)
closes: vim/vim#19019
4d5b303726
Co-authored-by: glepnir <glephunter@gmail.com>
This commit is contained in:
@@ -326,7 +326,7 @@ OPTIONS
|
||||
• 'diffanchors' specifies addresses to anchor a diff.
|
||||
• 'diffopt' `inline:` configures diff highlighting for changes within a line.
|
||||
• 'fillchars' has new flag "foldinner".
|
||||
• 'grepformat' is now a |global-local| option.
|
||||
• 'fsync' and 'grepformat' are now |global-local| options.
|
||||
• 'jumpoptions' flag "view" now applies when popping the |tagstack|.
|
||||
• 'maxsearchcount' sets maximum value for |searchcount()| and defaults to 999.
|
||||
• 'pummaxwidth' sets maximum width for the completion popup menu.
|
||||
|
||||
@@ -3197,7 +3197,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|
||||
*'fsync'* *'fs'* *'nofsync'* *'nofs'*
|
||||
'fsync' 'fs' boolean (default on)
|
||||
global
|
||||
global or local to buffer |global-local|
|
||||
When on, the OS function fsync() will be called after saving a file
|
||||
(|:write|, |writefile()|, …), |swap-file|, |undo-persistence| and |shada-file|.
|
||||
This flushes the file to disk, ensuring that it is safely written.
|
||||
@@ -3210,6 +3210,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
- system signals low battery life
|
||||
- Nvim exits abnormally
|
||||
|
||||
This is a |global-local| option, so it can be set per buffer, for
|
||||
example when writing to a slow filesystem.
|
||||
This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||
security reasons.
|
||||
|
||||
|
||||
4
runtime/lua/vim/_meta/options.lua
generated
4
runtime/lua/vim/_meta/options.lua
generated
@@ -3002,12 +3002,16 @@ vim.go.fp = vim.go.formatprg
|
||||
--- - system signals low battery life
|
||||
--- - Nvim exits abnormally
|
||||
---
|
||||
--- This is a `global-local` option, so it can be set per buffer, for
|
||||
--- example when writing to a slow filesystem.
|
||||
--- This option cannot be set from a `modeline` or in the `sandbox`, for
|
||||
--- security reasons.
|
||||
---
|
||||
--- @type boolean
|
||||
vim.o.fsync = true
|
||||
vim.o.fs = vim.o.fsync
|
||||
vim.bo.fsync = vim.o.fsync
|
||||
vim.bo.fs = vim.bo.fsync
|
||||
vim.go.fsync = vim.o.fsync
|
||||
vim.go.fs = vim.go.fsync
|
||||
|
||||
|
||||
@@ -2145,6 +2145,7 @@ void free_buf_options(buf_T *buf, bool free_p_ff)
|
||||
clear_string_option(&buf->b_p_qe);
|
||||
buf->b_p_ac = -1;
|
||||
buf->b_p_ar = -1;
|
||||
buf->b_p_fs = -1;
|
||||
buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
|
||||
clear_string_option(&buf->b_p_lw);
|
||||
clear_string_option(&buf->b_p_bkc);
|
||||
|
||||
@@ -586,6 +586,7 @@ struct file_buffer {
|
||||
char *b_p_fp; ///< 'formatprg'
|
||||
char *b_p_fex; ///< 'formatexpr'
|
||||
uint32_t b_p_fex_flags; ///< flags for 'formatexpr'
|
||||
int b_p_fs; ///< 'fsync'
|
||||
char *b_p_kp; ///< 'keywordprg'
|
||||
int b_p_lisp; ///< 'lisp'
|
||||
char *b_p_lop; ///< 'lispoptions'
|
||||
|
||||
@@ -1226,7 +1226,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
||||
// the original file.
|
||||
// Don't do this if there is a backup file and we are exiting.
|
||||
if (reset_changed && !newfile && overwriting && !(exiting && backup != NULL)) {
|
||||
ml_preserve(buf, false, !!p_fs);
|
||||
ml_preserve(buf, false, !!(buf->b_p_fs >= 0 ? buf->b_p_fs : p_fs));
|
||||
if (got_int) {
|
||||
err = set_err(_(e_interr));
|
||||
goto restore_backup;
|
||||
@@ -1575,9 +1575,9 @@ restore_backup:
|
||||
// (could be a pipe).
|
||||
// If the 'fsync' option is false, don't fsync(). Useful for laptops.
|
||||
int error;
|
||||
if (p_fs && (error = os_fsync(fd)) != 0 && !device
|
||||
if ((buf->b_p_fs >= 0 ? buf->b_p_fs : p_fs) && (error = os_fsync(fd)) != 0
|
||||
// fsync not supported on this storage.
|
||||
&& error != UV_ENOTSUP) {
|
||||
&& error != UV_ENOTSUP && !device) {
|
||||
err = set_err_arg(e_fsync, error);
|
||||
end = 0;
|
||||
}
|
||||
|
||||
@@ -387,6 +387,7 @@ void set_init_1(bool clean_arg)
|
||||
curbuf->b_p_initialized = true;
|
||||
curbuf->b_p_ac = -1;
|
||||
curbuf->b_p_ar = -1; // no local 'autoread' value
|
||||
curbuf->b_p_fs = -1; // no local 'fsync' value
|
||||
curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
|
||||
check_buf_options(curbuf);
|
||||
check_win_options(curwin);
|
||||
@@ -3391,6 +3392,7 @@ static OptVal get_option_unset_value(OptIndex opt_idx)
|
||||
switch (opt_idx) {
|
||||
case kOptAutocomplete:
|
||||
case kOptAutoread:
|
||||
case kOptFsync:
|
||||
return BOOLEAN_OPTVAL(kNone);
|
||||
case kOptScrolloff:
|
||||
case kOptSidescrolloff:
|
||||
@@ -4434,6 +4436,8 @@ void *get_varp_scope_from(vimoption_T *p, int opt_flags, buf_T *buf, win_T *win)
|
||||
switch (opt_idx) {
|
||||
case kOptFormatprg:
|
||||
return &(buf->b_p_fp);
|
||||
case kOptFsync:
|
||||
return &(buf->b_p_fs);
|
||||
case kOptFindfunc:
|
||||
return &(buf->b_p_ffu);
|
||||
case kOptErrorformat:
|
||||
@@ -4567,6 +4571,8 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win)
|
||||
return *buf->b_p_tsrfu != NUL ? &(buf->b_p_tsrfu) : p->var;
|
||||
case kOptFormatprg:
|
||||
return *buf->b_p_fp != NUL ? &(buf->b_p_fp) : p->var;
|
||||
case kOptFsync:
|
||||
return buf->b_p_fs >= 0 ? &(buf->b_p_fs) : p->var;
|
||||
case kOptFindfunc:
|
||||
return *buf->b_p_ffu != NUL ? &(buf->b_p_ffu) : p->var;
|
||||
case kOptErrorformat:
|
||||
@@ -5241,6 +5247,7 @@ void buf_copy_options(buf_T *buf, int flags)
|
||||
// are not copied, start using the global value
|
||||
buf->b_p_ac = -1;
|
||||
buf->b_p_ar = -1;
|
||||
buf->b_p_fs = -1;
|
||||
buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
|
||||
buf->b_p_bkc = empty_string_option;
|
||||
buf->b_bkc_flags = 0;
|
||||
|
||||
@@ -3813,11 +3813,13 @@ local options = {
|
||||
- system signals low battery life
|
||||
- Nvim exits abnormally
|
||||
|
||||
This is a |global-local| option, so it can be set per buffer, for
|
||||
example when writing to a slow filesystem.
|
||||
This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||
security reasons.
|
||||
]=],
|
||||
full_name = 'fsync',
|
||||
scope = { 'global' },
|
||||
scope = { 'global', 'buf' },
|
||||
secure = true,
|
||||
short_desc = N_('whether to invoke fsync() after file write'),
|
||||
type = 'boolean',
|
||||
|
||||
@@ -1340,7 +1340,8 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_fs && fflush(fp) == 0 && os_fsync(fd) != 0) {
|
||||
if ((buf->b_p_fs >= 0 ? buf->b_p_fs : p_fs) && fflush(fp) == 0
|
||||
&& os_fsync(fd) != 0) {
|
||||
write_ok = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1662,27 +1662,36 @@ endfunc
|
||||
|
||||
" Test for setting boolean global-local option value
|
||||
func Test_set_boolean_global_local_option()
|
||||
setglobal autoread
|
||||
setlocal noautoread
|
||||
CheckUnix
|
||||
|
||||
setglobal autoread fsync
|
||||
setlocal noautoread nofsync
|
||||
call assert_equal(1, &g:autoread)
|
||||
call assert_equal(0, &l:autoread)
|
||||
call assert_equal(0, &autoread)
|
||||
call assert_equal(1, &g:fsync)
|
||||
call assert_equal(0, &l:fsync)
|
||||
call assert_equal(0, &fsync)
|
||||
|
||||
" :setlocal {option}< set the effective value of {option} to its global value.
|
||||
"set autoread<
|
||||
setlocal autoread<
|
||||
"set autoread< fsync<
|
||||
setlocal autoread< fsync<
|
||||
call assert_equal(1, &l:autoread)
|
||||
call assert_equal(1, &autoread)
|
||||
call assert_equal(1, &l:fsync)
|
||||
call assert_equal(1, &fsync)
|
||||
|
||||
" :set {option}< removes the local value, so that the global value will be used.
|
||||
setglobal noautoread
|
||||
setlocal autoread
|
||||
"setlocal autoread<
|
||||
set autoread<
|
||||
setglobal noautoread nofsync
|
||||
setlocal autoread fsync
|
||||
"setlocal autoread< fsync<
|
||||
set autoread< fsync<
|
||||
call assert_equal(-1, &l:autoread)
|
||||
call assert_equal(0, &autoread)
|
||||
call assert_equal(-1, &l:fsync)
|
||||
call assert_equal(0, &fsync)
|
||||
|
||||
set autoread&
|
||||
set autoread& fsync&
|
||||
endfunc
|
||||
|
||||
func Test_set_in_sandbox()
|
||||
|
||||
Reference in New Issue
Block a user