Skip to content
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

feat(ui): virtual indent #561

Closed
wants to merge 8 commits into from

Conversation

danilshvalov
Copy link
Contributor

@danilshvalov danilshvalov commented May 10, 2023

Preview

virtual-indent.mov

How to try it

  1. Install neovim with feat(ui): inline virtual text (2) neovim/neovim#23426

  2. Add the following code to your orgmode configuration:

local VirtualIndent = require("orgmode.ui.virtual-indent"):new()
VirtualIndent:attach()

TODO

  • Customizable indentation size (hidden or visible stars, possibly custom indentation)
  • Documentation

@danilshvalov danilshvalov changed the title feat(ui): add virtual indent feat(ui): virtual indent May 10, 2023
@IllustratedMan-code
Copy link

This looks great! Hopefully inline virtual text gets merged soon.

@danilshvalov
Copy link
Contributor Author

It has happened! Virtual text is merged into the master branch! So I've made some changes, now you can enable virtual indent as follows:

require("orgmode").setup({
  org_indent_mode = "virtual_indent",
  ui = {
    virtual_indent = {
      handler = nil,
      --- or
      handler = function(buffer, start_line, end_line)
        -- ...
      end,
    },
  },
})

@danilshvalov danilshvalov marked this pull request as ready for review May 22, 2023 14:49
@danilshvalov
Copy link
Contributor Author

Ready for review

Copy link
Member

@kristijanhusak kristijanhusak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PoC!

Generally looks ok, but I think we need to do some additional tweaking.
Check my comments.

@@ -175,6 +175,9 @@ local DefaultConfig = {
menu = {
handler = nil,
},
virtual_indent = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we need a custom handler for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, if the user wants to make virtual indents with indent lines (something like indent-blankline.nvim). Or change the size of the indentation. Or make the indentation colored depending on its size or title. It is quite difficult to cover all the options, so the user can provide his own handler.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this option for the time being. Once the feature is officially released and there is a proper Neovim release with the support, we can expand on it.

@@ -194,8 +195,15 @@ local function foldtext()
return line .. config.org_ellipsis
end

local function setup()
if config.org_indent_mode == 'virtual_indent' then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to check if value is noindent here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? And if the user doesn't want any indentation? I see three options for using indentation:

  1. No indentation
  2. Virtual indentation
  3. Real indentation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No indentation was initially meant to be used as virtual indentation.
If you check in the Emacs docs, there are two values, indent and noindent (https://orgmode.org/manual/Org-Indent-Mode.html)

Problem is that I set the indent as default, where it should actually be noindent. indent option is actually a virtual indent. I'll fix that and announce it on the breaking change issue so people are aware. Once I do that you will actually have to check for indent value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not have 3 options? Yes, this is somewhat at odds with emacs, but it makes the configuration more flexible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noindent option as it is now is not useful at all. Everything is aligned to the left. As far as I know, people are now using it only to get proper formatting with other tools, like Orgzly. What we have now by default will become noindent, and this PR will introduce a proper indent option. There's no need for 3rd.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it may be weird, but some people don't use indentation. Some time ago I came across this discussion and found out that not everyone needs indents (see the first comment).

In addition, if you break backward compatibility with indent, quite a lot of org files can be visually broken. I'm not sure if this is a good idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can allow that functionality by doing the same thing that Emacs does, via org-adapt-indentation option. The discussion has a few comments explaining how it works.


self:set_indent(buffer, 0, vim.api.nvim_buf_line_count(buffer) - 1)

vim.api.nvim_buf_attach(buffer, true, {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need vim.schedule in the callback?

Also, is there any advantage of using nvim_buf_attach over nvim_set_decoration_provider ?
We use decoration provider for markup, so we could maybe use the same for this while using the ephermal ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need vim.schedule, because otherwise, when undoing, the virtual indent handler is called too early and processed incorrectly.

As far as I know, ephemeral virtual text has not been implemented yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave it a quick test, and it seems to work. Switching to it should reduce some code that does the cleanup. Lets try switching to decoration provider and see if it works out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it true? I get E5108: Error executing lua [string ":lua"]:1: not yet implemented error.

Here is the code I run:

vim.api.nvim_buf_set_extmark(0, vim.api.nvim_create_namespace("test"), 0, 1, {virt_text_pos = "inline", virt_text = {{"    "}}, ephemeral = true})

My neovim version is NVIM v0.10.0-dev-410+gc48f94d1f

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I get the point. I'll try to redo it

@milanglacier
Copy link
Contributor

This is one of the most missing UI features of emacs in neovim! I am glad that finally, this is implemented!

@kristijanhusak kristijanhusak force-pushed the master branch 2 times, most recently from 9094379 to abff0dc Compare November 6, 2023 20:52
@PriceHiller PriceHiller mentioned this pull request Nov 9, 2023
@kristijanhusak
Copy link
Member

Closing this since it was resolved in #627

@PriceHiller
Copy link
Contributor

Thanks @danilshvalov for the initial work 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants