1414import sys
1515import threading
1616import traceback
17- from typing import IO , Any , Callable , Generator , Iterable , Literal
17+ from typing import IO , Any , Generator , Iterable , Literal
1818
1919try :
2020 from pwd import getpwuid
5050 to_formatted_text ,
5151 to_plain_text ,
5252)
53- from prompt_toolkit .key_binding .bindings .named_commands import register as prompt_register
54- from prompt_toolkit .key_binding .key_processor import KeyPressEvent
5553from prompt_toolkit .layout .processors import ConditionalProcessor , HighlightMatchingBracketProcessor
5654from prompt_toolkit .lexers import PygmentsLexer
5755from prompt_toolkit .output import ColorDepth
6058from pymysql .constants .CR import CR_SERVER_LOST
6159from pymysql .constants .ER import ACCESS_DENIED_ERROR , HANDSHAKE_ERROR
6260from pymysql .cursors import Cursor
63- import sqlglot
6461import sqlparse
6562
6663from mycli import __version__
9390from mycli .packages .cli_utils import filtered_sys_argv , is_valid_connection_scheme
9491from mycli .packages .filepaths import dir_path_exists , guess_socket_location
9592from mycli .packages .hybrid_redirection import get_redirect_components , is_redirect_command
93+ from mycli .packages .key_binding_utils import (
94+ handle_clip_command ,
95+ handle_editor_command ,
96+ )
9697from mycli .packages .prompt_utils import confirm , confirm_destructive_query
9798from mycli .packages .ptoolkit .history import FileHistoryWithTimestamp
9899from mycli .packages .special .favoritequeries import FavoriteQueries
@@ -871,99 +872,6 @@ def _connect(
871872 self .echo (str (e ), err = True , fg = "red" )
872873 sys .exit (1 )
873874
874- def handle_editor_command (
875- self ,
876- text : str ,
877- inputhook : Callable | None ,
878- loaded_message_fn : Callable ,
879- ) -> str :
880- r"""Editor command is any query that is prefixed or suffixed by a '\e'.
881- The reason for a while loop is because a user might edit a query
882- multiple times. For eg:
883-
884- "select * from \e"<enter> to edit it in vim, then come
885- back to the prompt with the edited query "select * from
886- blah where q = 'abc'\e" to edit it again.
887- :param text: Document
888- :return: Document
889-
890- """
891-
892- while special .editor_command (text ):
893- filename = special .get_filename (text )
894- query = special .get_editor_query (text ) or self .get_last_query ()
895- sql , message = special .open_external_editor (filename = filename , sql = query )
896- if message :
897- # Something went wrong. Raise an exception and bail.
898- raise RuntimeError (message )
899- while True :
900- try :
901- assert isinstance (self .prompt_app , PromptSession )
902- text = self .prompt_app .prompt (
903- default = sql ,
904- inputhook = inputhook ,
905- message = loaded_message_fn ,
906- )
907- break
908- except KeyboardInterrupt :
909- sql = ""
910-
911- continue
912- return text
913-
914- def handle_clip_command (self , text : str ) -> bool :
915- r"""A clip command is any query that is prefixed or suffixed by a
916- '\clip'.
917-
918- :param text: Document
919- :return: Boolean
920-
921- """
922-
923- if special .clip_command (text ):
924- query = special .get_clip_query (text ) or self .get_last_query ()
925- message = special .copy_query_to_clipboard (sql = query )
926- if message :
927- raise RuntimeError (message )
928- return True
929- return False
930-
931- def handle_prettify_binding (self , text : str ) -> str :
932- if not text :
933- return ''
934- try :
935- statements = sqlglot .parse (text , read = 'mysql' )
936- except Exception :
937- statements = []
938- if len (statements ) == 1 and statements [0 ]:
939- parse_succeeded = True
940- pretty_text = statements [0 ].sql (pretty = True , pad = 4 , dialect = 'mysql' )
941- else :
942- parse_succeeded = False
943- pretty_text = text .rstrip (';' )
944- self .toolbar_error_message = 'Prettify failed to parse single statement'
945- if pretty_text and parse_succeeded :
946- pretty_text = pretty_text + ';'
947- return pretty_text
948-
949- def handle_unprettify_binding (self , text : str ) -> str :
950- if not text :
951- return ''
952- try :
953- statements = sqlglot .parse (text , read = 'mysql' )
954- except Exception :
955- statements = []
956- if len (statements ) == 1 and statements [0 ]:
957- parse_succeeded = True
958- unpretty_text = statements [0 ].sql (pretty = False , dialect = 'mysql' )
959- else :
960- parse_succeeded = False
961- unpretty_text = text .rstrip (';' )
962- self .toolbar_error_message = 'Unprettify failed to parse single statement'
963- if unpretty_text and parse_succeeded :
964- unpretty_text = unpretty_text + ';'
965- return unpretty_text
966-
967875 def output_timing (self , timing : str , is_warnings_style : bool = False ) -> None :
968876 self .log_output (timing )
969877 add_style = 'class:warnings.timing' if is_warnings_style else 'class:output.timing'
@@ -1168,7 +1076,8 @@ def one_iteration(text: str | None = None) -> None:
11681076 special .set_forced_horizontal_output (False )
11691077
11701078 try :
1171- text = self .handle_editor_command (
1079+ text = handle_editor_command (
1080+ self ,
11721081 text ,
11731082 inputhook ,
11741083 loaded_message_fn ,
@@ -1180,7 +1089,7 @@ def one_iteration(text: str | None = None) -> None:
11801089 return
11811090
11821091 try :
1183- if self . handle_clip_command (text ):
1092+ if handle_clip_command (self , text ):
11841093 return
11851094 except RuntimeError as e :
11861095 logger .error ("sql: %r, error: %r" , text , e )
@@ -2698,14 +2607,6 @@ def tips_picker() -> str:
26982607 return choice (tips ) if tips else r'\? or "help" for help!'
26992608
27002609
2701- @prompt_register ("edit-and-execute-command" )
2702- def edit_and_execute (event : KeyPressEvent ) -> None :
2703- """Different from the prompt-toolkit default, we want to have a choice not
2704- to execute a query after editing, hence validate_and_handle=False."""
2705- buff = event .current_buffer
2706- buff .open_in_editor (validate_and_handle = False )
2707-
2708-
27092610def main () -> int | None :
27102611 try :
27112612 result = click_entrypoint .main (
0 commit comments