;;; jao-org-focus.el --- focusing on org subtrees -*- lexical-binding: t; -*- ;; Copyright (C) 2025 Jose Antonio Ortega Ruiz ;; Author: Jose Antonio Ortega Ruiz ;; Keywords: docs ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program 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 General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Miscellanous utilities for working with org files (require 'org) ;;; focus on subtree (defvar-local jao-org-focus--parent nil) (defun jao-org-focus () "Pop creatingly to an indirect buffer focused on the encloing subtree. When invoked on an indirect buffer, pops back to its base." (interactive) (if-let* ((b (get-buffer (or jao-org-focus--parent "")))) (pop-to-buffer b) (when-let* ((elem (org-element-at-point)) (header (if (eq 'headline (org-element-type elem)) elem (org-previous-visible-heading 1) (org-element-at-point))) (title (org-element-property :title header)) (parent (buffer-name)) (bname (format "%s [%s]" title parent))) (if-let* ((b (get-buffer bname))) (pop-to-buffer b) (clone-indirect-buffer bname t) (setq jao-org-focus--parent parent) (org-narrow-to-subtree))))) (defun jao-org-focus-list (&optional any-parent) "List of buffers that are focusing on a subtree of this one or its parent." (let ((n (or jao-org-focus--parent (buffer-name)))) (seq-filter (lambda (b) (let ((p (buffer-local-value 'jao-org-focus--parent b))) (and p (or any-parent (string= n p))))) (buffer-list)))) (defvar jao-org-focus--focused-history nil) (defun jao-org-focus-switch (arg) "Read with completion a focused child and pop to it. With arg, offer to switch to all children, regardless of their parent." (interactive "P") (let ((fl (mapcar 'buffer-name (jao-org-focus-list arg)))) (unless fl (error "No focused children")) (pop-to-buffer (completing-read "Focused child: " fl nil t nil 'jao-org-focus--focused-history)))) (defvar jao-org-focus-consult-buffer-source `(:name "Focus buffers" :category jao-org-focus-buffers :action switch-to-buffer :hidden t :narrow ,(cons ?o "focus") :history jao-org-focus--focused-history :items ,(lambda () (mapcar 'buffer-name (jao-org-focus-list t))))) (provide 'jao-org-focus) ;;; jao-org.el ends here