kaqing 2.0.98__py3-none-any.whl → 2.0.203__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. adam/__init__.py +0 -2
  2. adam/app_session.py +9 -12
  3. adam/apps.py +18 -4
  4. adam/batch.py +11 -25
  5. adam/checks/check_utils.py +16 -46
  6. adam/checks/cpu.py +7 -1
  7. adam/checks/cpu_metrics.py +52 -0
  8. adam/checks/disk.py +2 -3
  9. adam/columns/columns.py +3 -1
  10. adam/columns/cpu.py +3 -1
  11. adam/columns/cpu_metrics.py +22 -0
  12. adam/columns/memory.py +3 -4
  13. adam/commands/__init__.py +24 -0
  14. adam/commands/alter_tables.py +37 -63
  15. adam/commands/app/app.py +38 -0
  16. adam/commands/{app_ping.py → app/app_ping.py} +8 -14
  17. adam/commands/app/show_app_actions.py +49 -0
  18. adam/commands/{show → app}/show_app_id.py +8 -11
  19. adam/commands/{show → app}/show_app_queues.py +8 -14
  20. adam/commands/app/utils_app.py +106 -0
  21. adam/commands/audit/audit.py +31 -35
  22. adam/commands/audit/audit_repair_tables.py +26 -48
  23. adam/commands/audit/audit_run.py +50 -0
  24. adam/commands/audit/completions_l.py +15 -0
  25. adam/commands/audit/show_last10.py +36 -0
  26. adam/commands/audit/show_slow10.py +36 -0
  27. adam/commands/audit/show_top10.py +36 -0
  28. adam/commands/audit/utils_show_top10.py +71 -0
  29. adam/commands/bash/__init__.py +5 -0
  30. adam/commands/bash/bash.py +36 -0
  31. adam/commands/bash/bash_completer.py +93 -0
  32. adam/commands/bash/utils_bash.py +16 -0
  33. adam/commands/cassandra/__init__.py +0 -0
  34. adam/commands/cassandra/download_cassandra_log.py +45 -0
  35. adam/commands/cassandra/nodetool.py +64 -0
  36. adam/commands/cassandra/nodetool_commands.py +120 -0
  37. adam/commands/{restart.py → cassandra/restart_cluster.py} +12 -26
  38. adam/commands/cassandra/restart_node.py +51 -0
  39. adam/commands/cassandra/restart_nodes.py +47 -0
  40. adam/commands/cassandra/rollout.py +88 -0
  41. adam/commands/cat.py +36 -0
  42. adam/commands/cd.py +14 -92
  43. adam/commands/check.py +18 -21
  44. adam/commands/cli_commands.py +8 -4
  45. adam/commands/clipboard_copy.py +87 -0
  46. adam/commands/code.py +57 -0
  47. adam/commands/command.py +212 -39
  48. adam/commands/commands_utils.py +20 -28
  49. adam/commands/cql/alter_tables.py +66 -0
  50. adam/commands/cql/completions_c.py +29 -0
  51. adam/commands/cql/cqlsh.py +10 -29
  52. adam/commands/cql/utils_cql.py +305 -0
  53. adam/commands/debug/__init__.py +0 -0
  54. adam/commands/debug/debug.py +22 -0
  55. adam/commands/debug/debug_completes.py +35 -0
  56. adam/commands/debug/debug_timings.py +35 -0
  57. adam/commands/deploy/code_start.py +7 -10
  58. adam/commands/deploy/code_stop.py +4 -21
  59. adam/commands/deploy/code_utils.py +3 -3
  60. adam/commands/deploy/deploy.py +4 -21
  61. adam/commands/deploy/deploy_frontend.py +14 -17
  62. adam/commands/deploy/deploy_pg_agent.py +3 -6
  63. adam/commands/deploy/deploy_pod.py +65 -73
  64. adam/commands/deploy/deploy_utils.py +14 -24
  65. adam/commands/deploy/undeploy.py +4 -21
  66. adam/commands/deploy/undeploy_frontend.py +4 -7
  67. adam/commands/deploy/undeploy_pg_agent.py +6 -8
  68. adam/commands/deploy/undeploy_pod.py +11 -12
  69. adam/commands/devices/__init__.py +0 -0
  70. adam/commands/devices/device.py +149 -0
  71. adam/commands/devices/device_app.py +163 -0
  72. adam/commands/devices/device_auit_log.py +49 -0
  73. adam/commands/devices/device_cass.py +179 -0
  74. adam/commands/devices/device_export.py +87 -0
  75. adam/commands/devices/device_postgres.py +160 -0
  76. adam/commands/devices/devices.py +25 -0
  77. adam/commands/download_cassandra_log.py +45 -0
  78. adam/commands/download_file.py +47 -0
  79. adam/commands/exit.py +1 -4
  80. adam/commands/export/__init__.py +0 -0
  81. adam/commands/export/clean_up_all_export_sessions.py +37 -0
  82. adam/commands/export/clean_up_export_sessions.py +39 -0
  83. adam/commands/export/completions_x.py +11 -0
  84. adam/commands/export/download_export_session.py +40 -0
  85. adam/commands/export/drop_export_database.py +39 -0
  86. adam/commands/export/drop_export_databases.py +37 -0
  87. adam/commands/export/export.py +37 -0
  88. adam/commands/export/export_databases.py +247 -0
  89. adam/commands/export/export_select.py +34 -0
  90. adam/commands/export/export_sessions.py +211 -0
  91. adam/commands/export/export_use.py +49 -0
  92. adam/commands/export/export_x_select.py +48 -0
  93. adam/commands/export/exporter.py +361 -0
  94. adam/commands/export/import_files.py +44 -0
  95. adam/commands/export/import_session.py +44 -0
  96. adam/commands/export/importer.py +82 -0
  97. adam/commands/export/importer_athena.py +150 -0
  98. adam/commands/export/importer_sqlite.py +69 -0
  99. adam/commands/export/show_column_counts.py +45 -0
  100. adam/commands/export/show_export_databases.py +39 -0
  101. adam/commands/export/show_export_session.py +39 -0
  102. adam/commands/export/show_export_sessions.py +37 -0
  103. adam/commands/export/utils_export.py +366 -0
  104. adam/commands/find_files.py +51 -0
  105. adam/commands/find_processes.py +76 -0
  106. adam/commands/generate_report.py +52 -0
  107. adam/commands/head.py +36 -0
  108. adam/commands/help.py +12 -8
  109. adam/commands/intermediate_command.py +52 -0
  110. adam/commands/issues.py +14 -40
  111. adam/commands/kubectl.py +38 -0
  112. adam/commands/login.py +26 -25
  113. adam/commands/ls.py +11 -116
  114. adam/commands/medusa/medusa.py +4 -22
  115. adam/commands/medusa/medusa_backup.py +20 -27
  116. adam/commands/medusa/medusa_restore.py +35 -48
  117. adam/commands/medusa/medusa_show_backupjobs.py +17 -18
  118. adam/commands/medusa/medusa_show_restorejobs.py +13 -18
  119. adam/commands/medusa/utils_medusa.py +15 -0
  120. adam/commands/nodetool.py +8 -19
  121. adam/commands/os/__init__.py +0 -0
  122. adam/commands/os/cat.py +36 -0
  123. adam/commands/os/download_file.py +47 -0
  124. adam/commands/os/find_files.py +51 -0
  125. adam/commands/os/find_processes.py +76 -0
  126. adam/commands/os/head.py +36 -0
  127. adam/commands/os/shell.py +41 -0
  128. adam/commands/param_get.py +11 -14
  129. adam/commands/param_set.py +8 -12
  130. adam/commands/postgres/completions_p.py +22 -0
  131. adam/commands/postgres/postgres.py +47 -55
  132. adam/commands/postgres/postgres_databases.py +269 -0
  133. adam/commands/postgres/postgres_ls.py +4 -8
  134. adam/commands/postgres/postgres_preview.py +5 -9
  135. adam/commands/postgres/utils_postgres.py +79 -0
  136. adam/commands/preview_table.py +10 -61
  137. adam/commands/pwd.py +14 -46
  138. adam/commands/reaper/reaper.py +4 -24
  139. adam/commands/reaper/reaper_forward.py +49 -56
  140. adam/commands/reaper/reaper_forward_session.py +6 -0
  141. adam/commands/reaper/reaper_forward_stop.py +10 -16
  142. adam/commands/reaper/reaper_restart.py +7 -14
  143. adam/commands/reaper/reaper_run_abort.py +8 -33
  144. adam/commands/reaper/reaper_runs.py +43 -58
  145. adam/commands/reaper/reaper_runs_abort.py +29 -49
  146. adam/commands/reaper/reaper_schedule_activate.py +14 -33
  147. adam/commands/reaper/reaper_schedule_start.py +9 -33
  148. adam/commands/reaper/reaper_schedule_stop.py +9 -33
  149. adam/commands/reaper/reaper_schedules.py +4 -14
  150. adam/commands/reaper/reaper_status.py +8 -16
  151. adam/commands/reaper/utils_reaper.py +203 -0
  152. adam/commands/repair/repair.py +4 -22
  153. adam/commands/repair/repair_log.py +5 -11
  154. adam/commands/repair/repair_run.py +27 -34
  155. adam/commands/repair/repair_scan.py +32 -40
  156. adam/commands/repair/repair_stop.py +5 -12
  157. adam/commands/restart_cluster.py +47 -0
  158. adam/commands/restart_node.py +51 -0
  159. adam/commands/restart_nodes.py +47 -0
  160. adam/commands/rollout.py +19 -24
  161. adam/commands/shell.py +12 -4
  162. adam/commands/show/show.py +10 -23
  163. adam/commands/show/show_adam.py +3 -3
  164. adam/commands/show/show_cassandra_repairs.py +37 -0
  165. adam/commands/show/show_cassandra_status.py +47 -51
  166. adam/commands/show/show_cassandra_version.py +5 -18
  167. adam/commands/show/show_cli_commands.py +56 -0
  168. adam/commands/show/show_host.py +1 -1
  169. adam/commands/show/show_login.py +23 -27
  170. adam/commands/show/show_params.py +2 -5
  171. adam/commands/show/show_processes.py +18 -21
  172. adam/commands/show/show_storage.py +11 -20
  173. adam/commands/watch.py +26 -29
  174. adam/config.py +5 -15
  175. adam/embedded_params.py +1 -1
  176. adam/log.py +4 -4
  177. adam/repl.py +105 -133
  178. adam/repl_commands.py +68 -28
  179. adam/repl_session.py +9 -1
  180. adam/repl_state.py +300 -62
  181. adam/sql/async_executor.py +44 -0
  182. adam/sql/lark_completer.py +286 -0
  183. adam/sql/lark_parser.py +604 -0
  184. adam/sql/qingl.lark +1076 -0
  185. adam/sql/sql_completer.py +104 -64
  186. adam/sql/sql_state_machine.py +630 -0
  187. adam/sql/term_completer.py +3 -0
  188. adam/sso/authn_ad.py +6 -8
  189. adam/sso/authn_okta.py +4 -6
  190. adam/sso/cred_cache.py +3 -5
  191. adam/sso/idp.py +9 -12
  192. adam/utils.py +640 -10
  193. adam/utils_athena.py +140 -87
  194. adam/utils_audits.py +102 -0
  195. adam/utils_issues.py +32 -0
  196. adam/utils_k8s/app_clusters.py +28 -0
  197. adam/utils_k8s/app_pods.py +35 -0
  198. adam/utils_k8s/cassandra_clusters.py +34 -21
  199. adam/utils_k8s/cassandra_nodes.py +9 -6
  200. adam/utils_k8s/custom_resources.py +16 -17
  201. adam/utils_k8s/ingresses.py +2 -2
  202. adam/utils_k8s/jobs.py +7 -11
  203. adam/utils_k8s/k8s.py +96 -0
  204. adam/utils_k8s/kube_context.py +3 -6
  205. adam/{pod_exec_result.py → utils_k8s/pod_exec_result.py} +11 -5
  206. adam/utils_k8s/pods.py +146 -75
  207. adam/utils_k8s/secrets.py +4 -4
  208. adam/utils_k8s/service_accounts.py +5 -4
  209. adam/utils_k8s/services.py +2 -2
  210. adam/utils_k8s/statefulsets.py +6 -14
  211. adam/utils_local.py +42 -0
  212. adam/utils_net.py +4 -4
  213. adam/utils_repl/__init__.py +0 -0
  214. adam/utils_repl/appendable_completer.py +6 -0
  215. adam/utils_repl/automata_completer.py +48 -0
  216. adam/utils_repl/repl_completer.py +89 -0
  217. adam/utils_repl/state_machine.py +173 -0
  218. adam/utils_sqlite.py +137 -0
  219. adam/version.py +1 -1
  220. {kaqing-2.0.98.dist-info → kaqing-2.0.203.dist-info}/METADATA +1 -1
  221. kaqing-2.0.203.dist-info/RECORD +277 -0
  222. kaqing-2.0.203.dist-info/top_level.txt +2 -0
  223. teddy/__init__.py +0 -0
  224. teddy/lark_parser.py +436 -0
  225. teddy/lark_parser2.py +618 -0
  226. adam/commands/app.py +0 -67
  227. adam/commands/bash.py +0 -92
  228. adam/commands/cp.py +0 -95
  229. adam/commands/cql/cql_completions.py +0 -11
  230. adam/commands/cql/cql_table_completer.py +0 -8
  231. adam/commands/cql/cql_utils.py +0 -115
  232. adam/commands/describe/describe.py +0 -47
  233. adam/commands/describe/describe_keyspace.py +0 -60
  234. adam/commands/describe/describe_keyspaces.py +0 -49
  235. adam/commands/describe/describe_schema.py +0 -49
  236. adam/commands/describe/describe_table.py +0 -60
  237. adam/commands/describe/describe_tables.py +0 -49
  238. adam/commands/devices.py +0 -118
  239. adam/commands/logs.py +0 -39
  240. adam/commands/postgres/postgres_session.py +0 -240
  241. adam/commands/postgres/postgres_utils.py +0 -31
  242. adam/commands/postgres/psql_completions.py +0 -10
  243. adam/commands/postgres/psql_table_completer.py +0 -11
  244. adam/commands/reaper/reaper_session.py +0 -159
  245. adam/commands/report.py +0 -57
  246. adam/commands/show/show_app_actions.py +0 -53
  247. adam/commands/show/show_commands.py +0 -61
  248. adam/commands/show/show_repairs.py +0 -47
  249. adam/sql/state_machine.py +0 -460
  250. kaqing-2.0.98.dist-info/RECORD +0 -191
  251. kaqing-2.0.98.dist-info/top_level.txt +0 -1
  252. /adam/commands/{describe → app}/__init__.py +0 -0
  253. {kaqing-2.0.98.dist-info → kaqing-2.0.203.dist-info}/WHEEL +0 -0
  254. {kaqing-2.0.98.dist-info → kaqing-2.0.203.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,286 @@
1
+ import functools
2
+ import os
3
+ from typing import Iterable
4
+ from prompt_toolkit.completion import CompleteEvent, Completer, Completion, NestedCompleter, WordCompleter
5
+ from prompt_toolkit.document import Document
6
+
7
+ from adam.config import Config
8
+ from adam.sql.async_executor import AsyncExecutor
9
+ from adam.sql.lark_parser import LarkParser
10
+ from adam.utils import debug, log_timing, offload
11
+ from adam.utils_repl.appendable_completer import AppendableCompleter
12
+ from adam.utils_repl.repl_completer import merge_completions
13
+
14
+ __all__ = [
15
+ "LarkCompleter",
16
+ ]
17
+
18
+ def default_columns(x: list[str]):
19
+ return 'id,x.,y.,z.'.split(',')
20
+
21
+ class LarkCompleter(Completer, AppendableCompleter):
22
+ SYSTEM = 'system'
23
+
24
+ def __init__(self,
25
+ dml: str = None,
26
+ expandables: dict = {},
27
+ variant: str = 'c',
28
+
29
+ name: str = None,
30
+ options_lambda: callable = None,
31
+ auto: str = 'lazy',
32
+ debug = False
33
+ ) -> None:
34
+ self.nested: NestedCompleter = None
35
+ self.options_lambda = options_lambda
36
+ if options_lambda and auto == 'lazy':
37
+ AsyncExecutor.preload(options_lambda, log_key=name)
38
+
39
+ self.variant = variant
40
+ self.parser = None
41
+ self.dml = dml
42
+ self.expandables = expandables
43
+
44
+ self.display_dict = {}
45
+ self.meta_dict = {}
46
+ self.WORD = None
47
+ self.sentence = False
48
+ self.match_middle = False
49
+ self.pattern = None
50
+
51
+ self.debug = debug
52
+
53
+ if variant:
54
+ self.parser = LarkCompleter.lark_parser(variant)
55
+ self.preload_lazy_auto_completes()
56
+
57
+ def __repr__(self):
58
+ return f"LarkCompleter.{self.variant}"
59
+
60
+ def preload_lazy_auto_completes(self):
61
+ for key, value in self.expandables.items():
62
+ if callable(value):
63
+ if self.auto_complete(key) == 'lazy':
64
+ AsyncExecutor.preload(value, log_key=key)
65
+
66
+ def from_lambda(name: str, options_lambda: callable, auto: str = 'lazy'):
67
+ return LarkCompleter(name=name, options_lambda=options_lambda, auto=auto, variant=None)
68
+
69
+ @functools.lru_cache()
70
+ def lark_parser(variant: str):
71
+ dir_path = os.path.dirname(os.path.realpath(__file__))
72
+ with open(dir_path + f"/qingl.lark") as f:
73
+ grammar: str = None
74
+ with log_timing(f'lark.{variant}.file-read'):
75
+ grammar = f.read()
76
+
77
+ common_contexts = {
78
+ 'cd_command.file_name': 'direct-dirs',
79
+ }
80
+
81
+ if variant in ['a', 'c0', 'p0', 'x0']:
82
+ grammar = grammar.replace('start: statement_sequence', f'start: qing_{variant}_statement')
83
+ contexts_by_path = {
84
+ } | common_contexts
85
+
86
+ debug(f'* GRAMMAR replaced to start: qing_{variant}_statement')
87
+
88
+ return LarkParser(grammar, contexts_by_path)
89
+ elif variant == 'system':
90
+ grammar = grammar.replace('start: statement_sequence', f'start: qing_{variant}_statement')
91
+ contexts_by_path = {
92
+ } | common_contexts
93
+
94
+ return LarkParser(grammar, contexts_by_path)
95
+
96
+ grammar = grammar.replace('qing_statement: qing_p_statement', f'qing_statement: qing_{variant}_statement')
97
+ debug(f'* GRAMMAR replaced to qing_statement: qing_{variant}_statement')
98
+
99
+ bash_contexts = {
100
+ 'bash_statement.host_name': 'hosts',
101
+ 'bash_statement.bash_command': 'bash-commands',
102
+ }
103
+
104
+ contexts_by_path = {
105
+ 'describe_keyspace.keyspace_name': 'keyspaces',
106
+ 'keyspace_ref.keyspace_path.namespace_ref.identifier_ref': 'tables',
107
+ 'preview_table_statement.path.identifier_ref': 'tables',
108
+
109
+ 'insert_statement.insert_select': 'column-names',
110
+ 'update_statement.set_clause.path.identifier_ref': 'column-names',
111
+ 'update_statement.where_clause.cond.expr.path.identifier_ref': 'column-names',
112
+ 'delete_statement.where_clause.cond.expr.path.identifier_ref': 'column-names',
113
+
114
+ 'select_clause.projection.result_expr.expr.path.identifier_ref': 'columns',
115
+ 'select_from.where_clause.cond.expr.path.identifier_ref': 'columns',
116
+ 'select_from.where_clause.cond.expr.logical_term.and_expr.cond.expr.path.identifier_ref': 'columns',
117
+ 'select_from.group_by_clause.group_term.expr.path.identifier_ref': 'columns',
118
+ 'select_statement.order_by_clause.ordering_term.expr.path.identifier_ref': 'columns',
119
+ 'select_from.from_clause.from_terms.join_clause.ansi_join_clause.ansi_join_predicate.expr.path.identifier_ref': 'columns',
120
+ 'select_from.from_clause.from_terms.join_clause.ansi_join_clause.ansi_join_predicate.expr.comparison_term.relational_expr.expr.path.identifier_ref': 'columns',
121
+
122
+ 'select_from.from_clause.from_terms.from_generic.alias.identifier_ref': 'column-aliases',
123
+
124
+ 'select_statement.limit_clause.expr.literal.nbr.digit': 'limits',
125
+ } | common_contexts
126
+
127
+ if variant == 'p':
128
+ contexts_by_path = bash_contexts | contexts_by_path
129
+ elif variant == 'c':
130
+ contexts_by_path = {
131
+ 'export_table.path.identifier_ref': 'tables',
132
+ 'show_column_counts_command.path.identifier_ref': 'tables',
133
+ 'export_statement.export_tables.keyspace_name': 'keyspaces',
134
+
135
+ 'alter_tables_statement.properties.property.property_name': 'table-props',
136
+ 'alter_cql_table_statement.properties.property.property_name': 'table-props',
137
+ 'alter_tables_statement.properties.property.property_value.literal': 'table-props-value',
138
+ 'alter_cql_table_statement.properties.property.property_value.literal': 'table-props-value',
139
+
140
+ 'select_clause.projection.result_expr.expr.path.identifier_ref': 'columns',
141
+ 'export_statement.export_tables.export_table.column_name_list.column_name': 'columns',
142
+
143
+ 'consistency_statement.consistency': 'consistencies',
144
+ 'export_statement.export_to.export_database_type': 'export-database-types',
145
+ 'drop_export_database.export_database_name': 'export-databases',
146
+ 'use_export_db_statement.export_database_name': 'export-databases',
147
+ 'clean_up_export_session_statement.clean_up_export_sessions.export_session_name': 'export-sessions',
148
+ 'show_export_command.export_session_name': 'export-sessions',
149
+ 'import_statement.import_session.export_session_name': 'export-sessions-incomplete',
150
+ 'download_session_statement.export_session_name': 'export-sessions-incomplete',
151
+ } | bash_contexts | contexts_by_path
152
+ elif variant == 'l':
153
+ contexts_by_path = {
154
+ 'add_partition_action.partition_ref.partition_name': 'partition-columns',
155
+ 'show_topn_statement.topn_count': 'topn-counts',
156
+ 'show_topn_statement.topn_type': 'topn-types',
157
+ 'show_topn_statement.topn_window': 'topn-windows'
158
+ } | contexts_by_path
159
+ elif variant == 'x':
160
+ contexts_by_path = {
161
+ 'show_column_counts_command.path.identifier_ref': 'tables',
162
+ 'drop_export_database.export_database_name': 'export-databases',
163
+ 'use_export_db_statement.export_database_name': 'export-databases',
164
+ } | contexts_by_path
165
+
166
+ grammar = grammar.replace('select_clause: "SELECT"i hint_comment? projection', 'select_clause: ("SELECT"i | "XELECT"i) hint_comment? projection')
167
+
168
+ with offload():
169
+ with open('/tmp/grammar.lark', 'wt') as f:
170
+ f.write(grammar)
171
+
172
+ return LarkParser(grammar, contexts_by_path)
173
+
174
+ def get_completions(
175
+ self, document: Document, complete_event: CompleteEvent
176
+ ) -> Iterable[Completion]:
177
+ if not self.nested and self.options_lambda:
178
+ # for lazy completions
179
+ self.nested = NestedCompleter.from_nested_dict(self.options_lambda())
180
+
181
+ nested_words = set()
182
+
183
+ if self.nested:
184
+ # from NestedCompleter
185
+
186
+ # Split document.
187
+ text = document.text_before_cursor.lstrip()
188
+ stripped_len = len(document.text_before_cursor) - len(text)
189
+
190
+ # If there is a space, check for the first term, and use a
191
+ # subcompleter.
192
+ if " " in text:
193
+ first_term = text.split()[0]
194
+ completer = self.nested.options.get(first_term)
195
+
196
+ # If we have a sub completer, use this for the completions.
197
+ if completer is not None:
198
+ remaining_text = text[len(first_term) :].lstrip()
199
+ move_cursor = len(text) - len(remaining_text) + stripped_len
200
+
201
+ new_document = Document(
202
+ remaining_text,
203
+ cursor_position=document.cursor_position - move_cursor,
204
+ )
205
+
206
+ for c in completer.get_completions(new_document, complete_event):
207
+ nested_words.add(c.text)
208
+ yield c
209
+
210
+ # No space in the input: behave exactly like `WordCompleter`.
211
+ else:
212
+ completer = WordCompleter(
213
+ list(self.nested.options.keys()), ignore_case=self.nested.ignore_case
214
+ )
215
+ for c in completer.get_completions(document, complete_event):
216
+ nested_words.add(c.text)
217
+ yield c
218
+
219
+ if self.parser:
220
+ full = document.text_before_cursor
221
+ if self.dml:
222
+ full = self.dml + ' ' + full
223
+
224
+ words0 = []
225
+ words1 = []
226
+ context = {}
227
+ for word in self.parser.next_terminals(full, context=context):
228
+ if ex := self.expandable(word):
229
+ if ex in self.expandables:
230
+ e = self.expandables[ex]
231
+ if callable(e):
232
+ if self.auto_complete(ex) != 'off':
233
+ ctx = None
234
+ if 'last-id' in context:
235
+ ctx = context['last-id']
236
+ e = e(ctx)
237
+ words0.extend(e)
238
+ else:
239
+ words0.extend(e)
240
+ else:
241
+ words1.append(word)
242
+ words = words0 + words1
243
+
244
+ word_before_cursor = document.get_word_before_cursor(
245
+ WORD=self.WORD, pattern=self.pattern
246
+ )
247
+
248
+ word_before_cursor = word_before_cursor.lower()
249
+
250
+ def word_matches(word: str) -> bool:
251
+ return word.lower().startswith(word_before_cursor)
252
+
253
+ for word in words:
254
+ if word_matches(word) and word not in nested_words:
255
+ display = self.display_dict.get(word, word)
256
+ display_meta = self.meta_dict.get(word, "")
257
+ yield Completion(
258
+ word,
259
+ -len(word_before_cursor),
260
+ display=display,
261
+ display_meta=display_meta,
262
+ )
263
+
264
+ def completions_for_nesting(self, dml: str = None):
265
+ if dml:
266
+ return {dml: LarkCompleter(dml, expandables=self.expandables, variant=self.variant)}
267
+
268
+ return {
269
+ word.text.lower(): LarkCompleter(word.text, expandables=self.expandables, variant=self.variant)
270
+ for word in self.get_completions(Document(''), None)
271
+ }
272
+
273
+ def expandable(self, word: str):
274
+ return word.strip('`') if word.startswith('`') else None
275
+
276
+ def append_completions(self, key: str, value: dict[str, any]):
277
+ if isinstance(value, LarkCompleter) and self.variant == value.variant:
278
+ return
279
+
280
+ if self.nested:
281
+ self.nested = NestedCompleter.from_nested_dict(merge_completions(self.nested.options, value))
282
+ else:
283
+ self.nested = NestedCompleter.from_nested_dict(value)
284
+
285
+ def auto_complete(self, key: str, default = 'lazy'):
286
+ return Config().get(f'auto-complete.{self.variant}.{key}', default=default)