71

Can I retrieve the current operating system (Windows, Linux, OS X, ..) using pure Vimscript (no Python or Perl)?

I want to enable different settings in my (synchronized) .vimrc for different types of operation systems I am using.

2
  • Could you provide some specific examples of OS-dependent behaviours that you seek to implement? Mar 16, 2015 at 8:47
  • @200_success I have some scripts and key bindings for MS TFS and msbuild that are pretty useless in non-Windows environments, while I don't need tmux support in gVim on Windows. In addition, there are different fonts installed on different systems, and paths may differ as well.
    – muffel
    Mar 16, 2015 at 8:52

6 Answers 6

74

The best way is to use has(), with this function you can check for features of Vim; OS specific features from :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)

And some older (semi-deprecated) systems:

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.

Example:

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

An alternative way with more flexibility is to call the external uname, this also allows you to get the version number and such:

let uname = system('uname -a')

Note that uname isn't present on most Windows systems.

It's generally best to use feature detection, rather than OS detection. For example by using one of the features in has() or checking if some path exists. 200_success' post gives a good overview of that, so I'll not repeat the same content here.

2
  • 7
    Very important to note romainl's answer if you want it to work on OS X, though.
    – Rich
    Mar 16, 2015 at 10:33
  • 1
    +1 for pointer to :h feature-list
    – JESii
    Jun 4, 2017 at 19:18
39

has() sounds like a good idea until you try it on Mac OS X: in the default /usr/bin/vim, has('unix') is true but both has('macunix') and has('mac') are false while, in the regular MacVim download, all three are true whether you use the GUI or the TUI.

So the best solution is a mix of has('winXX') for Windows and uname on unix-like systems. Note that the output of uname ends with a newline so it must be cleaned before use.

Here is the code I've been using for a while, updated for 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

After that, you can use the g:os variable anywhere in your 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
11
  • 1
    Well, OSX is a UNIX system, I believe it's even "certified UNIX". So has('unix') is accurate. It's odd that has('macunix') is false, though. This almost sounds like a bug? Mar 16, 2015 at 10:48
  • 2
    I did some checking, and has('macunix') seems to depend on MACOS_X_UNIX, which is set if uname is Darwin in the configure script... Mar 16, 2015 at 10:56
  • 1
    @Rich Yes, and that's documented as such. This is really the sane thing to do, do you care if your app is 32 or 64 bits? I don't. The reason it's called 'win32', is because that's the name Microsoft choose for their Windows NT API. Naming things isn't Microsoft's strong point. Mar 16, 2015 at 16:55
  • 2
    has('unix') is also true on Windows Git Bash, so it's not very useful for distinguishing real unix from emulated.
    – wisbucky
    Jun 5, 2018 at 9:45
  • 1
    @wisbucky why would you want to distinguish emulated unix? The emulator means to be compatible in the first place.
    – lilydjwg
    Aug 21, 2021 at 12:26
8

Environment variables would be useful.

To detect tmux, you could check if !empty($TMUX) or if $TERM == 'screen'.

You can also deduce the operating system from environment variables such as $MACHTYPE (which is set by Bash) or $PATH.

To detect whether a feature such as TFS is installed, you can use the executable() function.

1
  • "$MACHTYPE (which is set by Bash)". Actually, if a variable is set by Bash, that means it is not an environment variable, and you will not be able to access it in vim simply with $MACHTYPE. You will have to do something like let machtype=system('echo -n $MACHTYPE') first.
    – wisbucky
    Jun 6, 2018 at 0:02
4

As others have already indicated, a reliable detection can be tricky. Better not reinvent the wheel, so I'd like to mention the vim-misc library, which provides xolox#misc#os#is_mac() and xolox#misc#os#is_win() functions.

0
3

I tried has('unix'), but I didn't find it helpful since all my Linux, Mac, and Windows Git Bash returned true for it.

I found uname to be suitable as it distinguishes between Linux, Mac, Windows, without too much granularity.

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
1

I use this on my vimscript, currently on Vim v8.0:

if has("mac")
    "Mac
elseif has("win32")
    "all Windows, ie win32,win64
elseif has("win32unix")
    "Cygwin
elseif has("bsd")
    "BSD-based, ie freeBSD"
elseif has("linux")
    "Linux
end

This covers most of the OS, I hope. One should use has(feature) if possible, and avoid uname, since uname is not portable (ie not available on non-unix-like OS)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.