vim-autoformat doesn't seem to have any of the weird problems in vim-go's :GoFmt. Folds are intact etc. We should take a look at how its done in that plugin.
Seems like it uses Python, maybe it doesn't have those problems with it. Also we should first know what these weird errors are. Right now the only problem is folding as I know.
Yea, its only folding.
A quick glance at the code shows the magic sauce:
vim.current.buffer[:] = lines
I quickly hacked that into fmt.vim and noticed:
1) The buffer is updated in-place again, so no need to silent edit! to re-open the buffer
2) Manual fold state is respected since the buffer is not re-initialized (the position of the manual folds, being line-based, do not account however for imports being added, etc)
3) Syntax fold state is respected, although all folds still collapse when foldlevel=0, as through zM (not sure there is an easy workaround for that)
It appears that since the buffer is being modified from within the Python module, it really does get updated in a single pass, as opposed to setline(1, lines), which just initiates the loop for [i, line] in lines | setline(1+i, line), triggering a fold recalculation + more for every setline call.
https://github.com/vim/vim/blob/74c5bbf/src/if_py_both.h#L4202-L4405
If @fatih is willing to require +python{,3} or maintain two code paths in fmt.vim, using the python module really appears to be best approach to replacing a buffer in-place.
Side note:
@fatih:
I just noticed your @guns call-outs. Sorry for missing the signal! I filter my mail from this vim-go repo into a separate mail folder so I didn't notice your messages. I'll have to readjust my filters.
Thanks again for vim-go!
If we do change it, lets make sure to credit @Chiel92.
vim-go was always pure vim-script (except some of the code in snippets, which I wanted to remove anyways). I'm for any improvements, but we should add them in a way that enhances the current functionality.
For example let us take :GoBuild. It works perfectly with Vim and MacVim. But if you use it with NeoVim it builds the source code in async behavior.
We should do the same for :GoFmt. Check if it's compiled with +python and then call the enhanced and improved formatting. And probably we also should put it behind a flag, which we'll then remove later (not sure for this). But in any case, we never should make it problematic or throw an error. Especially :GoFmt is the most used function in vim-go, anything that breaks it is a bad thing for us.
@guns since you already added it and tested it, can you create the PR?
Closing this issue as we don't have any progress for months. I'm always open improvements on :GoFmt, feel free to work on these things, just let me know before you start. Thanks!
Most helpful comment
vim-go was always pure vim-script (except some of the code in snippets, which I wanted to remove anyways). I'm for any improvements, but we should add them in a way that enhances the current functionality.
For example let us take
:GoBuild. It works perfectly withVimandMacVim. But if you use it withNeoVimit builds the source code in async behavior.We should do the same for
:GoFmt. Check if it's compiled with+pythonand then call the enhanced and improved formatting. And probably we also should put it behind a flag, which we'll then remove later (not sure for this). But in any case, we never should make it problematic or throw an error. Especially :GoFmt is the most used function in vim-go, anything that breaks it is a bad thing for us.