I love how easy Visual Studio Code makes things, especially when it comes to working on the frontend of websites. The autocompletion features and extensions make writing code a breeze so I can focus on the solution I'm trying to implement.

But when I started messing around with ERB views in a Ruby on Rails app, I ran into problems. Normally I would look to see if there's an extension available with built-in helpers to simplify code completion. This didn't quite work well in VS Code, because while the extension would enable the ERB-related tags, it would end up disabling the HTML-related ones.

So I could type <%= yield %> with ease, but not <h2>Some headline</h2>.

Some searching didn't turn up much until I noted in the documentation for an ERB helper extension by Rayhan Wirjowerdojo that it was possible to manually add the helpers directly as user snippets.

How to do it

Instead of adding the helpers to user snippets for ERB, I added them for HTML. This allowed me to autocomplete both ERB and HTML-related tags.

Here are the snippets that I added. They're taken from Rayhan's extension and modified slightly so that they all begin with "r" for Rails (which is the most likely framework I'll be using them with):

{
	"pc": {
		"prefix": "rpc",
		"body": "<%# $0 %>",
		"description": "commented ERB tags",
		"scope": "text.html.ruby"
	  },
	  "each": {
		"prefix": "reach",
		"body": "\n<% ${1:@things}.each do |${2:thing}| %>\n\t$0\n<% end %>\n",
		"description": "ERB each block",
		"scope": "text.html.ruby"
	  },
	  "else": {
		"prefix": "relse",
		"body": "<% else %>",
		"description": "ERB else tag",
		"scope": "text.html.ruby"
	  },
	  "elsif": {
		"prefix": "relsif",
		"body": "<% elsif ${1:true} %>",
		"description": "ERB elsif tag",
		"scope": "text.html.ruby"
	  },
	  "end": {
		"prefix": "rend",
		"body": "<% end %>\n",
		"description": "ERB end tag",
		"scope": "text.html.ruby"
	  },
	  "er": {
		"prefix": "rer",
		"body": "<% $0 %>",
		"description": "ERB no display tag",
		"scope": "text.html.ruby"
	  },
	  "ff": {
		"prefix": "rff",
		"body": "<%= form_for(${1:@things}) do |${2:f}| %>\n\t\t$3\n<% end %>\n  ",
		"description": "ERB form_for tag",
		"scope": "text.html.ruby"
	  },
	  "ife": {
		"prefix": "rife",
		"body": "\n<% if $1 %>\n\t$2\n<% else %>\n\t$0\n<% end %>\n",
		"description": "ERB if / else / end",
		"scope": "text.html.ruby"
	  },
	  "if": {
		"prefix": "rif",
		"body": "\n<% if $1 %>\n\t$0\n<% end %>\n",
		"description": "ERB if / end",
		"scope": "text.html.ruby"
	  },
	  "lblt": {
		"prefix": "rlblt",
		"body": "<%= label_tag :${1:thing}, \"${2:Your label text}\" %>",
		"description": "ERB label tag",
		"scope": "text.html.ruby"
	  },
	  "lt": {
		"prefix": "rlt",
		"body": "<%= link_to $1, $2 %>",
		"description": "ERB link tag",
		"scope": "text.html.ruby"
	  },
	  "pe": {
		"prefix": "rpe",
		"body": "<%= $0 %>",
		"description": "ERB display tag",
		"scope": "text.html.ruby"
	  },
	  "st": {
		"prefix": "rst",
		"body": "<%= submit_tag \"${1:My Button Text}\", class: \"${2:class}\" %>",
		"description": "ERB submit tag",
		"scope": "text.html.ruby"
	  },
	  "tft": {
		"prefix": "rtft",
		"body": "<%= text_field_tag \"${1:name}\", \"${2:value}\", placeholder: \"${3:placeholder}\", class: \"${4:class}\" %>",
		"description": "ERB text field tag",
		"scope": "text.html.ruby"
	  },
	  "unless": {
		"prefix": "runless",
		"body": "\n<% unless $1 %>\n\t$0\n<% end %>\n",
		"description": "ERB unless / end",
		"scope": "text.html.ruby"
	  },
	  "image tag": {
		"prefix": "rit",
		"body": "<%= image_tag ${1:source}, :${2:alttext} %>",
		"description": "Image tag",
		"scope": "text.html.ruby"
	  },
	  "cloudinary image tag": {
		"prefix": "rclt",
		"body": "<%= cl_image_tag(@$1) %>",
		"description": "a cloudinary image tag",
		"scope": "text.html.ruby"
	  },
	  "time ago in words": {
		"prefix": "rtw",
		"body": "<%= time_ago_in_words($1) %>",
		"description": "distance from time tag",
		"scope": "text.html.ruby"
	  },
	  "simple form helper": {
		"prefix": "rsf",
		"body": "<%= simple_form_for @${1:model} do |f| %>\n\t$0\n<% end %>\n",
		"description": "simple form tag",
		"scope": "text.html.ruby"
	  },
	  "simple form nested model helper": {
		"prefix": "rsfn",
		"body": "<%= simple_form_for [@${1:first}, @${2:second}] do |f| %>\n\t$0\n<% end %>\n",
		"description": "nested model simple form tag",
		"scope": "text.html.ruby"
	  },
	  "simple form input": {
		"prefix": "rfi",
		"body": "<%= f.input :${1:attribute} %>",
		"description": "Input for simple form",
		"scope": "text.html.ruby"
	  },
	  "hidden field tag": {
		"prefix": "rhft",
		"body": "<%= hidden_field_tag :${1:label}, ${2:value} %>",
		"description": "Hidden field tag helper",
		"scope": "text.html.ruby"
	  },
	  "simple form submit": {
		"prefix": "rft",
		"body": "<%= f.submit '${1:text}' %>",
		"description": "Submit tag for simple form",
		"scope": "text.html.ruby"
	  },
	  "link to if": {
		"prefix": "rlft",
		"body": "<%= link_to_if($1, $2) %>",
		"description": "Link to if tag",
		"scope": "text.html.ruby"
	  },
	  "javascript pack tag": {
		"prefix": "rjpt",
		"body": "<%= javascript_pack_tag '$1' %>",
		"description": "javascript pack tag",
		"scope": "text.html.ruby"
	  }
}

I'm now able to seamlessly interact with views in my Rails app with Visual Studio Code. I can autocomplete all syntax HTML-related syntax, as well as ERB.

If there was a better way I could have done this, please let me know. :)