From 8e758393aee8a8596f540c766d79d72441693dcd Mon Sep 17 00:00:00 2001 From: cage Date: Tue, 7 Jan 2025 13:25:36 +0100 Subject: [PATCH] -[TUI] added configuration directive ("use terminal") to redirect output of an external program on the same terminal where tinmop is running; useful to run external programs that use TUI. --- etc/shared.conf | 18 +++++++++++++-- src/os-utils.lisp | 40 +++++++++++++++++++++++++++----- src/package.lisp | 3 ++- src/software-configuration.lisp | 41 ++++++++++++++++++++++++++------- src/ui-goodies.lisp | 5 ++++ 5 files changed, 90 insertions(+), 17 deletions(-) diff --git a/etc/shared.conf b/etc/shared.conf index dcefce3..0aba9ec 100644 --- a/etc/shared.conf +++ b/etc/shared.conf @@ -133,20 +133,34 @@ gemini.exclusive.mode.links.height = 1/4 # ▼▼▼▼▼▼▼▼▼ buffer 20 Mib # open "mp4$" with "xterm -e mpv" no wait buffer 20 -# to open some kind of files use "editor" as program name +# if the program runs on TUI, you have to instruct tinmop to pause +# itself and wait for external program to finish running +# ▼▼▼▼▼▼▼▼▼▼▼▼ +# open "jpe?g$" with "chafa" use cache use terminal + +# to open some kind of files with an editor # ▼▼▼▼▼▼▼▼ -#open "txt$" with "editor" +# open "txt$" with "editor" # finally if you want to open some kind of file with tinmop try the # following: valid values are "tinmop" "me" "internal" # ▼▼▼▼▼▼▼▼ + open "^((gemini://)|(\\.)|(/)).+gmi$" with "tinmop" open "^((gemini://)|(\\.)|(/)).+txt$" with "tinmop" open "^((gemini://)|(\\.)|(/)).+sh$" with "tinmop" open ".gpub$" with "tinmop" +# on terminal tinmop can collect the images linked to a gemini page +# and shows a collage of the images, needs "montage" program from +# imagemagick (and a graphical environment) to works + +# the size of the collage + gemini.images.montage.geometry = "640x480" +# number of tiles for row and column + gemini.images.montage.tile = "1" ######################### diff --git a/src/os-utils.lisp b/src/os-utils.lisp index fa0c89a..3ca286a 100644 --- a/src/os-utils.lisp +++ b/src/os-utils.lisp @@ -261,11 +261,16 @@ numerical user ID, as an assoc-list." :output t :error t)))) -(defun open-link-with-program (program-and-args link &key (wait nil)) +(defun make-external-program-arguments (program-and-args link) (let* ((command-line-splitted (text-utils:split-words program-and-args)) (program (first command-line-splitted)) (args (append (rest command-line-splitted) (list link)))) + (values program args))) + +(defun open-link-with-program (program-and-args link &key (wait nil)) + (multiple-value-bind (program args) + (make-external-program-arguments program-and-args link) (run-external-program program args :search t @@ -273,16 +278,37 @@ numerical user ID, as an assoc-list." :output nil :error :output))) +(defun open-link-with-tui-program (program-and-args link) + (multiple-value-bind (program args) + (make-external-program-arguments program-and-args link) + (croatoan:end-screen) + (run-external-program program + args + :search t + :wait t + :input t + :output t + :error t) + (setf (croatoan:input-blocking (windows:croatoan-window specials:*main-window*)) t) + (croatoan:get-char (windows:croatoan-window specials:*main-window*)) + (setf (croatoan:input-blocking (windows:croatoan-window specials:*main-window*)) nil))) + (defun open-resource-with-external-program (resource give-focus-to-message-window &key (open-for-edit nil)) (flet ((edit (file) (croatoan:end-screen) - (os-utils:open-with-editor file))) + (open-with-editor file)) + (open-in-terminal (program resource) + (open-link-with-tui-program program resource)) + (open-in-gui (program resource wait) + (open-link-with-program program resource :wait wait))) (alexandria::when-let* ((parsed-as-iri (iri:iri-parse resource :null-on-error t)) (parsed-no-fragment (iri:remove-fragment parsed-as-iri))) - (let ((program (if (iri:absolute-url-p resource) - (swconf:link-regex->program-to-use (text-utils:to-s parsed-no-fragment)) - (swconf:link-regex->program-to-use resource)))) + (multiple-value-bind (program x y z use-tui-p) + (if (iri:absolute-url-p resource) + (swconf:link-regex->program-to-use (text-utils:to-s parsed-no-fragment)) + (swconf:link-regex->program-to-use resource)) + (declare (ignore x y z)) (if program (cond ((swconf:use-editor-as-external-program-p program) @@ -294,7 +320,9 @@ numerical user ID, as an assoc-list." :give-focus-to-message-window give-focus-to-message-window))) (t - (os-utils:open-link-with-program program resource :wait open-for-edit))) + (if use-tui-p + (open-in-terminal program resource) + (open-in-gui program resource open-for-edit)))) (if open-for-edit (error (_ "No program defined in configuration file to edit this kind of files")) (os-utils:xdg-open resource))))))) diff --git a/src/package.lisp b/src/package.lisp index 4a9125f..b009910 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -3300,7 +3300,8 @@ :search-fediverse-local :localized-default-string :search-fediverse-with-query - :open-resource-with-external-program)) + :open-resource-with-external-program + :block-screen-until-enter-pressed)) (defpackage :scheduled-events (:use diff --git a/src/software-configuration.lisp b/src/software-configuration.lisp index 1b8fdaf..7db3917 100644 --- a/src/software-configuration.lisp +++ b/src/software-configuration.lisp @@ -33,7 +33,7 @@ ;; SERVER-ASSIGN := SERVER-KEY BLANKS ASSIGN BLANKS GENERIC-VALUE BLANKS ;; USERNAME-ASSIGN := USERNAME-KEY BLANKS WITH BLANKS GENERIC-VALUE BLANKS ;; OPEN-LINK-HELPER := OPEN-LINK-HELPER-KEY BLANKS ASSIGN BLANKS -;; REGEXP PROGRAM-NAME BLANKS USE-CACHE? NOWAIT? +;; REGEXP PROGRAM-NAME BLANKS (USE-CACHE BLANCKS)? (NOWAIT BLANKS)? TUI? ;; GENERIC-ASSIGN := (and key blanks assign blanks ;; (or quoted-string ;; hexcolor @@ -51,6 +51,8 @@ ;; PROGRAM-NAME := QUOTED-STRING ;; USE-CACHE := USE BLANKS CACHE ;; NOWAIT := NO BLANKS WAIT BLANKS (BUFFER-LABEL BLANKS DIGIT+)? +;; TUI := USE BLANKS "terminal" +;; TERMINAL := "terminal" ;; NO := "no" ;; WAIT := "wait" ;; CACHE := "cache" @@ -359,7 +361,12 @@ (buffer-size :initform +buffer-minimum-size-to-open+ :initarg :buffer-size - :accessor buffer-size)) + :accessor buffer-size) + (use-tui + :initform nil + :initarg :use-tui + :reader use-tui-p + :writer (setf use-tui))) (:documentation "When a gemini link matches `re' try to open it with 'program-name'")) (defmethod print-object ((object open-link-helper) stream) @@ -374,7 +381,10 @@ re program-name use-cache-p waitp buffer-size)))) (defun make-open-link-helper (re program-name use-cache - &key (wait t) (buffer-size +buffer-minimum-size-to-open+)) + &key + (buffer-size +buffer-minimum-size-to-open+) + (wait t) + (use-tui nil)) (assert (stringp program-name)) (assert (stringp re)) @@ -385,7 +395,8 @@ :program-name program-name :use-cache use-cache :wait wait - :buffer-size buffer-size)) + :buffer-size buffer-size + :use-tui use-tui)) (defrule conf-use "use" (:text t)) @@ -408,6 +419,15 @@ (defrule conf-no-wait (and conf-no conf-blanks conf-wait) (:constant t)) +;; TUI := USE BLANKS "terminal" +;; TERMINAL := "terminal" + +(defrule conf-terminal "terminal" + (::text t)) + +(defrule conf-tui (and conf-use conf-blanks conf-terminal) + (:constant t)) + (defrule conf-open-link-helper (and conf-open-link-helper-key conf-blanks @@ -424,7 +444,9 @@ (? (and conf-buffer-label conf-blanks (+ conf-digit))) - conf-blanks))) + conf-blanks)) + (? (and conf-tui + conf-blanks))) ;; 10 the program uses the terminal interface? (:function (lambda (args) (let* ((use-cache (elt args 8)) (wait-parameters (elt args 9)) @@ -438,13 +460,15 @@ (mebimytes (parse-integer mebibyte-string)) (bytes (* 1024 1024 mebimytes))) (abs bytes)) - swconf:+buffer-minimum-size-to-open+))) + swconf:+buffer-minimum-size-to-open+)) + (use-tui-p (elt args 10))) (list :open-link-helper (make-open-link-helper (elt args 2) (elt args 6) use-cache :wait waitp - :buffer-size buffer-size)))))) + :buffer-size buffer-size + :use-tui use-tui-p)))))) (defrule conf-filepath conf-quoted-string) @@ -1284,7 +1308,8 @@ (values (program-name found) (use-cache-p found) (waitp found) - (buffer-size found)))) + (buffer-size found) + (use-tui-p found)))) (defun link-regex->program-to-use-buffer-size (link) (when-let ((found (link-regex->program-to-use-parameters link))) diff --git a/src/ui-goodies.lisp b/src/ui-goodies.lisp index ae3012c..158a87a 100644 --- a/src/ui-goodies.lisp +++ b/src/ui-goodies.lisp @@ -3744,3 +3744,8 @@ gemini client certificates!)." (os-utils:open-resource-with-external-program resource give-focus-to-message-window :open-for-edit open-for-edit))) + +(defun block-screen-until-enter-pressed () + (setf (c:input-blocking (croatoan-window *main-window*)) t) + (c:get-char (croatoan-window *main-window*)) + (setf (c:input-blocking (croatoan-window *main-window*)) nil))