Phát hiện HĐH trong Vimscript


38

Tôi có thể truy xuất hệ điều hành hiện tại (Windows, Linux, OS X, ..) bằng Vimscript thuần túy (không có Python hoặc Perl) không?

Tôi muốn bật các cài đặt khác nhau trong .vimrc (được đồng bộ hóa) cho các loại hệ điều hành khác nhau mà tôi đang sử dụng.


Bạn có thể cung cấp một số ví dụ cụ thể về các hành vi phụ thuộc vào hệ điều hành mà bạn tìm cách thực hiện không?
200_success

@ 200_success Tôi có một số tập lệnh và các ràng buộc chính cho MS TFS và msbuild khá vô dụng trong môi trường không phải Windows, trong khi tôi không cần hỗ trợ tmux trong gVim trên Windows. Ngoài ra, có các phông chữ khác nhau được cài đặt trên các hệ thống khác nhau và các đường dẫn cũng có thể khác nhau.
muffel

Câu trả lời:


42

Cách tốt nhất là sử dụng has(), với chức năng này, bạn có thể kiểm tra các tính năng của Vim; Các tính năng cụ thể của hệ điều hành từ :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)

Và một số hệ thống cũ (không dùng nữa):

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.

Thí dụ:

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

Một cách khác với sự linh hoạt hơn là gọi bên ngoài uname, điều này cũng cho phép bạn có được số phiên bản và như vậy:

let uname = system('uname -a')

Lưu ý rằng unamekhông có trên hầu hết các hệ thống Windows.

Nói chung, tốt nhất là sử dụng tính năng phát hiện , thay vì phát hiện hệ điều hành . Ví dụ: bằng cách sử dụng một trong các tính năng trong has()hoặc kiểm tra nếu một số đường dẫn tồn tại. Bài đăng của 200_success cung cấp một cái nhìn tổng quan về điều đó, vì vậy tôi sẽ không lặp lại cùng một nội dung ở đây.


5
Tuy nhiên, rất quan trọng để lưu ý câu trả lời của romainl nếu bạn muốn nó hoạt động trên OS X.
Giàu

+1 cho con trỏ tới:h feature-list
JESii

24

has()âm thanh như một ý tưởng tốt cho đến khi bạn thử nó trên Mac OS X: trong mặc định /usr/bin/vim, has('unix')đúng nhưng cả hai has('macunix')has('mac')sai thời gian, trong MacVim tải thường xuyên, cả ba đều đúng cho dù bạn sử dụng giao diện đồ họa hoặc TUI.

Vì vậy, giải pháp tốt nhất là kết hợp has('winXX')cho Windows và unametrên các hệ thống giống như unix. Lưu ý rằng đầu ra của các unamekết thúc với một dòng mới để nó phải được làm sạch trước khi sử dụng.

Đây là mã tôi đã sử dụng một thời gian, được cập nhật cho 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

Sau đó, bạn có thể sử dụng g:osbiến ở bất cứ đâu trong 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

Chà, OSX là một hệ thống UNIX, tôi tin rằng nó thậm chí còn được "chứng nhận UNIX". Như vậy has('unix')là chính xác. Tuy nhiên, điều đó thật kỳ quặc has('macunix'). Điều này gần như là một lỗi?
Martin Tournoij

1
Tôi đã làm một số kiểm tra, và has('macunix')dường như phụ thuộc vào MACOS_X_UNIX, đó là thiết lập nếu unameDarwintrong configurekịch bản ...
Martin Tournoij

Thật kỳ lạ, has ("win32")dường như làm việc cho tôi ngay cả trong Vim 64 bit.
Giàu

@Rich Có, và đó là tài liệu như vậy. Đây thực sự là điều lành mạnh để làm, bạn có quan tâm nếu ứng dụng của bạn là 32 hoặc 64 bit? Tôi không. Lý do nó được gọi là 'win32', là vì đó là tên Microsoft chọn cho API Windows NT của họ. Đặt tên những thứ không phải là điểm mạnh của Microsoft .
Martin Tournoij

1
has('unix')cũng đúng trên Windows Git Bash, vì vậy nó không hữu ích lắm để phân biệt unix thực với mô phỏng.
wvducky

8

Biến môi trường sẽ hữu ích.

Để phát hiện tmux, bạn có thể kiểm tra if !empty($TMUX)hoặc if $TERM == 'screen'.

Bạn cũng có thể suy ra hệ điều hành từ các biến môi trường như $MACHTYPE( được đặt bởi Bash ) hoặc $PATH.

Để phát hiện xem một tính năng như TFS có được cài đặt hay không, bạn có thể sử dụng executable()chức năng đó.


"$ MachTYPE (được đặt bởi Bash)" . Trên thực tế, nếu một biến được đặt bởi Bash, điều đó có nghĩa là nó không phải là biến môi trường và bạn sẽ không thể truy cập nó trong vim đơn giản với $MACHTYPE. Bạn sẽ phải làm một cái gì đó như let machtype=system('echo -n $MACHTYPE')đầu tiên.
wvducky

4

Như những người khác đã chỉ ra, một phát hiện đáng tin cậy có thể khó khăn. Tốt hơn là không phát minh lại bánh xe, vì vậy tôi muốn đề cập đến thư viện vim-misc , nơi cung cấp xolox#misc#os#is_mac()xolox#misc#os#is_win()chức năng.


1

Tôi đã thử has('unix'), nhưng tôi không thấy nó hữu ích vì tất cả Linux, Mac và Windows Git Bash của tôi đã trả lại truecho nó.

Tôi thấy unamelà phù hợp vì nó phân biệt giữa Linux, Mac, Windows, mà không có quá nhiều chi tiết.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.