emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Leo Vivier <leo.vivier@gmail.com>
To: emacs-orgmode@gnu.org
Cc: Leo Vivier <leo.vivier@gmail.com>
Subject: [PATCH 1/2] Fix narrowing for 1-line subtrees
Date: Mon, 18 Feb 2019 01:25:46 +0100	[thread overview]
Message-ID: <20190218002547.30325-1-leo.vivier@gmail.com> (raw)

* lisp/org.el (org-narrow-to-subtree): Ensure newline at end of
  subtree.
  (org-tree-to-indirect-buffer): Ensure newline at end of
  subtree.
  (org-widen): Create wrapper for `widen' to handle end newline.

* lisp/org-capture.el (org-capture-finalize): Replace `widen' with
  `org-widen'.
  (org-capture-narrow): Ensure newline at end of subtree.

* lisp/org-keys.el (org-remap): Remap `widen' to `org-widen'.

There was a problem with narrowed 1-line subtrees which caused
clocking and scheduling commands to print their modifications outside
of the current narrowing, e.g. `org-clock-in'. This also prevented
some commands from working as expected,
e.g. `org-clock-out-when-done', since the clock-drawer isn't visible.

Previous commits have addressed this problem by patching those
commands to act on a widened buffer within a `save-restriction'
environment (cf. 8fc22d464, 503ede74b, and 6872088c7) but this does
not address the original problem, namely the modifications not being
visible in the narrowed buffer.

The problem is inherent to Emacs's narrowing.  In org-mode, the
narrowing commands use `org-end-of-subtree' to retrieve the
end-position of the region to be narrowed.  However, with a 1-line
subtree, `org-end-of-subtree' moves the point to the end of the line
which is before the position where clocking and scheduling commands
print their modifications, i.e. right below the headline.

To address the problem, we need to change the way we narrow and widen
buffers in org-mode:
- We patch the narrowing commands in org-mode to always add a newline
  at the end of subtrees (not only the 1-line subtrees).  This ensures
  that clocking and scheduling commands print their modifications
  within the narrowed buffer.
- We create a wrapper for `widen' within org-mode (called `org-widen')
  which deletes the newline added when we narrowed the buffer to the
  subtree.

However, for this solution to be complete, we need to ensure that the
newlines added by the narrowing commands cannot be deleted by the
user.
---
This is an implementation of the solution I've discussed in 'Bug:
org-clock commands spawn drawer outside of narrowing' on Fri, 15 Feb
2019 09:48:00 +0100.

