tpope / vim-fugitive

fugitive.vim: A Git wrapper so awesome, it should be illegal
https://www.vim.org/scripts/script.php?script_id=2975
19.85k stars 1.01k forks source link

Can't run :Gcommit on Windows 7 with PowerShell #435

Closed tbrosnan closed 4 years ago

tbrosnan commented 10 years ago

I'm seeing the following error message "Can't open file C:/.../Appdata/Local/Temp/VILA140.tmp". That temporary file doesn't appear to exist.

I am using GVim 7.4, running :Git --version shows "git version 1.8.3.msysgit.0".

tbrosnan commented 10 years ago

I think I have figured this out, changing my shell from powershell to cmd,exe and things work correctly. Maybe this is a shell escaping issue?

tpope commented 10 years ago

Yeah that's gotta be it. If you search through the plugin for shell.*cmd, you can find the places it's special cased.

Konfekt commented 9 years ago

Dear @tpope,

Would you accept a pull request that, under MS Windows, temporarily sets the shell to 'cmd' with its standard parameters while a fugitive command is being executed ?

Something like

  if has('win32')
    let savedShell=[&shell, &shellcmdflag, &shellxquote, &shellxescape, &shellquote, &shellpipe, &shellredir, &shellslash]
    set shell=cmd shellcmdflag=/c shellxquote=\" shellquote= shellpipe=> shellredir=>%s\ 2>&1 noshellslash
  endif
...
  if has('win32')
    let [&shell, &shellcmdflag, &shellxquote, &shellxescape, &shellquote, &shellpipe, &shellredir, &shellslash]=savedShell
  endif

With the idea to make it work in terminal vim for every shell such as powershell, bash, Kornshell,..

tbrosnan commented 9 years ago

This turned out to be a very common problem for plugins that use external commands on Windows. I ended keeping a "toggleshell" function in my vimrc. A reusable solution that plugin authors could be pointed at would be great!

Konfekt commented 9 years ago

I just sent two pull requests for vim-latex and Ctrl-Space to work around their implementations. Perhaps you could give them a shot if you happen to use these. That would make them more trustful.

Well, regarding a toggleshell function do you suggest any additions to make that above more robust? It already circumvents cygwin as that gives has('win32unix').

tpope commented 9 years ago

Explicitly overriding the user's choice of shell seems like a terrible idea, which could easily make matters worse. And I've seen zero evidence this affects anything other than powershell.

The conditional logic is now encapsulated in s:winshell(). I would imagine it's a simple tweak to accommodate powershell.

tbrosnan commented 9 years ago

It could affect more than powershell. Many plugins assume that the shell on windows is cmd.exe and format commands accordingly, so anything other than cmd won't work (i.e. I no longer use powershell but sometimes use bash and I still need to toggle shell parameters in vim to make some plugins work).

Overriding the shell to cmd should be fine as long as it's changed back after the command is run, cmd is guaranteed to exist on Windows.

tpope commented 9 years ago

Fugitive is not one of those plugins. It explicitly checks for cmd.exe and uses UNIX shell escaping otherwise.

Konfekt commented 9 years ago

Problem is that Powershell pipes into UTF-16. So for example system() or read break down and instead thre tempfile the output is piped to needs to be opened in a buffer to convert.

It is also Vim's fault that Vim uses forward slashes if the shellcmdflag doesn't start with /c

Konfekt commented 9 years ago

The UTF16 piping by Powershell is the problem.

Fugitive does not expect the UTF16 ouput that Powershell gives. To remedy this, the shell settings were already set to

set shell=powershell.exe\ -NoLogo\ -NoProfile\ -NonInteractive\ -ExecutionPolicy\ RemoteSigned
" if shellcmdflag starts with '-' then tempname() uses forward slashes, see 
" https://groups.google.com/forum/#!topic/vim_dev/vTR05EZyfE0
set shellcmdflag=\ -Command
set shellquote=
set shellxquote=(
let &shellpipe='| Out-File -Encoding UTF8 %s'
let &shellredir='| Out-File -Encoding UTF8 %s'
set noshellslash

Still, the commit messages are piped as UTF16 where fugitive expects UTF8. This becomes visible by :Gstatus followed by cc which displays each character in its proper line.

@tpope, could you give a hint how this might come about?

justinmk commented 9 years ago

temporarily sets the shell to 'cmd'

@Konfekt Instead of setting 'shell', did you try set noshelltemp ?

Konfekt commented 9 years ago

Hello Justin,

That did not change anything. The reason is that

:if has("filterpipe")

returns 0 in Powershell.

Also, I do not know if I understood you correctly. Vim works fine fired up under Powershell with the standard cmd shell but preferably I'd like to make it work with the powershell shell.

This is what :Gitcommit returns:


:!git --git-dir="C:/Users/Konfekt/.dotfiles/.git" commit  > C:\Users\Konfekt\AppData\Local\Temp\VIHE245.tmp 2> C:\Users\Konfekt\AppData\Local\Temp\VIJE246.tmp

<ff><fe>O
n

b
r
a
n
c
h

m
a
s
t
e
r

Y
o
u
r

b
r
a
n
c
h

i
s

u
p
-
t
o
-
d
a
t
e

w
i
t
h

'
o
r
i
g
i
n
/
m
a
s
t
e
r
'
.

C
h
a
n
g
e
s

n
o
t

s
t
a
g
e
d

f
o
r

c
o
m
m
i
t
:

m
o
d
i
f
i
e
d
:

.
a
u
t
o
h
o
t
k
e
y
/
E
P
N
H
o
t
s
t
r
i
n
g
s
.
a
h
k

n
o

c
h
a
n
g
e
s

a
d
d
e
d

t
o

c
o
m
m
i
t
justinmk commented 9 years ago

:if has("filterpipe") returns 0 in Powershell.

Oh. Well that seems wrong, does it not?

Vim works fine fired up under Powershell with the standard cmd shell but preferably I'd like to make it work with the powershell shell.

If you could set noshelltemp, then system() wouldn't use temp files for redirection, which may avoid your problem.

Konfekt commented 9 years ago

It is false that has('filterpipe') = 0 because the function system() reads everything from a temp file.

In general it is a good thing that temp file piping is used because this way Vim automatically detects the right shell pipe encoding, which I think is UTF16 on Windows 7 by default.

However, :Gcommit does not use the powershell piping but calls

:!git --git-dir="C:/Users/Konfekt/.dotfiles/.git" commit  > C:\Users\Konfekt\AppData\Local\Temp\VICC89D.tmp 2> C:\Users\Konfekt\AppData\Local\Temp\VIDC8AE.tmp

and therefore bypasses my carefully chosen Powershell piping settings

let &shellpipe='| Out-File -Encoding UTF8 %s'
let &shellredir='| Out-File -Encoding UTF8 %s'

:Gcommit builds its own command assuming the cmd shell syntax without verifying that &shell~=?'cmd.

justinmk commented 8 years ago

Does anyone have set shell=powershell working with Vim+fugitive at this point?

@Konfekt let &shellpipe='| Out-File -Encoding UTF8 %s' seems to break things like :r!ls (which works with shellpipe=| shellredir=>).

dragon788 commented 8 years ago

@justinmk I've been having many failures with Vim+PowerShell as my working combo, which makes me really sad as I need to work in PowerShell for work, and I'd prefer to use Vim to do so, but these failures mean I probably need to use PowerShell and fall back to cmd.exe as the Vim shell and pass /c powershell -Command to do anything. :-1:

justinmk commented 8 years ago

@dragon788 I use co! mapping to toggle powershell on/off:

https://github.com/justinmk/config/commit/bb1469f870f0a9a8613802513ff5acdf1e1e19fe#diff-4e12c6a37ff2cbb2c93d1b33324a6051R493

Yes, this sucks.

dragon788 commented 8 years ago

Interestingly, I seem to have less issues with it failing once I disabled the solarized plugin. I was seeing these failures when using vim plug to install or update plugins in Windows.

At first I thought it was some of my symlinks causing issues, but I went through and unmade and remade them and was able to reproduce the issue in all my various iterations, but as soon as I removed solarized and cleared out my plugins it worked fine.

I may need to switch to another theme and see if it is a particular issue there or if it is reproducible depending on the plug-in list.

I did set up the mapping and it does seem to help in some cases, so I'll have to see about testing both ways.

Apologies Tim, I do like a pathogen but experiment from time to time. On Jun 27, 2016 4:31 PM, "Justin M. Keyes" notifications@github.com wrote:

@dragon788 https://github.com/dragon788 I use co! mapping to toggle powershell on/off:

justinmk/config@bb1469f#diff-4e12c6a37ff2cbb2c93d1b33324a6051R493 https://github.com/justinmk/config/commit/bb1469f870f0a9a8613802513ff5acdf1e1e19fe#diff-4e12c6a37ff2cbb2c93d1b33324a6051R493

Yes, this sucks.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/tpope/vim-fugitive/issues/435#issuecomment-228881957, or mute the thread https://github.com/notifications/unsubscribe/AAdxXiXsfvvU3XVc6Cc18Z4mszIXoXw0ks5qQEE9gaJpZM4BgnXY .

Konfekt commented 8 years ago

There is vim-flattened as a stripped down alternative to solarized.

tpope commented 5 years ago

How well does PowerShell play with Vim jobs? Been thinking of using jobs to make :Gstatus snappier and could see rolling it out for everything if it works out well.

Konfekt commented 5 years ago

As I was just looking at https://github.com/janlazo/dotvim8/blob/9356e51767a8081146cda6409ce272feafffc3bc/shared.vim#L186 and https://github.com/janlazo/dotvim8/blob/5cfc40a9c7fd2723bf5d23cea1a046e02e96d7e1/autoload/dotvim8.vim#L131 when you asked about it, perhaps @janlazo could answer that question.

tpope commented 5 years ago

It has just occurred to me that PowerShell is only relevant in the [&shell, &shellcmdflag, cmd] case. Mind you, this is a case I care very much about because it's the easiest to transition to.

The latest dispatch.vim does this, so it's easy to test with :Dispatch git status.

janlazo commented 5 years ago

@Konfekt Check https://github.com/janlazo/dotvim8/blob/master/after/ftplugin/ps1.vim on how I use powershell for keyword search.

tpope commented 5 years ago

Does | in PowerShell pipe stdout and stderr or just stdout?

janlazo commented 5 years ago

@tpope stdout

tpope commented 5 years ago

Thanks @janlazo.

Fugitive assumes that system() and friends capture stderr, so my guess is all error handling is broken with PowerShell. :Gcommit needs to capture stdout and stderr separately even for its success case, is that even possible with PowerShell?

tpope commented 5 years ago

No longer using :!, is this working now?

thekpaul commented 4 years ago

Same problem appears for me, seems to say that env is not a recognised cmdlet, etc. when the command env GIT_EDITOR=false git commit ... is called.

(Windows 10, Powershell 5.0 used in nvim-qt)

tpope commented 4 years ago

Try set shellcmdflag=\ -Command (with the leading space) and see if that fixes it.

thekpaul commented 4 years ago

Adding the leading space (and slash) fixed it, thanks. :D

Konfekt commented 4 years ago

@tpope Is the leading white space for the same reason (to circumvent a faulty shell detection by Vim) as that given here: https://stackoverflow.com/questions/94382/vim-with-powershell/27499996#27499996 ?

tpope commented 4 years ago

I assumed the leading whitespace was to circumvent Fugitive's detection - which is now fixed - but maybe it's a Vim thing too.