4
votes

I am trying to write a ruby source code as a string (as part of real Ruby code) on a text editor with syntax highlighting for Ruby code, but want the Ruby syntax highlighting to work on the code inside the string. Using double or single quotes, percent notation, heredoc all make the text editor recognize that it is a string, so the whole chunk of code is colored in a single color as a string.

<<_
class Foo
    def bar
        # blah blah
    end
end
_

Is there a way to let the Ruby syntax highlighting on the editor miss the borders of the string so that its content is highlightened as Ruby code?


Edit

Stefan notices a wonderful feature on Atom, Sublime Text and RubyMine to do this. But unfortunately, it does not seem to work on Emacs ruby mode. Does someone know of a modified ruby-mode.el or a some additional library on emacs to do this?

Edit

Or can anyone write a simple elisp code (just to ignore heredoc start and end when the heredoc identifier is RUBY if it is difficult to implement highlighting for other languages)?

2
Using RUBY (or HTML or SQL) as the heredoc identifier works in some editors, i.e. str = <<-RUBYStefan
You should be able to set that up using mmm-mode, but that will require some tinkering.Dmitry

2 Answers

8
votes

At least Atom, Sublime Text and RubyMine support syntax highlighting based on the heredoc identifier. <<-RUBY is rendered as Ruby, <<-SQL as SQL and so on.

Here's a screenshot from Atom:

Atom Editor Screenshot

2
votes

As Dmitry hints at it is indeed possible to do this in emacs mmm-mode. Here is part of my init-ruby-mode.el emacs config:

(require 'mmm-mode) ; install from melpa

(eval-after-load 'mmm-mode
'(progn
 (mmm-add-classes
  '((ruby-heredoc-js
     :submode js2-mode
     :front "<<-?JS_?.*\r?\n"
     :back "[ \t]*JS_?.*"
     :face mmm-code-submode-face)))
 (mmm-add-mode-ext-class 'ruby-mode "\\.rb$" 'ruby-heredoc-js)))

(eval-after-load 'mmm-mode
 '(progn
  (mmm-add-classes
  '((ruby-heredoc-shell
     :submode shell-script-mode
     :front "<<-?SH_?.*\r?\n"
     :back "[ \t]*SH_?.*"
     :face mmm-code-submode-face)))
 (mmm-add-mode-ext-class 'ruby-mode "\\.rb$" 'ruby-heredoc-shell)))

My emacs config is based entirely off of the purcell/emacs.d package, so I'd recommend looking there for LOTS more good examples of how to make emacs work for you. I added a section to make nested Ruby code work, here's what it looks like:

nested Ruby code

As a side note, above where it says require 'mmm-mode - my config is actually using the purcell function require-package, but that's not as portable.

There is a bug where I need to save and revert the buffer to get mmm-mode to recognize the a new heredoc string, but I hardly use this feature so it's not worth solving for me.