Attached patch implements the delbufline() function. That should address 
all the previous complaints. I did intentionally not add a delline() 
function, because I thought the gain would be dubious.

Best,
Christian
-- 
Das beste an der Zukunft ist vielleicht der Umstand, daß immer nur ein
Tag auf einmal kommt.
                -- Dean Acheson

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
From 6b67e72b21aeffbac8313a7fd07ca962cab76a2e Mon Sep 17 00:00:00 2001
From: Christian Brabandt <[email protected]>
Date: Fri, 27 Apr 2018 15:01:19 +0200
Subject: [PATCH] delbufline: allow to remove lines in a buffer

delbufline({buf}, {lnum} [, {line}])

delbufline() allows to remove lines {lnum} to {line} in the buffer
{buf}.  For the use of {buf} see |bufname()|.  If {line} is larger than
{lnum} the start and end lines will silently be swapped.  If {line} is
not given, only the single line {lnum} will be deleted.

In addition, add a test, so that the behaviour can be verified.
---
 runtime/doc/eval.txt         |  13 +++++
 runtime/doc/usr_41.txt       |   4 +-
 src/evalfunc.c               | 129 +++++++++++++++++++++++++++++++++++++------
 src/testdir/test_bufline.vim |  23 ++++++++
 4 files changed, 152 insertions(+), 17 deletions(-)

diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 0a22a717c..6e7d34fc6 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2109,6 +2109,9 @@ cursor({lnum}, {col} [, {off}])
 				Number	move cursor to {lnum}, {col}, {off}
 cursor({list})			Number	move cursor to position in {list}
 deepcopy({expr} [, {noref}])	any	make a full copy of {expr}
+delbufline({expr}, {lnum} [, {line}])
+				Number	delete line {lnum} to {line} in buffer
+					{expr}
 delete({fname} [, {flags}])	Number	delete the file or directory {fname}
 did_filetype()			Number	|TRUE| if FileType autocmd event used
 diff_filler({lnum})		Number	diff filler lines about {lnum}
@@ -3481,6 +3484,16 @@ deepcopy({expr} [, {noref}])				*deepcopy()* *E698*
 		{noref} set to 1 will fail.
 		Also see |copy()|.
 
+delbufline({expr}, {lnum} [, {line}])		        *delbufline()*
+		Delete line {lnum} to {line} in buffer {expr}.
+
+		For the use of {expr}, see |bufname()| above.
+
+		{lnum} is used like with |setline()|.
+		On success 0 is returned, on failure 1 is returned.
+
+		If {expr} is not a valid buffer an error message is given.
+
 delete({fname} [, {flags}])					*delete()*
 		Without {flags} or with {flags} empty: Deletes the file by the
 		name {fname}.  This also works when {fname} is a symbolic link.
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index bf324e661..7adeff8fb 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -725,7 +725,9 @@ Cursor and mark position:		*cursor-functions* *mark-functions*
 
 Working with text in the current buffer:		*text-functions*
 	getline()		get a line or list of lines from the buffer
-	setline()		replace a line in the buffer
+	setline()		replace a line in the current buffer
+	setbufline()		replace a line in a buffer
+	delbufline()		delete a line in a buffer
 	append()		append line or list of lines in the buffer
 	indent()		indent of a specific line
 	cindent()		indent according to C indenting
diff --git a/src/evalfunc.c b/src/evalfunc.c
index ae1425e53..2bab58ba2 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -124,6 +124,7 @@ static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
 static void f_cursor(typval_T *argsvars, typval_T *rettv);
 static void f_deepcopy(typval_T *argvars, typval_T *rettv);
 static void f_delete(typval_T *argvars, typval_T *rettv);
+static void f_delbufline(typval_T *argvars, typval_T *rettv);
 static void f_did_filetype(typval_T *argvars, typval_T *rettv);
 static void f_diff_filler(typval_T *argvars, typval_T *rettv);
 static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
@@ -568,6 +569,7 @@ static struct fst
     {"cscope_connection",0,3, f_cscope_connection},
     {"cursor",		1, 3, f_cursor},
     {"deepcopy",	1, 2, f_deepcopy},
+    {"delbufline",      2, 3, f_delbufline},
     {"delete",		1, 2, f_delete},
     {"did_filetype",	0, 0, f_did_filetype},
     {"diff_filler",	1, 1, f_diff_filler},
@@ -1082,6 +1084,22 @@ get_tv_lnum(typval_T *argvars)
     return lnum;
 }
 
+/*
+ * Get the lnum from the first argument.
+ * Also accepts "$", then "buf" is used.
+ * Returns 0 on error.
+ */
+    static linenr_T
+get_tv_lnum_buf(typval_T *argvars, buf_T *buf)
+{
+    if (argvars[0].v_type == VAR_STRING
+	    && argvars[0].vval.v_string != NULL
+	    && argvars[0].vval.v_string[0] == '$'
+	    && buf != NULL)
+	return buf->b_ml.ml_line_count;
+    return (linenr_T)get_tv_number_chk(&argvars[0], NULL);
+}
+
 #ifdef FEAT_FLOAT
 static int get_float_arg(typval_T *argvars, float_T *f);
 
@@ -2634,6 +2652,100 @@ f_deepcopy(typval_T *argvars, typval_T *rettv)
     }
 }
 
