1111from prompt_toolkit .application .run_in_terminal import run_in_terminal
1212from prompt_toolkit .data_structures import Size
1313from prompt_toolkit .formatted_text import AnyFormattedText , to_formatted_text
14- from prompt_toolkit .input . posix_pipe import PosixPipeInput
14+ from prompt_toolkit .input import create_pipe_input
1515from prompt_toolkit .output .vt100 import Vt100_Output
1616from prompt_toolkit .renderer import print_formatted_text as print_formatted_text
1717from prompt_toolkit .styles import BaseStyle , DummyStyle
2828 SE ,
2929 SUPPRESS_GO_AHEAD ,
3030 WILL ,
31+ TTYPE ,
32+ SEND ,
3133 TelnetProtocolParser ,
3234)
3335
@@ -59,6 +61,12 @@ def _initialize_telnet(connection: socket.socket) -> None:
5961 # Negotiate window size
6062 connection .send (IAC + DO + NAWS )
6163
64+ # Negotiate terminal type
65+ connection .send (IAC + DO + TTYPE )
66+
67+ # Negotiate terminal type
68+ connection .send (IAC + SB + TTYPE + SEND + IAC + SE )
69+
6270
6371class _ConnectionStdout :
6472 """
@@ -115,6 +123,7 @@ def __init__(
115123 self .encoding = encoding
116124 self .style = style
117125 self ._closed = False
126+ self ._ready = asyncio .Event ()
118127
119128 # Create "Output" object.
120129 self .size = Size (rows = 40 , columns = 79 )
@@ -123,14 +132,14 @@ def __init__(
123132 _initialize_telnet (conn )
124133
125134 # Create input.
126- self .vt100_input = PosixPipeInput ()
135+ self .vt100_output = None
136+ self .vt100_input = create_pipe_input ()
127137
128138 # Create output.
129139 def get_size () -> Size :
130140 return self .size
131141
132142 self .stdout = cast (TextIO , _ConnectionStdout (conn , encoding = encoding ))
133- self .vt100_output = Vt100_Output (self .stdout , get_size , write_binary = False )
134143
135144 def data_received (data : bytes ) -> None :
136145 """ TelnetProtocolParser 'data_received' callback """
@@ -139,9 +148,17 @@ def data_received(data: bytes) -> None:
139148 def size_received (rows : int , columns : int ) -> None :
140149 """ TelnetProtocolParser 'size_received' callback """
141150 self .size = Size (rows = rows , columns = columns )
142- get_app ()._on_resize ()
151+ if self .vt100_output is not None :
152+ get_app ()._on_resize ()
153+
154+ def ttype_received (ttype : str ) -> None :
155+ """ TelnetProtocolParser 'ttype_received' callback """
156+ self .vt100_output = Vt100_Output (
157+ self .stdout , get_size , term = ttype , write_binary = False
158+ )
159+ self ._ready .set ()
143160
144- self .parser = TelnetProtocolParser (data_received , size_received )
161+ self .parser = TelnetProtocolParser (data_received , size_received , ttype_received )
145162 self .context : Optional [contextvars .Context ] = None
146163
147164 async def run_application (self ) -> None :
@@ -158,25 +175,24 @@ def handle_incoming_data() -> None:
158175 logger .info ("Connection closed by client. %r %r" % self .addr )
159176 self .close ()
160177
161- async def run () -> None :
162- # Add reader.
163- loop = get_event_loop ()
164- loop .add_reader (self .conn , handle_incoming_data )
178+ # Add reader.
179+ loop = get_event_loop ()
180+ loop .add_reader (self .conn , handle_incoming_data )
165181
166- try :
182+ try :
183+ # Wait for v100_output to be properly instantiated
184+ await self ._ready .wait ()
185+ with create_app_session (input = self .vt100_input , output = self .vt100_output ):
186+ self .context = contextvars .copy_context ()
167187 await self .interact (self )
168- except Exception as e :
169- print ("Got %s" % type (e ).__name__ , e )
170- import traceback
171-
172- traceback .print_exc ()
173- raise
174- finally :
175- self .close ()
176-
177- with create_app_session (input = self .vt100_input , output = self .vt100_output ):
178- self .context = contextvars .copy_context ()
179- await run ()
188+ except Exception as e :
189+ print ("Got %s" % type (e ).__name__ , e )
190+ import traceback
191+
192+ traceback .print_exc ()
193+ raise
194+ finally :
195+ self .close ()
180196
181197 def feed (self , data : bytes ) -> None :
182198 """
0 commit comments