syl20bnr / spacemacs

A community-driven Emacs distribution - The best editor is neither Emacs nor Vim, it's Emacs *and* Vim!
http://spacemacs.org
GNU General Public License v3.0
23.58k stars 4.9k forks source link

org-paste-subtree inserts empty line above paste #16274

Closed felixwiemuth closed 3 weeks ago

felixwiemuth commented 5 months ago

Description :octocat:

When pasting a subtree into an empty heading (line starting with some ***, which can be used to set the level of the pasted tree) with org-paste-subtree, an empty line is inserted above the inserted subtree.

I would expect no new line to be inserted, and I think this was the behaviour before I noticed this.

The value of org-blank-before-new-entry is ((heading) (plain-list-item)), which should mean no empty lines. And I think it is this variable which worked before, but stopped working (already in 2020-01, where I noticed the problem).

This does not seem to be a bug in org-mode itself, as it does not happen in plain emacs (tested 2022-09).

In case it is related, and someone takes a look at it, I'd like to mention that it sometimes happens that more then the last cut/yanked subtree is pasted, namely subtree(s) from below the yanked or something that was in the kill ring already (if I recall correctly).

Reproduction guide :beetle:

Fresh spacemacs installation with evil mode and minimal packages

Copy (yank) the following

* Hello
** World

and paste (org-paste-subtree) at position "_" here:

* One
** Two
** _

It does not matter whether in insert mode or navigation mode (using evil).

Observed behaviour: :eyes: :broken_heart:

* One
** Two

** Hello
*** World

Expected behaviour: :heart: :smile:

* One
** Two
** Hello
*** World

System Info :computer:

smile13241324 commented 3 months ago

Hmmm this sounds like a package issue to me when I am honest, can you go ahead and try to reproduce the issue on a vanilla emacs first? I don't think that we have any custom org paste functions implemented.

felixwiemuth commented 3 months ago

I had tested it in vanilla emacs (see date above) and it was not reproducible there. But it does happen in a fresh spacemacs installation.

fnussbaum commented 2 months ago

org-paste-subtree does not insert empty lines, it just skips over any existing lines and pastes the subtree just before the next heading or at the end of the buffer. If point is positioned after the asterisks in an otherwise empty heading when invoking it, as in the example above, the asterisks are effectively moved to where the subtree is inserted. This behaviour was changed in Org 9.3, here is the corresponding changelog entry and part of the corresponding source code:

*** ~org-paste-subtree~ no longer breaks sections

Unless point is at the beginning of a headline, ~org-paste-subtree~
now pastes the tree before the next visible headline.  If you need to
break the section, use ~org-yank~ instead.

(from https://github.com/emacs-mirror/emacs/blob/3dfca6f9c7f4da512fff48cf6957c6492e2c0449/etc/ORG-NEWS#L2726)

       ;; Remove the forced level indicator.
       (when (and force-level (not level))
         (delete-region (line-beginning-position) (point)))
       ;; Paste before the next visible heading or at end of buffer,
       ;; unless point is at the beginning of a headline.
       (unless (and (bolp) (org-at-heading-p))
         (org-next-visible-heading 1)
         (unless (bolp) (insert "\n")))

So the behaviour observed above could be due either to a mismatch in the Org versions, or to the presence or absence of newline characters at the end. In my tests, the behaviour in Spacemacs seemed to be consistent with emacs -Q.

felixwiemuth commented 2 months ago

Thanks for sharing this observation and testing again with plain emacs. Regarding that 9.3 was release in 12/2019, there is a time-wise relation as I discovered the issue in 01/2020.

However, regarding that I tested with plain emacs 2022, I don't think this was due to an old version. emacs -Q is somehow not reliably having the org-paste-subtree command (it suddenly was available after some time), and copy or yank and then org-paste-subtree fails ("is not a tree").

Regarding a newline character after point where pasting, this indeed makes a difference (tested in Spacemacs, orgmode 9.6.15):

It is enough that point is on a single space after the ** for the newline to occur after pasting, whether that space ends the line or more spaces are following. Basically it seems that all whitespace after asterisk (whether point is on asterisk or whitespace) is jumped over and put on a line between ** Two and the pasted subtree.

fnussbaum commented 2 months ago

Thanks, I can reproduce your observations. For me, the behaviour in Spacemacs and emacs -Q seems consistent, there is only the following difference due to evil-mode: When leaving evil-insert-state, the cursor moves back one character by default. See the variables evil-move-cursor-back and evil-move-beyond-eol. I included this observation previously in another comment, but deleted it now as it did not address the crux of the matter.

I found a thread corresponding to your issue on the Org mailing list, and it has just been fixed. In my tests it also works well with the default behaviours of the evil cursor. I would expect the fix to be included in the next Org release, presumably 9.6.28.

smile13241324 commented 3 weeks ago

Upstream issue therefore I am going to close it

felixwiemuth commented 3 weeks ago

Thanks @fnussbaum for further investigation and the reference to the thread on the org mailing list!