Hi Hari,

On 10/22/06, Hari Krishna Dara <[EMAIL PROTECTED]> wrote:
> On 10/22/06, Hari Krishna Dara <[EMAIL PROTECTED]> wrote:
> >
> > I see functions for creating new unlisted buffers (bufnr() with {create}
> > option), and for reading the lines from the buffer using getbufline(),
> > all without having to change the current buffer, but I don't see a
> > setbufline() so there is no way to set the lines without having to
> > switch to it. Is there a reason to leave this circle incomplete?
> >
>
> Yes. I had a patch for the setbufline() function last year. There were
> several problems with it. So it was not included in Vim7 and only
> the getbufline() function was included.
>
> The setbufline() function worked only for loaded buffers. The undo
> history was not updated correctly.
>
> But I agree that it will be good to have the setbufline() function.
>
> - Yegappan

Nice, so it will be included at some point after resolving these issues.


You can try the attached patch against the latest Vim7 sources.
The syntax of the new function is:

           setbufline({expr}, {lnum}, {line})

where, {expr} specifies the loaded buffer name/number, {lnum} specifies
a valid line number in that buffer and {line} is either a single line
or a List of lines.

Note. The patch also includes the new gettabvar() and settabvar()
functions.

- Yegappan
Index: src/eval.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/eval.c,v
retrieving revision 1.198
diff -c -p -r1.198 eval.c
*** src/eval.c	17 Oct 2006 13:16:39 -0000	1.198
--- src/eval.c	23 Oct 2006 04:26:57 -0000
*************** static void f_getpos __ARGS((typval_T *a
*** 531,536 ****
--- 531,537 ----
  static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_gettabvar __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv));
*************** static void f_searchpairpos __ARGS((typv
*** 611,616 ****
--- 612,618 ----
  static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_setbufline __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
*************** static void f_setloclist __ARGS((typval_
*** 618,623 ****
--- 620,626 ----
  static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_settabvar __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv));
*************** static void getwinvar __ARGS((typval_T *
*** 740,745 ****
--- 743,749 ----
  static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos));
  static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp));
  static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
+ static void set_buffer_lines __ARGS((buf_T *buf, linenr_T lnum, char_u *line, list_T *l, typval_T *rettv));
  
  /* Character used as separated in autoload function/variable names. */
  #define AUTOLOAD_CHAR '#'
*************** static struct fst
*** 7077,7082 ****
--- 7081,7087 ----
      {"getqflist",	0, 0, f_getqflist},
      {"getreg",		0, 2, f_getreg},
      {"getregtype",	0, 1, f_getregtype},
+     {"gettabvar",	2, 2, f_gettabvar},
      {"gettabwinvar",	3, 3, f_gettabwinvar},
      {"getwinposx",	0, 0, f_getwinposx},
      {"getwinposy",	0, 0, f_getwinposy},
*************** static struct fst
*** 7159,7164 ****
--- 7164,7170 ----
      {"searchpos",	1, 3, f_searchpos},
      {"server2client",	2, 2, f_server2client},
      {"serverlist",	0, 0, f_serverlist},
+     {"setbufline",	3, 3, f_setbufline},
      {"setbufvar",	3, 3, f_setbufvar},
      {"setcmdpos",	1, 1, f_setcmdpos},
      {"setline",		2, 2, f_setline},
*************** static struct fst
*** 7166,7171 ****
--- 7172,7178 ----
      {"setpos",		2, 2, f_setpos},
      {"setqflist",	1, 2, f_setqflist},
      {"setreg",		2, 3, f_setreg},
+     {"settabvar",	3, 3, f_settabvar},
      {"settabwinvar",	4, 4, f_settabwinvar},
      {"setwinvar",	3, 3, f_setwinvar},
      {"shellescape",	1, 1, f_shellescape},
