|
9 | 9 |
|
10 | 10 | from argparse import ArgumentParser |
11 | 11 | from code import InteractiveConsole |
12 | | -from contextlib import contextmanager |
13 | 12 | from textwrap import dedent |
14 | 13 |
|
| 14 | +from ._completer import enable_completer |
| 15 | + |
15 | 16 |
|
16 | 17 | def execute(c, sql, suppress_errors=True): |
17 | 18 | """Helper that wraps execution of SQL code. |
@@ -63,59 +64,6 @@ def runsource(self, source, filename="<input>", symbol="single"): |
63 | 64 | return False |
64 | 65 |
|
65 | 66 |
|
66 | | -def _complete(text, state): |
67 | | - keywords = ["ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ALWAYS", |
68 | | - "ANALYZE", "AND", "AS", "ASC", "ATTACH", "AUTOINCREMENT", |
69 | | - "BEFORE", "BEGIN", "BETWEEN", "BY", "CASCADE", "CASE", "CAST", |
70 | | - "CHECK", "COLLATE", "COLUMN", "COMMIT", "CONFLICT", |
71 | | - "CONSTRAINT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", |
72 | | - "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", |
73 | | - "DEFERRABLE", "DEFERRED", "DELETE", "DESC", "DETACH", |
74 | | - "DISTINCT", "DO", "DROP", "EACH", "ELSE", "END", "ESCAPE", |
75 | | - "EXCEPT", "EXCLUDE", "EXCLUSIVE", "EXISTS", "EXPLAIN", "FAIL", |
76 | | - "FILTER", "FIRST", "FOLLOWING", "FOR", "FOREIGN", "FROM", |
77 | | - "FULL", "GENERATED", "GLOB", "GROUP", "GROUPS", "HAVING", "IF", |
78 | | - "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", |
79 | | - "INNER", "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", |
80 | | - "ISNULL", "JOIN", "KEY", "LAST", "LEFT", "LIKE", "LIMIT", |
81 | | - "MATCH", "MATERIALIZED", "NATURAL", "NO", "NOT", "NOTHING", |
82 | | - "NOTNULL", "NULL", "NULLS", "OF", "OFFSET", "ON", "OR", |
83 | | - "ORDER", "OTHERS", "OUTER", "OVER", "PARTITION", "PLAN", |
84 | | - "PRAGMA", "PRECEDING", "PRIMARY", "QUERY", "RAISE", "RANGE", |
85 | | - "RECURSIVE", "REFERENCES", "REGEXP", "REINDEX", "RELEASE", |
86 | | - "RENAME", "REPLACE", "RESTRICT", "RETURNING", "RIGHT", |
87 | | - "ROLLBACK", "ROW", "ROWS", "SAVEPOINT", "SELECT", "SET", |
88 | | - "TABLE", "TEMP", "TEMPORARY", "THEN", "TIES", "TO", |
89 | | - "TRANSACTION", "TRIGGER", "UNBOUNDED", "UNION", "UNIQUE", |
90 | | - "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", |
91 | | - "WHEN", "WHERE", "WINDOW", "WITH", "WITHOUT"] |
92 | | - options = [c + " " for c in keywords if c.startswith(text.upper())] |
93 | | - try: |
94 | | - return options[state] |
95 | | - except IndexError: |
96 | | - return None |
97 | | - |
98 | | -@contextmanager |
99 | | -def _enable_completer(): |
100 | | - try: |
101 | | - import readline |
102 | | - except ImportError: |
103 | | - yield |
104 | | - return |
105 | | - |
106 | | - old_completer = readline.get_completer() |
107 | | - try: |
108 | | - readline.set_completer(_complete) |
109 | | - if readline.backend == "editline": |
110 | | - # libedit uses "^I" instead of "tab" |
111 | | - command_string = "bind ^I rl_complete" |
112 | | - else: |
113 | | - command_string = "tab: complete" |
114 | | - readline.parse_and_bind(command_string) |
115 | | - yield |
116 | | - finally: |
117 | | - readline.set_completer(old_completer) |
118 | | - |
119 | 67 | def main(*args): |
120 | 68 | parser = ArgumentParser( |
121 | 69 | description="Python sqlite3 CLI", |
@@ -168,7 +116,7 @@ def main(*args): |
168 | 116 | execute(con, args.sql, suppress_errors=False) |
169 | 117 | else: |
170 | 118 | # No SQL provided; start the REPL. |
171 | | - with _enable_completer(): |
| 119 | + with enable_completer(): |
172 | 120 | console = SqliteInteractiveConsole(con) |
173 | 121 | console.interact(banner, exitmsg="") |
174 | 122 | finally: |
|
0 commit comments