Repository navigation
Conversation
PR JuliaEditorSupport#285 tried to support multi-line REPL input with a single `match` rule containing `\n`: ^(julia>)(\s+.*(?:\n\s{6}\s+.*)*) That can never fire. TextMate grammars are tokenized one line at a time -- vscode-textmate (what VS Code and GitHub use) calls `tokenizeLine()` per line, and the input string never contains a newline. Only begin/end rules carry state across lines. The regex has therefore been dead code since it was merged, and multi-line input on GitHub is still unhighlighted. Replace it with a begin/end rule that stays open while lines are indented to the REPL's 7-column continuation alignment. As a bonus this also fixes `begin`/`end` keyword pairing on the prompt line, which needed cross-line state too. The reason CI went green is that `tokenize()` passed the whole multi-line source to `grammar.tokenizeLine()` as a single line, which hands oniguruma a string that really does contain newlines. It is the only consumer in the world that does this. Tokenize line by line instead, threading the rule stack, so a `match` rule spanning lines can no longer pass a test. That change surfaced 14 expectations asserting token values that contain `\n` -- impossible under real tokenization -- which are split into per-line tokens here. One of them, in the PyCall test, also needed `meta.embedded.inline.python` added: line-based tokenization does apply the `contentName` to the string body, matching the neighbouring cxx and js tests. Also add a test over a realistic transcript asserting that continuation lines get Julia scopes while REPL *output* does not. Known limitation, unchanged from JuliaEditorSupport#285's assumptions: output indented by 7 or more columns (stacktraces, some `show` methods) is scoped as code. Requiring `\s{7}\S` does not help, since nested code is indented further.
`punctuation.separator.prompt.julia.console` has no rule in
primer/github-vscode-theme, so on GitHub the prompt falls through to
the default foreground and is indistinguishable from surrounding
output. Resolving the theme through vscode-textmate:
punctuation.separator.prompt.julia.console -> #1F2328 (default)
entity.name.tag.prompt.julia.console -> #116329 (green)
`entity.name.tag` is one of the few scopes that theme paints green
(alongside `support.class.component`, `markup.inserted`,
`punctuation.definition.inserted` and `markup.quote`). Keeping the
`.prompt.julia.console` tail means theme prefix matching still finds
the `entity.name.tag` rule -- and its three components outrank the
`entity.name` -> orange rule -- while a Julia-specific theme can still
target the full scope. On github.com this lands in the `.pl-ent`
class.
This is an admitted abuse of the scope name: `entity.name.tag` means
"XML/HTML tag name", and because this grammar also ships in the VS
Code Julia extension the prompt changes color in every editor and
every theme, not just GitHub. Please take or leave this commit
independently of the first one.
The cleaner fix lives upstream of this grammar: Primer's theme styles
no `punctuation.separator.prompt` scope at all, which is also why
ShellSession `$` prompts render plain on GitHub. Adding that scope
there would fix every console grammar at once without distorting
anyone's semantics. Happy to drop this commit and pursue that instead.
`shell>` and `help?>` keep their `punctuation.separator` scopes here,
since this only concerns the julia> prompt.
pfitzseb
approved these changes
Sep 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #285, which does not actually work.
The multi-line regex is dead code
#285 changed the
julia>pattern to a singlematchrule containing a newline:TextMate grammars are tokenized one line at a time. vscode-textmate — what VS Code and GitHub both use — calls
tokenizeLine()per line, and the string it passes never contains a newline, so(?:\n\s{6}\s+.*)*can only ever match zero times. Onlybegin/endrules carry state across lines.Tokenizing the current grammar line by line, the way a real consumer does:
So multi-line REPL input has been unhighlighted on GitHub this whole time, even though the change shipped in Linguist v9.2.0.
Why CI went green
tokenize()intest/test.jspassed the entire multi-line source togrammar.tokenizeLine()as one line, handing oniguruma a string that really does contain newlines. It is the only consumer that does this. The tell-tale sign is in the expected tokens of the multi-line test —{ value: '\ntrue\n\n' }. A token whose value contains a newline is impossible under real tokenization.Commit 1 — the fix
A
begin/endrule that stays open while lines are indented to the REPL's 7-column continuation alignment:{ "begin": "^(julia>)", "beginCaptures": { "1": { "name": "..." } }, "end": "^(?!\\s{7})", "patterns": [{ "include": "source.julia" }] }Verified on a realistic transcript — continuation lines get Julia scopes, output does not:
It also fixes
begin/endkeyword pairing on the prompt line, which needed cross-line state as well.tokenize()now splits on newlines and threads the rule stack, so amatchrule spanning lines can no longer pass a test. That surfaced 14 expectations asserting\n-containing token values, split into per-line tokens here. One, in the PyCall test, also neededmeta.embedded.inline.pythonadded — real line-based tokenization does apply thecontentNameto the string body, consistent with the neighbouring cxx and js tests.The existing
"should highlight multi-line expressions"test is now a genuine regression test: reverting just the grammar makes it fail. I also added a test over the transcript above.Known limitation, unchanged from #285's assumptions: output indented by 7+ columns (stacktraces, some
showmethods) gets scoped as code. Requiring\s{7}\Sdoesn't help, since nested code is indented further. Happy to take suggestions if you'd prefer a different heuristic.Commit 2 — prompt color on GitHub (separable, take it or leave it)
punctuation.separator.prompt.julia.consolehas no rule inprimer/github-vscode-theme, so the prompt renders in the default foreground on GitHub. Renaming the capture toentity.name.tag.prompt.julia.consolemakes it green (#116329light /#7ee787dark, the.pl-entclass).This is an admitted abuse of the scope name —
entity.name.tagmeans "XML/HTML tag name" — and since this grammar also ships in the VS Code extension it changes the prompt color in every editor and theme, not only GitHub. Please evaluate this commit independently of the first; I'll drop it without complaint.The cleaner fix is upstream of this grammar: Primer's theme styles no
punctuation.separator.promptscope at all, which is also why ShellSession$prompts render plain on GitHub. Adding it there would fix every console grammar at once. I'm glad to open that instead if you'd rather not carry commit 2.npm test: 131 passing.