;;; infobox.el -- Infobox in a help buffer -*- lexical-binding: t -*- ;; Copyright (C) 2025 Free Software Foundation, Inc. ;; Author: Yuchen Pei ;; Package-Requires: ((emacs "29.4")) ;; This file is part of dotted. ;; dotted is free software: you can redistribute it and/or modify it under ;; the terms of the GNU Affero General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; dotted is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General ;; Public License for more details. ;; You should have received a copy of the GNU Affero General Public ;; License along with dotted. If not, see . ;;; Commentary: ;; Infobox in a help buffer. ;;; Code: (defun infobox-default-specs (info) (seq-map (lambda (pair) (cons (car pair) (replace-regexp-in-string "[-_]" " " (capitalize (format "%s" (car pair)))))) info)) (defun infobox-translate (info specs) "Translate INFO according to SPECS. TODO: allow multiple levels in specs keys using let-alist, i.e. something like (.channel.name . \"Channel name\")" (seq-map (lambda (pair) (when-let ((val (alist-get (car pair) info))) (if (or (stringp (cdr pair)) (symbolp (cdr pair))) (cons (cdr pair) val) (cons (cadr pair) (funcall (cddr pair) val))))) specs)) (defun infobox-render (info item &optional interactive-p) "Render and display a help buffer of INFO." (with-help-window "*infobox*" (with-current-buffer standard-output (let ((n-rows 0)) (seq-do (lambda (pair) (when pair (when (stringp (car pair)) (insert (car pair) ": ") (setq n-rows (1+ n-rows))) (insert (format "%s" (cdr pair)) "\n"))) info) (align-regexp (point-min) (progn (goto-line (1+ n-rows)) (point)) "\\(\\s-*\\):")) (visual-line-mode))) (with-current-buffer "*infobox*" (let ((help-xref-following t)) (help-setup-xref item interactive-p) ))) (defun infobox-render-string (text item &optional interactive-p) (help-setup-xref item interactive-p) (with-help-window "*infobox*" (with-current-buffer standard-output (insert text) (visual-line-mode))) (with-current-buffer "*infobox*" (let ((help-xref-following t)) (help-setup-xref item interactive-p) ))) (defun infobox-exiftool (filename) (interactive (list (expand-file-name (read-file-name "infobox exiftool: ")))) (infobox-render-string (with-temp-buffer (call-process "exiftool" nil t nil filename) (buffer-string)) `(infobox-exiftool ,filename) (called-interactively-p 'interactive) )) (defun infobox-pacman (package-name) (interactive (list (completing-read "pacman package: " (infobox-pacman-installed-packages) nil t))) (infobox-render-string (with-temp-buffer (call-process "pacman" nil t nil "-Qi" package-name) (buffer-string)) `(infobox-pacman ,package-name) (called-interactively-p 'interactive) )) (defun infobox-pacman-installed-packages () "Returns list of installed packages." (with-temp-buffer (call-process "pacman" nil t nil "-Qq") (split-string (buffer-string) "\n"))) (defun infobox-calibre (book-id) (interactive (list (car (split-string (completing-read "calibre book: " (infobox-calibre-books) nil t) " ")))) (infobox-render-string (with-temp-buffer (call-process "calibredb" nil t nil "show_metadata" book-id) (buffer-string)) `(infobox-calibre ,book-id) (called-interactively-p 'interactive))) (defun infobox-calibre-books () (with-temp-buffer (call-process "calibredb" nil t nil "list") (seq-filter (lambda (line) (string-match-p "^[0-9]" line)) (split-string (buffer-string) "\n")))) (defun my-call-process-out (command &rest args) (with-temp-buffer (apply 'call-process (append (list command nil t nil) args)) (buffer-string))) (provide 'infobox)