1*261f346fSBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet: 2*261f346fSBram Moolenaar * 3*261f346fSBram Moolenaar * VIM - Vi IMproved by Bram Moolenaar 4*261f346fSBram Moolenaar * 5*261f346fSBram Moolenaar * Do ":help uganda" in Vim to read copying and usage conditions. 6*261f346fSBram Moolenaar * Do ":help credits" in Vim to see a list of people who contributed. 7*261f346fSBram Moolenaar * See README.txt for an overview of the Vim source code. 8*261f346fSBram Moolenaar */ 9*261f346fSBram Moolenaar 10*261f346fSBram Moolenaar /* 11*261f346fSBram Moolenaar * evalbuffer.c: Buffer related builtin functions 12*261f346fSBram Moolenaar */ 13*261f346fSBram Moolenaar 14*261f346fSBram Moolenaar #include "vim.h" 15*261f346fSBram Moolenaar 16*261f346fSBram Moolenaar #if defined(FEAT_EVAL) || defined(PROTO) 17*261f346fSBram Moolenaar /* 18*261f346fSBram Moolenaar * Mark references in functions of buffers. 19*261f346fSBram Moolenaar */ 20*261f346fSBram Moolenaar int 21*261f346fSBram Moolenaar set_ref_in_buffers(int copyID) 22*261f346fSBram Moolenaar { 23*261f346fSBram Moolenaar int abort = FALSE; 24*261f346fSBram Moolenaar buf_T *bp; 25*261f346fSBram Moolenaar 26*261f346fSBram Moolenaar FOR_ALL_BUFFERS(bp) 27*261f346fSBram Moolenaar { 28*261f346fSBram Moolenaar listener_T *lnr; 29*261f346fSBram Moolenaar typval_T tv; 30*261f346fSBram Moolenaar 31*261f346fSBram Moolenaar for (lnr = bp->b_listener; !abort && lnr != NULL; lnr = lnr->lr_next) 32*261f346fSBram Moolenaar { 33*261f346fSBram Moolenaar if (lnr->lr_callback.cb_partial != NULL) 34*261f346fSBram Moolenaar { 35*261f346fSBram Moolenaar tv.v_type = VAR_PARTIAL; 36*261f346fSBram Moolenaar tv.vval.v_partial = lnr->lr_callback.cb_partial; 37*261f346fSBram Moolenaar abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); 38*261f346fSBram Moolenaar } 39*261f346fSBram Moolenaar } 40*261f346fSBram Moolenaar # ifdef FEAT_JOB_CHANNEL 41*261f346fSBram Moolenaar if (!abort && bp->b_prompt_callback.cb_partial != NULL) 42*261f346fSBram Moolenaar { 43*261f346fSBram Moolenaar tv.v_type = VAR_PARTIAL; 44*261f346fSBram Moolenaar tv.vval.v_partial = bp->b_prompt_callback.cb_partial; 45*261f346fSBram Moolenaar abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); 46*261f346fSBram Moolenaar } 47*261f346fSBram Moolenaar if (!abort && bp->b_prompt_interrupt.cb_partial != NULL) 48*261f346fSBram Moolenaar { 49*261f346fSBram Moolenaar tv.v_type = VAR_PARTIAL; 50*261f346fSBram Moolenaar tv.vval.v_partial = bp->b_prompt_interrupt.cb_partial; 51*261f346fSBram Moolenaar abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); 52*261f346fSBram Moolenaar } 53*261f346fSBram Moolenaar # endif 54*261f346fSBram Moolenaar if (abort) 55*261f346fSBram Moolenaar break; 56*261f346fSBram Moolenaar } 57*261f346fSBram Moolenaar return abort; 58*261f346fSBram Moolenaar } 59*261f346fSBram Moolenaar 60*261f346fSBram Moolenaar buf_T * 61*261f346fSBram Moolenaar buflist_find_by_name(char_u *name, int curtab_only) 62*261f346fSBram Moolenaar { 63*261f346fSBram Moolenaar int save_magic; 64*261f346fSBram Moolenaar char_u *save_cpo; 65*261f346fSBram Moolenaar buf_T *buf; 66*261f346fSBram Moolenaar 67*261f346fSBram Moolenaar // Ignore 'magic' and 'cpoptions' here to make scripts portable 68*261f346fSBram Moolenaar save_magic = p_magic; 69*261f346fSBram Moolenaar p_magic = TRUE; 70*261f346fSBram Moolenaar save_cpo = p_cpo; 71*261f346fSBram Moolenaar p_cpo = (char_u *)""; 72*261f346fSBram Moolenaar 73*261f346fSBram Moolenaar buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 74*261f346fSBram Moolenaar TRUE, FALSE, curtab_only)); 75*261f346fSBram Moolenaar 76*261f346fSBram Moolenaar p_magic = save_magic; 77*261f346fSBram Moolenaar p_cpo = save_cpo; 78*261f346fSBram Moolenaar return buf; 79*261f346fSBram Moolenaar } 80*261f346fSBram Moolenaar 81*261f346fSBram Moolenaar /* 82*261f346fSBram Moolenaar * Find a buffer by number or exact name. 83*261f346fSBram Moolenaar */ 84*261f346fSBram Moolenaar buf_T * 85*261f346fSBram Moolenaar find_buffer(typval_T *avar) 86*261f346fSBram Moolenaar { 87*261f346fSBram Moolenaar buf_T *buf = NULL; 88*261f346fSBram Moolenaar 89*261f346fSBram Moolenaar if (avar->v_type == VAR_NUMBER) 90*261f346fSBram Moolenaar buf = buflist_findnr((int)avar->vval.v_number); 91*261f346fSBram Moolenaar else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 92*261f346fSBram Moolenaar { 93*261f346fSBram Moolenaar buf = buflist_findname_exp(avar->vval.v_string); 94*261f346fSBram Moolenaar if (buf == NULL) 95*261f346fSBram Moolenaar { 96*261f346fSBram Moolenaar // No full path name match, try a match with a URL or a "nofile" 97*261f346fSBram Moolenaar // buffer, these don't use the full path. 98*261f346fSBram Moolenaar FOR_ALL_BUFFERS(buf) 99*261f346fSBram Moolenaar if (buf->b_fname != NULL 100*261f346fSBram Moolenaar && (path_with_url(buf->b_fname) 101*261f346fSBram Moolenaar #ifdef FEAT_QUICKFIX 102*261f346fSBram Moolenaar || bt_nofilename(buf) 103*261f346fSBram Moolenaar #endif 104*261f346fSBram Moolenaar ) 105*261f346fSBram Moolenaar && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 106*261f346fSBram Moolenaar break; 107*261f346fSBram Moolenaar } 108*261f346fSBram Moolenaar } 109*261f346fSBram Moolenaar return buf; 110*261f346fSBram Moolenaar } 111*261f346fSBram Moolenaar 112*261f346fSBram Moolenaar /* 113*261f346fSBram Moolenaar * If there is a window for "curbuf", make it the current window. 114*261f346fSBram Moolenaar */ 115*261f346fSBram Moolenaar static void 116*261f346fSBram Moolenaar find_win_for_curbuf(void) 117*261f346fSBram Moolenaar { 118*261f346fSBram Moolenaar wininfo_T *wip; 119*261f346fSBram Moolenaar 120*261f346fSBram Moolenaar for (wip = curbuf->b_wininfo; wip != NULL; wip = wip->wi_next) 121*261f346fSBram Moolenaar { 122*261f346fSBram Moolenaar if (wip->wi_win != NULL) 123*261f346fSBram Moolenaar { 124*261f346fSBram Moolenaar curwin = wip->wi_win; 125*261f346fSBram Moolenaar break; 126*261f346fSBram Moolenaar } 127*261f346fSBram Moolenaar } 128*261f346fSBram Moolenaar } 129*261f346fSBram Moolenaar 130*261f346fSBram Moolenaar /* 131*261f346fSBram Moolenaar * Set line or list of lines in buffer "buf". 132*261f346fSBram Moolenaar */ 133*261f346fSBram Moolenaar static void 134*261f346fSBram Moolenaar set_buffer_lines( 135*261f346fSBram Moolenaar buf_T *buf, 136*261f346fSBram Moolenaar linenr_T lnum_arg, 137*261f346fSBram Moolenaar int append, 138*261f346fSBram Moolenaar typval_T *lines, 139*261f346fSBram Moolenaar typval_T *rettv) 140*261f346fSBram Moolenaar { 141*261f346fSBram Moolenaar linenr_T lnum = lnum_arg + (append ? 1 : 0); 142*261f346fSBram Moolenaar char_u *line = NULL; 143*261f346fSBram Moolenaar list_T *l = NULL; 144*261f346fSBram Moolenaar listitem_T *li = NULL; 145*261f346fSBram Moolenaar long added = 0; 146*261f346fSBram Moolenaar linenr_T append_lnum; 147*261f346fSBram Moolenaar buf_T *curbuf_save = NULL; 148*261f346fSBram Moolenaar win_T *curwin_save = NULL; 149*261f346fSBram Moolenaar int is_curbuf = buf == curbuf; 150*261f346fSBram Moolenaar 151*261f346fSBram Moolenaar // When using the current buffer ml_mfp will be set if needed. Useful when 152*261f346fSBram Moolenaar // setline() is used on startup. For other buffers the buffer must be 153*261f346fSBram Moolenaar // loaded. 154*261f346fSBram Moolenaar if (buf == NULL || (!is_curbuf && buf->b_ml.ml_mfp == NULL) || lnum < 1) 155*261f346fSBram Moolenaar { 156*261f346fSBram Moolenaar rettv->vval.v_number = 1; // FAIL 157*261f346fSBram Moolenaar return; 158*261f346fSBram Moolenaar } 159*261f346fSBram Moolenaar 160*261f346fSBram Moolenaar if (!is_curbuf) 161*261f346fSBram Moolenaar { 162*261f346fSBram Moolenaar curbuf_save = curbuf; 163*261f346fSBram Moolenaar curwin_save = curwin; 164*261f346fSBram Moolenaar curbuf = buf; 165*261f346fSBram Moolenaar find_win_for_curbuf(); 166*261f346fSBram Moolenaar } 167*261f346fSBram Moolenaar 168*261f346fSBram Moolenaar if (append) 169*261f346fSBram Moolenaar // appendbufline() uses the line number below which we insert 170*261f346fSBram Moolenaar append_lnum = lnum - 1; 171*261f346fSBram Moolenaar else 172*261f346fSBram Moolenaar // setbufline() uses the line number above which we insert, we only 173*261f346fSBram Moolenaar // append if it's below the last line 174*261f346fSBram Moolenaar append_lnum = curbuf->b_ml.ml_line_count; 175*261f346fSBram Moolenaar 176*261f346fSBram Moolenaar if (lines->v_type == VAR_LIST) 177*261f346fSBram Moolenaar { 178*261f346fSBram Moolenaar l = lines->vval.v_list; 179*261f346fSBram Moolenaar li = l->lv_first; 180*261f346fSBram Moolenaar } 181*261f346fSBram Moolenaar else 182*261f346fSBram Moolenaar line = tv_get_string_chk(lines); 183*261f346fSBram Moolenaar 184*261f346fSBram Moolenaar // default result is zero == OK 185*261f346fSBram Moolenaar for (;;) 186*261f346fSBram Moolenaar { 187*261f346fSBram Moolenaar if (l != NULL) 188*261f346fSBram Moolenaar { 189*261f346fSBram Moolenaar // list argument, get next string 190*261f346fSBram Moolenaar if (li == NULL) 191*261f346fSBram Moolenaar break; 192*261f346fSBram Moolenaar line = tv_get_string_chk(&li->li_tv); 193*261f346fSBram Moolenaar li = li->li_next; 194*261f346fSBram Moolenaar } 195*261f346fSBram Moolenaar 196*261f346fSBram Moolenaar rettv->vval.v_number = 1; // FAIL 197*261f346fSBram Moolenaar if (line == NULL || lnum > curbuf->b_ml.ml_line_count + 1) 198*261f346fSBram Moolenaar break; 199*261f346fSBram Moolenaar 200*261f346fSBram Moolenaar // When coming here from Insert mode, sync undo, so that this can be 201*261f346fSBram Moolenaar // undone separately from what was previously inserted. 202*261f346fSBram Moolenaar if (u_sync_once == 2) 203*261f346fSBram Moolenaar { 204*261f346fSBram Moolenaar u_sync_once = 1; // notify that u_sync() was called 205*261f346fSBram Moolenaar u_sync(TRUE); 206*261f346fSBram Moolenaar } 207*261f346fSBram Moolenaar 208*261f346fSBram Moolenaar if (!append && lnum <= curbuf->b_ml.ml_line_count) 209*261f346fSBram Moolenaar { 210*261f346fSBram Moolenaar // Existing line, replace it. 211*261f346fSBram Moolenaar // Removes any existing text properties. 212*261f346fSBram Moolenaar if (u_savesub(lnum) == OK && ml_replace_len( 213*261f346fSBram Moolenaar lnum, line, (colnr_T)STRLEN(line) + 1, TRUE, TRUE) == OK) 214*261f346fSBram Moolenaar { 215*261f346fSBram Moolenaar changed_bytes(lnum, 0); 216*261f346fSBram Moolenaar if (is_curbuf && lnum == curwin->w_cursor.lnum) 217*261f346fSBram Moolenaar check_cursor_col(); 218*261f346fSBram Moolenaar rettv->vval.v_number = 0; // OK 219*261f346fSBram Moolenaar } 220*261f346fSBram Moolenaar } 221*261f346fSBram Moolenaar else if (added > 0 || u_save(lnum - 1, lnum) == OK) 222*261f346fSBram Moolenaar { 223*261f346fSBram Moolenaar // append the line 224*261f346fSBram Moolenaar ++added; 225*261f346fSBram Moolenaar if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 226*261f346fSBram Moolenaar rettv->vval.v_number = 0; // OK 227*261f346fSBram Moolenaar } 228*261f346fSBram Moolenaar 229*261f346fSBram Moolenaar if (l == NULL) // only one string argument 230*261f346fSBram Moolenaar break; 231*261f346fSBram Moolenaar ++lnum; 232*261f346fSBram Moolenaar } 233*261f346fSBram Moolenaar 234*261f346fSBram Moolenaar if (added > 0) 235*261f346fSBram Moolenaar { 236*261f346fSBram Moolenaar win_T *wp; 237*261f346fSBram Moolenaar tabpage_T *tp; 238*261f346fSBram Moolenaar 239*261f346fSBram Moolenaar appended_lines_mark(append_lnum, added); 240*261f346fSBram Moolenaar 241*261f346fSBram Moolenaar // Only adjust the cursor for buffers other than the current, unless it 242*261f346fSBram Moolenaar // is the current window. For curbuf and other windows it has been 243*261f346fSBram Moolenaar // done in mark_adjust_internal(). 244*261f346fSBram Moolenaar FOR_ALL_TAB_WINDOWS(tp, wp) 245*261f346fSBram Moolenaar if (wp->w_buffer == buf 246*261f346fSBram Moolenaar && (wp->w_buffer != curbuf || wp == curwin) 247*261f346fSBram Moolenaar && wp->w_cursor.lnum > append_lnum) 248*261f346fSBram Moolenaar wp->w_cursor.lnum += added; 249*261f346fSBram Moolenaar check_cursor_col(); 250*261f346fSBram Moolenaar update_topline(); 251*261f346fSBram Moolenaar } 252*261f346fSBram Moolenaar 253*261f346fSBram Moolenaar if (!is_curbuf) 254*261f346fSBram Moolenaar { 255*261f346fSBram Moolenaar curbuf = curbuf_save; 256*261f346fSBram Moolenaar curwin = curwin_save; 257*261f346fSBram Moolenaar } 258*261f346fSBram Moolenaar } 259*261f346fSBram Moolenaar 260*261f346fSBram Moolenaar /* 261*261f346fSBram Moolenaar * "append(lnum, string/list)" function 262*261f346fSBram Moolenaar */ 263*261f346fSBram Moolenaar void 264*261f346fSBram Moolenaar f_append(typval_T *argvars, typval_T *rettv) 265*261f346fSBram Moolenaar { 266*261f346fSBram Moolenaar linenr_T lnum = tv_get_lnum(&argvars[0]); 267*261f346fSBram Moolenaar 268*261f346fSBram Moolenaar set_buffer_lines(curbuf, lnum, TRUE, &argvars[1], rettv); 269*261f346fSBram Moolenaar } 270*261f346fSBram Moolenaar 271*261f346fSBram Moolenaar /* 272*261f346fSBram Moolenaar * "appendbufline(buf, lnum, string/list)" function 273*261f346fSBram Moolenaar */ 274*261f346fSBram Moolenaar void 275*261f346fSBram Moolenaar f_appendbufline(typval_T *argvars, typval_T *rettv) 276*261f346fSBram Moolenaar { 277*261f346fSBram Moolenaar linenr_T lnum; 278*261f346fSBram Moolenaar buf_T *buf; 279*261f346fSBram Moolenaar 280*261f346fSBram Moolenaar buf = tv_get_buf(&argvars[0], FALSE); 281*261f346fSBram Moolenaar if (buf == NULL) 282*261f346fSBram Moolenaar rettv->vval.v_number = 1; // FAIL 283*261f346fSBram Moolenaar else 284*261f346fSBram Moolenaar { 285*261f346fSBram Moolenaar lnum = tv_get_lnum_buf(&argvars[1], buf); 286*261f346fSBram Moolenaar set_buffer_lines(buf, lnum, TRUE, &argvars[2], rettv); 287*261f346fSBram Moolenaar } 288*261f346fSBram Moolenaar } 289*261f346fSBram Moolenaar 290*261f346fSBram Moolenaar /* 291*261f346fSBram Moolenaar * "bufadd(expr)" function 292*261f346fSBram Moolenaar */ 293*261f346fSBram Moolenaar void 294*261f346fSBram Moolenaar f_bufadd(typval_T *argvars, typval_T *rettv) 295*261f346fSBram Moolenaar { 296*261f346fSBram Moolenaar char_u *name = tv_get_string(&argvars[0]); 297*261f346fSBram Moolenaar 298*261f346fSBram Moolenaar rettv->vval.v_number = buflist_add(*name == NUL ? NULL : name, 0); 299*261f346fSBram Moolenaar } 300*261f346fSBram Moolenaar 301*261f346fSBram Moolenaar /* 302*261f346fSBram Moolenaar * "bufexists(expr)" function 303*261f346fSBram Moolenaar */ 304*261f346fSBram Moolenaar void 305*261f346fSBram Moolenaar f_bufexists(typval_T *argvars, typval_T *rettv) 306*261f346fSBram Moolenaar { 307*261f346fSBram Moolenaar rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 308*261f346fSBram Moolenaar } 309*261f346fSBram Moolenaar 310*261f346fSBram Moolenaar /* 311*261f346fSBram Moolenaar * "buflisted(expr)" function 312*261f346fSBram Moolenaar */ 313*261f346fSBram Moolenaar void 314*261f346fSBram Moolenaar f_buflisted(typval_T *argvars, typval_T *rettv) 315*261f346fSBram Moolenaar { 316*261f346fSBram Moolenaar buf_T *buf; 317*261f346fSBram Moolenaar 318*261f346fSBram Moolenaar buf = find_buffer(&argvars[0]); 319*261f346fSBram Moolenaar rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 320*261f346fSBram Moolenaar } 321*261f346fSBram Moolenaar 322*261f346fSBram Moolenaar /* 323*261f346fSBram Moolenaar * "bufload(expr)" function 324*261f346fSBram Moolenaar */ 325*261f346fSBram Moolenaar void 326*261f346fSBram Moolenaar f_bufload(typval_T *argvars, typval_T *rettv UNUSED) 327*261f346fSBram Moolenaar { 328*261f346fSBram Moolenaar buf_T *buf = get_buf_arg(&argvars[0]); 329*261f346fSBram Moolenaar 330*261f346fSBram Moolenaar if (buf != NULL) 331*261f346fSBram Moolenaar buffer_ensure_loaded(buf); 332*261f346fSBram Moolenaar } 333*261f346fSBram Moolenaar 334*261f346fSBram Moolenaar /* 335*261f346fSBram Moolenaar * "bufloaded(expr)" function 336*261f346fSBram Moolenaar */ 337*261f346fSBram Moolenaar void 338*261f346fSBram Moolenaar f_bufloaded(typval_T *argvars, typval_T *rettv) 339*261f346fSBram Moolenaar { 340*261f346fSBram Moolenaar buf_T *buf; 341*261f346fSBram Moolenaar 342*261f346fSBram Moolenaar buf = find_buffer(&argvars[0]); 343*261f346fSBram Moolenaar rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 344*261f346fSBram Moolenaar } 345*261f346fSBram Moolenaar 346*261f346fSBram Moolenaar /* 347*261f346fSBram Moolenaar * "bufname(expr)" function 348*261f346fSBram Moolenaar */ 349*261f346fSBram Moolenaar void 350*261f346fSBram Moolenaar f_bufname(typval_T *argvars, typval_T *rettv) 351*261f346fSBram Moolenaar { 352*261f346fSBram Moolenaar buf_T *buf; 353*261f346fSBram Moolenaar 354*261f346fSBram Moolenaar if (argvars[0].v_type == VAR_UNKNOWN) 355*261f346fSBram Moolenaar buf = curbuf; 356*261f346fSBram Moolenaar else 357*261f346fSBram Moolenaar { 358*261f346fSBram Moolenaar (void)tv_get_number(&argvars[0]); // issue errmsg if type error 359*261f346fSBram Moolenaar ++emsg_off; 360*261f346fSBram Moolenaar buf = tv_get_buf(&argvars[0], FALSE); 361*261f346fSBram Moolenaar --emsg_off; 362*261f346fSBram Moolenaar } 363*261f346fSBram Moolenaar rettv->v_type = VAR_STRING; 364*261f346fSBram Moolenaar if (buf != NULL && buf->b_fname != NULL) 365*261f346fSBram Moolenaar rettv->vval.v_string = vim_strsave(buf->b_fname); 366*261f346fSBram Moolenaar else 367*261f346fSBram Moolenaar rettv->vval.v_string = NULL; 368*261f346fSBram Moolenaar } 369*261f346fSBram Moolenaar 370*261f346fSBram Moolenaar /* 371*261f346fSBram Moolenaar * "bufnr(expr)" function 372*261f346fSBram Moolenaar */ 373*261f346fSBram Moolenaar void 374*261f346fSBram Moolenaar f_bufnr(typval_T *argvars, typval_T *rettv) 375*261f346fSBram Moolenaar { 376*261f346fSBram Moolenaar buf_T *buf; 377*261f346fSBram Moolenaar int error = FALSE; 378*261f346fSBram Moolenaar char_u *name; 379*261f346fSBram Moolenaar 380*261f346fSBram Moolenaar if (argvars[0].v_type == VAR_UNKNOWN) 381*261f346fSBram Moolenaar buf = curbuf; 382*261f346fSBram Moolenaar else 383*261f346fSBram Moolenaar { 384*261f346fSBram Moolenaar (void)tv_get_number(&argvars[0]); // issue errmsg if type error 385*261f346fSBram Moolenaar ++emsg_off; 386*261f346fSBram Moolenaar buf = tv_get_buf(&argvars[0], FALSE); 387*261f346fSBram Moolenaar --emsg_off; 388*261f346fSBram Moolenaar } 389*261f346fSBram Moolenaar 390*261f346fSBram Moolenaar // If the buffer isn't found and the second argument is not zero create a 391*261f346fSBram Moolenaar // new buffer. 392*261f346fSBram Moolenaar if (buf == NULL 393*261f346fSBram Moolenaar && argvars[1].v_type != VAR_UNKNOWN 394*261f346fSBram Moolenaar && tv_get_number_chk(&argvars[1], &error) != 0 395*261f346fSBram Moolenaar && !error 396*261f346fSBram Moolenaar && (name = tv_get_string_chk(&argvars[0])) != NULL 397*261f346fSBram Moolenaar && !error) 398*261f346fSBram Moolenaar buf = buflist_new(name, NULL, (linenr_T)1, 0); 399*261f346fSBram Moolenaar 400*261f346fSBram Moolenaar if (buf != NULL) 401*261f346fSBram Moolenaar rettv->vval.v_number = buf->b_fnum; 402*261f346fSBram Moolenaar else 403*261f346fSBram Moolenaar rettv->vval.v_number = -1; 404*261f346fSBram Moolenaar } 405*261f346fSBram Moolenaar 406*261f346fSBram Moolenaar static void 407*261f346fSBram Moolenaar buf_win_common(typval_T *argvars, typval_T *rettv, int get_nr) 408*261f346fSBram Moolenaar { 409*261f346fSBram Moolenaar win_T *wp; 410*261f346fSBram Moolenaar int winnr = 0; 411*261f346fSBram Moolenaar buf_T *buf; 412*261f346fSBram Moolenaar 413*261f346fSBram Moolenaar (void)tv_get_number(&argvars[0]); // issue errmsg if type error 414*261f346fSBram Moolenaar ++emsg_off; 415*261f346fSBram Moolenaar buf = tv_get_buf(&argvars[0], TRUE); 416*261f346fSBram Moolenaar FOR_ALL_WINDOWS(wp) 417*261f346fSBram Moolenaar { 418*261f346fSBram Moolenaar ++winnr; 419*261f346fSBram Moolenaar if (wp->w_buffer == buf) 420*261f346fSBram Moolenaar break; 421*261f346fSBram Moolenaar } 422*261f346fSBram Moolenaar rettv->vval.v_number = (wp != NULL ? (get_nr ? winnr : wp->w_id) : -1); 423*261f346fSBram Moolenaar --emsg_off; 424*261f346fSBram Moolenaar } 425*261f346fSBram Moolenaar 426*261f346fSBram Moolenaar /* 427*261f346fSBram Moolenaar * "bufwinid(nr)" function 428*261f346fSBram Moolenaar */ 429*261f346fSBram Moolenaar void 430*261f346fSBram Moolenaar f_bufwinid(typval_T *argvars, typval_T *rettv) 431*261f346fSBram Moolenaar { 432*261f346fSBram Moolenaar buf_win_common(argvars, rettv, FALSE); 433*261f346fSBram Moolenaar } 434*261f346fSBram Moolenaar 435*261f346fSBram Moolenaar /* 436*261f346fSBram Moolenaar * "bufwinnr(nr)" function 437*261f346fSBram Moolenaar */ 438*261f346fSBram Moolenaar void 439*261f346fSBram Moolenaar f_bufwinnr(typval_T *argvars, typval_T *rettv) 440*261f346fSBram Moolenaar { 441*261f346fSBram Moolenaar buf_win_common(argvars, rettv, TRUE); 442*261f346fSBram Moolenaar } 443*261f346fSBram Moolenaar 444*261f346fSBram Moolenaar /* 445*261f346fSBram Moolenaar * "deletebufline()" function 446*261f346fSBram Moolenaar */ 447*261f346fSBram Moolenaar void 448*261f346fSBram Moolenaar f_deletebufline(typval_T *argvars, typval_T *rettv) 449*261f346fSBram Moolenaar { 450*261f346fSBram Moolenaar buf_T *buf; 451*261f346fSBram Moolenaar linenr_T first, last; 452*261f346fSBram Moolenaar linenr_T lnum; 453*261f346fSBram Moolenaar long count; 454*261f346fSBram Moolenaar int is_curbuf; 455*261f346fSBram Moolenaar buf_T *curbuf_save = NULL; 456*261f346fSBram Moolenaar win_T *curwin_save = NULL; 457*261f346fSBram Moolenaar tabpage_T *tp; 458*261f346fSBram Moolenaar win_T *wp; 459*261f346fSBram Moolenaar 460*261f346fSBram Moolenaar buf = tv_get_buf(&argvars[0], FALSE); 461*261f346fSBram Moolenaar if (buf == NULL) 462*261f346fSBram Moolenaar { 463*261f346fSBram Moolenaar rettv->vval.v_number = 1; // FAIL 464*261f346fSBram Moolenaar return; 465*261f346fSBram Moolenaar } 466*261f346fSBram Moolenaar is_curbuf = buf == curbuf; 467*261f346fSBram Moolenaar 468*261f346fSBram Moolenaar first = tv_get_lnum_buf(&argvars[1], buf); 469*261f346fSBram Moolenaar if (argvars[2].v_type != VAR_UNKNOWN) 470*261f346fSBram Moolenaar last = tv_get_lnum_buf(&argvars[2], buf); 471*261f346fSBram Moolenaar else 472*261f346fSBram Moolenaar last = first; 473*261f346fSBram Moolenaar 474*261f346fSBram Moolenaar if (buf->b_ml.ml_mfp == NULL || first < 1 475*261f346fSBram Moolenaar || first > buf->b_ml.ml_line_count || last < first) 476*261f346fSBram Moolenaar { 477*261f346fSBram Moolenaar rettv->vval.v_number = 1; // FAIL 478*261f346fSBram Moolenaar return; 479*261f346fSBram Moolenaar } 480*261f346fSBram Moolenaar 481*261f346fSBram Moolenaar if (!is_curbuf) 482*261f346fSBram Moolenaar { 483*261f346fSBram Moolenaar curbuf_save = curbuf; 484*261f346fSBram Moolenaar curwin_save = curwin; 485*261f346fSBram Moolenaar curbuf = buf; 486*261f346fSBram Moolenaar find_win_for_curbuf(); 487*261f346fSBram Moolenaar } 488*261f346fSBram Moolenaar if (last > curbuf->b_ml.ml_line_count) 489*261f346fSBram Moolenaar last = curbuf->b_ml.ml_line_count; 490*261f346fSBram Moolenaar count = last - first + 1; 491*261f346fSBram Moolenaar 492*261f346fSBram Moolenaar // When coming here from Insert mode, sync undo, so that this can be 493*261f346fSBram Moolenaar // undone separately from what was previously inserted. 494*261f346fSBram Moolenaar if (u_sync_once == 2) 495*261f346fSBram Moolenaar { 496*261f346fSBram Moolenaar u_sync_once = 1; // notify that u_sync() was called 497*261f346fSBram Moolenaar u_sync(TRUE); 498*261f346fSBram Moolenaar } 499*261f346fSBram Moolenaar 500*261f346fSBram Moolenaar if (u_save(first - 1, last + 1) == FAIL) 501*261f346fSBram Moolenaar { 502*261f346fSBram Moolenaar rettv->vval.v_number = 1; // FAIL 503*261f346fSBram Moolenaar return; 504*261f346fSBram Moolenaar } 505*261f346fSBram Moolenaar 506*261f346fSBram Moolenaar for (lnum = first; lnum <= last; ++lnum) 507*261f346fSBram Moolenaar ml_delete(first, TRUE); 508*261f346fSBram Moolenaar 509*261f346fSBram Moolenaar FOR_ALL_TAB_WINDOWS(tp, wp) 510*261f346fSBram Moolenaar if (wp->w_buffer == buf) 511*261f346fSBram Moolenaar { 512*261f346fSBram Moolenaar if (wp->w_cursor.lnum > last) 513*261f346fSBram Moolenaar wp->w_cursor.lnum -= count; 514*261f346fSBram Moolenaar else if (wp->w_cursor.lnum> first) 515*261f346fSBram Moolenaar wp->w_cursor.lnum = first; 516*261f346fSBram Moolenaar if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count) 517*261f346fSBram Moolenaar wp->w_cursor.lnum = wp->w_buffer->b_ml.ml_line_count; 518*261f346fSBram Moolenaar } 519*261f346fSBram Moolenaar check_cursor_col(); 520*261f346fSBram Moolenaar deleted_lines_mark(first, count); 521*261f346fSBram Moolenaar 522*261f346fSBram Moolenaar if (!is_curbuf) 523*261f346fSBram Moolenaar { 524*261f346fSBram Moolenaar curbuf = curbuf_save; 525*261f346fSBram Moolenaar curwin = curwin_save; 526*261f346fSBram Moolenaar } 527*261f346fSBram Moolenaar } 528*261f346fSBram Moolenaar 529*261f346fSBram Moolenaar /* 530*261f346fSBram Moolenaar * Returns buffer options, variables and other attributes in a dictionary. 531*261f346fSBram Moolenaar */ 532*261f346fSBram Moolenaar static dict_T * 533*261f346fSBram Moolenaar get_buffer_info(buf_T *buf) 534*261f346fSBram Moolenaar { 535*261f346fSBram Moolenaar dict_T *dict; 536*261f346fSBram Moolenaar tabpage_T *tp; 537*261f346fSBram Moolenaar win_T *wp; 538*261f346fSBram Moolenaar list_T *windows; 539*261f346fSBram Moolenaar 540*261f346fSBram Moolenaar dict = dict_alloc(); 541*261f346fSBram Moolenaar if (dict == NULL) 542*261f346fSBram Moolenaar return NULL; 543*261f346fSBram Moolenaar 544*261f346fSBram Moolenaar dict_add_number(dict, "bufnr", buf->b_fnum); 545*261f346fSBram Moolenaar dict_add_string(dict, "name", buf->b_ffname); 546*261f346fSBram Moolenaar dict_add_number(dict, "lnum", buf == curbuf ? curwin->w_cursor.lnum 547*261f346fSBram Moolenaar : buflist_findlnum(buf)); 548*261f346fSBram Moolenaar dict_add_number(dict, "loaded", buf->b_ml.ml_mfp != NULL); 549*261f346fSBram Moolenaar dict_add_number(dict, "listed", buf->b_p_bl); 550*261f346fSBram Moolenaar dict_add_number(dict, "changed", bufIsChanged(buf)); 551*261f346fSBram Moolenaar dict_add_number(dict, "changedtick", CHANGEDTICK(buf)); 552*261f346fSBram Moolenaar dict_add_number(dict, "hidden", 553*261f346fSBram Moolenaar buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0); 554*261f346fSBram Moolenaar 555*261f346fSBram Moolenaar // Get a reference to buffer variables 556*261f346fSBram Moolenaar dict_add_dict(dict, "variables", buf->b_vars); 557*261f346fSBram Moolenaar 558*261f346fSBram Moolenaar // List of windows displaying this buffer 559*261f346fSBram Moolenaar windows = list_alloc(); 560*261f346fSBram Moolenaar if (windows != NULL) 561*261f346fSBram Moolenaar { 562*261f346fSBram Moolenaar FOR_ALL_TAB_WINDOWS(tp, wp) 563*261f346fSBram Moolenaar if (wp->w_buffer == buf) 564*261f346fSBram Moolenaar list_append_number(windows, (varnumber_T)wp->w_id); 565*261f346fSBram Moolenaar dict_add_list(dict, "windows", windows); 566*261f346fSBram Moolenaar } 567*261f346fSBram Moolenaar 568*261f346fSBram Moolenaar #ifdef FEAT_TEXT_PROP 569*261f346fSBram Moolenaar // List of popup windows displaying this buffer 570*261f346fSBram Moolenaar windows = list_alloc(); 571*261f346fSBram Moolenaar if (windows != NULL) 572*261f346fSBram Moolenaar { 573*261f346fSBram Moolenaar for (wp = first_popupwin; wp != NULL; wp = wp->w_next) 574*261f346fSBram Moolenaar if (wp->w_buffer == buf) 575*261f346fSBram Moolenaar list_append_number(windows, (varnumber_T)wp->w_id); 576*261f346fSBram Moolenaar FOR_ALL_TABPAGES(tp) 577*261f346fSBram Moolenaar for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) 578*261f346fSBram Moolenaar if (wp->w_buffer == buf) 579*261f346fSBram Moolenaar list_append_number(windows, (varnumber_T)wp->w_id); 580*261f346fSBram Moolenaar 581*261f346fSBram Moolenaar dict_add_list(dict, "popups", windows); 582*261f346fSBram Moolenaar } 583*261f346fSBram Moolenaar #endif 584*261f346fSBram Moolenaar 585*261f346fSBram Moolenaar #ifdef FEAT_SIGNS 586*261f346fSBram Moolenaar if (buf->b_signlist != NULL) 587*261f346fSBram Moolenaar { 588*261f346fSBram Moolenaar // List of signs placed in this buffer 589*261f346fSBram Moolenaar list_T *signs = list_alloc(); 590*261f346fSBram Moolenaar if (signs != NULL) 591*261f346fSBram Moolenaar { 592*261f346fSBram Moolenaar get_buffer_signs(buf, signs); 593*261f346fSBram Moolenaar dict_add_list(dict, "signs", signs); 594*261f346fSBram Moolenaar } 595*261f346fSBram Moolenaar } 596*261f346fSBram Moolenaar #endif 597*261f346fSBram Moolenaar 598*261f346fSBram Moolenaar return dict; 599*261f346fSBram Moolenaar } 600*261f346fSBram Moolenaar 601*261f346fSBram Moolenaar /* 602*261f346fSBram Moolenaar * "getbufinfo()" function 603*261f346fSBram Moolenaar */ 604*261f346fSBram Moolenaar void 605*261f346fSBram Moolenaar f_getbufinfo(typval_T *argvars, typval_T *rettv) 606*261f346fSBram Moolenaar { 607*261f346fSBram Moolenaar buf_T *buf = NULL; 608*261f346fSBram Moolenaar buf_T *argbuf = NULL; 609*261f346fSBram Moolenaar dict_T *d; 610*261f346fSBram Moolenaar int filtered = FALSE; 611*261f346fSBram Moolenaar int sel_buflisted = FALSE; 612*261f346fSBram Moolenaar int sel_bufloaded = FALSE; 613*261f346fSBram Moolenaar int sel_bufmodified = FALSE; 614*261f346fSBram Moolenaar 615*261f346fSBram Moolenaar if (rettv_list_alloc(rettv) != OK) 616*261f346fSBram Moolenaar return; 617*261f346fSBram Moolenaar 618*261f346fSBram Moolenaar // List of all the buffers or selected buffers 619*261f346fSBram Moolenaar if (argvars[0].v_type == VAR_DICT) 620*261f346fSBram Moolenaar { 621*261f346fSBram Moolenaar dict_T *sel_d = argvars[0].vval.v_dict; 622*261f346fSBram Moolenaar 623*261f346fSBram Moolenaar if (sel_d != NULL) 624*261f346fSBram Moolenaar { 625*261f346fSBram Moolenaar dictitem_T *di; 626*261f346fSBram Moolenaar 627*261f346fSBram Moolenaar filtered = TRUE; 628*261f346fSBram Moolenaar 629*261f346fSBram Moolenaar di = dict_find(sel_d, (char_u *)"buflisted", -1); 630*261f346fSBram Moolenaar if (di != NULL && tv_get_number(&di->di_tv)) 631*261f346fSBram Moolenaar sel_buflisted = TRUE; 632*261f346fSBram Moolenaar 633*261f346fSBram Moolenaar di = dict_find(sel_d, (char_u *)"bufloaded", -1); 634*261f346fSBram Moolenaar if (di != NULL && tv_get_number(&di->di_tv)) 635*261f346fSBram Moolenaar sel_bufloaded = TRUE; 636*261f346fSBram Moolenaar 637*261f346fSBram Moolenaar di = dict_find(sel_d, (char_u *)"bufmodified", -1); 638*261f346fSBram Moolenaar if (di != NULL && tv_get_number(&di->di_tv)) 639*261f346fSBram Moolenaar sel_bufmodified = TRUE; 640*261f346fSBram Moolenaar } 641*261f346fSBram Moolenaar } 642*261f346fSBram Moolenaar else if (argvars[0].v_type != VAR_UNKNOWN) 643*261f346fSBram Moolenaar { 644*261f346fSBram Moolenaar // Information about one buffer. Argument specifies the buffer 645*261f346fSBram Moolenaar (void)tv_get_number(&argvars[0]); // issue errmsg if type error 646*261f346fSBram Moolenaar ++emsg_off; 647*261f346fSBram Moolenaar argbuf = tv_get_buf(&argvars[0], FALSE); 648*261f346fSBram Moolenaar --emsg_off; 649*261f346fSBram Moolenaar if (argbuf == NULL) 650*261f346fSBram Moolenaar return; 651*261f346fSBram Moolenaar } 652*261f346fSBram Moolenaar 653*261f346fSBram Moolenaar // Return information about all the buffers or a specified buffer 654*261f346fSBram Moolenaar FOR_ALL_BUFFERS(buf) 655*261f346fSBram Moolenaar { 656*261f346fSBram Moolenaar if (argbuf != NULL && argbuf != buf) 657*261f346fSBram Moolenaar continue; 658*261f346fSBram Moolenaar if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL) 659*261f346fSBram Moolenaar || (sel_buflisted && !buf->b_p_bl) 660*261f346fSBram Moolenaar || (sel_bufmodified && !buf->b_changed))) 661*261f346fSBram Moolenaar continue; 662*261f346fSBram Moolenaar 663*261f346fSBram Moolenaar d = get_buffer_info(buf); 664*261f346fSBram Moolenaar if (d != NULL) 665*261f346fSBram Moolenaar list_append_dict(rettv->vval.v_list, d); 666*261f346fSBram Moolenaar if (argbuf != NULL) 667*261f346fSBram Moolenaar return; 668*261f346fSBram Moolenaar } 669*261f346fSBram Moolenaar } 670*261f346fSBram Moolenaar 671*261f346fSBram Moolenaar /* 672*261f346fSBram Moolenaar * Get line or list of lines from buffer "buf" into "rettv". 673*261f346fSBram Moolenaar * Return a range (from start to end) of lines in rettv from the specified 674*261f346fSBram Moolenaar * buffer. 675*261f346fSBram Moolenaar * If 'retlist' is TRUE, then the lines are returned as a Vim List. 676*261f346fSBram Moolenaar */ 677*261f346fSBram Moolenaar static void 678*261f346fSBram Moolenaar get_buffer_lines( 679*261f346fSBram Moolenaar buf_T *buf, 680*261f346fSBram Moolenaar linenr_T start, 681*261f346fSBram Moolenaar linenr_T end, 682*261f346fSBram Moolenaar int retlist, 683*261f346fSBram Moolenaar typval_T *rettv) 684*261f346fSBram Moolenaar { 685*261f346fSBram Moolenaar char_u *p; 686*261f346fSBram Moolenaar 687*261f346fSBram Moolenaar rettv->v_type = VAR_STRING; 688*261f346fSBram Moolenaar rettv->vval.v_string = NULL; 689*261f346fSBram Moolenaar if (retlist && rettv_list_alloc(rettv) == FAIL) 690*261f346fSBram Moolenaar return; 691*261f346fSBram Moolenaar 692*261f346fSBram Moolenaar if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 693*261f346fSBram Moolenaar return; 694*261f346fSBram Moolenaar 695*261f346fSBram Moolenaar if (!retlist) 696*261f346fSBram Moolenaar { 697*261f346fSBram Moolenaar if (start >= 1 && start <= buf->b_ml.ml_line_count) 698*261f346fSBram Moolenaar p = ml_get_buf(buf, start, FALSE); 699*261f346fSBram Moolenaar else 700*261f346fSBram Moolenaar p = (char_u *)""; 701*261f346fSBram Moolenaar rettv->vval.v_string = vim_strsave(p); 702*261f346fSBram Moolenaar } 703*261f346fSBram Moolenaar else 704*261f346fSBram Moolenaar { 705*261f346fSBram Moolenaar if (end < start) 706*261f346fSBram Moolenaar return; 707*261f346fSBram Moolenaar 708*261f346fSBram Moolenaar if (start < 1) 709*261f346fSBram Moolenaar start = 1; 710*261f346fSBram Moolenaar if (end > buf->b_ml.ml_line_count) 711*261f346fSBram Moolenaar end = buf->b_ml.ml_line_count; 712*261f346fSBram Moolenaar while (start <= end) 713*261f346fSBram Moolenaar if (list_append_string(rettv->vval.v_list, 714*261f346fSBram Moolenaar ml_get_buf(buf, start++, FALSE), -1) == FAIL) 715*261f346fSBram Moolenaar break; 716*261f346fSBram Moolenaar } 717*261f346fSBram Moolenaar } 718*261f346fSBram Moolenaar 719*261f346fSBram Moolenaar /* 720*261f346fSBram Moolenaar * "getbufline()" function 721*261f346fSBram Moolenaar */ 722*261f346fSBram Moolenaar void 723*261f346fSBram Moolenaar f_getbufline(typval_T *argvars, typval_T *rettv) 724*261f346fSBram Moolenaar { 725*261f346fSBram Moolenaar linenr_T lnum; 726*261f346fSBram Moolenaar linenr_T end; 727*261f346fSBram Moolenaar buf_T *buf; 728*261f346fSBram Moolenaar 729*261f346fSBram Moolenaar (void)tv_get_number(&argvars[0]); // issue errmsg if type error 730*261f346fSBram Moolenaar ++emsg_off; 731*261f346fSBram Moolenaar buf = tv_get_buf(&argvars[0], FALSE); 732*261f346fSBram Moolenaar --emsg_off; 733*261f346fSBram Moolenaar 734*261f346fSBram Moolenaar lnum = tv_get_lnum_buf(&argvars[1], buf); 735*261f346fSBram Moolenaar if (argvars[2].v_type == VAR_UNKNOWN) 736*261f346fSBram Moolenaar end = lnum; 737*261f346fSBram Moolenaar else 738*261f346fSBram Moolenaar end = tv_get_lnum_buf(&argvars[2], buf); 739*261f346fSBram Moolenaar 740*261f346fSBram Moolenaar get_buffer_lines(buf, lnum, end, TRUE, rettv); 741*261f346fSBram Moolenaar } 742*261f346fSBram Moolenaar 743*261f346fSBram Moolenaar /* 744*261f346fSBram Moolenaar * "getline(lnum, [end])" function 745*261f346fSBram Moolenaar */ 746*261f346fSBram Moolenaar void 747*261f346fSBram Moolenaar f_getline(typval_T *argvars, typval_T *rettv) 748*261f346fSBram Moolenaar { 749*261f346fSBram Moolenaar linenr_T lnum; 750*261f346fSBram Moolenaar linenr_T end; 751*261f346fSBram Moolenaar int retlist; 752*261f346fSBram Moolenaar 753*261f346fSBram Moolenaar lnum = tv_get_lnum(argvars); 754*261f346fSBram Moolenaar if (argvars[1].v_type == VAR_UNKNOWN) 755*261f346fSBram Moolenaar { 756*261f346fSBram Moolenaar end = 0; 757*261f346fSBram Moolenaar retlist = FALSE; 758*261f346fSBram Moolenaar } 759*261f346fSBram Moolenaar else 760*261f346fSBram Moolenaar { 761*261f346fSBram Moolenaar end = tv_get_lnum(&argvars[1]); 762*261f346fSBram Moolenaar retlist = TRUE; 763*261f346fSBram Moolenaar } 764*261f346fSBram Moolenaar 765*261f346fSBram Moolenaar get_buffer_lines(curbuf, lnum, end, retlist, rettv); 766*261f346fSBram Moolenaar } 767*261f346fSBram Moolenaar 768*261f346fSBram Moolenaar /* 769*261f346fSBram Moolenaar * "setbufline()" function 770*261f346fSBram Moolenaar */ 771*261f346fSBram Moolenaar void 772*261f346fSBram Moolenaar f_setbufline(typval_T *argvars, typval_T *rettv) 773*261f346fSBram Moolenaar { 774*261f346fSBram Moolenaar linenr_T lnum; 775*261f346fSBram Moolenaar buf_T *buf; 776*261f346fSBram Moolenaar 777*261f346fSBram Moolenaar buf = tv_get_buf(&argvars[0], FALSE); 778*261f346fSBram Moolenaar if (buf == NULL) 779*261f346fSBram Moolenaar rettv->vval.v_number = 1; // FAIL 780*261f346fSBram Moolenaar else 781*261f346fSBram Moolenaar { 782*261f346fSBram Moolenaar lnum = tv_get_lnum_buf(&argvars[1], buf); 783*261f346fSBram Moolenaar set_buffer_lines(buf, lnum, FALSE, &argvars[2], rettv); 784*261f346fSBram Moolenaar } 785*261f346fSBram Moolenaar } 786*261f346fSBram Moolenaar 787*261f346fSBram Moolenaar /* 788*261f346fSBram Moolenaar * "setline()" function 789*261f346fSBram Moolenaar */ 790*261f346fSBram Moolenaar void 791*261f346fSBram Moolenaar f_setline(typval_T *argvars, typval_T *rettv) 792*261f346fSBram Moolenaar { 793*261f346fSBram Moolenaar linenr_T lnum = tv_get_lnum(&argvars[0]); 794*261f346fSBram Moolenaar 795*261f346fSBram Moolenaar set_buffer_lines(curbuf, lnum, FALSE, &argvars[1], rettv); 796*261f346fSBram Moolenaar } 797*261f346fSBram Moolenaar #endif // FEAT_EVAL 798*261f346fSBram Moolenaar 799*261f346fSBram Moolenaar #if defined(FEAT_JOB_CHANNEL) \ 800*261f346fSBram Moolenaar || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ 801*261f346fSBram Moolenaar || defined(PROTO) 802*261f346fSBram Moolenaar /* 803*261f346fSBram Moolenaar * Make "buf" the current buffer. restore_buffer() MUST be called to undo. 804*261f346fSBram Moolenaar * No autocommands will be executed. Use aucmd_prepbuf() if there are any. 805*261f346fSBram Moolenaar */ 806*261f346fSBram Moolenaar void 807*261f346fSBram Moolenaar switch_buffer(bufref_T *save_curbuf, buf_T *buf) 808*261f346fSBram Moolenaar { 809*261f346fSBram Moolenaar block_autocmds(); 810*261f346fSBram Moolenaar set_bufref(save_curbuf, curbuf); 811*261f346fSBram Moolenaar --curbuf->b_nwindows; 812*261f346fSBram Moolenaar curbuf = buf; 813*261f346fSBram Moolenaar curwin->w_buffer = buf; 814*261f346fSBram Moolenaar ++curbuf->b_nwindows; 815*261f346fSBram Moolenaar } 816*261f346fSBram Moolenaar 817*261f346fSBram Moolenaar /* 818*261f346fSBram Moolenaar * Restore the current buffer after using switch_buffer(). 819*261f346fSBram Moolenaar */ 820*261f346fSBram Moolenaar void 821*261f346fSBram Moolenaar restore_buffer(bufref_T *save_curbuf) 822*261f346fSBram Moolenaar { 823*261f346fSBram Moolenaar unblock_autocmds(); 824*261f346fSBram Moolenaar /* Check for valid buffer, just in case. */ 825*261f346fSBram Moolenaar if (bufref_valid(save_curbuf)) 826*261f346fSBram Moolenaar { 827*261f346fSBram Moolenaar --curbuf->b_nwindows; 828*261f346fSBram Moolenaar curwin->w_buffer = save_curbuf->br_buf; 829*261f346fSBram Moolenaar curbuf = save_curbuf->br_buf; 830*261f346fSBram Moolenaar ++curbuf->b_nwindows; 831*261f346fSBram Moolenaar } 832*261f346fSBram Moolenaar } 833*261f346fSBram Moolenaar 834*261f346fSBram Moolenaar /* 835*261f346fSBram Moolenaar * Find a window for buffer "buf". 836*261f346fSBram Moolenaar * If found OK is returned and "wp" and "tp" are set to the window and tabpage. 837*261f346fSBram Moolenaar * If not found FAIL is returned. 838*261f346fSBram Moolenaar */ 839*261f346fSBram Moolenaar static int 840*261f346fSBram Moolenaar find_win_for_buf( 841*261f346fSBram Moolenaar buf_T *buf, 842*261f346fSBram Moolenaar win_T **wp, 843*261f346fSBram Moolenaar tabpage_T **tp) 844*261f346fSBram Moolenaar { 845*261f346fSBram Moolenaar FOR_ALL_TAB_WINDOWS(*tp, *wp) 846*261f346fSBram Moolenaar if ((*wp)->w_buffer == buf) 847*261f346fSBram Moolenaar return OK; 848*261f346fSBram Moolenaar return FAIL; 849*261f346fSBram Moolenaar } 850*261f346fSBram Moolenaar 851*261f346fSBram Moolenaar /* 852*261f346fSBram Moolenaar * Find a window that contains "buf" and switch to it. 853*261f346fSBram Moolenaar * If there is no such window, use the current window and change "curbuf". 854*261f346fSBram Moolenaar * Caller must initialize save_curbuf to NULL. 855*261f346fSBram Moolenaar * restore_win_for_buf() MUST be called later! 856*261f346fSBram Moolenaar */ 857*261f346fSBram Moolenaar void 858*261f346fSBram Moolenaar switch_to_win_for_buf( 859*261f346fSBram Moolenaar buf_T *buf, 860*261f346fSBram Moolenaar win_T **save_curwinp, 861*261f346fSBram Moolenaar tabpage_T **save_curtabp, 862*261f346fSBram Moolenaar bufref_T *save_curbuf) 863*261f346fSBram Moolenaar { 864*261f346fSBram Moolenaar win_T *wp; 865*261f346fSBram Moolenaar tabpage_T *tp; 866*261f346fSBram Moolenaar 867*261f346fSBram Moolenaar if (find_win_for_buf(buf, &wp, &tp) == FAIL) 868*261f346fSBram Moolenaar switch_buffer(save_curbuf, buf); 869*261f346fSBram Moolenaar else if (switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL) 870*261f346fSBram Moolenaar { 871*261f346fSBram Moolenaar restore_win(*save_curwinp, *save_curtabp, TRUE); 872*261f346fSBram Moolenaar switch_buffer(save_curbuf, buf); 873*261f346fSBram Moolenaar } 874*261f346fSBram Moolenaar } 875*261f346fSBram Moolenaar 876*261f346fSBram Moolenaar void 877*261f346fSBram Moolenaar restore_win_for_buf( 878*261f346fSBram Moolenaar win_T *save_curwin, 879*261f346fSBram Moolenaar tabpage_T *save_curtab, 880*261f346fSBram Moolenaar bufref_T *save_curbuf) 881*261f346fSBram Moolenaar { 882*261f346fSBram Moolenaar if (save_curbuf->br_buf == NULL) 883*261f346fSBram Moolenaar restore_win(save_curwin, save_curtab, TRUE); 884*261f346fSBram Moolenaar else 885*261f346fSBram Moolenaar restore_buffer(save_curbuf); 886*261f346fSBram Moolenaar } 887*261f346fSBram Moolenaar #endif 888