Deteksi OS dalam Vimscript

38

Dapatkah saya mengambil sistem operasi saat ini (Windows, Linux, OS X, ..) menggunakan Vimscript murni (tanpa Python atau Perl)?

Saya ingin mengaktifkan berbagai pengaturan di .vimrc (disinkronkan) saya untuk berbagai jenis sistem operasi yang saya gunakan.

muffel
sumber
Bisakah Anda memberikan beberapa contoh spesifik perilaku yang tergantung pada OS yang ingin Anda terapkan?
200_success
@ 200_success Saya memiliki beberapa skrip dan binding kunci untuk MS TFS dan msbuild yang sangat tidak berguna di lingkungan non-Windows, sementara saya tidak memerlukan dukungan tmux di gVim pada Windows. Selain itu, ada berbagai font yang diinstal pada sistem yang berbeda, dan jalur mungkin berbeda juga.
muffel

Jawaban:

42

Cara terbaik adalah menggunakan has(), dengan fungsi ini Anda dapat memeriksa fitur-fitur Vim; Fitur spesifik OS dari :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)

Dan beberapa sistem yang lebih tua (semi-usang):

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.

Contoh:

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

Cara alternatif dengan lebih banyak fleksibilitas adalah dengan memanggil eksternal uname, ini juga memungkinkan Anda untuk mendapatkan nomor versi dan semacamnya:

let uname = system('uname -a')

Catatan yang unametidak ada pada kebanyakan sistem Windows.

Biasanya lebih baik menggunakan deteksi fitur , daripada deteksi OS . Misalnya dengan menggunakan salah satu fitur di has()atau memeriksa apakah ada jalur. Posting 200_success memberikan ikhtisar yang bagus tentang itu, jadi saya tidak akan mengulangi konten yang sama di sini.

Martin Tournoij
sumber
5
Sangat penting untuk mencatat jawaban romainl jika Anda ingin itu berfungsi pada OS X.
Rich
+1 untuk penunjuk ke:h feature-list
JESii
24

has()terdengar seperti ide yang baik sampai Anda mencobanya di Mac OS X: di default /usr/bin/vim, has('unix')adalah benar namun kedua has('macunix')dan has('mac')yang palsu sementara, di reguler MacVim download, ketiganya benar apakah Anda menggunakan GUI atau TUI tersebut.

Jadi solusi terbaik adalah campuran has('winXX')untuk Windows dan unamepada sistem seperti unix. Perhatikan bahwa keluaran unameujung dengan baris baru sehingga harus dibersihkan sebelum digunakan.

Ini adalah kode yang saya gunakan untuk sementara waktu, diperbarui untuk 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

Setelah itu, Anda dapat menggunakan g:osvariabel di mana saja di 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
sumber
OSX adalah sistem UNIX, saya percaya itu bahkan "UNIX bersertifikat". Jadi has('unix')akurat. Aneh kalau has('macunix')itu salah. Ini hampir terdengar seperti bug?
Martin Tournoij
1
Saya melakukan beberapa pengecekan, dan has('macunix')tampaknya bergantung pada MACOS_X_UNIX, yang diatur jika unameada Darwindalam configureskrip ...
Martin Tournoij
Anehnya, has ("win32")tampaknya bekerja untuk saya bahkan dalam Vim 64-bit.
Rich
@ Rich Ya, dan itu sudah didokumentasikan. Ini benar-benar hal yang waras untuk dilakukan, apakah Anda peduli jika aplikasi Anda 32 atau 64 bit? Bukan saya. Alasan itu disebut 'win32', adalah karena itulah nama yang dipilih Microsoft untuk Windows NT API mereka. Memberi nama hal-hal bukan titik kuat Microsoft .
Martin Tournoij
1
has('unix')ini juga berlaku pada Windows Git Bash, jadi tidak terlalu berguna untuk membedakan unix nyata dari yang ditiru.
wisbucky
8

Variabel lingkungan akan bermanfaat.

Untuk mendeteksi tmux, Anda dapat memeriksa if !empty($TMUX)atau if $TERM == 'screen'.

Anda juga dapat menyimpulkan sistem operasi dari variabel lingkungan seperti $MACHTYPE( yang ditetapkan oleh Bash ) atau $PATH.

Untuk mendeteksi apakah fitur seperti TFS diinstal, Anda dapat menggunakan executable()fungsi ini.

200_sukses
sumber
"$ MACHTYPE (yang diatur oleh Bash)" . Sebenarnya, jika sebuah variabel diatur oleh Bash, itu berarti itu bukan variabel lingkungan, dan Anda tidak akan dapat mengaksesnya di vim hanya dengan $MACHTYPE. Anda harus melakukan sesuatu seperti let machtype=system('echo -n $MACHTYPE')dulu.
wisbucky
4

Seperti yang telah ditunjukkan orang lain, deteksi yang andal bisa rumit. Lebih baik tidak menemukan kembali roda, jadi saya ingin menyebutkan perpustakaan vim-misc , yang menyediakan xolox#misc#os#is_mac()dan xolox#misc#os#is_win()fungsi.

Ingo Karkat
sumber
1

Saya mencoba has('unix'), tetapi saya merasa tidak membantu karena semua Linux, Mac, dan Windows Git Bash saya kembali trueuntuk itu.

Saya menemukan unamecocok karena membedakan antara Linux, Mac, Windows, tanpa terlalu banyak rincian.

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
sumber