nvim-orgmode / orgmode

Orgmode clone written in Lua for Neovim 0.9+.
https://nvim-orgmode.github.io/
MIT License
3.03k stars 134 forks source link

Set Default Fold Level #614

Closed orhnk closed 1 year ago

orhnk commented 1 year ago

Describe the bug

Initial setup folds all headers in an org file on startup.

You can disable this by:

vim.cmd [[setlocal nofoldenable]] -- No folds initially

With this in you config the headers don't fold anymore but folding works incorrect!

https://github.com/nvim-orgmode/orgmode/assets/101834410/2faa0fbc-c3cd-41e1-9bb4-133f2bffba3e

As you can see:

Steps to reproduce

  1. define setlocal nofoldenable in your config
  2. open a org file
  3. try to fold any header

Expected behavior

Wanted to see the merge-lang header folded only. (in the video)

Emacs functionality

Emacs works as it should

Minimal init.lua


vim.cmd [[setlocal nofoldenable]] -- No folds initially

Screenshots and recordings

No response

OS / Distro

archlinux

Neovim version/commit

NVIM v0.10.0-dev-bb38c06 Build type: RelWithDebInfo LuaJIT 2.1.1693350652

Additional context

No response

kristijanhusak commented 1 year ago

@UTFeight does your folds work correctly when you do not do setlocal nofoldenable?

orhnk commented 1 year ago

Here is how they look without setlocal nofoldenable:

https://github.com/nvim-orgmode/orgmode/assets/101834410/f7da69cb-299c-4314-b5e2-cc5b58cf5ad0

They do work how they should be now.

But there is no option to set as fold_depth which I want to see like the following:

[!NOTE] This is set foldlevel=99 And works exactly how I want it to work. But... (look at the next video)

https://github.com/nvim-orgmode/orgmode/assets/101834410/fb9eee42-3a20-471f-a82c-2f2ca26c3a1e

[!NOTE] Using set foldlevel=99 loaded after the config, seems to not work?

https://github.com/nvim-orgmode/orgmode/assets/101834410/7068e947-1cce-4a79-aa05-2ed698d3f8c5


for some nice blue switch ASMR, you can unmute videos :D

orhnk commented 1 year ago

I have found a solution for this!

adding options after lazy loading the plugin didn't work well so this was happening.

Solution

Autocmd Version:

-- (Put that in init.lua if you don't have an option like mine)
vim.cmd [[autocmd FileType org setlocal nofoldenable]] -- No folds initially
vim.cmd [[autocmd FileType org setlocal foldlevel=99]]
PriceHiller commented 1 year ago

Without UFO I can reproduce this issue, I have attached a minimal init.

Here's a minimal init that reproduces the folding behavior ```lua local M = {} ---@class MinPlugin A plugin to download and register on the package path ---@alias PluginName string The plugin name, will be used as part of the git clone destination ---@alias PluginUrl string The git url at which a plugin is located, can be a path. See https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols for details ---@alias MinPlugins table local base_root_path = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":p:h") .. "/.min" ---Gets the root directory of the minimal init and if path is specified appends the given path to the root allowing for ---subdirectories within the current cwd ---@param path string? The additional path to append to the root, not required ---@return string root The root path suffixed with the path provided or an empty suffix if none was given function M.root(path) return base_root_path .. "/" .. (path or "") end ---Downloads a plugin from a given url and overwrites the 'packpath' to the new plugin package path ---@param plugin_name PluginName ---@param plugin_url PluginUrl function M.load_plugin(plugin_name, plugin_url) local package_root = M.root("plugins/") local install_destination = package_root .. plugin_name vim.opt.runtimepath:append(install_destination) if not vim.loop.fs_stat(package_root) then vim.fn.mkdir(package_root, "p") end -- If the plugin install path already exists, we don't need to clone it again. if not vim.loop.fs_stat(install_destination) then print(string.format("> Downloading plugin '%s' to '%s'", plugin_name, install_destination)) vim.fn.system({ "git", "clone", "--depth=1", plugin_url, install_destination, }) if vim.v.shell_error > 0 then error(string.format("> Failed to clone plugin: '%s' in '%s'!", plugin_name, install_destination), vim.log.levels.ERROR) end end end ---@class MinSetupConfig ---@field root? string The base path to use for all data storage, if nil the root will be set to this module's directory ---@field plugins? MinPlugins The plugins to install and register on the runtimepath ---Do the initial setup. Downloads plugins, ensures the minimal init does not pollute the filesystem by keeping ---everything self contained to the CWD of the minimal init file. Run prior to running tests, reproducing issues, etc. ---READ: It is on the user to setup the plugins, this only registers them to the runtime path, it does NOT set them up! ---@param config? MinSetupConfig function M.setup(config) vim.opt.packpath = {} -- Empty the package path so we use only the plugins specified vim.opt.runtimepath:append(M.root(".min")) -- Ensure the runtime detects the root min dir if config ~= nil then if config.root ~= nil then base_root_path = config.root end -- Install required plugins if config.plugins ~= nil then for plugin_name, plugin_url in pairs(config.plugins) do M.load_plugin(plugin_name, plugin_url) end end end vim.env.XDG_CONFIG_HOME = M.root("xdg/config") vim.env.XDG_DATA_HOME = M.root("xdg/data") vim.env.XDG_STATE_HOME = M.root("xdg/state") vim.env.XDG_CACHE_HOME = M.root("xdg/cache") -- NOTE: Cleanup the xdg cache on exit so new runs of the minimal init doesn't share any previous state, e.g. shada vim.api.nvim_create_autocmd("VimLeave", { callback = function() vim.fn.system({ "rm", "-r", "-f", M.root("xdg") }) end }) end -- NOTE: If you have additional plugins you need to install to reproduce your issue, include them in the plugins -- table within the setup call below. M.setup({ plugins = { treesitter = "https://github.com/nvim-treesitter/nvim-treesitter", orgmode = "https://github.com/nvim-orgmode/orgmode", } }) -- WARN: Do all plugin setup, test runs, reproductions, etc. AFTER calling setup with a list of plugins! -- Basically, do all that stuff AFTER this line. -- Load treesitter grammar for org require("orgmode").setup_ts_grammar() -- Setup treesitter vim.opt.foldexpr = "nvim_treesitter#foldexpr()" require("nvim-treesitter.configs").setup({ highlight = { enable = true, additional_vim_regex_highlighting = { "org" }, }, ensure_installed = { "org" }, sync_install = true }) -- Setup orgmode vim.opt.foldlevel = 99 require("orgmode").setup({}) vim.cmd.edit("tester.org") vim.api.nvim_buf_set_lines(0, 0, -1, false, { "* Heading uno", "", "** Inner Heading One", "", "** Inner Heading Two", "", "* Another toplevel heading", "", }) vim.cmd.write() -- Have to make treesitter happy so we get correct folds. So we have to write after writing the content, TS wasn't -- ready. local timer = vim.loop.new_timer() timer:start(100, 0, vim.schedule_wrap(function() vim.cmd.edit() print("Notice that some of the content is already folded when opened... this shouldn't be the case.") timer:close() end)) ```

Just copy and paste that big 'ol beast and run it with nvim -nu MINIMAL_INIT_FILE_NAME.lua. It'll show the issue.

Orgmode is overriding the foldlevel to 0 and doesn't respect the foldlevel a user may have set. It does that here.

Ideally Orgmode wouldn't mess with the foldlevel as it is 0 by default and if a user changed that it really should respect the custom foldlevel.

I think I have fixed the issues with UFO as well by commenting out the fillchars line as well in the ftplugin file, link to that.

When both the foldlevel and fillchars lines are removed from the ftplugin/org.vim file, UFO and my foldlevel settings work as expected.

@kristijanhusak Is there a particular reason Orgmode ignores user configuration of fillchars & foldlevel? If so, I'll see if I can find an alternative work around.

orhnk commented 1 year ago

Orgmode is overriding the foldlevel to 0 and doesn't respect the foldlevel a user may have set. It does that here.

@treatybreaker That looks like a PR!

kristijanhusak commented 1 year ago

@treatybreaker I understand why foldlevel might be an issue, but I'm not sure why would fillchars cause an issue? We could introduce org-startup-folded as described here https://orgmode.org/manual/Initial-visibility.html and have it's value as overview by default. This value would set foldlevel to 0 as it does now. This is just to keep everything backward compatible. Valid options would be overview (foldlevel=0), content (foldlevel=1), showeverything (foldlevel=99) and nil (no foldlevel set). Then we should read this configuration and act accordingly.

PriceHiller commented 1 year ago

@kristijanhusak

So the fillchars may be more relevant to #599, as the fold fillchars interfere with nvim-ufo's fold chars.

In terms of foldlevel, would you accept a PR with that variable org-startup-folded? I'd be more than happy to send it your way.

Arguably though we don't even need options for that as Neovim has buffer options which a user could set themselves or just the filetype plugin in their after directory to set the foldlevel. It's basically built-in. The best way to handle this may just be to just not set the foldlevel at all and mention it in the docs.

kristijanhusak commented 1 year ago

In terms of foldlevel, would you accept a PR with that variable org-startup-folded? I'd be more than happy to send it your way.

Yes, please send it over. I'd like to streamline it through configuration.