*************** f_getregtype(argvars, rettv)
*** 10328,10333 ****
--- 10335,10366 ----
  }
  
  /*
+  * "gettabvar()" function
+  */
+     static void
+ f_gettabvar(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     tabpage_T	*tp;
+     dictitem_T	*v;
+     char_u	*varname;
+ 
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = NULL;
+ 
+     varname = get_tv_string_chk(&argvars[1]);
+     tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
+     if (tp != NULL && varname != NULL)
+     {
+ 	/* look up the variable */
+ 	v = find_var_in_ht(&tp->tp_vars.dv_hashtab, varname, FALSE);
+ 	if (v != NULL)
+ 	    copy_tv(&v->di_tv, rettv);
+     }
+ }
+ 
+ /*
   * "gettabwinvar()" function
   */
      static void
*************** f_serverlist(argvars, rettv)
*** 14205,14210 ****
--- 14238,14349 ----
  }
  
  /*
+  * set_buffer_lines()
+  * Set one or more lines in buffer 'buf' to the supplied lines
+  */
+     static void
+ set_buffer_lines(buf, lnum, line, l, rettv)
+     buf_T	*buf;
+     linenr_T	lnum;
+     char_u	*line;
+     list_T	*l;
+     typval_T	*rettv;
+ {
+     aco_save_T	aco;
+     linenr_T	lcount;
+     listitem_T	*li = NULL;
+     long	added = 0;
+ 
+     /* set curbuf to be our buf, temporarily */
+     aucmd_prepbuf(&aco, buf);
+ 
+     if (l != NULL)
+ 	li = l->lv_first;
+ 
+     lcount = curbuf->b_ml.ml_line_count;
+     for (;;)
+     {
+ 	if (l != NULL)
+ 	{
+ 	    /* list argument, get next string */
+ 	    if (li == NULL)
+ 		break;
+ 	    line = get_tv_string_chk(&li->li_tv);
+ 	    li = li->li_next;
+ 	}
+ 
+ 	rettv->vval.v_number = 1;	/* FAIL */
+ 	if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
+ 	    break;
+ 	if (lnum <= curbuf->b_ml.ml_line_count)
+ 	{
+ 	    /* existing line, replace it */
+ 	    if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
+ 	    {
+ 		changed_bytes(lnum, 0);
+ 		check_cursor_col();
+ 		rettv->vval.v_number = 0;	/* OK */
+ 	    }
+ 	}
+ 	else if (added > 0 || u_save(lnum - 1, lnum) == OK)
+ 	{
+ 	    /* lnum is one past the last line, append the line */
+ 	    ++added;
+ 	    if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
+ 		rettv->vval.v_number = 0;	/* OK */
+ 	}
+ 
+ 	if (l == NULL)			/* only one string argument */
+ 	    break;
+ 	++lnum;
+     }
+ 
+     if (added > 0)
+ 	appended_lines_mark(lcount, added);
+ 
+     /* reset notion of buffer */
+     aucmd_restbuf(&aco);
+ }
+ 
+ /*
+  * "setbufline()" function
+  */
+     static void
+ f_setbufline(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     linenr_T	lnum;
+     char_u	*line = NULL;
+     list_T	*l = NULL;
+     buf_T	*buf;
+ 
+     rettv->vval.v_number = 0;
+ 
+     if (check_restricted() || check_secure())
+ 	return;
+ 
+     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
+     ++emsg_off;
+     buf = get_buf_tv(&argvars[0]);
+     --emsg_off;
+ 
+     lnum = get_tv_lnum_buf(&argvars[1], buf);
+     if (argvars[2].v_type == VAR_LIST)
+ 	l = argvars[2].vval.v_list;
+     else
+ 	line = get_tv_string_chk(&argvars[2]);
+ 
+     /* Make sure a valid loaded buffer is used */
+     if (buf == NULL || buf->b_ml.ml_mfp == NULL)
+ 	return;
+ 
+     set_buffer_lines(buf, lnum, line, l, rettv);
+ 
+     check_cursor_col();
+ }
+ 
+ /*
   * "setbufvar()" function
   */
  /*ARGSUSED*/
