mycli 2.5.1__tar.gz → 2.7.0__tar.gz
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.
- {mycli-2.5.1/mycli.egg-info → mycli-2.7.0}/PKG-INFO +16 -21
- {mycli-2.5.1 → mycli-2.7.0}/README.md +2 -1
- {mycli-2.5.1 → mycli-2.7.0}/changelog.md +68 -0
- mycli-2.7.0/doc/screenshots/total_histogram.png +0 -0
- mycli-2.7.0/doc/transforms.md +128 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/TIPS +12 -2
- {mycli-2.5.1 → mycli-2.7.0}/mycli/app_state.py +11 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/cli_runner.py +4 -4
- {mycli-2.5.1 → mycli-2.7.0}/mycli/client.py +12 -1
- {mycli-2.5.1 → mycli-2.7.0}/mycli/client_commands.py +1 -1
- {mycli-2.5.1 → mycli-2.7.0}/mycli/client_query.py +1 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/clistyle.py +1 -0
- mycli-2.7.0/mycli/compat.py +27 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/completion_refresher.py +5 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/main_modes/checkup.py +34 -21
- {mycli-2.5.1 → mycli-2.7.0}/mycli/main_modes/repl.py +22 -7
- {mycli-2.5.1 → mycli-2.7.0}/mycli/myclirc +28 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/output.py +26 -1
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/completion_engine.py +37 -5
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/hybrid_redirection.py +17 -4
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/polars_transform.py +144 -35
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/dsn_aliases.py +2 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/iocommands.py +4 -4
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/main.py +11 -11
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/sqlresult.py +8 -1
- {mycli-2.5.1 → mycli-2.7.0}/mycli/schema_prefetcher.py +8 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/sqlcompleter.py +85 -7
- {mycli-2.5.1 → mycli-2.7.0}/mycli/sqlexecute.py +19 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/types.py +6 -0
- {mycli-2.5.1 → mycli-2.7.0/mycli.egg-info}/PKG-INFO +16 -21
- {mycli-2.5.1 → mycli-2.7.0}/mycli.egg-info/SOURCES.txt +1 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli.egg-info/requires.txt +13 -19
- {mycli-2.5.1 → mycli-2.7.0}/mycli.egg-info/scm_file_list.json +131 -130
- mycli-2.7.0/mycli.egg-info/scm_version.json +8 -0
- {mycli-2.5.1 → mycli-2.7.0}/pyproject.toml +20 -22
- {mycli-2.5.1 → mycli-2.7.0}/test/myclirc +69 -43
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_app_state.py +72 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_checkup.py +18 -10
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_client.py +100 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_client_query.py +12 -2
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_clistyle.py +12 -1
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_completer_use_switch.py +3 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_completion_engine.py +40 -4
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_completion_refresher.py +4 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_hybrid_redirection.py +50 -2
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_main_modes_repl.py +140 -12
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_naive_completion.py +13 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_output.py +90 -1
- mycli-2.7.0/test/pytests/test_polars_transform.py +868 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_schema_prefetcher.py +11 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_smart_completion_public_schema_only.py +143 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_special_main.py +3 -3
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_sqlcompleter.py +90 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_sqlexecute.py +39 -0
- mycli-2.5.1/doc/transforms.md +0 -98
- mycli-2.5.1/mycli/compat.py +0 -5
- mycli-2.5.1/mycli.egg-info/scm_version.json +0 -8
- mycli-2.5.1/test/pytests/test_polars_transform.py +0 -405
- {mycli-2.5.1 → mycli-2.7.0}/.git-blame-ignore-revs +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.github/dependabot.yml +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.github/workflows/ci.yml +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.github/workflows/lint.yml +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.github/workflows/publish.yml +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.github/workflows/typecheck.yml +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/.gitignore +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/AGENTS.md +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/AUTHORS.rst +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/CONTRIBUTING.md +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/LICENSE.txt +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/MANIFEST.in +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/SPONSORS.rst +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/doc/key_bindings.rst +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/doc/llm.md +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/doc/screenshots/main.gif +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/doc/screenshots/tables.png +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/AUTHORS +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/SPONSORS +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/__init__.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/clibuffer.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/client_connection.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/clitoolbar.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/config.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/constants.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/key_bindings.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/lexer.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/main.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/main_modes/batch.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/main_modes/execute.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/main_modes/list_dsn.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/__init__.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/batch_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/cli_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/filepaths.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/interactive_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/key_binding_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/ptoolkit/__init__.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/ptoolkit/fzf.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/ptoolkit/history.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/ptoolkit/utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/__init__.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/dbcommands.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/delimitercommand.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/favoritequeries.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/llm.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/special/utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/sql_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/string_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/tabular_output/__init__.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/packages/tabular_output/sql_format.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/password_sources.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/ssh_tunnel.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli/vault.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli.egg-info/dependency_links.txt +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli.egg-info/entry_points.txt +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/mycli.egg-info/top_level.txt +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/setup.cfg +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/__init__.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/__init__.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/auto_vertical.feature +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/basic_commands.feature +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/connection.feature +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/crud_database.feature +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/crud_table.feature +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/db_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/environment.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/fixture_data/help_commands.txt +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/fixture_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/iocommands.feature +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/named_queries.feature +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/specials.feature +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/__init__.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/auto_vertical.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/basic_commands.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/connection.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/crud_database.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/crud_table.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/iocommands.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/named_queries.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/specials.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/steps/wrappers.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/features/wrappager.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/mylogin.cnf +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/conftest.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_batch_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_cli_runner.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_cli_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_clibuffer.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_client_commands.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_client_connection.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_clitoolbar.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_config.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_delimitercommand.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_dsn_aliases.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_favoritequeries.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_filepaths.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_interactive_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_key_binding_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_key_bindings.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_lexer.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_main.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_main_modes_batch.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_main_modes_execute.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_main_modes_list_dsn.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_password_sources.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_ptoolkit_fzf.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_ptoolkit_history.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_ptoolkit_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_special_dbcommands.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_special_init.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_special_iocommands.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_special_llm.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_special_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_sql_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_sqlresult.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_ssh_tunnel.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_string_utils.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_tabular_output.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/pytests/test_vault.py +0 -0
- {mycli-2.5.1 → mycli-2.7.0}/test/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mycli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: CLI for MySQL Database. With auto-completion and syntax highlighting.
|
|
5
5
|
Author: Mycli Core Team
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -13,18 +13,18 @@ Requires-Python: >=3.10
|
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE.txt
|
|
15
15
|
License-File: AUTHORS.rst
|
|
16
|
-
Requires-Dist: click~=8.
|
|
16
|
+
Requires-Dist: click~=8.4.2
|
|
17
17
|
Requires-Dist: clickdc~=0.1.1
|
|
18
|
-
Requires-Dist: cryptography~=
|
|
19
|
-
Requires-Dist: Pygments~=2.
|
|
18
|
+
Requires-Dist: cryptography~=49.0.0
|
|
19
|
+
Requires-Dist: Pygments~=2.20.0
|
|
20
20
|
Requires-Dist: prompt_toolkit<4.0.0,>=3.0.41
|
|
21
21
|
Requires-Dist: PyMySQL~=1.1.2
|
|
22
22
|
Requires-Dist: sqlparse<0.6.0,>=0.3.0
|
|
23
|
-
Requires-Dist: sqlglot~=30.
|
|
24
|
-
Requires-Dist: sqlglotc~=30.
|
|
23
|
+
Requires-Dist: sqlglot~=30.12.0
|
|
24
|
+
Requires-Dist: sqlglotc~=30.12.0
|
|
25
25
|
Requires-Dist: configobj~=5.0.9
|
|
26
|
-
Requires-Dist: cli_helpers[styles]~=2.15.
|
|
27
|
-
Requires-Dist: wcwidth~=0.
|
|
26
|
+
Requires-Dist: cli_helpers[styles]~=2.15.1
|
|
27
|
+
Requires-Dist: wcwidth~=0.8.2
|
|
28
28
|
Requires-Dist: pyperclip~=1.11.0
|
|
29
29
|
Requires-Dist: pycryptodomex~=3.23.0
|
|
30
30
|
Requires-Dist: pyfzf~=0.3.1
|
|
@@ -32,32 +32,26 @@ Requires-Dist: rapidfuzz~=3.14.3
|
|
|
32
32
|
Requires-Dist: keyring~=25.7.0
|
|
33
33
|
Requires-Dist: yaspin~=3.4.0
|
|
34
34
|
Provides-Extra: llm
|
|
35
|
-
Requires-Dist: llm~=0.
|
|
36
|
-
Requires-Dist:
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist: pip==26.*; extra == "llm"
|
|
35
|
+
Requires-Dist: llm~=0.31.1; extra == "llm"
|
|
36
|
+
Requires-Dist: setuptools==83.*; extra == "llm"
|
|
37
|
+
Requires-Dist: pip~=26.1.2; extra == "llm"
|
|
39
38
|
Provides-Extra: dataframe
|
|
40
39
|
Requires-Dist: polars~=1.42.1; extra == "dataframe"
|
|
41
40
|
Requires-Dist: altair~=6.2.2; extra == "dataframe"
|
|
41
|
+
Requires-Dist: vl-convert-python~=1.9.0; extra == "dataframe"
|
|
42
42
|
Provides-Extra: all
|
|
43
43
|
Requires-Dist: mycli[dataframe,llm]; extra == "all"
|
|
44
44
|
Provides-Extra: dev
|
|
45
45
|
Requires-Dist: behave~=1.3.3; extra == "dev"
|
|
46
46
|
Requires-Dist: coverage~=7.13.4; extra == "dev"
|
|
47
|
-
Requires-Dist: mypy~=
|
|
47
|
+
Requires-Dist: mypy~=2.3.0; extra == "dev"
|
|
48
48
|
Requires-Dist: pexpect~=4.9.0; extra == "dev"
|
|
49
|
-
Requires-Dist: pytest~=9.
|
|
49
|
+
Requires-Dist: pytest~=9.1.1; extra == "dev"
|
|
50
50
|
Requires-Dist: pytest-cov~=7.0.0; extra == "dev"
|
|
51
51
|
Requires-Dist: pytest-random-order~=1.2.0; extra == "dev"
|
|
52
52
|
Requires-Dist: tox~=4.35.0; extra == "dev"
|
|
53
53
|
Requires-Dist: pdbpp~=0.11.7; extra == "dev"
|
|
54
|
-
Requires-Dist: llm~=0.30.0; extra == "dev"
|
|
55
|
-
Requires-Dist: pydantic_core~=2.41.5; extra == "dev"
|
|
56
|
-
Requires-Dist: setuptools==82.*; extra == "dev"
|
|
57
|
-
Requires-Dist: pip==26.*; extra == "dev"
|
|
58
54
|
Requires-Dist: ruff~=0.15.0; extra == "dev"
|
|
59
|
-
Requires-Dist: polars~=1.42.1; extra == "dev"
|
|
60
|
-
Requires-Dist: altair~=6.2.2; extra == "dev"
|
|
61
55
|
Dynamic: license-file
|
|
62
56
|
|
|
63
57
|
# mycli
|
|
@@ -67,6 +61,7 @@ Dynamic: license-file
|
|
|
67
61
|
A command line client for MySQL with auto-completion and syntax highlighting.
|
|
68
62
|
|
|
69
63
|
Homepage: [https://mycli.net](https://mycli.net)
|
|
64
|
+
|
|
70
65
|
Documentation: [https://mycli.net/docs](https://mycli.net/docs)
|
|
71
66
|
|
|
72
67
|

|
|
@@ -133,7 +128,7 @@ Features
|
|
|
133
128
|
* Pretty print tabular data (with colors!).
|
|
134
129
|
* Support for SSL connections
|
|
135
130
|
* Shell-style trailing redirects with `$>`, `$>>` and `$|` operators.
|
|
136
|
-
* [Polars](https://pola.rs) dataframe [transforms](doc/transforms.md) with
|
|
131
|
+
* [Polars](https://pola.rs) dataframe [transforms and plots](doc/transforms.md) with `.|`, and Parquet saves with `.>`.
|
|
137
132
|
* Support for querying LLMs with context derived from your schema using `/llm`.
|
|
138
133
|
* Support for storing passwords in the system keyring.
|
|
139
134
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
A command line client for MySQL with auto-completion and syntax highlighting.
|
|
6
6
|
|
|
7
7
|
Homepage: [https://mycli.net](https://mycli.net)
|
|
8
|
+
|
|
8
9
|
Documentation: [https://mycli.net/docs](https://mycli.net/docs)
|
|
9
10
|
|
|
10
11
|

|
|
@@ -71,7 +72,7 @@ Features
|
|
|
71
72
|
* Pretty print tabular data (with colors!).
|
|
72
73
|
* Support for SSL connections
|
|
73
74
|
* Shell-style trailing redirects with `$>`, `$>>` and `$|` operators.
|
|
74
|
-
* [Polars](https://pola.rs) dataframe [transforms](doc/transforms.md) with
|
|
75
|
+
* [Polars](https://pola.rs) dataframe [transforms and plots](doc/transforms.md) with `.|`, and Parquet saves with `.>`.
|
|
75
76
|
* Support for querying LLMs with context derived from your schema using `/llm`.
|
|
76
77
|
* Support for storing passwords in the system keyring.
|
|
77
78
|
|
|
@@ -1,3 +1,71 @@
|
|
|
1
|
+
2.7.0 (2026/07/25)
|
|
2
|
+
==============
|
|
3
|
+
|
|
4
|
+
Features
|
|
5
|
+
---------
|
|
6
|
+
* Show purpose in tabular `--checkup` output.
|
|
7
|
+
* Add optional dependencies to `--checkup`.
|
|
8
|
+
* Improve completions for `/command`s.
|
|
9
|
+
* Highlight indexed columns in completions with a suffix and/or a text style.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Bugfixes
|
|
13
|
+
---------
|
|
14
|
+
* Ignoring `min_completion_trigger` only applies to first token after `/`.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
Documentation
|
|
18
|
+
---------
|
|
19
|
+
* Add `.|` and `.>` to TIPS.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Internal
|
|
23
|
+
---------
|
|
24
|
+
* Update `cli_helpers` dependency to v2.15.1
|
|
25
|
+
* Update `click` to v8.4.2
|
|
26
|
+
* Update `cryptography` to v49.0.0
|
|
27
|
+
* Update `pygments` to v2.20.0
|
|
28
|
+
* Update `llm` to v0.31.1
|
|
29
|
+
* Update `setuptools` to v83.x
|
|
30
|
+
* Update `pip` to v26.1.2
|
|
31
|
+
* Update `pytest` to v9.1.1
|
|
32
|
+
* Add dependency cooldown period
|
|
33
|
+
* Exclude `cli_helpers` and `openai` from cooldown
|
|
34
|
+
* Update `sqlglot`/`sqlglotc` to v30.12.0
|
|
35
|
+
* Update `wcwidth` to v0.8.2
|
|
36
|
+
* Remove duplication in dev dependencies.
|
|
37
|
+
* Update `mypy` to v2.3.0.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
2.6.1 (2026/07/24)
|
|
41
|
+
==============
|
|
42
|
+
|
|
43
|
+
Features
|
|
44
|
+
---------
|
|
45
|
+
* Subcommand completions for the `/dsn` command.
|
|
46
|
+
* Allow file target of `$>` redirection to be quoted.
|
|
47
|
+
* Display of inline plots returned from `.|` operations.
|
|
48
|
+
* Don't attempt inline plots in the Windows console.
|
|
49
|
+
* Save plots, like parquets, with the `.>` operator.
|
|
50
|
+
* Display many native Python types returned from `.|` operations.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
Bug Fixes
|
|
54
|
+
---------
|
|
55
|
+
* Keep Vault username and password fields from being confused.
|
|
56
|
+
* Allow `\g` to terminate `.>` expressions.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
Documentation
|
|
60
|
+
---------
|
|
61
|
+
* `README.md` formatting.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
Internal
|
|
65
|
+
---------
|
|
66
|
+
* Sync test myclirc file closer to package myclirc file.
|
|
67
|
+
|
|
68
|
+
|
|
1
69
|
2.5.1 (2026/07/22)
|
|
2
70
|
==============
|
|
3
71
|
|
|
Binary file
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Transforms, Plots, and Parquets with Polars Dataframes
|
|
2
|
+
|
|
3
|
+
## Installing
|
|
4
|
+
|
|
5
|
+
Install mycli with dataframe support using:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install --upgrade 'mycli[dataframe]'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
or install these libraries separately:
|
|
12
|
+
|
|
13
|
+
* [`polars`](https://pypi.org/project/polars/)
|
|
14
|
+
* [`altair`](https://pypi.org/project/altair/)
|
|
15
|
+
* [`vl-convert-python`](https://pypi.org/project/vl-convert-python/)
|
|
16
|
+
|
|
17
|
+
## BETA STATUS
|
|
18
|
+
|
|
19
|
+
Dataframe transforms and plots are new and experimental. The interface and
|
|
20
|
+
functionality may still change.
|
|
21
|
+
|
|
22
|
+
Here are some known limitations:
|
|
23
|
+
|
|
24
|
+
* transforms can't be composed with `$|` shell redirection
|
|
25
|
+
* composing multiple transform operations is not supported
|
|
26
|
+
* results from `UNION`s may be unable to be transformed
|
|
27
|
+
|
|
28
|
+
And there are inherent limitations to the post-processing model: the entire
|
|
29
|
+
SQL result must be transferred from the server and loaded into local memory.
|
|
30
|
+
|
|
31
|
+
## Transforming
|
|
32
|
+
|
|
33
|
+
In the interactive REPL, append the `.|` operator and a Python expression to a
|
|
34
|
+
single SQL statement. The Python expression receives
|
|
35
|
+
|
|
36
|
+
* `df`, a Polars `DataFrame`
|
|
37
|
+
* `pl`, the Polars module
|
|
38
|
+
* `alt`, the Altair module
|
|
39
|
+
|
|
40
|
+
Spaces may be required around the `.|` operator.
|
|
41
|
+
|
|
42
|
+
Transform example:
|
|
43
|
+
|
|
44
|
+
```sql
|
|
45
|
+
SELECT * FROM orders .| df.group_by('customer_id').len();
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
which is equivalent to this native SQL:
|
|
49
|
+
|
|
50
|
+
```sql
|
|
51
|
+
SELECT customer_id, COUNT(1) AS len FROM orders GROUP BY customer_id;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Transform expressions run with normal Python privileges, and expressions
|
|
55
|
+
should not be run from untrusted sources.
|
|
56
|
+
|
|
57
|
+
If the transform operation returns a Polars `DataFrame` or `Series`, or a
|
|
58
|
+
Python type which can be rendered as a table, the result is rendered by mycli
|
|
59
|
+
as tabular output. `None` return values will be silently ignored, and other
|
|
60
|
+
return types will result in a warning message.
|
|
61
|
+
|
|
62
|
+
Transform expressions are useful for operations such as medians which
|
|
63
|
+
cannot be done (or are awkward) in SQL. Example:
|
|
64
|
+
|
|
65
|
+
```sql
|
|
66
|
+
SELECT * FROM orders .| df.describe();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Plotting
|
|
70
|
+
|
|
71
|
+
If the dataframe transform operation returns an Altair plot, the result can
|
|
72
|
+
be rendered as an inline PNG in many terminals.
|
|
73
|
+
|
|
74
|
+
Example:
|
|
75
|
+
|
|
76
|
+
```sql
|
|
77
|
+
SELECT * FROM orders .| df['total'].plot.hist();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
<img src="https://raw.githubusercontent.com/dbcli/mycli/main/doc/screenshots/total_histogram.png" height=400>
|
|
81
|
+
|
|
82
|
+
Image size, display protocol, and other properties can be configured in
|
|
83
|
+
the `[dataframe]` section of `~/.myclirc`.
|
|
84
|
+
|
|
85
|
+
## Saving
|
|
86
|
+
|
|
87
|
+
A query result, transformed `DataFrame`, or transformed `Series` can be
|
|
88
|
+
written directly to a Parquet file with the `.>` operator. An Altair plot can
|
|
89
|
+
also be written to a file with the same operator.
|
|
90
|
+
|
|
91
|
+
Save example:
|
|
92
|
+
|
|
93
|
+
```sql
|
|
94
|
+
SELECT * FROM orders .> orders.parquet;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The `.>` operator must be last, requires a `.parquet`, `.png`, `.pdf`, `.svg`,
|
|
98
|
+
or `.html` file extension on the destination, and overwrites any existing file.
|
|
99
|
+
|
|
100
|
+
Spaces may be required around the operator. Destination paths containing
|
|
101
|
+
whitespace must be quoted. A successful write reports its destination and row
|
|
102
|
+
count if appropriate.
|
|
103
|
+
|
|
104
|
+
When saving a plot, the format is deduced from the file extension.
|
|
105
|
+
|
|
106
|
+
When `post_redirect_command` is set in `~/.myclirc`, the given command runs
|
|
107
|
+
after a successful file save.
|
|
108
|
+
|
|
109
|
+
`.>` cannot be combined with the `\x` or `\G` special display terminators.
|
|
110
|
+
|
|
111
|
+
## Combining
|
|
112
|
+
|
|
113
|
+
Parquet saves may be combined with dataframe transforms. Again, the save
|
|
114
|
+
operator `.>` must be the last operator.
|
|
115
|
+
|
|
116
|
+
Combined transform and save examples:
|
|
117
|
+
|
|
118
|
+
```sql
|
|
119
|
+
SELECT * FROM orders .| df.group_by('customer_id').len() .> customer_counts.parquet;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```sql
|
|
123
|
+
SELECT * FROM orders .| df['order_id'] .> order_ids.parquet;
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```sql
|
|
127
|
+
SELECT * FROM orders .| df['total'].plot.hist() .> total_histogram.png;
|
|
128
|
+
```
|
|
@@ -144,6 +144,8 @@ display output in an interactive explorer \x at the end of a query!
|
|
|
144
144
|
|
|
145
145
|
run SQL scripts in batch mode using the standard input!
|
|
146
146
|
|
|
147
|
+
indexed columns are tagged with a "*" in completion menus!
|
|
148
|
+
|
|
147
149
|
###
|
|
148
150
|
### keystrokes
|
|
149
151
|
###
|
|
@@ -296,8 +298,16 @@ customize password sources/precedence with "password_sources" in ~/.myclirc!
|
|
|
296
298
|
|
|
297
299
|
redirect query output to a shell command with "$| <command>"!
|
|
298
300
|
|
|
299
|
-
redirect query output to a file with "$> <filename>"!
|
|
301
|
+
redirect query output to a CSV file with "$> <filename>"!
|
|
300
302
|
|
|
301
|
-
append query output to a file with "$>> <filename>"!
|
|
303
|
+
append query output to a CSV file with "$>> <filename>"!
|
|
302
304
|
|
|
303
305
|
run a command after shell redirects with "post_redirect_command" in ~/.myclirc!
|
|
306
|
+
|
|
307
|
+
###
|
|
308
|
+
### transforms
|
|
309
|
+
###
|
|
310
|
+
|
|
311
|
+
transform or plot query output with a dataframe using ".| df"!
|
|
312
|
+
|
|
313
|
+
save query output to a Parquet file with ".> output.parquet"!
|
|
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
6
6
|
from configobj import ConfigObj
|
|
7
7
|
|
|
8
8
|
from mycli.config import strip_matching_quotes
|
|
9
|
+
from mycli.types import ImageProtocol
|
|
9
10
|
|
|
10
11
|
if TYPE_CHECKING:
|
|
11
12
|
from mycli.client import MyCli
|
|
@@ -46,6 +47,16 @@ def normalize_ssl_mode(
|
|
|
46
47
|
return ssl_mode, error_notice
|
|
47
48
|
|
|
48
49
|
|
|
50
|
+
def normalize_image_protocol(image_protocol: str | None) -> tuple[ImageProtocol, str | None]:
|
|
51
|
+
if image_protocol == 'iterm2':
|
|
52
|
+
return 'iterm2', None
|
|
53
|
+
if image_protocol == 'kitty':
|
|
54
|
+
return 'kitty', None
|
|
55
|
+
if image_protocol in ('none', '', None):
|
|
56
|
+
return 'none', None
|
|
57
|
+
return 'none', f'Invalid config option provided for image_protocol ({image_protocol}); disabling.'
|
|
58
|
+
|
|
59
|
+
|
|
49
60
|
def configure_prompt_state(
|
|
50
61
|
mycli: MyCli,
|
|
51
62
|
config: ConfigObj,
|
|
@@ -384,13 +384,13 @@ def run_from_cli_args(cli_args: 'CliArgs', client_factory: ClientFactory) -> Non
|
|
|
384
384
|
vault_config = mycli.config.get('vault_beta', {})
|
|
385
385
|
vault_address = cli_args.vault_address or os.environ.get('VAULT_ADDR') or vault_config.get('address') or None
|
|
386
386
|
vault_mount = cli_args.vault_mount or vault_config.get('default_mount') or None
|
|
387
|
-
|
|
387
|
+
vault_password_field = cli_args.vault_password_field or vault_config.get('default_password_field') or DEFAULT_VAULT_PASSWORD_FIELD
|
|
388
388
|
vault_executable = vault_config.get('vault_executable') or DEFAULT_VAULT_EXECUTABLE
|
|
389
389
|
|
|
390
390
|
def load_vault_password() -> str | None:
|
|
391
391
|
try:
|
|
392
392
|
return get_field_from_vault(
|
|
393
|
-
|
|
393
|
+
vault_password_field,
|
|
394
394
|
vault_secret,
|
|
395
395
|
executable=vault_executable,
|
|
396
396
|
mount=vault_mount,
|
|
@@ -406,11 +406,11 @@ def run_from_cli_args(cli_args: 'CliArgs', client_factory: ClientFactory) -> Non
|
|
|
406
406
|
vault_config = mycli.config.get('vault_beta', {})
|
|
407
407
|
vault_address = cli_args.vault_address or os.environ.get('VAULT_ADDR') or vault_config.get('address') or None
|
|
408
408
|
vault_mount = cli_args.vault_mount or vault_config.get('default_mount') or None
|
|
409
|
-
|
|
409
|
+
vault_username_field = cli_args.vault_username_field or vault_config.get('default_username_field') or DEFAULT_VAULT_USERNAME_FIELD
|
|
410
410
|
vault_executable = vault_config.get('vault_executable') or DEFAULT_VAULT_EXECUTABLE
|
|
411
411
|
try:
|
|
412
412
|
vault_username = get_field_from_vault(
|
|
413
|
-
|
|
413
|
+
vault_username_field,
|
|
414
414
|
cli_args.vault_secret,
|
|
415
415
|
executable=vault_executable,
|
|
416
416
|
mount=vault_mount,
|
|
@@ -17,6 +17,7 @@ from mycli.app_state import (
|
|
|
17
17
|
configure_prompt_state,
|
|
18
18
|
destructive_keywords_from_config,
|
|
19
19
|
llm_prompt_truncation,
|
|
20
|
+
normalize_image_protocol,
|
|
20
21
|
normalize_ssl_mode,
|
|
21
22
|
)
|
|
22
23
|
from mycli.client_commands import ClientCommandsMixin
|
|
@@ -145,6 +146,12 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
145
146
|
self.null_string = c['main'].get('null_string')
|
|
146
147
|
self.numeric_alignment = c['main'].get('numeric_alignment', 'right') or 'right'
|
|
147
148
|
self.binary_display = c['main'].get('binary_display')
|
|
149
|
+
self.image_protocol, image_protocol_error = normalize_image_protocol(c['dataframe'].get('image_protocol'))
|
|
150
|
+
if image_protocol_error:
|
|
151
|
+
self.echo(image_protocol_error, err=True, fg='red')
|
|
152
|
+
self.plot_scale_factor = c['dataframe'].as_float('plot_scale_factor')
|
|
153
|
+
self.plot_ppi = c['dataframe'].as_int('plot_ppi')
|
|
154
|
+
self.plot_theme = c['dataframe'].get('plot_theme', 'carbong90') or 'carbong90'
|
|
148
155
|
self.llm_prompt_field_truncate, self.llm_prompt_section_truncate = llm_prompt_truncation(c)
|
|
149
156
|
|
|
150
157
|
self.ssl_mode, ssl_mode_error = normalize_ssl_mode(c, self.config_without_package_defaults)
|
|
@@ -176,6 +183,7 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
176
183
|
self.initialize_logging()
|
|
177
184
|
|
|
178
185
|
keyword_casing = c["main"].get("keyword_casing", "auto")
|
|
186
|
+
indexed_column_suffix = c['main'].get('indexed_column_suffix', '')
|
|
179
187
|
|
|
180
188
|
self.highlight_preview = c['search'].as_bool('highlight_preview')
|
|
181
189
|
|
|
@@ -184,7 +192,10 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
184
192
|
# Initialize completer.
|
|
185
193
|
self.smart_completion = c["main"].as_bool("smart_completion")
|
|
186
194
|
self.completer = SQLCompleter(
|
|
187
|
-
self.smart_completion,
|
|
195
|
+
self.smart_completion,
|
|
196
|
+
supported_formats=self.main_formatter.supported_formats,
|
|
197
|
+
keyword_casing=keyword_casing,
|
|
198
|
+
indexed_column_suffix=indexed_column_suffix,
|
|
188
199
|
)
|
|
189
200
|
self._completer_lock = threading.Lock()
|
|
190
201
|
|
|
@@ -52,6 +52,7 @@ class ClientQueryMixin:
|
|
|
52
52
|
"smart_completion": self.smart_completion,
|
|
53
53
|
"supported_formats": self.main_formatter.supported_formats,
|
|
54
54
|
"keyword_casing": self.completer.keyword_casing,
|
|
55
|
+
"indexed_column_suffix": self.completer.indexed_column_suffix,
|
|
55
56
|
},
|
|
56
57
|
)
|
|
57
58
|
|
|
@@ -15,6 +15,7 @@ logger = logging.getLogger(__name__)
|
|
|
15
15
|
TOKEN_TO_PROMPT_STYLE: dict[Token, str] = {
|
|
16
16
|
Token.Menu.Completions.Completion.Current: "completion-menu.completion.current",
|
|
17
17
|
Token.Menu.Completions.Completion: "completion-menu.completion",
|
|
18
|
+
Token.Menu.Completions.Completion.Indexed: "completion-menu.completion.indexed",
|
|
18
19
|
Token.Menu.Completions.Meta.Current: "completion-menu.meta.completion.current",
|
|
19
20
|
Token.Menu.Completions.Meta: "completion-menu.meta.completion",
|
|
20
21
|
Token.Menu.Completions.MultiColumnMeta: "completion-menu.multi-column-meta",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Platform and Python version compatibility support."""
|
|
2
|
+
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
WIN: bool = sys.platform in ("win32", "cygwin")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _is_win32() -> bool:
|
|
10
|
+
return sys.platform == 'win32'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def is_windows_console(output: object | None) -> bool:
|
|
14
|
+
"""Return whether output uses a native Windows console backend."""
|
|
15
|
+
if not _is_win32() or output is None:
|
|
16
|
+
return False
|
|
17
|
+
|
|
18
|
+
output_types = tuple(
|
|
19
|
+
getattr(import_module(module_name), class_name)
|
|
20
|
+
for module_name, class_name in (
|
|
21
|
+
('prompt_toolkit.output.conemu', 'ConEmuOutput'),
|
|
22
|
+
('prompt_toolkit.output.win32', 'Win32Output'),
|
|
23
|
+
('prompt_toolkit.output.windows10', 'Windows10_Output'),
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
return isinstance(output, output_types)
|
|
@@ -167,6 +167,11 @@ def refresh_tables(completer: SQLCompleter, executor: SQLExecute) -> None:
|
|
|
167
167
|
completer.extend_columns(table_columns_dbresult, kind="tables")
|
|
168
168
|
|
|
169
169
|
|
|
170
|
+
@refresher("indexed_columns")
|
|
171
|
+
def refresh_indexed_columns(completer: SQLCompleter, executor: SQLExecute) -> None:
|
|
172
|
+
completer.extend_indexed_columns(executor.indexed_columns())
|
|
173
|
+
|
|
174
|
+
|
|
170
175
|
@refresher("foreign_keys")
|
|
171
176
|
def refresh_foreign_keys(completer: SQLCompleter, executor: SQLExecute) -> None:
|
|
172
177
|
completer.extend_foreign_keys(executor.foreign_keys())
|
|
@@ -6,6 +6,8 @@ import sys
|
|
|
6
6
|
import urllib.error
|
|
7
7
|
import urllib.request
|
|
8
8
|
|
|
9
|
+
from tabulate import tabulate
|
|
10
|
+
|
|
9
11
|
from mycli.constants import REPO_URL
|
|
10
12
|
|
|
11
13
|
PYPI_API_BASE = 'https://pypi.org/pypi'
|
|
@@ -24,15 +26,20 @@ def pypi_api_fetch(fragment: str) -> dict:
|
|
|
24
26
|
|
|
25
27
|
def _dependencies_checkup() -> None:
|
|
26
28
|
print('\n### Key Python dependencies:\n')
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
29
|
+
table = []
|
|
30
|
+
for dependency, purpose in [
|
|
31
|
+
('cli_helpers', 'required'),
|
|
32
|
+
('click', 'required'),
|
|
33
|
+
('prompt_toolkit', 'required'),
|
|
34
|
+
('pygments', 'required'),
|
|
35
|
+
('pymysql', 'required'),
|
|
36
|
+
('sqlglot', 'required'),
|
|
37
|
+
('sqlglotc', 'required'),
|
|
38
|
+
('tabulate', 'required'),
|
|
39
|
+
('llm', 'optional for /llm command'),
|
|
40
|
+
('polars', 'optional for .| operator'),
|
|
41
|
+
('altair', 'optional for .| operator'),
|
|
42
|
+
('vl-convert-python', 'optional for .| operator'),
|
|
36
43
|
]:
|
|
37
44
|
try:
|
|
38
45
|
installed_version = importlib.metadata.version(dependency)
|
|
@@ -40,32 +47,38 @@ def _dependencies_checkup() -> None:
|
|
|
40
47
|
installed_version = None
|
|
41
48
|
pypi_profile = pypi_api_fetch(f'/{dependency}/json')
|
|
42
49
|
latest_version = pypi_profile.get('info', {}).get('version', None)
|
|
43
|
-
|
|
50
|
+
table.append([dependency, installed_version, latest_version, purpose])
|
|
51
|
+
print(tabulate(table, headers=['library', 'version', 'latest', 'purpose']))
|
|
44
52
|
|
|
45
53
|
|
|
46
54
|
def _executables_checkup() -> None:
|
|
47
55
|
print('\n### External executables:\n')
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
'
|
|
51
|
-
'
|
|
56
|
+
table = []
|
|
57
|
+
for executable, purpose in [
|
|
58
|
+
('less', 'required for paging'),
|
|
59
|
+
('fzf', r'optional for history search and \x'),
|
|
60
|
+
('pygmentize', 'optional for history search'),
|
|
52
61
|
]:
|
|
62
|
+
# executable, purpose = external
|
|
53
63
|
if shutil.which(executable):
|
|
54
|
-
|
|
64
|
+
table.append([executable, 'found', purpose])
|
|
55
65
|
else:
|
|
56
|
-
|
|
66
|
+
table.append([executable, 'MISSING', purpose])
|
|
67
|
+
print(tabulate(table, headers=['executable', 'status', 'purpose']))
|
|
57
68
|
|
|
58
69
|
|
|
59
70
|
def _environment_checkup() -> None:
|
|
60
71
|
print('\n### Environment variables:\n')
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
'
|
|
72
|
+
table = []
|
|
73
|
+
for variable, purpose in [
|
|
74
|
+
('EDITOR', r'optional for \edit and C-x C-e'),
|
|
75
|
+
('VISUAL', r'optional for \edit and C-x C-e'),
|
|
64
76
|
]:
|
|
65
77
|
if value := os.environ.get(variable):
|
|
66
|
-
|
|
78
|
+
table.append([f'${variable}', value, purpose])
|
|
67
79
|
else:
|
|
68
|
-
|
|
80
|
+
table.append([f'${variable}', 'UNSET', purpose])
|
|
81
|
+
print(tabulate(table, headers=['variable', 'setting', 'purpose']))
|
|
69
82
|
|
|
70
83
|
|
|
71
84
|
def _configuration_checkup(mycli) -> None:
|
|
@@ -112,7 +112,7 @@ def complete_while_typing_filter() -> bool:
|
|
|
112
112
|
return True
|
|
113
113
|
app = get_app()
|
|
114
114
|
text = app.current_buffer.text.lstrip()
|
|
115
|
-
if text.startswith('/') and not text.startswith('/*'):
|
|
115
|
+
if text.startswith('/') and not text.startswith('/*') and ' ' not in text:
|
|
116
116
|
return True
|
|
117
117
|
text_len = len(text)
|
|
118
118
|
if text_len < MIN_COMPLETION_TRIGGER:
|
|
@@ -750,20 +750,35 @@ def _one_iteration(
|
|
|
750
750
|
mycli.explorer_formatter.query = text
|
|
751
751
|
if polars_transform is not None:
|
|
752
752
|
assert polars_pipeline is not None
|
|
753
|
-
if polars_pipeline.
|
|
754
|
-
polars_result = run_polars_transform(
|
|
753
|
+
if polars_pipeline.output_path is None:
|
|
754
|
+
polars_result = run_polars_transform(
|
|
755
|
+
polars_transform,
|
|
756
|
+
results,
|
|
757
|
+
image_protocol=mycli.image_protocol,
|
|
758
|
+
plot_scale_factor=mycli.plot_scale_factor,
|
|
759
|
+
plot_ppi=mycli.plot_ppi,
|
|
760
|
+
plot_theme=mycli.plot_theme,
|
|
761
|
+
)
|
|
755
762
|
else:
|
|
756
|
-
polars_result = run_polars_transform(
|
|
757
|
-
|
|
763
|
+
polars_result = run_polars_transform(
|
|
764
|
+
polars_transform,
|
|
765
|
+
results,
|
|
766
|
+
polars_pipeline.output_path,
|
|
767
|
+
image_protocol=mycli.image_protocol,
|
|
768
|
+
plot_scale_factor=mycli.plot_scale_factor,
|
|
769
|
+
plot_ppi=mycli.plot_ppi,
|
|
770
|
+
plot_theme=mycli.plot_theme,
|
|
771
|
+
)
|
|
772
|
+
if polars_pipeline.output_path is None:
|
|
758
773
|
if polars_pipeline.output_mode == 'explorer':
|
|
759
774
|
special.set_explorer_output(True)
|
|
760
775
|
elif polars_pipeline.output_mode == 'expanded':
|
|
761
776
|
special.set_expanded_output(True)
|
|
762
777
|
_output_results(mycli, state, iter([polars_result]), start)
|
|
763
|
-
if polars_pipeline.
|
|
778
|
+
if polars_pipeline.output_path is not None:
|
|
764
779
|
special.run_post_redirect_hook(
|
|
765
780
|
mycli.post_redirect_command,
|
|
766
|
-
polars_pipeline.
|
|
781
|
+
polars_pipeline.output_path,
|
|
767
782
|
)
|
|
768
783
|
else:
|
|
769
784
|
_output_results(mycli, state, results, start)
|