Yesterday, I Installed vim and some colorscheme like gruvbox, monokai, molokai.

I set it in ~/.vimrc and turned on the syntax highlight, everything work well on HTML but in ruby files (.rb) it still have colorscheme but few keywords like puts and print are still in grey color, it looks weird and boring.

That is two syntax I'd using alot during the time I learning. Can anyone help me?

  • This depends more on the syntax elements defined/available to ruby and whether or not the colorscheme makes use of them. I will investigate further later – D. Ben Knoble Aug 28 at 13:59
  • What system are you using, and which version of Vim? I've noticed when editing a new ruby file that I often have to redraw the screen with ^L to get the syntax highlighting to appear correctly on my work machine, gVim 8.0 on 64 bit Win 7. – Herb Wolfe Aug 28 at 15:04
  • @HieuC hope that answer helps – D. Ben Knoble Sep 5 at 19:24

D.Ben Knoble has given a terrific explanation of exactly what happens in the default Ruby syntax configuration.

However, I don't care for his two proposed solutions:

  1. Complain to the Ruby syntax maintainers,
  2. Edit the Ruby syntax file in your local Vim installation, which may then be overwritten when you update Vim.

Vim offers two much simpler solutions:

1. Define your own keyword syntax items

You can define syntax keyword items (:help :syn-keyword) for the strings you want to highlight. These will be used in preference to the existing rubyLocalVariableOrMethod item because that is a lower-priority match item. (See :help :sy-priority)

  1. From your terminal, start editing a new file inside your .vim directory:

    mkdir -p ~/.vim/after/syntax
    vim ~/.vim/after/syntax/ruby.vim
    
  2. Add the following contents:

    syntax keyword Error puts
    syntax keyword Error print
    

    These highlight the literal strings listed with the Error highlight group.

    (I picked this group simply because it's likely to show up in a bright colour in most colour schemes. You will probably want to pick a more appropriate group by viewing the output of the :hi command.)

2. Override the existing syntax item

  1. Same as before:

    mkdir -p ~/.vim/after/syntax
    vim ~/.vim/after/syntax/ruby.vim
    
  2. Add the lines:

    syn match rubyLocalVariableOrMethod "\<[_[:lower:]][_[:alnum:]]*[?!=]\=" contains=NONE display
    highlight link rubyLocalVariableOrMethod Error
    

Because the code in the after/syntax directory runs after Vim's standard syntax files, this overwrites the existing rubyLocalVariableOrMethod syntax item replacing it with a copy of it that does not contain the transparent argument.

The second line then sets up a link to highlight the item with the existing Error highlight colours. (:help hi-link).

Which of these solutions you decide to use will depend on your specific requirements.

  • Good answer Rich; I don't do much monkey-ing around with syntax highlighting, and would rather leave it to people who know what they're doing (for the moment—it seems high time I learn). Hence my suggestions. I'm glad you were able to provide some alternatives that allow for more customization! – D. Ben Knoble Dec 7 at 4:09

There are two different things going on here that prevent colorization of the word puts in ruby files. I examine them (and what led to their discovery) separately.

Setup

First, create the temporary file some.rb, which vim will rightfully detect as ruby code. I gave it the contents

puts "stuff"

Initial thoughts

Next, I ran vim -u DEFAULTS some.rb. To my surprise, puts wasn't highlighted. Time for further investigation! (To eliminate it being something in the defaults script, I also used vim -u NONE some.rb and slowly enabled filetype detection, syntax, &c. I noticed the same results.)

Finding the syntax group

I use my plugin synstax and the mapping <Leader><Leader>s to get the value of the syntax element under the cursor. The relevant code is reproduced in Notes.

The highlight group is: rubyLocalVariableOrMethod. Don't ask me why, that's just how the syntax file defines it.

The highlight

:verbose highlight rubyLocalVariableOrMethod gives, unsurprisingly, cleared. Alright, I think, the colors are just getting cleared. We can track that down.

In $VIMRUNTIME/syntax/ruby.vim, we find at line 122:

syn match rubyLocalVariableOrMethod "\<[_[:lower:]][_[:alnum:]]*[?!=]\=" contains=NONE display transparent

At line 515:

hi def link rubyCapitalizedMethod   rubyLocalVariableOrMethod

There are the only two occurrences in the entire $VIMRUNTIME directory. So no colorscheme even makes use of it.

So it's not getting 'cleared' so much as never being :highlighted. Alright, switch back to some.rb and :highlight link rubyLocalVariableOrMethod Statement.

...

Hint: it won't work.

The :verbose highlight ... idiom gives the expected results: colors, linked to Statement. But why isn't it showing up on the screen?

Syntax & highlight attributes

Take another look at the definition:

syn match rubyLocalVariableOrMethod "\<[_[:lower:]][_[:alnum:]]*[?!=]\=" contains=NONE display transparent

We have the standard syn match <name>, followed by a pattern to match. Sounds good. contains=NONE... a little weird, if you're not familiar, but it seems to indicate things matching this pattern don't contain other syntax groups.

It's easy to miss, being at the end of a longer line, but display and transparent come next. Hmm, I think, this could be relevant.

display simply indicates that no highlighting need be done when the syntax element is off screen; it's a tiny optimization for vim which can reduce it's overall memory consumption (cf. :help :syn-display).

transparent, on the other hand, is the culprit. It effectively disables colors! See :help :syn-transparent for an explanation.

This is useful for syntax items that don't need any highlighting but are used only to skip over a part of the text.

End result

No matter what highlighting you try to apply to rubyLocalVariableOrMethod, it won't show up.

Where do I go from here?

File a bug with the syntax maintainers, possibly with a patch that would fix it: you might - remove transparent, or - add puts and other special words to a different group that has highlighting - something else.

Or, you could monkey-patch your own copy of vim, deleting the transparent word and putting special highlighting in your vimrc. You'd need to do this with every update as well though, since your changes are liable to be blown away.

Notes

The synstax code, as referenced above:

function! synstax#UnderCursor() abort
  let l:stack = synstax#Stack(line('.'), col('.'))
  if empty(l:stack)
    return "No syntax highlight groups under cursor"
  endif
  let l:names = synstax#Attributes(l:stack, 'name')
  return l:names
endfunction

function! synstax#Stack(line, col) abort
  return synstack(a:line, a:col)
endfunction

function! synstax#Attributes(stack, attr) abort
  let l:attr_func = printf('synIDattr(v:val, "%s")', a:attr)
  return map(a:stack, l:attr_func)
endfunction

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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