SidOfc/mkdx

Reloading vimrc within Vim breaks

Battleman opened this issue · 9 comments

OS type:

  • Unix
  • Windows
  • Other ([SPECIFY])

Vim:

  • vim
  • neovim
  • Other ([SPECIFY])

Vim version: 8.2.716
Configuration:

  • Plugin manager: Vundle
  • Relevant vimrc parts:
let g:mkdx#settings     = { 'highlight': { 'enable': 1 },
                        \ 'enter': { 'shift': 1 },
                        \ 'links': { 'external': { 'enable': 0 } },
                        \ 'toc'  : { 'text': 'Table of Contents', 'update_on_write': 1 },
               	\ 'fold' : { 'enable': 1 },
			\ 'tab'  : { 'enable': 1 } }

Not sure if the rest of the vimrc is relevant

Reproduce steps:

  • Open a markdown file test.md
  • Write anything
  • Go to normal mode, type :so $MYVIMRC and enter
  • Try to insert a new line (Enter in insert mode, o or O in normal mode)

Expected:
A simple new line is created

Actual:
A new line is created, but an error is thrown (for each new line). It depends on the method used to create a new line:
Enter:

Error detected while processing function mkdx#EnterHandler:                                                                                                                                                                          
line    3:
E716: Key not present in Dictionary: enable && !empty(line))

o:

Error detected while processing function mkdx#OHandler:                                                                                                                                                                               
line    1:
E716: Key not present in Dictionary: o || !g:mkdx#settings.enter.enable)

O:

Error detected while processing function mkdx#ShiftOHandler:                                                                                                                                                                           
line    1:
E716: Key not present in Dictionary: shifto || !g:mkdx#settings.enter.enable)

Hello @Battleman,

Hmn interesting indeed, does your vim has('*dictwatcheradd')? when true, mkdx listens to setting updates and tries to validate them and update the document instantly, this can be disabled by setting g:mkdx#settings = { 'auto_update': { 'enable': 0 } }. Maybe this will make a difference.

Additionally, while ugly, could you try guarding the settings block with an if statement, something like:

if !exists('g:mkdx_loaded')
  let g:mkdx_loaded = 1
  let g:mkdx#settings = { 'highlight': { 'enable': 1 },
                        \ 'enter': { 'shift': 1 },
                        \ 'links': { 'external': { 'enable': 0 } },
                        \ 'toc'  : { 'text': 'Table of Contents', 'update_on_write': 1 },
               	        \ 'fold' : { 'enable': 1 },
			\ 'tab'  : { 'enable': 1 } }
endif

If the latter works I will likely provide an alternative method to specify settings using a function, I can then implement this logic internally so users don't have to be bothered by this.

does your vim has('*dictwatcheradd')?

No, :echo has('*dictwatcheradd') -> 0. I still tried for the sake of it, but adding 'auto_update': { 'enable': 0 } didn't work.

could you try guarding the settings block

That seems to work 🎉 Thanks for the suggestion

However it feels going against the point of the vimrc. If I modify a mkdx setting, I can't reload the settings file and must either close/open all files, or manually re-enter the changed setting(s) as commands in the editor.

Yeah I agree it is certainly subpar but at least you now have a way to resource without seeing a bunch of errors, the next step is figuring out what is actually causing this kind of behavior. I'm certainly not going to call this one done yet until I have at least looked at it :)

In the meantime though, thanks for trying out the guarding tactic, glad that works at least!

Oke I haven't fixed this yet but it is quite a hairy issue, when I try moving the settings to different places it actually causes more errors :( In Neovim everything does work, which is also what I primarily use while developing this plugin. I don't think there is a quick fix for this and will have to look into it a bit deeper though so for now the best option is to still use the guard and try not to change mkdx' settings too often. Leaving this open until it's sorted.

Alright so I figured out a way to make this possible now. It's not pretty but I think any plugin with complex options will have this issue due to the loading order during vim initialization (which is why you'll often see g:pluginname_some_setting = ... settings).

I added a wrapper function called mkdx#configure which takes 1 argument, the dictionary you would otherwise supply to let g:mkdx#settings = { ... }

For me, using regular vim and vim-plug as my plugin manager, specifying my settings like this works:

" runtime is critical
runtime plugged/mkdx/plugin/mkdx.vim
call mkdx#configure({
      \ 'restore_visual': 1,
      \ 'gf_on_steroids': 1,
      \ 'highlight': { 'enable':   1 },
      \ 'enter':     { 'shift':    1 },
      \ 'links':     { 'external': { 'enable': 1 } },
      \ 'fold':      { 'enable':   1 },
      \ 'toc': {
      \    'text': 'Table of Contents',
      \    'update_on_write': 1,
      \    'details': { 'nesting_level': 0 }
      \ }
      \ })

I must however note that this works for me in regular vim but not in neovim. This is because regular Vim &rtp includes ~/.vim and my plugins install into ~/.vim/plugged which in turn allows plugged/mkdx/plugin/mkdx.vim to be found and sourced. Neovim however does not use or add ~/.vim to &rtp unless you add it manually but since this is irrelevant for Neovim it doesn't matter.

Without first manually sourcing the file you won't be able to call mkdx#configure so you will have to figure out where the your plugins are installed and use runtime or source to include mkdx/plugin/mkdx.vim.

I have already confirmed that I can now re-source my vim config and press enter successfully but I will keep the issue open until you've had time to confirm this. Please update mkdx to the latest version and change your config to look like above snippet and of course don't forget to change the runtime argument to match the location where your mkdx plugin is installed.

Confirmed, the following

runtime bundle/mkdx/plugin/mkdx.vim
call mkdx#configure({ 
           \ 'highlight': { 'enable': 1 },
           \ 'enter': { 'shift': 1 },
           \ 'links': { 'external': { 'enable': 0 } },
           \ 'toc'  : { 
                \ 'text': 'Table of Contents', 
                \ 'update_on_write': 1 },
           \ 'fold' : { 'enable': 1 },
    	   \ 'tab'  : { 'enable': 1 }})

works as intended, and allows for vimrc sourcing (with Vundle)

Alright, thank you for pointing this out @Battleman, I will go ahead and close this issue, happy vimming 👍

Made some changes recently which allow mkdx#configure to be called without requiring any runtime modifications.