*************** f_setline(argvars, rettv)
*** 14287,14345 ****
      linenr_T	lnum;
      char_u	*line = NULL;
      list_T	*l = NULL;
-     listitem_T	*li = NULL;
-     long	added = 0;
-     linenr_T	lcount = curbuf->b_ml.ml_line_count;
  
      lnum = get_tv_lnum(&argvars[0]);
      if (argvars[1].v_type == VAR_LIST)
-     {
  	l = argvars[1].vval.v_list;
- 	li = l->lv_first;
-     }
      else
  	line = get_tv_string_chk(&argvars[1]);
  
      rettv->vval.v_number = 0;		/* OK */
-     for (;;)
-     {
- 	if (l != NULL)
- 	{
- 	    /* list argument, get next string */
- 	    if (li == NULL)
- 		break;
- 	    line = get_tv_string_chk(&li->li_tv);
- 	    li = li->li_next;
- 	}
  
! 	rettv->vval.v_number = 1;	/* FAIL */
! 	if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
! 	    break;
! 	if (lnum <= curbuf->b_ml.ml_line_count)
! 	{
! 	    /* existing line, replace it */
! 	    if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
! 	    {
! 		changed_bytes(lnum, 0);
! 		check_cursor_col();
! 		rettv->vval.v_number = 0;	/* OK */
! 	    }
! 	}
! 	else if (added > 0 || u_save(lnum - 1, lnum) == OK)
! 	{
! 	    /* lnum is one past the last line, append the line */
! 	    ++added;
! 	    if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
! 		rettv->vval.v_number = 0;	/* OK */
! 	}
! 
! 	if (l == NULL)			/* only one string argument */
! 	    break;
! 	++lnum;
!     }
! 
!     if (added > 0)
! 	appended_lines_mark(lcount, added);
  }
  
  /*
--- 14426,14441 ----
      linenr_T	lnum;
      char_u	*line = NULL;
      list_T	*l = NULL;
  
      lnum = get_tv_lnum(&argvars[0]);
      if (argvars[1].v_type == VAR_LIST)
  	l = argvars[1].vval.v_list;
      else
  	line = get_tv_string_chk(&argvars[1]);
  
      rettv->vval.v_number = 0;		/* OK */
  
!     set_buffer_lines(curbuf, lnum, line, l, rettv);
  }
  
  /*
*************** f_setreg(argvars, rettv)
*** 14519,14524 ****
--- 14615,14664 ----
  }
  
  /*
+  * "settabvar()" function
+  */
+     static void
+ f_settabvar(argvars, rettv)
+     typval_T	*argvars;
+     typval_T	*rettv;
+ {
+     tabpage_T	*save_curtab;
+     char_u	*varname, *tabvarname;
+     typval_T	*varp;
+     char_u	nbuf[NUMBUFLEN];
+     tabpage_T	*tp;
+ 
+     rettv->vval.v_number = 0;
+ 
+     if (check_restricted() || check_secure())
+ 	return;
+ 
+     tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
+     varname = get_tv_string_chk(&argvars[1]);
+     varp = &argvars[2];
+ 
+     if (tp != NULL && varname != NULL && varp != NULL)
+     {
+ 	save_curtab = curtab;
+ 	goto_tabpage_tp(tp);
+ 
+ 	tabvarname = alloc((unsigned)STRLEN(varname) + 3);
+ 	if (tabvarname != NULL)
+ 	{
+ 	    STRCPY(tabvarname, "t:");
+ 	    STRCPY(tabvarname + 2, varname);
+ 	    set_var(tabvarname, varp, TRUE);
+ 	    vim_free(tabvarname);
+ 	}
+ 
+ 	/* Restore current tabpage */
+ 	if (valid_tabpage(save_curtab))
+ 	    goto_tabpage_tp(save_curtab);
+     }
+ }
+ 
+ 
+ /*
   * "settabwinvar()" function
   */
      static void

Reply via email to