emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Mikhail Skorzhisnkii <mskorzhinskii@eml.cc>
To: Ihor Radchenko <yantar92@gmail.com>
Cc: Mikhail Skorzhinskii <mskorzhinskiy@eml.cc>,
	Org Mode <emacs-orgmode@gnu.org>
Subject: Re: [PATCH] org-agenda.el: customise outline path in echo area
Date: Tue, 30 Aug 2022 16:59:57 +0200	[thread overview]
Message-ID: <87r10x22lw.fsf@eml.cc> (raw)
In-Reply-To: <87r13vbnxo.fsf@localhost>

[-- Attachment #1: Type: text/plain, Size: 2366 bytes --]

I have signed the FSF papers now and we can continue the review of this work now.

I am attaching updated and rebased patch for this and another e-mail thread, since these two patches are depend on each other. I have additionally tested the functionality of these changes by verifying that it works as expected on my setup;

• Tried to use org-agenda on buffers with and without title property set
• Tried to call org-refile and see if refiling will happen
• `make test' passes

I have *not* tried to see if it will work on buffers without file representation, but the component tests for refile should cover that.

Let me know what you think.

      Thanks,
      Mikhail Skorzhinskii

Ihor Radchenko <yantar92@gmail.com> writes:

> Mikhail Skorzhinskii <mskorzhinskiy@eml.cc> writes:
>
>> Thank you for your comments once again. I’ve changed string= to eq and
>> it appears to be working OK.
>>
>> I’ve also renamed “title” variable to “title-prop” for better
>> readability. The -prop suffix should show the reader that it was
>> extracted from the file, and thus cost some CPU/IO.
>>
>> I’ve attached an updated version to this email. Would love to hear what
>> you think.
>
> Thanks! And sorry for the late reply. Your patch fell through the cracks
> in my todo list.
>
>> * lisp/org-agenda.el (org-agenda-show-outline-path): add an option to
>> show document title in outline path (instead of file name)
>> * lisp/org.el (org-get-title-from-file): a function to collect the
>> document title from the org-mode file
>> * lisp/org.el (org-display-outline-path): add logic that will collect a
>> document title and put it into the outline path if
>> org-agenda-show-outline-path set to ’title
>
> It would make sense to document the new customization in ORG-NEWS.
>
>> +(defun org-get-title-from-file (file)
>> +  “Collect tilte from the provided `org-mode’ FILE.”
>> +  (let (title)
>               ^ typo
>> +    (when file
>> +      (with-current-buffer
>> +	  (get-file-buffer file)
>> +	(pcase (org-collect-keywords ’(“TITLE”))
>> +	  (`((“TITLE” . ,val))
>> +	   (setq title (car val)))))
>> +      title)))
>
> Note that this function behavior is underfined when FILE buffer does not
> exist. It would be better to accept buffer as argument.
>
> Best,
> Ihor

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-org-refile.el-show-refile-targets-with-doc.-title.patch --]
[-- Type: text/x-diff, Size: 5968 bytes --]

From 646af66fa88fbcc2b1f2848a14dd5c262763ef98 Mon Sep 17 00:00:00 2001
From: Mikhail Skorzhinskii <mskorzhinskiy@eml.cc>
Date: Mon, 21 Sep 2020 14:53:13 +0200
Subject: [PATCH 2/2] org-refile.el: show refile targets with doc. title

* lisp/org-refile.el (org-refile-use-outline-path): add an option 'title
* lisp/org-refile.el (org-refile-get-targets): start refile target
outline with document title (#+title) instead of file name
---
 etc/ORG-NEWS             |  4 ++++
 lisp/org-refile.el       | 16 +++++++++++++---
 testing/lisp/test-org.el | 37 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 4405489bb..df2c882bb 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -290,6 +290,10 @@ level used for top level headings, much like how
 headings in HTML export.
 
 ** New options
+*** A new option for custom setting =org-refile-use-outline-path= to show document title in refile targets
+
+Setting =org-refile-use-outline-path= to ='title= will show title instead of the file name in refile targets. If the documen do not have a title, the filename will be used, similar to ='file= option.
+
 *** A new option for custom setting =org-agenda-show-outline-path= to show document title
 
 Settings =org-agenda-show-outline-path=  to ='title= will show title instead of
diff --git a/lisp/org-refile.el b/lisp/org-refile.el
index 01f0dfa46..14bd81a2b 100644
--- a/lisp/org-refile.el
+++ b/lisp/org-refile.el
@@ -158,7 +158,8 @@ When `buffer-name', use the buffer name."
 	  (const :tag "Yes" t)
 	  (const :tag "Start with file name" file)
 	  (const :tag "Start with full file path" full-file-path)
-	  (const :tag "Start with buffer name" buffer-name)))
+	  (const :tag "Start with buffer name" buffer-name)
+	  (const :tag "Start with document title" title)))
 
 (defcustom org-outline-path-complete-in-steps t
   "Non-nil means complete the outline path in hierarchical steps.
@@ -317,6 +318,9 @@ converted to a headline before refiling."
 		 (push (list (and (buffer-file-name (buffer-base-buffer))
                                   (file-truename (buffer-file-name (buffer-base-buffer))))
                              f nil nil) tgs))
+	       (when (eq org-refile-use-outline-path 'title)
+		 (push (list (or (org-get-title-from-buffer)
+                                 (and f (file-name-nondirectory f))) f nil nil) tgs))
 	       (org-with-wide-buffer
 		(goto-char (point-min))
 		(setq org-outline-path-cache nil)
@@ -343,7 +347,13 @@ converted to a headline before refiling."
                                            (and (buffer-file-name (buffer-base-buffer))
                                                 (file-name-nondirectory
                                                  (buffer-file-name (buffer-base-buffer))))))
-				   (`full-file-path
+                                   (`title (list
+                                            (or
+                                             (org-get-title-from-buffer)
+                                             (and (buffer-file-name (buffer-base-buffer))
+                                                  (file-name-nondirectory
+                                                   (buffer-file-name (buffer-base-buffer)))))))
+                                   (`full-file-path
 				    (list (buffer-file-name
 					   (buffer-base-buffer))))
 				   (`buffer-name
@@ -631,7 +641,7 @@ this function appends the default value from
 	 (tbl (mapcar
 	       (lambda (x)
 		 (if (and (not (member org-refile-use-outline-path
-				       '(file full-file-path)))
+				       '(file full-file-path title)))
 			  (not (equal filename (nth 1 x))))
 		     (cons (concat (car x) extra " ("
 				   (file-name-nondirectory (nth 1 x)) ")")
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index b14cbeb26..b85dd7dea 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -6728,7 +6728,42 @@ Paragraph<point>"
    (org-test-with-temp-text "* H1"
      (let* ((org-refile-use-outline-path 'buffer-name)
 	    (org-refile-targets `((nil :level . 1))))
-       (member (buffer-name) (mapcar #'car (org-refile-get-targets)))))))
+       (member (buffer-name) (mapcar #'car (org-refile-get-targets))))))
+  ;; When `org-refile-use-outline-path' is `title', return extracted
+  ;; document title
+  (should
+   (equal '("T" "T/H1")
+     (org-test-with-temp-text-in-file "#+title: T\n* H1"
+      (let* ((org-refile-use-outline-path 'title)
+             (org-refile-targets `((nil :level . 1))))
+        (mapcar #'car (org-refile-get-targets))))))
+  ;; When `org-refile-use-outline-path' is `title' validate that
+  ;; deeper levels are correctly reported too (the same behaviour as
+  ;; 'file)
+  (should
+   (equal '("T" "T/H1" "T/H1/H2" "T/H1/H2/H3" "T/H1")
+     (org-test-with-temp-text-in-file "#+title: T\n* H1\n** H2\n*** H3\n* H1"
+       (let ((org-refile-use-outline-path 'title)
+             (org-refile-targets `((nil :maxlevel . 3))))
+         (mapcar #'car (org-refile-get-targets))))))
+  ;; When `org-refile-use-outline-path' is `title' and document do not
+  ;; have an extracted document title, return just the file name
+  (should
+   (org-test-with-temp-text-in-file "* H1"
+     (let* ((filename (buffer-file-name))
+            (org-refile-use-outline-path 'title)
+            (org-refile-targets `((nil :level . 1))))
+       (member (file-name-nondirectory filename)
+               (mapcar #'car (org-refile-get-targets))))))
+  ;; When `org-refile-use-outline-path' is `title' and document is a
+  ;; temporary buffer without a file, it is still possible to extract
+  ;; a title
+  (should
+   (equal '("T" "T/H1")
+     (org-test-with-temp-text "#+title: T\n* H1\n** H2"
+      (let* ((org-refile-use-outline-path 'title)
+             (org-refile-targets `((nil :level . 1))))
+      (mapcar #'car (org-refile-get-targets)))))))
 
 
 \f
-- 
2.35.1


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-org-agenda.el-customize-outline-path-in-echo-area.patch --]
[-- Type: text/x-diff, Size: 5570 bytes --]

From ceb6c9836032c92a792bf58aab91d74141664f50 Mon Sep 17 00:00:00 2001
From: Mikhail Skorzhinskii <mskorzhinskiy@eml.cc>
Date: Sat, 12 Sep 2020 18:10:05 +0200
Subject: [PATCH 1/2] org-agenda.el: customize outline path in echo area

* lisp/org-agenda.el (org-agenda-show-outline-path): add an option to
show document title in outline path (instead of file name)
* lisp/org.el (org-get-title-from-buffer): a function to collect the
document title from the org-mode buffer
* lisp/org.el (org-display-outline-path): add logic that will collect a
document title and put it into the outline path if
org-agenda-show-outline-path set to 'title
---
 etc/ORG-NEWS       | 10 ++++++++++
 lisp/org-agenda.el | 11 ++++++++---
 lisp/org.el        | 25 ++++++++++++++++++++++---
 3 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 7dae03dc6..4405489bb 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -290,6 +290,12 @@ level used for top level headings, much like how
 headings in HTML export.
 
 ** New options
+*** A new option for custom setting =org-agenda-show-outline-path= to show document title
+
+Settings =org-agenda-show-outline-path=  to ='title= will show title instead of
+the file name at the beginning of the outline. The title of the
+document can be set by special keyword =#+title:=.
+
 *** A new custom setting =org-hide-drawer-startup= to control initial folding state of drawers
 
 Previously, all the drawers were always folded when opening an Org
@@ -320,6 +326,10 @@ event time when the alarm time is set to 0.  The default value is
 nil -- do not create alarms at the event time.
 
 ** New functions and changes in function arguments
+*** New function ~org-get-title-from-buffer~ to get ~#+TITLE:~ property
+
+A function to collect the document title from the org-mode buffer.
+
 *** ~org-fold-show-entry~ does not fold drawers by default anymore
 
 ~org-fold-show-entry~ now accepts an optional argument HIDE-DRAWERS.
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index b98041ea8..f308f8f76 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -1058,9 +1058,14 @@ current item's tree, in an indirect buffer."
   :type 'boolean)
 
 (defcustom org-agenda-show-outline-path t
-  "Non-nil means show outline path in echo area after line motion."
+  "Non-nil means show outline path in echo area after line motion.
+
+If set to 'title, show document title."
   :group 'org-agenda-startup
-  :type 'boolean)
+  :type '(choice
+	  (const :tag "Don't show outline path in agenda view." nil)
+	  (const :tag "Show outline path with prepended file name." t)
+	  (const :tag "Show outline path with prepended document title. Fallback to file name is no title is present." title)))
 
 (defcustom org-agenda-start-with-entry-text-mode nil
   "The initial value of entry-text-mode in a newly created agenda window."
@@ -9424,7 +9429,7 @@ When called with a prefix argument, include all archive files as well."
 	       (org-agenda-tree-to-indirect-buffer nil)
 	     (org-agenda-show)))
       (and org-agenda-show-outline-path
-	   (org-with-point-at m (org-display-outline-path t))))))
+	   (org-with-point-at m (org-display-outline-path org-agenda-show-outline-path))))))
 
 (defun org-agenda-show-tags ()
   "Show the tags applicable to the current item."
diff --git a/lisp/org.el b/lisp/org.el
index 858123e67..fd76af48a 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -7396,10 +7396,24 @@ the default is \"/\"."
 	(setf (substring fpath (- width 2)) "..")))
     fpath))
 
-(defun org-display-outline-path (&optional file current separator just-return-string)
+(defun org-get-title-from-buffer (&optional buffer)
+  "Collect title from the provided `org-mode' BUFFER."
+  (let* ((buffer (or buffer (current-buffer)))
+         (buffer (or (buffer-base-buffer buffer)
+                     buffer))
+         title)
+    (with-current-buffer buffer
+      (pcase (org-collect-keywords '("TITLE"))
+        (`(("TITLE" . ,val))
+         (setq title (car val)))))
+    title))
+
+(defun org-display-outline-path (&optional file-or-title current separator just-return-string)
   "Display the current outline path in the echo area.
 
-If FILE is non-nil, prepend the output with the file name.
+If FILE-OR-TITLE is 'title, prepend outline with file title.  If
+it is non-nil or title is not present in document, prepend
+outline path with the file name.
 If CURRENT is non-nil, append the current heading to the output.
 SEPARATOR is passed through to `org-format-outline-path'.  It separates
 the different parts of the path and defaults to \"/\".
@@ -7407,6 +7421,8 @@ If JUST-RETURN-STRING is non-nil, return a string, don't display a message."
   (interactive "P")
   (let* (case-fold-search
 	 (bfn (buffer-file-name (buffer-base-buffer)))
+         (title-prop (when (and file-or-title (eq file-or-title 'title))
+                       (org-get-title-from-buffer)))
 	 (path (and (derived-mode-p 'org-mode) (org-get-outline-path)))
 	 res)
     (when current (setq path (append path
@@ -7418,7 +7434,10 @@ If JUST-RETURN-STRING is non-nil, return a string, don't display a message."
 	  (org-format-outline-path
 	   path
 	   (1- (frame-width))
-	   (and file bfn (concat (file-name-nondirectory bfn) separator))
+	   (and file-or-title bfn (concat (if (and (eq file-or-title 'title) title-prop)
+					      title-prop
+					    (file-name-nondirectory bfn))
+				 separator))
 	   separator))
     (add-face-text-property 0 (length res)
 			    `(:height ,(face-attribute 'default :height))
-- 
2.35.1


      reply	other threads:[~2022-08-30 15:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-25 15:24 [PATCH] org-agenda.el: customise outline path in echo area Mikhail Skorzhinskii
2021-12-26 13:44 ` Ihor Radchenko
2021-12-26 13:49   ` Mikhail Skorzhinskiy
2021-12-26 14:01     ` Ihor Radchenko
2021-12-28 12:01   ` Mikhail Skorzhinskii
2022-06-11  8:32     ` Ihor Radchenko
2022-08-30 14:59       ` Mikhail Skorzhisnkii [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r10x22lw.fsf@eml.cc \
    --to=mskorzhinskii@eml.cc \
    --cc=emacs-orgmode@gnu.org \
    --cc=mskorzhinskiy@eml.cc \
    --cc=yantar92@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).