Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 42 additions & 7 deletions addon/globalPlugins/virtualRevision.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,48 @@
except:
SCRCAT_TEXTREVIEW = None

def _isTermControl(obj):
return hasattr(obj, "UIAElement") and obj.UIAElement and obj.UIAElement.currentClassName == "TermControl"

def _isDecorativeTerminalLine(line):
# True for lines whose only non-whitespace characters are in the Unicode Box Drawing
# block (U+2500-U+257F): the borders, separators, and corners that TUI apps such as
# Claude Code paint. Content lines that happen to contain a "│" border still survive
# because the letters/digits inside fall outside the range.
stripped = line.strip()
if not stripped:
return True
return all("─" <= ch <= "╿" for ch in stripped)

def _cleanTerminalText(text):
# Terminal cells are space-padded to the column width, and TUI apps reserve fixed
# rows/columns for borders, status, input, etc. Captured as a UNIT_STORY this turns
# into long runs of blank padding and box-border-only lines that bury the actual
# content when navigated line-by-line in the review window. Strip per-line trailing
# whitespace and drop lines that carry no real content.
lines = []
for line in text.split("\n"):
stripped = line.rstrip()
if _isDecorativeTerminalLine(stripped):
continue
lines.append(stripped)
return "\n".join(lines)

def obtainUWPWindowText():
foreground = api.getForegroundObject()
desktop = api.getDesktopObject()
uwpTextList = [foreground.name]
termTextList = []
hasTerm = _isTermControl(foreground)
curObject=foreground.firstChild
while curObject:
if curObject.name is not None: uwpTextList.append(curObject.name)
if hasattr(curObject, "UIAElement") and curObject.UIAElement and curObject.UIAElement.currentClassName == "TermControl":
if _isTermControl(curObject):
hasTerm = True
info = curObject.makeTextInfo(textInfos.POSITION_FIRST)
info.expand(textInfos.UNIT_STORY)
text = info.clipboardText.rstrip()
uwpTextList.append(text)
termTextList.append(_cleanTerminalText(info.clipboardText))
elif curObject.name is not None:
uwpTextList.append(curObject.name)
if curObject.simpleFirstChild:
curObject=curObject.simpleFirstChild
continue
Expand All @@ -49,11 +79,16 @@ def obtainUWPWindowText():
curObject=parent.simpleNext
except AttributeError:
continue
if hasattr(foreground, "UIAElement") and foreground.UIAElement and foreground.UIAElement.currentClassName == "TermControl":
if _isTermControl(foreground):
hasTerm = True
info = foreground.makeTextInfo(textInfos.POSITION_FIRST)
info.expand(textInfos.UNIT_STORY)
text = info.clipboardText.rstrip()
uwpTextList.append(text)
termTextList.append(_cleanTerminalText(info.clipboardText))
# For terminal-hosted windows (e.g. cmd.exe inside Windows Terminal), the child walk
# also picks up the duplicated title, scroll-bar parts, "Close Tab" and "System" menu.
# Suppress that chrome and return only the title plus the actual terminal text.
if hasTerm:
return [foreground.name] + termTextList
return uwpTextList

class GlobalPlugin(globalPluginHandler.GlobalPlugin):
Expand Down