mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-10-31 04:32:33 +00:00 
			
		
		
		
	Fix regressions in completion filtering. Also improve performance slightly.
If there was no filter then we would return all results - this caused huge delays for #include completion.
This commit is contained in:
		
							parent
							
								
									fae959e0ee
								
							
						
					
					
						commit
						566b508b8e
					
				| @ -103,6 +103,9 @@ void FilterAndSortCompletionResponse( | |||||||
|     Out_TextDocumentComplete* complete_response, |     Out_TextDocumentComplete* complete_response, | ||||||
|     const std::string& complete_text, |     const std::string& complete_text, | ||||||
|     bool enable) { |     bool enable) { | ||||||
|  |   if (!enable) | ||||||
|  |     return; | ||||||
|  | 
 | ||||||
|   ScopedPerfTimer timer("FilterAndSortCompletionResponse"); |   ScopedPerfTimer timer("FilterAndSortCompletionResponse"); | ||||||
| 
 | 
 | ||||||
| // Used to inject more completions.
 | // Used to inject more completions.
 | ||||||
| @ -119,23 +122,38 @@ void FilterAndSortCompletionResponse( | |||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|   auto& items = complete_response->result.items; |   auto& items = complete_response->result.items; | ||||||
| 
 | 
 | ||||||
|   if (!enable || complete_text.empty()) { |   auto finalize = [&]() { | ||||||
|     // Just set the |sortText| to be the priority and return.
 |     const size_t kMaxResultSize = 100u; | ||||||
|  |     if (items.size() > kMaxResultSize) { | ||||||
|  |       items.resize(kMaxResultSize); | ||||||
|  |       complete_response->result.isIncomplete = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Set sortText. Note that this happens after resizing - we could do it
 | ||||||
|  |     // before, but then we should also sort by priority.
 | ||||||
|     char buf[16]; |     char buf[16]; | ||||||
|     for (auto& item : items) |     for (size_t i = 0; i < items.size(); ++i) | ||||||
|       item.sortText = tofixedbase64(item.priority_, buf); |       items[i].sortText = tofixedbase64(i, buf); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   // No complete text; don't run any filtering logic except to trim the items.
 | ||||||
|  |   if (complete_text.empty()) { | ||||||
|  |     finalize(); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Make sure all items have |filterText| set, code that follow needs it.
 |   // Make sure all items have |filterText| set, code that follow needs it.
 | ||||||
|   for (auto& item : items) |   for (auto& item : items) { | ||||||
|     if (!item.filterText) |     if (!item.filterText) | ||||||
|       item.filterText = item.label; |       item.filterText = item.label; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   // If the text doesn't start with underscore,
 |   // If the text doesn't start with underscore, remove all candidates that
 | ||||||
|   // remove all candidates that start with underscore.
 |   // start with underscore.
 | ||||||
|   if (complete_text[0] != '_') { |   if (complete_text[0] != '_') { | ||||||
|     auto filter = [](const lsCompletionItem& item) { |     auto filter = [](const lsCompletionItem& item) { | ||||||
|       return (*item.filterText)[0] == '_'; |       return (*item.filterText)[0] == '_'; | ||||||
| @ -144,26 +162,23 @@ void FilterAndSortCompletionResponse( | |||||||
|                 items.end()); |                 items.end()); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Fuzzy match.
 |   // Fuzzy match. Remove any candidates that do not match.
 | ||||||
|   bool found = false; |   bool found = false; | ||||||
|   for (auto& item : items) { |   for (auto& item : items) { | ||||||
|     std::tie(item.found_, item.skip_) = |     std::tie(item.found_, item.skip_) = | ||||||
|         SubsequenceCountSkip(complete_text, *item.filterText); |         SubsequenceCountSkip(complete_text, *item.filterText); | ||||||
|     found = found || item.found_; |     found = found || item.found_; | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   if (found) { |   if (found) { | ||||||
|     auto filter = [](const lsCompletionItem& item) { return !item.found_; }; |     auto filter = [](const lsCompletionItem& item) { return !item.found_; }; | ||||||
|     items.erase(std::remove_if(items.begin(), items.end(), filter), |     items.erase(std::remove_if(items.begin(), items.end(), filter), | ||||||
|                 items.end()); |                 items.end()); | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|     // Order all items and set |sortText|.
 |     // Order all items and set |sortText|.
 | ||||||
|     const size_t kMaxSortSize = 200u; |     const size_t kMaxSortSize = 200u; | ||||||
|   if (found) { |     if (items.size() <= kMaxSortSize) { | ||||||
|     if (items.size() <= kMaxSortSize) |  | ||||||
|       std::sort(items.begin(), items.end(), CompareLsCompletionItem); |       std::sort(items.begin(), items.end(), CompareLsCompletionItem); | ||||||
|     else { |     } else { | ||||||
|       // Just place items that found the text before those not.
 |       // Just place items that found the text before those not.
 | ||||||
|       std::vector<lsCompletionItem> items_found, items_notfound; |       std::vector<lsCompletionItem> items_found, items_notfound; | ||||||
|       for (auto& item : items) |       for (auto& item : items) | ||||||
| @ -173,15 +188,8 @@ void FilterAndSortCompletionResponse( | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   char buf[16]; |   // Trim result.
 | ||||||
|   for (size_t i = 0; i < items.size(); ++i) |   finalize(); | ||||||
|     items[i].sortText = tofixedbase64(i, buf); |  | ||||||
| 
 |  | ||||||
|   const size_t kMaxResultSize = 100u; |  | ||||||
|   if (items.size() > kMaxResultSize) { |  | ||||||
|     items.resize(kMaxResultSize); |  | ||||||
|     complete_response->result.isIncomplete = true; |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct TextDocumentCompletionHandler : MessageHandler { | struct TextDocumentCompletionHandler : MessageHandler { | ||||||
| @ -239,7 +247,8 @@ struct TextDocumentCompletionHandler : MessageHandler { | |||||||
|       } |       } | ||||||
|       // If the character is > but - does not preced it, or if it is : and :
 |       // If the character is > but - does not preced it, or if it is : and :
 | ||||||
|       // does not preced it, do not show completion results.
 |       // does not preced it, do not show completion results.
 | ||||||
|       else if (preceding_index < (int)buffer_line.size()) { |       else if (preceding_index >= 0 && | ||||||
|  |                preceding_index < (int)buffer_line.size()) { | ||||||
|         char preceding = buffer_line[preceding_index]; |         char preceding = buffer_line[preceding_index]; | ||||||
|         did_fail_check = (preceding != '-' && character == ">") || |         did_fail_check = (preceding != '-' && character == ">") || | ||||||
|                          (preceding != ':' && character == ":"); |                          (preceding != ':' && character == ":"); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user