Home Download Buy Blog Forum Support

(Better?) Ruby Syntax Highlighting

(Better?) Ruby Syntax Highlighting

Postby edubkendo on Sat Aug 10, 2013 5:46 am

I've recently taken quite a liking to the Base16 set of themes, in particular, Solarized, Eighties, and Tomorrow Night. However, when using it with Ruby, I realized that the output looked nothing like the example shown here: http://chriskempson.github.io/base16/ . When I examined the scopes of the uncolorized elements, I discovered that many of them remained unscoped.

This led me on a quest to find a better tmLanguage file for Ruby, but I was greatly surprised to find out that very little development in this regard had been done. The textmate tmBundle is in fact, updated regularly, but even replacing subl's Ruby.tmLanguage with the most recent clone of it's ruby.plist did not improve the output much, and seemed to lose some things like proper syntax folding. I then found an old "experiment" called Experimental Ruby, but even though it fixed some of the omissions it had problems of its own.

Thus followed several days of hacking, combining and experimentation. I was sad to discover that neither the original, nor @FichteFoil's awesome update to AAAPackageDevelopment was currently supporting ST3, so I reinstalled ST2 while working on this project. For doing anything besides tweaking, working on YAML files is just so much easier than trying to deal with XML.

This is the result: RubyNext.tmLanguage . It's a very optimistic grammar, assuming in some places that we'd prefer to accidentally color something that should not be, over missing many many things that should be. Ruby is such an ambigious language, without a real parser and AST, i think it's pretty difficult to get 100%.

I also made a tiny tweak to the Base16 tmTheme. Taking his Base16 Builder, I tweaked the file /templates/textmate/dark.tmTheme.erb like this:

Code: Select all
         <string>variable, punctuation.definition.variable, variable.parameter.function</string>
            <string>#<%= @base["08"]["hex"] %></string>

Otherwise, even with my updates, it was not correct according to the example online.

Running ./base16 after that update produces a bunch of files in a folder called "output", including a folder "output/textmate" with all the tmThemes inside that can be moved into your packages directory. These are the results:


There are still just a few things it doesn't color, but honestly, at this point enough things are color, the gray text is just another element of contrast.
Posts: 30
Joined: Fri May 18, 2012 2:43 pm
Location: Nashville

Re: (Better?) Ruby Syntax Highlighting

Postby Inkling on Sat Dec 14, 2013 7:34 am

Thanks for this, been using it the past few weeks and its definitely an improvement.

However there is an issue I want to bring to your attention. When there is a comment line above another line like so:
Code: Select all
# Comment goes here
require 'spec_helper'
the proper syntax selector/scope doesn't get applied to "require" or other keyword, it only gets the base scope, and therefore it doesn't get colored correctly. However this only occurs when Ruby on Rails syntax is activated for the file (or a derivative like Rspec), it doesn't happen with just plain Ruby selected.
You would think then that perhaps the rails tmLanguage file was the culprit, but the issue does not occur when using the default ruby language definition (again, with Rails syntax activated), and I was able to fix it by replacing your modifications for the comment scope (comment.line.number-sign.ruby) with the default.

Also I'd just like to make one suggestion. I know the syntax scope for local variables isn't perfect due to the very nature of ruby, but a small improvement I can think of is excluding a single name/word if it's surrounded by curly braces, as it's unlikely to be a variable and far more likely to be a method call within an inline block. In this example:
Code: Select all
{ probably_not_a_variable }
"probably_not_a_variable" currently gets given a variable scope, unless you add explicit parentheses, or a space(s) and another word after it.
If the curly braces do represent an inline block, it doesn't make much sense for it to be a variable, because it'd just be sitting there on its lonesome not really doing anything:
Code: Select all
method_that_accepts_block { probably_not_a_variable }

And if the curly braces represent a hash, there will just be a syntax error because it's not paired with anything:
Code: Select all
hash = { syntax_error }
Once paired with a value or key the highlighting will figure itself out as usual.

I attempted to do this myself but unfortunately failed, it was made more difficult by the fact that you could have any number of spaces between the word and the brackets depending on style:
Code: Select all
{ word }
{  word  }
{   word   }
{                           word}
but \s* apparently can't be used in lookbehinds in regular expressions. After trying a few different strategies I gave up :P
Posts: 4
Joined: Mon Dec 09, 2013 6:24 am

Return to Plugin Development

Who is online

Users browsing this forum: Google [Bot] and 4 guests