In shell I do conditional stuff depending on distro like this:
eval "$(source /etc/os-release && typeset -p ID)"
if [[ $ID =~ ^(rhel|fedora.*|amzn|ol|rocky|almalinux)$ ]]; then
...
fi
How could I do that in vimscript?
As I pointed out in my comment, I suspect it's an XY problem. I wouldn't read any files in /etc
in Vim at all. Although I have to say I'm delighted to have read some great answers.
A comment on the question says the same dotfiles are used on all machines and I think that's where things start to go wrong. Those are configuration files, they are meant to be configured. So allow for some system-specific tweaking.
I would propose a distro-agnostic approach of reading from an optional, machine-specific configuration file like this:
" set defaults that make sense
" ...
if filereadable(expand('~/.vim/overrides/distro.vim'))
source ~/.vim/overrides/distro.vim
endif
You can put the config file next to your Vim configuration like in my example or specify another path. See :help filereadable()
and :help expand()
for usage information.
There are two more points to consider which largely depend on how the machines are set up and dotfiles are deployed. There's nothing about it in the question so I'll have to guess a little.
You can write distro.vim
e.g. from a shell script much like that in the question or a makefile when you set up a new machine and install your dotfiles. A less favorable option would be to write it from a shell profile whenever you log in.
Also, the configuration should be ignored in whatever tool is used to setup the dotfiles, e.g. add it to .gitignore
if Git is what you use.
Main advantages of this approach:
source
ing another file and re-setting some options. You should not be able to notice.$ENV
variables to make it more flexible. And heredocs could also be used if you really want to
Commented
Oct 24, 2023 at 9:41
Here's my version:
:echo readfile('/etc/os-release')->filter({k,v -> v =~# '^ID='})[0]->slice(3)
This errors if !filereadable('/etc/os-release')
and assumes the line of interest is exactly ID=<value>
. If the file must be interpreted by a shell to be correct, something like Vivian's answer using source
in systemlist()
is probably more appropriate.
nvim
, which I also use. E117: Unknown function: slice
Commented
Oct 24, 2023 at 1:47
[3:]
or similar syntax @paradroid
I would do:
let distrib = system('source /etc/os-release && typeset -p ID')
if distrib =~ '(rhel|fedora.*|amzn|ol|rocky|almalinux)'
" ...
endif
system
to get the output of source
Commented
Oct 23, 2023 at 6:30
Will this work ?
function! GetLinuxDistro()
let os_release_path = '/etc/os-release'
if filereadable(os_release_path)
let os_info = readfile(os_release_path)
for line in os_info
if line =~ 'PRETTY_NAME'
return substitute(line, 'PRETTY_NAME="\(.*\)"', '\1', '')
endif
endfor
endif
return 'Unknown Linux Distribution'
endfunction
echo GetLinuxDistro()
I've started using different terminal colours on different machines/servers to help me know where I am and wanted to change the vim colourschemes to match. I can't think of a better way to differentiate as they all use the same dotfiles. I could use hostnames, but this would not need updating.
Or you could:
$TERM
, like xterm-16color
,default
and any of the other built-in ones or this one or that one.That way, Vim doesn't need to be aware of where it is running; it always shows the expected colors.
$TERM
fine and all shells local and remote are either xterm-256
or tmux-256color
with 16m Truecolor and everything displaying as it should (with this fix ix.io/4JPR). In tmux things aren't quite perfect, but only if I look very closely. Not sure what you mean, as I basically want different colours on remote servers compared to local machines, as it helps workflow, remembering where I am in the terminal.) It's $LS_COLORS
and vim colorschemes that I am conditionally changing, I should have been clearer.)
Commented
Oct 24, 2023 at 13:26
$LS_COLORS
then my answer is irrelevant. FWIW, a colleague of mine used a similar technique a few years ago: one profile/theme per host, with a different background for each, all set at the terminal emulator level. It seemed to work well for him.
readfile()
orsystem()
orsystemlist()
to get the distribuation. But note, checking this on startup, may slow down your startup time (obviously)