Skip to content

Conversation

@ckardaris
Copy link

This PR fixes 3 issues that I stumbled upon as soon as I installed the plugin and started playing with it. Two of the issues were discovered because I am using non-default options in my vim configuration (g:netrw_liststyles and splitbelow). The other one should be visible for anyone using the Netrw plugin (even with the default configuration).

I will be providing examples on how to reproduce these issues in a clean vim setup. For all setups we will use the same example directory structure, that I include in the attached file. The file should be extracted in the root directory of vim-dirdiff.

tree.zip

Structure after setup:

tree
.
├── doc
│   └── dirdiff.txt
├── example
│   ├── cmp1
│   │   ├── alpha
│   │   │   └── gamma
│   │   ├── beta.txt
│   │   └── delta.txt
│   └── cmp2
│       └── beta.txt
├── plugin
│   └── dirdiff.vim
├── README.md
└── screenshot.png

Suppress Netrw unlisted buffer deletion error

vim --clean -c 'runtime plugin/netrwPlugin.vim | so plugin/dirdiff.vim | DirDiff example/cmp1 example/cmp2'

In the diff window we can see something like the following

==> Files [A]/beta.txt and [B]/beta.txt differ
    Only in [A]: alpha
    Only in [A]: delta.txt

Then, we type, j<CR> and we have selected the alpha directory. Typing :ls! should output something similar to the following

:ls!
  1 %a-  "/tmp/vXVXiaA/0"               line 8
  2 #    "example/cmp2/beta.txt"        line 1
  3u     "example/cmp1/beta.txt"        line 1
  4u a-  "example/cmp1/alpha"           line 0

We can see the the alpha buffer is "unlisted", meaning that a bdelete operation will produce and error.
After typing j<CR>, to select the delta.txt entry the following error should show in the statusline.

Error detected while processing function <SNR>11_DirDiffOpen:
line   48:
E516: No buffers were deleted: bd 5

Fix window navigation if 'splitbelow' is set

vim --clean -c 'set splitbelow | so plugin/dirdiff.vim | DirDiff example/cmp1 example/cmp2'

When opening with splitbelow the window structure should be

┌───────────┐
│   diff    │
├─────┬─────┤
│  A  │  B  │
└─────┴─────┘

Typing h to toggle hex mode will not work properly, because the the wincmd commands in DirDiffHexMode expect the diff window to be below the file windows.

Fix Netrw window focus when g:netrw_liststyle = 3

The final bug is specific to the Netrw configuration. If g:netrw_liststyle = 3 (i.3. tree listing), Netrw will create one additional buffer that is shared for all directory operations. This buffer has the name NetrwTreeListing. If it is visible, instead of a buffer with the directory name, it means that we cannot focus on the correct window during diff entry selection changes. The original directory buffer is still there, but not displayed anymore.

For all other values of the g:netrw_liststyle, there is always one buffer created and its name is the same as the directory being displayed, so the bug is not showing up.

vim --clean -c 'runtime plugin/netrwPlugin.vim | let g:netrw_liststyle=3 | so plugin/dirdiff.vim | DirDiff example/cmp1 example/cmp2'

Same as before the diff window contains

==> Files [A]/beta.txt and [B]/beta.txt differ                                                                                                                  │
    Only in [A]: alpha                                                                                                                                          │
    Only in [A]: delta.txt

We type j<CR> and then

:ls!                                                                                                                                                            │
  1 %a-  "/tmp/vtMuABh/0"               line 8                                                                                                                  │
  2 #    "example/cmp2/beta.txt"        line 1                                                                                                                  │
  3u     "example/cmp1/beta.txt"        line 1                                                                                                                  │
  4u a-  "example/cmp1/alpha"           line 0

At this point the buffer with the directory name is visible and the current code would work. This is evident by calling bufwinid.

:echo bufwinid("alpha")
1001

If we now focus on the directory window, by typing <C-w>w, the situation changes.

:ls!                                                                                                                                                            │
  1  a-  "/tmp/vwmU38y/0"               line 0                                                                                                                  │
  2      "example/cmp2/beta.txt"        line 1                                                                                                                  │
  3u     "example/cmp1/beta.txt"        line 1                                                                                                                  │
  4u# -  "example/cmp1/alpha"           line 1                                                                                                                  │
  5u%a-  "NetrwTreeListing"             line 8

Netrw has taken over and replaced the directory buffer in the visible window.

If we now type <C-w>w to get back to the diff window and j<CR>, the contents of the directory window won't change to those of the delta.txt file and this is because of the faulty focus logic in the Drop function. There is no window visible named "alpha". The visible window is NetrwTreeListing.

The Netrw plugin creates an 'unlisted' buffer for directories.
Running 'bd {buffer}' on an unlisted buffer produces the following error:

E516: No buffers were deleted.

Suppress the error with 'silent!'.
Do not rely on 'wincmd h/j/k/l' movements, because the 'splitbelow'
options affects the position of the diff window.
If the Netrw plugin is configured in tree style listing mode
(i.e. g:netrw_liststyle = 3), then a buffer named 'NetrwTreeListing' is shown
(i.e. active window).

This happens only after the original buffer, which has the directory as its
name, is focused for the first time.

We work around this by comparing the 'netrw_curdir' variable of the
'NetrwTreeListing' buffer against the directory name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant