From 261f346f8154c0ec7094a4a211c653c74e9f7c2e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 7 Sep 2019 15:45:32 +0200 Subject: patch 8.1.2001: some source files are too big Problem: Some source files are too big. Solution: Move buffer and window related functions to evalbuffer.c and evalwindow.c. (Yegappan Lakshmanan, closes #4898) --- src/Make_cyg_ming.mak | 2 + src/Make_morph.mak | 2 + src/Make_mvc.mak | 8 + src/Make_vms.mms | 17 +- src/Makefile | 20 + src/README.md | 2 + src/buffer.c | 105 ---- src/channel.c | 6 +- src/evalbuffer.c | 887 +++++++++++++++++++++++++++ src/evalfunc.c | 1511 ++-------------------------------------------- src/evalwindow.c | 1054 ++++++++++++++++++++++++++++++++ src/proto.h | 4 +- src/proto/buffer.pro | 3 - src/proto/evalbuffer.pro | 26 + src/proto/evalfunc.pro | 2 + src/proto/evalwindow.pro | 36 ++ src/proto/window.pro | 17 - src/version.c | 2 + src/window.c | 447 -------------- 19 files changed, 2114 insertions(+), 2037 deletions(-) create mode 100644 src/evalbuffer.c create mode 100644 src/evalwindow.c create mode 100644 src/proto/evalbuffer.pro create mode 100644 src/proto/evalwindow.pro (limited to 'src') diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 9f86cef72d..bd2dba26cd 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -721,8 +721,10 @@ OBJ = \ $(OUTDIR)/digraph.o \ $(OUTDIR)/edit.o \ $(OUTDIR)/eval.o \ + $(OUTDIR)/evalbuffer.o \ $(OUTDIR)/evalfunc.o \ $(OUTDIR)/evalvars.o \ + $(OUTDIR)/evalwindow.o \ $(OUTDIR)/ex_cmds.o \ $(OUTDIR)/ex_cmds2.o \ $(OUTDIR)/ex_docmd.o \ diff --git a/src/Make_morph.mak b/src/Make_morph.mak index 09e514c249..3f896da5b6 100644 --- a/src/Make_morph.mak +++ b/src/Make_morph.mak @@ -41,8 +41,10 @@ SRC = arabic.c \ digraph.c \ edit.c \ eval.c \ + evalbuffer.c \ evalfunc.c \ evalvars.c \ + evalwindow.c \ ex_cmds.c \ ex_cmds2.c \ ex_docmd.c \ diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index 31970faf32..0401902f22 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -728,8 +728,10 @@ OBJ = \ $(OUTDIR)\digraph.obj \ $(OUTDIR)\edit.obj \ $(OUTDIR)\eval.obj \ + $(OUTDIR)\evalbuffer.obj \ $(OUTDIR)\evalfunc.obj \ $(OUTDIR)\evalvars.obj \ + $(OUTDIR)\evalwindow.obj \ $(OUTDIR)\ex_cmds.obj \ $(OUTDIR)\ex_cmds2.obj \ $(OUTDIR)\ex_docmd.obj \ @@ -1485,10 +1487,14 @@ $(OUTDIR)/edit.obj: $(OUTDIR) edit.c $(INCL) $(OUTDIR)/eval.obj: $(OUTDIR) eval.c $(INCL) +$(OUTDIR)/evalbuffer.obj: $(OUTDIR) evalbuffer.c $(INCL) + $(OUTDIR)/evalfunc.obj: $(OUTDIR) evalfunc.c $(INCL) $(OUTDIR)/evalvars.obj: $(OUTDIR) evalvars.c $(INCL) +$(OUTDIR)/evalwindow.obj: $(OUTDIR) evalwindow.c $(INCL) + $(OUTDIR)/ex_cmds.obj: $(OUTDIR) ex_cmds.c $(INCL) $(OUTDIR)/ex_cmds2.obj: $(OUTDIR) ex_cmds2.c $(INCL) @@ -1775,8 +1781,10 @@ proto.h: \ proto/digraph.pro \ proto/edit.pro \ proto/eval.pro \ + proto/evalbuffer.pro \ proto/evalfunc.pro \ proto/evalvars.pro \ + proto/evalwindow.pro \ proto/ex_cmds.pro \ proto/ex_cmds2.pro \ proto/ex_docmd.pro \ diff --git a/src/Make_vms.mms b/src/Make_vms.mms index 5b4075de83..607f564352 100644 --- a/src/Make_vms.mms +++ b/src/Make_vms.mms @@ -309,8 +309,10 @@ ALL_LIBS = $(LIBS) $(GUI_LIB_DIR) $(GUI_LIB) \ SRC = arabic.c arglist.c autocmd.c beval.c blob.c blowfish.c buffer.c \ change.c charset.c cmdexpand.c cmdhist.c crypt.c crypt_zip.c \ - debugger.c dict.c diff.c digraph.c edit.c eval.c evalfunc.c \ - evalvars.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c \ + debugger.c dict.c diff.c digraph.c edit.c eval.c evalbuffer.c \ + evalfunc.c \ + evalvars.c evalwindow.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c \ + ex_getln.c \ if_cscope.c if_xcmdsrv.c fileio.c filepath.c, findfile.c fold.c \ getchar.c hardcopy.c hashtab.c highlight.c \ indent.c insexpand.c json.c list.c main.c map.c mark.c menu.c mbyte.c \ @@ -327,7 +329,8 @@ SRC = arabic.c arglist.c autocmd.c beval.c blob.c blowfish.c buffer.c \ OBJ = arabic.obj arglist.obj autocmd.obj beval.obj blob.obj blowfish.obj \ buffer.obj change.obj charset.obj cmdexpand.obj cmdhist.obj \ crypt.obj crypt_zip.obj debugger.obj dict.obj diff.obj digraph.obj \ - edit.obj eval.obj evalfunc.obj evalvars.obj ex_cmds.obj ex_cmds2.obj \ + edit.obj eval.obj evalbuffer.obj evalfunc.obj evalvars.obj \ + evalwindow.obj ex_cmds.obj ex_cmds2.obj \ ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj if_xcmdsrv.obj \ fileio.obj filepath.obj \ findfile.obj fold.obj getchar.obj hardcopy.obj hashtab.obj \ @@ -567,6 +570,10 @@ eval.obj : eval.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \ version.h +evalbuffer.obj : evalbuffer.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h option.h structs.h \ + regexp.h gui.h beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h \ + proto.h globals.h version.h evalfunc.obj : evalfunc.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h option.h structs.h \ regexp.h gui.h beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h \ @@ -575,6 +582,10 @@ evalvars.obj : evalvars.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h option.h structs.h \ regexp.h gui.h beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h \ proto.h globals.h version.h +evalwindow.obj : evalwindow.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h option.h structs.h \ + regexp.h gui.h beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h \ + proto.h globals.h version.h ex_cmds.obj : ex_cmds.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ diff --git a/src/Makefile b/src/Makefile index 840e3fe1e2..34d1c145af 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1595,8 +1595,10 @@ BASIC_SRC = \ digraph.c \ edit.c \ eval.c \ + evalbuffer.c \ evalfunc.c \ evalvars.c \ + evalwindow.c \ ex_cmds.c \ ex_cmds2.c \ ex_docmd.c \ @@ -1726,8 +1728,10 @@ OBJ_COMMON = \ objects/digraph.o \ objects/edit.o \ objects/eval.o \ + objects/evalbuffer.o \ objects/evalfunc.o \ objects/evalvars.o \ + objects/evalwindow.o \ objects/ex_cmds.o \ objects/ex_cmds2.o \ objects/ex_docmd.o \ @@ -1870,8 +1874,10 @@ PRO_AUTO = \ digraph.pro \ edit.pro \ eval.pro \ + evalbuffer.pro \ evalfunc.pro \ evalvars.pro \ + evalwindow.pro \ ex_cmds.pro \ ex_cmds2.pro \ ex_docmd.pro \ @@ -3080,12 +3086,18 @@ objects/edit.o: edit.c objects/eval.o: eval.c $(CCC) -o $@ eval.c +objects/evalbuffer.o: evalbuffer.c + $(CCC) -o $@ evalbuffer.c + objects/evalfunc.o: evalfunc.c $(CCC) -o $@ evalfunc.c objects/evalvars.o: evalvars.c $(CCC) -o $@ evalvars.c +objects/evalwindow.o: evalwindow.c + $(CCC) -o $@ evalwindow.c + objects/ex_cmds.o: ex_cmds.c $(CCC) -o $@ ex_cmds.c @@ -3603,6 +3615,10 @@ objects/eval.o: eval.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h version.h +objects/evalbuffer.o: evalbuffer.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h version.h objects/evalfunc.o: evalfunc.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ @@ -3611,6 +3627,10 @@ objects/evalvars.o: evalvars.c vim.h protodef.h auto/config.h feature.h \ os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/evalwindow.o: evalwindow.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/ex_cmds.o: ex_cmds.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff --git a/src/README.md b/src/README.md index dcc7a5c83c..6ba83910ee 100644 --- a/src/README.md +++ b/src/README.md @@ -33,8 +33,10 @@ cmdhist.c | command-line history debugger.c | vim script debugger diff.c | diff mode (vimdiff) eval.c | expression evaluation +evalbuffer.c | buffer related built-in functions evalfunc.c | built-in functions evalvars.c | vim variables +evalwindow.c | window related built-in functions fileio.c | reading and writing files filepath.c | dealing with file names and paths findfile.c | search for files in 'path' diff --git a/src/buffer.c b/src/buffer.c index c42dece642..81f2799f49 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5450,66 +5450,6 @@ buf_spname(buf_T *buf) return NULL; } -#if defined(FEAT_JOB_CHANNEL) \ - || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ - || defined(PROTO) -/* - * Find a window for buffer "buf". - * If found OK is returned and "wp" and "tp" are set to the window and tabpage. - * If not found FAIL is returned. - */ - static int -find_win_for_buf( - buf_T *buf, - win_T **wp, - tabpage_T **tp) -{ - FOR_ALL_TAB_WINDOWS(*tp, *wp) - if ((*wp)->w_buffer == buf) - goto win_found; - return FAIL; -win_found: - return OK; -} - -/* - * Find a window that contains "buf" and switch to it. - * If there is no such window, use the current window and change "curbuf". - * Caller must initialize save_curbuf to NULL. - * restore_win_for_buf() MUST be called later! - */ - void -switch_to_win_for_buf( - buf_T *buf, - win_T **save_curwinp, - tabpage_T **save_curtabp, - bufref_T *save_curbuf) -{ - win_T *wp; - tabpage_T *tp; - - if (find_win_for_buf(buf, &wp, &tp) == FAIL) - switch_buffer(save_curbuf, buf); - else if (switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL) - { - restore_win(*save_curwinp, *save_curtabp, TRUE); - switch_buffer(save_curbuf, buf); - } -} - - void -restore_win_for_buf( - win_T *save_curwin, - tabpage_T *save_curtab, - bufref_T *save_curbuf) -{ - if (save_curbuf->br_buf == NULL) - restore_win(save_curwin, save_curtab, TRUE); - else - restore_buffer(save_curbuf); -} -#endif - /* * Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed. */ @@ -5603,48 +5543,3 @@ wipe_buffer( if (!aucmd) unblock_autocmds(); } - -#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; - typval_T tv; - - for (lnr = bp->b_listener; !abort && lnr != NULL; lnr = lnr->lr_next) - { - if (lnr->lr_callback.cb_partial != NULL) - { - tv.v_type = VAR_PARTIAL; - tv.vval.v_partial = lnr->lr_callback.cb_partial; - abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); - } - } -# ifdef FEAT_JOB_CHANNEL - if (!abort && bp->b_prompt_callback.cb_partial != NULL) - { - tv.v_type = VAR_PARTIAL; - tv.vval.v_partial = bp->b_prompt_callback.cb_partial; - abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); - } - if (!abort && bp->b_prompt_interrupt.cb_partial != NULL) - { - tv.v_type = VAR_PARTIAL; - tv.vval.v_partial = bp->b_prompt_interrupt.cb_partial; - abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); - } -# endif - if (abort) - break; - } - return abort; -} -#endif diff --git a/src/channel.c b/src/channel.c index b4493cf752..e4dbcf6039 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1036,7 +1036,7 @@ prepare_buffer(buf_T *buf) * Returns NULL if there is something very wrong (error already reported). */ static buf_T * -find_buffer(char_u *name, int err, int msg) +channel_find_buffer(char_u *name, int err, int msg) { buf_T *buf = NULL; buf_T *save_curbuf = curbuf; @@ -1126,7 +1126,7 @@ channel_set_options(channel_T *channel, jobopt_T *opt) if (opt->jo_set2 & JO2_OUT_MSG) msg = opt->jo_message[PART_OUT]; - buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE, msg); + buf = channel_find_buffer(opt->jo_io_name[PART_OUT], FALSE, msg); } if (buf != NULL) { @@ -1173,7 +1173,7 @@ channel_set_options(channel_T *channel, jobopt_T *opt) if (opt->jo_set2 & JO2_ERR_MSG) msg = opt->jo_message[PART_ERR]; - buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE, msg); + buf = channel_find_buffer(opt->jo_io_name[PART_ERR], TRUE, msg); } if (buf != NULL) { diff --git a/src/evalbuffer.c b/src/evalbuffer.c new file mode 100644 index 0000000000..35c9ed2459 --- /dev/null +++ b/src/evalbuffer.c @@ -0,0 +1,887 @@ +/* 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; + typval_T tv; + + for (lnr = bp->b_listener; !abort && lnr != NULL; lnr = lnr->lr_next) + { + if (lnr->lr_callback.cb_partial != NULL) + { + tv.v_type = VAR_PARTIAL; + tv.vval.v_partial = lnr->lr_callback.cb_partial; + abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); + } + } +# ifdef FEAT_JOB_CHANNEL + if (!abort && bp->b_prompt_callback.cb_partial != NULL) + { + tv.v_type = VAR_PARTIAL; + tv.vval.v_partial = bp->b_prompt_callback.cb_partial; + abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); + } + if (!abort && bp->b_prompt_interrupt.cb_partial != NULL) + { + tv.v_type = VAR_PARTIAL; + tv.vval.v_partial = bp->b_prompt_interrupt.cb_partial; + abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); + } +# endif + 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 = (char_u *)""; + + 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 (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) +#ifdef FEAT_QUICKFIX + || bt_nofilename(buf) +#endif + ) + && 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 (wip = curbuf->b_wininfo; wip != NULL; wip = wip->wi_next) + { + if (wip->wi_win != NULL) + { + curwin = wip->wi_win; + break; + } + } +} + +/* + * Set line or list of lines in buffer "buf". + */ + 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; + + // 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 + return; + } + + if (!is_curbuf) + { + curbuf_save = curbuf; + curwin_save = curwin; + curbuf = buf; + find_win_for_curbuf(); + } + + if (append) + // appendbufline() uses the line number below which we insert + append_lnum = lnum - 1; + else + // setbufline() uses the line number above which we insert, we only + // append if it's below the last line + append_lnum = curbuf->b_ml.ml_line_count; + + if (lines->v_type == VAR_LIST) + { + l = lines->vval.v_list; + li = l->lv_first; + } + else + line = tv_get_string_chk(lines); + + // default result is zero == OK + for (;;) + { + if (l != NULL) + { + // list argument, get next string + if (li == NULL) + break; + line = tv_get_string_chk(&li->li_tv); + li = li->li_next; + } + + rettv->vval.v_number = 1; // FAIL + if (line == NULL || lnum > curbuf->b_ml.ml_line_count + 1) + break; + + // 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 (!append && lnum <= curbuf->b_ml.ml_line_count) + { + // Existing line, replace it. + // Removes any existing text properties. + if (u_savesub(lnum) == OK && ml_replace_len( + lnum, line, (colnr_T)STRLEN(line) + 1, TRUE, TRUE) == OK) + { + changed_bytes(lnum, 0); + if (is_curbuf && lnum == curwin->w_cursor.lnum) + check_cursor_col(); + rettv->vval.v_number = 0; // OK + } + } + else if (added > 0 || u_save(lnum - 1, lnum) == OK) + { + // 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) + { + win_T *wp; + tabpage_T *tp; + + appended_lines_mark(append_lnum, added); + + // Only adjust the cursor for buffers other than the current, unless it + // is the current window. For curbuf and other windows it has been + // done in mark_adjust_internal(). + FOR_ALL_TAB_WINDOWS(tp, wp) + if (wp->w_buffer == buf + && (wp->w_buffer != curbuf || wp == curwin) + && wp->w_cursor.lnum > append_lnum) + wp->w_cursor.lnum += added; + check_cursor_col(); + update_topline(); + } + + if (!is_curbuf) + { + curbuf = curbuf_save; + curwin = curwin_save; + } +} + +/* + * "append(lnum, string/list)" function + */ + void +f_append(typval_T *argvars, typval_T *rettv) +{ + linenr_T lnum = tv_get_lnum(&argvars[0]); + + set_buffer_lines(curbuf, lnum, TRUE, &argvars[1], rettv); +} + +/* + * "appendbufline(buf, lnum, string/list)" function + */ + void +f_appendbufline(typval_T *argvars, typval_T *rettv) +{ + linenr_T lnum; + buf_T *buf; + + buf = tv_get_buf(&argvars[0], FALSE); + if (buf == NULL) + rettv->vval.v_number = 1; // FAIL + else + { + lnum = tv_get_lnum_buf(&argvars[1], buf); + set_buffer_lines(buf, lnum, TRUE, &argvars[2], rettv); + } +} + +/* + * "bufadd(expr)" function + */ + void +f_bufadd(typval_T *argvars, typval_T *rettv) +{ + char_u *name = tv_get_string(&argvars[0]); + + rettv->vval.v_number = buflist_add(*name == NUL ? NULL : name, 0); +} + +/* + * "bufexists(expr)" function + */ + void +f_bufexists(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); +} + +/* + * "buflisted(expr)" function + */ + void +f_buflisted(typval_T *argvars, typval_T *rettv) +{ + buf_T *buf; + + buf = find_buffer(&argvars[0]); + rettv->vval.v_number = (buf != NULL && buf->b_p_bl); +} + +/* + * "bufload(expr)" function + */ + void +f_bufload(typval_T *argvars, typval_T *rettv UNUSED) +{ + buf_T *buf = get_buf_arg(&argvars[0]); + + if (buf != NULL) + buffer_ensure_loaded(buf); +} + +/* + * "bufloaded(expr)" function + */ + void +f_bufloaded(typval_T *argvars, typval_T *rettv) +{ + buf_T *buf; + + buf = find_buffer(&argvars[0]); + rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); +} + +/* + * "bufname(expr)" function + */ + void +f_bufname(typval_T *argvars, typval_T *rettv) +{ + buf_T *buf; + + if (argvars[0].v_type == VAR_UNKNOWN) + buf = curbuf; + else + { + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + ++emsg_off; + buf = tv_get_buf(&argvars[0], FALSE); + --emsg_off; + } + rettv->v_type = VAR_STRING; + if (buf != NULL && buf->b_fname != NULL) + rettv->vval.v_string = vim_strsave(buf->b_fname); + else + rettv->vval.v_string = NULL; +} + +/* + * "bufnr(expr)" function + */ + void +f_bufnr(typval_T *argvars, typval_T *rettv) +{ + buf_T *buf; + int error = FALSE; + char_u *name; + + if (argvars[0].v_type == VAR_UNKNOWN) + buf = curbuf; + else + { + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + ++emsg_off; + buf = tv_get_buf(&argvars[0], FALSE); + --emsg_off; + } + + // If the buffer isn't found and the second argument is not zero create a + // new buffer. + if (buf == NULL + && argvars[1].v_type != VAR_UNKNOWN + && tv_get_number_chk(&argvars[1], &error) != 0 + && !error + && (name = tv_get_string_chk(&argvars[0])) != NULL + && !error) + buf = buflist_new(name, NULL, (linenr_T)1, 0); + + if (buf != NULL) + rettv->vval.v_number = buf->b_fnum; + else + rettv->vval.v_number = -1; +} + + static void +buf_win_common(typval_T *argvars, typval_T *rettv, int get_nr) +{ + win_T *wp; + int winnr = 0; + buf_T *buf; + + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + ++emsg_off; + buf = tv_get_buf(&argvars[0], TRUE); + FOR_ALL_WINDOWS(wp) + { + ++winnr; + if (wp->w_buffer == buf) + break; + } + rettv->vval.v_number = (wp != NULL ? (get_nr ? winnr : wp->w_id) : -1); + --emsg_off; +} + +/* + * "bufwinid(nr)" function + */ + void +f_bufwinid(typval_T *argvars, typval_T *rettv) +{ + buf_win_common(argvars, rettv, FALSE); +} + +/* + * "bufwinnr(nr)" function + */ + void +f_bufwinnr(typval_T *argvars, typval_T *rettv) +{ + buf_win_common(argvars, rettv, TRUE); +} + +/* + * "deletebufline()" function + */ + void +f_deletebufline(typval_T *argvars, typval_T *rettv) +{ + 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; + tabpage_T *tp; + win_T *wp; + + 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; + } +} + +/* + * Returns buffer options, variables and other attributes in a dictionary. + */ + static dict_T * +get_buffer_info(buf_T *buf) +{ + dict_T *dict; + tabpage_T *tp; + win_T *wp; + list_T *windows; + + dict = dict_alloc(); + if (dict == NULL) + return NULL; + + dict_add_number(dict, "bufnr", buf->b_fnum); + dict_add_string(dict, "name", buf->b_ffname); + dict_add_number(dict, "lnum", buf == curbuf ? curwin->w_cursor.lnum + : buflist_findlnum(buf)); + dict_add_number(dict, "loaded", buf->b_ml.ml_mfp != NULL); + dict_add_number(dict, "listed", buf->b_p_bl); + dict_add_number(dict, "changed", bufIsChanged(buf)); + dict_add_number(dict, "changedtick", CHANGEDTICK(buf)); + dict_add_number(dict, "hidden", + buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0); + + // Get a reference to buffer variables + dict_add_dict(dict, "variables", buf->b_vars); + + // List of windows displaying this buffer + windows = list_alloc(); + if (windows != NULL) + { + FOR_ALL_TAB_WINDOWS(tp, wp) + if (wp->w_buffer == buf) + list_append_number(windows, (varnumber_T)wp->w_id); + dict_add_list(dict, "windows", windows); + } + +#ifdef FEAT_TEXT_PROP + // List of popup windows displaying this buffer + windows = list_alloc(); + if (windows != NULL) + { + for (wp = first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_buffer == buf) + list_append_number(windows, (varnumber_T)wp->w_id); + FOR_ALL_TABPAGES(tp) + for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_buffer == buf) + list_append_number(windows, (varnumber_T)wp->w_id); + + dict_add_list(dict, "popups", windows); + } +#endif + +#ifdef FEAT_SIGNS + if (buf->b_signlist != NULL) + { + // List of signs placed in this buffer + list_T *signs = list_alloc(); + if (signs != NULL) + { + get_buffer_signs(buf, signs); + dict_add_list(dict, "signs", signs); + } + } +#endif + + return dict; +} + +/* + * "getbufinfo()" function + */ + void +f_getbufinfo(typval_T *argvars, typval_T *rettv) +{ + buf_T *buf = NULL; + buf_T *argbuf = NULL; + dict_T *d; + int filtered = FALSE; + int sel_buflisted = FALSE; + int sel_bufloaded = FALSE; + int sel_bufmodified = FALSE; + + if (rettv_list_alloc(rettv) != OK) + return; + + // List of all the buffers or selected buffers + if (argvars[0].v_type == VAR_DICT) + { + dict_T *sel_d = argvars[0].vval.v_dict; + + if (sel_d != NULL) + { + dictitem_T *di; + + filtered = TRUE; + + di = dict_find(sel_d, (char_u *)"buflisted", -1); + if (di != NULL && tv_get_number(&di->di_tv)) + sel_buflisted = TRUE; + + di = dict_find(sel_d, (char_u *)"bufloaded", -1); + if (di != NULL && tv_get_number(&di->di_tv)) + sel_bufloaded = TRUE; + + di = dict_find(sel_d, (char_u *)"bufmodified", -1); + if (di != NULL && tv_get_number(&di->di_tv)) + sel_bufmodified = TRUE; + } + } + else if (argvars[0].v_type != VAR_UNKNOWN) + { + // Information about one buffer. Argument specifies the buffer + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + ++emsg_off; + argbuf = tv_get_buf(&argvars[0], FALSE); + --emsg_off; + if (argbuf == NULL) + return; + } + + // Return information about all the buffers or a specified buffer + FOR_ALL_BUFFERS(buf) + { + if (argbuf != NULL && argbuf != buf) + continue; + if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL) + || (sel_buflisted && !buf->b_p_bl) + || (sel_bufmodified && !buf->b_changed))) + continue; + + d = get_buffer_info(buf); + if (d != NULL) + list_append_dict(rettv->vval.v_list, d); + if (argbuf != NULL) + return; + } +} + +/* + * Get line or list of lines from buffer "buf" into "rettv". + * Return a range (from start to end) of lines in rettv from the specified + * buffer. + * If 'retlist' is TRUE, then the lines are returned as a Vim List. + */ + static void +get_buffer_lines( + buf_T *buf, + linenr_T start, + linenr_T end, + int retlist, + typval_T *rettv) +{ + char_u *p; + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + if (retlist && rettv_list_alloc(rettv) == FAIL) + return; + + if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) + return; + + if (!retlist) + { + if (start >= 1 && start <= buf->b_ml.ml_line_count) + p = ml_get_buf(buf, start, FALSE); + else + p = (char_u *)""; + rettv->vval.v_string = vim_strsave(p); + } + else + { + if (end < start) + return; + + if (start < 1) + start = 1; + if (end > buf->b_ml.ml_line_count) + end = buf->b_ml.ml_line_count; + while (start <= end) + if (list_append_string(rettv->vval.v_list, + ml_get_buf(buf, start++, FALSE), -1) == FAIL) + break; + } +} + +/* + * "getbufline()" function + */ + void +f_getbufline(typval_T *argvars, typval_T *rettv) +{ + linenr_T lnum; + linenr_T end; + buf_T *buf; + + (void)tv_get_number(&argvars[0]); // issue errmsg if type error + ++emsg_off; + buf = tv_get_buf(&argvars[0], FALSE); + --emsg_off; + + lnum = tv_get_lnum_buf(&argvars[1], buf); + if (argvars[2].v_type == VAR_UNKNOWN) + end = lnum; + else + end = tv_get_lnum_buf(&argvars[2], buf); + + get_buffer_lines(buf, lnum, end, TRUE, rettv); +} + +/* + * "getline(lnum, [end])" function + */ + void +f_getline(typval_T *argvars, typval_T *rettv) +{ + linenr_T lnum; + linenr_T end; + int retlist; + + lnum = tv_get_lnum(argvars); + if (argvars[1].v_type == VAR_UNKNOWN) + { + end = 0; + retlist = FALSE; + } + else + { + end = tv_get_lnum(&argvars[1]); + retlist = TRUE; + } + + get_buffer_lines(curbuf, lnum, end, retlist, rettv); +} + +/* + * "setbufline()" function + */ + void +f_setbufline(typval_T *argvars, typval_T *rettv) +{ + linenr_T lnum; + buf_T *buf; + + buf = tv_get_buf(&argvars[0], FALSE); + if (buf == NULL) + rettv->vval.v_number = 1; // FAIL + else + { + lnum = tv_get_lnum_buf(&argvars[1], buf); + set_buffer_lines(buf, lnum, FALSE, &argvars[2], rettv); + } +} + +/* + * "setline()" function + */ + void +f_setline(typval_T *argvars, typval_T *rettv) +{ + linenr_T lnum = tv_get_lnum(&argvars[0]); + + set_buffer_lines(curbuf, lnum, FALSE, &argvars[1], rettv); +} +#endif // FEAT_EVAL + +#if defined(FEAT_JOB_CHANNEL) \ + || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ + || defined(PROTO) +/* + * Make "buf" the current buffer. restore_buffer() MUST be called to undo. + * No autocommands will be executed. Use aucmd_prepbuf() if there are any. + */ + void +switch_buffer(bufref_T *save_curbuf, buf_T *buf) +{ + block_autocmds(); + set_bufref(save_curbuf, curbuf); + --curbuf->b_nwindows; + curbuf = buf; + curwin->w_buffer = buf; + ++curbuf->b_nwindows; +} + +/* + * Restore the current buffer after using switch_buffer(). + */ + void +restore_buffer(bufref_T *save_curbuf) +{ + unblock_autocmds(); + /* Check for valid buffer, just in case. */ + if (bufref_valid(save_curbuf)) + { + --curbuf->b_nwindows; + curwin->w_buffer = save_curbuf->br_buf; + curbuf = save_curbuf->br_buf; + ++curbuf->b_nwindows; + } +} + +/* + * Find a window for buffer "buf". + * If found OK is returned and "wp" and "tp" are set to the window and tabpage. + * If not found FAIL is returned. + */ + static int +find_win_for_buf( + buf_T *buf, + win_T **wp, + tabpage_T **tp) +{ + FOR_ALL_TAB_WINDOWS(*tp, *wp) + if ((*wp)->w_buffer == buf) + return OK; + return FAIL; +} + +/* + * Find a window that contains "buf" and switch to it. + * If there is no such window, use the current window and change "curbuf". + * Caller must initialize save_curbuf to NULL. + * restore_win_for_buf() MUST be called later! + */ + void +switch_to_win_for_buf( + buf_T *buf, + win_T **save_curwinp, + tabpage_T **save_curtabp, + bufref_T *save_curbuf) +{ + win_T *wp; + tabpage_T *tp; + + if (find_win_for_buf(buf, &wp, &tp) == FAIL) + switch_buffer(save_curbuf, buf); + else if (switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL) + { + restore_win(*save_curwinp, *save_curtabp, TRUE); + switch_buffer(save_curbuf, buf); + } +} + + void +restore_win_for_buf( + win_T *save_curwin, + tabpage_T *save_curtab, + bufref_T *save_curbuf) +{ + if (save_curbuf->br_buf == NULL) + restore_win(save_curwin, save_curtab, TRUE); + else + restore_buffer(save_curbuf); +} +#endif diff --git a/src/evalfunc.c b/src/evalfunc.c index b2ab63dbce..2461b6c304 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -29,8 +29,6 @@ static void f_abs(typval_T *argvars, typval_T *rettv); static void f_acos(typval_T *argvars, typval_T *rettv); #endif static void f_and(typval_T *argvars, typval_T *rettv); -static void f_append(typval_T *argvars, typval_T *rettv); -static void f_appendbufline(typval_T *argvars, typval_T *rettv); #ifdef FEAT_FLOAT static void f_asin(typval_T *argvars, typval_T *rettv); static void f_atan(typval_T *argvars, typval_T *rettv); @@ -43,15 +41,6 @@ static void f_balloon_show(typval_T *argvars, typval_T *rettv); static void f_balloon_split(typval_T *argvars, typval_T *rettv); # endif #endif -static void f_bufadd(typval_T *argvars, typval_T *rettv); -static void f_bufexists(typval_T *argvars, typval_T *rettv); -static void f_buflisted(typval_T *argvars, typval_T *rettv); -static void f_bufload(typval_T *argvars, typval_T *rettv); -static void f_bufloaded(typval_T *argvars, typval_T *rettv); -static void f_bufname(typval_T *argvars, typval_T *rettv); -static void f_bufnr(typval_T *argvars, typval_T *rettv); -static void f_bufwinid(typval_T *argvars, typval_T *rettv); -static void f_bufwinnr(typval_T *argvars, typval_T *rettv); static void f_byte2line(typval_T *argvars, typval_T *rettv); static void byteidx(typval_T *argvars, typval_T *rettv, int comp); static void f_byteidx(typval_T *argvars, typval_T *rettv); @@ -75,7 +64,6 @@ static void f_cursor(typval_T *argsvars, typval_T *rettv); static void f_debugbreak(typval_T *argvars, typval_T *rettv); #endif static void f_deepcopy(typval_T *argvars, typval_T *rettv); -static void f_deletebufline(typval_T *argvars, typval_T *rettv); static void f_did_filetype(typval_T *argvars, typval_T *rettv); static void f_empty(typval_T *argvars, typval_T *rettv); static void f_environ(typval_T *argvars, typval_T *rettv); @@ -101,8 +89,6 @@ static void f_funcref(typval_T *argvars, typval_T *rettv); static void f_function(typval_T *argvars, typval_T *rettv); static void f_garbagecollect(typval_T *argvars, typval_T *rettv); static void f_get(typval_T *argvars, typval_T *rettv); -static void f_getbufinfo(typval_T *argvars, typval_T *rettv); -static void f_getbufline(typval_T *argvars, typval_T *rettv); static void f_getchangelist(typval_T *argvars, typval_T *rettv); static void f_getchar(typval_T *argvars, typval_T *rettv); static void f_getcharmod(typval_T *argvars, typval_T *rettv); @@ -111,18 +97,12 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv); static void f_getenv(typval_T *argvars, typval_T *rettv); static void f_getfontname(typval_T *argvars, typval_T *rettv); static void f_getjumplist(typval_T *argvars, typval_T *rettv); -static void f_getline(typval_T *argvars, typval_T *rettv); static void f_getpid(typval_T *argvars, typval_T *rettv); static void f_getcurpos(typval_T *argvars, typval_T *rettv); static void f_getpos(typval_T *argvars, typval_T *rettv); static void f_getreg(typval_T *argvars, typval_T *rettv); static void f_getregtype(typval_T *argvars, typval_T *rettv); -static void f_gettabinfo(typval_T *argvars, typval_T *rettv); static void f_gettagstack(typval_T *argvars, typval_T *rettv); -static void f_getwininfo(typval_T *argvars, typval_T *rettv); -static void f_getwinpos(typval_T *argvars, typval_T *rettv); -static void f_getwinposx(typval_T *argvars, typval_T *rettv); -static void f_getwinposy(typval_T *argvars, typval_T *rettv); static void f_has(typval_T *argvars, typval_T *rettv); static void f_haslocaldir(typval_T *argvars, typval_T *rettv); static void f_hasmapto(typval_T *argvars, typval_T *rettv); @@ -229,11 +209,9 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv); static void f_searchpos(typval_T *argvars, typval_T *rettv); static void f_server2client(typval_T *argvars, typval_T *rettv); static void f_serverlist(typval_T *argvars, typval_T *rettv); -static void f_setbufline(typval_T *argvars, typval_T *rettv); static void f_setcharsearch(typval_T *argvars, typval_T *rettv); static void f_setenv(typval_T *argvars, typval_T *rettv); static void f_setfperm(typval_T *argvars, typval_T *rettv); -static void f_setline(typval_T *argvars, typval_T *rettv); static void f_setpos(typval_T *argvars, typval_T *rettv); static void f_setreg(typval_T *argvars, typval_T *rettv); static void f_settagstack(typval_T *argvars, typval_T *rettv); @@ -279,8 +257,6 @@ static void f_synIDtrans(typval_T *argvars, typval_T *rettv); static void f_synstack(typval_T *argvars, typval_T *rettv); static void f_synconcealed(typval_T *argvars, typval_T *rettv); static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv); -static void f_tabpagenr(typval_T *argvars, typval_T *rettv); -static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv); static void f_taglist(typval_T *argvars, typval_T *rettv); static void f_tagfiles(typval_T *argvars, typval_T *rettv); #ifdef FEAT_FLOAT @@ -298,23 +274,6 @@ static void f_type(typval_T *argvars, typval_T *rettv); static void f_virtcol(typval_T *argvars, typval_T *rettv); static void f_visualmode(typval_T *argvars, typval_T *rettv); static void f_wildmenumode(typval_T *argvars, typval_T *rettv); -static void f_win_execute(typval_T *argvars, typval_T *rettv); -static void f_win_findbuf(typval_T *argvars, typval_T *rettv); -static void f_win_getid(typval_T *argvars, typval_T *rettv); -static void f_win_gotoid(typval_T *argvars, typval_T *rettv); -static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv); -static void f_win_id2win(typval_T *argvars, typval_T *rettv); -static void f_win_screenpos(typval_T *argvars, typval_T *rettv); -static void f_winbufnr(typval_T *argvars, typval_T *rettv); -static void f_wincol(typval_T *argvars, typval_T *rettv); -static void f_winheight(typval_T *argvars, typval_T *rettv); -static void f_winlayout(typval_T *argvars, typval_T *rettv); -static void f_winline(typval_T *argvars, typval_T *rettv); -static void f_winnr(typval_T *argvars, typval_T *rettv); -static void f_winrestcmd(typval_T *argvars, typval_T *rettv); -static void f_winrestview(typval_T *argvars, typval_T *rettv); -static void f_winsaveview(typval_T *argvars, typval_T *rettv); -static void f_winwidth(typval_T *argvars, typval_T *rettv); static void f_wordcount(typval_T *argvars, typval_T *rettv); static void f_xor(typval_T *argvars, typval_T *rettv); @@ -1127,7 +1086,7 @@ tv_get_lnum(typval_T *argvars) * Also accepts "$", then "buf" is used. * Returns 0 on error. */ - static linenr_T + linenr_T tv_get_lnum_buf(typval_T *argvars, buf_T *buf) { if (argvars[0].v_type == VAR_STRING @@ -1212,184 +1171,6 @@ f_and(typval_T *argvars, typval_T *rettv) & tv_get_number_chk(&argvars[1], NULL); } -/* - * 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; - } - } -} - -/* - * Set line or list of lines in buffer "buf". - */ - 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; - - /* 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 */ - return; - } - - if (!is_curbuf) - { - curbuf_save = curbuf; - curwin_save = curwin; - curbuf = buf; - find_win_for_curbuf(); - } - - if (append) - // appendbufline() uses the line number below which we insert - append_lnum = lnum - 1; - else - // setbufline() uses the line number above which we insert, we only - // append if it's below the last line - append_lnum = curbuf->b_ml.ml_line_count; - - if (lines->v_type == VAR_LIST) - { - l = lines->vval.v_list; - li = l->lv_first; - } - else - line = tv_get_string_chk(lines); - - /* default result is zero == OK */ - for (;;) - { - if (l != NULL) - { - /* list argument, get next string */ - if (li == NULL) - break; - line = tv_get_string_chk(&li->li_tv); - li = li->li_next; - } - - rettv->vval.v_number = 1; /* FAIL */ - if (line == NULL || lnum > curbuf->b_ml.ml_line_count + 1) - break; - - /* 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 (!append && lnum <= curbuf->b_ml.ml_line_count) - { - // Existing line, replace it. - // Removes any existing text properties. - if (u_savesub(lnum) == OK && ml_replace_len( - lnum, line, (colnr_T)STRLEN(line) + 1, TRUE, TRUE) == OK) - { - changed_bytes(lnum, 0); - if (is_curbuf && lnum == curwin->w_cursor.lnum) - check_cursor_col(); - rettv->vval.v_number = 0; /* OK */ - } - } - else if (added > 0 || u_save(lnum - 1, lnum) == OK) - { - /* 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) - { - win_T *wp; - tabpage_T *tp; - - appended_lines_mark(append_lnum, added); - - // Only adjust the cursor for buffers other than the current, unless it - // is the current window. For curbuf and other windows it has been - // done in mark_adjust_internal(). - FOR_ALL_TAB_WINDOWS(tp, wp) - if (wp->w_buffer == buf - && (wp->w_buffer != curbuf || wp == curwin) - && wp->w_cursor.lnum > append_lnum) - wp->w_cursor.lnum += added; - check_cursor_col(); - update_topline(); - } - - if (!is_curbuf) - { - curbuf = curbuf_save; - curwin = curwin_save; - } -} - -/* - * "append(lnum, string/list)" function - */ - static void -f_append(typval_T *argvars, typval_T *rettv) -{ - linenr_T lnum = tv_get_lnum(&argvars[0]); - - set_buffer_lines(curbuf, lnum, TRUE, &argvars[1], rettv); -} - -/* - * "appendbufline(buf, lnum, string/list)" function - */ - static void -f_appendbufline(typval_T *argvars, typval_T *rettv) -{ - linenr_T lnum; - buf_T *buf; - - buf = tv_get_buf(&argvars[0], FALSE); - if (buf == NULL) - rettv->vval.v_number = 1; /* FAIL */ - else - { - lnum = tv_get_lnum_buf(&argvars[1], buf); - set_buffer_lines(buf, lnum, TRUE, &argvars[2], rettv); - } -} - #ifdef FEAT_FLOAT /* * "asin()" function @@ -1509,114 +1290,6 @@ f_balloon_split(typval_T *argvars, typval_T *rettv UNUSED) # endif #endif -/* - * Find a buffer by number or exact name. - */ - static 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 (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) -#ifdef FEAT_QUICKFIX - || bt_nofilename(buf) -#endif - ) - && STRCMP(buf->b_fname, avar->vval.v_string) == 0) - break; - } - } - return buf; -} - -/* - * "bufadd(expr)" function - */ - static void -f_bufadd(typval_T *argvars, typval_T *rettv) -{ - char_u *name = tv_get_string(&argvars[0]); - - rettv->vval.v_number = buflist_add(*name == NUL ? NULL : name, 0); -} - -/* - * "bufexists(expr)" function - */ - static void -f_bufexists(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); -} - -/* - * "buflisted(expr)" function - */ - static void -f_buflisted(typval_T *argvars, typval_T *rettv) -{ - buf_T *buf; - - buf = find_buffer(&argvars[0]); - rettv->vval.v_number = (buf != NULL && buf->b_p_bl); -} - -/* - * "bufload(expr)" function - */ - static void -f_bufload(typval_T *argvars, typval_T *rettv UNUSED) -{ - buf_T *buf = get_buf_arg(&argvars[0]); - - if (buf != NULL) - buffer_ensure_loaded(buf); -} - -/* - * "bufloaded(expr)" function - */ - static void -f_bufloaded(typval_T *argvars, typval_T *rettv) -{ - buf_T *buf; - - buf = find_buffer(&argvars[0]); - rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); -} - - 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 = (char_u *)""; - - buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), - TRUE, FALSE, curtab_only)); - - p_magic = save_magic; - p_cpo = save_cpo; - return buf; -} - /* * Get buffer by number or pattern. */ @@ -1661,104 +1334,6 @@ get_buf_arg(typval_T *arg) return buf; } -/* - * "bufname(expr)" function - */ - static void -f_bufname(typval_T *argvars, typval_T *rettv) -{ - buf_T *buf; - - if (argvars[0].v_type == VAR_UNKNOWN) - buf = curbuf; - else - { - (void)tv_get_number(&argvars[0]); // issue errmsg if type error - ++emsg_off; - buf = tv_get_buf(&argvars[0], FALSE); - --emsg_off; - } - rettv->v_type = VAR_STRING; - if (buf != NULL && buf->b_fname != NULL) - rettv->vval.v_string = vim_strsave(buf->b_fname); - else - rettv->vval.v_string = NULL; -} - -/* - * "bufnr(expr)" function - */ - static void -f_bufnr(typval_T *argvars, typval_T *rettv) -{ - buf_T *buf; - int error = FALSE; - char_u *name; - - if (argvars[0].v_type == VAR_UNKNOWN) - buf = curbuf; - else - { - (void)tv_get_number(&argvars[0]); // issue errmsg if type error - ++emsg_off; - buf = tv_get_buf(&argvars[0], FALSE); - --emsg_off; - } - - // If the buffer isn't found and the second argument is not zero create a - // new buffer. - if (buf == NULL - && argvars[1].v_type != VAR_UNKNOWN - && tv_get_number_chk(&argvars[1], &error) != 0 - && !error - && (name = tv_get_string_chk(&argvars[0])) != NULL - && !error) - buf = buflist_new(name, NULL, (linenr_T)1, 0); - - if (buf != NULL) - rettv->vval.v_number = buf->b_fnum; - else - rettv->vval.v_number = -1; -} - - static void -buf_win_common(typval_T *argvars, typval_T *rettv, int get_nr) -{ - win_T *wp; - int winnr = 0; - buf_T *buf; - - (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ - ++emsg_off; - buf = tv_get_buf(&argvars[0], TRUE); - FOR_ALL_WINDOWS(wp) - { - ++winnr; - if (wp->w_buffer == buf) - break; - } - rettv->vval.v_number = (wp != NULL ? (get_nr ? winnr : wp->w_id) : -1); - --emsg_off; -} - -/* - * "bufwinid(nr)" function - */ - static void -f_bufwinid(typval_T *argvars, typval_T *rettv) -{ - buf_win_common(argvars, rettv, FALSE); -} - -/* - * "bufwinnr(nr)" function - */ - static void -f_bufwinnr(typval_T *argvars, typval_T *rettv) -{ - buf_win_common(argvars, rettv, TRUE); -} - /* * "byte2line(byte)" function */ @@ -2201,91 +1776,6 @@ f_deepcopy(typval_T *argvars, typval_T *rettv) } } -/* - * "deletebufline()" function - */ - static void -f_deletebufline(typval_T *argvars, typval_T *rettv) -{ - 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; - tabpage_T *tp; - win_T *wp; - - 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 */ @@ -2509,7 +1999,7 @@ get_list_line( /* * "execute()" function */ - static void + void execute_common(typval_T *argvars, typval_T *rettv, int arg_off) { char_u *cmd = NULL; @@ -3308,220 +2798,6 @@ f_get(typval_T *argvars, typval_T *rettv) copy_tv(tv, rettv); } -/* - * Returns buffer options, variables and other attributes in a dictionary. - */ - static dict_T * -get_buffer_info(buf_T *buf) -{ - dict_T *dict; - tabpage_T *tp; - win_T *wp; - list_T *windows; - - dict = dict_alloc(); - if (dict == NULL) - return NULL; - - dict_add_number(dict, "bufnr", buf->b_fnum); - dict_add_string(dict, "name", buf->b_ffname); - dict_add_number(dict, "lnum", buf == curbuf ? curwin->w_cursor.lnum - : buflist_findlnum(buf)); - dict_add_number(dict, "loaded", buf->b_ml.ml_mfp != NULL); - dict_add_number(dict, "listed", buf->b_p_bl); - dict_add_number(dict, "changed", bufIsChanged(buf)); - dict_add_number(dict, "changedtick", CHANGEDTICK(buf)); - dict_add_number(dict, "hidden", - buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0); - - // Get a reference to buffer variables - dict_add_dict(dict, "variables", buf->b_vars); - - // List of windows displaying this buffer - windows = list_alloc(); - if (windows != NULL) - { - FOR_ALL_TAB_WINDOWS(tp, wp) - if (wp->w_buffer == buf) - list_append_number(windows, (varnumber_T)wp->w_id); - dict_add_list(dict, "windows", windows); - } - -#ifdef FEAT_TEXT_PROP - // List of popup windows displaying this buffer - windows = list_alloc(); - if (windows != NULL) - { - for (wp = first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_buffer == buf) - list_append_number(windows, (varnumber_T)wp->w_id); - FOR_ALL_TABPAGES(tp) - for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_buffer == buf) - list_append_number(windows, (varnumber_T)wp->w_id); - - dict_add_list(dict, "popups", windows); - } -#endif - -#ifdef FEAT_SIGNS - if (buf->b_signlist != NULL) - { - /* List of signs placed in this buffer */ - list_T *signs = list_alloc(); - if (signs != NULL) - { - get_buffer_signs(buf, signs); - dict_add_list(dict, "signs", signs); - } - } -#endif - - return dict; -} - -/* - * "getbufinfo()" function - */ - static void -f_getbufinfo(typval_T *argvars, typval_T *rettv) -{ - buf_T *buf = NULL; - buf_T *argbuf = NULL; - dict_T *d; - int filtered = FALSE; - int sel_buflisted = FALSE; - int sel_bufloaded = FALSE; - int sel_bufmodified = FALSE; - - if (rettv_list_alloc(rettv) != OK) - return; - - /* List of all the buffers or selected buffers */ - if (argvars[0].v_type == VAR_DICT) - { - dict_T *sel_d = argvars[0].vval.v_dict; - - if (sel_d != NULL) - { - dictitem_T *di; - - filtered = TRUE; - - di = dict_find(sel_d, (char_u *)"buflisted", -1); - if (di != NULL && tv_get_number(&di->di_tv)) - sel_buflisted = TRUE; - - di = dict_find(sel_d, (char_u *)"bufloaded", -1); - if (di != NULL && tv_get_number(&di->di_tv)) - sel_bufloaded = TRUE; - - di = dict_find(sel_d, (char_u *)"bufmodified", -1); - if (di != NULL && tv_get_number(&di->di_tv)) - sel_bufmodified = TRUE; - } - } - else if (argvars[0].v_type != VAR_UNKNOWN) - { - /* Information about one buffer. Argument specifies the buffer */ - (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ - ++emsg_off; - argbuf = tv_get_buf(&argvars[0], FALSE); - --emsg_off; - if (argbuf == NULL) - return; - } - - /* Return information about all the buffers or a specified buffer */ - FOR_ALL_BUFFERS(buf) - { - if (argbuf != NULL && argbuf != buf) - continue; - if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL) - || (sel_buflisted && !buf->b_p_bl) - || (sel_bufmodified && !buf->b_changed))) - continue; - - d = get_buffer_info(buf); - if (d != NULL) - list_append_dict(rettv->vval.v_list, d); - if (argbuf != NULL) - return; - } -} - -/* - * Get line or list of lines from buffer "buf" into "rettv". - * Return a range (from start to end) of lines in rettv from the specified - * buffer. - * If 'retlist' is TRUE, then the lines are returned as a Vim List. - */ - static void -get_buffer_lines( - buf_T *buf, - linenr_T start, - linenr_T end, - int retlist, - typval_T *rettv) -{ - char_u *p; - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - if (retlist && rettv_list_alloc(rettv) == FAIL) - return; - - if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) - return; - - if (!retlist) - { - if (start >= 1 && start <= buf->b_ml.ml_line_count) - p = ml_get_buf(buf, start, FALSE); - else - p = (char_u *)""; - rettv->vval.v_string = vim_strsave(p); - } - else - { - if (end < start) - return; - - if (start < 1) - start = 1; - if (end > buf->b_ml.ml_line_count) - end = buf->b_ml.ml_line_count; - while (start <= end) - if (list_append_string(rettv->vval.v_list, - ml_get_buf(buf, start++, FALSE), -1) == FAIL) - break; - } -} - -/* - * "getbufline()" function - */ - static void -f_getbufline(typval_T *argvars, typval_T *rettv) -{ - linenr_T lnum; - linenr_T end; - buf_T *buf; - - (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ - ++emsg_off; - buf = tv_get_buf(&argvars[0], FALSE); - --emsg_off; - - lnum = tv_get_lnum_buf(&argvars[1], buf); - if (argvars[2].v_type == VAR_UNKNOWN) - end = lnum; - else - end = tv_get_lnum_buf(&argvars[2], buf); - - get_buffer_lines(buf, lnum, end, TRUE, rettv); -} - /* * "getchangelist()" function */ @@ -3841,31 +3117,6 @@ f_getjumplist(typval_T *argvars, typval_T *rettv) #endif } -/* - * "getline(lnum, [end])" function - */ - static void -f_getline(typval_T *argvars, typval_T *rettv) -{ - linenr_T lnum; - linenr_T end; - int retlist; - - lnum = tv_get_lnum(argvars); - if (argvars[1].v_type == VAR_UNKNOWN) - { - end = 0; - retlist = FALSE; - } - else - { - end = tv_get_lnum(&argvars[1]); - retlist = TRUE; - } - - get_buffer_lines(curbuf, lnum, end, retlist, rettv); -} - /* * "getpid()" function */ @@ -3989,381 +3240,77 @@ f_getreg(typval_T *argvars, typval_T *rettv) else ++rettv->vval.v_list->lv_refcount; } - else - { - rettv->v_type = VAR_STRING; - rettv->vval.v_string = get_reg_contents(regname, - arg2 ? GREG_EXPR_SRC : 0); - } -} - -/* - * "getregtype()" function - */ - static void -f_getregtype(typval_T *argvars, typval_T *rettv) -{ - char_u *strregname; - int regname; - char_u buf[NUMBUFLEN + 2]; - long reglen = 0; - - if (argvars[0].v_type != VAR_UNKNOWN) - { - strregname = tv_get_string_chk(&argvars[0]); - if (strregname == NULL) /* type error; errmsg already given */ - { - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - return; - } - } - else - /* Default to v:register */ - strregname = get_vim_var_str(VV_REG); - - regname = (strregname == NULL ? '"' : *strregname); - if (regname == 0) - regname = '"'; - - buf[0] = NUL; - buf[1] = NUL; - switch (get_reg_type(regname, ®len)) - { - case MLINE: buf[0] = 'V'; break; - case MCHAR: buf[0] = 'v'; break; - case MBLOCK: - buf[0] = Ctrl_V; - sprintf((char *)buf + 1, "%ld", reglen + 1); - break; - } - rettv->v_type = VAR_STRING; - rettv->vval.v_string = vim_strsave(buf); -} - -/* - * Returns information (variables, options, etc.) about a tab page - * as a dictionary. - */ - static dict_T * -get_tabpage_info(tabpage_T *tp, int tp_idx) -{ - win_T *wp; - dict_T *dict; - list_T *l; - - dict = dict_alloc(); - if (dict == NULL) - return NULL; - - dict_add_number(dict, "tabnr", tp_idx); - - l = list_alloc(); - if (l != NULL) - { - for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; - wp != NULL; wp = wp->w_next) - list_append_number(l, (varnumber_T)wp->w_id); - dict_add_list(dict, "windows", l); - } - - /* Make a reference to tabpage variables */ - dict_add_dict(dict, "variables", tp->tp_vars); - - return dict; -} - -/* - * "gettabinfo()" function - */ - static void -f_gettabinfo(typval_T *argvars, typval_T *rettv) -{ - tabpage_T *tp, *tparg = NULL; - dict_T *d; - int tpnr = 0; - - if (rettv_list_alloc(rettv) != OK) - return; - - if (argvars[0].v_type != VAR_UNKNOWN) - { - /* Information about one tab page */ - tparg = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); - if (tparg == NULL) - return; - } - - /* Get information about a specific tab page or all tab pages */ - FOR_ALL_TABPAGES(tp) - { - tpnr++; - if (tparg != NULL && tp != tparg) - continue; - d = get_tabpage_info(tp, tpnr); - if (d != NULL) - list_append_dict(rettv->vval.v_list, d); - if (tparg != NULL) - return; - } -} - -/* - * "gettagstack()" function - */ - static void -f_gettagstack(typval_T *argvars, typval_T *rettv) -{ - win_T *wp = curwin; // default is current window - - if (rettv_dict_alloc(rettv) != OK) - return; - - if (argvars[0].v_type != VAR_UNKNOWN) - { - wp = find_win_by_nr_or_id(&argvars[0]); - if (wp == NULL) - return; - } - - get_tagstack(wp, rettv->vval.v_dict); -} - -/* - * Returns information about a window as a dictionary. - */ - static dict_T * -get_win_info(win_T *wp, short tpnr, short winnr) -{ - dict_T *dict; - - dict = dict_alloc(); - if (dict == NULL) - return NULL; - - dict_add_number(dict, "tabnr", tpnr); - dict_add_number(dict, "winnr", winnr); - dict_add_number(dict, "winid", wp->w_id); - dict_add_number(dict, "height", wp->w_height); - dict_add_number(dict, "winrow", wp->w_winrow + 1); - dict_add_number(dict, "topline", wp->w_topline); - dict_add_number(dict, "botline", wp->w_botline - 1); -#ifdef FEAT_MENU - dict_add_number(dict, "winbar", wp->w_winbar_height); -#endif - dict_add_number(dict, "width", wp->w_width); - dict_add_number(dict, "wincol", wp->w_wincol + 1); - dict_add_number(dict, "bufnr", wp->w_buffer->b_fnum); - -#ifdef FEAT_TERMINAL - dict_add_number(dict, "terminal", bt_terminal(wp->w_buffer)); -#endif -#ifdef FEAT_QUICKFIX - dict_add_number(dict, "quickfix", bt_quickfix(wp->w_buffer)); - dict_add_number(dict, "loclist", - (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)); -#endif - - /* Add a reference to window variables */ - dict_add_dict(dict, "variables", wp->w_vars); - - return dict; -} - -/* - * "getwininfo()" function - */ - static void -f_getwininfo(typval_T *argvars, typval_T *rettv) -{ - tabpage_T *tp; - win_T *wp = NULL, *wparg = NULL; - dict_T *d; - short tabnr = 0, winnr; - - if (rettv_list_alloc(rettv) != OK) - return; - - if (argvars[0].v_type != VAR_UNKNOWN) - { - wparg = win_id2wp(tv_get_number(&argvars[0])); - if (wparg == NULL) - return; - } - - /* Collect information about either all the windows across all the tab - * pages or one particular window. - */ - FOR_ALL_TABPAGES(tp) - { - tabnr++; - winnr = 0; - FOR_ALL_WINDOWS_IN_TAB(tp, wp) - { - winnr++; - if (wparg != NULL && wp != wparg) - continue; - d = get_win_info(wp, tabnr, winnr); - if (d != NULL) - list_append_dict(rettv->vval.v_list, d); - if (wparg != NULL) - /* found information about a specific window */ - return; - } - } -} - -/* - * "win_execute()" function - */ - static void -f_win_execute(typval_T *argvars, typval_T *rettv) -{ - int id = (int)tv_get_number(argvars); - tabpage_T *tp; - win_T *wp = win_id2wp_tp(id, &tp); - win_T *save_curwin; - tabpage_T *save_curtab; - - if (wp != NULL && tp != NULL) - { - if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, TRUE) == OK) - { - check_cursor(); - execute_common(argvars, rettv, 1); - } - restore_win_noblock(save_curwin, save_curtab, TRUE); - } -} - -/* - * "win_findbuf()" function - */ - static void -f_win_findbuf(typval_T *argvars, typval_T *rettv) -{ - if (rettv_list_alloc(rettv) != FAIL) - win_findbuf(argvars, rettv->vval.v_list); -} - -/* - * "win_getid()" function - */ - static void -f_win_getid(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = win_getid(argvars); -} - -/* - * "win_gotoid()" function - */ - static void -f_win_gotoid(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = win_gotoid(argvars); -} - -/* - * "win_id2tabwin()" function - */ - static void -f_win_id2tabwin(typval_T *argvars, typval_T *rettv) -{ - if (rettv_list_alloc(rettv) != FAIL) - win_id2tabwin(argvars, rettv->vval.v_list); -} - -/* - * "win_id2win()" function - */ - static void -f_win_id2win(typval_T *argvars, typval_T *rettv) -{ - rettv->vval.v_number = win_id2win(argvars); -} - -/* - * "win_screenpos()" function - */ - static void -f_win_screenpos(typval_T *argvars, typval_T *rettv) -{ - win_T *wp; - - if (rettv_list_alloc(rettv) == FAIL) - return; - - wp = find_win_by_nr_or_id(&argvars[0]); - list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1); - list_append_number(rettv->vval