Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4fc6961

Browse files
committed
fix: synchronize cursor position by fetch hardware info
1 parenta383dc6 commit4fc6961

File tree

5 files changed

+44
-141
lines changed

5 files changed

+44
-141
lines changed

‎Lib/_pyrepl/console.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ def restore(self) -> None: ...
8383
defmove_cursor(self,x:int,y:int)->None: ...
8484

8585
@abstractmethod
86-
defsync_screen(self)->None: ...
86+
defsync_cursor(self)->None: ...
87+
88+
@abstractmethod
89+
defsync_screen_size(self)->None: ...
8790

8891
@abstractmethod
8992
defset_cursor_vis(self,visible:bool)->None: ...

‎Lib/_pyrepl/reader.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,9 @@ def handle1(self, block: bool = True) -> bool:
716716
elifevent.evt=="scroll":
717717
self.refresh()
718718
elifevent.evt=="resize":
719+
self.console.sync_screen_size()
720+
self.console.sync_cursor()
721+
self.console.clear()
719722
self.refresh()
720723
else:
721724
translate=False

‎Lib/_pyrepl/unix_console.py

Lines changed: 21 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,9 @@ def refresh(self, screen, c_xy):
271271
self.posxy=0,old_offset
272272
foriinrange(old_offset-offset):
273273
self.__write_code(self._ri)
274-
oldscr.pop(-1)
275274
oldscr.insert(0,"")
275+
iflen(oldscr)>height:
276+
oldscr.pop(-1)
276277
elifold_offset<offsetandself._ind:
277278
self.__hide_cursor()
278279
self.__write_code(self._cup,self.height-1,0)
@@ -321,78 +322,28 @@ def move_cursor(self, x, y):
321322
self.posxy=x,y
322323
self.flushoutput()
323324

324-
defsync_screen(self):
325+
defsync_cursor(self):
325326
"""
326-
Synchronize self.posxy, self.screen, self.width and self.height.
327-
Assuming that the content of the screen doesn't change, only the width changes.
327+
Synchronize posxy after resizing.
328328
"""
329-
ifnotself.screen:
330-
self.posxy=0,0
331-
return
329+
os.write(self.output_fd,b"\x1b[6n")
330+
response=b""
331+
whileTrue:
332+
ch=os.read(self.input_fd,1)
333+
response+=ch
334+
ifch==b'R':
335+
break
336+
m=re.match(rb"\x1b\[(\d+);(\d+)R",response)
337+
ifm:
338+
row,col=map(int,m.groups())
339+
cur_x,cur_y=col-1,row-1
340+
self.posxy=cur_x,cur_y+self.__offset
332341

