December 18, 2019

Ruby on Rails with Visual Studio Code in 2020

Discover how to customise Visual Studio Code for efficient Ruby on Rails development with extensions, themes and tasks.

After two years of using Visual Studio Code for Ruby and Ruby on Rails development, I've worked on tweaking my initial configuration quite considerably. In addition to this, the Visual Studio Code community and extension market has grown quite a lot, so I thought now is a great time to write up my process, commonly used questions and workflow.

Theme

Before I get in to describing the extensions I use, it's important to have something easy on the eye for those long hours of writing code.

As a result, I use the 'Solarized Dark' theme. You can activate this by:

  1. Clicking 'Code' (or 'File in Windows)
  2. Then choosing 'Preferences'
  3. Select 'Color Theme'
  4. Choose 'Solarized Dark'

Having a nice font is just as important as beautiful colors, so for that reason, I use Fira Code, which is free, supports retina displays and has multiple font weights, as well as bonus ligatures for symbols.

Extensions

Quick and dirty

If you want to cut straight to the chase, here's a list of extensions I use with commands to install them.

code --install-extension adamwalzer.scss-lint
code --install-extension castwide.solargraph
code --install-extension CraigMaslowski.erb
code --install-extension misogi.ruby-rubocop
code --install-extension mrmlnc.vscode-scss
code --install-extension ms-vscode.atom-keybindings
code --install-extension pavlitsky.yard
code --install-extension rebornix.ruby
code --install-extension shanehofstetter.rails-i18n
code --install-extension vortizhe.simple-ruby-erb
code --install-extension wayou.vscode-todo-highlight

Read on for configurations and helpful tweaks on how to get these working for optimum performance!

Extensions by extension

scss-lint

I use scss-lint to help ensure I stay semantically correct and tidy when writing SCSS.

As an added benefit, you can select properties and then order alphabetically by choosing 'View' > 'Command Palette...' and selecting 'Sort Lines Ascending'.

Download scss-lint from Visual Studio Code Marketplace.

Ruby Solargraph

For those times when you need extra method auto-completion, as well as suggests for class definitions from your code documentation, Ruby Solargraph does a great job of offering all the information you need. You do need to install the Solargraph gem for this, but more on that later.

Download Ruby Solargraph from Visual Studio Code Marketplace.

erb

I've had this installed since I started using Visual Studio Code for erb syntax highlighting.

Download erb from Visual Studio Code Marketplace.

Simple Ruby ERB

Using ERB with Visual Studio Code isn't part of its core build, which is where this extension comes in. Having the simple Ruby and ERB support this extension provides help to get things done a little bit quicker.

Download Simple Ruby ERB from Visual Studio Code Marketplace.

ruby-rubocop

I don't know where I'd be without Rubocop, it's very helpful in ensuring syntax is precise and clear. Its suggestions when something isn't quite right or the reminder for class documentations is helpful!

Download ruby-rubocop from Visual Studio Code Marketplace.

SCSS IntelliSense

Naturally, I work with SCSS as part of Rails; having the auto-completion and intellisense for this is a great time saver.

Download SCSS IntelliSense from Visual Studio Code Marketplace.

Atom Keymap

You may call me old-school for still using this, but the Atom keyboard shortcuts are carved in my memory from the many years I used it. Even though I've been using Visual Studio Code for years now, I've had this extension helping me navigate my way through since day one.

Download Atom Keymap from Visual Studio Code Marketplace.

YARD Documenter

Being able to comment code quick and easily using this extension has saved me many hours of writing comments and figuring out what things do; simply hitting Cmd + Option + Enter on a Mac or CTRL + ALT + Enter on Windows generates class, module, method, constant and attribute comments depending on the placement of your cursor.

This also works amazingly well with the Ruby Solargraph extension.

Download YARD Documenter from Visual Studio Code Marketplace.

Ruby

I may be slightly biased because I've used this extension since I first switched to Visual Studio Code, but this helps make working with Ruby so much more fluent and clean - it's a must have.

Download Ruby from Visual Studio Code Marketplace.

Rails i18n

My workflow consists of using i18n translations for all static text in the code. If it's not content managed, it sits in its translation file. These can grow quickly and having the ability to autocomplete from this file is not only useful, but it's a great time saver.

Download Rails i18n from Visual Studio Code Marketplace.

TODO Highlight

I'll admit, I can't always get everything done in one go, so I do like to leave TODO comments in and around my code to re-visit at the next available opportunity. This extension helps to make those comments stand out just that little bit more, making me want to get them done that little bit quicker.

It's great in combination with the following command built in to Rails, to help output the files and tasks still waiting to be done:

rails notes

Download TODO Highlight from Visual Studio Code Marketplace

Tasks

In addition to the extensions above, I have a tasks.json file that sits in a .vscode folder in the root of the workspace. This defines a few useful extras, such as using beautify to format views, running Rubocop on a separate file or the entire workspace.

As I also use Capistrano for deployment, I've amended that as a task too.

Additionally, as some of the extensions and tasks below require gems, I've configured those as a task; simply run 'configure' to install the required gems. This is great when you upgrade your Ruby version using rbenv as it ensures you have the gems installed quickly and easily.

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
    {
      "label": "beautify",
      "type": "shell",
      "command": "htmlbeautifier \"${relativeFile}\" --keep-blank-lines 1",
      "problemMatcher": [],
      "presentation": {
        "reveal": "never",
        "panel": "shared"
      }
    },
    {
      "label": "batch rubocop",
      "type": "shell",
      "command": "rubocop app/ lib/ --auto-correct",
      "problemMatcher": [],
      "presentation": {
        "reveal": "never",
        "panel": "shared"
      }
    },
    {
      "label": "rubocop",
      "type": "shell",
      "command": "rubocop --auto-correct \"${relativeFile}\"",
      "problemMatcher": [],
      "presentation": {
        "reveal": "never",
        "panel": "shared"
      }
    },
    {
      "label": "rspec",
      "type": "shell",
      "command": "bundle exec rspec",
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "shared"
      }
    },
    {
      "label": "rspec file",
      "type": "shell",
      "command": "bundle exec rspec \"${relativeFile}\"",
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "shared"
      }
    },
    {
      "label": "rails c",
      "type": "shell",
      "command": "bundle exec rails console",
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "dedicated"
      }
    },
    {
      "label": "rails s",
      "type": "shell",
      "command": "bundle exec rails server",
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "dedicated"
      }
    },
    {
      "label": "cap production deploy",
      "type": "shell",
      "command": "cap production deploy",
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "dedicated"
      }
    },
    {
      "label": "configure",
      "type": "shell",
      "command": "gem install ruby-debug-ide:0.6.0 debase:0.2.2.beta10 solargraph rubocop fastri htmlbeautifier scss_lint --no-document",
      "problemMatcher": [],
      "presentation": {
        "reveal": "always",
        "panel": "shared"
      }
    }
  ]
}

