-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support cygwin vim via cygpath and Windows binary #933
Conversation
Thanks, before we proceed, I spotted a couple of places where diff --git a/plugin/fzf.vim b/plugin/fzf.vim
index 8c8ff85..e262317 100644
--- a/plugin/fzf.vim
+++ b/plugin/fzf.vim
@@ -313,7 +313,7 @@ function! fzf#wrap(...)
if !isdirectory(dir)
call mkdir(dir, 'p')
endif
- let history = s:is_win ? fzf#shellescape(dir.'\'.name) : s:escape(dir.'/'.name)
+ let history = fzf#shellescape(dir.'/'.name)
let opts.options = join(['--history', history, opts.options])
endif
@@ -553,7 +553,7 @@ function! s:execute_tmux(dict, command, temps) abort
let command = a:command
if s:pushd(a:dict)
" -c '#{pane_current_path}' is only available on tmux 1.9 or above
- let command = 'cd '.s:escape(a:dict.dir).' && '.command
+ let command = 'cd '.fzf#shellescape(a:dict.dir).' && '.command
endif
call system(command) ( |
You can use
No. I have Only |
Sorry for not being clear, but I wasn't asking about cygwin environment, but native Windows.
You mean |
You're right. I missed |
plugin/fzf.vim
Outdated
@@ -152,7 +158,7 @@ function! s:escape(path) | |||
let escaped_chars = '$%#''"' | |||
|
|||
if has('unix') | |||
let escaped_chars .= ' \' | |||
let escaped_chars .= ' \()' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
()
should be added only on cygwin environment, not on all unix
.
plugin/fzf.vim
Outdated
@@ -401,7 +410,6 @@ try | |||
let optstr .= ' --no-height' | |||
endif | |||
let command = prefix.(use_tmux ? s:fzf_tmux(dict) : fzf_exec).' '.optstr.' > '.temps.result | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary.
plugin/fzf.vim
Outdated
@@ -455,7 +463,8 @@ function! s:pushd(dict) | |||
return 1 | |||
endif | |||
let a:dict.prev_dir = cwd | |||
execute 'lcd' s:escape(a:dict.dir) | |||
let dir = s:escape(a:dict.dir) | |||
execute 'lcd' has('win32unix') ? s:escape(s:cygpath(dir)) : dir |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be escaping twice (s:escape(s:cygpath(s:escape(a:dict.dir)))
), intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fzf#shellescape
isn't used in s:cygwin
even though it uses system
. To be consistent with recent changes, I'll use fzf#shellescape
in s:cygwin
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be a swap from s:escape
to shellescape
in cygwin
Edit: no issues so far so I'm committing the change.
I can't get tmux to work without mintty. What about using batchfile to run an external cmd.exe terminal for fzf to bypass mintty and other terminals? |
If we opt for this, it is tricky to escape because cygwin paths are invalid in cmd.exe and If only there's way to do equivalent of the |
So I installed cygwin on my Windows machine, but I was unable to start fzf. Exit with an error message if I just run fzf, terminal hangs if I run |
Cygwin's default terminal is mintty but mintty is not required to use cygwin environment. sh.exe runs on top of cmd.exe so anything passed to sh.exe will be piped to cmd.exe. It hangs in mintty so I put in the title of PR that mintty is not supported. |
Thanks for the explanation, I could confirm that the windows binary runs on cygwin running on conemu if I unset TERM. How about if I update the Windows binary to unset TERM if it's running on Cygwin ( |
Yes. Can you try the recent commit on mintty? |
I didn't test fzf on Vim, but just on the shell. Now that I try it, It's not working for me on Vim on ConEmu, with |
- Update install script to download Windows binary if $TERM == cygwin - Unset TERM if $TERM == cygwin (#933) - Always use cmd.exe instead of $SHELL when running commands
I updated the Go code to unset TERM if |
It works if not running in mintty. |
Works fine both on ConEmu and mintty, great job. Let me know if it's ready for merge. I'll merge it to devel branch first. |
I don't have X11 for Cygwin so I can't test gvim and xterm. |
let escaped = (a:use_height || s:is_win) ? a:command : escape(substitute(a:command, '\n', '\\n', 'g'), '%#!')
if has('gui_running')
let Launcher = get(a:dict, 'launcher', get(g:, 'Fzf_launcher', get(g:, 'fzf_launcher', s:launcher)))
let fmt = type(Launcher) == 2 ? call(Launcher, []) : Launcher
if has('unix')
let escaped = "'".substitute(escaped, "'", "'\"'\"'", 'g')."'"
endif
let command = printf(fmt, escaped)
else
let command = escaped
endif What's the |
I'm not sure if it was the best way to handle such directory arguments, but without it, Try this: cd /tmp
mkdir "a'b'c"
mkdir 'x"y"z'
touch "a'b'c"/{foo,bar}
touch 'x"y"z'/{foo,bar} Then: " Use tab completion to complete the directory name
:FZF /tmp/a<tab>
:FZF /tmp/x<tab> |
plugin/fzf.vim
Outdated
@@ -537,6 +549,15 @@ function! s:execute(dict, command, use_height, temps) abort | |||
call jobstart(cmd, fzf) | |||
return [] | |||
endif | |||
elseif has('win32unix') | |||
if $TERM ==# 'cygwin' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this branch can be removed now as the new binary will unset TERM if TERM == cygwin, so line 552 becomes elseif has('win32unix') && $TERM != 'cygwin'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
I intended the vim plugin to be compatible with the current binaries for Windows but cygwin is not officially supported yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to merge this to devel branch first and then merge to master when I release 0.16.8, so let me know if there are other things that can be done on the binary side that can help simplyfing the Vim plugin.
If TERM is set to cygwin, fzf will use https://github.com/junegunn/fzf-bin/releases/download/alpha/fzf-0.16.8-alpha-windows_amd64.zip Do you think we still need |
- remove if branch because fzf supports '$TERM == cygwin' - unset TERM in cmd.exe so sh.exe can set it to 'cygwin'
|
Assuming there's only 1 cygwin installation, |
I was able to run :FZF without cygpath on ConEmu and mintty with the following diff. diff --git a/plugin/fzf.vim b/plugin/fzf.vim
index 8bdeb3b..78e8128 100644
--- a/plugin/fzf.vim
+++ b/plugin/fzf.vim
@@ -386,10 +386,10 @@ try
let prefer_tmux = get(g:, 'fzf_prefer_tmux', 0)
let use_height = has_key(dict, 'down') &&
- \ !(has('nvim') || s:is_win || s:present(dict, 'up', 'left', 'right')) &&
+ \ !(has('nvim') || s:is_win || has('win32unix') || s:present(dict, 'up', 'left', 'right')) &&
\ executable('tput') && filereadable('/dev/tty')
let use_term = has('nvim') && !s:is_win
- let use_tmux = (!use_height && !use_term || prefer_tmux) && s:tmux_enabled() && s:splittable(dict)
+ let use_tmux = (!use_height && !use_term || prefer_tmux) && !has('win32unix') && s:tmux_enabled() && s:splittable(dict)
if prefer_tmux && use_tmux
let use_height = 0
let use_term = 0
@@ -485,7 +485,7 @@ function! s:xterm_launcher()
\ &columns, &lines/2, getwinposx(), getwinposy())
endfunction
unlet! s:launcher
-if s:is_win
+if s:is_win || has('win32unix')
let s:launcher = '%s'
else
let s:launcher = function('s:xterm_launcher')
@@ -537,6 +537,11 @@ function! s:execute(dict, command, use_height, temps) abort
call jobstart(cmd, fzf)
return []
endif
+ elseif has('win32unix') && $TERM !=# 'cygwin'
+ let shellscript = s:fzf_tempname()
+ call writefile([command], shellscript)
+ let command = 'cmd.exe /C ''set "TERM=" & start /WAIT sh -c '.fzf#shellescape(shellscript).''''
+ let a:temps.shellscript = shellscript
endif
if a:use_height
let stdin = has_key(a:dict, 'source') ? '' : '< /dev/tty' |
Can you test my version with the latest alpha binary? It uses cygwin find command instead of dir so there's no need for path conversion. Also I'm not sure why we need cygpath or fnamemodify on |
plugin/fzf.vim
Outdated
@@ -778,7 +772,7 @@ function! s:cmd(bang, ...) abort | |||
if s:is_win && !&shellslash | |||
let opts.dir = substitute(opts.dir, '/', '\\', 'g') | |||
elseif has('win32unix') | |||
let opts.dir = s:cygpath(opts.dir) | |||
let opts.dir = fnamemodify(opts.dir, ':p') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Required for Windows-style filepaths with the network drive
plugin/fzf.vim
Outdated
@@ -227,7 +221,7 @@ function! s:common_sink(action, lines) abort | |||
let autochdir = &autochdir | |||
set noautochdir | |||
if has('win32unix') | |||
call map(a:lines, 's:cygpath(v:val)') | |||
call map(a:lines, 's:fzf_fnamemodify(v:val, ":p")') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we need this branch anymore to guarantee absolute paths.
I tried it and |
Do you want to support it? fnamemodify is required for path conversion. |
Do you think it would be useful? What is your opinion as a Windows/Cygwin user? Though I don't like the fact that we have to change the code for By the way, can you give me an example where the extra escaping |
It's useful for me because Git For Windows ships cygwin vim as its default editor. I don't have to install the win32/64 version of vim. I use powershell 5 for my shell so I use Windows-style paths all the time.
|
Fair enough, let's keep it.
So can we remove it now? |
Done. |
Thanks a lot. I'm planning to release 0.16.8 after merging devel branch tomorrow, please let me know if there's any other issues you want to address before the release. |
Did you test symlinks via I think it's outside the scope of 0.16.8 but users may complain that they open a blank file instead of the symlinked file/directory. |
Thanks, but I'm not quite sure if I understood you correctly. I just opened a few symlinks with |
Try making a symlink directory with Compare the files in /bin with /NetworkDrive/path/to/CygwinRoot/bin and do the same for /usr/bin. |
Since cygwin sh/bash runs cmd.exe in the back (sh/bash by itself is run in a cmd.exe terminal) and use
TERM=cygwin
, we can run cygwin vim and the fzf (Windows) binary in cmd.exe/powershell. Benefit of including cygwin support to the vim plugin is running the tests as is in Windows. I'm currently using this for the Vader tests.By unsetting TERM, fzf runs as if vim (Windows) is used. cygpath (via
s:cygpath
) is used for path conversion between Windows and cygwin filepaths. I updateds:escape
to escape()
for Windows filepaths.Currently, this PR does not support mintty (
TERM=xterm
) because fzf is run inline (no shell script or batchfile) and I can't get the start command to work with shell redirection yet. Neovim TUI in cygwin sh/bash is not supported in the vim plugin even though it runs fine (without mintty) in sh/bash. I'll work on that along with:terminal
when 0.2.1 is released.I'm using the cygwin environment from Git For Windows and tested this PR in
sh.exe
withTERM=cygwin
.