How to detect REAL Operating System in VimScript? - vim

I need to decide which binary executable file I need to choose, so I have to know the OS which Vim is running on.
I find there is related question here. But the has('win32') || has('win64') solution doesn't work for me, since when I'm using msys2 Vim on Windows, I will get 0 from the has solution, because the has solution only tells the OS which vim is compiled for, not the real OS which it is running on.
And when I need to decide which binary executable file I need to choose, I have to know the real OS. Is there any good idea about this problem?

From this Gist:
Define a global variable containing the current environment's name if it hasn't been already defined.
if !exists('g:env')
if has('win64') || has('win32') || has('win16')
let g:env = 'WINDOWS'
else
let g:env = toupper(substitute(system('uname'), '\n', '', ''))
endif
endif
Use that global variable…
if g:env =~ 'DARWIN'
" ... to do Mac OS X-specific stuff.
endif
if g:env =~ 'LINUX'
" ... to do Linux-specific stuff.
endif
if g:env =~ 'WINDOWS'
" ... to do Windows-specific stuff.
endif
if g:env =~ 'CYGWIN'
" ... to do Cygwin-specific stuff.
endif
if g:env =~ 'MINGW'
" ... to do MinGW-specific stuff (Git Bash, mainly).
endif
And so on.

Related

Check if using Windows console in Vim while in Windows Subsystem for Linux?

I am using Vim inside the Windows Subsystem for Linux. The windows command prompt has a bug which renders the background color incorrectly.
The fix is set t_ut=. Rather than applying this fix in all situations, I assume it would make sense to only apply it when Vim is being used inside the Windows console.
Unfortunately, I am not sure how to detect whether the Windows console is being used, because I am inside the Windows Subsystem for Linux.
I used the following code that implemented Roadowl's comment.
let uname = substitute(system('uname'),'\n','','')
if uname == 'Linux'
if system('$PATH')=~ '/mnt/c/WINDOWS'
" We are in Windows Subsystem
endif
endif
Update: I combined roadowl's and bk2204's answer:
let uname = substitute(system('uname'),'\n','','')
if uname == 'Linux'
let lines = readfile("/proc/version")
if lines[0] =~ "Microsoft"
return 1
endif
endif
Typically, one addresses issues like this by detecting the terminal type, but it seems Microsoft Terminal reports xterm-256color when it really doesn't support this.
It's possible to detect whether one is running WSL with a function like the following:
function! IsWSL()
if has("unix")
let lines = readfile("/proc/version")
if lines[0] =~ "Microsoft"
return 1
endif
endif
return 0
endfunction
This is consistent with the way that Microsoft suggests that WSL be detected.

Vimdiff failing with "Cannot read or write temp files"

I'm using Vim 7.4 on Windows 7.
I do have a custom _vimrc file, but both Vim and gVim work fine. When I try to run vimdiff .\xxxxx .\yyyyy, it gives the error
Cannot read or write temp files
This issue can be caused by the default _vimrc file created by the installer on Windows. If you're still using that default file, or if you copied it at some point, then check the function you've assigned to the diffexpr option. One of the patches between Vim 7.3 and 7.4 introduced new default quoting rules for the cmd.exe shell on Windows. This patch broke the workaround in the MyDiff() function designed to fix the same issue solved by the patch.
The MyDiff() function was fixed by version 7.4.103 by fixing the installer. Here is the MyDiff() function which the latest installer will create for you if you just want to copy it to your _vimrc:
function MyDiff()
let opt = '-a --binary '
if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
let arg1 = v:fname_in
if arg1 =~ ' ' | let arg1 = '"' . arg1 . '"' | endif
let arg2 = v:fname_new
if arg2 =~ ' ' | let arg2 = '"' . arg2 . '"' | endif
let arg3 = v:fname_out
if arg3 =~ ' ' | let arg3 = '"' . arg3 . '"' | endif
if $VIMRUNTIME =~ ' '
if &sh =~ '\<cmd'
if empty(&shellxquote)
let l:shxq_sav = ''
set shellxquote&
endif
let cmd = '"' . $VIMRUNTIME . '\diff"'
else
let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
endif
else
let cmd = $VIMRUNTIME . '\diff'
endif
silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3
if exists('l:shxq_sav')
let &shellxquote=l:shxq_sav
endif
endfunction
You can see your full version in Vim using the :version or :intro commands, or at the splash screen at startup.
The official Vim 8.0 installer is now available, or you can install a nightly build, install Vim from other places or build your own Vim. Installing with any of these methods should get you the latest default vimrc file if you want to grab the latest incarnation of this function.
Copied from my answer to this same question on Super User.
Adding:
set shell=c:\cygwin64\bin\bash.exe
to my _vimrc worked for me.
I was getting this exact error and had uselessly fiddled around with the permissions on set backupdir.
But then I remembered that I have recently changed to Windows 7 and to using Cygwin 64 and had forgotten to repoint the following setting.
set shell=c:\\cygwin64\\bin\\zsh.exe shellcmdflag=-c shellxquote=\"
And hey presto the error went away and the following now works:
gvim -d v1.php v2.php
So what this error is really saying is I can't find your shell or cmd!
I installed Vim 8.0 on Windows 7. After adding the directory containg vim to my PATH variable "diffthis" etc. worked out of the box if called from a CMD command line. But calling gvim from a cygwin bash resulted in error "E97: cannot create diff".
The following _vimrc (inspired by this and this post) solved the problem with cygwin and it also works with Windows commandline:
runtime vimrc_example.vim
" Change path to bash with your workstation specific path
set shell=C:\Programme\cygwin\bin\bash
" Override value of TMP from cygwin (normally set to /tmp)
let $TMP="c:/tmp"
Note that with the _vimrc above you lose gvim's Windows-specific behavior like using CTRL-V for pasting etc (you can use SHIFT-Ins anyhow). But with enabled Windows-specific behavior (like in the generated _vimrc during install) gvim failed to perform "diffthis" with "E97:..." error.
I also was getting the messages
E810: Cannot read or write temp files
E97: Cannot create diffs
However my _vimrc file was fine.
The issue was that C:\Program Files\Vim\vim74 was not in the PATH environment variable, so Vim could not launch diff.exe.
Vim 8.1
I was experiencing this issue, and this answer resolved it for me.
Add this to your ~/.vimrc
set shell=$COMSPEC
For me using git for windows, this value is: C:\WINDOWS\system32\cmd.exe
Also note that in this thread every answer other than the top answer relates to changing your shell variable. So if you're someone who has stumbled upon this answer, try taking a look at that.
Have you set vim shell to powershell? If so this answer might work. After hard searching my problem was solved by it.
At least see what shell you're using, or try to set vim shell to other shells if installed, e.g. set shell=/path/to/bash.exe, it might shed some light.

