comparison src/map.c @ 27916:6efa2f193c94 v8.2.4483

patch 8.2.4483: command completion makes two rounds to collect matches Commit: https://github.com/vim/vim/commit/5de4c4372d4366bc85cb66efb3e373439b9471c5 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Mon Feb 28 13:28:38 2022 +0000 patch 8.2.4483: command completion makes two rounds to collect matches Problem: Command completion makes two rounds to collect matches. Solution: Use a growarray to collect matches. (Yegappan Lakshmanan, closes #9860)
author Bram Moolenaar <Bram@vim.org>
date Mon, 28 Feb 2022 14:30:04 +0100
parents 099c2e612827
children 86bf2dabc93a
comparison
equal deleted inserted replaced
27915:4058d89b7a48 27916:6efa2f193c94
1261 regmatch_T *regmatch, 1261 regmatch_T *regmatch,
1262 int *numMatches, 1262 int *numMatches,
1263 char_u ***matches) 1263 char_u ***matches)
1264 { 1264 {
1265 mapblock_T *mp; 1265 mapblock_T *mp;
1266 garray_T ga;
1266 int hash; 1267 int hash;
1267 int count; 1268 int count;
1268 int round;
1269 char_u *p; 1269 char_u *p;
1270 int i; 1270 int i;
1271 int fuzzy; 1271 int fuzzy;
1272 int match; 1272 int match;
1273 int score; 1273 int score;
1274 fuzmatch_str_T *fuzmatch = NULL; 1274 fuzmatch_str_T *fuzmatch;
1275 1275
1276 fuzzy = cmdline_fuzzy_complete(pat); 1276 fuzzy = cmdline_fuzzy_complete(pat);
1277 1277
1278 validate_maphash(); 1278 validate_maphash();
1279 1279
1280 *numMatches = 0; // return values in case of FAIL 1280 *numMatches = 0; // return values in case of FAIL
1281 *matches = NULL; 1281 *matches = NULL;
1282 1282
1283 // round == 1: Count the matches. 1283 if (!fuzzy)
1284 // round == 2: Build the array to keep the matches. 1284 ga_init2(&ga, sizeof(char *), 3);
1285 for (round = 1; round <= 2; ++round) 1285 else
1286 { 1286 ga_init2(&ga, sizeof(fuzmatch_str_T), 3);
1287 count = 0; 1287
1288 1288 // First search in map modifier arguments
1289 // First search in map modifier arguments 1289 for (i = 0; i < 7; ++i)
1290 for (i = 0; i < 7; ++i) 1290 {
1291 { 1291 if (i == 0)
1292 if (i == 0) 1292 p = (char_u *)"<silent>";
1293 p = (char_u *)"<silent>"; 1293 else if (i == 1)
1294 else if (i == 1) 1294 p = (char_u *)"<unique>";
1295 p = (char_u *)"<unique>";
1296 #ifdef FEAT_EVAL 1295 #ifdef FEAT_EVAL
1297 else if (i == 2) 1296 else if (i == 2)
1298 p = (char_u *)"<script>"; 1297 p = (char_u *)"<script>";
1299 else if (i == 3) 1298 else if (i == 3)
1300 p = (char_u *)"<expr>"; 1299 p = (char_u *)"<expr>";
1301 #endif 1300 #endif
1302 else if (i == 4 && !expand_buffer) 1301 else if (i == 4 && !expand_buffer)
1303 p = (char_u *)"<buffer>"; 1302 p = (char_u *)"<buffer>";
1304 else if (i == 5) 1303 else if (i == 5)
1305 p = (char_u *)"<nowait>"; 1304 p = (char_u *)"<nowait>";
1306 else if (i == 6) 1305 else if (i == 6)
1307 p = (char_u *)"<special>"; 1306 p = (char_u *)"<special>";
1308 else 1307 else
1308 continue;
1309
1310 if (!fuzzy)
1311 match = vim_regexec(regmatch, p, (colnr_T)0);
1312 else
1313 {
1314 score = fuzzy_match_str(p, pat);
1315 match = (score != 0);
1316 }
1317
1318 if (!match)
1319 continue;
1320
1321 if (ga_grow(&ga, 1) == FAIL)
1322 break;
1323
1324 if (fuzzy)
1325 {
1326 fuzmatch = &((fuzmatch_str_T *)ga.ga_data)[ga.ga_len];
1327 fuzmatch->idx = ga.ga_len;
1328 fuzmatch->str = vim_strsave(p);
1329 fuzmatch->score = score;
1330 }
1331 else
1332 ((char_u **)ga.ga_data)[ga.ga_len] = vim_strsave(p);
1333 ++ga.ga_len;
1334 }
1335
1336 for (hash = 0; hash < 256; ++hash)
1337 {
1338 if (expand_isabbrev)
1339 {
1340 if (hash > 0) // only one abbrev list
1341 break; // for (hash)
1342 mp = first_abbr;
1343 }
1344 else if (expand_buffer)
1345 mp = curbuf->b_maphash[hash];
1346 else
1347 mp = maphash[hash];
1348 for (; mp; mp = mp->m_next)
1349 {
1350 if (!(mp->m_mode & expand_mapmodes))
1351 continue;
1352
1353 p = translate_mapping(mp->m_keys);
1354 if (p == NULL)
1309 continue; 1355 continue;
1310 1356
1311 if (!fuzzy) 1357 if (!fuzzy)
1312 match = vim_regexec(regmatch, p, (colnr_T)0); 1358 match = vim_regexec(regmatch, p, (colnr_T)0);
1313 else 1359 else
1315 score = fuzzy_match_str(p, pat); 1361 score = fuzzy_match_str(p, pat);
1316 match = (score != 0); 1362 match = (score != 0);
1317 } 1363 }
1318 1364
1319 if (!match) 1365 if (!match)
1366 {
1367 vim_free(p);
1320 continue; 1368 continue;
1321 1369 }
1322 if (round == 2) 1370
1323 { 1371 if (ga_grow(&ga, 1) == FAIL)
1324 if (fuzzy) 1372 {
1325 { 1373 vim_free(p);
1326 fuzmatch[count].idx = count; 1374 break;
1327 fuzmatch[count].str = vim_strsave(p); 1375 }
1328 fuzmatch[count].score = score; 1376
1329 } 1377 if (fuzzy)
1330 else 1378 {
1331 (*matches)[count] = vim_strsave(p); 1379 fuzmatch = &((fuzmatch_str_T *)ga.ga_data)[ga.ga_len];
1332 } 1380 fuzmatch->idx = ga.ga_len;
1333 ++count; 1381 fuzmatch->str = p;
1334 } 1382 fuzmatch->score = score;
1335 1383 }
1336 for (hash = 0; hash < 256; ++hash)
1337 {
1338 if (expand_isabbrev)
1339 {
1340 if (hash > 0) // only one abbrev list
1341 break; // for (hash)
1342 mp = first_abbr;
1343 }
1344 else if (expand_buffer)
1345 mp = curbuf->b_maphash[hash];
1346 else 1384 else
1347 mp = maphash[hash]; 1385 ((char_u **)ga.ga_data)[ga.ga_len] = p;
1348 for (; mp; mp = mp->m_next) 1386
1349 { 1387 ++ga.ga_len;
1350 if (mp->m_mode & expand_mapmodes) 1388 } // for (mp)
1351 { 1389 } // for (hash)
1352 p = translate_mapping(mp->m_keys); 1390
1353 if (p != NULL) 1391 if (ga.ga_len == 0)
1354 { 1392 return FAIL;
1355 if (!fuzzy) 1393
1356 match = vim_regexec(regmatch, p, (colnr_T)0); 1394 if (!fuzzy)
1357 else 1395 {
1358 { 1396 *matches = ga.ga_data;
1359 score = fuzzy_match_str(p, pat); 1397 *numMatches = ga.ga_len;
1360 match = (score != 0); 1398 }
1361 } 1399 else
1362 1400 {
1363 if (match) 1401 if (fuzzymatches_to_strmatches(ga.ga_data, matches, ga.ga_len,
1364 {
1365 if (round == 2)
1366 {
1367 if (fuzzy)
1368 {
1369 fuzmatch[count].idx = count;
1370 fuzmatch[count].str = p;
1371 fuzmatch[count].score = score;
1372 }
1373 else
1374 (*matches)[count] = p;
1375 p = NULL;
1376 }
1377 ++count;
1378 }
1379 }
1380 vim_free(p);
1381 }
1382 } // for (mp)
1383 } // for (hash)
1384
1385 if (count == 0) // no match found
1386 break; // for (round)
1387
1388 if (round == 1)
1389 {
1390 if (fuzzy)
1391 {
1392 fuzmatch = ALLOC_MULT(fuzmatch_str_T, count);
1393 if (fuzmatch == NULL)
1394 return FAIL;
1395 }
1396 else
1397 {
1398 *matches = ALLOC_MULT(char_u *, count);
1399 if (*matches == NULL)
1400 return FAIL;
1401 }
1402 }
1403 } // for (round)
1404
1405 if (fuzzy && fuzzymatches_to_strmatches(fuzmatch, matches, count,
1406 FALSE) == FAIL) 1402 FALSE) == FAIL)
1407 return FAIL; 1403 return FAIL;
1408 1404 *numMatches = ga.ga_len;
1405 }
1406
1407 count = *numMatches;
1409 if (count > 1) 1408 if (count > 1)
1410 { 1409 {
1411 char_u **ptr1; 1410 char_u **ptr1;
1412 char_u **ptr2; 1411 char_u **ptr2;
1413 char_u **ptr3; 1412 char_u **ptr3;