[O] [PATCH] Save buffer in org-capture-refile

2018-09-05 Thread Andrew Burgess
I notice that if a capture template sets ':kill-buffer t', and I use
org-capture-refile to refile into a different file then I don't get
the result I expect.

Let me give an example, here's my setup:

  $ mkdir ~/tmp
  $ cd ~/tmp
  $ echo "* loc1/tasks" > loc1.org
  $ echo "* inbox/tasks" > inbox.org
  $ cat test.el
  (setq org-capture-templates
'(("t" "TASK that needs completing" entry
   (file+headline "~/tmp/inbox.org" "inbox/tasks")
   "** TODO %?"
   :prepend t :kill-buffer t)))
  (setq org-refile-targets (quote (("~/tmp/loc1.org" :maxlevel . 2
  $ emacs -Q -l test.el

Now in emacs:

  org-capture # Start a capture
  t   # Select the template 't'
  AA  # Fill in a task title
  org-capture-refile  # Start refiling
  l  # Select refile location, should complete to
  # 'loc1/tasks (loc1.org)'

At this point you should see the message:

  Buffer inbox.org modified; kill anyway? (yes or no)

Neither answer gets you the result you want (I think).

If you choose 'yes', then quit emacs (saving buffers as you go[1])
you'll find that task 'AA' is now in both inbox.org and loc1.org.

If you choose 'no', then quit emacs (saving buffers as you go) you'll
find that the task has moved out of inbox.org into loc1.org, but,
clearly the requested ':kill-buffer t' wasn't respected.

The problem is that org-capture-refile calls org-capture-finalize, but
suppresses the call to kill-buffer in org-capture-finalize, instead
performing that call itself.  However, org-capture-finalize calls
save-buffer, before calling kill-buffer, org-capture-refile doesn't.

If I add a call to save-buffer into org-capture-refile in a similar
fashion to the call in org-capture-finalize, then I get the behaviour
I expect.

My employer Embecosm should already have a copyright assignment on
file for emacs.

[1] I think that there's an argument to be made that, if the refile
destination is opened just for the purpose of refiling this item, and
':kill-buffer t' is in place, then org-capture-refile should probably
kill the refile destination too.  However, though related, I think
that's a separate issue.

Thanks,
Andrew

---

In org-capture-finalize if the capture template requests that the
capture buffer be killed, we first save the buffer, and then kill it.

However, org-capture-refile suppresses the killing of the buffer in
org-capture-finalize and performs the call to kill-buffer itself,
however, it doesn't save the buffer.  The result is that the user is
prompted with a "buffer has been modified, kill anyway?" message.  At
this point answering yes will leave the item being refiled in both the
source and destination locations, while answering no will leave the
buffer around (which isn't what the user wanted).

The solution is to call save-buffer in org-capture-refile, just like
it is called in org-capture-finalize.
---
 lisp/org-capture.el | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 993526fcb..33f1af147 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -877,7 +877,9 @@ for `entry'-type templates"))
  (org-with-wide-buffer
   (goto-char pos)
   (call-interactively 'org-refile
- (when kill-buffer (kill-buffer base))
+ (when kill-buffer
+   (with-current-buffer base (save-buffer))
+   (kill-buffer base))
  (when jump-to-captured (org-capture-goto-last-stored)))
   (set-marker pos nil
 
-- 
2.14.4




Re: [O] electric-indent-mode in Emacs 25 not indenting in Org

2014-10-21 Thread Andrew Burgess
* William Denton w...@pobox.com [2014-10-15 22:13:16 -0400]:

 I noticed something odd with electric-indent-mode, which I had enabled, and
 which is on by default in 24.4.

I think the problem is with the calls to `newline' within org-return.

The code for `newline' was changed so that non-interactive calls don't
run the post-self-insert-hook, the result is that the
electric-indent-post-self-insert-function is not called.

HTH
Andrew



[O] [PATCH] org-capture-place-item better alignment for new lists.

2014-10-07 Thread Andrew Burgess
Creating an entry in org-capture-templates of type item adds entries
into a list, however, if the list is empty then the first list item
will be indented to depth 0 (so hard on the left) like this:

* Top Level
** Second Level
- item #1
- item #2
- item #3

I prefer to indent content, including lists, to a level matching the
parent, so something like this:

* Top Level
** Second Level
   - item #1
   - item #2
   - item #3

The patch below changes org-capture-place-item so that, when starting
a new list, the items are indented as in the second example above.

The existing behaviour is maintained when adding additional items to a
list, that is the indentation of new items will match the indentation
on items already in the list.

All feedback welcome,

Thanks,
Andrew


lisp/org-capture.el (org-capture-place-item): When starting a
new list use (1+ org-current-level) rather than just 0 for the
indentation. This ensures new lists are indented under their
parent element.
---
 lisp/org-capture.el | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 9e33d25..150ba1e 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -1064,7 +1064,7 @@ may have been stored before.
   Place the template as a new plain list item.
   (let* ((txt (org-capture-get :template))
 (target-entry-p (org-capture-get :target-entry-p))
-(ind 0)
+(ind (1+ (org-current-level)))
 beg end)
 (if (org-capture-get :exact-position)
(goto-char (org-capture-get :exact-position))
@@ -1078,18 +1078,13 @@ may have been stored before.
   (if (org-capture-get :prepend)
  (progn
(goto-char beg)
-   (if (org-list-search-forward (org-item-beginning-re) end t)
-   (progn
- (goto-char (match-beginning 0))
- (setq ind (org-get-indentation)))
- (goto-char end)
- (setq ind 0)))
+   (when (org-list-search-forward (org-item-beginning-re) end t)
+ (goto-char (match-beginning 0))
+ (setq ind (org-get-indentation
(goto-char end)
-   (if (org-list-search-backward (org-item-beginning-re) beg t)
-   (progn
- (setq ind (org-get-indentation))
- (org-end-of-item))
- (setq ind 0
+   (when (org-list-search-backward (org-item-beginning-re) beg t)
+ (setq ind (org-get-indentation))
+ (org-end-of-item
 ;; Remove common indentation
 (setq txt (org-remove-indentation txt))
 ;; Make sure this is indeed an item
-- 
1.9.3




Re: [O] [PATCH] org-capture-place-item better alignment for new lists.

2014-10-07 Thread Andrew Burgess
* Nicolas Goaziou m...@nicolasgoaziou.fr [2014-10-07 15:49:09 +0200]:


 Thanks for the patch.

 However, this behaviour is wrong when `org-adapt-indentation' is nil.

 It is better to use `org-indent-line' than hard-coding

   (1+ (org-current-level)).


Thanks for taking a look at the patch, and thanks for the feedback. I
did suspect I'd have missed something.

I've revised the patch (below) so that I now use org-indent-line to
establish the best indentation if we're starting a new list, this has
resulted in slightly more churn, but hopefully not too much.

Thanks,
Andrew

---

Creating an entry in org-capture-templates of type item adds entries
into a list, however, currently, if the list is empty then the first
list item will always be indented to depth 0 (so hard on the left),
which looks like this:

* Top Level
** Second Level
- item #1
- item #2
- item #3

This is fine if org-adapt-indentation is nil, however, with the
default value of t lists should be indented more like this:

* Top Level
** Second Level
   - item #1
   - item #2
   - item #3

The patch below changes org-capture-place-item so that, when starting
a new list, the items are indented as above.

Care is taken to preserve two features of the existing behaviour,
first, when adding to an existing list, new items are indented to match
the items already in the list. And secondly, when there is some
introductory text before the list new items are inserted after the
text, like this:

* Top Level
** Second Level
   This is some introductory text:
   - item #1
   - item #2
   - item #3

lisp/org-capture.el (org-capture-place-item): When starting a
new list use org-indent-line to establish the correct
indentation rather than just using 0.
---
 lisp/org-capture.el | 35 ---
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 9e33d25..094ff55 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -1075,21 +1075,19 @@ may have been stored before.
(t
(setq beg (1+ (point-at-eol))
  end (save-excursion (outline-next-heading) (point)
+  (setq ind nil)
   (if (org-capture-get :prepend)
  (progn
(goto-char beg)
-   (if (org-list-search-forward (org-item-beginning-re) end t)
-   (progn
- (goto-char (match-beginning 0))
- (setq ind (org-get-indentation)))
- (goto-char end)
- (setq ind 0)))
+   (when (org-list-search-forward (org-item-beginning-re) end t)
+ (goto-char (match-beginning 0))
+ (setq ind (org-get-indentation
(goto-char end)
-   (if (org-list-search-backward (org-item-beginning-re) beg t)
-   (progn
- (setq ind (org-get-indentation))
- (org-end-of-item))
- (setq ind 0
+   (when (org-list-search-backward (org-item-beginning-re) beg t)
+ (setq ind (org-get-indentation))
+ (org-end-of-item)))
+  (unless ind
+   (goto-char end)))
 ;; Remove common indentation
 (setq txt (org-remove-indentation txt))
 ;; Make sure this is indeed an item
@@ -1097,17 +1095,24 @@ may have been stored before.
   (setq txt (concat - 
(mapconcat 'identity (split-string txt \n)
   \n  
+;; Prepare surrounding empty lines
+(org-capture-empty-lines-before)
+(setq beg (point))
+(unless (eolp)
+  (insert \n)
+  (previous-line))
+(unless ind
+  (org-indent-line)
+  (setq ind (org-get-indentation))
+  (delete-region beg (point)))
 ;; Set the correct indentation, depending on context
 (setq ind (make-string ind ?\ ))
 (setq txt (concat ind
  (mapconcat 'identity (split-string txt \n)
 (concat \n ind))
  \n))
-;; Insert, with surrounding empty lines
-(org-capture-empty-lines-before)
-(setq beg (point))
+;; Insert
 (insert txt)
-(or (bolp) (insert \n))
 (org-capture-empty-lines-after 1)
 (org-capture-position-for-last-stored beg)
 (forward-char 1)
-- 
1.9.3