Browse Source

feat(TTkTerminal): add getBuffer (#496)

pull/499/head
Pier CeccoPierangioliEugenio 5 months ago committed by GitHub
parent
commit
997d0f6d72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      libs/pyTermTk/TermTk/TTkCore/canvas.py
  2. 19
      libs/pyTermTk/TermTk/TTkWidgets/TTkTerminal/terminal.py
  3. 21
      libs/pyTermTk/TermTk/TTkWidgets/TTkTerminal/terminal_screen.py
  4. 15
      libs/pyTermTk/TermTk/TTkWidgets/TTkTerminal/terminalview.py
  5. 110
      tests/t.pty/test.pty.006.terminal.08.getBuffer.py

4
libs/pyTermTk/TermTk/TTkCore/canvas.py

@ -22,6 +22,8 @@
__all__ = ['TTkCanvas']
from typing import Tuple
from TermTk.TTkCore.TTkTerm.term import TTkTerm
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.log import TTkLog
@ -90,7 +92,7 @@ class TTkCanvas():
self._height = h
self._width = w
def size(self):
def size(self) -> Tuple[int,int]:
return (self._width, self._height)
def resize(self, w, h):

19
libs/pyTermTk/TermTk/TTkWidgets/TTkTerminal/terminal.py

@ -22,7 +22,10 @@
__all__ = ['TTkTerminal']
from typing import List
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea, _ForwardData
from TermTk.TTkWidgets.TTkTerminal.terminalview import TTkTerminalView
@ -40,7 +43,7 @@ class TTkTerminal(TTkAbstractScrollArea):
'bell', 'titleChanged', 'terminalClosed', 'textSelected',
'termData', 'termResized'],
methods=[# Forwarded Methods From TTkTreeWidget
'termWrite', 'termSize']
'termWrite', 'termSize', 'getBuffer']
)
__slots__ = ('_terminalView')
@ -145,4 +148,18 @@ class TTkTerminal(TTkAbstractScrollArea):
:rtype: tuple
'''
return self._terminalView.termSize()
def getBuffer(self) -> List[TTkString]:
'''
.. seealso:: this method is forwarded to :py:meth:`TTkTerminalView.getBuffer`
Get the terminal buffer contents.
This method returns the complete terminal buffer, including both the
scrollback buffer (buffered lines) and the currently visible screen content.
:return: A list of TTkString objects representing all lines in the terminal buffer.
The list includes the scrollback history followed by the visible screen lines.
:rtype: List[TTkString]
'''
return self._terminalView.getBuffer()
#--FORWARD-AUTOGEN-END--#

21
libs/pyTermTk/TermTk/TTkWidgets/TTkTerminal/terminal_screen.py

@ -1,4 +1,4 @@
# MIT License
1 # MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
@ -26,6 +26,8 @@ import collections
import unicodedata
from dataclasses import dataclass
from typing import List
from TermTk.TTkCore.canvas import TTkCanvas
from TermTk.TTkCore.color import TTkColor
@ -253,6 +255,23 @@ class _TTkTerminalScreen(_TTkTerminalScreen_CSI, _TTkTerminalScreen_C1):
# Convert x/y in line/pos
self._selectCursor.select(x,y,moveAnchor)
def getBuffer(self) -> List[TTkString]:
w,h = self._canvas.size()
ret:List[TTkString] = list(self._bufferedLines)
for y in range(h):
nl = self._canvasNewLine[y]
ls = self._canvasLineSize[y]
data = self._canvas._data[y][:ls]
colors = self._canvas._colors[y][:ls]
line = TTkString._importString1("".join(data),colors)
if nl and ret:
ret[-1] += line
else:
ret.append(line)
while ret and not len(ret[-1]):
ret.pop()
return ret
def getSelected(self):
if not self._selectCursor.hasSelection():
return ""

15
libs/pyTermTk/TermTk/TTkWidgets/TTkTerminal/terminalview.py

@ -24,6 +24,8 @@ __all__ = ['TTkTerminalView']
import re
from typing import List
from dataclasses import dataclass
from TermTk.TTkCore.canvas import TTkCanvas
@ -309,6 +311,19 @@ class TTkTerminalView(TTkAbstractScrollView, _TTkTerminal_CSI_DEC):
if data:
self._termLoop.send(data)
def getBuffer(self) -> List[TTkString]:
'''
Get the terminal buffer contents.
This method returns the complete terminal buffer, including both the
scrollback buffer (buffered lines) and the currently visible screen content.
:return: A list of TTkString objects representing all lines in the terminal buffer.
The list includes the scrollback history followed by the visible screen lines.
:rtype: List[TTkString]
'''
return self._screen_current.getBuffer()
def _loopGenerator(self):
def _checkSize():
if self._newSize:

110
tests/t.pty/test.pty.006.terminal.08.getBuffer.py

@ -0,0 +1,110 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the"Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import os, sys, argparse
from select import select
sys.path.append(os.path.join(sys.path[0],'../..'))
import TermTk as ttk
parser = argparse.ArgumentParser()
parser.add_argument('-d', help='Debug (Add LogViewer Panel)', action='store_true')
args = parser.parse_args()
# ttk.TTkLog.use_default_file_logging()
root = ttk.TTk(layout=ttk.TTkGridLayout(), mouseTrack=True)
split = ttk.TTkSplitter(parent=root, orientation=ttk.TTkK.VERTICAL)
split.addItem(top := ttk.TTkLayout())
if args.d:
split.addWidget(ttk.TTkLogViewer(follow=False ), title='Log', size=20)
quitBtn = ttk.TTkButton(text="QUIT", border=True)
quitBtn.clicked.connect(ttk.TTkHelper.quit)
cb_c = ttk.TTkCheckbox(pos=(0,3),size=(20,1), text="CTRL-C (VINTR) ", checked=ttk.TTkK.Checked)
cb_s = ttk.TTkCheckbox(pos=(0,4),size=(20,1), text="CTRL-S (VSTOP) ", checked=ttk.TTkK.Checked)
cb_z = ttk.TTkCheckbox(pos=(0,5),size=(20,1), text="CTRL-Z (VSUSP) ", checked=ttk.TTkK.Checked)
cb_q = ttk.TTkCheckbox(pos=(0,6),size=(20,1), text="CTRL-Q (VSTART)", checked=ttk.TTkK.Checked)
cb_c.stateChanged.connect(lambda x: ttk.TTkTerm.setSigmask(ttk.TTkTerm.Sigmask.CTRL_C,x==ttk.TTkK.Checked))
cb_s.stateChanged.connect(lambda x: ttk.TTkTerm.setSigmask(ttk.TTkTerm.Sigmask.CTRL_S,x==ttk.TTkK.Checked))
cb_z.stateChanged.connect(lambda x: ttk.TTkTerm.setSigmask(ttk.TTkTerm.Sigmask.CTRL_Z,x==ttk.TTkK.Checked))
cb_q.stateChanged.connect(lambda x: ttk.TTkTerm.setSigmask(ttk.TTkTerm.Sigmask.CTRL_Q,x==ttk.TTkK.Checked))
winT = ttk.TTkWindow(pos=(20,10), size=(100,30), title="TextEdit", border=True, layout=ttk.TTkVBoxLayout(), flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint|ttk.TTkK.WindowFlag.WindowCloseButtonHint)
te = ttk.TTkTextEdit(parent=winT, readOnly=False, lineNumber=True)
clipboard = ttk.TTkClipboard()
@ttk.pyTTkSlot(ttk.TTkString)
def _textSelected(text, te=te):
te.setText("Selected Text in the terminal:")
te.append( "------------------------------\n")
te.append(text)
tnum = 0
@ttk.pyTTkSlot()
def _addTerminal() -> ttk.TTkTerminal:
global tnum
tnum+=1
win = ttk.TTkWindow(pos=(12,0), size=(100,30), title=f"Terminallo n.{tnum}", border=True, layout=ttk.TTkVBoxLayout(), flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint|ttk.TTkK.WindowFlag.WindowCloseButtonHint)
term = ttk.TTkTerminal(parent=win)
th = ttk.TTkTerminalHelper(term=term)
th.terminalClosed.connect(win.close)
term.bell.connect(lambda : ttk.TTkLog.debug("BELL!!! 🔔🔔🔔"))
term.titleChanged.connect(win.setTitle)
term.textSelected.connect(clipboard.setText)
term.textSelected.connect(_textSelected)
win.closed.connect(term.close)
top.addWidget(win)
term.setFocus()
term.raiseWidget()
th.runShell()
return term
btn_gb = ttk.TTkButton(pos=(0,8), text="Get Buffer", border=True)
top.addWidgets([quitBtn, btn_gb, cb_c, cb_s, cb_z, cb_q, winT])
term = _addTerminal()
@ttk.pyTTkSlot()
def _getBuffer():
buffer = term.getBuffer()
text = ttk.TTkString('\n').join(buffer)
te.setText("Selected Text in the terminal:")
te.append( "------------------------------\n")
te.append(text)
btn_gb.clicked.connect(_getBuffer)
root.mainloop()
Loading…
Cancel
Save