333-
px,py=self.posxy
334-
old_height,old_width=self.height,self.width
335-
new_height,new_width=self.getheightwidth()
336-
337-
vlines= []
338-
x,y=0,0
339-
new_line=True
340-
fori,lineinenumerate(self.screen):
341-
l=wlen(line)
342-
ifi==py:
343-
ifnew_line:
344-
y=sum(wlen(g)//new_widthforginvlines)+len(vlines)
345-
x=px
346-
else:
347-
y=sum(wlen(g)//new_widthforginvlines[:-1])+len(vlines)-1
348-
x=px+wlen(vlines[-1])
349-
ifx>=new_width:
350-
y+=x//new_width
351-
x%=new_width
352-
353-
ifnew_line:
354-
vlines.append(line)
355-
new_line=False
356-
else:
357-
vlines[-1]+=line
358-
ifl!=old_width:
359-
new_line=True
360-
361-
new_screen= []
362-
forvlineinvlines:
363-
parts= []
364-
last_end=0
365-
formatchinANSI_ESCAPE_SEQUENCE.finditer(vline):
366-
ifmatch.start()>last_end:
367-
parts.append((vline[last_end:match.start()],False))
368-
parts.append((match.group(),True))
369-
last_end=match.end()
370-
371-
iflast_end<len(vline):
372-
parts.append((vline[last_end:],False))
373-
374-
result=""
375-
length=0
376-
forpart,is_escapeinparts:
377-
ifis_escape:
378-
result+=part
379-
continue
380-
forcharinpart:
381-
lc=wlen(char)
382-
iflc+length>new_width:
383-
# save the current line
384-
new_screen.append(result)
385-
result=""
386-
length=0
387-
result+=char
388-
length+=lc
389-
390-
ifresult:
391-
new_screen.append(result)
392-
393-
self.posxy=x,y
394-
self.screen=new_screen
395-
self.height,self.width=new_height,new_width
342+
defsync_screen_size(self):
343+
"""
344+
Synchronize screen size after resizing.
345+
"""
346+
self.height,self.width=self.getheightwidth()
396347

397348
defprepare(self):
398349
"""

‎Lib/_pyrepl/windows_console.py

Lines changed: 12 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -395,78 +395,21 @@ def move_cursor(self, x: int, y: int) -> None:
395395
self._move_relative(x,y)
396396
self.posxy=x,y
397397

398-
defsync_screen(self):
398+
defsync_cursor(self):
399399
"""
400-
Synchronize self.posxy, self.screen, self.width and self.height.
401-
Assuming that the content of the screen doesn't change, only the width changes.
400+
Synchronize posxy after resizing.
402401
"""
403-
ifnotself.screen:
404-
self.posxy=0,0
405-
return
402+
info=CONSOLE_SCREEN_BUFFER_INFO()
403+
ifnotGetConsoleScreenBufferInfo(OutHandle,info):
404+
raiseWinError(GetLastError())
405+
cur_x,cur_y=info.dwCursorPosition.X,info.dwCursorPosition.Y
406+
self.posxy=cur_x,cur_y+self.__offset
406407

407-
px,py=self.posxy
408-
old_height,old_width=self.height,self.width
409-
new_height,new_width=self.getheightwidth()
410-
411-
vlines= []
412-
x,y=0,0
413-
new_line=True
414-
fori,lineinenumerate(self.screen):
415-
l=wlen(line)
416-
ifi==py:
417-
ifnew_line:
418-
y=sum(wlen(g)//new_widthforginvlines)+len(vlines)
419-
x=px
420-
else:
421-
y=sum(wlen(g)//new_widthforginvlines[:-1])+len(vlines)-1
422-
x=px+wlen(vlines[-1])
423-
ifx>=new_width:
424-
y+=x//new_width
425-
x%=new_width
426-
427-
ifnew_line:
428-
vlines.append(line)
429-
new_line=False
430-
else:
431-
vlines[-1]+=line
432-
ifl!=old_width:
433-
new_line=True
434-
435-
new_screen= []
436-
forvlineinvlines:
437-
parts= []
438-
last_end=0
439-
formatchinANSI_ESCAPE_SEQUENCE.finditer(vline):
440-
ifmatch.start()>last_end:
441-
parts.append((vline[last_end:match.start()],False))
442-
parts.append((match.group(),True))
443-
last_end=match.end()
444-
445-
iflast_end<len(vline):
446-
parts.append((vline[last_end:],False))
447-
448-
result=""
449-
length=0
450-
forpart,is_escapeinparts:
451-
ifis_escape:
452-
result+=part
453-
continue
454-
forcharinpart:
455-
lc=wlen(char)
456-
iflc+length>new_width:
457-
# save the current line
458-
new_screen.append(result)
459-
result=""
460-
length=0
461-
result+=char
462-
length+=lc
463-
464-
ifresult:
465-
new_screen.append(result)
466-
467-
self.posxy=x,y
468-
self.screen=new_screen
469-
self.height,self.width=new_height,new_width
408+
defsync_screen_size(self):
409+
"""
410+
Synchronize screen size after resizing.
411+
"""
412+
self.height,self.width=self.getheightwidth()
470413

471414
defset_cursor_vis(self,visible:bool)->None:
472415
ifvisible:

‎Lib/test/test_pyrepl/support.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ def restore(self) -> None:
143143
defmove_cursor(self,x:int,y:int)->None:
144144
pass
145145

146-
defsync_screen(self)->None:
146+
defsync_cursor(self)->None:
147+
pass
148+
149+
defsync_screen_size(self)->None:
147150
pass
148151

149152
defset_cursor_vis(self,visible:bool)->None:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp