comparison src/evalfunc.c @ 18010:cf8e0c7e0cb9 v8.1.2001

patch 8.1.2001: some source files are too big Commit: https://github.com/vim/vim/commit/261f346f8154c0ec7094a4a211c653c74e9f7c2e Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 7 15:45:32 2019 +0200 patch 8.1.2001: some source files are too big Problem: Some source files are too big. Solution: Move buffer and window related functions to evalbuffer.c and evalwindow.c. (Yegappan Lakshmanan, closes #4898)
author Bram Moolenaar <Bram@vim.org>
date Sat, 07 Sep 2019 16:00:03 +0200
parents 8ae333756614
children 988e5a868b60
comparison
equal deleted inserted replaced
18009:40255308856f 18010:cf8e0c7e0cb9
27 #ifdef FEAT_FLOAT 27 #ifdef FEAT_FLOAT
28 static void f_abs(typval_T *argvars, typval_T *rettv); 28 static void f_abs(typval_T *argvars, typval_T *rettv);
29 static void f_acos(typval_T *argvars, typval_T *rettv); 29 static void f_acos(typval_T *argvars, typval_T *rettv);
30 #endif 30 #endif
31 static void f_and(typval_T *argvars, typval_T *rettv); 31 static void f_and(typval_T *argvars, typval_T *rettv);
32 static void f_append(typval_T *argvars, typval_T *rettv);
33 static void f_appendbufline(typval_T *argvars, typval_T *rettv);
34 #ifdef FEAT_FLOAT 32 #ifdef FEAT_FLOAT
35 static void f_asin(typval_T *argvars, typval_T *rettv); 33 static void f_asin(typval_T *argvars, typval_T *rettv);
36 static void f_atan(typval_T *argvars, typval_T *rettv); 34 static void f_atan(typval_T *argvars, typval_T *rettv);
37 static void f_atan2(typval_T *argvars, typval_T *rettv); 35 static void f_atan2(typval_T *argvars, typval_T *rettv);
38 #endif 36 #endif
41 static void f_balloon_show(typval_T *argvars, typval_T *rettv); 39 static void f_balloon_show(typval_T *argvars, typval_T *rettv);
42 # if defined(FEAT_BEVAL_TERM) 40 # if defined(FEAT_BEVAL_TERM)
43 static void f_balloon_split(typval_T *argvars, typval_T *rettv); 41 static void f_balloon_split(typval_T *argvars, typval_T *rettv);
44 # endif 42 # endif
45 #endif 43 #endif
46 static void f_bufadd(typval_T *argvars, typval_T *rettv);
47 static void f_bufexists(typval_T *argvars, typval_T *rettv);
48 static void f_buflisted(typval_T *argvars, typval_T *rettv);
49 static void f_bufload(typval_T *argvars, typval_T *rettv);
50 static void f_bufloaded(typval_T *argvars, typval_T *rettv);
51 static void f_bufname(typval_T *argvars, typval_T *rettv);
52 static void f_bufnr(typval_T *argvars, typval_T *rettv);
53 static void f_bufwinid(typval_T *argvars, typval_T *rettv);
54 static void f_bufwinnr(typval_T *argvars, typval_T *rettv);
55 static void f_byte2line(typval_T *argvars, typval_T *rettv); 44 static void f_byte2line(typval_T *argvars, typval_T *rettv);
56 static void byteidx(typval_T *argvars, typval_T *rettv, int comp); 45 static void byteidx(typval_T *argvars, typval_T *rettv, int comp);
57 static void f_byteidx(typval_T *argvars, typval_T *rettv); 46 static void f_byteidx(typval_T *argvars, typval_T *rettv);
58 static void f_byteidxcomp(typval_T *argvars, typval_T *rettv); 47 static void f_byteidxcomp(typval_T *argvars, typval_T *rettv);
59 static void f_call(typval_T *argvars, typval_T *rettv); 48 static void f_call(typval_T *argvars, typval_T *rettv);
73 static void f_cursor(typval_T *argsvars, typval_T *rettv); 62 static void f_cursor(typval_T *argsvars, typval_T *rettv);
74 #ifdef MSWIN 63 #ifdef MSWIN
75 static void f_debugbreak(typval_T *argvars, typval_T *rettv); 64 static void f_debugbreak(typval_T *argvars, typval_T *rettv);
76 #endif 65 #endif
77 static void f_deepcopy(typval_T *argvars, typval_T *rettv); 66 static void f_deepcopy(typval_T *argvars, typval_T *rettv);
78 static void f_deletebufline(typval_T *argvars, typval_T *rettv);
79 static void f_did_filetype(typval_T *argvars, typval_T *rettv); 67 static void f_did_filetype(typval_T *argvars, typval_T *rettv);
80 static void f_empty(typval_T *argvars, typval_T *rettv); 68 static void f_empty(typval_T *argvars, typval_T *rettv);
81 static void f_environ(typval_T *argvars, typval_T *rettv); 69 static void f_environ(typval_T *argvars, typval_T *rettv);
82 static void f_escape(typval_T *argvars, typval_T *rettv); 70 static void f_escape(typval_T *argvars, typval_T *rettv);
83 static void f_eval(typval_T *argvars, typval_T *rettv); 71 static void f_eval(typval_T *argvars, typval_T *rettv);
99 static void f_foreground(typval_T *argvars, typval_T *rettv); 87 static void f_foreground(typval_T *argvars, typval_T *rettv);
100 static void f_funcref(typval_T *argvars, typval_T *rettv); 88 static void f_funcref(typval_T *argvars, typval_T *rettv);
101 static void f_function(typval_T *argvars, typval_T *rettv); 89 static void f_function(typval_T *argvars, typval_T *rettv);
102 static void f_garbagecollect(typval_T *argvars, typval_T *rettv); 90 static void f_garbagecollect(typval_T *argvars, typval_T *rettv);
103 static void f_get(typval_T *argvars, typval_T *rettv); 91 static void f_get(typval_T *argvars, typval_T *rettv);
104 static void f_getbufinfo(typval_T *argvars, typval_T *rettv);
105 static void f_getbufline(typval_T *argvars, typval_T *rettv);
106 static void f_getchangelist(typval_T *argvars, typval_T *rettv); 92 static void f_getchangelist(typval_T *argvars, typval_T *rettv);
107 static void f_getchar(typval_T *argvars, typval_T *rettv); 93 static void f_getchar(typval_T *argvars, typval_T *rettv);
108 static void f_getcharmod(typval_T *argvars, typval_T *rettv); 94 static void f_getcharmod(typval_T *argvars, typval_T *rettv);
109 static void f_getcharsearch(typval_T *argvars, typval_T *rettv); 95 static void f_getcharsearch(typval_T *argvars, typval_T *rettv);
110 static void f_getcmdwintype(typval_T *argvars, typval_T *rettv); 96 static void f_getcmdwintype(typval_T *argvars, typval_T *rettv);
111 static void f_getenv(typval_T *argvars, typval_T *rettv); 97 static void f_getenv(typval_T *argvars, typval_T *rettv);
112 static void f_getfontname(typval_T *argvars, typval_T *rettv); 98 static void f_getfontname(typval_T *argvars, typval_T *rettv);
113 static void f_getjumplist(typval_T *argvars, typval_T *rettv); 99 static void f_getjumplist(typval_T *argvars, typval_T *rettv);
114 static void f_getline(typval_T *argvars, typval_T *rettv);
115 static void f_getpid(typval_T *argvars, typval_T *rettv); 100 static void f_getpid(typval_T *argvars, typval_T *rettv);
116 static void f_getcurpos(typval_T *argvars, typval_T *rettv); 101 static void f_getcurpos(typval_T *argvars, typval_T *rettv);
117 static void f_getpos(typval_T *argvars, typval_T *rettv); 102 static void f_getpos(typval_T *argvars, typval_T *rettv);
118 static void f_getreg(typval_T *argvars, typval_T *rettv); 103 static void f_getreg(typval_T *argvars, typval_T *rettv);
119 static void f_getregtype(typval_T *argvars, typval_T *rettv); 104 static void f_getregtype(typval_T *argvars, typval_T *rettv);
120 static void f_gettabinfo(typval_T *argvars, typval_T *rettv);
121 static void f_gettagstack(typval_T *argvars, typval_T *rettv); 105 static void f_gettagstack(typval_T *argvars, typval_T *rettv);
122 static void f_getwininfo(typval_T *argvars, typval_T *rettv);
123 static void f_getwinpos(typval_T *argvars, typval_T *rettv);
124 static void f_getwinposx(typval_T *argvars, typval_T *rettv);
125 static void f_getwinposy(typval_T *argvars, typval_T *rettv);
126 static void f_has(typval_T *argvars, typval_T *rettv); 106 static void f_has(typval_T *argvars, typval_T *rettv);
127 static void f_haslocaldir(typval_T *argvars, typval_T *rettv); 107 static void f_haslocaldir(typval_T *argvars, typval_T *rettv);
128 static void f_hasmapto(typval_T *argvars, typval_T *rettv); 108 static void f_hasmapto(typval_T *argvars, typval_T *rettv);
129 static void f_hlID(typval_T *argvars, typval_T *rettv); 109 static void f_hlID(typval_T *argvars, typval_T *rettv);
130 static void f_hlexists(typval_T *argvars, typval_T *rettv); 110 static void f_hlexists(typval_T *argvars, typval_T *rettv);
227 static void f_searchpair(typval_T *argvars, typval_T *rettv); 207 static void f_searchpair(typval_T *argvars, typval_T *rettv);
228 static void f_searchpairpos(typval_T *argvars, typval_T *rettv); 208 static void f_searchpairpos(typval_T *argvars, typval_T *rettv);
229 static void f_searchpos(typval_T *argvars, typval_T *rettv); 209 static void f_searchpos(typval_T *argvars, typval_T *rettv);
230 static void f_server2client(typval_T *argvars, typval_T *rettv); 210 static void f_server2client(typval_T *argvars, typval_T *rettv);
231 static void f_serverlist(typval_T *argvars, typval_T *rettv); 211 static void f_serverlist(typval_T *argvars, typval_T *rettv);
232 static void f_setbufline(typval_T *argvars, typval_T *rettv);
233 static void f_setcharsearch(typval_T *argvars, typval_T *rettv); 212 static void f_setcharsearch(typval_T *argvars, typval_T *rettv);
234 static void f_setenv(typval_T *argvars, typval_T *rettv); 213 static void f_setenv(typval_T *argvars, typval_T *rettv);
235 static void f_setfperm(typval_T *argvars, typval_T *rettv); 214 static void f_setfperm(typval_T *argvars, typval_T *rettv);
236 static void f_setline(typval_T *argvars, typval_T *rettv);
237 static void f_setpos(typval_T *argvars, typval_T *rettv); 215 static void f_setpos(typval_T *argvars, typval_T *rettv);
238 static void f_setreg(typval_T *argvars, typval_T *rettv); 216 static void f_setreg(typval_T *argvars, typval_T *rettv);
239 static void f_settagstack(typval_T *argvars, typval_T *rettv); 217 static void f_settagstack(typval_T *argvars, typval_T *rettv);
240 #ifdef FEAT_CRYPT 218 #ifdef FEAT_CRYPT
241 static void f_sha256(typval_T *argvars, typval_T *rettv); 219 static void f_sha256(typval_T *argvars, typval_T *rettv);
277 static void f_synIDattr(typval_T *argvars, typval_T *rettv); 255 static void f_synIDattr(typval_T *argvars, typval_T *rettv);
278 static void f_synIDtrans(typval_T *argvars, typval_T *rettv); 256 static void f_synIDtrans(typval_T *argvars, typval_T *rettv);
279 static void f_synstack(typval_T *argvars, typval_T *rettv); 257 static void f_synstack(typval_T *argvars, typval_T *rettv);
280 static void f_synconcealed(typval_T *argvars, typval_T *rettv); 258 static void f_synconcealed(typval_T *argvars, typval_T *rettv);
281 static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv); 259 static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv);
282 static void f_tabpagenr(typval_T *argvars, typval_T *rettv);
283 static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv);
284 static void f_taglist(typval_T *argvars, typval_T *rettv); 260 static void f_taglist(typval_T *argvars, typval_T *rettv);
285 static void f_tagfiles(typval_T *argvars, typval_T *rettv); 261 static void f_tagfiles(typval_T *argvars, typval_T *rettv);
286 #ifdef FEAT_FLOAT 262 #ifdef FEAT_FLOAT
287 static void f_tan(typval_T *argvars, typval_T *rettv); 263 static void f_tan(typval_T *argvars, typval_T *rettv);
288 static void f_tanh(typval_T *argvars, typval_T *rettv); 264 static void f_tanh(typval_T *argvars, typval_T *rettv);
296 #endif 272 #endif
297 static void f_type(typval_T *argvars, typval_T *rettv); 273 static void f_type(typval_T *argvars, typval_T *rettv);
298 static void f_virtcol(typval_T *argvars, typval_T *rettv); 274 static void f_virtcol(typval_T *argvars, typval_T *rettv);
299 static void f_visualmode(typval_T *argvars, typval_T *rettv); 275 static void f_visualmode(typval_T *argvars, typval_T *rettv);
300 static void f_wildmenumode(typval_T *argvars, typval_T *rettv); 276 static void f_wildmenumode(typval_T *argvars, typval_T *rettv);
301 static void f_win_execute(typval_T *argvars, typval_T *rettv);
302 static void f_win_findbuf(typval_T *argvars, typval_T *rettv);
303 static void f_win_getid(typval_T *argvars, typval_T *rettv);
304 static void f_win_gotoid(typval_T *argvars, typval_T *rettv);
305 static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv);
306 static void f_win_id2win(typval_T *argvars, typval_T *rettv);
307 static void f_win_screenpos(typval_T *argvars, typval_T *rettv);
308 static void f_winbufnr(typval_T *argvars, typval_T *rettv);
309 static void f_wincol(typval_T *argvars, typval_T *rettv);
310 static void f_winheight(typval_T *argvars, typval_T *rettv);
311 static void f_winlayout(typval_T *argvars, typval_T *rettv);
312 static void f_winline(typval_T *argvars, typval_T *rettv);
313 static void f_winnr(typval_T *argvars, typval_T *rettv);
314 static void f_winrestcmd(typval_T *argvars, typval_T *rettv);
315 static void f_winrestview(typval_T *argvars, typval_T *rettv);
316 static void f_winsaveview(typval_T *argvars, typval_T *rettv);
317 static void f_winwidth(typval_T *argvars, typval_T *rettv);
318 static void f_wordcount(typval_T *argvars, typval_T *rettv); 277 static void f_wordcount(typval_T *argvars, typval_T *rettv);
319 static void f_xor(typval_T *argvars, typval_T *rettv); 278 static void f_xor(typval_T *argvars, typval_T *rettv);
320 279
321 /* 280 /*
322 * Array with names and number of arguments of all internal functions 281 * Array with names and number of arguments of all internal functions
1125 /* 1084 /*
1126 * Get the lnum from the first argument. 1085 * Get the lnum from the first argument.
1127 * Also accepts "$", then "buf" is used. 1086 * Also accepts "$", then "buf" is used.
1128 * Returns 0 on error. 1087 * Returns 0 on error.
1129 */ 1088 */
1130 static linenr_T 1089 linenr_T
1131 tv_get_lnum_buf(typval_T *argvars, buf_T *buf) 1090 tv_get_lnum_buf(typval_T *argvars, buf_T *buf)
1132 { 1091 {
1133 if (argvars[0].v_type == VAR_STRING 1092 if (argvars[0].v_type == VAR_STRING
1134 && argvars[0].vval.v_string != NULL 1093 && argvars[0].vval.v_string != NULL
1135 && argvars[0].vval.v_string[0] == '$' 1094 && argvars[0].vval.v_string[0] == '$'
1210 { 1169 {
1211 rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL) 1170 rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
1212 & tv_get_number_chk(&argvars[1], NULL); 1171 & tv_get_number_chk(&argvars[1], NULL);
1213 } 1172 }
1214 1173
1215 /*
1216 * If there is a window for "curbuf", make it the current window.
1217 */
1218 static void
1219 find_win_for_curbuf(void)
1220 {
1221 wininfo_T *wip;
1222
1223 for (wip = curbuf->b_wininfo; wip != NULL; wip = wip->wi_next)
1224 {
1225 if (wip->wi_win != NULL)
1226 {
1227 curwin = wip->wi_win;
1228 break;
1229 }
1230 }
1231 }
1232
1233 /*
1234 * Set line or list of lines in buffer "buf".
1235 */
1236 static void
1237 set_buffer_lines(
1238 buf_T *buf,
1239 linenr_T lnum_arg,
1240 int append,
1241 typval_T *lines,
1242 typval_T *rettv)
1243 {
1244 linenr_T lnum = lnum_arg + (append ? 1 : 0);
1245 char_u *line = NULL;
1246 list_T *l = NULL;
1247 listitem_T *li = NULL;
1248 long added = 0;
1249 linenr_T append_lnum;
1250 buf_T *curbuf_save = NULL;
1251 win_T *curwin_save = NULL;
1252 int is_curbuf = buf == curbuf;
1253
1254 /* When using the current buffer ml_mfp will be set if needed. Useful when
1255 * setline() is used on startup. For other buffers the buffer must be
1256 * loaded. */
1257 if (buf == NULL || (!is_curbuf && buf->b_ml.ml_mfp == NULL) || lnum < 1)
1258 {
1259 rettv->vval.v_number = 1; /* FAIL */
1260 return;
1261 }
1262
1263 if (!is_curbuf)
1264 {
1265 curbuf_save = curbuf;
1266 curwin_save = curwin;
1267 curbuf = buf;
1268 find_win_for_curbuf();
1269 }
1270
1271 if (append)
1272 // appendbufline() uses the line number below which we insert
1273 append_lnum = lnum - 1;
1274 else
1275 // setbufline() uses the line number above which we insert, we only
1276 // append if it's below the last line
1277 append_lnum = curbuf->b_ml.ml_line_count;
1278
1279 if (lines->v_type == VAR_LIST)
1280 {
1281 l = lines->vval.v_list;
1282 li = l->lv_first;
1283 }
1284 else
1285 line = tv_get_string_chk(lines);
1286
1287 /* default result is zero == OK */
1288 for (;;)
1289 {
1290 if (l != NULL)
1291 {
1292 /* list argument, get next string */
1293 if (li == NULL)
1294 break;
1295 line = tv_get_string_chk(&li->li_tv);
1296 li = li->li_next;
1297 }
1298
1299 rettv->vval.v_number = 1; /* FAIL */
1300 if (line == NULL || lnum > curbuf->b_ml.ml_line_count + 1)
1301 break;
1302
1303 /* When coming here from Insert mode, sync undo, so that this can be
1304 * undone separately from what was previously inserted. */
1305 if (u_sync_once == 2)
1306 {
1307 u_sync_once = 1; /* notify that u_sync() was called */
1308 u_sync(TRUE);
1309 }
1310
1311 if (!append && lnum <= curbuf->b_ml.ml_line_count)
1312 {
1313 // Existing line, replace it.
1314 // Removes any existing text properties.
1315 if (u_savesub(lnum) == OK && ml_replace_len(
1316 lnum, line, (colnr_T)STRLEN(line) + 1, TRUE, TRUE) == OK)
1317 {
1318 changed_bytes(lnum, 0);
1319 if (is_curbuf && lnum == curwin->w_cursor.lnum)
1320 check_cursor_col();
1321 rettv->vval.v_number = 0; /* OK */
1322 }
1323 }
1324 else if (added > 0 || u_save(lnum - 1, lnum) == OK)
1325 {
1326 /* append the line */
1327 ++added;
1328 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
1329 rettv->vval.v_number = 0; /* OK */
1330 }
1331
1332 if (l == NULL) /* only one string argument */
1333 break;
1334 ++lnum;
1335 }
1336
1337 if (added > 0)
1338 {
1339 win_T *wp;
1340 tabpage_T *tp;
1341
1342 appended_lines_mark(append_lnum, added);
1343
1344 // Only adjust the cursor for buffers other than the current, unless it
1345 // is the current window. For curbuf and other windows it has been
1346 // done in mark_adjust_internal().
1347 FOR_ALL_TAB_WINDOWS(tp, wp)
1348 if (wp->w_buffer == buf
1349 && (wp->w_buffer != curbuf || wp == curwin)
1350 && wp->w_cursor.lnum > append_lnum)
1351 wp->w_cursor.lnum += added;
1352 check_cursor_col();
1353 update_topline();
1354 }
1355
1356 if (!is_curbuf)
1357 {
1358 curbuf = curbuf_save;
1359 curwin = curwin_save;
1360 }
1361 }
1362
1363 /*
1364 * "append(lnum, string/list)" function
1365 */
1366 static void
1367 f_append(typval_T *argvars, typval_T *rettv)
1368 {
1369 linenr_T lnum = tv_get_lnum(&argvars[0]);
1370
1371 set_buffer_lines(curbuf, lnum, TRUE, &argvars[1], rettv);
1372 }
1373
1374 /*
1375 * "appendbufline(buf, lnum, string/list)" function
1376 */
1377 static void
1378 f_appendbufline(typval_T *argvars, typval_T *rettv)
1379 {
1380 linenr_T lnum;
1381 buf_T *buf;
1382
1383 buf = tv_get_buf(&argvars[0], FALSE);
1384 if (buf == NULL)
1385 rettv->vval.v_number = 1; /* FAIL */
1386 else
1387 {
1388 lnum = tv_get_lnum_buf(&argvars[1], buf);
1389 set_buffer_lines(buf, lnum, TRUE, &argvars[2], rettv);
1390 }
1391 }
1392
1393 #ifdef FEAT_FLOAT 1174 #ifdef FEAT_FLOAT
1394 /* 1175 /*
1395 * "asin()" function 1176 * "asin()" function
1396 */ 1177 */
1397 static void 1178 static void
1506 } 1287 }
1507 } 1288 }
1508 } 1289 }
1509 # endif 1290 # endif
1510 #endif 1291 #endif
1511
1512 /*
1513 * Find a buffer by number or exact name.
1514 */
1515 static buf_T *
1516 find_buffer(typval_T *avar)
1517 {
1518 buf_T *buf = NULL;
1519
1520 if (avar->v_type == VAR_NUMBER)
1521 buf = buflist_findnr((int)avar->vval.v_number);
1522 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL)
1523 {
1524 buf = buflist_findname_exp(avar->vval.v_string);
1525 if (buf == NULL)
1526 {
1527 /* No full path name match, try a match with a URL or a "nofile"
1528 * buffer, these don't use the full path. */
1529 FOR_ALL_BUFFERS(buf)
1530 if (buf->b_fname != NULL
1531 && (path_with_url(buf->b_fname)
1532 #ifdef FEAT_QUICKFIX
1533 || bt_nofilename(buf)
1534 #endif
1535 )
1536 && STRCMP(buf->b_fname, avar->vval.v_string) == 0)
1537 break;
1538 }
1539 }
1540 return buf;
1541 }
1542
1543 /*
1544 * "bufadd(expr)" function
1545 */
1546 static void
1547 f_bufadd(typval_T *argvars, typval_T *rettv)
1548 {
1549 char_u *name = tv_get_string(&argvars[0]);
1550
1551 rettv->vval.v_number = buflist_add(*name == NUL ? NULL : name, 0);
1552 }
1553
1554 /*
1555 * "bufexists(expr)" function
1556 */
1557 static void
1558 f_bufexists(typval_T *argvars, typval_T *rettv)
1559 {
1560 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
1561 }
1562
1563 /*
1564 * "buflisted(expr)" function
1565 */
1566 static void
1567 f_buflisted(typval_T *argvars, typval_T *rettv)
1568 {
1569 buf_T *buf;
1570
1571 buf = find_buffer(&argvars[0]);
1572 rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
1573 }
1574
1575 /*
1576 * "bufload(expr)" function
1577 */
1578 static void
1579 f_bufload(typval_T *argvars, typval_T *rettv UNUSED)
1580 {
1581 buf_T *buf = get_buf_arg(&argvars[0]);
1582
1583 if (buf != NULL)
1584 buffer_ensure_loaded(buf);
1585 }
1586
1587 /*
1588 * "bufloaded(expr)" function
1589 */
1590 static void
1591 f_bufloaded(typval_T *argvars, typval_T *rettv)
1592 {
1593 buf_T *buf;
1594
1595 buf = find_buffer(&argvars[0]);
1596 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
1597 }
1598
1599 buf_T *
1600 buflist_find_by_name(char_u *name, int curtab_only)
1601 {
1602 int save_magic;
1603 char_u *save_cpo;
1604 buf_T *buf;
1605
1606 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */
1607 save_magic = p_magic;
1608 p_magic = TRUE;
1609 save_cpo = p_cpo;
1610 p_cpo = (char_u *)"";
1611
1612 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
1613 TRUE, FALSE, curtab_only));
1614
1615 p_magic = save_magic;
1616 p_cpo = save_cpo;
1617 return buf;
1618 }
1619 1292
1620 /* 1293 /*
1621 * Get buffer by number or pattern. 1294 * Get buffer by number or pattern.
1622 */ 1295 */
1623 buf_T * 1296 buf_T *
1657 buf = tv_get_buf(arg, FALSE); 1330 buf = tv_get_buf(arg, FALSE);
1658 --emsg_off; 1331 --emsg_off;
1659 if (buf == NULL) 1332 if (buf == NULL)
1660 semsg(_("E158: Invalid buffer name: %s"), tv_get_string(arg)); 1333 semsg(_("E158: Invalid buffer name: %s"), tv_get_string(arg));
1661 return buf; 1334 return buf;
1662 }
1663
1664 /*
1665 * "bufname(expr)" function
1666 */
1667 static void
1668 f_bufname(typval_T *argvars, typval_T *rettv)
1669 {
1670 buf_T *buf;
1671
1672 if (argvars[0].v_type == VAR_UNKNOWN)
1673 buf = curbuf;
1674 else
1675 {
1676 (void)tv_get_number(&argvars[0]); // issue errmsg if type error
1677 ++emsg_off;
1678 buf = tv_get_buf(&argvars[0], FALSE);
1679 --emsg_off;
1680 }
1681 rettv->v_type = VAR_STRING;
1682 if (buf != NULL && buf->b_fname != NULL)
1683 rettv->vval.v_string = vim_strsave(buf->b_fname);
1684 else
1685 rettv->vval.v_string = NULL;
1686 }
1687
1688 /*
1689 * "bufnr(expr)" function
1690 */
1691 static void
1692 f_bufnr(typval_T *argvars, typval_T *rettv)
1693 {
1694 buf_T *buf;
1695 int error = FALSE;
1696 char_u *name;
1697
1698 if (argvars[0].v_type == VAR_UNKNOWN)
1699 buf = curbuf;
1700 else
1701 {
1702 (void)tv_get_number(&argvars[0]); // issue errmsg if type error
1703 ++emsg_off;
1704 buf = tv_get_buf(&argvars[0], FALSE);
1705 --emsg_off;
1706 }
1707
1708 // If the buffer isn't found and the second argument is not zero create a
1709 // new buffer.
1710 if (buf == NULL
1711 && argvars[1].v_type != VAR_UNKNOWN
1712 && tv_get_number_chk(&argvars[1], &error) != 0
1713 && !error
1714 && (name = tv_get_string_chk(&argvars[0])) != NULL
1715 && !error)
1716 buf = buflist_new(name, NULL, (linenr_T)1, 0);
1717
1718 if (buf != NULL)
1719 rettv->vval.v_number = buf->b_fnum;
1720 else
1721 rettv->vval.v_number = -1;
1722 }
1723
1724 static void
1725 buf_win_common(typval_T *argvars, typval_T *rettv, int get_nr)
1726 {
1727 win_T *wp;
1728 int winnr = 0;
1729 buf_T *buf;
1730
1731 (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */
1732 ++emsg_off;
1733 buf = tv_get_buf(&argvars[0], TRUE);
1734 FOR_ALL_WINDOWS(wp)
1735 {
1736 ++winnr;
1737 if (wp->w_buffer == buf)
1738 break;
1739 }
1740 rettv->vval.v_number = (wp != NULL ? (get_nr ? winnr : wp->w_id) : -1);
1741 --emsg_off;
1742 }
1743
1744 /*
1745 * "bufwinid(nr)" function
1746 */
1747 static void
1748 f_bufwinid(typval_T *argvars, typval_T *rettv)
1749 {
1750 buf_win_common(argvars, rettv, FALSE);
1751 }
1752
1753 /*
1754 * "bufwinnr(nr)" function
1755 */
1756 static void
1757 f_bufwinnr(typval_T *argvars, typval_T *rettv)
1758 {
1759 buf_win_common(argvars, rettv, TRUE);
1760 } 1335 }
1761 1336
1762 /* 1337 /*
1763 * "byte2line(byte)" function 1338 * "byte2line(byte)" function
1764 */ 1339 */
2200 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? copyID : 0); 1775 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? copyID : 0);
2201 } 1776 }
2202 } 1777 }
2203 1778
2204 /* 1779 /*
2205 * "deletebufline()" function
2206 */
2207 static void
2208 f_deletebufline(typval_T *argvars, typval_T *rettv)
2209 {
2210 buf_T *buf;
2211 linenr_T first, last;
2212 linenr_T lnum;
2213 long count;
2214 int is_curbuf;
2215 buf_T *curbuf_save = NULL;
2216 win_T *curwin_save = NULL;
2217 tabpage_T *tp;
2218 win_T *wp;
2219
2220 buf = tv_get_buf(&argvars[0], FALSE);
2221 if (buf == NULL)
2222 {
2223 rettv->vval.v_number = 1; /* FAIL */
2224 return;
2225 }
2226 is_curbuf = buf == curbuf;
2227
2228 first = tv_get_lnum_buf(&argvars[1], buf);
2229 if (argvars[2].v_type != VAR_UNKNOWN)
2230 last = tv_get_lnum_buf(&argvars[2], buf);
2231 else
2232 last = first;
2233
2234 if (buf->b_ml.ml_mfp == NULL || first < 1
2235 || first > buf->b_ml.ml_line_count || last < first)
2236 {
2237 rettv->vval.v_number = 1; /* FAIL */
2238 return;
2239 }
2240
2241 if (!is_curbuf)
2242 {
2243 curbuf_save = curbuf;
2244 curwin_save = curwin;
2245 curbuf = buf;
2246 find_win_for_curbuf();
2247 }
2248 if (last > curbuf->b_ml.ml_line_count)
2249 last = curbuf->b_ml.ml_line_count;
2250 count = last - first + 1;
2251
2252 // When coming here from Insert mode, sync undo, so that this can be
2253 // undone separately from what was previously inserted.
2254 if (u_sync_once == 2)
2255 {
2256 u_sync_once = 1; // notify that u_sync() was called
2257 u_sync(TRUE);
2258 }
2259
2260 if (u_save(first - 1, last + 1) == FAIL)
2261 {
2262 rettv->vval.v_number = 1; /* FAIL */
2263 return;
2264 }
2265
2266 for (lnum = first; lnum <= last; ++lnum)
2267 ml_delete(first, TRUE);
2268
2269 FOR_ALL_TAB_WINDOWS(tp, wp)
2270 if (wp->w_buffer == buf)
2271 {
2272 if (wp->w_cursor.lnum > last)
2273 wp->w_cursor.lnum -= count;
2274 else if (wp->w_cursor.lnum> first)
2275 wp->w_cursor.lnum = first;
2276 if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count)
2277 wp->w_cursor.lnum = wp->w_buffer->b_ml.ml_line_count;
2278 }
2279 check_cursor_col();
2280 deleted_lines_mark(first, count);
2281
2282 if (!is_curbuf)
2283 {
2284 curbuf = curbuf_save;
2285 curwin = curwin_save;
2286 }
2287 }
2288
2289 /*
2290 * "did_filetype()" function 1780 * "did_filetype()" function
2291 */ 1781 */
2292 static void 1782 static void
2293 f_did_filetype(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 1783 f_did_filetype(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
2294 { 1784 {
2507 } 1997 }
2508 1998
2509 /* 1999 /*
2510 * "execute()" function 2000 * "execute()" function
2511 */ 2001 */
2512 static void 2002 void
2513 execute_common(typval_T *argvars, typval_T *rettv, int arg_off) 2003 execute_common(typval_T *argvars, typval_T *rettv, int arg_off)
2514 { 2004 {
2515 char_u *cmd = NULL; 2005 char_u *cmd = NULL;
2516 list_T *list = NULL; 2006 list_T *list = NULL;
2517 int save_msg_silent = msg_silent; 2007 int save_msg_silent = msg_silent;
3307 else 2797 else
3308 copy_tv(tv, rettv); 2798 copy_tv(tv, rettv);
3309 } 2799 }
3310 2800
3311 /* 2801 /*
3312 * Returns buffer options, variables and other attributes in a dictionary.
3313 */
3314 static dict_T *
3315 get_buffer_info(buf_T *buf)
3316 {
3317 dict_T *dict;
3318 tabpage_T *tp;
3319 win_T *wp;
3320 list_T *windows;
3321
3322 dict = dict_alloc();
3323 if (dict == NULL)
3324 return NULL;
3325
3326 dict_add_number(dict, "bufnr", buf->b_fnum);
3327 dict_add_string(dict, "name", buf->b_ffname);
3328 dict_add_number(dict, "lnum", buf == curbuf ? curwin->w_cursor.lnum
3329 : buflist_findlnum(buf));
3330 dict_add_number(dict, "loaded", buf->b_ml.ml_mfp != NULL);
3331 dict_add_number(dict, "listed", buf->b_p_bl);
3332 dict_add_number(dict, "changed", bufIsChanged(buf));
3333 dict_add_number(dict, "changedtick", CHANGEDTICK(buf));
3334 dict_add_number(dict, "hidden",
3335 buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0);
3336
3337 // Get a reference to buffer variables
3338 dict_add_dict(dict, "variables", buf->b_vars);
3339
3340 // List of windows displaying this buffer
3341 windows = list_alloc();
3342 if (windows != NULL)
3343 {
3344 FOR_ALL_TAB_WINDOWS(tp, wp)
3345 if (wp->w_buffer == buf)
3346 list_append_number(windows, (varnumber_T)wp->w_id);
3347 dict_add_list(dict, "windows", windows);
3348 }
3349
3350 #ifdef FEAT_TEXT_PROP
3351 // List of popup windows displaying this buffer
3352 windows = list_alloc();
3353 if (windows != NULL)
3354 {
3355 for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
3356 if (wp->w_buffer == buf)
3357 list_append_number(windows, (varnumber_T)wp->w_id);
3358 FOR_ALL_TABPAGES(tp)
3359 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next)
3360 if (wp->w_buffer == buf)
3361 list_append_number(windows, (varnumber_T)wp->w_id);
3362
3363 dict_add_list(dict, "popups", windows);
3364 }
3365 #endif
3366
3367 #ifdef FEAT_SIGNS
3368 if (buf->b_signlist != NULL)
3369 {
3370 /* List of signs placed in this buffer */
3371 list_T *signs = list_alloc();
3372 if (signs != NULL)
3373 {
3374 get_buffer_signs(buf, signs);
3375 dict_add_list(dict, "signs", signs);
3376 }
3377 }
3378 #endif
3379
3380 return dict;
3381 }
3382
3383 /*
3384 * "getbufinfo()" function
3385 */
3386 static void
3387 f_getbufinfo(typval_T *argvars, typval_T *rettv)
3388 {
3389 buf_T *buf = NULL;
3390 buf_T *argbuf = NULL;
3391 dict_T *d;
3392 int filtered = FALSE;
3393 int sel_buflisted = FALSE;
3394 int sel_bufloaded = FALSE;
3395 int sel_bufmodified = FALSE;
3396
3397 if (rettv_list_alloc(rettv) != OK)
3398 return;
3399
3400 /* List of all the buffers or selected buffers */
3401 if (argvars[0].v_type == VAR_DICT)
3402 {
3403 dict_T *sel_d = argvars[0].vval.v_dict;
3404
3405 if (sel_d != NULL)
3406 {
3407 dictitem_T *di;
3408
3409 filtered = TRUE;
3410
3411 di = dict_find(sel_d, (char_u *)"buflisted", -1);
3412 if (di != NULL && tv_get_number(&di->di_tv))
3413 sel_buflisted = TRUE;
3414
3415 di = dict_find(sel_d, (char_u *)"bufloaded", -1);
3416 if (di != NULL && tv_get_number(&di->di_tv))
3417 sel_bufloaded = TRUE;
3418
3419 di = dict_find(sel_d, (char_u *)"bufmodified", -1);
3420 if (di != NULL && tv_get_number(&di->di_tv))
3421 sel_bufmodified = TRUE;
3422 }
3423 }
3424 else if (argvars[0].v_type != VAR_UNKNOWN)
3425 {
3426 /* Information about one buffer. Argument specifies the buffer */
3427 (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */
3428 ++emsg_off;
3429 argbuf = tv_get_buf(&argvars[0], FALSE);
3430 --emsg_off;
3431 if (argbuf == NULL)
3432 return;
3433 }
3434
3435 /* Return information about all the buffers or a specified buffer */
3436 FOR_ALL_BUFFERS(buf)
3437 {
3438 if (argbuf != NULL && argbuf != buf)
3439 continue;
3440 if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL)
3441 || (sel_buflisted && !buf->b_p_bl)
3442 || (sel_bufmodified && !buf->b_changed)))
3443 continue;
3444
3445 d = get_buffer_info(buf);
3446 if (d != NULL)
3447 list_append_dict(rettv->vval.v_list, d);
3448 if (argbuf != NULL)
3449 return;
3450 }
3451 }
3452
3453 /*
3454 * Get line or list of lines from buffer "buf" into "rettv".
3455 * Return a range (from start to end) of lines in rettv from the specified
3456 * buffer.
3457 * If 'retlist' is TRUE, then the lines are returned as a Vim List.
3458 */
3459 static void
3460 get_buffer_lines(
3461 buf_T *buf,
3462 linenr_T start,
3463 linenr_T end,
3464 int retlist,
3465 typval_T *rettv)
3466 {
3467 char_u *p;
3468
3469 rettv->v_type = VAR_STRING;
3470 rettv->vval.v_string = NULL;
3471 if (retlist && rettv_list_alloc(rettv) == FAIL)
3472 return;
3473
3474 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0)
3475 return;
3476
3477 if (!retlist)
3478 {
3479 if (start >= 1 && start <= buf->b_ml.ml_line_count)
3480 p = ml_get_buf(buf, start, FALSE);
3481 else
3482 p = (char_u *)"";
3483 rettv->vval.v_string = vim_strsave(p);
3484 }
3485 else
3486 {
3487 if (end < start)
3488 return;
3489
3490 if (start < 1)
3491 start = 1;
3492 if (end > buf->b_ml.ml_line_count)
3493 end = buf->b_ml.ml_line_count;
3494 while (start <= end)
3495 if (list_append_string(rettv->vval.v_list,
3496 ml_get_buf(buf, start++, FALSE), -1) == FAIL)
3497 break;
3498 }
3499 }
3500
3501 /*
3502 * "getbufline()" function
3503 */
3504 static void
3505 f_getbufline(typval_T *argvars, typval_T *rettv)
3506 {
3507 linenr_T lnum;
3508 linenr_T end;
3509 buf_T *buf;
3510
3511 (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */
3512 ++emsg_off;
3513 buf = tv_get_buf(&argvars[0], FALSE);
3514 --emsg_off;
3515
3516 lnum = tv_get_lnum_buf(&argvars[1], buf);
3517 if (argvars[2].v_type == VAR_UNKNOWN)
3518 end = lnum;
3519 else
3520 end = tv_get_lnum_buf(&argvars[2], buf);
3521
3522 get_buffer_lines(buf, lnum, end, TRUE, rettv);
3523 }
3524
3525 /*
3526 * "getchangelist()" function 2802 * "getchangelist()" function
3527 */ 2803 */
3528 static void 2804 static void
3529 f_getchangelist(typval_T *argvars, typval_T *rettv) 2805 f_getchangelist(typval_T *argvars, typval_T *rettv)
3530 { 2806 {
3840 } 3116 }
3841 #endif 3117 #endif
3842 } 3118 }
3843 3119
3844 /* 3120 /*
3845 * "getline(lnum, [end])" function
3846 */
3847 static void
3848 f_getline(typval_T *argvars, typval_T *rettv)
3849 {
3850 linenr_T lnum;
3851 linenr_T end;
3852 int retlist;
3853
3854 lnum = tv_get_lnum(argvars);
3855 if (argvars[1].v_type == VAR_UNKNOWN)
3856 {
3857 end = 0;
3858 retlist = FALSE;
3859 }
3860 else
3861 {
3862 end = tv_get_lnum(&argvars[1]);
3863 retlist = TRUE;
3864 }
3865
3866 get_buffer_lines(curbuf, lnum, end, retlist, rettv);
3867 }
3868
3869 /*
3870 * "getpid()" function 3121 * "getpid()" function
3871 */ 3122 */
3872 static void 3123 static void
3873 f_getpid(typval_T *argvars UNUSED, typval_T *rettv) 3124 f_getpid(typval_T *argvars UNUSED, typval_T *rettv)
3874 { 3125 {
4040 rettv->v_type = VAR_STRING; 3291 rettv->v_type = VAR_STRING;
4041 rettv->vval.v_string = vim_strsave(buf); 3292 rettv->vval.v_string = vim_strsave(buf);
4042 } 3293 }
4043 3294
4044 /* 3295 /*
4045 * Returns information (variables, options, etc.) about a tab page
4046 * as a dictionary.
4047 */
4048 static dict_T *
4049 get_tabpage_info(tabpage_T *tp, int tp_idx)
4050 {
4051 win_T *wp;
4052 dict_T *dict;
4053 list_T *l;
4054
4055 dict = dict_alloc();
4056 if (dict == NULL)
4057 return NULL;
4058
4059 dict_add_number(dict, "tabnr", tp_idx);
4060
4061 l = list_alloc();
4062 if (l != NULL)
4063 {
4064 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
4065 wp != NULL; wp = wp->w_next)
4066 list_append_number(l, (varnumber_T)wp->w_id);
4067 dict_add_list(dict, "windows", l);
4068 }
4069
4070 /* Make a reference to tabpage variables */
4071 dict_add_dict(dict, "variables", tp->tp_vars);
4072
4073 return dict;
4074 }
4075
4076 /*
4077 * "gettabinfo()" function
4078 */
4079 static void
4080 f_gettabinfo(typval_T *argvars, typval_T *rettv)
4081 {
4082 tabpage_T *tp, *tparg = NULL;
4083 dict_T *d;
4084 int tpnr = 0;
4085
4086 if (rettv_list_alloc(rettv) != OK)
4087 return;
4088
4089 if (argvars[0].v_type != VAR_UNKNOWN)
4090 {
4091 /* Information about one tab page */
4092 tparg = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
4093 if (tparg == NULL)
4094 return;
4095 }
4096
4097 /* Get information about a specific tab page or all tab pages */
4098 FOR_ALL_TABPAGES(tp)
4099 {
4100 tpnr++;
4101 if (tparg != NULL && tp != tparg)
4102 continue;
4103 d = get_tabpage_info(tp, tpnr);
4104 if (d != NULL)
4105 list_append_dict(rettv->vval.v_list, d);
4106 if (tparg != NULL)
4107 return;
4108 }
4109 }
4110
4111 /*
4112 * "gettagstack()" function 3296 * "gettagstack()" function
4113 */ 3297 */
4114 static void 3298 static void
4115 f_gettagstack(typval_T *argvars, typval_T *rettv) 3299 f_gettagstack(typval_T *argvars, typval_T *rettv)
4116 { 3300 {
4125 if (wp == NULL) 3309 if (wp == NULL)
4126 return; 3310 return;
4127 } 3311 }
4128 3312
4129 get_tagstack(wp, rettv->vval.v_dict); 3313 get_tagstack(wp, rettv->vval.v_dict);
4130 }
4131
4132 /*
4133 * Returns information about a window as a dictionary.
4134 */
4135 static dict_T *
4136 get_win_info(win_T *wp, short tpnr, short winnr)
4137 {
4138 dict_T *dict;
4139
4140 dict = dict_alloc();
4141 if (dict == NULL)
4142 return NULL;
4143
4144 dict_add_number(dict, "tabnr", tpnr);
4145 dict_add_number(dict, "winnr", winnr);
4146 dict_add_number(dict, "winid", wp->w_id);
4147 dict_add_number(dict, "height", wp->w_height);
4148 dict_add_number(dict, "winrow", wp->w_winrow + 1);
4149 dict_add_number(dict, "topline", wp->w_topline);
4150 dict_add_number(dict, "botline", wp->w_botline - 1);
4151 #ifdef FEAT_MENU
4152 dict_add_number(dict, "winbar", wp->w_winbar_height);
4153 #endif
4154 dict_add_number(dict, "width", wp->w_width);
4155 dict_add_number(dict, "wincol", wp->w_wincol + 1);
4156 dict_add_number(dict, "bufnr", wp->w_buffer->b_fnum);
4157
4158 #ifdef FEAT_TERMINAL
4159 dict_add_number(dict, "terminal", bt_terminal(wp->w_buffer));
4160 #endif
4161 #ifdef FEAT_QUICKFIX
4162 dict_add_number(dict, "quickfix", bt_quickfix(wp->w_buffer));
4163 dict_add_number(dict, "loclist",
4164 (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL));
4165 #endif
4166
4167 /* Add a reference to window variables */
4168 dict_add_dict(dict, "variables", wp->w_vars);
4169
4170 return dict;
4171 }
4172
4173 /*
4174 * "getwininfo()" function
4175 */
4176 static void
4177 f_getwininfo(typval_T *argvars, typval_T *rettv)
4178 {
4179 tabpage_T *tp;
4180 win_T *wp = NULL, *wparg = NULL;
4181 dict_T *d;
4182 short tabnr = 0, winnr;
4183
4184 if (rettv_list_alloc(rettv) != OK)
4185 return;
4186
4187 if (argvars[0].v_type != VAR_UNKNOWN)
4188 {
4189 wparg = win_id2wp(tv_get_number(&argvars[0]));
4190 if (wparg == NULL)
4191 return;
4192 }
4193
4194 /* Collect information about either all the windows across all the tab
4195 * pages or one particular window.
4196 */
4197 FOR_ALL_TABPAGES(tp)
4198 {
4199 tabnr++;
4200 winnr = 0;
4201 FOR_ALL_WINDOWS_IN_TAB(tp, wp)
4202 {
4203 winnr++;
4204 if (wparg != NULL && wp != wparg)
4205 continue;
4206 d = get_win_info(wp, tabnr, winnr);
4207 if (d != NULL)
4208 list_append_dict(rettv->vval.v_list, d);
4209 if (wparg != NULL)
4210 /* found information about a specific window */
4211 return;
4212 }
4213 }
4214 }
4215
4216 /*
4217 * "win_execute()" function
4218 */
4219 static void
4220 f_win_execute(typval_T *argvars, typval_T *rettv)
4221 {
4222 int id = (int)tv_get_number(argvars);
4223 tabpage_T *tp;
4224 win_T *wp = win_id2wp_tp(id, &tp);
4225 win_T *save_curwin;
4226 tabpage_T *save_curtab;
4227
4228 if (wp != NULL && tp != NULL)
4229 {
4230 if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, TRUE) == OK)
4231 {
4232 check_cursor();
4233 execute_common(argvars, rettv, 1);
4234 }
4235 restore_win_noblock(save_curwin, save_curtab, TRUE);
4236 }
4237 }
4238
4239 /*
4240 * "win_findbuf()" function
4241 */
4242 static void
4243 f_win_findbuf(typval_T *argvars, typval_T *rettv)
4244 {
4245 if (rettv_list_alloc(rettv) != FAIL)
4246 win_findbuf(argvars, rettv->vval.v_list);
4247 }
4248
4249 /*
4250 * "win_getid()" function
4251 */
4252 static void
4253 f_win_getid(typval_T *argvars, typval_T *rettv)
4254 {
4255 rettv->vval.v_number = win_getid(argvars);
4256 }
4257
4258 /*
4259 * "win_gotoid()" function
4260 */
4261 static void
4262 f_win_gotoid(typval_T *argvars, typval_T *rettv)
4263 {
4264 rettv->vval.v_number = win_gotoid(argvars);
4265 }
4266
4267 /*
4268 * "win_id2tabwin()" function
4269 */
4270 static void
4271 f_win_id2tabwin(typval_T *argvars, typval_T *rettv)
4272 {
4273 if (rettv_list_alloc(rettv) != FAIL)
4274 win_id2tabwin(argvars, rettv->vval.v_list);
4275 }
4276
4277 /*
4278 * "win_id2win()" function
4279 */
4280 static void
4281 f_win_id2win(typval_T *argvars, typval_T *rettv)
4282 {
4283 rettv->vval.v_number = win_id2win(argvars);
4284 }
4285
4286 /*
4287 * "win_screenpos()" function
4288 */
4289 static void
4290 f_win_screenpos(typval_T *argvars, typval_T *rettv)
4291 {
4292 win_T *wp;
4293
4294 if (rettv_list_alloc(rettv) == FAIL)
4295 return;
4296
4297 wp = find_win_by_nr_or_id(&argvars[0]);
4298 list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1);
4299 list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1);
4300 }
4301
4302 /*
4303 * "getwinpos({timeout})" function
4304 */
4305 static void
4306 f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv)
4307 {
4308 int x = -1;
4309 int y = -1;
4310
4311 if (rettv_list_alloc(rettv) == FAIL)
4312 return;
4313 #if defined(FEAT_GUI) \
4314 || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \
4315 || defined(MSWIN)
4316 {
4317 varnumber_T timeout = 100;
4318
4319 if (argvars[0].v_type != VAR_UNKNOWN)
4320 timeout = tv_get_number(&argvars[0]);
4321
4322 (void)ui_get_winpos(&x, &y, timeout);
4323 }
4324 #endif
4325 list_append_number(rettv->vval.v_list, (varnumber_T)x);
4326 list_append_number(rettv->vval.v_list, (varnumber_T)y);
4327 }
4328
4329
4330 /*
4331 * "getwinposx()" function
4332 */
4333 static void
4334 f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
4335 {
4336 rettv->vval.v_number = -1;
4337 #if defined(FEAT_GUI) \
4338 || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \
4339 || defined(MSWIN)
4340
4341 {
4342 int x, y;
4343
4344 if (ui_get_winpos(&x, &y, 100) == OK)
4345 rettv->vval.v_number = x;
4346 }
4347 #endif
4348 }
4349
4350 /*
4351 * "getwinposy()" function
4352 */
4353 static void
4354 f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
4355 {
4356 rettv->vval.v_number = -1;
4357 #if defined(FEAT_GUI) \
4358 || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \
4359 || defined(MSWIN)
4360 {
4361 int x, y;
4362
4363 if (ui_get_winpos(&x, &y, 100) == OK)
4364 rettv->vval.v_number = y;
4365 }
4366 #endif
4367 } 3314 }
4368 3315
4369 /* for VIM_VERSION_ defines */ 3316 /* for VIM_VERSION_ defines */
4370 #include "version.h" 3317 #include "version.h"
4371 3318
7688 #endif 6635 #endif
7689 rettv->v_type = VAR_STRING; 6636 rettv->v_type = VAR_STRING;
7690 rettv->vval.v_string = r; 6637 rettv->vval.v_string = r;
7691 } 6638 }
7692 6639
7693 /*
7694 * "setbufline()" function
7695 */
7696 static void
7697 f_setbufline(typval_T *argvars, typval_T *rettv)
7698 {
7699 linenr_T lnum;
7700 buf_T *buf;
7701
7702 buf = tv_get_buf(&argvars[0], FALSE);
7703 if (buf == NULL)
7704 rettv->vval.v_number = 1; /* FAIL */
7705 else
7706 {
7707 lnum = tv_get_lnum_buf(&argvars[1], buf);
7708 set_buffer_lines(buf, lnum, FALSE, &argvars[2], rettv);
7709 }
7710 }
7711
7712 static void 6640 static void
7713 f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED) 6641 f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED)
7714 { 6642 {
7715 dict_T *d; 6643 dict_T *d;
7716 dictitem_T *di; 6644 dictitem_T *di;
7799 if (mode_str[i] != '-') 6727 if (mode_str[i] != '-')
7800 mode |= mask; 6728 mode |= mask;
7801 mask = mask << 1; 6729 mask = mask << 1;
7802 } 6730 }
7803 rettv->vval.v_number = mch_setperm(fname, mode) == OK; 6731 rettv->vval.v_number = mch_setperm(fname, mode) == OK;
7804 }
7805
7806 /*
7807 * "setline()" function
7808 */
7809 static void
7810 f_setline(typval_T *argvars, typval_T *rettv)
7811 {
7812 linenr_T lnum = tv_get_lnum(&argvars[0]);
7813
7814 set_buffer_lines(curbuf, lnum, FALSE, &argvars[1], rettv);
7815 } 6732 }
7816 6733
7817 /* 6734 /*
7818 * "setpos()" function 6735 * "setpos()" function
7819 */ 6736 */
9159 break; 8076 break;
9160 } 8077 }
9161 } 8078 }
9162 8079
9163 /* 8080 /*
9164 * "tabpagenr()" function
9165 */
9166 static void
9167 f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv)
9168 {
9169 int nr = 1;
9170 char_u *arg;
9171
9172 if (argvars[0].v_type != VAR_UNKNOWN)
9173 {
9174 arg = tv_get_string_chk(&argvars[0]);
9175 nr = 0;
9176 if (arg != NULL)
9177 {
9178 if (STRCMP(arg, "$") == 0)
9179 nr = tabpage_index(NULL) - 1;
9180 else
9181 semsg(_(e_invexpr2), arg);
9182 }
9183 }
9184 else
9185 nr = tabpage_index(curtab);
9186 rettv->vval.v_number = nr;
9187 }
9188
9189
9190 /*
9191 * Common code for tabpagewinnr() and winnr().
9192 */
9193 static int
9194 get_winnr(tabpage_T *tp, typval_T *argvar)
9195 {
9196 win_T *twin;
9197 int nr = 1;
9198 win_T *wp;
9199 char_u *arg;
9200
9201 twin = (tp == curtab) ? curwin : tp->tp_curwin;
9202 if (argvar->v_type != VAR_UNKNOWN)
9203 {
9204 int invalid_arg = FALSE;
9205
9206 arg = tv_get_string_chk(argvar);
9207 if (arg == NULL)
9208 nr = 0; /* type error; errmsg already given */
9209 else if (STRCMP(arg, "$") == 0)
9210 twin = (tp == curtab) ? lastwin : tp->tp_lastwin;
9211 else if (STRCMP(arg, "#") == 0)
9212 {
9213 twin = (tp == curtab) ? prevwin : tp->tp_prevwin;
9214 if (twin == NULL)
9215 nr = 0;
9216 }
9217 else
9218 {
9219 long count;
9220 char_u *endp;
9221
9222 // Extract the window count (if specified). e.g. winnr('3j')
9223 count = strtol((char *)arg, (char **)&endp, 10);
9224 if (count <= 0)
9225 count = 1; // if count is not specified, default to 1
9226 if (endp != NULL && *endp != '\0')
9227 {
9228 if (STRCMP(endp, "j") == 0)
9229 twin = win_vert_neighbor(tp, twin, FALSE, count);
9230 else if (STRCMP(endp, "k") == 0)
9231 twin = win_vert_neighbor(tp, twin, TRUE, count);
9232 else if (STRCMP(endp, "h") == 0)
9233 twin = win_horz_neighbor(tp, twin, TRUE, count);
9234 else if (STRCMP(endp, "l") == 0)
9235 twin = win_horz_neighbor(tp, twin, FALSE, count);
9236 else
9237 invalid_arg = TRUE;
9238 }
9239 else
9240 invalid_arg = TRUE;
9241 }
9242
9243 if (invalid_arg)
9244 {
9245 semsg(_(e_invexpr2), arg);
9246 nr = 0;
9247 }
9248 }
9249
9250 if (nr > 0)
9251 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
9252 wp != twin; wp = wp->w_next)
9253 {
9254 if (wp == NULL)
9255 {
9256 /* didn't find it in this tabpage */
9257 nr = 0;
9258 break;
9259 }
9260 ++nr;
9261 }
9262 return nr;
9263 }
9264
9265 /*
9266 * "tabpagewinnr()" function
9267 */
9268 static void
9269 f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv)
9270 {
9271 int nr = 1;
9272 tabpage_T *tp;
9273
9274 tp = find_tabpage((int)tv_get_number(&argvars[0]));
9275 if (tp == NULL)
9276 nr = 0;
9277 else
9278 nr = get_winnr(tp, &argvars[1]);
9279 rettv->vval.v_number = nr;
9280 }
9281
9282 /*
9283 * "tagfiles()" function 8081 * "tagfiles()" function
9284 */ 8082 */
9285 static void 8083 static void
9286 f_tagfiles(typval_T *argvars UNUSED, typval_T *rettv) 8084 f_tagfiles(typval_T *argvars UNUSED, typval_T *rettv)
9287 { 8085 {
9658 rettv->vval.v_number = 1; 8456 rettv->vval.v_number = 1;
9659 #endif 8457 #endif
9660 } 8458 }
9661 8459
9662 /* 8460 /*
9663 * "winbufnr(nr)" function
9664 */
9665 static void
9666 f_winbufnr(typval_T *argvars, typval_T *rettv)
9667 {
9668 win_T *wp;
9669
9670 wp = find_win_by_nr_or_id(&argvars[0]);
9671 if (wp == NULL)
9672 rettv->vval.v_number = -1;
9673 else
9674 rettv->vval.v_number = wp->w_buffer->b_fnum;
9675 }
9676
9677 /*
9678 * "wincol()" function
9679 */
9680 static void
9681 f_wincol(typval_T *argvars UNUSED, typval_T *rettv)
9682 {
9683 validate_cursor();
9684 rettv->vval.v_number = curwin->w_wcol + 1;
9685 }
9686
9687 /*
9688 * "winheight(nr)" function
9689 */
9690 static void
9691 f_winheight(typval_T *argvars, typval_T *rettv)
9692 {
9693 win_T *wp;
9694
9695 wp = find_win_by_nr_or_id(&argvars[0]);
9696 if (wp == NULL)
9697 rettv->vval.v_number = -1;
9698 else
9699 rettv->vval.v_number = wp->w_height;
9700 }
9701
9702 /*
9703 * "winlayout()" function
9704 */
9705 static void
9706 f_winlayout(typval_T *argvars, typval_T *rettv)
9707 {
9708 tabpage_T *tp;
9709
9710 if (rettv_list_alloc(rettv) != OK)
9711 return;
9712
9713 if (argvars[0].v_type == VAR_UNKNOWN)
9714 tp = curtab;
9715 else
9716 {
9717 tp = find_tabpage((int)tv_get_number(&argvars[0]));
9718 if (tp == NULL)
9719 return;
9720 }
9721
9722 get_framelayout(tp->tp_topframe, rettv->vval.v_list, TRUE);
9723 }
9724
9725 /*
9726 * "winline()" function
9727 */
9728 static void
9729 f_winline(typval_T *argvars UNUSED, typval_T *rettv)
9730 {
9731 validate_cursor();
9732 rettv->vval.v_number = curwin->w_wrow + 1;
9733 }
9734
9735 /*
9736 * "winnr()" function
9737 */
9738 static void
9739 f_winnr(typval_T *argvars UNUSED, typval_T *rettv)
9740 {
9741 int nr = 1;
9742
9743 nr = get_winnr(curtab, &argvars[0]);
9744 rettv->vval.v_number = nr;
9745 }
9746
9747 /*
9748 * "winrestcmd()" function
9749 */
9750 static void
9751 f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv)
9752 {
9753 win_T *wp;
9754 int winnr = 1;
9755 garray_T ga;
9756 char_u buf[50];
9757
9758 ga_init2(&ga, (int)sizeof(char), 70);
9759 FOR_ALL_WINDOWS(wp)
9760 {
9761 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height);
9762 ga_concat(&ga, buf);
9763 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width);
9764 ga_concat(&ga, buf);
9765 ++winnr;
9766 }
9767 ga_append(&ga, NUL);
9768
9769 rettv->vval.v_string = ga.ga_data;
9770 rettv->v_type = VAR_STRING;
9771 }
9772
9773 /*
9774 * "winrestview()" function
9775 */
9776 static void
9777 f_winrestview(typval_T *argvars, typval_T *rettv UNUSED)
9778 {
9779 dict_T *dict;
9780
9781 if (argvars[0].v_type != VAR_DICT
9782 || (dict = argvars[0].vval.v_dict) == NULL)
9783 emsg(_(e_invarg));
9784 else
9785 {
9786 if (dict_find(dict, (char_u *)"lnum", -1) != NULL)
9787 curwin->w_cursor.lnum = (linenr_T)dict_get_number(dict, (char_u *)"lnum");
9788 if (dict_find(dict, (char_u *)"col", -1) != NULL)
9789 curwin->w_cursor.col = (colnr_T)dict_get_number(dict, (char_u *)"col");
9790 if (dict_find(dict, (char_u *)"coladd", -1) != NULL)
9791 curwin->w_cursor.coladd = (colnr_T)dict_get_number(dict, (char_u *)"coladd");
9792 if (dict_find(dict, (char_u *)"curswant", -1) != NULL)
9793 {
9794 curwin->w_curswant = (colnr_T)dict_get_number(dict, (char_u *)"curswant");
9795 curwin->w_set_curswant = FALSE;
9796 }
9797
9798 if (dict_find(dict, (char_u *)"topline", -1) != NULL)
9799 set_topline(curwin, (linenr_T)dict_get_number(dict, (char_u *)"topline"));
9800 #ifdef FEAT_DIFF
9801 if (dict_find(dict, (char_u *)"topfill", -1) != NULL)
9802 curwin->w_topfill = (int)dict_get_number(dict, (char_u *)"topfill");
9803 #endif
9804 if (dict_find(dict, (char_u *)"leftcol", -1) != NULL)
9805 curwin->w_leftcol = (colnr_T)dict_get_number(dict, (char_u *)"leftcol");
9806 if (dict_find(dict, (char_u *)"skipcol", -1) != NULL)
9807 curwin->w_skipcol = (colnr_T)dict_get_number(dict, (char_u *)"skipcol");
9808
9809 check_cursor();
9810 win_new_height(curwin, curwin->w_height);
9811 win_new_width(curwin, curwin->w_width);
9812 changed_window_setting();
9813
9814 if (curwin->w_topline <= 0)
9815 curwin->w_topline = 1;
9816 if (curwin->w_topline > curbuf->b_ml.ml_line_count)
9817 curwin->w_topline = curbuf->b_ml.ml_line_count;
9818 #ifdef FEAT_DIFF
9819 check_topfill(curwin, TRUE);
9820 #endif
9821 }
9822 }
9823
9824 /*
9825 * "winsaveview()" function
9826 */
9827 static void
9828 f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv)
9829 {
9830 dict_T *dict;
9831
9832 if (rettv_dict_alloc(rettv) == FAIL)
9833 return;
9834 dict = rettv->vval.v_dict;
9835
9836 dict_add_number(dict, "lnum", (long)curwin->w_cursor.lnum);
9837 dict_add_number(dict, "col", (long)curwin->w_cursor.col);
9838 dict_add_number(dict, "coladd", (long)curwin->w_cursor.coladd);
9839 update_curswant();
9840 dict_add_number(dict, "curswant", (long)curwin->w_curswant);
9841
9842 dict_add_number(dict, "topline", (long)curwin->w_topline);
9843 #ifdef FEAT_DIFF
9844 dict_add_number(dict, "topfill", (long)curwin->w_topfill);
9845 #endif
9846 dict_add_number(dict, "leftcol", (long)curwin->w_leftcol);
9847 dict_add_number(dict, "skipcol", (long)curwin->w_skipcol);
9848 }
9849
9850 /*
9851 * "winwidth(nr)" function
9852 */
9853 static void
9854 f_winwidth(typval_T *argvars, typval_T *rettv)
9855 {
9856 win_T *wp;
9857
9858 wp = find_win_by_nr_or_id(&argvars[0]);
9859 if (wp == NULL)
9860 rettv->vval.v_number = -1;
9861 else
9862 rettv->vval.v_number = wp->w_width;
9863 }
9864
9865 /*
9866 * "wordcount()" function 8461 * "wordcount()" function
9867 */ 8462 */
9868 static void 8463 static void
9869 f_wordcount(typval_T *argvars UNUSED, typval_T *rettv) 8464 f_wordcount(typval_T *argvars UNUSED, typval_T *rettv)
9870 { 8465 {