aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
authorAndrej Zieger <jerdna-regeiz@users.noreply.github.com>2019-05-21 21:50:59 +0200
committerAndrej Zieger <jerdna-regeiz@users.noreply.github.com>2019-05-26 19:32:32 +0200
commit237cecd81b83dcbdac05b208ea6adc3357039858 (patch)
treed18a7216e74f7fe28841c4ad2909016c326ceda4 /src/nvim/eval.c
parent8df9213d1b6ed804fb883073e012b82d26080963 (diff)
downloadrneovim-237cecd81b83dcbdac05b208ea6adc3357039858.tar.gz
rneovim-237cecd81b83dcbdac05b208ea6adc3357039858.tar.bz2
rneovim-237cecd81b83dcbdac05b208ea6adc3357039858.zip
vim-patch:8.1.0039: cannot easily delete lines in another buffer
Problem: Cannot easily delete lines in another buffer. Solution: Add deletebufline(). https://github.com/vim/vim/commit/d79a26219d7161e9211fd144f0e874aa5f6d251e
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c101
1 files changed, 101 insertions, 0 deletions
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
@@ -1115,6 +1115,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'.
* Returns NULL when there is an error.
@@ -8018,6 +8036,89 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
/*
+ * "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
*/
static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr)