diff --git a/changelog.md b/changelog.md index f685262f..7f8f151b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,11 @@ TBD ============== +Features +-------- +* Place special commands first in the list of completion candidates, and remove duplicates. + + Bug Fixes -------- * Fix CamelCase fuzzy matching. diff --git a/mycli/sqlcompleter.py b/mycli/sqlcompleter.py index eee9b08c..e27fcfa6 100644 --- a/mycli/sqlcompleter.py +++ b/mycli/sqlcompleter.py @@ -14,6 +14,7 @@ from mycli.packages.parseutils import last_word from mycli.packages.special import llm from mycli.packages.special.favoritequeries import FavoriteQueries +from mycli.packages.special.main import COMMANDS as SPECIAL_COMMANDS _logger = logging.getLogger(__name__) @@ -32,14 +33,18 @@ class SQLCompleter(Completer): 'LIKE', 'LIMIT', ] - keywords = [ + keywords_raw = [ x.upper() for x in favorite_keywords + list(MYSQL_DATATYPES) + list(MYSQL_KEYWORDS) + ['ALTER TABLE', 'CHANGE MASTER TO', 'CHARACTER SET', 'FOREIGN KEY'] ] - keywords = list(dict.fromkeys(keywords)) + keywords_d = dict.fromkeys(keywords_raw) + for x in SPECIAL_COMMANDS: + if x.upper() in keywords_d: + del keywords_d[x.upper()] + keywords = list(keywords_d) tidb_keywords = [ "SELECT", @@ -1104,7 +1109,8 @@ def get_completions( elif suggestion["type"] == "special": special_m = self.find_matches(word_before_cursor, self.special_commands, start_only=True, fuzzy=False) - completions.extend(special_m) + # specials are special, and go early in the candidates, first if possible + completions = list(special_m) + completions elif suggestion["type"] == "favoritequery": if hasattr(FavoriteQueries, 'instance') and hasattr(FavoriteQueries.instance, 'list'): diff --git a/test/test_smart_completion_public_schema_only.py b/test/test_smart_completion_public_schema_only.py index c688b398..f841db49 100644 --- a/test/test_smart_completion_public_schema_only.py +++ b/test/test_smart_completion_public_schema_only.py @@ -61,7 +61,7 @@ def test_empty_string_completion(completer, complete_event): text = "" position = 0 result = list(completer.get_completions(Document(text=text, cursor_position=position), complete_event)) - assert list(map(Completion, completer.keywords + completer.special_commands)) == result + assert list(map(Completion, completer.special_commands + completer.keywords)) == result def test_select_keyword_completion(completer, complete_event): @@ -474,6 +474,20 @@ def test_grant_on_suggets_tables_and_schemata(completer, complete_event): ] +# todo: this test belongs more logically in test_naive_completion.py, but it didn't work there: +# multiple completion candidates were not suggested. +def test_deleted_keyword_completion(completer, complete_event): + text = "exi" + position = len("exi") + result = list(completer.get_completions(Document(text=text, cursor_position=position), complete_event)) + assert result == [ + Completion(text="exit", start_position=-3), + Completion(text='exists', start_position=-3), + Completion(text='expire', start_position=-3), + Completion(text='explain', start_position=-3), + ] + + def dummy_list_path(dir_name): dirs = { "/": [