diff --git a/changelog.md b/changelog.md index aad43e30..2fe0ee33 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,11 @@ +Upcoming (TBD) +============== + +Features +-------- +* Show a trailing dot on database names in completion menus. + + 2.18.5 (2026/08/31) ============== diff --git a/mycli/sqlcompleter.py b/mycli/sqlcompleter.py index 81e3797b..3ef04533 100644 --- a/mycli/sqlcompleter.py +++ b/mycli/sqlcompleter.py @@ -1477,6 +1477,7 @@ def get_completions( completions: list[tuple[str, int, int]] = [] indexed_column_candidates: set[str] = set() + schema_candidates: set[str] = set() special_command_candidates: set[str] = set() suggestions = suggest_type(document.text, document.text_before_cursor) rigid_sort = False @@ -1648,11 +1649,14 @@ def get_completions( completions.extend([(*x, rank) for x in aliases_m]) elif suggestion["type"] == "database": - dbs_m = self.find_matches( - word_before_cursor, - self.databases, - text_before_cursor=document.text_before_cursor, + dbs_m = list( + self.find_matches( + word_before_cursor, + self.databases, + text_before_cursor=document.text_before_cursor, + ) ) + schema_candidates.update(candidate for candidate, _fuzziness in dbs_m) completions.extend([(*x, rank) for x in dbs_m]) elif suggestion["type"] == "keyword": @@ -1854,6 +1858,13 @@ def completion_sort_key(item: tuple[str, int, int], text_for_len: str): sorted_completions = sorted(completions, key=lambda item: completion_sort_key(item, completion_filter_text)) uniq_completions_str = dict.fromkeys(x[0] for x in sorted_completions) + def completion_display(candidate: str) -> str | None: + if candidate in indexed_column_candidates: + return f'{candidate}{self.indexed_column_suffix}' + if candidate in schema_candidates: + return f'{candidate}.' + return None + if config_property_length is not None: return (Completion(x, -config_property_length) for x in uniq_completions_str) elif source_file_completion_length is not None: @@ -1863,7 +1874,7 @@ def completion_sort_key(item: tuple[str, int, int], text_for_len: str): Completion( x, -len(last_for_len_paths), - display=f'{x}{self.indexed_column_suffix}' if x in indexed_column_candidates else None, + display=completion_display(x), display_meta=self.special_command_snippets.get(x) if x in special_command_candidates else None, style=_INDEXED_COLUMN_STYLE if x in indexed_column_candidates else '', ) @@ -1874,7 +1885,7 @@ def completion_sort_key(item: tuple[str, int, int], text_for_len: str): Completion( x, -len(text_for_len), - display=f'{x}{self.indexed_column_suffix}' if x in indexed_column_candidates else None, + display=completion_display(x), display_meta=self.special_command_snippets.get(x) if x in special_command_candidates else None, style=_INDEXED_COLUMN_STYLE if x in indexed_column_candidates else '', ) diff --git a/test/pytests/test_smart_completion_public_schema_only.py b/test/pytests/test_smart_completion_public_schema_only.py index 5630a243..7928a537 100644 --- a/test/pytests/test_smart_completion_public_schema_only.py +++ b/test/pytests/test_smart_completion_public_schema_only.py @@ -95,8 +95,8 @@ def test_use_database_completion(completer, complete_event): ) result = completer.get_completions(Document(text=text, cursor_position=position), complete_event) assert list(result) == [ - Completion(text="test", start_position=0), - Completion(text="`test 2`", start_position=0), + Completion(text="test", start_position=0, display="test."), + Completion(text="`test 2`", start_position=0, display="`test 2`."), ] @@ -302,8 +302,8 @@ def test_table_completion(completer, complete_event): Completion(text="time_zone_name", start_position=0), Completion(text="time_zone_transition", start_position=0), Completion(text="time_zone_transition_type", start_position=0), - Completion(text="test", start_position=0), - Completion(text="`test 2`", start_position=0), + Completion(text="test", start_position=0, display="test."), + Completion(text="`test 2`", start_position=0, display="`test 2`."), ] @@ -321,8 +321,8 @@ def test_select_filtered_table_completion(completer, complete_event): Completion(text="time_zone_name", start_position=0), Completion(text="time_zone_transition", start_position=0), Completion(text="time_zone_transition_type", start_position=0), - Completion(text="test", start_position=0), - Completion(text="`test 2`", start_position=0), + Completion(text="test", start_position=0, display="test."), + Completion(text="`test 2`", start_position=0, display="`test 2`."), ] @@ -340,8 +340,8 @@ def test_sub_select_filtered_table_completion(completer, complete_event): Completion(text="time_zone_name", start_position=0), Completion(text="time_zone_transition", start_position=0), Completion(text="time_zone_transition_type", start_position=0), - Completion(text="test", start_position=0), - Completion(text="`test 2`", start_position=0), + Completion(text="test", start_position=0, display="test."), + Completion(text="`test 2`", start_position=0, display="`test 2`."), ] @@ -595,8 +595,8 @@ def test_table_names_after_from(completer, complete_event): Completion(text="time_zone_name", start_position=0), Completion(text="time_zone_transition", start_position=0), Completion(text="time_zone_transition_type", start_position=0), - Completion(text="test", start_position=0), - Completion(text="`test 2`", start_position=0), + Completion(text="test", start_position=0, display="test."), + Completion(text="`test 2`", start_position=0, display="`test 2`."), ] @@ -669,8 +669,8 @@ def test_grant_on_suggets_tables_and_schemata(completer, complete_event): position = len(text) result = list(completer.get_completions(Document(text=text, cursor_position=position), complete_event)) assert result == [ - Completion(text="test", start_position=0), - Completion(text="`test 2`", start_position=0), + Completion(text="test", start_position=0, display="test."), + Completion(text="`test 2`", start_position=0, display="`test 2`."), Completion(text='users', start_position=0), Completion(text='orders', start_position=0), Completion(text='`select`', start_position=0), @@ -1265,8 +1265,8 @@ def test_backticked_table_completion_not_required(completer, complete_event): position = len(text) result = list(completer.get_completions(Document(text=text, cursor_position=position), complete_event)) assert result == [ - Completion(text='`test`', start_position=-2), - Completion(text='`test 2`', start_position=-2), + Completion(text='`test`', start_position=-2, display='`test`.'), + Completion(text='`test 2`', start_position=-2, display='`test 2`.'), Completion(text='`time_zone`', start_position=-2), Completion(text='`time_zone_name`', start_position=-2), Completion(text='`time_zone_transition`', start_position=-2),