From 1d7b0cb0577829a5fd2a1400ca102b0809f03701 Mon Sep 17 00:00:00 2001 From: Anders Norman Date: Fri, 25 Oct 2024 18:15:18 +0200 Subject: [PATCH] Added copy (yank) function on keypress 'y' --- poetry.lock | 16 +++++++++++++--- pyproject.toml | 1 + src/toolong/help.py | 3 +++ src/toolong/log_lines.py | 7 +++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d2a1dba..0cc0989 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "aiohttp" @@ -400,7 +400,7 @@ files = [ {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, - {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, ] [[package]] @@ -517,6 +517,16 @@ files = [ plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "pyperclip" +version = "1.9.0" +description = "A cross-platform clipboard module for Python. (Only handles plain text for now.)" +optional = false +python-versions = "*" +files = [ + {file = "pyperclip-1.9.0.tar.gz", hash = "sha256:b7de0142ddc81bfc5c7507eea19da920b92252b548b96186caf94a5e2527d310"}, +] + [[package]] name = "rich" version = "13.7.1" @@ -704,4 +714,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "58d9a6258e13953abdd4fc0a2ad25d2945791398a1edcb17633e1e6687b3c2ef" +content-hash = "70ea848615c554ae58e3d68520042a95d83d1f2a3ae72759b1d4efb9b16a39d0" diff --git a/pyproject.toml b/pyproject.toml index 885ec5f..026e099 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ python = "^3.8" click = "^8.1.7" textual = "^0.58.0" typing-extensions = "^4.9.0" +pyperclip = "^1.9.0" [tool.poetry.group.dev.dependencies] textual-dev = "^1.4.0" diff --git a/src/toolong/help.py b/src/toolong/help.py index 95c59d4..ef1241b 100644 --- a/src/toolong/help.py +++ b/src/toolong/help.py @@ -41,6 +41,7 @@ - `ctrl+l` Toggle line numbers. - `ctrl+t` Tail current file. - `ctrl+c` Exit the app. +- `y` Copy (yank) current line in pointer mode ### Opening Files @@ -75,6 +76,8 @@ To enter pointer mode, press `enter` or click a line. When in pointer mode, the navigation keys will move this pointer rather than scroll the log file. +Press `y` to copy (yank) the current line to the system clipboard. + Press `enter` again or click the line a second time to expand the line in to a new panel. Press `escape` to hide the line panel if it is visible, or to leave pointer mode if the line panel is not visible. diff --git a/src/toolong/log_lines.py b/src/toolong/log_lines.py index 22f8906..6fff40b 100644 --- a/src/toolong/log_lines.py +++ b/src/toolong/log_lines.py @@ -4,6 +4,7 @@ from queue import Empty, Queue from operator import itemgetter import platform +import pyperclip from threading import Event, RLock, Thread from textual.message import Message @@ -139,6 +140,7 @@ class LogLines(ScrollView, inherit_bindings=False): Binding("pagedown,space", "page_down", "Page Down", show=False), Binding("enter", "select", "Select line", show=False), Binding("escape", "dismiss", "Dismiss", show=False, priority=True), + Binding("y", "copy", "Copy (yank) current selection", show=False, priority=True), Binding("m", "navigate(+1, 'm')"), Binding("M", "navigate(-1, 'm')"), Binding("o", "navigate(+1, 'h')"), @@ -906,6 +908,11 @@ def action_navigate(self, steps: int, unit: Literal["m", "h", "d"]) -> None: self.pointer_line = line_no self.scroll_pointer_to_center(animate=abs(initial_line_no - line_no) < 100) + def action_copy(self, **argv): + if self.pointer_line: + line = self.get_line_from_index(self.pointer_line) + pyperclip.copy(line) + def watch_tail(self, tail: bool) -> None: self.set_class(tail, "-tail") if tail: