neorg
neorg copied to clipboard
core.itero.next-iteration should respect groups
Issues
- [X] I have checked existing issues and there are no existing ones with the same request.
Feature description
Best explained by example. When you are in this position (note the cursor pipe):
- item 1
- item 2|
-- item 2a
-- item 2b
And you call core.itero.next-iteration
, the result should be:
- item 1
- item 2
-- item 2a
-- item 2b
- |
But instead, you get:
- item 1
- item 2
- |
-- item 2a
-- item 2b
As though items item 2a
and item 2b
are suddenly part of the forthcoming item 3
.
Help
Yes
Implementation help
I am not sure how to contribute this, but I'm sure I could sort it out. The main questions are, do others agree and unfortunately do I have enough time?
I came here to make a similar request. Where I find that the current behavior to be a problem is when navigating around the file in normal mode, since then I'm unlikely to have the cursor at the end of the current list item or heading section. I've made a normal mode keybinding to core.itero.next-iteration
to <C-CR>
(Control + Enter) to match the behavior in Doom Emacs org-mode, for which <C-CR>
calls '+org/insert-item-below
(see Doom's config.el for the org-mode module)
Here's an example in a Norg file,
* Heading 1
some text for heading 1
** Heading 1.1 [A]
some more text that spans [B]
multiple lines [C]
** Heading 1.2
Here I'm using [A] [B] and [C] to mark lines. In Doom Emacs, pressing Control + Enter in normal mode (or in insert mode) with the cursor anywhere in these lines will create a new level 2 heading right above ** Heading 1.2
. But core.itero.next-iteration
in Norg starts the new heading on the like right after wherever the cursor is.
Another place where this would come up is if you are typing a list and have a list item spanning multiple lines that you enter normal mode to edit, then want to continue the list. With the current behavior, you have to make sure your cursor is on the last line of that list item.
I'm guessing that part of why the behavior is how it currently is is that the use case in mind was when you are first actively typing a list in insert mode and so the cursor is at the end of the line; but the current behavior doesn't seem to generalize well to other contexts.
I haven't worked directly with treesitter myself before, but I'm guessing the functionality that @theherk and I are asking for could be handled by a function that uses treesitter to find the end of the appropriate subtree and insert the new heading or list item there.
One question I have is whether we should change the behavior of core.itero.next-iteration
or instead a new function (which we might call core.itero.insert-item-below
after org-mode) to allow users to choose which function they keybind to. In other words, are there cases where users would prefer the current behavior instead of the behavior that we're suggesting here?
I might try to figure this out over the holidays, though lua + treesitter + plugins are all new to me so. While we're at it, we might as well try to add an equivalent to org-mode's +org/insert-item-above
(which is bound to Control+Shift+Enter in Doom Emacs)
Did some hacking on this and think I've achieved the desired behavior by changing the end of the definition of the next-iteration
starting at https://github.com/nvim-neorg/neorg/blob/9021c7c7eefc1e11a8f1591f8cba5e118405336b/lua/neorg/modules/core/itero/module.lua#L140 to
-- Determine the row to insert the new line after the end of the
-- current node. There are two cases; for list items that are followed
-- by a blank line, the end of the node as returned by treesitter will
-- be on the line with text (in which case, we need to add 1 to then
-- end row); for other cases, it will be at column 0 of the following
-- line (in which case we can use the end row).
local end_row, end_col = current:end_()
cursor_pos = end_row + (end_col == 0 and 0 or 1)
vim.api.nvim_buf_set_lines(
event.buffer,
cursor_pos,
cursor_pos,
true,
{ string.rep(" ", column) .. text_to_repeat .. (should_append_extension and "( ) " or "") }
)
vim.api.nvim_win_set_cursor(
event.window,
{ cursor_pos + 1, column + text_to_repeat:len() + (should_append_extension and ("( ) "):len() or 0) }
)
end
end
The if/else clause to determine the cursor_pos
is to handle the issue I noted in https://github.com/nvim-neorg/tree-sitter-norg/issues/58