Detectar SO en Vimscript

38

¿Puedo recuperar el sistema operativo actual (Windows, Linux, OS X, ...) usando Vimscript puro (sin Python o Perl)?

Quiero habilitar diferentes configuraciones en mi .vimrc (sincronizado) para los diferentes tipos de sistemas operativos que estoy usando.

muffel
fuente
¿Podría proporcionar algunos ejemplos específicos de comportamientos dependientes del sistema operativo que busca implementar?
200_success
@ 200_success Tengo algunos scripts y enlaces de teclas para MS TFS y msbuild que son bastante inútiles en entornos que no son Windows, aunque no necesito soporte de tmux en gVim en Windows. Además, hay diferentes fuentes instaladas en diferentes sistemas, y las rutas también pueden diferir.
muffel

Respuestas:

42

La mejor manera es usarlo has(), con esta función puede verificar las características de Vim; Características específicas del sistema operativo de :help feature-list:

macunix                 Macintosh version of Vim, using Unix files (OS-X).
unix                    Unix version of Vim.
win32                   Win32 version of Vim (MS-Windows 95 and later, 32 or
                        64 bits)
win32unix               Win32 version of Vim, using Unix files (Cygwin)

Y algunos sistemas más antiguos (semi-obsoletos):

amiga                   Amiga version of Vim.
os2                     OS/2 version of Vim.
win16                   Win16 version of Vim (MS-Windows 3.1).
win64                   Win64 version of Vim (MS-Windows 64 bit).
win95                   Win32 version for MS-Windows 95/98/ME.

Ejemplo:

if has('win32')
    echo "Someone please open the Window(s)!"
endif

Una forma alternativa con más flexibilidad es llamar al externo uname, esto también le permite obtener el número de versión y tal:

let uname = system('uname -a')

Tenga en cuenta que unameno está presente en la mayoría de los sistemas Windows.

En general, es mejor usar la detección de funciones , en lugar de la detección del sistema operativo . Por ejemplo, mediante el uso de una de las funciones en has()o comprobando si existe alguna ruta. La publicación 200_success ' ofrece una buena visión general de eso, así que no repetiré el mismo contenido aquí.

Martin Tournoij
fuente
55
Sin embargo, es muy importante tener en cuenta la respuesta de romainl si quieres que funcione en OS X.
Rico
+1 para puntero a:h feature-list
JESii
24

has()suena como una buena idea hasta que lo pruebe en Mac OS X: por defecto /usr/bin/vim, has('unix')es verdadero pero ambos has('macunix')y has('mac')son falsos , mientras que, en la descarga normal de MacVim, los tres son verdaderos si usa la GUI o la TUI.

Entonces, la mejor solución es una combinación de has('winXX')Windows y unameen sistemas similares a Unix. Tenga en cuenta que la salida de unametermina con una nueva línea, por lo que debe limpiarse antes de su uso.

Aquí está el código que he estado usando durante un tiempo, actualizado para win64:

if !exists("g:os")
    if has("win64") || has("win32") || has("win16")
        let g:os = "Windows"
    else
        let g:os = substitute(system('uname'), '\n', '', '')
    endif
endif

Después de eso, puede usar la g:osvariable en cualquier parte de su vimrc:

if has("gui_running")
    if g:os == "Darwin"
        set guifont=Fira\ Mono:h12
    elseif g:os == "Linux"
        set guifont=Fira\ Mono\ 10
    elseif g:os == "Windows"
        set guifont=Fira_Mono:h12:cANSI
    endif
endif
romainl
fuente
Bueno, OSX es un sistema UNIX, creo que incluso es "UNIX certificado". Entonces has('unix')es exacto. Sin has('macunix')embargo, es extraño que sea ​​falso. Esto casi suena como un error?
Martin Tournoij
1
Hice algunas comprobaciones y has('macunix')parece depender de lo MACOS_X_UNIXque se establece si unameestá Darwinen el configureguión ...
Martin Tournoij
Por extraño que parezca, has ("win32")parece funcionar para mí, incluso en Vim de 64 bits.
Rich
@ Rich Sí, y eso está documentado como tal. Esto es realmente lo más sensato, ¿te importa si tu aplicación tiene 32 o 64 bits? Yo no. La razón por la que se llama 'win32' es porque ese es el nombre que Microsoft elige para su API de Windows NT. Nombrar cosas no es el punto fuerte de Microsoft .
Martin Tournoij
1
has('unix')También es cierto en Windows Git Bash, por lo que no es muy útil para distinguir unix real de emulado.
wisbucky
8

Las variables de entorno serían útiles.

Para detectar tmux, puede verificar if !empty($TMUX)o if $TERM == 'screen'.

También puede deducir el sistema operativo a partir de variables de entorno como $MACHTYPE( que está configurado por Bash ) o $PATH.

Para detectar si está instalada una función como TFS, puede usar la executable()función.

200_success
fuente
"$ MACHTYPE (que está configurado por Bash)" . En realidad, si Bash establece una variable, eso significa que no es una variable de entorno, y no podrá acceder a ella en vim simplemente con $MACHTYPE. Tendrás que hacer algo como let machtype=system('echo -n $MACHTYPE')primero.
wisbucky
4

Como otros ya han indicado, una detección confiable puede ser complicada. Mejor no reinventar la rueda, así que me gustaría mencionar la biblioteca vim-misc , que proporciona xolox#misc#os#is_mac()y xolox#misc#os#is_win()funciona.

Ingo Karkat
fuente
1

Lo intenté has('unix'), pero no lo encontré útil, ya que todos mis Linux, Mac y Windows Git Bash volvieron truepor él.

Me pareció unameadecuado, ya que distingue entre Linux, Mac, Windows, sin demasiada granularidad.

let uname = substitute(system('uname'), '\n', '', '')
" Example values: Linux, Darwin, MINGW64_NT-10.0, MINGW32_NT-6.1

if uname == 'Linux' || uname == 'Darwin'
    " do linux/mac command
else " windows
    " do windows command
endif
Wisbucky
fuente