Mercurial > vim
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; |