From ea24ef81a4a8551a8212582a65dd4aa685c9c648 Mon Sep 17 00:00:00 2001 From: Daniel Mendler Date: Wed, 11 Dec 2024 07:36:16 +0100 Subject: [PATCH] Add `browse-url-qutebrowser' The browser launcher supports the NEW-WINDOW argument and `browse-url-qutebrowser-new-window-is-tab' to open tabs. Furthermore opening new URLs is speed up via Unix socket IPC if available. * lisp/net/browse-url.el (browse-url-qutebrowser-send): Function to send command to Qutebrowser via IPC. (browse-url-qutebrowser): New browser launcher. Use `browse-url-qutebrowser-send'. (browse-url-qutebrowser-program, browse-url-qutebrowser-arguments, browse-url-qutebrowser-new-window-is-tab): New customizables. --- lisp/net/browse-url.el | 68 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 8ec025d017b..3b6833715f4 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -342,6 +342,14 @@ browse-url-epiphany-startup-arguments `browse-url' is loaded." :type '(repeat (string :tag "Argument"))) +(defcustom browse-url-qutebrowser-program "qutebrowser" + "The name by which to invoke Qutebrowser." + :type 'string) + +(defcustom browse-url-qutebrowser-arguments nil + "A list of strings to pass to Qutebrowser when it starts up." + :type '(repeat (string :tag "Argument"))) + (defcustom browse-url-webpositive-program "WebPositive" "The name by which to invoke WebPositive." :type 'string @@ -387,6 +395,12 @@ browse-url-epiphany-new-window-is-tab `browse-url-epiphany' is asked to open it in a new window." :type 'boolean) +(defcustom browse-url-qutebrowser-new-window-is-tab nil + "Whether to open up new windows in a tab or a new window. +If non-nil, then open the URL in a new tab rather than a new window if +`browse-url-qutebrowser' is asked to open it in a new window." + :type 'boolean) + (defcustom browse-url-new-window-flag nil "Non-nil means always open a new browser window with appropriate browsers. Passing an interactive argument to \\[browse-url], or specific browser @@ -1294,6 +1308,60 @@ browse-url-epiphany-sentinel browse-url-epiphany-program (append browse-url-epiphany-startup-arguments (list url)))))) +(defun browse-url-qutebrowser-send (cmd) + "Send CMD to Qutebrowser via IPC." + (let* ((dir (getenv "XDG_RUNTIME_DIR")) + (sock (and dir (expand-file-name + (format "qutebrowser/ipc-%s" (md5 (user-login-name))) + dir)))) + (unless (file-exists-p sock) + (error "No Qutebrowser IPC socket found")) + (let ((proc + (make-network-process + :name "qutebrowser" + :family 'local + :service sock + :coding 'utf-8))) + (unwind-protect + (process-send-string + proc + (concat + (json-serialize `( :args [,cmd] + :target_arg :null + :protocol_version 1)) + "\n")) + (delete-process proc))))) + +(defun browse-url-qutebrowser (url &optional new-window) + "Ask the Qutebrowser WWW browser to load URL. +Default to the URL around or before point. + +When called interactively, if variable `browse-url-new-window-flag' is +non-nil, load the document in a new Qutebrowser window, otherwise use a +random existing one. A non-nil interactive prefix argument reverses +the effect of `browse-url-new-window-flag'. + +If `browse-url-qutebrowser-new-window-is-tab' is non-nil, then whenever a +document would otherwise be loaded in a new window, it is loaded in a +new tab in an existing window instead. + +When called non-interactively, optional second argument NEW-WINDOW is +used instead of `browse-url-new-window-flag'." + (interactive (browse-url-interactive-arg "URL: ")) + (let ((cmd (concat ":open " + (and (browse-url-maybe-new-window new-window) + (if browse-url-qutebrowser-new-window-is-tab + "-t " "-w ")) + (browse-url-encode-url url)))) + (condition-case nil + (browse-url-qutebrowser-send cmd) + (error + (apply #'start-process (concat "qutebrowser " url) nil + browse-url-qutebrowser-program + (append browse-url-qutebrowser-arguments (list cmd))))))) + +(function-put 'browse-url-qutebrowser 'browse-url-browser-kind 'external) + (defvar url-handler-regexp) ;;;###autoload -- 2.45.2