How to re-indent code on Mac
You can do this with Note My — here is how to reformat a whole document at once, what our indentation engine rewrites for you, and how to make it yours.
Code arrives badly indented for ordinary reasons. It was pasted out of a web page, a chat window or an AI answer and lost its leading whitespace. It was edited in an app that inserted tabs where the rest of the file used spaces. Three statements ended up sharing one line. Whatever the cause, the fix you want is one command that puts the whole document right, the way your language expects.
Note My has that command. It lives in one place, it shows you a sheet before it touches anything, and it remembers how you like each language formatted so the second file is quicker than the first.
What re-indenting actually changes in your file
Re-indenting does more than shift lines sideways. Our indentation engine puts braces, blocks and statements back at the depths your language implies, following your brace style, indent width and tabs-or-spaces preference. A file that arrived flush-left comes back with its shape visible again. It also unpacks statements that share a line, so code crammed onto one row becomes one statement per row.
It works on the shape of your file, never on its meaning. Whitespace moves and crowded lines are given room; the identifiers, strings and logic you wrote come back exactly as you wrote them. That is the deal worth understanding before you run it on something you care about: you get a file that reads properly, with the same code inside it.
Fifteen languages are supported by name: Swift, C, C++, JavaScript, TypeScript, Go, Kotlin, Rust, PHP, CSS, Java, Python, Ruby, Shell and HTML. Anything else is still re-indented rather than refused — expect dependable results on brace-delimited code, and read the result before you save on anything further afield.
Re-indent a document
-
Save the file first
Press ⌘S before anything else. A saved copy on disk is a solid floor under the whole operation: whatever the sheet does to the window, File ▸ Reload from Disk (⌘R) brings the saved version straight back, and reloading never changes the file on disk. Our auto-recovery safety net covers the other case, the one where the app closes unexpectedly with work still in the window.
To see exactly what moved, duplicate the file in the Finder first and read the two copies side by side in our comparison view. It lines the before and after up against each other so every changed line is easy to spot, which is a good way to learn what a given set of sheet settings does to your own code.
-
Click the Indent button in the toolbar
It is the curly-braces glyph, between the Clean menu and the Guides toggle. The toolbar is icon-only, so hover if you are unsure; the accessibility name is Indent.
Nothing changes at this point. The button opens a sheet, and your document is untouched until you apply it, so it is safe to open the sheet, read the settings and cancel.
-
Check the language
The picker at the top has sixteen options: a global default plus the fifteen supported languages. Our advanced language identifier will normally have picked the right one for you already, so most of the time you can leave this alone. It is here for the two occasions that matter: when you disagree with the choice, and when a file arrives without a clear language of its own. Changing it also snaps the brace style, width and unit to whatever you have stored for that language, so expect the controls below to move.
-
Set the brace style, width and unit
There are exactly two brace styles: same line (K&R), which is the default, and next line (Allman). Indent width defaults to 4 and the sheet accepts 1 to 12. The unit defaults to spaces.
Two language locks override that. Go is locked to tabs, on by default, which is what Go tooling expects. Python has a four-space lock that is off by default — turn it on to have PEP 8 enforced rather than assumed.
-
Read the sample as your legend
The card in the middle redraws as you change the controls, braces tinted blue, so a width or brace-style change shows immediately. It lays out the same compact
if <condition> { … }sample every time, which makes it a quick way to compare settings: nudge the width from 2 to 4, flip the braces to the next line, and read off which combination you actually want before you commit to it. -
Press Apply
↩ applies and ⎋ cancels, so once the settings read the way you want them, one key finishes the job. Applying also saves every setting in the sheet, so the next document you open starts from the same choices and you never set them up twice. Get one language exactly how you like it and it stays that way.
One button, always in the same place
Re-indentation has a single entry point: the curly-braces button in the toolbar. That is worth knowing because it makes the command easy to find on a Mac you have not used for a while, and because it puts a sheet between you and the document every single time — the operation is never one stray keypress away from happening. The indentation guides toggle sits directly beside it, so the two things you reach for when a file is hard to read are next to each other. If the toolbar is hidden, bring it back with ⌥⌘T.
Re-indent is a whole-document command, which is the point of it: one pass and the entire file is consistent from top to bottom. Press ⌘S first so the copy on disk is the one you would want back.
The language-specific section
Below the common controls sits a section for the language you picked. This is where the opinionated decisions live, and several of them default to preserve: on those, your existing choice is left alone unless you ask for a change. Left as they are, the re-indent fixes the depths and nothing else.
| Policy | Options | Default |
|---|---|---|
| C pointer style | Preserve · int *p · int* p · both sides · no space | Preserve |
| Swift and Python trailing commas | Preserve · add · remove | Preserve |
| JavaScript trailing commas | None · multi-line only · all | Multi-line only |
| JavaScript semicolons | Preserve · always · never | Preserve |
| Python continuation lines | Hanging · aligned | Hanging |
| Ruby block style | Automatic · always do…end · always braces | Automatic |
| PHP else-if | elseif · else if | elseif |
Shell then placement | Same line · next line | Same line |
Around twenty-eight further switches and column limits exist across the languages, and the section shows the ones belonging to the language you picked — C case-label indent, JavaScript object-literal splitting, Java annotations, Rust where wrapping, Go import-group preservation, and more. The column limits default to 0, meaning off, so long lines are not rewrapped unless you set a column.
Recover damaged comments
This checkbox is off by default and it solves a specific problem. When code is copied out of a rendered page, line breaks are sometimes lost and a comment marker swallows the code that followed it. A line like // Preserve state let x = 1 let y = 2 becomes one comment where it should be a comment and two statements.
Ticked, that line comes back as three: the comment, then the two statements that belong on rows of their own. The repair is deliberately cautious: single-line comments only, anything ambiguous left alone, and documentation markers — ///, //!, /**, /*! — never altered.
Comment recovery covers thirteen languages, so the everyday case — a Swift, C, JavaScript, Go or Python snippet lifted out of a browser or an AI answer — comes back with its comments and its code on separate rows again. It is the switch worth knowing about when code has arrived from somewhere else. Leave it off for a file whose comments are fine, and nothing about them is touched.
Re-indenting a very large file
The sheet never turns a document away for being big. A generated file, a minified bundle, a log-sized export of source — our large-file engine opens documents like that and keeps them scrolling, and the same curly-braces button re-indents them. The moves are the ones you already know: you open the file, you open the sheet, you press Apply.
On an ordinary source file the pass is instant. A very large document is a bigger piece of work, so give it a moment to put every line at the depth your language implies, and let it finish before you carry on. What comes back is the whole file, consistent from top to bottom. Press ⌘S first, as always, so the copy on disk is the one you would want back.
There is a lighter way through a very large file when only one region has to be readable: copy the section you care about into a new document, run the sheet on that, and paste the tidied result back where it belongs. A short document makes for a short pass, and the settings you chose are already waiting in the sheet the next time you open it, so nothing has to be set up twice.
If the file is JSON or XML instead
Structured data has its own commands in the Edit menu: Format JSON, Minify JSON, Validate JSON, Format XML and Minify XML. Format JSON uses a two-space indent and sorts the keys — a real change to the document, not only to its whitespace. Validate JSON reports without mutating, and its errors carry (around line N, column M) so you can jump straight to the character that broke the file. These commands act on the selection if you have one, otherwise the whole document, and if one fails your file is left exactly as it was.
Troubleshooting
I pressed Apply and nothing happened
An empty document gives you nothing to see. Neither does a file already formatted the way the sheet would format it. And with the wrong language selected, the result can land close enough to what you already had that nothing appears to move. Check the language picker first, then the width and unit, and run it again.
I want the formatting I had before
File ▸ Reload from Disk (⌘R) is the route to take. It puts the saved version of the file back in the window, exactly as it sits on disk, which is why the first step above is to press ⌘S. Get into that habit and every re-indent becomes something you can try, look at and step out of in a couple of seconds.
My Go file gets spaces when I type but tabs when I re-indent
That is the Go tabs lock doing its job. It governs the re-indent pass rather than each keystroke, so you can type however you like — including with spaces, as Return continues the file — and one run of the sheet afterwards normalises the entire file to tabs, which is what Go tooling expects to find.
The result is indented wrongly in one place
Read upwards from the line where the depths start to look odd, and you will usually find an unbalanced brace or an unterminated string. The formatted file is following the structure as written, so a stray brace shows up as a visible shift in shape — which makes a re-indent a surprisingly quick way to spot one. Fix it and run the sheet again.
What "Reset to global" resets
It clears three things: brace style, indent width and tabs-or-spaces. Every other per-language policy is remembered separately and survives the reset, so an earlier trailing-comma or semicolon decision stays made and you do not lose fine-grained work by returning the basics to the default. Look over the language-specific section before you apply, and set any of those back individually.
What you can count on
The habits that make a formatter pleasant to live with are the ones you stop noticing:
- Nothing re-indents on save, and nothing re-indents on paste. It is always something you ask for, on the document you asked for it on.
- Your settings persist. Apply once and the brace style, width and unit come back the next time you open the sheet, per language.
- The preserve defaults leave your choices alone. Trailing commas, semicolons and pointer style stay as you wrote them until you decide otherwise.
- Long lines stay as you wrote them unless you set a column limit yourself.
- The sheet is safe to open. Read the settings, change them, cancel — the document is untouched until you press Apply.
- The comparison view shows you the difference whenever you want to see precisely what a pass did to a file.
One thing worth saying plainly: none of this involves a server. Re-indenting happens on your Mac, there is no account to make, nothing is uploaded, and a file you reformat never leaves the machine. That holds for the source you would rather not hand to a web formatter — client code, anything under an agreement, anything you simply do not want in someone else's logs.
Frequently asked questions
What is the keyboard shortcut to re-indent a document?
Click the Indent button in the toolbar — the curly-braces glyph — and the sheet opens. From there ↩ applies and ⎋ cancels, so the run itself is a keystroke. If the toolbar is hidden, ⌥⌘T brings it back.
Does it re-indent the whole document?
Yes — one pass puts every line in the file at the depth your language implies, which is what you usually want from a re-indent. Press ⌘S first and the saved copy is always there to come back to.
Which languages can it re-indent?
Fifteen are supported by name: Swift, C, C++, JavaScript, TypeScript, Go, Kotlin, Rust, PHP, CSS, Java, Python, Ruby, Shell and HTML. Anything else is still re-indented rather than refused, so an unfamiliar extension is no obstacle — expect dependable results on brace-delimited code, and read the result before you save on anything further afield.
Will it change my tabs to spaces?
Yes, if that is what the sheet says. The unit defaults to spaces at width 4. Go is locked to tabs by default; Python has a four-space lock that is off by default. Set the language first, then the unit — changing the language reloads those controls.
Does re-indenting sort or rewrite anything besides whitespace?
It unpacks statements that share a line, and it can add or remove trailing commas and semicolons if you move those policies off their defaults. Format JSON is the one command that reorders content — it sorts keys.