I've tried it with `emacs -q' and with different numbers of
blank-lines between headings, and  I haven't encountered any problem so
far.  The code doesn't make any assumption about how many lines you
should have between your headings, which means that it shouldn't
interfere with `org-blank-before-new-entry'.

If there are more idiomatic ways to write some of the functions,
please let me know.

Thank you.

 lisp/org-capture.el | 12 +++++++++---
 lisp/org-keys.el    |  1 +
 lisp/org.el         | 26 +++++++++++++++++++++-----
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index debf1808c..ff3134fb4 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -746,7 +746,7 @@ captured item after finalizing."
   (let ((abort-note nil))
     ;; Store the size of the capture buffer
     (org-capture-put :captured-entry-size (- (point-max) (point-min)))
-    (widen)
+    (org-widen)
     ;; Store the insertion point in the target buffer
     (org-capture-put :insertion-point (point))
 
@@ -1416,8 +1416,14 @@ Of course, if exact position has been required, just put it there."
 (defun org-capture-narrow (beg end)
   "Narrow, unless configuration says not to narrow."
   (unless (org-capture-get :unnarrowed)
-    (narrow-to-region beg end)
-    (goto-char beg)))
+    (goto-char beg)
+    (narrow-to-region
+     beg
+     (progn (org-end-of-subtree t t)
+            (when (and (org-at-heading-p) (not (eobp)))
+              (backward-char 1)
+              (insert "\n"))
+            (point)))))
 
 (defun org-capture-empty-lines-before (&optional n)
   "Set the correct number of empty lines before the insertion point.
diff --git a/lisp/org-keys.el b/lisp/org-keys.el
index d103957a9..90e8139b0 100644
--- a/lisp/org-keys.el
+++ b/lisp/org-keys.el
@@ -532,6 +532,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
 	   'delete-char            'org-delete-char
 	   'delete-backward-char   'org-delete-backward-char
 	   'kill-line              'org-kill-line
+	   'widen                  'org-widen
 	   'open-line              'org-open-line
 	   'yank                   'org-yank
 	   'comment-dwim           'org-comment-dwim
diff --git a/lisp/org.el b/lisp/org.el
index ebec2befa..3110f14ba 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -7391,7 +7391,9 @@ frame is not changed."
       (setq beg (point)
 	    heading (org-get-heading 'no-tags))
       (org-end-of-subtree t t)
-      (when (org-at-heading-p) (backward-char 1))
+      (when (and (org-at-heading-p) (not (eobp)))
+              (backward-char 1)
+              (insert "\n"))
       (setq end (point)))
     (when (and (buffer-live-p org-last-indirect-buffer)
 	       (not (eq org-indirect-buffer-display 'new-frame))
@@ -8381,16 +8383,21 @@ If yes, remember the marker and the distance to BEG."
     (move-marker (car x) (+ beg (cdr x))))
   (setq org-markers-to-move nil))
 
-(defun org-narrow-to-subtree ()
-  "Narrow buffer to the current subtree."
-  (interactive)
+(defun org-narrow-to-subtree (&optional newline)
+  "Narrow buffer to the current subtree.
+
+When called interactively, ensures that there’s a newline at the
+end of the narrowed tree."
+  (interactive "p")
   (save-excursion
     (save-match-data
       (org-with-limited-levels
        (narrow-to-region
 	(progn (org-back-to-heading t) (point))
 	(progn (org-end-of-subtree t t)
-	       (when (and (org-at-heading-p) (not (eobp))) (backward-char 1))
+	       (when (and (org-at-heading-p) (not (eobp)))
+                 (backward-char 1)
+                 (when newline (insert "\n")))
 	       (point)))))))
 
 (defun org-toggle-narrow-to-subtree ()
@@ -8410,6 +8417,15 @@ If yes, remember the marker and the distance to BEG."
 	(narrow-to-region (car blockp) (cdr blockp))
       (user-error "Not in a block"))))
 
+(defun org-widen ()
+  "Widen buffer."
+  (interactive)
+  (save-excursion
+    (goto-char (point-max))
+    (when (string-match-p "^\\s-*$" (thing-at-point 'line))
+      (delete-char -1)))
+  (widen))
+
 (defun org-clone-subtree-with-time-shift (n &optional shift)
   "Clone the task (subtree) at point N times.
 The clones will be inserted as siblings.
-- 
2.20.1

             reply	other threads:[~2019-02-18  0:26 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-18  0:25 Leo Vivier [this message]
2019-02-18  0:25 ` [PATCH 2/2] Prevent deletion of newline added by narrowing Leo Vivier
2019-02-18  1:02   ` [PATCH] Fix other commands for exiting narrowing Leo Vivier
2019-02-18  1:21     ` [PATCH] Fix other commands for exiting narrowing (2) Leo Vivier
2019-02-18 17:18       ` [PATCH] Fix problems Leo Vivier
2019-02-19 10:01 ` [PATCH 1/2] Fix narrowing for 1-line subtrees Nicolas Goaziou
2019-02-19 10:24   ` Leo Vivier
2019-02-19 10:35     ` [PATCH] Fix narrowing for 1-line subtrees (squashed) Leo Vivier
2019-02-19 12:05     ` [PATCH 1/2] Fix narrowing for 1-line subtrees Nicolas Goaziou
2019-02-19 13:37       ` Leo Vivier
2019-02-19 15:28         ` Leo Vivier
2019-02-19 15:40           ` Leo Vivier
2019-02-20 13:25             ` Nicolas Goaziou
2019-02-20 13:36               ` Leo Vivier
2019-02-21 15:38                 ` [PATCH] Fix narrowed " Leo Vivier
2019-02-21 15:41                   ` Leo Vivier
2019-02-21 15:43                     ` [PATCH] Fix spaces with `org-remove-timestamp-with-keyword' Leo Vivier
2019-02-22 20:23                     ` [PATCH] Fix narrowed 1-line subtrees Leo Vivier
2019-02-22 20:54                       ` Leo Vivier
2019-02-22 21:53                         ` Samuel Wales
2019-02-22 22:04                           ` Leo Vivier
2019-02-22 23:58                             ` Samuel Wales
2019-02-23 10:43                               ` Leo Vivier

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=20190218002547.30325-1-leo.vivier@gmail.com \
    --to=leo.vivier@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    /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).