summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmjith Ramanujam <amjith@netflix.com>2024-11-03 20:02:42 -0800
committerAmjith Ramanujam <amjith@netflix.com>2024-11-03 20:02:42 -0800
commitacb4f097c39dc0d500f2666ea9560f0b3e9066ac (patch)
tree4060661d372c46199faf2aff7678ed8e49563f31
parent5ab845e0ff5d964f0b90ef3491650ca2e0acf64b (diff)
Add a special case for to only show keywords after a *
-rw-r--r--mycli/packages/completion_engine.py2
-rw-r--r--test/myclirc3
-rw-r--r--test/test_smart_completion_public_schema_only.py523
3 files changed, 305 insertions, 223 deletions
diff --git a/mycli/packages/completion_engine.py b/mycli/packages/completion_engine.py
index 2735f5b..6d5709a 100644
--- a/mycli/packages/completion_engine.py
+++ b/mycli/packages/completion_engine.py
@@ -138,6 +138,8 @@ def suggest_based_on_last_token(token, text_before_cursor, full_text, identifier
if not token:
return [{'type': 'keyword'}, {'type': 'special'}]
+ elif token_v == "*":
+ return [{'type': 'keyword'}]
elif token_v.endswith('('):
p = sqlparse.parse(text_before_cursor)[0]
diff --git a/test/myclirc b/test/myclirc
index 0c1a7ad..7d96c45 100644
--- a/test/myclirc
+++ b/test/myclirc
@@ -89,6 +89,9 @@ keyword_casing = auto
# disabled pager on startup
enable_pager = True
+# Choose a specific pager
+pager = less
+
# Custom colors for the completion menu, toolbar, etc.
[colors]
completion-menu.completion.current = "bg:#ffffff #000000"
diff --git a/test/test_smart_completion_public_schema_only.py b/test/test_smart_completion_public_schema_only.py
index b60e67c..bed989f 100644
--- a/test/test_smart_completion_public_schema_only.py
+++ b/test/test_smart_completion_public_schema_only.py
@@ -5,17 +5,17 @@ from prompt_toolkit.document import Document
import mycli.packages.special.main as special
metadata = {
- 'users': ['id', 'email', 'first_name', 'last_name'],
- 'orders': ['id', 'ordered_date', 'status'],
- 'select': ['id', 'insert', 'ABC'],
- 'réveillé': ['id', 'insert', 'ABC']
+ "users": ["id", "email", "first_name", "last_name"],
+ "orders": ["id", "ordered_date", "status"],
+ "select": ["id", "insert", "ABC"],
+ "réveillé": ["id", "insert", "ABC"],
}
@pytest.fixture
def completer():
-
import mycli.sqlcompleter as sqlcompleter
+
comp = sqlcompleter.SQLCompleter(smart_completion=True)
tables, columns = [], []
@@ -24,10 +24,10 @@ def completer():
tables.append((table,))
columns.extend([(table, col) for col in cols])
- comp.set_dbname('test')
- comp.extend_schemata('test')
- comp.extend_relations(tables, kind='tables')
- comp.extend_columns(columns, kind='tables')
+ comp.set_dbname("test")
+ comp.extend_schemata("test")
+ comp.extend_relations(tables, kind="tables")
+ comp.extend_columns(columns, kind="tables")
comp.extend_special_commands(special.COMMANDS)
return comp
@@ -36,59 +36,78 @@ def completer():
@pytest.fixture
def complete_event():
from unittest.mock import Mock
+
return Mock()
def test_special_name_completion(completer, complete_event):
- text = '\\d'
- position = len('\\d')
+ text = "\\d"
+ position = len("\\d")
result = completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event)
- assert result == [Completion(text='\\dt', start_position=-2)]
+ Document(text=text, cursor_position=position), complete_event
+ )
+ assert result == [Completion(text="\\dt", start_position=-2)]
def test_empty_string_completion(completer, complete_event):
- text = ''
+ 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
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert (
+ list(map(Completion, completer.keywords + completer.special_commands)) == result
+ )
def test_select_keyword_completion(completer, complete_event):
- text = 'SEL'
- position = len('SEL')
+ text = "SEL"
+ position = len("SEL")
result = completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event)
- assert list(result) == list([Completion(text='SELECT', start_position=-3)])
+ Document(text=text, cursor_position=position), complete_event
+ )
+ assert list(result) == list([Completion(text="SELECT", start_position=-3)])
+
+
+def test_select_star(completer, complete_event):
+ text = "SELECT * "
+ position = len(text)
+ result = completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ assert list(result) == list(map(Completion, completer.keywords))
def test_table_completion(completer, complete_event):
- text = 'SELECT * FROM '
+ text = "SELECT * FROM "
position = len(text)
result = completer.get_completions(
- Document(text=text, cursor_position=position), complete_event)
- assert list(result) == list([
- Completion(text='users', start_position=0),
- Completion(text='orders', start_position=0),
- Completion(text='`select`', start_position=0),
- Completion(text='`réveillé`', start_position=0),
- ])
+ Document(text=text, cursor_position=position), complete_event
+ )
+ assert list(result) == list(
+ [
+ Completion(text="users", start_position=0),
+ Completion(text="orders", start_position=0),
+ Completion(text="`select`", start_position=0),
+ Completion(text="`réveillé`", start_position=0),
+ ]
+ )
def test_function_name_completion(completer, complete_event):
- text = 'SELECT MA'
- position = len('SELECT MA')
+ text = "SELECT MA"
+ position = len("SELECT MA")
result = completer.get_completions(
- Document(text=text, cursor_position=position), complete_event)
- assert list(result) == list([Completion(text='MAX', start_position=-2),
- Completion(text='MASTER', start_position=-2),
- ])
+ Document(text=text, cursor_position=position), complete_event
+ )
+ assert list(result) == list(
+ [
+ Completion(text="MAX", start_position=-2),
+ Completion(text="MASTER", start_position=-2),
+ ]
+ )
def test_suggested_column_names(completer, complete_event):
@@ -99,21 +118,25 @@ def test_suggested_column_names(completer, complete_event):
:return:
"""
- text = 'SELECT from users'
- position = len('SELECT ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='email', start_position=0),
- Completion(text='first_name', start_position=0),
- Completion(text='last_name', start_position=0),
- ] +
- list(map(Completion, completer.functions)) +
- [Completion(text='users', start_position=0)] +
- list(map(Completion, completer.keywords)))
+ text = "SELECT from users"
+ position = len("SELECT ")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="email", start_position=0),
+ Completion(text="first_name", start_position=0),
+ Completion(text="last_name", start_position=0),
+ ]
+ + list(map(Completion, completer.functions))
+ + [Completion(text="users", start_position=0)]
+ + list(map(Completion, completer.keywords))
+ )
def test_suggested_column_names_in_function(completer, complete_event):
@@ -125,17 +148,20 @@ def test_suggested_column_names_in_function(completer, complete_event):
:return:
"""
- text = 'SELECT MAX( from users'
- position = len('SELECT MAX(')
+ text = "SELECT MAX( from users"
+ position = len("SELECT MAX(")
result = completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event)
- assert list(result) == list([
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='email', start_position=0),
- Completion(text='first_name', start_position=0),
- Completion(text='last_name', start_position=0)])
+ Document(text=text, cursor_position=position), complete_event
+ )
+ assert list(result) == list(
+ [
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="email", start_position=0),
+ Completion(text="first_name", start_position=0),
+ Completion(text="last_name", start_position=0),
+ ]
+ )
def test_suggested_column_names_with_table_dot(completer, complete_event):
@@ -146,17 +172,22 @@ def test_suggested_column_names_with_table_dot(completer, complete_event):
:return:
"""
- text = 'SELECT users. from users'
- position = len('SELECT users.')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='email', start_position=0),
- Completion(text='first_name', start_position=0),
- Completion(text='last_name', start_position=0)])
+ text = "SELECT users. from users"
+ position = len("SELECT users.")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="email", start_position=0),
+ Completion(text="first_name", start_position=0),
+ Completion(text="last_name", start_position=0),
+ ]
+ )
def test_suggested_column_names_with_alias(completer, complete_event):
@@ -167,17 +198,22 @@ def test_suggested_column_names_with_alias(completer, complete_event):
:return:
"""
- text = 'SELECT u. from users u'
- position = len('SELECT u.')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='email', start_position=0),
- Completion(text='first_name', start_position=0),
- Completion(text='last_name', start_position=0)])
+ text = "SELECT u. from users u"
+ position = len("SELECT u.")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="email", start_position=0),
+ Completion(text="first_name", start_position=0),
+ Completion(text="last_name", start_position=0),
+ ]
+ )
def test_suggested_multiple_column_names(completer, complete_event):
@@ -189,20 +225,25 @@ def test_suggested_multiple_column_names(completer, complete_event):
:return:
"""
- text = 'SELECT id, from users u'
- position = len('SELECT id, ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='email', start_position=0),
- Completion(text='first_name', start_position=0),
- Completion(text='last_name', start_position=0)] +
- list(map(Completion, completer.functions)) +
- [Completion(text='u', start_position=0)] +
- list(map(Completion, completer.keywords)))
+ text = "SELECT id, from users u"
+ position = len("SELECT id, ")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="email", start_position=0),
+ Completion(text="first_name", start_position=0),
+ Completion(text="last_name", start_position=0),
+ ]
+ + list(map(Completion, completer.functions))
+ + [Completion(text="u", start_position=0)]
+ + list(map(Completion, completer.keywords))
+ )
def test_suggested_multiple_column_names_with_alias(completer, complete_event):
@@ -214,17 +255,22 @@ def test_suggested_multiple_column_names_with_alias(completer, complete_event):
:return:
"""
- text = 'SELECT u.id, u. from users u'
- position = len('SELECT u.id, u.')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='email', start_position=0),
- Completion(text='first_name', start_position=0),
- Completion(text='last_name', start_position=0)])
+ text = "SELECT u.id, u. from users u"
+ position = len("SELECT u.id, u.")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="email", start_position=0),
+ Completion(text="first_name", start_position=0),
+ Completion(text="last_name", start_position=0),
+ ]
+ )
def test_suggested_multiple_column_names_with_dot(completer, complete_event):
@@ -236,154 +282,185 @@ def test_suggested_multiple_column_names_with_dot(completer, complete_event):
:return:
"""
- text = 'SELECT users.id, users. from users u'
- position = len('SELECT users.id, users.')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='email', start_position=0),
- Completion(text='first_name', start_position=0),
- Completion(text='last_name', start_position=0)])
+ text = "SELECT users.id, users. from users u"
+ position = len("SELECT users.id, users.")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="email", start_position=0),
+ Completion(text="first_name", start_position=0),
+ Completion(text="last_name", start_position=0),
+ ]
+ )
def test_suggested_aliases_after_on(completer, complete_event):
- text = 'SELECT u.name, o.id FROM users u JOIN orders o ON '
- position = len('SELECT u.name, o.id FROM users u JOIN orders o ON ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='u', start_position=0),
- Completion(text='o', start_position=0),
- ])
+ text = "SELECT u.name, o.id FROM users u JOIN orders o ON "
+ position = len("SELECT u.name, o.id FROM users u JOIN orders o ON ")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="u", start_position=0),
+ Completion(text="o", start_position=0),
+ ]
+ )
def test_suggested_aliases_after_on_right_side(completer, complete_event):
- text = 'SELECT u.name, o.id FROM users u JOIN orders o ON o.user_id = '
- position = len(
- 'SELECT u.name, o.id FROM users u JOIN orders o ON o.user_id = ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='u', start_position=0),
- Completion(text='o', start_position=0),
- ])
+ text = "SELECT u.name, o.id FROM users u JOIN orders o ON o.user_id = "
+ position = len("SELECT u.name, o.id FROM users u JOIN orders o ON o.user_id = ")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="u", start_position=0),
+ Completion(text="o", start_position=0),
+ ]
+ )
def test_suggested_tables_after_on(completer, complete_event):
- text = 'SELECT users.name, orders.id FROM users JOIN orders ON '
- position = len('SELECT users.name, orders.id FROM users JOIN orders ON ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='users', start_position=0),
- Completion(text='orders', start_position=0),
- ])
+ text = "SELECT users.name, orders.id FROM users JOIN orders ON "
+ position = len("SELECT users.name, orders.id FROM users JOIN orders ON ")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="users", start_position=0),
+ Completion(text="orders", start_position=0),
+ ]
+ )
def test_suggested_tables_after_on_right_side(completer, complete_event):
- text = 'SELECT users.name, orders.id FROM users JOIN orders ON orders.user_id = '
+ text = "SELECT users.name, orders.id FROM users JOIN orders ON orders.user_id = "
position = len(
- 'SELECT users.name, orders.id FROM users JOIN orders ON orders.user_id = ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='users', start_position=0),
- Completion(text='orders', start_position=0),
- ])
+ "SELECT users.name, orders.id FROM users JOIN orders ON orders.user_id = "
+ )
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="users", start_position=0),
+ Completion(text="orders", start_position=0),
+ ]
+ )
def test_table_names_after_from(completer, complete_event):
- text = 'SELECT * FROM '
- position = len('SELECT * FROM ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='users', start_position=0),
- Completion(text='orders', start_position=0),
- Completion(text='`select`', start_position=0),
- Completion(text='`réveillé`', start_position=0),
- ])
+ text = "SELECT * FROM "
+ position = len("SELECT * FROM ")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="users", start_position=0),
+ Completion(text="orders", start_position=0),
+ Completion(text="`select`", start_position=0),
+ Completion(text="`réveillé`", start_position=0),
+ ]
+ )
def test_auto_escaped_col_names(completer, complete_event):
- text = 'SELECT from `select`'
- position = len('SELECT ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
+ text = "SELECT from `select`"
+ position = len("SELECT ")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
assert result == [
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='`insert`', start_position=0),
- Completion(text='`ABC`', start_position=0),
- ] + \
- list(map(Completion, completer.functions)) + \
- [Completion(text='select', start_position=0)] + \
- list(map(Completion, completer.keywords))
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="`insert`", start_position=0),
+ Completion(text="`ABC`", start_position=0),
+ ] + list(map(Completion, completer.functions)) + [
+ Completion(text="select", start_position=0)
+ ] + list(map(Completion, completer.keywords))
def test_un_escaped_table_names(completer, complete_event):
- text = 'SELECT from réveillé'
- position = len('SELECT ')
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
- assert result == list([
- Completion(text='*', start_position=0),
- Completion(text='id', start_position=0),
- Completion(text='`insert`', start_position=0),
- Completion(text='`ABC`', start_position=0),
- ] +
- list(map(Completion, completer.functions)) +
- [Completion(text='réveillé', start_position=0)] +
- list(map(Completion, completer.keywords)))
+ text = "SELECT from réveillé"
+ position = len("SELECT ")
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
+ assert result == list(
+ [
+ Completion(text="*", start_position=0),
+ Completion(text="id", start_position=0),
+ Completion(text="`insert`", start_position=0),
+ Completion(text="`ABC`", start_position=0),
+ ]
+ + list(map(Completion, completer.functions))
+ + [Completion(text="réveillé", start_position=0)]
+ + list(map(Completion, completer.keywords))
+ )
def dummy_list_path(dir_name):
dirs = {
- '/': [
- 'dir1',
- 'file1.sql',
- 'file2.sql',
+ "/": [
+ "dir1",
+ "file1.sql",
+ "file2.sql",
],
- '/dir1': [
- 'subdir1',
- 'subfile1.sql',
- 'subfile2.sql',
+ "/dir1": [
+ "subdir1",
+ "subfile1.sql",
+ "subfile2.sql",
],
- '/dir1/subdir1': [
- 'lastfile.sql',
+ "/dir1/subdir1": [
+ "lastfile.sql",
],
}
return dirs.get(dir_name, [])
-@patch('mycli.packages.filepaths.list_path', new=dummy_list_path)
-@pytest.mark.parametrize('text,expected', [
- # ('source ', [('~', 0),
- # ('/', 0),
- # ('.', 0),
- # ('..', 0)]),
- ('source /', [('dir1', 0),
- ('file1.sql', 0),
- ('file2.sql', 0)]),
- ('source /dir1/', [('subdir1', 0),
- ('subfile1.sql', 0),
- ('subfile2.sql', 0)]),
- ('source /dir1/subdir1/', [('lastfile.sql', 0)]),
-])
+@patch("mycli.packages.filepaths.list_path", new=dummy_list_path)
+@pytest.mark.parametrize(
+ "text,expected",
+ [
+ # ('source ', [('~', 0),
+ # ('/', 0),
+ # ('.', 0),
+ # ('..', 0)]),
+ ("source /", [("dir1", 0), ("file1.sql", 0), ("file2.sql", 0)]),
+ ("source /dir1/", [("subdir1", 0), ("subfile1.sql", 0), ("subfile2.sql", 0)]),
+ ("source /dir1/subdir1/", [("lastfile.sql", 0)]),
+ ],
+)
def test_file_name_completion(completer, complete_event, text, expected):
position = len(text)
- result = list(completer.get_completions(
- Document(text=text, cursor_position=position),
- complete_event))
+ result = list(
+ completer.get_completions(
+ Document(text=text, cursor_position=position), complete_event
+ )
+ )
expected = list((Completion(txt, pos) for txt, pos in expected))
assert result == expected