+    static void
+delete_buffer_lines(buf_T *buf, linenr_T lnum, linenr_T end, typval_T *rettv)
+{
+    buf_T	*curbuf_save = NULL;
+    win_T	*curwin_save = NULL;
+    int		is_curbuf = buf == curbuf;
+    pos_T	curpos = curwin->w_cursor;
+    long	lcount;
+    linenr_T	max;
+
+    /* When using the current buffer ml_mfp will be set if needed.  Useful when
+     * used on startup.  For other buffers the buffer must be loaded. */
+    if (buf == NULL || (!is_curbuf && buf->b_ml.ml_mfp == NULL) || lnum < 1)
+    {
+	rettv->vval.v_number = 1;	/* FAIL */
+	return;
+    }
+
+    if (!is_curbuf)
+    {
+	wininfo_T *wip;
+
+	curbuf_save = curbuf;
+	curwin_save = curwin;
+	curbuf = buf;
+	for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
+	{
+	    if (wip->wi_win != NULL)
+	    {
+		curwin = wip->wi_win;
+		break;
+	    }
+	}
+    }
+
+    max = curbuf->b_ml.ml_line_count;
+
+    if (end > 0 && end < lnum)
+    {
+	/* swap start and end, if end > start */
+	linenr_T t = end;
+	end = lnum;
+	lnum = t;
+    }
+
+    lcount = end ? end - lnum + 1 : 1L;
+    if (lcount > max)
+	lcount = max;
+
+    if (lnum <= max)
+    {
+	curwin->w_cursor.lnum = lnum;
+	del_lines(lcount, TRUE);
+	if (curpos.lnum > curbuf->b_ml.ml_line_count)
+	    curpos.lnum = curbuf->b_ml.ml_line_count;
+	curwin->w_cursor = curpos;
+    }
+    else
+	rettv->vval.v_number = 1;   /* FAIL */
+
+    if (!is_curbuf)
+    {
+	curbuf = curbuf_save;
+	curwin = curwin_save;
+    }
+}
+
+
+/*
+ * "delbufline()" function
+ */
+    static void
+f_delbufline(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    linenr_T	start;
+    linenr_T	end = 0;
+    buf_T	*buf;
+
+    buf = get_buf_tv(&argvars[0], FALSE);
+
+    if (buf == NULL)
+	rettv->vval.v_number = 1; /* FAIL */
+    else
+    {
+	start = get_tv_lnum_buf(&argvars[1], buf);
+	if (argvars[2].v_type != VAR_UNKNOWN)
+	    end = (int)get_tv_number_chk(&argvars[2], NULL);
+
+	delete_buffer_lines(buf, start, end, rettv);
+    }
+}
+
 /*
  * "delete()" function
  */
@@ -4264,22 +4376,6 @@ get_buffer_lines(
     }
 }
 
-/*
- * Get the lnum from the first argument.
- * Also accepts "$", then "buf" is used.
- * Returns 0 on error.
- */
-    static linenr_T
-get_tv_lnum_buf(typval_T *argvars, buf_T *buf)
-{
-    if (argvars[0].v_type == VAR_STRING
-	    && argvars[0].vval.v_string != NULL
-	    && argvars[0].vval.v_string[0] == '$'
-	    && buf != NULL)
-	return buf->b_ml.ml_line_count;
-    return (linenr_T)get_tv_number_chk(&argvars[0], NULL);
-}
-
 /*
  * "getbufline()" function
  */
@@ -10132,6 +10228,7 @@ f_serverlist(typval_T *argvars UNUSED, typval_T *rettv)
 
 /*
  * Set line or list of lines in buffer "buf".
+ * Adds content of *lines to buffer buf at line lnum
  */
     static void
 set_buffer_lines(buf_T *buf, linenr_T lnum, typval_T *lines, typval_T *rettv)
diff --git a/src/testdir/test_bufline.vim b/src/testdir/test_bufline.vim
index b886e9950..71d2a4d0a 100644
--- a/src/testdir/test_bufline.vim
+++ b/src/testdir/test_bufline.vim
@@ -65,3 +65,26 @@ func Test_setline_startup()
   call delete('Xscript')
   call delete('Xtest')
 endfunc
+
+func Test_delbufline()
+  new
+  let b = bufnr('%')
+  hide
+  call assert_equal(0, setbufline(b, 1, ['foo', 'bar', 'foobar']))
+  call assert_equal(1, delbufline(b, 10))
+  call assert_equal(0, delbufline(b, 1))
+  call assert_equal(['bar', 'foobar'], getbufline(b, 1, 2))
+  call assert_equal(0, delbufline(b, 2, 1))
+  call assert_equal([''], getbufline(b, 1, 2))
+  try
+    " should throw E94
+    call assert_equal(1, delbufline('.', 1))
+    call assert_equal(0, 1)
+  catch /E94/
+    call assert_match(':E94:', v:exception)
+  endtry
+  call assert_equal(0, setbufline(b, 1, ['foo', 'bar', 'foobar']))
+  call assert_equal(0, delbufline(b, 1, 1))
+  call assert_equal(['bar', 'foobar'], getbufline(b, 1, 2))
+  exe "bw!" b
+endfunc
-- 
2.16.3

Raspunde prin e-mail lui