ntpeters / vim-better-whitespace

Better whitespace highlighting for Vim

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

automatic whitespace removal not working

dio4ev opened this issue · comments

Hi all!

I use vim-better-whitespace now for some time and have the following configuration:
let g:better_whitespace_enabled=1
let g:strip_whitespace_on_save=1
let g:strip_whitespace_confirm=0
let g:strip_only_modified_lines=1

I just want that the plugin removes my trailing whitespace when I save a file.
Apparently it stopped working now and I have no clue why.
Is use vim-plug and neovim (NVIM v0.4.3) .
Is there somebdy with the same problem?

let g:strip_only_modified_lines=1 means whitespace is only stripped on the lines you modified. Is that what you meant to do? If so, can you try to test the add-on without this setting? Can you also try it without any other plugins loaded?

Yes I want this behaviour :)
Manually removing whitespace with :StripWhitespace works.
Without the setting it still works manually.
Also without any plugins, it does not remove trailing whitespace on save,
but it works manually...

I can confirm the issue. It works with :StripWhitespace but not automatically on save.

I’m sorry but I don’t have neovim so I can’t test this issue that easily. Basically we trigger stripping on BufWritePre events. There’s only (I think) 3 reasons that StripWhitespace works but automatic saving doesn’t:

  1. the BufWritePre event doesn’t get set up
  2. the BufWritePre event doesn’t get triggered
  3. computing the changed lines with diff doesn’t work.

Events 1 and 2 can be easily tested by adding a echom "event setup" and echom "event triggered" in the if setting up the event and in the StripWhitespaceOnSave function, and then checking (after editing and writing a file) in :messages whether the messages appear.

if <SID>ShouldStripWhitespaceOnSave()
autocmd BufWritePre * call <SID>StripWhitespaceOnSave(v:cmdbang)
endif

function! s:StripWhitespaceOnSave(force)
let ranges = g:strip_only_modified_lines ? <SID>ChangedLines() : [[1,line('$')]]

To test the diff output, you could run from a modified buffer:

:echo system(g:diff_binary.' -a --unchanged-group-format="" --old-group-format="" --new-group-format="%dF,%dL " --changed-group-format="%dF,%dL " '.shellescape(expand('%')).' -', join(getline(1, line('$')), "\n") . "\n")

The output should be the list of modified lines as start,end pairs for each modified set of lines.

I had this problem as well, I'm in Neovim too, so maybe it is that. But I fixed it with:

g.better_whitespace_enabled = 1
g.strip_only_modified_lines = 1
vim.cmd("autocmd BufWritePre * :StripWhitespace")

or plain Vimscript I guess it would be:

let g:better_whitespace_enabled=1
let g:strip_only_modified_lines=1
autocmd BufWritePre * :StripWhitespace"

I have the same issue on Vim 9.0.

Relevant .vimrc config is:

let g:better_whitespace_enabled=1
let g:strip_whitespace_on_save=1
let g:strip_whitelines_at_eof=1
let g:strip_whitespace_confirm=0
let g:show_spaces_that_precede_tabs=1

Same here.

NVIM v0.9.1

vim.g.strip_whitespace_on_save = true
vim.g.strip_whitespace_confirm = false
vim.g.strip_only_modified_lines = false
vim.g.strip_whitelines_at_eof = true

In my environment it seems to be related to the file type. Editing simple text files doesn't seem to trigger the problem, ie spaces are removed on save, but JSON and YAML files do exhibit the problem, ie spaces are not removed on save.

Thanks @tombh, your work-around fixes it for the time being.

Tried reproducing on nvim, but works as intended for me. Here’s the setup:

~/.local/share/nvim/site> cat ~/.config/nvim/init.vim 
let g:strip_whitespace_on_save = 1
let g:strip_whitespace_confirm = 0
let g:strip_only_modified_lines = 0
let g:strip_whitelines_at_eof = 1

packloadall
~/.local/share/nvim/site> tree
.
└── pack
    └── test
        └── start
            └── vim-better-whitespace
                ├── doc
                │   ├── better-whitespace.txt
                │   └── tags
                ├── LICENSE
                ├── plugin
                │   └── better-whitespace.vim
                ├── README.md
                └── whitespace_examples.txt

7 directories, 6 files
~/.local/share/nvim/site> nvim --version
NVIM v0.9.1
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/cc  -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wvla -Wdouble-promotion -Wmissing-noreturn -Wmissing-format-attribute -Wmissing-prototypes -fno-common -Wno-unused-result -Wimplicit-fallthrough -fdiagnostics-color=auto -fstack-protector-strong -DUNIT_TESTING -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -I/usr/include/luajit-5_1-2.1 -I/usr/include -I/usr/include/lua5.1 -I/home/abuild/rpmbuild/BUILD/neovim-0.9.1/build/src/nvim/auto -I/home/abuild/rpmbuild/BUILD/neovim-0.9.1/build/include -I/home/abuild/rpmbuild/BUILD/neovim-0.9.1/build/cmake.config -I/home/abuild/rpmbuild/BUILD/neovim-0.9.1/src -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/share/nvim"

Run :checkhealth for more info

@tombh is basically running StripWhitespace on all files rather than when the addon is enabled (global on + non-blacklisted files), so I suspect ShouldStripWhitespaceOnSave() returns false for some reason, though it’s not clear why as I can’t repro. Maybe a difference in the sequence of events, but unless someone with the bug can probe around in there.

Does force-enabling the behaviour work, i.e. doing :EnableWhitespace ?

I'm also experiencing this. Some things I found (using a test file test.txt with nothing but a few whitespaces in it):

  • After invoking :EnableWhitespace it works again.
  • Also, if I first start vim and then load the file via :e test.txt it works.
  • The minimal init.lua that causes the problems for me is
    local cmp = require('cmp')
    cmp.setup({})
    cmp.setup.cmdline(':', {
        sources = cmp.config.sources({
            { name = 'cmdline' },
        })
    })
    vim.g.strip_max_file_size      = 0
    vim.g.strip_whitelines_at_eof  = 1
    vim.g.strip_whitespace_on_save = 1
    
    When I comment out either cmp.setup({}) or the call to cmp.setup.cmdline it works again. So at least for me there seems to be some problem in the interplay with hrsh7th/nvim-cmp and its source plugin hrsh7th/cmp-cmdline. Although I should mention that I use Vim's native pack plugin system, so I cannot completely rule out that some other plugin does also interfere. Is there a way to use nvim --noplugin and specifying only selected pack plugins to load?

@Cimbali I think I found the underlying issue. While the BufWritePre autocmd is correctly set up, it may get deleted before the actual write is triggered. In the minimal example I provided above, the reason seems to be that my completion plugin hrsh7th/nvim-cmp with the hrsh7th/cmp-cmdline extension triggers completions when I start to issue the write command (i.e., starting to type :w). This opens a floating window, which triggers a call to <SID>SetupAutoCommands(). During this setup, s:ShouldHighlight() determines that better-whitespace should be disabled for the auxiliary completion buffer in the floating window. While this is true for this completion buffer, at that point the BufWritePre autocmds (and others) have already been deleted by <SID>SetupAutoCommands(), so the subsequent write does not trigger better-whitespace.

I assume similar problems can be caused by other plugins using auxiliary buffers which cause the autocmds to be deleted and do not trigger a re-setup of the autocmds before the actual write. E.g., it looks to me that #147 might be caused by such a problem (but I did not check, since I don't use NERDTree).

Not sure what's the correct/best way to fix this, but locally I'm using buffer-specific autocmds to trigger whitespace highlights/deletions, which seems to work fine so far.

Thanks @pitkling these changes seem to make a lot of sense anyways, as all decisions of highlighting are made per buffer, scoping autocommands to buffers is logical. Feel free to open a PR and I'll try to inspect it more closely.

Forgot to mention here: I opened a corresponding PR (#168).