/* vi:set ts=8 sts=4 sw=4 noet:
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
* See README.txt for an overview of the Vim source code.
*/
/*
* evalbuffer.c: Buffer related builtin functions
*/
#include "vim.h"
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* Mark references in functions of buffers.
*/
int
set_ref_in_buffers(int copyID)
{
int abort = FALSE;
buf_T *bp;
FOR_ALL_BUFFERS(bp)
{
listener_T *lnr;
for (lnr = bp->b_listener; !abort && lnr != NULL; lnr = lnr->lr_next)
abort = abort || set_ref_in_callback(&lnr->lr_callback, copyID);
# ifdef FEAT_JOB_CHANNEL
if (!abort)
abort = abort || set_ref_in_callback(&bp->b_prompt_callback, copyID);
if (!abort)
abort = abort || set_ref_in_callback(&bp->b_prompt_interrupt, copyID);
# endif
#ifdef FEAT_COMPL_FUNC
if (!abort)
abort = abort || set_ref_in_callback(&bp->b_cfu_cb, copyID);
if (!abort)
abort = abort || set_ref_in_callback(&bp->b_ofu_cb, copyID);
if (!abort)
abort = abort || set_ref_in_callback(&bp->b_tsrfu_cb, copyID);
#endif
if (!abort)
abort = abort || set_ref_in_callback(&bp->b_tfu_cb, copyID);
if (abort)
break;
}
return abort;
}
buf_T *
buflist_find_by_name(char_u *name, int curtab_only)
{
int save_magic;
char_u *save_cpo;
buf_T *buf;
// Ignore 'magic' and 'cpoptions' here to make scripts portable
save_magic = p_magic;
p_magic = TRUE;
save_cpo = p_cpo;
p_cpo = empty_option;
buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
TRUE, FALSE, curtab_only));
p_magic = save_magic;
p_cpo = save_cpo;
return buf;
}
/*
* Find a buffer by number or exact name.
*/
buf_T *
find_buffer(typval_T *avar)
{
buf_T *buf = NULL;
if (avar->v_type == VAR_NUMBER)
buf = buflist_findnr((int)avar->vval.v_number);
else if (in_vim9script() && check_for_string_arg(avar, 0) == FAIL)
return NULL;
else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL)
{
buf = buflist_findname_exp(avar->vval.v_string);
if (buf == NULL)
{
// No full path name match, try a match with a URL or a "nofile"
// buffer, these don't use the full path.
FOR_ALL_BUFFERS(buf)
if (buf->b_fname != NULL
&& (path_with_url(buf->b_fname) || bt_nofilename(buf))
&& STRCMP(buf->b_fname, avar->vval.v_string) == 0)
break;
}
}
return buf;
}
/*
* If there is a window for "curbuf", make it the current window.
*/
static void
find_win_for_curbuf(void)
{
wininfo_T *wip;
FOR_ALL_BUF_WININFO(curbuf, wip)
{
if (wip->wi_win != NULL)
{
curwin = wip->wi_win;
break;
}
}
}
/*
* Set line or list of lines in buffer "buf" to "lines".
* Any type is allowed and converted to a string.
*/
static void
set_buffer_lines(
buf_T *buf,
linenr_T lnum_arg,
int append,
typval_T *lines,
typval_T *rettv)
{
linenr_T lnum = lnum_arg + (append ? 1 : 0);
char_u *line = NULL;
list_T *l = NULL;
listitem_T *li = NULL;
long added = 0;
linenr_T append_lnum;
buf_T *curbuf_save = NULL;
win_T *curwin_save = NULL;
int is_curbuf = buf == curbuf;
int save_VIsual_active = VIsual_active;
// When using the current buffer ml_mfp will be set if needed. Useful when
// setline() is 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
if (in_vim9script() && lnum < 1)