From mboxrd@z Thu Jan 1 00:00:00 1970 From: Leo Vivier Subject: [PATCH 1/2] Fix narrowing for 1-line subtrees Date: Mon, 18 Feb 2019 01:25:46 +0100 Message-ID: <20190218002547.30325-1-leo.vivier@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Return-path: Received: from eggs.gnu.org ([209.51.188.92]:53394) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gvWl1-00021h-0s for emacs-orgmode@gnu.org; Sun, 17 Feb 2019 19:26:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gvWkz-0006rl-Ba for emacs-orgmode@gnu.org; Sun, 17 Feb 2019 19:26:02 -0500 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:37530) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gvWkz-0006px-43 for emacs-orgmode@gnu.org; Sun, 17 Feb 2019 19:26:01 -0500 Received: by mail-wr1-x433.google.com with SMTP id c8so16430656wrs.4 for ; Sun, 17 Feb 2019 16:25:58 -0800 (PST) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: emacs-orgmode@gnu.org Cc: Leo Vivier * 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