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