Mercurial > vim
changeset 18010:cf8e0c7e0cb9 v8.1.2001
patch 8.1.2001: some source files are too big
Commit: https://github.com/vim/vim/commit/261f346f8154c0ec7094a4a211c653c74e9f7c2e
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Sep 7 15:45:32 2019 +0200
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 07 Sep 2019 16:00:03 +0200 |
parents | 40255308856f |
children | 57f25ee98789 |
files | Filelist src/Make_cyg_ming.mak src/Make_morph.mak src/Make_mvc.mak src/Make_vms.mms src/Makefile src/README.md src/buffer.c src/channel.c src/evalbuffer.c src/evalfunc.c src/evalwindow.c src/proto.h src/proto/buffer.pro src/proto/evalbuffer.pro src/proto/evalfunc.pro src/proto/evalwindow.pro src/proto/window.pro src/version.c src/window.c |
diffstat | 20 files changed, 2067 insertions(+), 1986 deletions(-) [+] |
line wrap: on
line diff
--- a/Filelist +++ b/Filelist @@ -34,8 +34,10 @@ SRC_ALL = \ src/digraph.c \ src/edit.c \ src/eval.c \ + src/evalbuffer.c \ src/evalfunc.c \ src/evalvars.c \ + src/evalwindow.c \ src/ex_cmdidxs.h \ src/ex_cmds.c \ src/ex_cmds.h \ @@ -189,8 +191,10 @@ SRC_ALL = \ src/proto/digraph.pro \ src/proto/edit.pro \ src/proto/eval.pro \ + src/proto/evalbuffer.pro \ src/proto/evalfunc.pro \ src/proto/evalvars.pro \ + src/proto/evalwindow.pro \ src/proto/ex_cmds.pro \ src/proto/ex_cmds2.pro \ src/proto/ex_docmd.pro \
--- 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 \
--- 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 \
--- 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 @@ testclean: $(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 \
--- a/src/Make_vms.mms +++ b/src/Make_vms.mms @@ -309,8 +309,10 @@ ALL_LIBS = $(LIBS) $(GUI_LIB_DIR) $(GUI_ 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 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 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]c 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 \
--- 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/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 pro 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 \
--- 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'
--- 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
--- 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, 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, 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) {
new file mode 100644 --- /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
--- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -29,8 +29,6 @@ static void f_abs(typval_T *argvars, typ 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 *arg 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, 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, 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 *ar 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 *ar 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 *argva 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, ty 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 @@ -1510,114 +1291,6 @@ f_balloon_split(typval_T *argvars, typva #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. */ buf_T * @@ -1662,104 +1335,6 @@ get_buf_arg(typval_T *arg) } /* - * "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 */ static void @@ -2202,91 +1777,6 @@ f_deepcopy(typval_T *argvars, typval_T * } /* - * "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 */ static void @@ -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; @@ -3309,220 +2799,6 @@ f_get(typval_T *argvars, typval_T *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 */ static void @@ -3842,31 +3118,6 @@ f_getjumplist(typval_T *argvars, typval_ } /* - * "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 */ static void @@ -4042,73 +3293,6 @@ f_getregtype(typval_T *argvars, typval_T } /* - * 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 @@ -4129,243 +3313,6 @@ f_gettagstack(typval_T *argvars, typval_ 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.v_list, wp == NULL ? 0 : wp->w_wincol + 1); -} - -/* - * "getwinpos({timeout})" function - */ - static void -f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv) -{ - int x = -1; - int y = -1; - - if (rettv_list_alloc(rettv) == FAIL) - return; -#if defined(FEAT_GUI) \ - || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ - || defined(MSWIN) - { - varnumber_T timeout = 100; - - if (argvars[0].v_type != VAR_UNKNOWN) - timeout = tv_get_number(&argvars[0]); - - (void)ui_get_winpos(&x, &y, timeout); - } -#endif - list_append_number(rettv->vval.v_list, (varnumber_T)x); - list_append_number(rettv->vval.v_list, (varnumber_T)y); -} - - -/* - * "getwinposx()" function - */ - static void -f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv->vval.v_number = -1; -#if defined(FEAT_GUI) \ - || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ - || defined(MSWIN) - - { - int x, y; - - if (ui_get_winpos(&x, &y, 100) == OK) - rettv->vval.v_number = x; - } -#endif -} - -/* - * "getwinposy()" function - */ - static void -f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv) -{ - rettv->vval.v_number = -1; -#if defined(FEAT_GUI) \ - || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ - || defined(MSWIN) - { - int x, y; - - if (ui_get_winpos(&x, &y, 100) == OK) - rettv->vval.v_number = y; - } -#endif -} - /* for VIM_VERSION_ defines */ #include "version.h" @@ -7690,25 +6637,6 @@ f_serverlist(typval_T *argvars UNUSED, t rettv->vval.v_string = r; } -/* - * "setbufline()" function - */ - static 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); - } -} - static void f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED) { @@ -7804,17 +6732,6 @@ f_setfperm(typval_T *argvars, typval_T * } /* - * "setline()" function - */ - static 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); -} - -/* * "setpos()" function */ static void @@ -9161,125 +8078,6 @@ f_tabpagebuflist(typval_T *argvars UNUSE } /* - * "tabpagenr()" function - */ - static void -f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv) -{ - int nr = 1; - char_u *arg; - - if (argvars[0].v_type != VAR_UNKNOWN) - { - arg = tv_get_string_chk(&argvars[0]); - nr = 0; - if (arg != NULL) - { - if (STRCMP(arg, "$") == 0) - nr = tabpage_index(NULL) - 1; - else - semsg(_(e_invexpr2), arg); - } - } - else - nr = tabpage_index(curtab); - rettv->vval.v_number = nr; -} - - -/* - * Common code for tabpagewinnr() and winnr(). - */ - static int -get_winnr(tabpage_T *tp, typval_T *argvar) -{ - win_T *twin; - int nr = 1; - win_T *wp; - char_u *arg; - - twin = (tp == curtab) ? curwin : tp->tp_curwin; - if (argvar->v_type != VAR_UNKNOWN) - { - int invalid_arg = FALSE; - - arg = tv_get_string_chk(argvar); - if (arg == NULL) - nr = 0; /* type error; errmsg already given */ - else if (STRCMP(arg, "$") == 0) - twin = (tp == curtab) ? lastwin : tp->tp_lastwin; - else if (STRCMP(arg, "#") == 0) - { - twin = (tp == curtab) ? prevwin : tp->tp_prevwin; - if (twin == NULL) - nr = 0; - } - else - { - long count; - char_u *endp; - - // Extract the window count (if specified). e.g. winnr('3j') - count = strtol((char *)arg, (char **)&endp, 10); - if (count <= 0) - count = 1; // if count is not specified, default to 1 - if (endp != NULL && *endp != '\0') - { - if (STRCMP(endp, "j") == 0) - twin = win_vert_neighbor(tp, twin, FALSE, count); - else if (STRCMP(endp, "k") == 0) - twin = win_vert_neighbor(tp, twin, TRUE, count); - else if (STRCMP(endp, "h") == 0) - twin = win_horz_neighbor(tp, twin, TRUE, count); - else if (STRCMP(endp, "l") == 0) - twin = win_horz_neighbor(tp, twin, FALSE, count); - else - invalid_arg = TRUE; - } - else - invalid_arg = TRUE; - } - - if (invalid_arg) - { - semsg(_(e_invexpr2), arg); - nr = 0; - } - } - - if (nr > 0) - for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; - wp != twin; wp = wp->w_next) - { - if (wp == NULL) - { - /* didn't find it in this tabpage */ - nr = 0; - break; - } - ++nr; - } - return nr; -} - -/* - * "tabpagewinnr()" function - */ - static void -f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv) -{ - int nr = 1; - tabpage_T *tp; - - tp = find_tabpage((int)tv_get_number(&argvars[0])); - if (tp == NULL) - nr = 0; - else - nr = get_winnr(tp, &argvars[1]); - rettv->vval.v_number = nr; -} - -/* * "tagfiles()" function */ static void @@ -9660,209 +8458,6 @@ f_wildmenumode(typval_T *argvars UNUSED, } /* - * "winbufnr(nr)" function - */ - static void -f_winbufnr(typval_T *argvars, typval_T *rettv) -{ - win_T *wp; - - wp = find_win_by_nr_or_id(&argvars[0]); - if (wp == NULL) - rettv->vval.v_number = -1; - else - rettv->vval.v_number = wp->w_buffer->b_fnum; -} - -/* - * "wincol()" function - */ - static void -f_wincol(typval_T *argvars UNUSED, typval_T *rettv) -{ - validate_cursor(); - rettv->vval.v_number = curwin->w_wcol + 1; -} - -/* - * "winheight(nr)" function - */ - static void -f_winheight(typval_T *argvars, typval_T *rettv) -{ - win_T *wp; - - wp = find_win_by_nr_or_id(&argvars[0]); - if (wp == NULL) - rettv->vval.v_number = -1; - else - rettv->vval.v_number = wp->w_height; -} - -/* - * "winlayout()" function - */ - static void -f_winlayout(typval_T *argvars, typval_T *rettv) -{ - tabpage_T *tp; - - if (rettv_list_alloc(rettv) != OK) - return; - - if (argvars[0].v_type == VAR_UNKNOWN) - tp = curtab; - else - { - tp = find_tabpage((int)tv_get_number(&argvars[0])); - if (tp == NULL) - return; - } - - get_framelayout(tp->tp_topframe, rettv->vval.v_list, TRUE); -} - -/* - * "winline()" function - */ - static void -f_winline(typval_T *argvars UNUSED, typval_T *rettv) -{ - validate_cursor(); - rettv->vval.v_number = curwin->w_wrow + 1; -} - -/* - * "winnr()" function - */ - static void -f_winnr(typval_T *argvars UNUSED, typval_T *rettv) -{ - int nr = 1; - - nr = get_winnr(curtab, &argvars[0]); - rettv->vval.v_number = nr; -} - -/* - * "winrestcmd()" function - */ - static void -f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv) -{ - win_T *wp; - int winnr = 1; - garray_T ga; - char_u buf[50]; - - ga_init2(&ga, (int)sizeof(char), 70); - FOR_ALL_WINDOWS(wp) - { - sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); - ga_concat(&ga, buf); - sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); - ga_concat(&ga, buf); - ++winnr; - } - ga_append(&ga, NUL); - - rettv->vval.v_string = ga.ga_data; - rettv->v_type = VAR_STRING; -} - -/* - * "winrestview()" function - */ - static void -f_winrestview(typval_T *argvars, typval_T *rettv UNUSED) -{ - dict_T *dict; - - if (argvars[0].v_type != VAR_DICT - || (dict = argvars[0].vval.v_dict) == NULL) - emsg(_(e_invarg)); - else - { - if (dict_find(dict, (char_u *)"lnum", -1) != NULL) - curwin->w_cursor.lnum = (linenr_T)dict_get_number(dict, (char_u *)"lnum"); - if (dict_find(dict, (char_u *)"col", -1) != NULL) - curwin->w_cursor.col = (colnr_T)dict_get_number(dict, (char_u *)"col"); - if (dict_find(dict, (char_u *)"coladd", -1) != NULL) - curwin->w_cursor.coladd = (colnr_T)dict_get_number(dict, (char_u *)"coladd"); - if (dict_find(dict, (char_u *)"curswant", -1) != NULL) - { - curwin->w_curswant = (colnr_T)dict_get_number(dict, (char_u *)"curswant"); - curwin->w_set_curswant = FALSE; - } - - if (dict_find(dict, (char_u *)"topline", -1) != NULL) - set_topline(curwin, (linenr_T)dict_get_number(dict, (char_u *)"topline")); -#ifdef FEAT_DIFF - if (dict_find(dict, (char_u *)"topfill", -1) != NULL) - curwin->w_topfill = (int)dict_get_number(dict, (char_u *)"topfill"); -#endif - if (dict_find(dict, (char_u *)"leftcol", -1) != NULL) - curwin->w_leftcol = (colnr_T)dict_get_number(dict, (char_u *)"leftcol"); - if (dict_find(dict, (char_u *)"skipcol", -1) != NULL) - curwin->w_skipcol = (colnr_T)dict_get_number(dict, (char_u *)"skipcol"); - - check_cursor(); - win_new_height(curwin, curwin->w_height); - win_new_width(curwin, curwin->w_width); - changed_window_setting(); - - if (curwin->w_topline <= 0) - curwin->w_topline = 1; - if (curwin->w_topline > curbuf->b_ml.ml_line_count) - curwin->w_topline = curbuf->b_ml.ml_line_count; -#ifdef FEAT_DIFF - check_topfill(curwin, TRUE); -#endif - } -} - -/* - * "winsaveview()" function - */ - static void -f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv) -{ - dict_T *dict; - - if (rettv_dict_alloc(rettv) == FAIL) - return; - dict = rettv->vval.v_dict; - - dict_add_number(dict, "lnum", (long)curwin->w_cursor.lnum); - dict_add_number(dict, "col", (long)curwin->w_cursor.col); - dict_add_number(dict, "coladd", (long)curwin->w_cursor.coladd); - update_curswant(); - dict_add_number(dict, "curswant", (long)curwin->w_curswant); - - dict_add_number(dict, "topline", (long)curwin->w_topline); -#ifdef FEAT_DIFF - dict_add_number(dict, "topfill", (long)curwin->w_topfill); -#endif - dict_add_number(dict, "leftcol", (long)curwin->w_leftcol); - dict_add_number(dict, "skipcol", (long)curwin->w_skipcol); -} - -/* - * "winwidth(nr)" function - */ - static void -f_winwidth(typval_T *argvars, typval_T *rettv) -{ - win_T *wp; - - wp = find_win_by_nr_or_id(&argvars[0]); - if (wp == NULL) - rettv->vval.v_number = -1; - else - rettv->vval.v_number = wp->w_width; -} - -/* * "wordcount()" function */ static void
new file mode 100644 --- /dev/null +++ b/src/evalwindow.c @@ -0,0 +1,1054 @@ +/* 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. + */ + +/* + * evalwindow.c: Window related builtin functions + */ + +#include "vim.h" + +#if defined(FEAT_EVAL) || defined(PROTO) + + static int +win_getid(typval_T *argvars) +{ + int winnr; + win_T *wp; + + if (argvars[0].v_type == VAR_UNKNOWN) + return curwin->w_id; + winnr = tv_get_number(&argvars[0]); + if (winnr > 0) + { + if (argvars[1].v_type == VAR_UNKNOWN) + wp = firstwin; + else + { + tabpage_T *tp; + int tabnr = tv_get_number(&argvars[1]); + + FOR_ALL_TABPAGES(tp) + if (--tabnr == 0) + break; + if (tp == NULL) + return -1; + if (tp == curtab) + wp = firstwin; + else + wp = tp->tp_firstwin; + } + for ( ; wp != NULL; wp = wp->w_next) + if (--winnr == 0) + return wp->w_id; + } + return 0; +} + + static int +win_gotoid(typval_T *argvars) +{ + win_T *wp; + tabpage_T *tp; + int id = tv_get_number(&argvars[0]); + + FOR_ALL_TAB_WINDOWS(tp, wp) + if (wp->w_id == id) + { + goto_tabpage_win(tp, wp); + return 1; + } + return 0; +} + + static void +win_id2tabwin(typval_T *argvars, list_T *list) +{ + win_T *wp; + tabpage_T *tp; + int winnr = 1; + int tabnr = 1; + int id = tv_get_number(&argvars[0]); + + FOR_ALL_TABPAGES(tp) + { + FOR_ALL_WINDOWS_IN_TAB(tp, wp) + { + if (wp->w_id == id) + { + list_append_number(list, tabnr); + list_append_number(list, winnr); + return; + } + ++winnr; + } + ++tabnr; + winnr = 1; + } + list_append_number(list, 0); + list_append_number(list, 0); +} + +/* + * Return the window pointer of window "id". + */ + win_T * +win_id2wp(int id) +{ + return win_id2wp_tp(id, NULL); +} + +/* + * Return the window and tab pointer of window "id". + */ + win_T * +win_id2wp_tp(int id, tabpage_T **tpp) +{ + win_T *wp; + tabpage_T *tp; + + FOR_ALL_TAB_WINDOWS(tp, wp) + if (wp->w_id == id) + { + if (tpp != NULL) + *tpp = tp; + return wp; + } +#ifdef FEAT_TEXT_PROP + // popup windows are in separate lists + FOR_ALL_TABPAGES(tp) + for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == id) + { + if (tpp != NULL) + *tpp = tp; + return wp; + } + for (wp = first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == id) + { + if (tpp != NULL) + *tpp = tp; + return wp; + } +#endif + + return NULL; +} + + static int +win_id2win(typval_T *argvars) +{ + win_T *wp; + int nr = 1; + int id = tv_get_number(&argvars[0]); + + FOR_ALL_WINDOWS(wp) + { + if (wp->w_id == id) + return nr; + ++nr; + } + return 0; +} + + void +win_findbuf(typval_T *argvars, list_T *list) +{ + win_T *wp; + tabpage_T *tp; + int bufnr = tv_get_number(&argvars[0]); + + FOR_ALL_TAB_WINDOWS(tp, wp) + if (wp->w_buffer->b_fnum == bufnr) + list_append_number(list, wp->w_id); +} + +/* + * Find window specified by "vp" in tabpage "tp". + */ + win_T * +find_win_by_nr( + typval_T *vp, + tabpage_T *tp) // NULL for current tab page +{ + win_T *wp; + int nr = (int)tv_get_number_chk(vp, NULL); + + if (nr < 0) + return NULL; + if (nr == 0) + return curwin; + + FOR_ALL_WINDOWS_IN_TAB(tp, wp) + { + if (nr >= LOWEST_WIN_ID) + { + if (wp->w_id == nr) + return wp; + } + else if (--nr <= 0) + break; + } + if (nr >= LOWEST_WIN_ID) + { +#ifdef FEAT_TEXT_PROP + // check tab-local popup windows + for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == nr) + return wp; + // check global popup windows + for (wp = first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == nr) + return wp; +#endif + return NULL; + } + return wp; +} + +/* + * Find a window: When using a Window ID in any tab page, when using a number + * in the current tab page. + */ + win_T * +find_win_by_nr_or_id(typval_T *vp) +{ + int nr = (int)tv_get_number_chk(vp, NULL); + + if (nr >= LOWEST_WIN_ID) + return win_id2wp(tv_get_number(vp)); + return find_win_by_nr(vp, NULL); +} + +/* + * Find window specified by "wvp" in tabpage "tvp". + * Returns the tab page in 'ptp' + */ + win_T * +find_tabwin( + typval_T *wvp, // VAR_UNKNOWN for current window + typval_T *tvp, // VAR_UNKNOWN for current tab page + tabpage_T **ptp) +{ + win_T *wp = NULL; + tabpage_T *tp = NULL; + long n; + + if (wvp->v_type != VAR_UNKNOWN) + { + if (tvp->v_type != VAR_UNKNOWN) + { + n = (long)tv_get_number(tvp); + if (n >= 0) + tp = find_tabpage(n); + } + else + tp = curtab; + + if (tp != NULL) + { + wp = find_win_by_nr(wvp, tp); + if (wp == NULL && wvp->v_type == VAR_NUMBER + && wvp->vval.v_number != -1) + // A window with the specified number is not found + tp = NULL; + } + } + else + { + wp = curwin; + tp = curtab; + } + + if (ptp != NULL) + *ptp = tp; + + return wp; +} + +/* + * Get the layout of the given tab page for winlayout(). + */ + static void +get_framelayout(frame_T *fr, list_T *l, int outer) +{ + frame_T *child; + list_T *fr_list; + list_T *win_list; + + if (fr == NULL) + return; + + if (outer) + // outermost call from f_winlayout() + fr_list = l; + else + { + fr_list = list_alloc(); + if (fr_list == NULL) + return; + list_append_list(l, fr_list); + } + + if (fr->fr_layout == FR_LEAF) + { + if (fr->fr_win != NULL) + { + list_append_string(fr_list, (char_u *)"leaf", -1); + list_append_number(fr_list, fr->fr_win->w_id); + } + } + else + { + list_append_string(fr_list, + fr->fr_layout == FR_ROW ? (char_u *)"row" : (char_u *)"col", -1); + + win_list = list_alloc(); + if (win_list == NULL) + return; + list_append_list(fr_list, win_list); + child = fr->fr_child; + while (child != NULL) + { + get_framelayout(child, win_list, FALSE); + child = child->fr_next; + } + } +} + +/* + * Common code for tabpagewinnr() and winnr(). + */ + static int +get_winnr(tabpage_T *tp, typval_T *argvar) +{ + win_T *twin; + int nr = 1; + win_T *wp; + char_u *arg; + + twin = (tp == curtab) ? curwin : tp->tp_curwin; + if (argvar->v_type != VAR_UNKNOWN) + { + int invalid_arg = FALSE; + + arg = tv_get_string_chk(argvar); + if (arg == NULL) + nr = 0; // type error; errmsg already given + else if (STRCMP(arg, "$") == 0) + twin = (tp == curtab) ? lastwin : tp->tp_lastwin; + else if (STRCMP(arg, "#") == 0) + { + twin = (tp == curtab) ? prevwin : tp->tp_prevwin; + if (twin == NULL) + nr = 0; + } + else + { + long count; + char_u *endp; + + // Extract the window count (if specified). e.g. winnr('3j') + count = strtol((char *)arg, (char **)&endp, 10); + if (count <= 0) + count = 1; // if count is not specified, default to 1 + if (endp != NULL && *endp != '\0') + { + if (STRCMP(endp, "j") == 0) + twin = win_vert_neighbor(tp, twin, FALSE, count); + else if (STRCMP(endp, "k") == 0) + twin = win_vert_neighbor(tp, twin, TRUE, count); + else if (STRCMP(endp, "h") == 0) + twin = win_horz_neighbor(tp, twin, TRUE, count); + else if (STRCMP(endp, "l") == 0) + twin = win_horz_neighbor(tp, twin, FALSE, count); + else + invalid_arg = TRUE; + } + else + invalid_arg = TRUE; + } + + if (invalid_arg) + { + semsg(_(e_invexpr2), arg); + nr = 0; + } + } + + if (nr > 0) + for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; + wp != twin; wp = wp->w_next) + { + if (wp == NULL) + { + // didn't find it in this tabpage + nr = 0; + break; + } + ++nr; + } + return nr; +} + +/* + * 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; +} + +/* + * 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 + */ + 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; + } +} + +/* + * "getwininfo()" function + */ + 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; + } + } +} + +/* + * "getwinpos({timeout})" function + */ + void +f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv) +{ + int x = -1; + int y = -1; + + if (rettv_list_alloc(rettv) == FAIL) + return; +#if defined(FEAT_GUI) \ + || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ + || defined(MSWIN) + { + varnumber_T timeout = 100; + + if (argvars[0].v_type != VAR_UNKNOWN) + timeout = tv_get_number(&argvars[0]); + + (void)ui_get_winpos(&x, &y, timeout); + } +#endif + list_append_number(rettv->vval.v_list, (varnumber_T)x); + list_append_number(rettv->vval.v_list, (varnumber_T)y); +} + + +/* + * "getwinposx()" function + */ + void +f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->vval.v_number = -1; +#if defined(FEAT_GUI) \ + || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ + || defined(MSWIN) + + { + int x, y; + + if (ui_get_winpos(&x, &y, 100) == OK) + rettv->vval.v_number = x; + } +#endif +} + +/* + * "getwinposy()" function + */ + void +f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->vval.v_number = -1; +#if defined(FEAT_GUI) \ + || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ + || defined(MSWIN) + { + int x, y; + + if (ui_get_winpos(&x, &y, 100) == OK) + rettv->vval.v_number = y; + } +#endif +} + +/* + * "tabpagenr()" function + */ + void +f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv) +{ + int nr = 1; + char_u *arg; + + if (argvars[0].v_type != VAR_UNKNOWN) + { + arg = tv_get_string_chk(&argvars[0]); + nr = 0; + if (arg != NULL) + { + if (STRCMP(arg, "$") == 0) + nr = tabpage_index(NULL) - 1; + else + semsg(_(e_invexpr2), arg); + } + } + else + nr = tabpage_index(curtab); + rettv->vval.v_number = nr; +} + +/* + * "tabpagewinnr()" function + */ + void +f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv) +{ + int nr = 1; + tabpage_T *tp; + + tp = find_tabpage((int)tv_get_number(&argvars[0])); + if (tp == NULL) + nr = 0; + else + nr = get_winnr(tp, &argvars[1]); + rettv->vval.v_number = nr; +} + +/* + * "win_execute()" function + */ + 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 + */ + 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 + */ + void +f_win_getid(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = win_getid(argvars); +} + +/* + * "win_gotoid()" function + */ + void +f_win_gotoid(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = win_gotoid(argvars); +} + +/* + * "win_id2tabwin()" function + */ + 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 + */ + void +f_win_id2win(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = win_id2win(argvars); +} + +/* + * "win_screenpos()" function + */ + 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.v_list, wp == NULL ? 0 : wp->w_wincol + 1); +} + +/* + * "winbufnr(nr)" function + */ + void +f_winbufnr(typval_T *argvars, typval_T *rettv) +{ + win_T *wp; + + wp = find_win_by_nr_or_id(&argvars[0]); + if (wp == NULL) + rettv->vval.v_number = -1; + else + rettv->vval.v_number = wp->w_buffer->b_fnum; +} + +/* + * "wincol()" function + */ + void +f_wincol(typval_T *argvars UNUSED, typval_T *rettv) +{ + validate_cursor(); + rettv->vval.v_number = curwin->w_wcol + 1; +} + +/* + * "winheight(nr)" function + */ + void +f_winheight(typval_T *argvars, typval_T *rettv) +{ + win_T *wp; + + wp = find_win_by_nr_or_id(&argvars[0]); + if (wp == NULL) + rettv->vval.v_number = -1; + else + rettv->vval.v_number = wp->w_height; +} + +/* + * "winlayout()" function + */ + void +f_winlayout(typval_T *argvars, typval_T *rettv) +{ + tabpage_T *tp; + + if (rettv_list_alloc(rettv) != OK) + return; + + if (argvars[0].v_type == VAR_UNKNOWN) + tp = curtab; + else + { + tp = find_tabpage((int)tv_get_number(&argvars[0])); + if (tp == NULL) + return; + } + + get_framelayout(tp->tp_topframe, rettv->vval.v_list, TRUE); +} + +/* + * "winline()" function + */ + void +f_winline(typval_T *argvars UNUSED, typval_T *rettv) +{ + validate_cursor(); + rettv->vval.v_number = curwin->w_wrow + 1; +} + +/* + * "winnr()" function + */ + void +f_winnr(typval_T *argvars UNUSED, typval_T *rettv) +{ + int nr = 1; + + nr = get_winnr(curtab, &argvars[0]); + rettv->vval.v_number = nr; +} + +/* + * "winrestcmd()" function + */ + void +f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv) +{ + win_T *wp; + int winnr = 1; + garray_T ga; + char_u buf[50]; + + ga_init2(&ga, (int)sizeof(char), 70); + FOR_ALL_WINDOWS(wp) + { + sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); + ga_concat(&ga, buf); + sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); + ga_concat(&ga, buf); + ++winnr; + } + ga_append(&ga, NUL); + + rettv->vval.v_string = ga.ga_data; + rettv->v_type = VAR_STRING; +} + +/* + * "winrestview()" function + */ + void +f_winrestview(typval_T *argvars, typval_T *rettv UNUSED) +{ + dict_T *dict; + + if (argvars[0].v_type != VAR_DICT + || (dict = argvars[0].vval.v_dict) == NULL) + emsg(_(e_invarg)); + else + { + if (dict_find(dict, (char_u *)"lnum", -1) != NULL) + curwin->w_cursor.lnum = (linenr_T)dict_get_number(dict, (char_u *)"lnum"); + if (dict_find(dict, (char_u *)"col", -1) != NULL) + curwin->w_cursor.col = (colnr_T)dict_get_number(dict, (char_u *)"col"); + if (dict_find(dict, (char_u *)"coladd", -1) != NULL) + curwin->w_cursor.coladd = (colnr_T)dict_get_number(dict, (char_u *)"coladd"); + if (dict_find(dict, (char_u *)"curswant", -1) != NULL) + { + curwin->w_curswant = (colnr_T)dict_get_number(dict, (char_u *)"curswant"); + curwin->w_set_curswant = FALSE; + } + + if (dict_find(dict, (char_u *)"topline", -1) != NULL) + set_topline(curwin, (linenr_T)dict_get_number(dict, (char_u *)"topline")); +#ifdef FEAT_DIFF + if (dict_find(dict, (char_u *)"topfill", -1) != NULL) + curwin->w_topfill = (int)dict_get_number(dict, (char_u *)"topfill"); +#endif + if (dict_find(dict, (char_u *)"leftcol", -1) != NULL) + curwin->w_leftcol = (colnr_T)dict_get_number(dict, (char_u *)"leftcol"); + if (dict_find(dict, (char_u *)"skipcol", -1) != NULL) + curwin->w_skipcol = (colnr_T)dict_get_number(dict, (char_u *)"skipcol"); + + check_cursor(); + win_new_height(curwin, curwin->w_height); + win_new_width(curwin, curwin->w_width); + changed_window_setting(); + + if (curwin->w_topline <= 0) + curwin->w_topline = 1; + if (curwin->w_topline > curbuf->b_ml.ml_line_count) + curwin->w_topline = curbuf->b_ml.ml_line_count; +#ifdef FEAT_DIFF + check_topfill(curwin, TRUE); +#endif + } +} + +/* + * "winsaveview()" function + */ + void +f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv) +{ + dict_T *dict; + + if (rettv_dict_alloc(rettv) == FAIL) + return; + dict = rettv->vval.v_dict; + + dict_add_number(dict, "lnum", (long)curwin->w_cursor.lnum); + dict_add_number(dict, "col", (long)curwin->w_cursor.col); + dict_add_number(dict, "coladd", (long)curwin->w_cursor.coladd); + update_curswant(); + dict_add_number(dict, "curswant", (long)curwin->w_curswant); + + dict_add_number(dict, "topline", (long)curwin->w_topline); +#ifdef FEAT_DIFF + dict_add_number(dict, "topfill", (long)curwin->w_topfill); +#endif + dict_add_number(dict, "leftcol", (long)curwin->w_leftcol); + dict_add_number(dict, "skipcol", (long)curwin->w_skipcol); +} + +/* + * "winwidth(nr)" function + */ + void +f_winwidth(typval_T *argvars, typval_T *rettv) +{ + win_T *wp; + + wp = find_win_by_nr_or_id(&argvars[0]); + if (wp == NULL) + rettv->vval.v_number = -1; + else + rettv->vval.v_number = wp->w_width; +} +#endif // FEAT_EVAL + +#if defined(FEAT_EVAL) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ + || defined(PROTO) +/* + * Set "win" to be the curwin and "tp" to be the current tab page. + * restore_win() MUST be called to undo, also when FAIL is returned. + * No autocommands will be executed until restore_win() is called. + * When "no_display" is TRUE the display won't be affected, no redraw is + * triggered, another tabpage access is limited. + * Returns FAIL if switching to "win" failed. + */ + int +switch_win( + win_T **save_curwin, + tabpage_T **save_curtab, + win_T *win, + tabpage_T *tp, + int no_display) +{ + block_autocmds(); + return switch_win_noblock(save_curwin, save_curtab, win, tp, no_display); +} + +/* + * As switch_win() but without blocking autocommands. + */ + int +switch_win_noblock( + win_T **save_curwin, + tabpage_T **save_curtab, + win_T *win, + tabpage_T *tp, + int no_display) +{ + *save_curwin = curwin; + if (tp != NULL) + { + *save_curtab = curtab; + if (no_display) + { + curtab->tp_firstwin = firstwin; + curtab->tp_lastwin = lastwin; + curtab = tp; + firstwin = curtab->tp_firstwin; + lastwin = curtab->tp_lastwin; + } + else + goto_tabpage_tp(tp, FALSE, FALSE); + } + if (!win_valid(win)) + return FAIL; + curwin = win; + curbuf = curwin->w_buffer; + return OK; +} + +/* + * Restore current tabpage and window saved by switch_win(), if still valid. + * When "no_display" is TRUE the display won't be affected, no redraw is + * triggered. + */ + void +restore_win( + win_T *save_curwin, + tabpage_T *save_curtab, + int no_display) +{ + restore_win_noblock(save_curwin, save_curtab, no_display); + unblock_autocmds(); +} + +/* + * As restore_win() but without unblocking autocommands. + */ + void +restore_win_noblock( + win_T *save_curwin, + tabpage_T *save_curtab, + int no_display) +{ + if (save_curtab != NULL && valid_tabpage(save_curtab)) + { + if (no_display) + { + curtab->tp_firstwin = firstwin; + curtab->tp_lastwin = lastwin; + curtab = save_curtab; + firstwin = curtab->tp_firstwin; + lastwin = curtab->tp_lastwin; + } + else + goto_tabpage_tp(save_curtab, FALSE, FALSE); + } + if (win_valid(save_curwin)) + { + curwin = save_curwin; + curbuf = curwin->w_buffer; + } +# ifdef FEAT_TEXT_PROP + else if (WIN_IS_POPUP(curwin)) + // original window was closed and now we're in a popup window: Go + // to the first valid window. + win_goto(firstwin); +# endif +} +#endif
--- a/src/proto.h +++ b/src/proto.h @@ -75,7 +75,10 @@ extern int _stricoll(char *a, char *b); # include "digraph.pro" # include "edit.pro" # include "eval.pro" +# include "evalbuffer.pro" # include "evalfunc.pro" +# include "evalvars.pro" +# include "evalwindow.pro" # include "ex_cmds.pro" # include "ex_cmds2.pro" # include "ex_docmd.pro" @@ -111,7 +114,6 @@ extern int _stricoll(char *a, char *b); # ifdef FEAT_VIMINFO # include "viminfo.pro" # endif -# include "evalvars.pro" /* These prototypes cannot be produced automatically. */ int smsg(const char *, ...)
--- a/src/proto/buffer.pro +++ b/src/proto/buffer.pro @@ -65,10 +65,7 @@ int bt_dontwrite(buf_T *buf); int bt_dontwrite_msg(buf_T *buf); int buf_hide(buf_T *buf); char_u *buf_spname(buf_T *buf); -void switch_to_win_for_buf(buf_T *buf, win_T **save_curwinp, tabpage_T **save_curtabp, bufref_T *save_curbuf); -void restore_win_for_buf(win_T *save_curwin, tabpage_T *save_curtab, bufref_T *save_curbuf); void set_buflisted(int on); int buf_contents_changed(buf_T *buf); void wipe_buffer(buf_T *buf, int aucmd); -int set_ref_in_buffers(int copyID); /* vim: set ft=c : */
new file mode 100644 --- /dev/null +++ b/src/proto/evalbuffer.pro @@ -0,0 +1,26 @@ +/* evalbuffer.c */ +int set_ref_in_buffers(int copyID); +buf_T *buflist_find_by_name(char_u *name, int curtab_only); +buf_T *find_buffer(typval_T *avar); +void f_append(typval_T *argvars, typval_T *rettv); +void f_appendbufline(typval_T *argvars, typval_T *rettv); +void f_bufadd(typval_T *argvars, typval_T *rettv); +void f_bufexists(typval_T *argvars, typval_T *rettv); +void f_buflisted(typval_T *argvars, typval_T *rettv); +void f_bufload(typval_T *argvars, typval_T *rettv); +void f_bufloaded(typval_T *argvars, typval_T *rettv); +void f_bufname(typval_T *argvars, typval_T *rettv); +void f_bufnr(typval_T *argvars, typval_T *rettv); +void f_bufwinid(typval_T *argvars, typval_T *rettv); +void f_bufwinnr(typval_T *argvars, typval_T *rettv); +void f_deletebufline(typval_T *argvars, typval_T *rettv); +void f_getbufinfo(typval_T *argvars, typval_T *rettv); +void f_getbufline(typval_T *argvars, typval_T *rettv); +void f_getline(typval_T *argvars, typval_T *rettv); +void f_setbufline(typval_T *argvars, typval_T *rettv); +void f_setline(typval_T *argvars, typval_T *rettv); +void switch_buffer(bufref_T *save_curbuf, buf_T *buf); +void restore_buffer(bufref_T *save_curbuf); +void switch_to_win_for_buf(buf_T *buf, win_T **save_curwinp, tabpage_T **save_curtabp, bufref_T *save_curbuf); +void restore_win_for_buf(win_T *save_curwin, tabpage_T *save_curtab, bufref_T *save_curbuf); +/* vim: set ft=c : */
--- a/src/proto/evalfunc.pro +++ b/src/proto/evalfunc.pro @@ -5,11 +5,13 @@ int has_internal_func(char_u *name); int call_internal_func(char_u *name, int argcount, typval_T *argvars, typval_T *rettv); int call_internal_method(char_u *name, int argcount, typval_T *argvars, typval_T *rettv, typval_T *basetv); linenr_T tv_get_lnum(typval_T *argvars); +linenr_T tv_get_lnum_buf(typval_T *argvars, buf_T *buf); buf_T *buflist_find_by_name(char_u *name, int curtab_only); buf_T *tv_get_buf(typval_T *tv, int curtab_only); buf_T *get_buf_arg(typval_T *arg); win_T *get_optional_window(typval_T *argvars, int idx); void execute_redir_str(char_u *value, int value_len); +void execute_common(typval_T *argvars, typval_T *rettv, int arg_off); void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv); float_T vim_round(float_T f); long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
new file mode 100644 --- /dev/null +++ b/src/proto/evalwindow.pro @@ -0,0 +1,36 @@ +/* evalwindow.c */ +win_T *win_id2wp(int id); +win_T *win_id2wp_tp(int id, tabpage_T **tpp); +void win_findbuf(typval_T *argvars, list_T *list); +win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); +win_T *find_win_by_nr_or_id(typval_T *vp); +win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp); +void f_gettabinfo(typval_T *argvars, typval_T *rettv); +void f_getwininfo(typval_T *argvars, typval_T *rettv); +void f_getwinpos(typval_T *argvars, typval_T *rettv); +void f_getwinposx(typval_T *argvars, typval_T *rettv); +void f_getwinposy(typval_T *argvars, typval_T *rettv); +void f_tabpagenr(typval_T *argvars, typval_T *rettv); +void f_tabpagewinnr(typval_T *argvars, typval_T *rettv); +void f_win_execute(typval_T *argvars, typval_T *rettv); +void f_win_findbuf(typval_T *argvars, typval_T *rettv); +void f_win_getid(typval_T *argvars, typval_T *rettv); +void f_win_gotoid(typval_T *argvars, typval_T *rettv); +void f_win_id2tabwin(typval_T *argvars, typval_T *rettv); +void f_win_id2win(typval_T *argvars, typval_T *rettv); +void f_win_screenpos(typval_T *argvars, typval_T *rettv); +void f_winbufnr(typval_T *argvars, typval_T *rettv); +void f_wincol(typval_T *argvars, typval_T *rettv); +void f_winheight(typval_T *argvars, typval_T *rettv); +void f_winlayout(typval_T *argvars, typval_T *rettv); +void f_winline(typval_T *argvars, typval_T *rettv); +void f_winnr(typval_T *argvars, typval_T *rettv); +void f_winrestcmd(typval_T *argvars, typval_T *rettv); +void f_winrestview(typval_T *argvars, typval_T *rettv); +void f_winsaveview(typval_T *argvars, typval_T *rettv); +void f_winwidth(typval_T *argvars, typval_T *rettv); +int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display); +int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display); +void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display); +void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab, int no_display); +/* vim: set ft=c : */
--- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -73,25 +73,8 @@ void check_lnums(int do_curwin); void reset_lnums(void); void make_snapshot(int idx); void restore_snapshot(int idx, int close_curwin); -int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display); -int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display); -void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display); -void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab, int no_display); -void switch_buffer(bufref_T *save_curbuf, buf_T *buf); -void restore_buffer(bufref_T *save_curbuf); int win_hasvertsplit(void); int get_win_number(win_T *wp, win_T *first_win); int get_tab_number(tabpage_T *tp); char *check_colorcolumn(win_T *wp); -int win_getid(typval_T *argvars); -int win_gotoid(typval_T *argvars); -void win_id2tabwin(typval_T *argvars, list_T *list); -win_T *win_id2wp(int id); -win_T *win_id2wp_tp(int id, tabpage_T **tpp); -int win_id2win(typval_T *argvars); -void win_findbuf(typval_T *argvars, list_T *list); -win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); -win_T *find_win_by_nr_or_id(typval_T *vp); -win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp); -void get_framelayout(frame_T *fr, list_T *l, int outer); /* vim: set ft=c : */
--- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2001, +/**/ 1999, /**/ 1998,
--- a/src/window.c +++ b/src/window.c @@ -6587,144 +6587,6 @@ restore_snapshot_rec(frame_T *sn, frame_ return wp; } -#if defined(FEAT_EVAL) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ - || defined(PROTO) -/* - * Set "win" to be the curwin and "tp" to be the current tab page. - * restore_win() MUST be called to undo, also when FAIL is returned. - * No autocommands will be executed until restore_win() is called. - * When "no_display" is TRUE the display won't be affected, no redraw is - * triggered, another tabpage access is limited. - * Returns FAIL if switching to "win" failed. - */ - int -switch_win( - win_T **save_curwin, - tabpage_T **save_curtab, - win_T *win, - tabpage_T *tp, - int no_display) -{ - block_autocmds(); - return switch_win_noblock(save_curwin, save_curtab, win, tp, no_display); -} - -/* - * As switch_win() but without blocking autocommands. - */ - int -switch_win_noblock( - win_T **save_curwin, - tabpage_T **save_curtab, - win_T *win, - tabpage_T *tp, - int no_display) -{ - *save_curwin = curwin; - if (tp != NULL) - { - *save_curtab = curtab; - if (no_display) - { - curtab->tp_firstwin = firstwin; - curtab->tp_lastwin = lastwin; - curtab = tp; - firstwin = curtab->tp_firstwin; - lastwin = curtab->tp_lastwin; - } - else - goto_tabpage_tp(tp, FALSE, FALSE); - } - if (!win_valid(win)) - return FAIL; - curwin = win; - curbuf = curwin->w_buffer; - return OK; -} - -/* - * Restore current tabpage and window saved by switch_win(), if still valid. - * When "no_display" is TRUE the display won't be affected, no redraw is - * triggered. - */ - void -restore_win( - win_T *save_curwin, - tabpage_T *save_curtab, - int no_display) -{ - restore_win_noblock(save_curwin, save_curtab, no_display); - unblock_autocmds(); -} - -/* - * As restore_win() but without unblocking autocommands. - */ - void -restore_win_noblock( - win_T *save_curwin, - tabpage_T *save_curtab, - int no_display) -{ - if (save_curtab != NULL && valid_tabpage(save_curtab)) - { - if (no_display) - { - curtab->tp_firstwin = firstwin; - curtab->tp_lastwin = lastwin; - curtab = save_curtab; - firstwin = curtab->tp_firstwin; - lastwin = curtab->tp_lastwin; - } - else - goto_tabpage_tp(save_curtab, FALSE, FALSE); - } - if (win_valid(save_curwin)) - { - curwin = save_curwin; - curbuf = curwin->w_buffer; - } -#ifdef FEAT_TEXT_PROP - else if (WIN_IS_POPUP(curwin)) - // original window was closed and now we're in a popup window: Go - // to the first valid window. - win_goto(firstwin); -#endif -} - -/* - * 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; - } -} -#endif - #if defined(FEAT_GUI) || defined(PROTO) /* * Return TRUE if there is any vertically split window. @@ -6896,312 +6758,3 @@ skip: return NULL; // no error } #endif - -#if defined(FEAT_EVAL) || defined(PROTO) - int -win_getid(typval_T *argvars) -{ - int winnr; - win_T *wp; - - if (argvars[0].v_type == VAR_UNKNOWN) - return curwin->w_id; - winnr = tv_get_number(&argvars[0]); - if (winnr > 0) - { - if (argvars[1].v_type == VAR_UNKNOWN) - wp = firstwin; - else - { - tabpage_T *tp; - int tabnr = tv_get_number(&argvars[1]); - - FOR_ALL_TABPAGES(tp) - if (--tabnr == 0) - break; - if (tp == NULL) - return -1; - if (tp == curtab) - wp = firstwin; - else - wp = tp->tp_firstwin; - } - for ( ; wp != NULL; wp = wp->w_next) - if (--winnr == 0) - return wp->w_id; - } - return 0; -} - - int -win_gotoid(typval_T *argvars) -{ - win_T *wp; - tabpage_T *tp; - int id = tv_get_number(&argvars[0]); - - FOR_ALL_TAB_WINDOWS(tp, wp) - if (wp->w_id == id) - { - goto_tabpage_win(tp, wp); - return 1; - } - return 0; -} - - void -win_id2tabwin(typval_T *argvars, list_T *list) -{ - win_T *wp; - tabpage_T *tp; - int winnr = 1; - int tabnr = 1; - int id = tv_get_number(&argvars[0]); - - FOR_ALL_TABPAGES(tp) - { - FOR_ALL_WINDOWS_IN_TAB(tp, wp) - { - if (wp->w_id == id) - { - list_append_number(list, tabnr); - list_append_number(list, winnr); - return; - } - ++winnr; - } - ++tabnr; - winnr = 1; - } - list_append_number(list, 0); - list_append_number(list, 0); -} - -/* - * Return the window pointer of window "id". - */ - win_T * -win_id2wp(int id) -{ - return win_id2wp_tp(id, NULL); -} - -/* - * Return the window and tab pointer of window "id". - */ - win_T * -win_id2wp_tp(int id, tabpage_T **tpp) -{ - win_T *wp; - tabpage_T *tp; - - FOR_ALL_TAB_WINDOWS(tp, wp) - if (wp->w_id == id) - { - if (tpp != NULL) - *tpp = tp; - return wp; - } -#ifdef FEAT_TEXT_PROP - // popup windows are in separate lists - FOR_ALL_TABPAGES(tp) - for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_id == id) - { - if (tpp != NULL) - *tpp = tp; - return wp; - } - for (wp = first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_id == id) - { - if (tpp != NULL) - *tpp = tp; - return wp; - } -#endif - - return NULL; -} - - int -win_id2win(typval_T *argvars) -{ - win_T *wp; - int nr = 1; - int id = tv_get_number(&argvars[0]); - - FOR_ALL_WINDOWS(wp) - { - if (wp->w_id == id) - return nr; - ++nr; - } - return 0; -} - - void -win_findbuf(typval_T *argvars, list_T *list) -{ - win_T *wp; - tabpage_T *tp; - int bufnr = tv_get_number(&argvars[0]); - - FOR_ALL_TAB_WINDOWS(tp, wp) - if (wp->w_buffer->b_fnum == bufnr) - list_append_number(list, wp->w_id); -} - -/* - * Find window specified by "vp" in tabpage "tp". - */ - win_T * -find_win_by_nr( - typval_T *vp, - tabpage_T *tp) // NULL for current tab page -{ - win_T *wp; - int nr = (int)tv_get_number_chk(vp, NULL); - - if (nr < 0) - return NULL; - if (nr == 0) - return curwin; - - FOR_ALL_WINDOWS_IN_TAB(tp, wp) - { - if (nr >= LOWEST_WIN_ID) - { - if (wp->w_id == nr) - return wp; - } - else if (--nr <= 0) - break; - } - if (nr >= LOWEST_WIN_ID) - { -#ifdef FEAT_TEXT_PROP - // check tab-local popup windows - for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_id == nr) - return wp; - // check global popup windows - for (wp = first_popupwin; wp != NULL; wp = wp->w_next) - if (wp->w_id == nr) - return wp; -#endif - return NULL; - } - return wp; -} - -/* - * Find a window: When using a Window ID in any tab page, when using a number - * in the current tab page. - */ - win_T * -find_win_by_nr_or_id(typval_T *vp) -{ - int nr = (int)tv_get_number_chk(vp, NULL); - - if (nr >= LOWEST_WIN_ID) - return win_id2wp(tv_get_number(vp)); - return find_win_by_nr(vp, NULL); -} - -/* - * Find window specified by "wvp" in tabpage "tvp". - * Returns the tab page in 'ptp' - */ - win_T * -find_tabwin( - typval_T *wvp, // VAR_UNKNOWN for current window - typval_T *tvp, // VAR_UNKNOWN for current tab page - tabpage_T **ptp) -{ - win_T *wp = NULL; - tabpage_T *tp = NULL; - long n; - - if (wvp->v_type != VAR_UNKNOWN) - { - if (tvp->v_type != VAR_UNKNOWN) - { - n = (long)tv_get_number(tvp); - if (n >= 0) - tp = find_tabpage(n); - } - else - tp = curtab; - - if (tp != NULL) - { - wp = find_win_by_nr(wvp, tp); - if (wp == NULL && wvp->v_type == VAR_NUMBER - && wvp->vval.v_number != -1) - // A window with the specified number is not found - tp = NULL; - } - } - else - { - wp = curwin; - tp = curtab; - } - - if (ptp != NULL) - *ptp = tp; - - return wp; -} - -/* - * Get the layout of the given tab page for winlayout(). - */ - void -get_framelayout(frame_T *fr, list_T *l, int outer) -{ - frame_T *child; - list_T *fr_list; - list_T *win_list; - - if (fr == NULL) - return; - - if (outer) - // outermost call from f_winlayout() - fr_list = l; - else - { - fr_list = list_alloc(); - if (fr_list == NULL) - return; - list_append_list(l, fr_list); - } - - if (fr->fr_layout == FR_LEAF) - { - if (fr->fr_win != NULL) - { - list_append_string(fr_list, (char_u *)"leaf", -1); - list_append_number(fr_list, fr->fr_win->w_id); - } - } - else - { - list_append_string(fr_list, - fr->fr_layout == FR_ROW ? (char_u *)"row" : (char_u *)"col", -1); - - win_list = list_alloc(); - if (win_list == NULL) - return; - list_append_list(fr_list, win_list); - child = fr->fr_child; - while (child != NULL) - { - get_framelayout(child, win_list, FALSE); - child = child->fr_next; - } - } -} -#endif