colorspace::swatchplot(colorspace::qualitative_hcl(n = 7, palette = "set2"))
My favorite color theme in RStudio is Tomorrow Night Bright. It’s an excellent, dark, high-contrast (‘bright’) theme that I’ve used consistently since I first started using RStudio. Originally written by Chris Kempson as one of the variants included in the MIT-licensed Tomorrow theme series, it has been ported widely to many editors, and is included as a default color theme in RStudio.
In this post, we will cover various color themes in Positron, specifically how they are implemented in the editor (i.e., syntax highlighting) and in other parts of the IDE (i.e., the workbench or chrome around the editor). To do that, we need a great example script that shows off various R features. There’s plenty of good scripts out there, but this is a great opportunity to tell you, dear readers, about my new book and R package.
For the screenshots below, I’ll be using a script from my new book (co-written with Stephanie A. Zimmer and Rebecca J. Powell), which comes with an accompanying R package, srvyexploR. This package provides datasets and scripts to help readers follow along with examples and exercises. The R script, anes_2020.R
, displays a wide breadth of symbols and colors. The screenshots below from RStudio and Positron should give you a flavor of the iterative changes we made in the Positron theme as we ported it from RStudio.
To start, here is what lines 347-366 of anes_2020.R
look like in RStudio with the Tomorrow Night Bright theme:
Looks great, right?! That’s what I’ve been used to for many years now. Please note that I have rainbow parentheses enabled in RStudio. Rainbow parentheses follow their own color palette, independent from the theme itself.
After exploring RStudio’s source code, we were very excited to learn that the color palette for rainbow parentheses was developed in R!
colorspace::swatchplot(colorspace::qualitative_hcl(n = 7, palette = "set2"))
I, like many others, am very excited about the early release of Positron and love seeing the community get their hands on it. As a Posit employee, I’ve had the chance to use it for many months. One of its biggest strengths is the Open VSX Registry extension mechanism. It unlocks infinite customizability, just like in VS Code.
Being so attached to the Tomorrow Night Bright theme in RStudio, I quickly noticed that Positron includes Tomorrow Night Blue by default, but not my favorite theme. I tried out Microsoft’s own Tomorrow Night Bright extension, but the colors felt off. It had an excessive amount of syntax highlighting and an especially distracting use of red. Here’s what the same lines of anes_2020.R
look like using the Microsoft port of Tomorrow Night Bright in Positron:
The Microsoft port of Tomorrow Night Bright had dated grey/blue workbench elements, reflecting its original design (released 2015, last updated 2017), rather than the style of more modern dark themes. Looking for other ‘bright’ themes, I found GitHub Dark Default, a sleek dark-and-bright theme with 16.3M installs in the VS Code Extension Marketplace and 156K in the Open VSX Registry as of this writing. It is featured in Garrick Aden-Buie‘s popular Positron Extension Pack, Positron +1e. While very popular, GitHub Dark Default also suffers from excessive (’saturated’) syntax highlighting of R code in Positron:
With help from my brother, I decided to write my own extension to better approximate what I’m used to in RStudio, and I’m pleased to announce that the resulting extension ‘Tomorrow Night Bright (R Classic)’ is now available on both the Open VSX Registry for Positron and the VS Code Extension Marketplace for VS Code!
Here is the final look:
Let’s walk through porting this theme over to Positron.
This tutorial assumes you already have RStudio and Positron installed. If not, do that first!1
You’ll need a few different programs to create your first extension.
Install Git:
# Install Homebrew (if you don't already have it on macOS) /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Install Git after Homebrew is installed brew install –cask git
Install Node.js:
# Download and install nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash # Download and install Node.js: nvm install 22
Then, restart your terminal:
# Verify the Node.js version: node -v # Should print "v22.13.1". nvm current # Should print "v22.13.1". # Verify npm version: npm -v # Should print "10.9.2".
I played around with installing Node.js and, while possible to do with Homebrew with brew install node@20
, this is quite time-consuming since Homebrew will install and then compile all of its dependencies from source. I was using an older laptop and nvm
(as detailed in the steps above) worked great to install the Node.js binary.
Finally, install Yeoman:
npm install --global yo generator-code
Now that everything is installed, let’s begin actually creating an extension. Point your terminal to your preferred folder:
cd ~/rrr
Then, start Yeoman:
yo code
You will see a welcome to the VS Code extension generator.
Here’s what I inputted into the Yeoman prompt, advancing through each field by pressing Enter:
Yeoman Prompt | Response |
---|---|
What type of extension do you want to create? | New Color Theme |
Do you want to import or convert an existing TextMate color theme? | Yes, import an existing theme and inline it in the Visual Studio Code color theme file. |
URL or filename to import: | https://raw.githubusercontent.com/chriskempson/tomorrow-theme/refs/heads/master/textmate/Tomorrow-Night-Bright.tmTheme |
What’s the name of your extension? | tomorrow-night-bright-r-classic |
What’s the identifier of your extension? | tomorrow-night-bright-r-classic |
What’s the description of your extension? | A Tomorrow Night Bright theme for Positron IDE and VS Code, inspired by RStudio IDE |
What’s the name of your theme shown to the user? | Tomorrow Night Bright (R Classic) |
Select a base theme: | Dark |
Initialize a git repository? | Yes |
Yeoman created the following files in the extension’s directory:2
fs::dir_tree("~/rrr/tomorrow-night-bright-r-classic", all = TRUE) #> ~/rrr/tomorrow-night-bright-r-classic #> ├── .gitattributes #> ├── .gitignore #> ├── .vscode #> │ ├── launch.json #> ├── .vscodeignore #> ├── CHANGELOG.md #> ├── README.md #> ├── package.json #> ├── themes #> │ └── tomorrow-night-bright-r-classic.json #> ├── vsc-extension-quickstart.md
The resulting folder contains all of the files necessary for the color theme extension.
package.json
– this is the manifest file that defines the location of the theme file and specifies the base theme.themes/tomorrow-night-bright-r-classic.json
– the color theme definition file.vsc-extension-quickstart.md
– this serves mainly as reference and you can feel free to delete it after reading it.If you open the folder in Positron and press F5, it will open a new Positron window with the header [Extension Development Host]
which has your extension loaded. From there, open the Command Palette with Shift+Cmd+P and navigate to Preferences: Color Theme
where you can select Tomorrow Night Bright (R Classic)
.
Right now, it looks identical to the Microsoft port of Tomorrow Night Bright and is far from a perfect match for RStudio’s implementation. Let’s customize!
First, gather all of the color themes that you’ll use for inspiration. In our case, the file tomorrow-night-bright-r-classic.json
in our local extension created by Yeoman currently mirrors the Microsoft port of Tomorrow Night Bright. The next steps for us are:
~/.positron/extensions/github.github-vscode-theme-6.3.5-universal/themes/dark-default.json
or similar depending on the version of your copy.tomorrow-night-bright-r-classic.json
and review how it impacts your theme in the [Extension Development Host]
window.This is the part of extension development that took the most time. It would be difficult to walk you through all of the individual design decisions we made while porting the theme. Briefly, since GitHub Dark Default is a great dark extension, it helped a lot to start with its settings, then to tweak its colors to superimpose editor and workbench colors specific to Tomorrow Night Bright. We kept most of GitHub Dark Default’s workbench colors, except that we changed its workbench green/orange accent colors to blue/orange accent colors — to match the Tomorrow Night Bright theme and aesthetic. In the end, we were able to port the editor colors to behave quite close to how they do in RStudio. We’re quite happy with the result!
Below I’ve reproduced tabsets with editor and workbench colors across the original Tomorrow Night Bright, original GitHub Dark Default, and the new Tomorrow Night Bright (R Classic) for reference. If you’re interested in seeing the R code we used to tame three JSON theme files into the tabsets below, you can find it here.
color | setting | scope |
---|---|---|
#000000◉ | background | NA |
#191919◉ | gutter | NA |
#404040◉ | gutterForeground | NA |
#dedede◉ | foreground | NA |
#3e999f◉ | foreground | meta.diff.range |
#4271ae◉ | background | meta.diff.header.from-file, meta.diff.header.to-file |
#70c0b1◉ | foreground | constant.other.color, keyword.operator |
#718c00◉ | foreground | markup.inserted.diff, meta.diff.header.to-file |
#7aa6da◉ | foreground | entity.name.function, keyword.other.special-method, markup.changed.git_gutter, meta.block-level, meta.function-call, support.function |
#82a3bf◉ | background | meta.separator |
#969896◉ | foreground | comment |
#b798bf◉ | background | invalid.deprecated |
#b9ca4a◉ | foreground | constant.other.symbol, entity.name.filename, entity.other.inherited-class, markup.heading, markup.inserted.git_gutter, string |
#c397d8◉ | foreground | entity.name.tag.css, keyword, storage, storage.type |
#ced2cf◉ | foreground | invalid, invalid.deprecated, meta.separator |
#d54e53◉ | foreground | declaration.tag, entity.name.tag, entity.other.attribute-name, markup.deleted.git_gutter, meta.tag, string.other.link, string.regexp, support.other.variable, variable |
#df5f5f◉ | background | invalid |
#e78c45◉ | foreground | constant.character, constant.language, constant.numeric, keyword.other.unit, punctuation.section.embedded, support.constant, variable.parameter |
#e7c547◉ | foreground | entity.name.class, entity.name.type.class, support.class, support.type |
#eeeeee◉ | foreground | constant.other, keyword.operator.class, source.php.embedded.line |
#ffffff◉ | foreground | markup.deleted.diff, markup.inserted.diff, meta.diff.header.from-file, meta.diff.header.from-file, meta.diff.header.to-file, meta.diff.header.to-file |
#c82829◉ | foreground | markup.deleted.diff, meta.diff.header.from-file |
color | setting | scope |
---|---|---|
#04260f◉ | background | markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted |
#161b22◉ | foreground | markup.ignored, markup.untracked |
#490202◉ | background | markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted |
#5a1e02◉ | background | markup.changed, punctuation.definition.changed |
#79c0ff◉ | background | markup.ignored, markup.untracked |
#79c0ff◉ | foreground | constant, entity, entity.name.constant, markup.heading, markup.heading entity.name, markup.inline.raw, meta.diff.header, meta.module-reference, meta.output, meta.property-name, meta.separator, string variable, support, support.constant, support.variable, variable.language, variable.other.constant, variable.other.enummember |
#7ee787◉ | foreground | entity.name.tag, markup.inserted, markup.quote, meta.diff.header.to-file, punctuation.definition.inserted, string.regexp constant.character.escape, support.class.component, support.type.property-name.json |
#8b949e◉ | foreground | brackethighlighter.angle, brackethighlighter.curly, brackethighlighter.quote, brackethighlighter.round, brackethighlighter.square, brackethighlighter.tag, comment, punctuation.definition.comment, string.comment |
#a5d6ff◉ | foreground | constant.other.reference.link, source.regexp, string, string punctuation.section.embedded source, string.other.link, string.regexp, string.regexp constant.character.escape, string.regexp source.ruby.embedded, string.regexp string.regexp.arbitrary-repitition, string.regexp.character-class |
#d2a8ff◉ | foreground | entity.name.function, meta.diff.range |
#e6edf3◉ | foreground | entity.name.constant, markup.bold, markup.italic, meta.block, meta.embedded.expression, meta.jsx.children, meta.object.member, meta.tag.attributes, storage.modifier.import, storage.modifier.package, storage.type.java, variable.other, variable.parameter.function |
#f0f6fc◉ | foreground | carriage-return |
#ff7b72◉ | background | carriage-return |
#ff7b72◉ | foreground | constant.character, constant.other.placeholder, keyword, punctuation.section.embedded, storage, storage.type |
#ffa198◉ | foreground | brackethighlighter.unmatched, invalid.broken, invalid.deprecated, invalid.illegal, invalid.unimplemented, markup.deleted, message.error, meta.diff.header.from-file, punctuation.definition.deleted |
#ffa657◉ | foreground | entity.name, markup.changed, meta.definition.variable, meta.export.default, punctuation.definition.changed, punctuation.definition.list.begin.markdown, variable |
color | setting | scope |
---|---|---|
#000000◉ | background | NA |
#dedede◉ | foreground | NA |
#70c0b1◉ | foreground | constant.other.color, keyword.operator |
#82a3bf◉ | background | meta.separator |
#969896◉ | foreground | comment |
#b798bf◉ | background | invalid.deprecated |
#b9ca4a◉ | foreground | constant.other.symbol, entity.other.inherited-class, markup.heading, string |
#c397d8◉ | foreground | entity.name.tag.css, keyword, storage, storage.type |
#ced2cf◉ | foreground | invalid, invalid.deprecated, meta.separator |
#dedede◉ | foreground | constant.character, declaration.tag, entity.name.function, entity.name.tag, entity.other.attribute-name, keyword.other.special-method, keyword.other.unit, meta.block-level, meta.function-call, meta.tag, punctuation.section.embedded, string.other.link, string.regexp, support.constant, support.function, support.other.variable, variable, variable.parameter |
#df5f5f◉ | background | invalid |
#e78c45◉ | foreground | constant.language, constant.numeric |
#e7c547◉ | foreground | entity.name.class, entity.name.type.class, support.class, support.type |
#eeeeee◉ | foreground | constant.other, keyword.operator.class, source.php.embedded.line |
color | setting |
---|---|
#000000◉ | editor.background |
#2a2a2a◉ | editor.lineHighlightBackground |
#343434◉ | editorWhitespace.foreground |
#424242◉ | editor.selectionBackground |
#9f9f9f◉ | editorCursor.foreground |
#dedede◉ | editor.foreground |
color | setting |
---|---|
#010409◉ | editorGroupHeader.tabsBackground, editorOverviewRuler.border, panel.background, sideBar.background, sideBarSectionHeader.background, tab.inactiveBackground, textBlockQuote.background, titleBar.inactiveBackground |
#033a16◉, #04260f◉, #0f5323◉, #196c2e◉, #238636◉, #2ea043◉, #3fb950◉, #56d364◉, #7ee787◉, #aff5b4◉ | symbolIcon.constantForeground |
#0d1117◉ | activityBar.background, editor.background, input.background, peekViewResult.background, statusBar.background, statusBar.noFolderBackground, tab.activeBackground, tab.activeBorder, tab.hoverBackground, tab.unfocusedActiveBorder, titleBar.activeBackground |
#161b22◉ | breadcrumbPicker.background, checkbox.background, debugToolBar.background, dropdown.background, dropdown.listBackground, editorWidget.background, notificationCenterHeader.background, notifications.background, quickInput.background |
#1f6feb◉ | activityBarBadge.background, badge.background, focusBorder, progressBar.background, statusBarItem.focusBorder |
#1f6feb◉80 | statusBar.focusBorder |
#21262d◉ | textSeparator.foreground, tree.indentGuidesStroke, welcomePage.buttonBackground |
#238636◉ | button.background |
#238636◉26 | diffEditor.insertedLineBackground |
#282e33◉ | button.secondaryBackground |
#2ea043◉ | button.hoverBackground |
#2ea043◉66 | editor.focusedStackFrameHighlightBackground, editorGutter.addedBackground |
#2f81f7◉ | editorCursor.foreground, list.highlightForeground, notificationsInfoIcon.foreground, textLink.activeForeground, textLink.foreground |
#2f81f7◉12 | editor.linkedEditingBackground |
#30363d◉ | activityBar.border, button.secondaryHoverBackground, checkbox.border, dropdown.border, editorGroup.border, editorGroupHeader.tabsBorder, input.border, notifications.border, panel.border, panelInput.border, pickerGroup.border, sideBar.border, sideBarSectionHeader.border, statusBar.border, statusBarItem.remoteBackground, tab.border, tab.unfocusedActiveBorderTop, textBlockQuote.border, titleBar.border, welcomePage.buttonHoverBackground |
#388bfd◉26 | list.focusBackground, list.inactiveFocusBackground |
#39c5cf◉ | terminal.ansiCyan |
#3fb950◉ | gitDecoration.addedResourceForeground, gitDecoration.untrackedResourceForeground, symbolIcon.numberForeground, terminal.ansiGreen |
#3fb950◉40 | editor.selectionHighlightBackground, editorBracketMatch.background |
#3fb950◉4d | diffEditor.insertedTextBackground |
#3fb950◉99 | editorBracketMatch.border |
#484f58◉ | editorWhitespace.foreground, terminal.ansiBlack |
#484f58◉33 | scrollbar.shadow |
#56d364◉ | debugTokenExpression.boolean, debugTokenExpression.number, editorBracketHighlight.foreground2, terminal.ansiBrightGreen |
#56d4dd◉ | terminal.ansiBrightCyan |
#58a6ff◉ | symbolIcon.booleanForeground, symbolIcon.enumeratorMemberForeground, symbolIcon.keyForeground, symbolIcon.nullForeground, symbolIcon.referenceForeground, symbolIcon.snippetForeground, symbolIcon.unitForeground, terminal.ansiBlue |
#6e7681◉ | editorLineNumber.foreground, gitDecoration.ignoredResourceForeground, input.placeholderForeground, symbolIcon.eventForeground, terminal.ansiBrightBlack |
#6e7681◉1a | editor.foldBackground, editor.lineHighlightBackground, list.hoverBackground, peekViewEditor.background, tab.unfocusedHoverBackground |
#6e7681◉4d | editor.wordHighlightStrongBackground |
#6e7681◉66 | list.activeSelectionBackground, list.inactiveSelectionBackground, statusBarItem.prominentBackground, textCodeBlock.background, textPreformat.background |
#6e7681◉80 | editor.wordHighlightBackground |
#6e7681◉99 | editor.wordHighlightBorder, editor.wordHighlightStrongBorder |
#79c0ff◉ | debugTokenExpression.name, editorBracketHighlight.foreground1, symbolIcon.colorForeground, symbolIcon.operatorForeground, symbolIcon.stringForeground, symbolIcon.textForeground, symbolIcon.typeParameterForeground, terminal.ansiBrightBlue |
#7d8590◉ | activityBar.inactiveForeground, breadcrumb.activeSelectionForeground, breadcrumb.foreground, descriptionForeground, editorBracketHighlight.unexpectedBracket.foreground, editorInlayHint.foreground, editorInlayHint.paramForeground, editorInlayHint.typeForeground, gitDecoration.submoduleResourceForeground, icon.foreground, notificationCenterHeader.foreground, panelTitle.inactiveForeground, pickerGroup.foreground, statusBar.foreground, tab.inactiveForeground, textPreformat.foreground, titleBar.activeForeground, titleBar.inactiveForeground |
#8b949e◉ | debugConsole.infoForeground |
#8b949e◉33 | editorInlayHint.background, editorInlayHint.paramBackground, editorInlayHint.typeBackground, minimapSlider.background, scrollbarSlider.background |
#8b949e◉3d | minimapSlider.hoverBackground, scrollbarSlider.hoverBackground |
#8b949e◉47 | minimapSlider.activeBackground, scrollbarSlider.activeBackground |
#9e6a03◉ | editor.findMatchBackground |
#a5d6ff◉ | debugTokenExpression.string, debugTokenExpression.value |
#b1bac4◉ | terminal.ansiWhite |
#bb8009◉66 | editor.stackFrameHighlightBackground, editorGutter.modifiedBackground, peekViewEditor.matchHighlightBackground, peekViewResult.matchHighlightBackground, settings.modifiedItemIndicator |
#bc8cff◉ | debugConsoleInputIcon.foreground, symbolIcon.functionForeground, symbolIcon.methodForeground, terminal.ansiMagenta |
#c9d1d9◉ | button.secondaryForeground |
#d29922◉ | debugConsole.warningForeground, gitDecoration.modifiedResourceForeground, notificationsWarningIcon.foreground, symbolIcon.fileForeground, symbolIcon.folderForeground, terminal.ansiYellow |
#d2a8ff◉ | editorBracketHighlight.foreground6, symbolIcon.constructorForeground, terminal.ansiBrightMagenta |
#da3633◉ | statusBar.debuggingBackground |
#da3633◉26 | diffEditor.removedLineBackground |
#db6d28◉ | gitDecoration.conflictingResourceForeground |
#e3b341◉ | debugConsole.sourceForeground, editorBracketHighlight.foreground3, terminal.ansiBrightYellow |
#e6edf3◉ | activityBar.foreground, breadcrumb.focusForeground, dropdown.foreground, editor.foreground, editorLineNumber.activeForeground, foreground, input.foreground, keybindingLabel.foreground, list.activeSelectionForeground, list.focusForeground, list.hoverForeground, list.inactiveSelectionForeground, notifications.foreground, panelTitle.activeForeground, quickInput.foreground, settings.headerForeground, sideBar.foreground, sideBarSectionHeader.foreground, sideBarTitle.foreground, statusBarItem.remoteForeground, tab.activeForeground, terminal.foreground |
#e6edf3◉14 | statusBarItem.hoverBackground |
#e6edf3◉1f | editorIndentGuide.background, statusBarItem.activeBackground |
#e6edf3◉3d | editorIndentGuide.activeBackground |
#f0883e◉ | symbolIcon.arrayForeground, symbolIcon.classForeground, symbolIcon.enumeratorForeground, symbolIcon.fieldForeground, symbolIcon.interfaceForeground, symbolIcon.objectForeground, symbolIcon.packageForeground, symbolIcon.propertyForeground, symbolIcon.structForeground, symbolIcon.variableForeground |
#f2cc60◉80 | editor.findMatchHighlightBackground |
#f78166◉ | activityBar.activeBorder, panelTitle.activeBorder, tab.activeBorderTop |
#f85149◉ | debugIcon.breakpointForeground, errorForeground, gitDecoration.deletedResourceForeground, notificationsErrorIcon.foreground |
#f85149◉66 | editorGutter.deletedBackground |
#ff7b72◉ | symbolIcon.keywordForeground, symbolIcon.moduleForeground, symbolIcon.namespaceForeground, terminal.ansiRed |
#ff7b72◉4d | diffEditor.removedTextBackground |
#ff9bce◉ | editorBracketHighlight.foreground5 |
#ffa198◉ | debugConsole.errorForeground, debugTokenExpression.error, editorBracketHighlight.foreground4, terminal.ansiBrightRed |
#ffffff◉ | activityBarBadge.foreground, badge.foreground, button.foreground, statusBar.debuggingForeground, terminal.ansiBrightWhite |
color | setting |
---|---|
#000000◉ | editor.background, editor.lineHighlightBorder |
#00bdce◉ | editorBracketHighlight.foreground5 |
#010409◉ | editorGroupHeader.tabsBackground, editorOverviewRuler.border, panel.background, sideBar.background, sideBarSectionHeader.background, tab.inactiveBackground, textBlockQuote.background, titleBar.inactiveBackground |
#033a16◉, #04260f◉, #0f5323◉, #196c2e◉, #238636◉, #2ea043◉, #3fb950◉, #56d364◉, #7ee787◉, #aff5b4◉ | symbolIcon.constantForeground |
#0d1117◉ | activityBar.background, input.background, peekViewResult.background, statusBar.background, statusBar.noFolderBackground, tab.activeBackground, tab.activeBorder, tab.hoverBackground, tab.unfocusedActiveBorder, titleBar.activeBackground |
#161b22◉ | breadcrumbPicker.background, checkbox.background, debugToolBar.background, dropdown.background, dropdown.listBackground, editorWidget.background, notificationCenterHeader.background, notifications.background, quickInput.background |
#1f6feb◉80 | statusBar.focusBorder |
#21262d◉ | textSeparator.foreground, tree.indentGuidesStroke, welcomePage.buttonBackground |
#238636◉26 | diffEditor.insertedLineBackground |
#282e33◉ | button.secondaryBackground |
#2ea043◉66 | editor.focusedStackFrameHighlightBackground |
#2f81f7◉ | list.highlightForeground, notificationsInfoIcon.foreground |
#2f81f7◉12 | editor.linkedEditingBackground |
#30363d◉ | activityBar.border, button.secondaryHoverBackground, checkbox.border, dropdown.border, editorGroup.border, editorGroupHeader.tabsBorder, input.border, notifications.border, panel.border, panelInput.border, pickerGroup.border, sideBar.border, sideBarSectionHeader.border, statusBar.border, statusBarItem.remoteBackground, tab.border, tab.unfocusedActiveBorderTop, textBlockQuote.border, titleBar.border, welcomePage.buttonHoverBackground |
#32609b◉ | button.hoverBackground |
#33c192◉ | editorBracketHighlight.foreground4 |
#343434◉ | editorWhitespace.foreground |
#388bfd◉26 | list.focusBackground, list.inactiveFocusBackground |
#39c5cf◉ | terminal.ansiCyan |
#3fb950◉ | symbolIcon.numberForeground, terminal.ansiGreen |
#3fb950◉4d | diffEditor.insertedTextBackground |
#424242◉ | editor.selectionBackground, editorBracketMatch.background, editorBracketMatch.border |
#4271ae◉ | activityBarBadge.background, badge.background, button.background, focusBorder, progressBar.background, statusBarItem.focusBorder |
#484f58◉ | terminal.ansiBlack |
#484f58◉33 | scrollbar.shadow |
#5089d3◉ | textLink.activeForeground, textLink.foreground |
#56d364◉ | debugTokenExpression.boolean, debugTokenExpression.number, terminal.ansiBrightGreen |
#56d4dd◉ | terminal.ansiBrightCyan |
#58a6ff◉ | symbolIcon.booleanForeground, symbolIcon.enumeratorMemberForeground, symbolIcon.keyForeground, symbolIcon.nullForeground, symbolIcon.referenceForeground, symbolIcon.snippetForeground, symbolIcon.unitForeground, terminal.ansiBlue |
#6e7681◉ | editorLineNumber.foreground, input.placeholderForeground, symbolIcon.eventForeground, terminal.ansiBrightBlack |
#6e7681◉1a | editor.foldBackground, list.hoverBackground, peekViewEditor.background, tab.unfocusedHoverBackground |
#6e7681◉4d | editor.wordHighlightStrongBackground |
#6e7681◉66 | list.activeSelectionBackground, list.inactiveSelectionBackground, statusBarItem.prominentBackground, textCodeBlock.background, textPreformat.background |
#6e7681◉80 | editor.wordHighlightBackground |
#6e7681◉99 | editor.wordHighlightBorder, editor.wordHighlightStrongBorder |
#70c0b1◉ | editorGutter.modifiedBackground, editorMarkerNavigationWarning.background, editorWarning.foreground, gitDecoration.addedResourceForeground, gitDecoration.modifiedResourceForeground, gitDecoration.untrackedResourceForeground, list.warningForeground, problemsWarningIcon.foreground, scmGraph.historyItemGroupLocal |
#79c0ff◉ | debugTokenExpression.name, symbolIcon.colorForeground, symbolIcon.operatorForeground, symbolIcon.stringForeground, symbolIcon.textForeground, symbolIcon.typeParameterForeground, terminal.ansiBrightBlue |
#7d8590◉ | activityBar.inactiveForeground, breadcrumb.activeSelectionForeground, breadcrumb.foreground, descriptionForeground, editorBracketHighlight.unexpectedBracket.foreground, editorInlayHint.foreground, editorInlayHint.paramForeground, editorInlayHint.typeForeground, icon.foreground, notificationCenterHeader.foreground, panelTitle.inactiveForeground, pickerGroup.foreground, statusBar.foreground, tab.inactiveForeground, textPreformat.foreground, titleBar.activeForeground, titleBar.inactiveForeground |
#82a3bf◉ | scmGraph.foreground1 |
#8b949e◉ | debugConsole.infoForeground |
#8b949e◉33 | editorInlayHint.background, editorInlayHint.paramBackground, editorInlayHint.typeBackground, minimapSlider.background, scrollbarSlider.background |
#8b949e◉3d | minimapSlider.hoverBackground, scrollbarSlider.hoverBackground |
#8b949e◉47 | minimapSlider.activeBackground, scrollbarSlider.activeBackground |
#94a9ec◉ | editorBracketHighlight.foreground6 |
#99b657◉ | editorBracketHighlight.foreground3 |
#9f9f9f◉ | editorCursor.foreground |
#9e6a03◉ | editor.findMatchBackground |
#a5d6ff◉ | debugTokenExpression.string, debugTokenExpression.value |
#b1bac4◉ | terminal.ansiWhite |
#b9ca4a◉ | editorGutter.addedBackground, scmGraph.foreground5 |
#bb8009◉66 | editor.stackFrameHighlightBackground, peekViewEditor.matchHighlightBackground, peekViewResult.matchHighlightBackground, settings.modifiedItemIndicator |
#bc8cff◉ | debugConsoleInputIcon.foreground, symbolIcon.functionForeground, symbolIcon.methodForeground, terminal.ansiMagenta |
#c397d8◉ | scmGraph.foreground2 |
#c9d1d9◉ | button.secondaryForeground |
#d29922◉ | debugConsole.warningForeground, notificationsWarningIcon.foreground, symbolIcon.folderForeground, terminal.ansiYellow |
#d2a8ff◉ | symbolIcon.constructorForeground, terminal.ansiBrightMagenta |
#d3a263◉ | editorBracketHighlight.foreground2 |
#da3633◉ | statusBar.debuggingBackground |
#da3633◉26 | diffEditor.removedLineBackground |
#dc91db◉ | editorBracketHighlight.foreground7 |
#dedede◉ | editor.foreground |
#df5f5f◉ | editorError.foreground, gitDecoration.conflictingResourceForeground, gitDecoration.deletedResourceForeground, list.errorForeground, problemsErrorIcon.foreground |
#e3b341◉ | debugConsole.sourceForeground, terminal.ansiBrightYellow |
#e6edf3◉ | activityBar.foreground, breadcrumb.focusForeground, dropdown.foreground, editorLineNumber.activeForeground, foreground, input.foreground, keybindingLabel.foreground, list.activeSelectionForeground, list.focusForeground, list.hoverForeground, list.inactiveSelectionForeground, notifications.foreground, panelTitle.activeForeground, quickInput.foreground, settings.headerForeground, sideBar.foreground, sideBarSectionHeader.foreground, sideBarTitle.foreground, statusBarItem.remoteForeground, tab.activeForeground, terminal.foreground |
#e6edf3◉14 | statusBarItem.hoverBackground |
#e6edf3◉1f | editorIndentGuide.background, statusBarItem.activeBackground |
#e6edf3◉3d | editorIndentGuide.activeBackground |
#e78c45◉ | activityBar.activeBorder, editorGutter.deletedBackground, panelTitle.activeBorder, scmGraph.foreground3, tab.activeBorderTop |
#e7c547◉ | scmGraph.foreground4 |
#ed90a4◉ | editorBracketHighlight.foreground1 |
#f0883e◉ | symbolIcon.arrayForeground, symbolIcon.classForeground, symbolIcon.enumeratorForeground, symbolIcon.fieldForeground, symbolIcon.interfaceForeground, symbolIcon.objectForeground, symbolIcon.packageForeground, symbolIcon.propertyForeground, symbolIcon.structForeground, symbolIcon.variableForeground |
#f2cc60◉80 | editor.findMatchHighlightBackground |
#f85149◉ | debugIcon.breakpointForeground, errorForeground, notificationsErrorIcon.foreground |
#ff7b72◉ | symbolIcon.keywordForeground, symbolIcon.moduleForeground, symbolIcon.namespaceForeground, terminal.ansiRed |
#ff7b72◉4d | diffEditor.removedTextBackground |
#ffa198◉ | debugConsole.errorForeground, debugTokenExpression.error, terminal.ansiBrightRed |
#ffffff◉ | activityBarBadge.foreground, badge.foreground, button.foreground, statusBar.debuggingForeground, terminal.ansiBrightWhite |
Once the tomorrow-night-bright-r-classic.json
file was ready, then it was time to publish the theme to the VS Code Extension Marketplace and then the Open VSX Registry. We added some resources on how to do this below.
Like any other open-source project, this is just the beginning! We’ve optimized the theme for R scripts and many key workbench elements, but there’s more to do. Our next steps will be to optimize the theme for Python scripts, JSON files, and other files supported by RStudio — so those migrating from RStudio to Positron will feel at home in Tomorrow Night Bright. We welcome you to submit a pull request in the GitHub repository or use the files as a reference if you want to create your own Positron theme!
To install the theme in Positron, navigate to the Extensions marketplace by:
Extensions: Install Extensions
,Search for ‘Tomorrow Night Bright (R Classic)’ and then click Install. Tada you now have our theme installed. We hope you enjoy it!
The process of building and publishing an extension can be quite involved! We found these links to be particularly helpful:
package.json
file in the root folder of all extensions, also known as the ‘extension manifest’ or ‘manifest.’ Our extension’s package.json
may be helpful for reference. N.B., the Yeoman utility generates only a bare-bones package.json
, but to publish your extension online you’ll need to add a publisher field and more. You will also need to add a package-lock.json
file!publish-extension.yaml
.Thanks to Mickaël Canouil’s Quarto extension, Preview Color, which allowed us to display colors associated with hex codes in this blog post.
brew install –cask r
, brew install –cask rstudio
, brew install –cask positron
will get you up and running quickly with Homebrew on macOS. Check out our recommended MacOS configuration.︎
Shoutout to {fs} for being an outstanding R package and fs::dir_tree()
in particular!︎