tagbar
tagbar copied to clipboard
Tagbar doesn't work on gvim for windows with python installed
Hi, When I run TagbarToggle I get the following error:
OSError: [WinError 6] The handle is invalid
But if debug mode is enabled, Tagbar work fine. In debug mode, the plugin does not use python to call ctags:
if tagbar#debug#enabled()
silent 5verbose let ctags_output = system(a:ctags_cmd)
call tagbar#debug#log(v:statusmsg)
call tagbar#debug#log('Exit code: ' . v:shell_error)
redraw!
else
let py_version = get(g:, 'tagbar_python', 1)
silent let ctags_output = s:run_system(a:ctags_cmd, py_version)
endif
The plugin uses undocumented parameter g:tagbar_python, which allows using python for ctags calls. By default, this parameter set to 1, which launches call via python by default. This parameter is processed here:
if has('win32') && !has('nvim') && a:version > 0 && (has('python3') || has('python2'))
if a:version == 3 && has('python3')
let pyx = 'py3 '
let python_eval = 'py3eval'
elseif a:version == 2 && has('python2')
let pyx = 'py2 '
let python_eval = 'pyeval'
else
let pyx = 'pyx '
let python_eval = 'pyxeval'
endif
Next, the part of the code where the ctags call is formed via Python:
exec pyx . 'import subprocess, vim'
exec pyx . '__argv = {"args":vim.eval("a:cmd"), "shell":True}'
exec pyx . '__argv["stdout"] = subprocess.PIPE'
exec pyx . '__argv["stderr"] = subprocess.STDOUT'
exec pyx . '__pp = subprocess.Popen(**__argv)'
exec pyx . '__return_text = __pp.stdout.read()'
exec pyx . '__pp.stdout.close()'
exec pyx . '__return_code = __pp.wait()'
exec 'let l:hr = '. python_eval .'("__return_text")'
exec 'let l:pc = '. python_eval .'("__return_code")'
Calling subprocess from gvim does not work, if "stdin" not defined. Bellow are the patches to fix this behaviour:
--- "a\\autoload\\tagbar.vim" 2020-10-24 00:17:10.000000000 +0300
+++ "b\\autoload\\tagbar.vim" 2020-10-24 21:29:14.307119000 +0300
@@ -2917,6 +2917,7 @@
let l:pc = 0
exec pyx . 'import subprocess, vim'
exec pyx . '__argv = {"args":vim.eval("a:cmd"), "shell":True}'
+ exec pyx . '__argv["stdin"] = subprocess.DEVNULL'
exec pyx . '__argv["stdout"] = subprocess.PIPE'
exec pyx . '__argv["stderr"] = subprocess.STDOUT'
exec pyx . '__pp = subprocess.Popen(**__argv)'
@@ -2971,7 +2972,7 @@
call tagbar#debug#log('Exit code: ' . v:shell_error)
redraw!
else
- let py_version = get(g:, 'tagbar_python', 1)
+ let py_version = get(g:, 'tagbar_python', 0)
silent let ctags_output = s:run_system(a:ctags_cmd, py_version)
endif
Thanks for the detailed report. Care to make this fix into a PR?