Mercurial > vim
comparison src/eval.c @ 16704:a927fdf9a4b0 v8.1.1354
patch 8.1.1354: getting a list of text lines is clumsy
commit https://github.com/vim/vim/commit/f5842c5a533346c4ff41ff666e465c85f1de35d5
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun May 19 18:41:26 2019 +0200
patch 8.1.1354: getting a list of text lines is clumsy
Problem: Getting a list of text lines is clumsy.
Solution: Add the =<< assignment. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/4386)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 19 May 2019 18:45:05 +0200 |
parents | a1ba0bd74e7d |
children | 77bcb5055fec |
comparison
equal
deleted
inserted
replaced
16703:d4eb78b4b086 | 16704:a927fdf9a4b0 |
---|---|
1223 return (int)retval; | 1223 return (int)retval; |
1224 } | 1224 } |
1225 #endif | 1225 #endif |
1226 | 1226 |
1227 /* | 1227 /* |
1228 * Get a list of lines from a HERE document. The here document is a list of | |
1229 * lines surrounded by a marker. | |
1230 * cmd << {marker} | |
1231 * {line1} | |
1232 * {line2} | |
1233 * .... | |
1234 * {marker} | |
1235 * | |
1236 * The {marker} is a string. If the optional 'trim' word is supplied before the | |
1237 * marker, then the leading indentation before the lines (matching the | |
1238 * indentation in the 'cmd' line) is stripped. | |
1239 * Returns a List with {lines} or NULL. | |
1240 */ | |
1241 static list_T * | |
1242 heredoc_get(exarg_T *eap, char_u *cmd) | |
1243 { | |
1244 char_u *theline; | |
1245 char_u *marker; | |
1246 list_T *l; | |
1247 char_u *p; | |
1248 int indent_len = 0; | |
1249 | |
1250 if (eap->getline == NULL) | |
1251 { | |
1252 emsg(_("E991: cannot use =<< here")); | |
1253 return NULL; | |
1254 } | |
1255 | |
1256 // Check for the optional 'trim' word before the marker | |
1257 cmd = skipwhite(cmd); | |
1258 if (STRNCMP(cmd, "trim", 4) == 0 && (cmd[4] == NUL || VIM_ISWHITE(cmd[4]))) | |
1259 { | |
1260 cmd = skipwhite(cmd + 4); | |
1261 | |
1262 // Trim the indentation from all the lines in the here document | |
1263 // The amount of indentation trimmed is the same as the indentation of | |
1264 // the :let command line. | |
1265 p = *eap->cmdlinep; | |
1266 while (VIM_ISWHITE(*p)) | |
1267 { | |
1268 p++; | |
1269 indent_len++; | |
1270 } | |
1271 } | |
1272 | |
1273 // The marker is the next word. Default marker is "." | |
1274 if (*cmd != NUL && *cmd != '"') | |
1275 { | |
1276 marker = skipwhite(cmd); | |
1277 p = skiptowhite(marker); | |
1278 if (*skipwhite(p) != NUL && *skipwhite(p) != '"') | |
1279 { | |
1280 emsg(_(e_trailing)); | |
1281 return NULL; | |
1282 } | |
1283 *p = NUL; | |
1284 } | |
1285 else | |
1286 marker = (char_u *)"."; | |
1287 | |
1288 l = list_alloc(); | |
1289 if (l == NULL) | |
1290 return NULL; | |
1291 | |
1292 for (;;) | |
1293 { | |
1294 int i = 0; | |
1295 | |
1296 theline = eap->getline(NUL, eap->cookie, 0); | |
1297 if (theline != NULL && indent_len > 0) | |
1298 { | |
1299 // trim the indent matching the first line | |
1300 if (STRNCMP(theline, *eap->cmdlinep, indent_len) == 0) | |
1301 i = indent_len; | |
1302 } | |
1303 | |
1304 if (theline == NULL) | |
1305 { | |
1306 semsg(_("E990: Missing end marker '%s'"), marker); | |
1307 break; | |
1308 } | |
1309 if (STRCMP(marker, theline + i) == 0) | |
1310 { | |
1311 vim_free(theline); | |
1312 break; | |
1313 } | |
1314 | |
1315 if (list_append_string(l, theline + i, -1) == FAIL) | |
1316 break; | |
1317 vim_free(theline); | |
1318 } | |
1319 | |
1320 return l; | |
1321 } | |
1322 | |
1323 /* | |
1228 * ":let" list all variable values | 1324 * ":let" list all variable values |
1229 * ":let var1 var2" list variable values | 1325 * ":let var1 var2" list variable values |
1230 * ":let var = expr" assignment command. | 1326 * ":let var = expr" assignment command. |
1231 * ":let var += expr" assignment command. | 1327 * ":let var += expr" assignment command. |
1232 * ":let var -= expr" assignment command. | 1328 * ":let var -= expr" assignment command. |
1283 list_script_vars(&first); | 1379 list_script_vars(&first); |
1284 list_func_vars(&first); | 1380 list_func_vars(&first); |
1285 list_vim_vars(&first); | 1381 list_vim_vars(&first); |
1286 } | 1382 } |
1287 eap->nextcmd = check_nextcmd(arg); | 1383 eap->nextcmd = check_nextcmd(arg); |
1384 } | |
1385 else if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<') | |
1386 { | |
1387 list_T *l; | |
1388 | |
1389 // HERE document | |
1390 l = heredoc_get(eap, expr + 3); | |
1391 if (l != NULL) | |
1392 { | |
1393 rettv_list_set(&rettv, l); | |
1394 op[0] = '='; | |
1395 op[1] = NUL; | |
1396 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, | |
1397 op); | |
1398 clear_tv(&rettv); | |
1399 } | |
1288 } | 1400 } |
1289 else | 1401 else |
1290 { | 1402 { |
1291 op[0] = '='; | 1403 op[0] = '='; |
1292 op[1] = NUL; | 1404 op[1] = NUL; |