问题
I am having trouble getting vimdiff
to work on a Windows 10 machine. I am running vim from Powershell. Powershell is also declared in $myvimrc
as my shell of choice:
set shell=C:\WINDOWS\system32\WindowsPowershell\v1.0\powershell.exe
The documents I am attempting to compare are not saved as files. I open two vertical splits, enter text into each, and run :windo diffthis
. The output is E97: Cannot create diffs
.
This article says I may need to download and use a different diff.exe
than the one installed with gvim. I have downloaded the recommended "GnuWin32 diff" package and added the install directory to my Windows Path ($env:path
). Continuing to follow these directions, I've commented out the default diffexpr
declaration, but still get E97.
I have also tried calling my own function to no avail. In this attempt, I've made sure to escape backslashes, and have also copied the downloaded diff.exe
to a directory I am confident I have full permissions to. To help with troubleshooting, I've temporarily saved the two files I wish to compare, and specified their full paths explicitly rather than using vim's v:fname_in
and v:fname_new
(and v:fname_out
).
set diffexpr=TestDiff()
function TestDiff()
silent execute "!& " . "C:\\diff.exe" . " -a --binary " "C:\\a.edi" . " " . "C:\\b.edi" . " > " . "C:\\tmp.txt"
endfunction
I've researched this error by running :h E97
, which returns the following information:
Vim will do a test if the diff output looks alright. If it doesn't, you will get an error message. Possible causes:
- The "diff" program cannot be executed.
- The "diff" program doesn't produce normal "ed" style diffs (see above).
- The 'shell' and associated options are not set correctly. Try if filtering works with a command like ":!sort".
- You are using 'diffexpr' and it doesn't work. If it's not clear what the problem is set the 'verbose' option to one or more to see more messages.
The self-installing Vim for MS-Windows includes a diff program. If you don't have it you might want to download a diff.exe. For example from http://gnuwin32.sourceforge.net/packages/diffutils.htm.
I believe that I pass the first two of these requirements, as tmp.txt
is generated and follows the example "ed" style diff that is provided in the help file. I have not set other shell-related parameters (shelltype, shellpipe, etc) in $myvimrc
, but executing other commands with :!
complete without issue.
There is no additional information in :messages
, only the E97 error.
Edit:
If I remove set shell=C:\WINDOWS\system32\WindowsPowershell\v1.0\powershell.exe
from $myvimrc
, defaulting the shell back to cmd.exe
, diffthis
works as expected. It seems that others have also had this problem when using Powershell.
Below are captures of the command windows that pop up when running diffthis
with both shells. The commands used are nearly identical.
I had speculated that the forward slashes apparent in the Powershell version of this attempt were problematic, but I am able to run this command exactly (with dummy files in place of the .tmp files) and it outputs what seems to be an adequate file for use with diff. I've also tried adding a substitute
of forward slashes to back slashes to no avail.
回答1:
The problem boils down to how vim/Powershell are A) encapsulating the command in quotes and B) handling white space in path names.
I am able to bypass this problem with the following changes to $myvimrc
:
set shell=powershell
set shellcmdflag=-c
set shellquote="
set shellxquote=
Also a change in the default MyDiff()
function within the if
that sets the path to diff in the cmd
variable:
" below is the default
" let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
let cmd = "C:/diff"
This approach is dependent upon copying the diff.exe
that ships with vim to a directory that doesn't contain spaces in the path for simplicity (C:\diff.exe).
The resulting command that is executed is:
powershell -c C:/diff -a --binary C:/<redacted>/a.tmp C:/<redacted>/b.tmp > C:/<redacted>/c.tmp
来源:https://stackoverflow.com/questions/56462619/vimdiff-e97-in-powershell