VIM source file on OS condition using interpolation in .vimrc?

I'd like to source files based on my OS platform in my .vimrc configuration file. I'd like to do something like this:
source .vimrc/{uname -S}.vim
I'm doing this because I'd like to source files based on operating system. I know my syntax is wrong, but I think you get the idea. How would I do this? Thank you.
I think OP wants to source the vim file in vim (e.g. vimrc) not in shell. so you could try to add this line in your vimrc:
execute 'source path/to/'. substitute(system('uname -s'), "\n", "", "") . '.vim'
This what I have in my vimrc:
let os=substitute(system('uname'), '\n', '', '')
if os == 'Darwin'
" settings for Mac OS X
elseif os == 'Linux'
" settings for Linux
endif
-- EDIT --
For what it's worth, I've written that snippet a "long" time ago and I can't remember why I added Mac. I initially thought that, maybe, I had found out that uname reported Mac in some context for some reason, but no, it appears to be Darwin everywhere. So I've removed Mac for that snippet to make more sense and will do the same to my vimrc.

Vimscript: How can I get the Operating System version?

Even though it's similar to this and this question I need to know the current version of the operating system while vim is running. The previous questions don't help me since they describe a feature set of the executable; what I need is a function to return the os version either name or number (e.g. as listed in this widows version chart).
Is there one?
I don't know about Windows but on Mac OS X you can do:
$ sw_vers -productVersion
and on Ubuntu you can do:
$ lsb_release -rs
This quick hack seems to work, you'll have to adapt it to your needs:
function! GetSysVersion()
let os=substitute(system('uname'), '\n', '', '')
if os == 'Darwin' || os == 'Mac'
let sys_version=substitute(system('sw_vers -productVersion'), '\n', '', '')
elseif os == 'Linux'
let sys_version=substitute(system('lsb_release -rs'), '\n', '', '')
endif
echo sys_version
endfunction
(Just to make 30 characters)
echo exec('cat "/etc/issue"')
To invoke the Win32 function GetVersionEx(), you have to write a DLL that exposes the function, and invoke it from Vim via libcall(). For all the implementation details, see
:help libcall()
Alternatively, you could write an executable and use system() to parse its output.

Vimscript: how do I get the OS that is running Vim?

I've got vim plugin that runs on different machines and sometimes needs to do things differently depending on whether it's Windows, Linux, Mac.
What's easiest way to test for the operating system? I know I could parse the output of :version command. Is there something simpler that will reveal the OS?
From google:
You can use has() and the list of features under :help feature-list to
determine what type of Vim (and therefore under which OS is running).
if has('win32')
... win32 specific stuff ...
endif
Search for "version of Vim" from the feature-list help topic and that
should bring you to the different versions for which you can check.
In addition to #John's answer here is a full list of possible operating systems:
"▶2 os.fullname
for s:os.fullname in ["unix", "win16", "win32", "win64", "win32unix", "win95",
\ "mac", "macunix", "amiga", "os2", "qnx", "beos", "vms"]
if has(s:os.fullname)
break
endif
let s:os.fullname='unknown'
endfor
"▶2 os.name
if s:os.fullname[-3:] is 'nix' || s:os.fullname[:2] is 'mac' ||
\s:os.fullname is 'qnx' || s:os.fullname is 'vms'
let s:os.name='posix'
elseif s:os.fullname[:2] is 'win'
let s:os.name='nt'
elseif s:os.fullname is 'os2'
let s:os.name='os2'
else
let s:os.name='other'
endif
"▲2
This is the code used by my frawor plugin for determining current operating system.
Due to my love of Python:
python << endpython
import sys
sys.platform
endpython
Also maybe os.name if needed.

Resources