Skip to content

Indentation increases with each item #472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
pianocomposer321 opened this issue Dec 17, 2022 · 14 comments
Open

Indentation increases with each item #472

pianocomposer321 opened this issue Dec 17, 2022 · 14 comments
Labels
non-core-feature Feature is not in orgmode core

Comments

@pianocomposer321
Copy link

pianocomposer321 commented Dec 17, 2022

Describe the bug

I'm having a hard time determining if this is intended or not...but it's really annoying and I'm not sure how to disable it, or if I'm just doing something wrong. The problem is that when I'm writing a list, instead of being on the same indentation level, it adds one on the new line. This is super confusing, and it also happens when org_indent_mode is set to noindent.

Steps to reproduce

When I start a list like so (| = cursor):

- List Item|

Then I press enter, I would expect this:

- List Item
|

But instead I get this:

 - List Item
   |

This means that repeatedly adding items gets each one indented an additional level, which is not what I want. If I want another level, I'll add one myself...

Expected behavior

Explained above.

Emacs functionality

Not really sure...I'm not an emacs user, and I'm not in a position to install it and check at the moment, but what demo videos I can find online do not seem to function the way this plugin does...though I think they're doing something more clever that I'm not sure is possible with neovim at all at the moment (with virtual indents and whatnot).

Minimal init.lua

The template works: https://github.com/nvim-orgmode/orgmode/blob/master/scripts/minimal_init.lua

vim.cmd([[set runtimepath=$VIMRUNTIME]])
vim.cmd([[set packpath=/tmp/nvim/site]])

local package_root = '/tmp/nvim/site/pack'
local install_path = package_root .. '/packer/start/packer.nvim'

local function load_plugins()
  require('packer').startup({
    {
      'wbthomason/packer.nvim',
      { 'nvim-treesitter/nvim-treesitter' },
      { 'kristijanhusak/orgmode.nvim', branch = 'master' },
    },
    config = {
      package_root = package_root,
      compile_path = install_path .. '/plugin/packer_compiled.lua',
    },
  })
end

_G.load_config = function()
  require('orgmode').setup_ts_grammar()
  require('nvim-treesitter.configs').setup({
    highlight = {
      enable = true,
      additional_vim_regex_highlighting = { 'org' },
    },
  })

  vim.cmd([[packadd nvim-treesitter]])
  vim.cmd([[runtime plugin/nvim-treesitter.lua]])
  vim.cmd([[TSUpdateSync org]])

  -- Close packer after install
  if vim.bo.filetype == 'packer' then
    vim.api.nvim_win_close(0, true)
  end

  require('orgmode').setup()

  -- Reload current file if it's org file to reload tree-sitter
  if vim.bo.filetype == 'org' then
    vim.cmd([[edit!]])
  end
end

if vim.fn.isdirectory(install_path) == 0 then
  vim.fn.system({ 'git', 'clone', 'https://github.com/wbthomason/packer.nvim', install_path })
  load_plugins()
  require('packer').sync()
  vim.cmd([[autocmd User PackerCompileDone ++once lua load_config()]])
else
  load_plugins()
  load_config()
end

Screenshots and recordings

No response

OS / Distro

Debian 11

Neovim version/commit

0.8.1

Additional context

No response

@pianocomposer321 pianocomposer321 added the bug Something isn't working label Dec 17, 2022
@pianocomposer321
Copy link
Author

pianocomposer321 commented Dec 17, 2022

I guess I'll be more specific about what I'd expect to happen:

After headlines, one indentation level should be added, but if I then type *, it should automatically de-dent. This would essentially fix #72 too.

After a list item, the indentation should stay the same. Increased or decreased nesting of subsequent items should be done by the user.

E.G.:

* Heading
  | <-- Cursor here

After typing *:

* Heading
*| <-- Cursor here
* Heading
   - List item| <-- Cursor here

After typing

* Heading
   - List item
   | <-- Cursor here

@pianocomposer321
Copy link
Author

If this is the intended behavior and I'm missing something, I'd love to hear what the right way to be doing this is :).

@jgollenz
Copy link
Contributor

I understand that the behavior you expect makes sense from your point of view, but I think it needs a bit more nuance. E.g.

* heading
  *something bold*

  - list
    --> important!

These would be very awkward to write with what you are proposing. Granted, you're more likely to add a new heading/list-item than doing what I did above. We surely can discuss whether your suggestion would be more beneficial.

