Closed tbrosnan closed 4 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?
Yeah that's gotta be it. If you search through the plugin for shell.*cmd
, you can find the places it's special cased.
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,..
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!
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')
.
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.
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.
Fugitive is not one of those plugins. It explicitly checks for cmd.exe
and uses UNIX shell escaping otherwise.
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
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?
temporarily sets the shell to 'cmd'
@Konfekt Instead of setting 'shell'
, did you try set noshelltemp
?
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
: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.
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
.
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=>
).
@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:
@dragon788 I use co!
mapping to toggle powershell on/off:
Yes, this sucks.
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 .
There is vim-flattened as a stripped down alternative to solarized.
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.
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.
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
.
@Konfekt Check https://github.com/janlazo/dotvim8/blob/master/after/ftplugin/ps1.vim on how I use powershell for keyword search.
Does |
in PowerShell pipe stdout and stderr or just stdout?
@tpope stdout
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?
No longer using :!
, is this working now?
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
)
Try set shellcmdflag=\ -Command
(with the leading space) and see if that fixes it.
Adding the leading space (and slash) fixed it, thanks. :D
@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 ?
I assumed the leading whitespace was to circumvent Fugitive's detection - which is now fixed - but maybe it's a Vim thing too.
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".