aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-cli/src/meshbay_cli/tui/app.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-15 09:33:28 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-15 09:33:28 +0200
commit5044bdfdfffceceecc0d92a776983ad361079839 (patch)
tree4a80ab66ef53f9ba76cdf8db4276dfc07d0fc1f7 /packages/meshbay-cli/src/meshbay_cli/tui/app.py
parent1e8eae1f3de765fcd8163716de6e5fe5aab5a034 (diff)
downloadmeshbay-5044bdfdfffceceecc0d92a776983ad361079839.tar.gz
feat(cli): help, and right-click copy and paste in the interactive chat
help prints what --help prints; help ACTION, what ACTION --help prints. In the interactive chat a right-click on the conversation copies the text selected with the mouse, else the line under the pointer: to the terminal (OSC 52) and to the platform's clipboard tool. A right-click on the line written in pastes the system clipboard's text at the cursor, its lines side by side, read with wl-paste, xclip or xsel, pbpaste or PowerShell, else what was copied here last. The conversation is selectable with the mouse, which RichLog alone is not. The deb and rpm packages recommend wl-clipboard or xclip for the paste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-cli/src/meshbay_cli/tui/app.py')
-rw-r--r--packages/meshbay-cli/src/meshbay_cli/tui/app.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/packages/meshbay-cli/src/meshbay_cli/tui/app.py b/packages/meshbay-cli/src/meshbay_cli/tui/app.py
index fe7fa2c..7abb149 100644
--- a/packages/meshbay-cli/src/meshbay_cli/tui/app.py
+++ b/packages/meshbay-cli/src/meshbay_cli/tui/app.py
@@ -12,7 +12,9 @@ the log goes to a file in the CLI's data directory instead.
import logging
+from textual import events
from textual.app import App
+from textual.errors import NoWidget
from ..client.account import Account, no_passphrase
from ..client.hub import Hub
@@ -31,6 +33,7 @@ class MeshBayApp(App):
self.hub = ctx.hub
# The screen a signed-in account lands on, made from the account.
self.home = home
+ self._right_click_taken = False
async def use_hub(self, url: str) -> None:
if url != self.hub.url:
@@ -39,6 +42,26 @@ class MeshBayApp(App):
self.ctx.hub = self.hub
self.ctx.hub_url = url
+ async def on_event(self, event: events.Event) -> None:
+ """A right-click goes to the widget under it when it has a use for one
+ (the chat's copy and paste), before Textual takes it for a selection."""
+ if (isinstance(event, (events.MouseDown, events.MouseUp)) and event.button == 3
+ and not event.is_forwarded):
+ if isinstance(event, events.MouseDown):
+ try:
+ widget, _ = self.get_widget_at(event.x, event.y)
+ except NoWidget:
+ widget = None
+ handler = getattr(widget, "right_click", None)
+ self._right_click_taken = handler is not None
+ if handler is not None:
+ await handler(event)
+ return
+ elif self._right_click_taken:
+ self._right_click_taken = False
+ return
+ await super().on_event(event)
+
def on_mount(self) -> None:
account = None
if self.ctx.store.peek().get("hub") == self.hub.url: