Writing Code

Syntax highlighting not working on Mac

Nothing is broken. Colour follows the language a document is in, and this one has opened in Plain Text — here is how to read the status bar and set the language yourself, in one click.

You open a script, and it arrives as plain text. No keywords, no strings, no comments — just characters. The natural conclusion is that syntax highlighting is switched off somewhere in settings and needs hunting down. The real answer is simpler, and quicker to act on: colour follows the language the document is in, and this document is in Plain Text. Tell Note My which language it is, and the colour arrives at once, along with a good deal else. Our advanced language identifier names the language for you, so most files open coloured on their own; when a file opens as plain text instead, choosing the language yourself takes one click from the status bar. It all happens on your Mac — nothing is uploaded, there is no account, and your file never leaves the machine.

First check: what does the status bar say?

Before changing anything, look at the right-hand end of the status bar. There is a language pill showing the mode the document is in, and next to it an Identify pill. If the language pill reads Plain Text, the document is not in a code language at all, and that on its own explains the missing colour. If it reads a language you did not expect, set the one you want. If it reads the right language and the page still looks grey, the troubleshooting section below takes it from there.

Six counters, live: characters, words, spaces, lines, the size of the selection, and how many times the selected word occurs. They are cached on the document, so a keystroke does not recount two million characters.
Note

Colour is never part of your file. Our syntax engine paints it on screen only, so switching language never marks the document as edited and never changes a byte on disk. You can try one language, then another, at no cost. The Export As commands that carry colour into HTML, RTF or PDF re-create it on purpose.

What the language setting controls

The language a tab is in decides a good deal more than colour, which is why it is the first thing worth setting. Once a document is in a language, you get:

  1. Syntax colouring. Keywords, strings, numbers, types and comments each get their own treatment from our syntax engine, so a stray unclosed quote shows itself.
  2. Code completion. That language's keywords and builtins are offered as you type, and ⌃Space opens the popup whenever you want it.
  3. Call tips. In Swift, Python, JavaScript, TypeScript, Java, C, C++, Ruby, PHP, Rust, Go and Kotlin, the signature of the call you are inside appears with the argument you are on picked out, so what a function expects is in front of you while you type it — and ⌃⇧Space summons one whenever you want it.
  4. The right comment markers. Comment Line uses the marker the language actually uses, so commenting out a block does what you expect.
  5. Document symbols. The jump list fills with the functions and types the file defines.
  6. A matching file extension offered when you save, so the document opens the same way next time.

That is the case for setting the language the moment you notice a tab in Plain Text: one click buys you the whole set, and the choice stays with the tab.

The result is stable, too. The same file opens the same way every time — today, next month, and on any Mac you use.

Six reasons a file opens in Plain Text

1. It is an extensionless script or a dotfile

An extensionless script, a file called run, a dotfile in a project folder — these routinely open as plain text. Set the language from the Identify pill, and if it is a file you return to often, give it an extension when you save.

2. It is a snippet, a fragment or a wrapper script

A wrapper script, a snippet pasted out of a ticket, a config fragment saved on its own — files like these often open as plain text. Nothing is wrong with the file, and nothing needs repairing. Set the language yourself from the Identify pill and carry on. The choice belongs to the tab, so it holds while you work, and saving the file with a matching extension makes it stick for next time.

3. It is a stylesheet saved under a plain name

Stylesheets need their extension. A stylesheet saved as styles or theme.txt opens as Plain Text every time. Two fixes: set CSS from the Identify pill now, or rename the file so it ends in .css and it opens coloured for good. If it is a file you edit most days, the rename is the one worth doing: it brings the CSS completion list and the document symbol jump list along with the colour.

4. The tab is in Plain Text prose mode

Plain Text is not a placeholder waiting to be replaced. It is a real mode, and it drops the colour on purpose so the tab behaves like a notes window: macOS's own spelling and grammar underlines come on, using your own Learn Spelling entries. .env files, Dockerfile, Makefile, extensionless scripts and every new untitled document open this way, which is exactly right for notes and jottings. When the tab holds code, switching into a language is one click, and everything that language carries — colour, completion keywords, call tips, comment markers, document symbols — arrives in the same moment.

Even in prose mode, nothing rewrites your text. Automatic spelling correction, smart quotes and dash substitution stay off in every mode, so a straight quote stays straight and a hyphen stays a hyphen — the substitutions that would otherwise break a script never happen.

5. It is a kind of file that lives in Plain Text

Fifteen languages colour on sight: Swift, Python, JavaScript, TypeScript, Java, C, C++, Ruby, HTML, CSS, PHP, Rust, Go, Kotlin and Shell. Each one brings its own completion keywords, builtins and document symbols with it, and setting any of them from the Identify pill takes a single click, so a tab that opened flat is a second away from being the right kind of editor for the job. Other files open in Plain Text, and they are well served there too:

  • A query file starts from a template. Our template library hands you query.sql to open from, and Comment Line uses the marker SQL expects, so commenting a clause in and out behaves exactly as you would want while you test a statement.
  • Markdown sits comfortably in prose mode. There is a notes.md template to begin from, macOS spelling and grammar underlines come on for the prose, and our cleanup rules understand Markdown's trailing-whitespace convention — so tidying stray spaces out of a document leaves your deliberate line breaks exactly where you put them.

6. The pill reads Custom…

If the language pill reads Custom…, you have found your answer in one look, and the fix is the same click as everywhere else. Pick one of the fifteen languages from the Identify pill, press Confirm, and colouring, completion keywords, call tips and document symbols all arrive together. Save As will then offer the matching extension, so the file opens ready to work in next time.

Set the language yourself

  1. Click the Identify pill in the status bar

    This opens the Language Inspector, a small card sheet. On a file with content it reads "Identified programming language: X". On an empty document it reads "Set programming language" instead. Either way, the same pop-up follows.

  2. Choose the language from the override pop-up

    The pop-up lists all seventeen modes — the fifteen code languages, Plain Text and Custom…. Pick the one you want.

  3. Press Confirm

    Colouring applies immediately, along with that language's completion keywords, builtins, document symbols and comment markers. Your choice sticks to the tab, and nothing will quietly change it back.

  4. Give the file an extension so it opens coloured next time

    Save As (⇧⌘S) pre-fills an extension that matches the document's current language, so a file saved under the suggested name opens in that language next time. Accept the suggested name once and the file arrives coloured from then on — on this Mac, and on any other you open it on.

What happens when you paste code in

Pasting is a moment where Note My sets the language for you. Paste into a brand-new, empty tab and the language pill changes on its own, with no sheet to dismiss and nothing to confirm — the colour, the completion keywords and the right comment markers are simply there by the time you look up. The Identify pill sits alongside it whenever you would rather choose for yourself.

In any other tab, a paste puts an accent dot on the Identify pill — a quiet nudge that there is a language worth setting, left for you to act on when you are ready. A short popover explains it the first time you see it. If you would rather be asked outright on a first paste, there is a setting for it, and it is off by default. Typing and scrolling never change the language of a tab, so a document you have set by hand stays where you put it.

The practical habit: when a snippet lands uncoloured in an existing tab, click the pill rather than opening a new window.

Troubleshooting

The pill shows the right language but there are still no colours

Two things to try, in this order. First, open the Language Inspector again from the Identify pill and press Confirm: the choice lands when you confirm it, so a sheet you closed any other way leaves the tab exactly as it was — deliberate, and the reason you can look at a language before committing to it. Second, if the colour you are actually after is the colour a log gets, that is a separate layer with its own switch, described a few entries below. Size is rarely the culprit: in a very large file our large-file engine keeps typing and scrolling responsive, and syntax colouring stays on right through it, so a long log or a generated data file reads like any other document.

The text is garbled as well as uncoloured

Stray accented characters or a repeated  mean the file was opened as the wrong encoding, and colour follows the characters, so those are worth putting right first. Use File ▸ Encoding ▸ Reload with Encoding… and pick the encoding the file was actually written in. Our encoding handling keeps the two commands distinct: reloading changes nothing on disk, and only File ▸ Encoding ▸ Convert to Encoding… changes what is written back, so you can try one encoding and then another until the text reads cleanly. Once it does, set the language from the Identify pill and the colour lands with it.

I renamed the file, and it is still uncoloured

An open tab holds the file exactly as you opened it, so a rename made in the Finder is yours to bring in when you are ready. Use File ▸ Reload from Disk (⌘R) to pick the file up under its new name. Setting the language from the Identify pill is faster still, and it hands you the colour, the completion keywords and the document symbol list on the spot.

It is a log file, and I want the colours logs get

Log colouring is a layer of its own, and it works whatever language the document is in. Turn on View ▸ Enable Log Highlighting, or click the Log pill in the status bar, and severity keywords, ISO-8601 timestamps, HTTP status codes, IPv4 addresses, UUIDs and URLs each get their own treatment. Like syntax colour, none of it is written into the file.

macOS says the file is not text at all

Open it with ⇧⌘O — File ▸ Open Anything as Text… — then set the language from the Identify pill. Note My does not make itself the default application for those file types, so opening one this way is a one-off and nothing about the Finder changes.

I want it to open coloured every time, without setting it

Give the file an extension that matches its language. Save As (⇧⌘S) pre-fills one for you, so accepting the suggested name is usually the whole job. From then on the file opens in that language on every launch and on every Mac you use, with the completion keywords, call tips and document symbols already in place — nothing to remember and nothing to configure.

What you can count on

  • The language is yours to set, and it holds. Apart from a paste into an empty tab, described above, nothing else moves it. Typing, scrolling, searching and saving all leave your choice exactly where you put it, for as long as the tab is open.
  • Colour is painted on screen, never into the file. Setting a language leaves every byte alone, so you can try one, look at it, and try another without the document ever being marked as edited.
  • Your text is never reformatted. Smart quotes, dash substitution and automatic spelling correction stay off in every mode, so a straight quote stays straight, a hyphen stays a hyphen, and a script you paste in stays runnable.
  • Nothing is sent anywhere to be classified. Your file never leaves your Mac, there is no account, and none of this needs a connection.

Frequently asked questions

My code opened flat. Where do I start?

At the language pill, at the right-hand end of the status bar. Colour follows the language a document is in, so the pill tells you the answer at a glance: a tab reading Plain Text or Custom explains itself. Click Identify next to it, choose the language, press Confirm, and colouring applies immediately.

Why does my .css file colour but the same content pasted into a new tab does not?

Stylesheets need their .css extension. A tab holding the same CSS with no filename behind it stays in Plain Text. Set CSS from the Identify pill, or save the tab with a .css name, and the colour arrives.

Does setting the language change my file?

Setting the language is always safe to try. Colour is shown on screen and is never written into the text, so choosing a language does not mark the document as edited and does not alter a single byte on disk. It does change what Note My offers you: completion keywords, builtins, call tips and comment markers all follow the language.

Will the same file always open in the same language?

Yes. With the same name and the same contents, a file opens the same way on every launch and on every Mac you use. If it opened coloured yesterday, it opens coloured today.

Which languages get the full treatment?

All fifteen are highlighted, and all fifteen bring completion keywords, builtins and document symbols with them. Twelve of them — Swift, Python, JavaScript, TypeScript, Java, C, C++, Ruby, PHP, Rust, Go and Kotlin — carry call tips as well, so a signature appears as you write a call, and Swift, Python, JavaScript and TypeScript go a step further again with automatic import lines.

Code completion stopped working at the same time. Related?

Usually yes — completion keywords and builtins belong to the language, so setting the language from the Identify pill brings both back along with the colour, in the same click. The list keeps pace with you as you type, and ⌃Space opens it on demand, so the language's keywords and builtins are there at the exact moment they are useful.