To: vim_dev@googlegroups.com Subject: Patch 8.1.2001 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.2001 Problem: Some source files are too big. Solution: Move buffer and window related functions to evalbuffer.c and evalwindow.c. (Yegappan Lakshmanan, closes #4898) 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/window.c *** ../vim-8.1.2000/Filelist 2019-09-04 15:54:23.908359707 +0200 --- Filelist 2019-09-07 15:24:01.971506247 +0200 *************** *** 34,41 **** --- 34,43 ---- 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,196 **** --- 191,200 ---- 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 \ *** ../vim-8.1.2000/src/Make_cyg_ming.mak 2019-09-06 21:46:12.348612042 +0200 --- src/Make_cyg_ming.mak 2019-09-07 15:24:01.975506213 +0200 *************** *** 721,728 **** --- 721,730 ---- $(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 \ *** ../vim-8.1.2000/src/Make_morph.mak 2019-09-04 15:54:23.912359700 +0200 --- src/Make_morph.mak 2019-09-07 15:24:01.975506213 +0200 *************** *** 41,48 **** --- 41,50 ---- digraph.c \ edit.c \ eval.c \ + evalbuffer.c \ evalfunc.c \ evalvars.c \ + evalwindow.c \ ex_cmds.c \ ex_cmds2.c \ ex_docmd.c \ *** ../vim-8.1.2000/src/Make_mvc.mak 2019-09-06 21:46:12.348612042 +0200 --- src/Make_mvc.mak 2019-09-07 15:24:01.975506213 +0200 *************** *** 728,735 **** --- 728,737 ---- $(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,1494 **** --- 1487,1500 ---- $(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,1782 **** --- 1781,1790 ---- 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 \ *** ../vim-8.1.2000/src/Make_vms.mms 2019-09-04 15:54:23.912359700 +0200 --- src/Make_vms.mms 2019-09-07 15:24:01.975506213 +0200 *************** *** 309,316 **** 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 \ 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 \ --- 309,318 ---- 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 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,333 **** 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 \ 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 \ --- 329,336 ---- 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 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,572 **** --- 570,579 ---- 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,580 **** --- 582,591 ---- 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 \ *** ../vim-8.1.2000/src/Makefile 2019-09-04 15:54:23.912359700 +0200 --- src/Makefile 2019-09-07 15:24:01.975506213 +0200 *************** *** 1595,1602 **** --- 1597,1606 ---- digraph.c \ edit.c \ eval.c \ + evalbuffer.c \ evalfunc.c \ evalvars.c \ + evalwindow.c \ ex_cmds.c \ ex_cmds2.c \ ex_docmd.c \ *************** *** 1726,1733 **** --- 1730,1739 ---- 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,1877 **** --- 1876,1885 ---- digraph.pro \ edit.pro \ eval.pro \ + evalbuffer.pro \ evalfunc.pro \ evalvars.pro \ + evalwindow.pro \ ex_cmds.pro \ ex_cmds2.pro \ ex_docmd.pro \ *************** *** 3080,3091 **** --- 3088,3105 ---- 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,3608 **** --- 3617,3626 ---- 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,3616 **** --- 3629,3638 ---- 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 \ *** ../vim-8.1.2000/src/README.md 2019-09-04 15:54:23.912359700 +0200 --- src/README.md 2019-09-07 15:24:01.975506213 +0200 *************** *** 33,40 **** --- 33,42 ---- 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' *** ../vim-8.1.2000/src/buffer.c 2019-09-03 23:20:00.929446231 +0200 --- src/buffer.c 2019-09-07 15:34:54.076983803 +0200 *************** *** 5450,5515 **** 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. */ --- 5450,5455 ---- *************** *** 5603,5650 **** 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 --- 5543,5545 ---- *** ../vim-8.1.2000/src/channel.c 2019-09-04 18:53:08.485096735 +0200 --- src/channel.c 2019-09-07 15:24:01.975506213 +0200 *************** *** 1036,1042 **** * Returns NULL if there is something very wrong (error already reported). */ static buf_T * ! find_buffer(char_u *name, int err, int msg) { buf_T *buf = NULL; buf_T *save_curbuf = curbuf; --- 1036,1042 ---- * Returns NULL if there is something very wrong (error already reported). */ static buf_T * ! channel_find_buffer(char_u *name, int err, int msg) { buf_T *buf = NULL; buf_T *save_curbuf = curbuf; *************** *** 1126,1132 **** if (opt->jo_set2 & JO2_OUT_MSG) msg = opt->jo_message[PART_OUT]; ! buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE, msg); } if (buf != NULL) { --- 1126,1132 ---- if (opt->jo_set2 & JO2_OUT_MSG) msg = opt->jo_message[PART_OUT]; ! buf = channel_find_buffer(opt->jo_io_name[PART_OUT], FALSE, msg); } if (buf != NULL) { *************** *** 1173,1179 **** if (opt->jo_set2 & JO2_ERR_MSG) msg = opt->jo_message[PART_ERR]; ! buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE, msg); } if (buf != NULL) { --- 1173,1179 ---- if (opt->jo_set2 & JO2_ERR_MSG) msg = opt->jo_message[PART_ERR]; ! buf = channel_find_buffer(opt->jo_io_name[PART_ERR], TRUE, msg); } if (buf != NULL) { *** ../vim-8.1.2000/src/evalbuffer.c 2019-09-07 15:42:29.076099890 +0200 --- src/evalbuffer.c 2019-09-07 15:36:39.847347675 +0200 *************** *** 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 *** ../vim-8.1.2000/src/evalfunc.c 2019-09-07 15:03:00.653670319 +0200 --- src/evalfunc.c 2019-09-07 15:24:01.979506185 +0200 *************** *** 29,36 **** 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); --- 29,34 ---- *************** *** 43,57 **** 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); --- 41,46 ---- *************** *** 75,81 **** 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); --- 64,69 ---- *************** *** 101,108 **** 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); --- 89,94 ---- *************** *** 111,128 **** 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); --- 97,108 ---- *************** *** 229,239 **** 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); --- 209,217 ---- *************** *** 279,286 **** 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 --- 257,262 ---- *************** *** 298,320 **** 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); --- 274,279 ---- *************** *** 1127,1133 **** * Also accepts "$", then "buf" is used. * Returns 0 on error. */ ! static linenr_T tv_get_lnum_buf(typval_T *argvars, buf_T *buf) { if (argvars[0].v_type == VAR_STRING --- 1086,1092 ---- * Also accepts "$", then "buf" is used. * Returns 0 on error. */ ! linenr_T tv_get_lnum_buf(typval_T *argvars, buf_T *buf) { if (argvars[0].v_type == VAR_STRING *************** *** 1212,1395 **** & 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 --- 1171,1176 ---- *************** *** 1510,1623 **** #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 * --- 1291,1296 ---- *************** *** 1662,1765 **** } /* - * "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 --- 1335,1340 ---- *************** *** 2202,2292 **** } /* - * "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 --- 1777,1782 ---- *************** *** 2509,2515 **** /* * "execute()" function */ ! static void execute_common(typval_T *argvars, typval_T *rettv, int arg_off) { char_u *cmd = NULL; --- 1999,2005 ---- /* * "execute()" function */ ! void execute_common(typval_T *argvars, typval_T *rettv, int arg_off) { char_u *cmd = NULL; *************** *** 3309,3528 **** } /* - * 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 --- 2799,2804 ---- *************** *** 3842,3872 **** } /* - * "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 --- 3118,3123 ---- *************** *** 4042,4114 **** } /* - * 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 --- 3293,3298 ---- *************** *** 4129,4371 **** 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" --- 3313,3318 ---- *************** *** 7690,7714 **** 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) { --- 6637,6642 ---- *************** *** 7804,7820 **** } /* - * "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 --- 6732,6737 ---- *************** *** 9161,9285 **** } /* - * "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 --- 8078,8083 ---- *************** *** 9660,9868 **** } /* - * "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 --- 8458,8463 ---- *** ../vim-8.1.2000/src/evalwindow.c 2019-09-07 15:42:29.088099994 +0200 --- src/evalwindow.c 2019-09-07 15:32:38.583450779 +0200 *************** *** 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 *** ../vim-8.1.2000/src/proto.h 2019-09-05 22:50:08.449226282 +0200 --- src/proto.h 2019-09-07 15:24:01.979506185 +0200 *************** *** 75,81 **** --- 75,84 ---- # 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,117 **** # ifdef FEAT_VIMINFO # include "viminfo.pro" # endif - # include "evalvars.pro" /* These prototypes cannot be produced automatically. */ int smsg(const char *, ...) --- 114,119 ---- *** ../vim-8.1.2000/src/proto/buffer.pro 2019-08-21 22:25:26.034016761 +0200 --- src/proto/buffer.pro 2019-09-07 15:36:52.315591626 +0200 *************** *** 65,74 **** 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 : */ --- 65,71 ---- *** ../vim-8.1.2000/src/proto/evalbuffer.pro 2019-09-07 15:42:29.100100097 +0200 --- src/proto/evalbuffer.pro 2019-09-07 15:36:52.563596410 +0200 *************** *** 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 : */ *** ../vim-8.1.2000/src/proto/evalfunc.pro 2019-09-05 22:33:23.264963492 +0200 --- src/proto/evalfunc.pro 2019-09-07 15:24:01.979506185 +0200 *************** *** 5,15 **** --- 5,17 ---- 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); *** ../vim-8.1.2000/src/proto/evalwindow.pro 2019-09-07 15:42:29.108100166 +0200 --- src/proto/evalwindow.pro 2019-09-07 15:36:53.055605896 +0200 *************** *** 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 : */ *** ../vim-8.1.2000/src/proto/window.pro 2019-09-02 22:31:08.010296361 +0200 --- src/proto/window.pro 2019-09-07 15:36:52.811601195 +0200 *************** *** 73,97 **** 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 : */ --- 73,80 ---- *** ../vim-8.1.2000/src/window.c 2019-09-02 22:31:08.014296345 +0200 --- src/window.c 2019-09-07 15:31:26.896012603 +0200 *************** *** 6587,6730 **** 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. --- 6587,6592 ---- *************** *** 6896,7207 **** 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 --- 6758,6760 ---- *** ../vim-8.1.2000/src/version.c 2019-09-07 15:44:34.789023120 +0200 --- src/version.c 2019-09-07 15:25:52.258638931 +0200 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 2001, /**/ -- hundred-and-one symptoms of being an internet addict: 208. Your goals for the future are obtaining an T1 connection and a 130 gig hard drive. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///