From 237cecd81b83dcbdac05b208ea6adc3357039858 Mon Sep 17 00:00:00 2001 From: Andrej Zieger Date: Tue, 21 May 2019 21:50:59 +0200 Subject: 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 --- src/nvim/eval.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nvim/eval.lua | 1 + 2 files changed, 102 insertions(+) (limited to 'src') 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={}, -- cgit