From 2aa28fb2be608da5dadd947b35b2e5710e469dad Mon Sep 17 00:00:00 2001 From: dogeystamp Date: Sat, 6 May 2023 17:31:46 -0400 Subject: [PATCH] qutebrowser: add code block copying --- src/.config/qutebrowser/config.py | 9 ++- .../qutebrowser/userscripts/code_select.py | 57 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100755 src/.local/share/qutebrowser/userscripts/code_select.py diff --git a/src/.config/qutebrowser/config.py b/src/.config/qutebrowser/config.py index fcdc757..3371109 100644 --- a/src/.config/qutebrowser/config.py +++ b/src/.config/qutebrowser/config.py @@ -83,7 +83,7 @@ c.content.headers.custom = {"accept": "text/html,application/xhtml+xml,applicati # Sending a Do Not Track header makes your fingerprint more unique according to Panopticlick, # and I don't trust sites to respect it, so I think it's better to not include it at all. # (True: send DNT, False: Send DNT header set to 0, None: Don't send DNT) -c.content.headers.do_not_track = None; +c.content.headers.do_not_track = None # Block certain trackers c.content.canvas_reading = False @@ -95,3 +95,10 @@ config.bind("#", "set-cmd-text -s :scroll-to-anchor ") config.bind(";I", "hint images yank") # This overrides pP because I don't use primary clip config.bind("p", "open -t {clipboard}") + +# code block copying +c.hints.selectors["code"] = [ + ":not(pre) > code", + "pre" +] +config.bind("cc", "hint code userscript code_select.py") diff --git a/src/.local/share/qutebrowser/userscripts/code_select.py b/src/.local/share/qutebrowser/userscripts/code_select.py new file mode 100755 index 0000000..b095d62 --- /dev/null +++ b/src/.local/share/qutebrowser/userscripts/code_select.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +import os +import html +import re +import sys +import xml.etree.ElementTree as ET +try: + import pyperclip +except ImportError: + try: + import pyclip as pyperclip + except ImportError: + PYPERCLIP = False + else: + PYPERCLIP = True +else: + PYPERCLIP = True + + +def parse_text_content(element): + root = ET.fromstring(element) + text = ET.tostring(root, encoding="unicode", method="text") + text = html.unescape(text) + return text + + +def send_command_to_qute(command): + with open(os.environ.get("QUTE_FIFO"), "w") as f: + f.write(command) + + +def main(): + delimiter = sys.argv[1] if len(sys.argv) > 1 else ";" + # For info on qute environment vairables, see + # https://github.com/qutebrowser/qutebrowser/blob/master/doc/userscripts.asciidoc + element = os.environ.get("QUTE_SELECTED_HTML") + code_text = parse_text_content(element) + if PYPERCLIP: + pyperclip.copy(code_text) + send_command_to_qute( + "message-info 'copied to clipboard: {info}{suffix}'".format( + info=code_text.splitlines()[0], + suffix="..." if len(code_text.splitlines()) > 1 else "" + ) + ) + else: + # Qute's yank command won't copy accross multiple lines so we + # compromise by placing lines on a single line seperated by the + # specified delimiter + code_text = re.sub("(\n)+", delimiter, code_text) + code_text = code_text.replace("'", "\"") + send_command_to_qute("yank inline '{code}'\n".format(code=code_text)) + + +if __name__ == "__main__": + main()