My goal is to fix two issues with code completion in KDevelop:
First, it seems to be mostly insensitive to upper/lowercasing, which is an issue with a case-sensitive language such as C++. I'd like to have all (case-insensitive) matches in the completion list, but always sort those to the top and have them selected by default which match the case of the typed text.
Second, I'd like to have the completion widget hidden when there is a case-sensitive exact match, such that the completion widget does not obstruct the view in this case. Currently it never seems to get hidden automatically.
This diff is an attempt to implement a first step towards these goals by improving some things in KTextEditor. I'd make more changes to ensure that the auto-selected completion item tries to match the case of the typed text, and to make this usable in KDevelop, but would like to put this up here for discussion first before making further changes. Would you be fine with the proposed changes in general? Would you choose a different approach? The changes in this initial diff are described below.
- The diff introduces a new setting m_exactMatchCaseSensitivity next to m_matchCaseSensitivity. By setting m_matchCaseSensitivity == Qt::CaseInsensitive and m_exactMatchCaseSensitivity == Qt::CaseSensitive, it is possible to have all case-insensitive matches in the completion list, while only allowing case-sensitive matches to be exact matches (that will hide the completion widget).
- In KateCompletionModel::Item::operator <, the (case-sensitive) comparison with the current typed text is moved up to just below the matchCompletion comparison. This means that items with correctly matching case will match better than items with incorrect case (if they both start with the typed text), regardless of inheritance depth and alphabetical ordering.
- This comparison is also modified to only return true or false if only one of the items matches the typed text. The original code would yield inconsistent results if both items match the typed text, since the comparison would return true for both the test (a < b) and the test (b < a).
- When determining whether a completion item matches the typed text, the diff makes matchesAbbreviation() take model->matchCaseSensitivity() into account (as the other match tests already do). This fixes the issue that without this change, "test" and "TEST" would be considered to match exactly with model->matchCaseSensitivity() == Qt::CaseSensitive, since the abbreviation matching would treat it as a match.
Regarding point 2, this change will only sort those completion items by case-compatibility that start with the typed text, but not the others. An alternative would be to determine case-compatibility of the item with the typed text when matching (in KateCompletionModel::Item::match()). Then completion items with the same MatchType could be sorted by case-compatibility (either in binary form, "matches case" vs. "does not match case", or by counting the number of letters with differing case).