aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/api/buffer.c5
-rw-r--r--src/nvim/option.c1
-rw-r--r--src/nvim/testdir/test_autocmd.vim2
-rw-r--r--src/nvim/undo.c11
-rw-r--r--test/functional/api/buffer_spec.lua7
5 files changed, 19 insertions, 7 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 41d7d8ba6b..690497159a 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -453,6 +453,11 @@ void nvim_buf_set_lines(uint64_t channel_id,
aco_save_T aco;
aucmd_prepbuf(&aco, (buf_T *)buf);
+ if (!MODIFIABLE(buf)) {
+ api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
+ goto end;
+ }
+
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to save undo information");
goto end;
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 04349414a2..d1753526a7 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -6985,6 +6985,7 @@ void save_file_ff(buf_T *buf)
/// When "ignore_empty" is true don't consider a new, empty buffer to be
/// changed.
bool file_ff_differs(buf_T *buf, bool ignore_empty)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
// In a buffer that was never loaded the options are not valid.
if (buf->b_flags & BF_NEVERLOADED) {
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 16bacf4591..5848940a2b 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -1343,6 +1343,8 @@ func Test_Changed_FirstTime()
call writefile([''], 'Xchanged.txt')
let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
call assert_equal('running', term_getstatus(buf))
+ " Wait for the ruler (in the status line) to be shown.
+ call WaitFor({-> term_getline(buf, 3) =~# '\<All$'})
" It's only adding autocmd, so that no event occurs.
call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>")
call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 1a31f6a6c7..c8343941d2 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -2962,7 +2962,7 @@ static char_u *u_save_line(linenr_T lnum)
///
/// @return true if the buffer has changed
bool bufIsChanged(buf_T *buf)
- FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
return !bt_dontwrite(buf) && (buf->b_changed || file_ff_differs(buf, true));
}
@@ -2979,15 +2979,12 @@ bool anyBufIsChanged(void)
return false;
}
-/// Check if the 'modified' flag is set, or 'ff' has changed (only need to
-/// check the first character, because it can only be "dos", "unix" or "mac").
-/// "nofile" and "scratch" type buffers are considered to always be unchanged.
-///
+/// @see bufIsChanged
/// @return true if the current buffer has changed
bool curbufIsChanged(void)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
- return (!bt_dontwrite(curbuf)
- && (curbuf->b_changed || file_ff_differs(curbuf, true)));
+ return bufIsChanged(curbuf);
}
/// Append the list of undo blocks to a newly allocated list
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua
index 9d6cfb99ab..849fbedd01 100644
--- a/test/functional/api/buffer_spec.lua
+++ b/test/functional/api/buffer_spec.lua
@@ -14,6 +14,7 @@ local meth_pcall = helpers.meth_pcall
local command = helpers.command
local bufmeths = helpers.bufmeths
local feed = helpers.feed
+local expect_err = helpers.expect_err
describe('api/buf', function()
before_each(clear)
@@ -197,6 +198,12 @@ describe('api/buf', function()
eq(': ' .. exp_emsg, emsg:sub(-#exp_emsg - 2))
end)
+ it("fails if 'nomodifiable'", function()
+ command('set nomodifiable')
+ expect_err([[Buffer is not 'modifiable']],
+ bufmeths.set_lines, 1, 1, 2, false, {'a','b'})
+ end)
+
it('has correct line_count when inserting and deleting', function()
eq(1, line_count())
set_lines(-1, -1, true, {'line'})