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;