How to indent Ruby code on Mac
You can do this with Note My, and Ruby gets a setting of its own. Here is how to put it at two spaces without changing every other language, what the Ruby section of the Indentation sheet controls, and how to read the file that comes back.
A Ruby file that has passed through a few hands ends up with three-space blocks, a stray tab, and do … end in some places and braces in others. The fix is one pass over the whole file, and in Note My it runs from a single toolbar button. Ruby is one of the languages our indentation engine treats as its own, and the sheet gives it two controls no other language gets.
This guide covers setting a two-space width for Ruby without changing it everywhere else, what those two controls do, and how to read the file that comes back.
All of this happens on your Mac. Nothing is uploaded, there is no account to make, and your source never leaves the machine to be formatted.
Set Ruby to two spaces
The indent width control starts at 4 and runs from 1 to 12, and the unit starts on spaces. A couple of languages arrive with the unit already chosen for you — Go on tabs, Python on four spaces — and Ruby is left in your hands, which is the arrangement you want on a language with a house style per team. You set it once, with Ruby selected, and it stays set for Ruby in every Ruby file you open after that, today and next week.
-
Save the file first
Press ⌘S. A re-indent rewrites the whole file, and a saved copy on disk is what makes that a comfortable thing to do: File ▸ Reload from Disk (⌘R) discards the reformatted text and reads back exactly what you saved. One keystroke out, one keystroke back — that is the habit worth building before any whole-file operation.
-
Check that Note My knows it is Ruby
The status bar shows the language the tab is set to, and the Ruby controls in the sheet only apply once it says Ruby. Our advanced language identifier does that part for you, so a Ruby file you open usually arrives set to Ruby and you rarely have to think about it; a short fragment pasted into an untitled tab is the case worth a glance. You always have the last word: click the Identify pill, choose Ruby, and confirm. Settle it before you open the Indentation sheet, so the Ruby section is there waiting when you get to it.
-
Open the Indentation sheet
Click Indent in the toolbar — the curly-braces glyph. It opens a sheet and changes nothing on the way, so you can open it mid-thought, look at what is set for Ruby, and close it again with your file exactly as you left it. The toolbar button is one click from wherever you are in the document.
-
Choose Ruby in the language picker
The picker offers a global default plus a list of languages. Selecting Ruby snaps the brace-style, width and tabs-or-spaces controls to whatever you have already chosen for Ruby — those three are the settings kept per language.
-
Set the width to 2, and leave it on spaces
With Ruby selected, a width of 2 is stored against Ruby, and your Java and C files keep whatever you set for them. Leave the tabs switch off — Ruby is conventionally written in spaces, and the switch stays exactly where you put it.
-
Press Apply
Nothing in your document changes until you do. The preview card renders a short
if <condition> { … }sample, so you can see the width and the brace style themselves before you commit them; Apply is the moment those settings go through your own file.
Re-indent is at its best as a whole-document operation. One pass and the entire file agrees with itself, top to bottom, which is exactly what you want on a file several people have edited. Save, Indent, Apply, read the result.
Block style: automatic, always do/end, or always braces
Ruby is one of the few languages in the sheet with its own policy control, and block style is the interesting one.
| Setting | Effect |
|---|---|
| Automatic | The default. Neither form is forced on the document. |
| Always do/end | Normalises blocks to the do … end form. |
| Always braces | Normalises blocks to the brace form. |
On a file where both forms are mixed, one of the two absolutes is what settles it. Pick whichever matches the majority of the file, Apply, and the rest comes into line with it in a single pass — the work you would otherwise do block by block, done in the time it takes to scroll through the result.
items.each { |item|
puts item.name
total += item.price
}With Always do/end selected, that comes back in the form most Ruby style guides ask for on a multi-line block:
items.each do |item|
puts item.name
total += item.price
endAligning hash rockets
The Ruby section carries a second option: hash-rocket alignment. It decides whether the => arrows in a multi-line hash line up into a column or stay where they fall. Set it before you press Apply — like everything in this sheet, it takes effect at Apply and not before.
DEFAULTS = {
:host => "localhost",
:port => 3000,
:read_timeout => 5,
:log => :verbose
}Be deliberate: an aligned hash reads well and produces a wide diff the next time a key is added. If your team reviews changes line by line, leaving the arrows where they fall is the kinder choice. This one is a single global setting rather than a per-language one, which matters for the reset behaviour below.
What the pass gets right in a Ruby file
Ruby is awkward to re-indent by hand. Blocks close with end rather than a brace, if can sit at the end of a line as a modifier, and symbols, strings and comments all use characters that mean something else elsewhere. A general-purpose tidy that treats every language as curly braces leaves a Ruby file worse than it found it.
Our indentation engine treats Ruby as Ruby. In practice that means do … end blocks close at the depth they opened at, a trailing if or unless does not drag the following line in, and a symbol-heavy hash comes back looking like a hash rather than a nested block. The payoff is one pass instead of a pass followed by manual repair — and, as with everything here, it happens on your Mac.
The routine that gets the most out of it is short: save, Apply, read the result. On a file that is sound you get the whole thing right in one go, and the saved copy on disk means you are never committed to anything until you have looked at it and decided you like it. If the shape that comes back surprises you, the depth of the file is telling you something useful about the code — the troubleshooting entry on an unbalanced end below shows how to read it.
Unpacking statements that share a line
Re-indent does more than move lines sideways. Statements compressed onto one line are unpacked, not merely shifted:
def summary(order); total = order.sum; puts total; endcomes back as separate lines at their correct depths — the part people do not expect, and the reason to run a first pass on a saved file. It changes the shape of your code, not just its margins, so read the result before you carry on.
Recovering code a comment swallowed
Recover damaged comments is a checkbox in the sheet, off by default. It handles one particular kind of damage, and it handles it in Ruby: a line where a comment marker has swallowed real code, so a comment and two statements ended up as a single commented line. Switch it on and that line comes back as the comment and the statements it was before someone's careless paste ran them together.
It is deliberately cautious. It only ever changes single-line comments, and a comment you wrote on purpose comes back untouched. Even so, treat it as a tool for a specific job: switch it on for an inherited file you know has that damage, check the result, and switch it off again rather than leaving it on as routine. If you are not sure a file has the problem, run the pass once with the box off, read what comes back, and decide then.
Reading end-terminated blocks
Two spaces is a shallow indent, so a deeply nested Ruby method is where indentation guides earn their place. Guides are on by default, with ten styles — Dots is the default — in Settings ▸ Guides, plus a toolbar toggle.
Run the pass first and then read them: once the file is at a single width, the guides trace every do … end and every nested class straight down the page, and a block that closes in the wrong place shows up as a line that does not land where you expected. Nothing about them is written into the file — turn the toggle off and they are gone, and what you save is unchanged either way.
To look at the whitespace itself, turn on Show Invisibles. Spaces, tabs and line endings become visible markers, which is the quickest way to find the one stray tab in a file that otherwise looks fine. Those markers are drawn too, never inserted.
Resetting Ruby to your global defaults
Three settings are kept per language: brace style, indent width, and tabs-or-spaces. Everything else in the sheet — including Ruby's block style and hash-rocket alignment — is a single global choice. The "Reset to global" link appears once Ruby has overrides, and it is precise about what it touches: those three go back to the global values and everything else stays as you set it. Your block-style choice survives it, so putting the width back to the house default never disturbs the way your blocks are written. When you do want block style back on automatic, the picker is where you set it, and it takes one click.
What one pass changes in a Ruby file
- Depth, all the way down. Every line lands at the depth its block implies, through nested modules, classes, methods and the blocks inside them, whatever the file arrived at.
- The whitespace unit. Two spaces throughout, in place of the three-space blocks and the stray tab someone left behind.
- Block delimiters. One setting takes the whole document to
do … endor to braces, so a file written by four people reads as though it were written by one. - Hash rockets. Aligned into a column or left exactly where they fall — your call, applied consistently across the file.
- Statements sharing a line. Compressed one-liners are unpacked into real lines at their proper depths.
- Only when you ask. Every re-indent is something you started, from a button that opens a sheet rather than acting. Your layout is your business until you press Apply.
What it changes is the shape of the file, and it leaves the meaning of your code alone: methods stay in the order you wrote them, names stay as they are, and nothing is rewritten to satisfy a style guide you did not choose. That boundary is the reason it is safe to run on a file you inherited and have not read yet.
Troubleshooting
I pressed Indent and nothing happened
The Indent button opens the sheet; it does not act. Nothing changes until you press Apply. Escape and Cancel both close it and leave your settings exactly as they were, so open it again, set the width and the Ruby controls you want, and press Apply to put them through the file.
Pressing Return still gives me four spaces
The width you set against Ruby is the width the re-indent pass writes, and live typing follows the global width. Two ways to line them up, both quick. If two spaces suit most of what you write anyway, set the global width to 2 as well and everything agrees from the first keystroke. If you want four spaces elsewhere, leave the global as it is and finish with a pass — type however you like as you go, then Apply once and the whole file comes out at two spaces.
Return after a line ending in a colon adds a level
When you press Return, the new line keeps the indentation of the line above and adds a level after a trailing {, [, ( or :. In Ruby a hash key left at the end of a line will pull the next line in with it. You have two good options. Leave it on and let the re-indent pass settle the depth at the end, or turn that single behaviour off in Settings ▸ Editing, where the five smart-editing switches live, all on by default. The switches are individual, so the other four keep working for you.
My blocks did not change form
Block style is Automatic unless you changed it, and Automatic forces neither form. Reopen the sheet, select Ruby, choose Always do/end or Always braces, and Apply again.
I want the file back the way it was
This is what the save in step one buys you. With a saved copy on disk, File ▸ Reload from Disk (⌘R) throws away the reformatted text and gives you back exactly what you had, character for character. Reloading only ever reads the file; it never writes to it, so you can go back and forth as often as you like while you make up your mind. Save, run the pass, read it, keep it or reload — that loop costs two keystrokes and takes all the risk out of trying a setting you are unsure about.
Re-indenting a very large Ruby file
Our large-file engine is what lets you open a Ruby file of that size and move around in it comfortably, and a whole-file re-indent is the biggest thing you will ask of it. On an ordinary source file the pass is instant; a document of several megabytes is a bigger piece of work, so give it a moment to put every line at the depth Ruby implies. What comes back is the whole file, agreeing with itself from the first line to the last. Save first, press Apply, and let it finish; the text redraws when it is done, and the saved copy on disk is there to read the result against.
Cleanup reported mixed tab and space indentation
Mixed tab/space indent is one of the things our cleanup rules will tell you about. It is reported for information and never rewritten for you. The re-indent pass is what resolves it: set Ruby to 2 spaces, leave the tabs switch off, and Apply.
An unbalanced end mis-indented everything below it
A file with a block left open re-indents to the structure it actually has, which makes the gap visible: everything after the missing end sits a level deeper than you meant it to. Read it as a pointer. The first line that looks wrong is usually just below the end that never got typed, and on a long method that is far quicker than counting keywords by eye. Reload from disk, add the end, then run the pass again and watch the depths fall into place.
Frequently asked questions
How do I make two-space indentation stick for Ruby?
Set it once and it stays. Open the Indentation sheet, select Ruby in the language picker, set the width to 2 and press Apply. That width is kept against Ruby from then on, so the sheet is already set to two spaces the next time you open it in a Ruby file, and every pass you run from it writes them.
Can I change the Ruby width without changing it for other languages?
Yes. Indent width, brace style and tabs-or-spaces are the three settings kept per language, so a change made with Ruby selected applies only to Ruby.
Will re-indenting convert all my braces to do/end?
Only if you ask it to. Block style defaults to Automatic, which forces neither form. Always do/end and Always braces are the settings that normalise a file.
How do I run a re-indent?
From the toolbar. The Indent button — the curly-braces glyph — is one click from wherever you are in the document, and it opens a sheet rather than acting immediately. You get a look at the width, the unit and the Ruby controls, with a preview card to check them against, and Apply is the moment they go through your file.
Do I get completion and call tips in a Ruby file?
Yes. Ruby is one of the code languages with call tips: ⌃Space runs auto-complete and ⌃⇧Space shows a call tip. The popup does not take the keyboard away from you — carry on typing and the list narrows as you go — and Tab or Return accepts the highlighted entry.