Concerning your original issue: the reason (or at least that's how I interpret it) why indentation is added after pressing enter at the end of a list-item, is that you might want to write something that still belongs to the list-item in a new line:

* foo
  - Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
    sed eiusmod tempor incididunt ut labore et dolore magna aliqua.
  - Ut enim ad minim veniam, quis nostrud exercitation ullamco 
    laboris nisi ut aliquip ex ea commodo consequat.

If you want to add a new list-item, you can use <leader>ENTER (aka Meta-Return) in normal mode, with the cursor on the list-item. This also works on headings, although it will add a new heading right below the heading on which your cursor lies, not respecting the contents of the heading. If you want to add a new heading below the current one with respect to the headings content, press <leader>oih.

@jgollenz
Copy link
Contributor

I just checked and I can reproduce this with org_indent_mode = "noindent" as well. I don't think that this is intended

@jgollenz
Copy link
Contributor

Ok, in emacs the list-items still preserve the indentation on <ENTER>, even with org-indent-mode turned off. The behavior we have for list-items appears to be correct. However, we still preserve indentation on headlines, even when org-indent-mode is turned off. That should not be the case

@pianocomposer321
Copy link
Author

Thanks for responding, @jgollenz!

That's certainly interesting...it kinda feels like it's treating adding a new list item immediately like the edge case rather than the normal thing...but that's just me I guess. If that's the way the original org mode does it, then I guess it's correct 🤷.

Just to add in my perspective a little more I guess, most of the time in other word processors and stuff like that, pressing enter adds a new list item at the same level. If you want to adjust the level, you can normally do this with tab/shift-tab, backspace, or enter, or sometimes all three (i.e. tab increases level, shift-tab, backspace, and enter decrease level). Then shift-enter is often what is used to add a newline without adding a new list item.

 - List item|

Shift-CR:

 - List item
   |

CR:

 - List item
 - |

CR again:

 - List item
|

Tab:

 - List item
   - |

Shift-tab:

 - List item
 - |

Again, just throwing it out there. Compatibility with org mode, at least by default, makes sense. It's just that exiting normal mode and pressing <LEADER><CR> for every new list item feels a little strange to me.

@jgollenz
Copy link
Contributor

jgollenz commented Dec 17, 2022

I get your points. Even Github follows this conventions to a degree. They treat lists as bullet-lists per default. However, in general it's probably not fair to compare neovim to a word processor. If you indent text in neovim and then add a new line with <CR> it will also be indented on the same level.

There is an argument to be had whether its worthwhile to enable the functionality you mentioned with a flag. Generally speaking, this repo tries to be a port and only add additional features that make sense in the neovim world. Personally I think that this feature will result in more complexity. I'd rather spent more energy on trying to be faithful to emacs orgmode first.

Btw, in emacs this does not impact users as much, since they can just press META-RETURN (Alt-Enter) to get the same. Do you think having the same mapping in normal mode would solve this issue for you?

@jgollenz
Copy link
Contributor

@pianocomposer321 in any case, the title for this GH issue doesn't really describe a bug. Can you please remove the bug label and add the enhancement label? I'll add a separate issue for the bug concerning org_indent_mode

@pianocomposer321
Copy link
Author

pianocomposer321 commented Dec 17, 2022

Fair enough, that makes sense. Having <M-CR> do this would be sufficient.

I'm not actually sure how to change the labels on GH issues lol. I'm not seeing an x or anything to remove the bug label. 🤷

@jgollenz
Copy link
Contributor

I'm not seeing an x or anything to remove the bug label

I guess @kristijanhusak has to do that then

@kristijanhusak kristijanhusak added core-feature Feature is in orgmode core and removed bug Something isn't working labels Dec 19, 2022
@jgollenz jgollenz added non-core-feature Feature is not in orgmode core and removed core-feature Feature is in orgmode core labels Mar 2, 2023
@seflue
Copy link
Contributor

seflue commented Jun 30, 2023

I ran into the same issue. I think, we should provide org_meta_return also for insert mode. It feels very clunky to have to always exit insert mode when I need a new item (which is - as @pianocomposer321 already stated out) the more expected usecase.
It would allow a user, wo doesn't care about the current behavior to map <CR> to org_meta_return. And if you care about this, you could literally map it to <M-CR>, so you just have to hold Alt with your left thumb while hitting return to get a new item instead of <ESC><M-CR>.

troiganto pushed a commit to troiganto/orgmode that referenced this issue Aug 13, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
troiganto pushed a commit to troiganto/orgmode that referenced this issue Aug 13, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
troiganto pushed a commit to troiganto/orgmode that referenced this issue Aug 13, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
troiganto pushed a commit to troiganto/orgmode that referenced this issue Aug 13, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
troiganto pushed a commit to troiganto/orgmode that referenced this issue Sep 12, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
troiganto pushed a commit to troiganto/orgmode that referenced this issue Sep 27, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
troiganto pushed a commit to troiganto/orgmode that referenced this issue Sep 27, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
troiganto pushed a commit to troiganto/orgmode that referenced this issue Oct 1, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
troiganto pushed a commit to troiganto/orgmode that referenced this issue Oct 11, 2023
Closes nvim-orgmode#473.

I tried doing small fixes to this code, but kept running into edge
cases. Hence, this complete rewrite. :) The important points:

- The queries in `indent.scm` no longer match on top-level (i.e
  un-nested) lists, but instead on list items of all levels.

- List item indentation no longer relies on the previous non-empty line.
  Each list item stores whether it's in a top-level or a nested list and
  calculates its indent based on that.

- The check whether we are in bulleted line or not no longer uses
  `str.match()`, since its pattern was buggy and forgot a few kinds of
  bullets. (namely, indented `*` bullets and `a.` ordered bullets)
  Instead, we compare the current line number to `match.line_nr`. We can
  do that because we query list items instead of lists now.

There is an edge case when the user is appending to a list. We want that
next line to be indented (see nvim-orgmode#472), but it's technically outside of the
list. At the same time, if an unindented line follows a list, it should
not become part of the list.

The best solution I found for this was to make the behavior of
`indentexpr()` depend on whether we are in insert mode. If yes, the line
after a list is part of the list. If not, it isn't.

The new code also correctly takes into account that two consecutive
empty lines always end a preceding list.
@lyz-code
Copy link

lyz-code commented Feb 7, 2024

Has anyone found a way to create new list items without exiting to normal mode since the last comment?

@kristijanhusak
Copy link
Member

Support for this was added on the latest nightly branch. You can find docs about it here: https://github.com/nvim-orgmode/orgmode/blob/nightly/DOCS.md#use-enter-in-insert-mode-to-add-list-itemscheckboxestodos

@lyz-code
Copy link

lyz-code commented Feb 7, 2024

Thanks @kristijanhusak I can confirm that with the minimal configuration using nightly the <S-CR> works. It doesn't work with my current setup though probably due to this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
non-core-feature Feature is not in orgmode core
Projects
None yet
Development

No branches or pull requests

5 participants