Detectar o SO no Vimscript

38

Posso recuperar o sistema operacional atual (Windows, Linux, OS X, ..) usando o Vimscript puro (sem Python ou Perl)?

Quero habilitar configurações diferentes no meu (sincronizado) .vimrc para diferentes tipos de sistemas operacionais que estou usando.

muffel
fonte
Você poderia fornecer alguns exemplos específicos de comportamentos dependentes do SO que você procura implementar?
200_success
@ 200_success Eu tenho alguns scripts e atalhos de teclado para MS TFS e msbuild que são bastante inútil em ambientes não-Windows, enquanto eu não preciso tmux apoio na gVim no Windows. Além disso, existem fontes diferentes instaladas em sistemas diferentes e os caminhos também podem ser diferentes.
Muffel

Respostas:

42

A melhor maneira é usar has(), com esta função, você pode verificar os recursos do Vim; Recursos específicos do SO 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)

E alguns sistemas mais antigos (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.

Exemplo:

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

Uma maneira alternativa, com mais flexibilidade, é ligar para o externo uname, isso também permite obter o número da versão e:

let uname = system('uname -a')

Observe que unamenão está presente na maioria dos sistemas Windows.

Geralmente, é melhor usar a detecção de recursos , em vez da detecção do SO . Por exemplo, usando um dos recursos has()ou verificando se existe algum caminho. A publicação 200_success ' fornece uma boa visão geral disso, então não repetirei o mesmo conteúdo aqui.

Martin Tournoij
fonte
5
Muito importante observar a resposta do romainl, se você quiser que ele funcione no OS X.
Rich
+1 para ponteiro para:h feature-list
JESii
24

has()parece uma boa idéia até você experimentá-lo no Mac OS X: no padrão /usr/bin/vim, has('unix')é verdadeiro, mas ambos has('macunix')e has('mac')são falsos , enquanto, no download regular do MacVim, todos os três são verdadeiros, independentemente de você usar a GUI ou a TUI.

Portanto, a melhor solução é uma combinação de sistemas has('winXX')Windows e unameUnix. Observe que a saída unametermina com uma nova linha, portanto ela deve ser limpa antes do uso.

Aqui está o código que uso há algum tempo, atualizado 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

Depois disso, você pode usar a g:osvariável em qualquer lugar do seu 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
fonte
Bem, o OSX é um sistema UNIX, acredito que seja "UNIX certificado". Então has('unix')é preciso. É estranho que has('macunix')seja falso, no entanto. Isso quase soa como um bug?
Martin Tournoij 16/03/2015
1
Eu fiz alguns testes, e has('macunix')parece depender MACOS_X_UNIX, que é definido se unameé Darwinno configurescript ...
Martin Tournoij
Curiosamente, has ("win32")parece funcionar para mim, mesmo no Vim de 64 bits.
Ricos
@ Rich Sim, e isso está documentado como tal. Esta é realmente a coisa mais sensata a fazer, você se importa se o seu aplicativo é de 32 ou 64 bits? Eu não. O motivo é chamado de 'win32', porque esse é o nome que a Microsoft escolhe para a API do Windows NT. Nomear coisas não é o ponto forte da Microsoft .
Martin Tournoij 16/03/2015
1
has('unix')também é verdade no Windows Git Bash, por isso não é muito útil para distinguir o unix real do emulado.
wisbucky
8

Variáveis ​​de ambiente seriam úteis.

Para detectar tmux, você pode verificar if !empty($TMUX)ou if $TERM == 'screen'.

Você também pode deduzir o sistema operacional de variáveis ​​de ambiente como $MACHTYPE( que é definido pelo Bash ) ou $PATH.

Para detectar se um recurso como o TFS está instalado, você pode usar a executable()função

200_success
fonte
"$ MACHTYPE (definido por Bash)" . Na verdade, se uma variável for definida pelo Bash, isso significa que não é uma variável de ambiente e você não poderá acessá-la no vim simplesmente com $MACHTYPE. Você terá que fazer algo como let machtype=system('echo -n $MACHTYPE')primeiro.
61518 wisbucky
4

Como outros já indicaram, uma detecção confiável pode ser complicada. É melhor não reinventar a roda, então eu gostaria de mencionar a biblioteca vim-misc , que fornece xolox#misc#os#is_mac()e xolox#misc#os#is_win()funciona.

Ingo Karkat
fonte
1

Eu tentei has('unix'), mas não achei útil, pois todos os meus Linux, Mac e Windows Git Bash voltaram truepara ele.

Eu achei unameadequado, pois distingue entre Linux, Mac, Windows, sem muita granularidade.

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
fonte