;; -*- lexical-binding: t -*- (require 'rx) (defvar ement--pantalaimon-conf-verbose (member "--verbose" command-line-args)) (defun ement--pantalaimon-conf-message (format-string &rest args) (when ement--pantalaimon-conf-verbose (apply #'message format-string args))) (defmacro with-no-messages (&rest body) (declare (indent 0)) `(progn (advice-add 'message :around #'ignore) (unwind-protect (progn ,@body) (advice-remove 'message #'ignore)))) (defun ement--pantalaimon-latest-doc-dir () (car (last (directory-files "/usr/share/doc/" t (rx string-start "pantalaimon"))))) (defun ement--pantalaimon-annotate (pantalaimon-conf-file) (let ((count 0) (pantalaimon-options-help (ignore-errors (with-no-messages (find-file-noselect (nth 0 (directory-files (ement--pantalaimon-latest-doc-dir) t (rx string-start "pantalaimon.5.md") t))))))) (if (not pantalaimon-options-help) (message "Can't find pantalaimon doc file to annotate pantalaimon config") (ement--pantalaimon-conf-message "Annotating file %s..." pantalaimon-conf-file) (let ((annotations (get-buffer-create " *annotations*"))) (with-current-buffer annotations (buffer-disable-undo)) ;; annotations need to be reformatted in their own buffer ;; because md syntax is different from conf syntax (defun ement--pantalaimon-conf-insert-annotation (key &optional buffer) (setq buffer (or buffer (current-buffer))) (with-current-buffer pantalaimon-options-help (save-excursion (goto-char (point-min)) (if (not (re-search-forward (rx line-start "**" (literal key) "**" line-end) nil t)) (progn (ement--pantalaimon-conf-message "Can't find annotation for key %s" key) nil) (re-search-forward (rx (zero-or-more whitespace)) nil t) (if (not (looking-at-p (rx ?\>))) (progn (ement--pantalaimon-conf-message "Unexpected annotation format for key %s" key) nil) (let ((start (point)) (end (re-search-forward (rx line-start (zero-or-more whitespace) line-end) nil t))) (with-current-buffer annotations (erase-buffer) (insert-buffer-substring-no-properties pantalaimon-options-help start end) (goto-char (point-min)) (while (re-search-forward (rx line-start ?\>) nil t) (delete-backward-char 1) (insert ?\#)))) (with-current-buffer buffer (insert-buffer-substring-no-properties annotations)) t))))) (with-current-buffer (find-file-noselect pantalaimon-conf-file) (goto-char (point-min)) (let ((maybe-fail-ungracefully (let ((count 0)) (lambda () (when (>= (setq count (1+ count)) 10000) (error "Annotating config failed ungracefully")))))) (while (not (= (point-max) (point))) ;; These loops are not very safe ;; todo: maybe rewrite with save-restriction (funcall maybe-fail-ungracefully) (when (looking-at (rx line-start (group (one-or-more alphabetic)) (zero-or-one ?\s) ?\=)) (let ((key (match-string-no-properties 1))) (when ement--pantalaimon-conf-verbose "Annotating option %s..." key) (beginning-of-line) (open-line 1) (when (ement--pantalaimon-conf-insert-annotation key) (ement--pantalaimon-conf-message "Done"))) (while (looking-at-p (rx (or whitespace line-end))) (funcall maybe-fail-ungracefully) (delete-char 1))) (next-logical-line) (while (looking-at-p (rx line-start ?\#)) (funcall maybe-fail-ungracefully) (next-logical-line)) (open-line 1) (next-logical-line))) (save-buffer)) (kill-buffer annotations))))) (ement--pantalaimon-annotate (expand-file-name "pantalaimon.conf" (getenv "S")))