diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index f6e8cdf762..cd5632e70c 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2028,6 +2028,8 @@ cursor({lnum}, {col} [, {off}]) cursor({list}) Number move cursor to position in {list} deepcopy({expr} [, {noref}]) any make a full copy of {expr} delete({fname} [, {flags}]) Number delete the file or directory {fname} +deletebufline({expr}, {first}[, {last}]) + Number delete lines from buffer {expr} dictwatcheradd({dict}, {pattern}, {callback}) Start watching a dictionary dictwatcherdel({dict}, {pattern}, {callback}) @@ -3209,6 +3211,17 @@ delete({fname} [, {flags}]) *delete()* The result is a Number, which is 0 if the delete operation was successful and -1 when the deletion failed or partly failed. +deletebufline({expr}, {first}[, {last}]) *deletebufline()* + Delete lines {first} to {last} (inclusive) from buffer {expr}. + If {last} is omitted then delete line {first} only. + On success 0 is returned, on failure 1 is returned. + + For the use of {expr}, see |bufname()| above. + + {first} and {last} are used like with |setline()|. Note that + when using |line()| this refers to the current buffer. Use "$" + to refer to the last line in buffer {expr}. + dictwatcheradd({dict}, {pattern}, {callback}) *dictwatcheradd()* Adds a watcher to a dictionary. A dictionary watcher is identified by three components: diff --git a/src/nvim/eval.c b/src/nvim/eval.c index f3c2e34d80..dded1a07f3 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1114,6 +1114,24 @@ static void restore_vimvar(int idx, typval_T *save_tv) } } +/* + * If there is a window for "curbuf", make it the current window. + */ + static void +find_win_for_curbuf(void) +{ + wininfo_T *wip; + + for (wip = curbuf->b_wininfo; wip != NULL; wip = wip->wi_next) + { + if (wip->wi_win != NULL) + { + curwin = wip->wi_win; + break; + } + } +} + /* * Evaluate an expression to a list with suggestions. * For the "expr:" part of 'spellsuggest'. @@ -8017,6 +8035,89 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) callback_free(&callback); } +/* + * "deletebufline()" function + */ + static void +f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + buf_T *buf; + linenr_T first, last; + linenr_T lnum; + long count; + int is_curbuf; + buf_T *curbuf_save = NULL; + win_T *curwin_save = NULL; + + buf = tv_get_buf(&argvars[0], FALSE); + if (buf == NULL) + { + rettv->vval.v_number = 1; /* FAIL */ + return; + } + is_curbuf = buf == curbuf; + + first = tv_get_lnum_buf(&argvars[1], buf); + if (argvars[2].v_type != VAR_UNKNOWN) + last = tv_get_lnum_buf(&argvars[2], buf); + else + last = first; + + if (buf->b_ml.ml_mfp == NULL || first < 1 + || first > buf->b_ml.ml_line_count || last < first) + { + rettv->vval.v_number = 1; /* FAIL */ + return; + } + + if (!is_curbuf) + { + curbuf_save = curbuf; + curwin_save = curwin; + curbuf = buf; + find_win_for_curbuf(); + } + if (last > curbuf->b_ml.ml_line_count) + last = curbuf->b_ml.ml_line_count; + count = last - first + 1; + + // When coming here from Insert mode, sync undo, so that this can be + // undone separately from what was previously inserted. + if (u_sync_once == 2) + { + u_sync_once = 1; // notify that u_sync() was called + u_sync(TRUE); + } + + if (u_save(first - 1, last + 1) == FAIL) + { + rettv->vval.v_number = 1; /* FAIL */ + return; + } + + for (lnum = first; lnum <= last; ++lnum) + ml_delete(first, TRUE); + + FOR_ALL_TAB_WINDOWS(tp, wp) + if (wp->w_buffer == buf) + { + if (wp->w_cursor.lnum > last) + wp->w_cursor.lnum -= count; + else if (wp->w_cursor.lnum> first) + wp->w_cursor.lnum = first; + if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count) + wp->w_cursor.lnum = wp->w_buffer->b_ml.ml_line_count; + } + check_cursor_col(); + deleted_lines_mark(first, count); + + if (!is_curbuf) + { + curbuf = curbuf_save; + curwin = curwin_save; + } +} + /* * "did_filetype()" function */ diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 15f392d8f1..aff1ff2a74 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -75,6 +75,7 @@ return { cursor={args={1, 3}}, deepcopy={args={1, 2}}, delete={args={1,2}}, + deletebufline={args={2,3}}, dictwatcheradd={args=3}, dictwatcherdel={args=3}, did_filetype={},