Settings

To configure some of these extensions, extra settings are required. Please find my settings.json file below; you can copy it as you need or take the bits relevant for you!

Here's a run through of the basic settings configured here:

  • Auto save files on focus change
  • Use two spaces for tabs
  • Trim trailing whitespace except for Mardown
  • Use Markdown as the default language for new files
  • Exclude version control and asset folders from search
  • Exclude version control folders from files list
  • Disable scroll beyond last line
  • Shrink tabs to fit the window rather than having scroll
  • Hide the feedback statusbar icon
  • Disable telemetrics
  • Disable minimap

You will also need to customise PATH_TO_SCSS_LINT and PATH_TO_RUBY if you wish to have separate configurations for these extensions. Alternatively, simply take them out of the JSON below.

You can open this file by selecting 'View' > 'Command Palette...' > 'Preferences: Open Settings (JSON)'.

{
  "files.autoSave": "onFocusChange",
  "workbench.colorTheme": "Solarized Dark",
  "atomKeymap.promptV3Features": true,
  "editor.multiCursorModifier": "ctrlCmd",
  "editor.tabSize": 2,
  "editor.rulers": [
    80
  ],
  "ruby.lint": {
    "rubocop": {
      "lint": true,
      "rails": true
    },
  },
  "workbench.activityBar.visible": true,
  "telemetry.enableCrashReporter": false,
  "files.trimTrailingWhitespace": true,
  "search.exclude": {
    "**/.git": true,
    "**/.svn": true,
    "**/.hg": true,
    "**/CVS": true,
    "**/.DS_Store": true,
    "**/log": true,
    "**/node_modules": true,
    "**/bower_components": true,
    "**/tmp": true,
    "**/coverage": true,
  },
  "files.exclude": {
    "**/.git": true,
    "**/.svn": true,
    "**/.hg": true,
    "**/CVS": true,
    "**/.DS_Store": true,
    "**/log": true
  },
  "git.ignoreLegacyWarning": true,
  "workbench.sideBar.location": "left",
  "editor.renderWhitespace": "none",
  "editor.scrollBeyondLastLine": false,
  "files.insertFinalNewline": true,
  "scssLint.configDir": "PATH_TO_SCSS_LINT",
  "workbench.startupEditor": "newUntitledFile",
  "window.zoomLevel": 0,
  "workbench.editor.tabSizing": "shrink",
  "editor.trimAutoWhitespace": true,
  "[markdown]": {
    "files.trimTrailingWhitespace": false
  },
  "typescript.tsc.autoDetect": "off",
  "grunt.autoDetect": "off",
  "jake.autoDetect": "off",
  "gulp.autoDetect": "off",
  "npm.autoDetect": "off",
  "files.defaultLanguage": "markdown",
  "editor.fontFamily": "'Fira Code'",
  "editor.fontLigatures": true,
  "breadcrumbs.enabled": true,
  "editor.wordWrap": "on",
  "workbench.statusBar.feedback.visible": false,
  "editor.cursorSmoothCaretAnimation": true,
  "editor.minimap.enabled": false,
  "telemetry.enableTelemetry": false,
  "solargraph.checkGemVersion": false,
  "ruby.interpreter.commandPath": "PATH_TO_RUBY"
}

Any tips or questions?

I'm always tweaking and looking for ways to improve my workflow, so if you have any questions or queries, feel free to get in touch and let me know.

I'd also love to hear your thoughts on my configuration, so do get in touch. For now, though, I hope this was useful in getting started with Ruby on Rails development using Visual Studio Code.