diff --git a/docs/configuration.org b/docs/configuration.org index 2936aae93..89e41e785 100644 --- a/docs/configuration.org +++ b/docs/configuration.org @@ -307,9 +307,9 @@ Possible values: - =true= - Uses /Virtual/ indents to align content visually. The indents are only visual, they are not saved to the file. - =false= - Do not add any /Virtual/ indentation. -You can toggle Virtual indents on the fly by setting =vim.b.org_indent_mode= to either =true= or =false= when in a org -buffer. For example, if virtual indents were enabled in the current buffer then you could disable them immediately by -setting ~vim.b.org_indent_mode = false~. +You can toggle Virtual indents on the fly by executing command =:Org indent_mode= when in a org buffer. +This additionally sets the buffer variable =vim.b.org_indent_mode= to =true= or =false=, depending on the current state. +Value of this buffer variable is then used to determine behavior of few options below. *** org_adapt_indentation :PROPERTIES: diff --git a/ftplugin/org.lua b/ftplugin/org.lua index a47f1165d..02fb08e49 100644 --- a/ftplugin/org.lua +++ b/ftplugin/org.lua @@ -6,18 +6,17 @@ vim.b.did_ftplugin = true local config = require('orgmode.config') -vim.b.org_bufnr = vim.api.nvim_get_current_buf() - vim.treesitter.start() -config:setup_mappings('org', vim.b.org_bufnr) -config:setup_mappings('text_objects', vim.b.org_bufnr) +local bufnr = vim.api.nvim_get_current_buf() + +config:setup_mappings('org', bufnr) +config:setup_mappings('text_objects', bufnr) config:setup_foldlevel() if config.org_startup_indented then - vim.b.org_indent_mode = true + require('orgmode.ui.virtual_indent'):new(bufnr):attach() end -require('orgmode.org.indent').setup_virtual_indent() vim.bo.modeline = false vim.opt_local.fillchars:append('fold: ') @@ -56,7 +55,7 @@ for _, char in ipairs({ '*', '=', '/', '+', '~', '_' }) do end if config.org_highlight_latex_and_related then - vim.bo[vim.b.org_bufnr].syntax = 'ON' + vim.bo[bufnr].syntax = 'ON' end vim.b.undo_ftplugin = table.concat({ @@ -70,5 +69,5 @@ vim.b.undo_ftplugin = table.concat({ 'formatexpr<', 'omnifunc<', 'indentkeys<', - '| unlet! b:org_bufnr b:org_tmp_edit_window', + '| unlet! b:org_tmp_edit_window', }, ' ') diff --git a/lua/orgmode/config/init.lua b/lua/orgmode/config/init.lua index 713cf2d03..06f616b5d 100644 --- a/lua/orgmode/config/init.lua +++ b/lua/orgmode/config/init.lua @@ -45,7 +45,6 @@ function Config:extend(opts) self.todo_keywords = nil self.priorities = nil opts = opts or {} - self:_deprecation_notify(opts) if not self:_are_priorities_valid(opts) then opts.org_priority_highest = self.opts.org_priority_highest opts.org_priority_lowest = self.opts.org_priority_lowest @@ -138,24 +137,6 @@ function Config:_are_priorities_valid(opts) return true end -function Config:_deprecation_notify(opts) - local messages = {} - if opts.org_indent_mode and type(opts.org_indent_mode) == 'string' then - table.insert( - messages, - '"org_indent_mode" is deprecated in favor of "org_startup_indented". Check the documentation about the new option.' - ) - opts.org_startup_indented = (opts.org_indent_mode == 'indent') - end - - if #messages > 0 then - -- Schedule so it gets printed out once whole init.vim is loaded - vim.schedule(function() - utils.echo_warning(table.concat(messages, '\n')) - end) - end -end - ---@return number function Config:get_week_start_day_number() return utils.convert_from_isoweekday(1) diff --git a/lua/orgmode/org/global.lua b/lua/orgmode/org/global.lua index b7ee6083e..fba0dba6a 100644 --- a/lua/orgmode/org/global.lua +++ b/lua/orgmode/org/global.lua @@ -91,6 +91,9 @@ local build = function(orgmode) orgmode.links:store_link_to_headline(headline) return require('orgmode.utils').echo_info('Stored: ' .. headline:get_title()) end, + indent_mode = function() + require('orgmode.ui.virtual_indent').toggle_buffer_indent_mode() + end, } _G.Org = OrgGlobal diff --git a/lua/orgmode/org/indent.lua b/lua/orgmode/org/indent.lua index 2bf6f7fc2..756bf3b15 100644 --- a/lua/orgmode/org/indent.lua +++ b/lua/orgmode/org/indent.lua @@ -322,18 +322,7 @@ local function foldtext() return line .. config.org_ellipsis end -local function setup_virtual_indent() - local virtualIndent = VirtualIndent:new() - - if config.org_startup_indented or vim.b.org_indent_mode then - return virtualIndent:attach() - end - - return virtualIndent:start_watch_org_indent() -end - return { - setup_virtual_indent = setup_virtual_indent, indentexpr = indentexpr, foldtext = foldtext, } diff --git a/lua/orgmode/ui/virtual_indent.lua b/lua/orgmode/ui/virtual_indent.lua index 0935664c4..c1b29988e 100644 --- a/lua/orgmode/ui/virtual_indent.lua +++ b/lua/orgmode/ui/virtual_indent.lua @@ -1,11 +1,9 @@ local tree_utils = require('orgmode.utils.treesitter') -local dict_watcher = require('orgmode.utils.dict_watcher') ---@class OrgVirtualIndent ---@field private _ns_id number extmarks namespace id ---@field private _bufnr integer Buffer VirtualIndent is attached to ---@field private _attached boolean Whether or not VirtualIndent is attached for its buffer ---@field private _bufnrs table Buffers with VirtualIndent attached ----@field private _watcher_running boolean Whether or not VirtualIndent is reacting to `vim.b.org_indent_mode` local VirtualIndent = { _ns_id = vim.api.nvim_create_namespace('orgmode.ui.indent'), _bufnrs = {}, @@ -23,13 +21,26 @@ function VirtualIndent:new(bufnr) end local this = setmetatable({ _bufnr = bufnr, - _watcher_running = false, _attached = false, }, self) self._bufnrs[bufnr] = this return this end +function VirtualIndent.toggle_buffer_indent_mode(bufnr) + bufnr = bufnr or vim.api.nvim_get_current_buf() + local instance = VirtualIndent:new(bufnr) + local message = '' + if vim.b[bufnr].org_indent_mode then + message = 'disabled' + instance:detach() + else + message = 'enabled' + instance:attach() + end + require('orgmode.utils').echo_info('Org-Indent mode ' .. message .. ' in current buffer') +end + function VirtualIndent:_delete_old_extmarks(start_line, end_line) local ok, old_extmarks = pcall( vim.api.nvim_buf_get_extmarks, @@ -117,32 +128,12 @@ function VirtualIndent:set_indent(start_line, end_line, ignore_ts) end end ---- Make all VirtualIndent instances react to changes in `org_indent_mode` -function VirtualIndent:start_watch_org_indent() - if self._watcher_running then - return - end - dict_watcher.watch_buffer_variable('org_indent_mode', function(indent_mode, _, buf_vars) - local instance = self._bufnrs[buf_vars.org_bufnr] - if not instance then - return - end - local indent_mode_enabled = indent_mode.new or false - if indent_mode_enabled then - return instance:attach() - end - return instance:detach() - end) - self._watcher_running = true -end - --- Enables virtual indentation in registered buffer function VirtualIndent:attach() if self._attached then return end self:set_indent(0, vim.api.nvim_buf_line_count(self._bufnr) - 1, true) - self:start_watch_org_indent() vim.api.nvim_buf_attach(self._bufnr, false, { on_lines = function(_, _, _, start_line, _, end_line) @@ -163,6 +154,7 @@ function VirtualIndent:attach() end, }) self._attached = true + vim.b[self._bufnr].org_indent_mode = true end function VirtualIndent:detach() @@ -171,6 +163,7 @@ function VirtualIndent:detach() end self:_delete_old_extmarks(0, vim.api.nvim_buf_line_count(self._bufnr) - 1) self._attached = false + vim.b[self._bufnr].org_indent_mode = false end return VirtualIndent diff --git a/lua/orgmode/utils/dict_watcher.lua b/lua/orgmode/utils/dict_watcher.lua deleted file mode 100644 index 929be9028..000000000 --- a/lua/orgmode/utils/dict_watcher.lua +++ /dev/null @@ -1,32 +0,0 @@ --- NOTE: Be aware of https://github.com/neovim/neovim/issues/21469. Upstream *might* decide to --- deprecate this, seems unlikely but something to keep an eye on. -local watchers = {} -local M = {} - ----@param change_dict { old?: any, new: any } ----@param key string ----@param dict table -function M.dict_changed(change_dict, key, dict) - if watchers[key] then - watchers[key](change_dict, key, dict) - end -end - ----@param key string ----@param callback fun(change_dict: { old?: any, new: any }, key: string, dict: table) -function M.watch_buffer_variable(key, callback) - vim.cmd(([[ - call dictwatcheradd(b:, '%s', 'OrgmodeWatchDictChanges') - ]]):format(key)) - watchers[key] = callback -end - ----@param key string -function M.unwatch_buffer_variable(key) - vim.cmd(([[ - call dictwatcherdel(b:, '%s', 'OrgmodeWatchDictChanges') - ]]):format(key)) - watchers[key] = nil -end - -return M diff --git a/plugin/orgmode.vim b/plugin/orgmode.vim deleted file mode 100644 index 91fdd19d5..000000000 --- a/plugin/orgmode.vim +++ /dev/null @@ -1,18 +0,0 @@ -" Wrapper around input() function that allows providing custom completion function -" @see https://github.com/neovim/neovim/issues/16301#issuecomment-968247015 -function! OrgmodeInput(prompt, default, ...) abort - let opts = { - \ 'prompt': a:prompt, - \ 'default': a:default, - \ 'cancelreturn': v:null, - \ } - - if a:0 > 0 && a:1 !=? v:null - let opts.completion = 'customlist,'..get(a:1, 'name') - endif - return input(opts) -endfunction - -function OrgmodeWatchDictChanges(dict, key, change_dict) abort - return luaeval('require("orgmode.utils.dict_watcher").dict_changed(_A[1], _A[2], _A[3])', [a:change_dict, a:key, a:dict]) -endfunction