├── .github └── workflows │ └── deploy.yml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .node-version ├── .vscode ├── launch.json └── settings.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── astro.config.js ├── designs ├── code.pxd │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ ├── data │ │ ├── 08D14584-93B6-43FE-ACEA-3C52A7E532BF │ │ └── originalImportedContentDocumentInfo │ └── metadata.info ├── github-social.pxd │ ├── QuickLook │ │ ├── Icon.tiff │ │ └── Thumbnail.tiff │ ├── data │ │ ├── 25A742AA-75B2-46DD-B7C8-AA2B8A8A5BF4 │ │ ├── 561B040C-E4EE-48CC-A13B-C8ECC41DFD22 │ │ ├── F3723612-4B7A-4993-B0A4-FC2CC3C83361 │ │ └── originalImportedContentDocumentInfo │ └── metadata.info ├── icon-old.afdesign ├── icon.afdesign └── slack-screenshot.pxd │ ├── QuickLook │ ├── Icon.tiff │ └── Thumbnail.tiff │ ├── data │ └── 40323E38-535F-4C23-9866-B9B7263BBF7F │ └── metadata.info ├── eslint.config.js ├── images ├── icon.png └── icon.svg ├── lint-staged.config.js ├── package.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── prettier.config.js ├── samples ├── css.css ├── go.go ├── html.html ├── ini.ini ├── js.jsx ├── markdown.md ├── python.python ├── terminal-colours.sh ├── tsx.tsx └── yaml.yaml ├── screenshot.png ├── src ├── colors.ts ├── index.ts └── theme-main.ts ├── tailwind.config.js ├── themes ├── deprioritised-punctuation.json └── main.json ├── tsconfig.json └── website ├── env.d.ts ├── pages └── index.astro └── public ├── favicon.ico ├── favicon ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── browserconfig.xml ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── mstile-144x144.png ├── mstile-150x150.png ├── mstile-310x150.png ├── mstile-310x310.png ├── mstile-70x70.png ├── safari-pinned-tab.svg └── site.webmanifest └── images ├── code.png └── logo.svg /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub Pages 2 | 3 | on: 4 | # Trigger the workflow every time you push to the `main` branch 5 | # Using a different branch name? Replace `main` with your branch’s name 6 | push: 7 | branches: [main] 8 | # Allows you to run this workflow manually from the Actions tab on GitHub. 9 | workflow_dispatch: 10 | 11 | # Allow this job to clone the repo and create a page deployment 12 | permissions: 13 | contents: read 14 | pages: write 15 | id-token: write 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout your repository using git 22 | uses: actions/checkout@v4 23 | - name: Install, build, and upload your site output 24 | uses: withastro/action@v4 25 | with: 26 | node-version: 22 27 | package-manager: pnpm@latest 28 | 29 | deploy: 30 | needs: build 31 | runs-on: ubuntu-latest 32 | environment: 33 | name: github-pages 34 | url: ${{ steps.deployment.outputs.page_url }} 35 | steps: 36 | - name: Deploy to GitHub Pages 37 | id: deployment 38 | uses: actions/deploy-pages@v4 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist/ 4 | .astro 5 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | npx --no-install lint-staged 2 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 22 -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": ["--extensionDevelopmentPath=${workspaceFolder}"] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": ["deprioritised", "sunglo", "tinycolor"], 3 | "eslint.experimental.useFlatConfig": true, 4 | "eslint.validate": [ 5 | "javascript", 6 | "javascriptreact", 7 | "astro", // Enable .astro 8 | "typescript", // Enable .ts 9 | "typescriptreact" // Enable .tsx 10 | ], 11 | "workbench.colorCustomizations": { 12 | "titleBar.activeForeground": "#e06c75", 13 | "titleBar.inactiveForeground": "#e06c7599" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .github 2 | .husky 3 | .vscode 4 | designs 5 | dist 6 | node_modules 7 | samples 8 | src 9 | website 10 | 11 | .node-version 12 | astro.config.js 13 | eslint.config.js 14 | lint-staged.config.js 15 | prettier.config.cjs 16 | tailwind.config.js 17 | tsconfig.json 18 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the _Plastic_ theme will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) and this 6 | project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [9.5.0] - 2024-03-31 9 | 10 | - Theme the linked tag background. Previously this was the built-in orangey-red, 11 | it now uses Bunker. 12 | 13 | ## [9.4.2] - 2023-09-26 14 | 15 | - Fix screenshot not found. 16 | 17 | ## [9.4.1] - 2023-09-26 18 | 19 | - Update website URL to plastic.wstone.uk 20 | 21 | ## [9.4.0] - 2023-04-08 22 | 23 | - Added support for diff/patch files. 24 | 25 | ## [9.3.1] - 2023-02-03 26 | 27 | - Update changelogs. 28 | 29 | ## [9.3.0] - 2023-02-03 30 | 31 | - Support bracket pair colorization. 32 | - Add support for more statusbar items. 33 | 34 | ## [9.2.0] - 2023-01-08 35 | 36 | - Add support for sticky scroll. 37 | 38 | ## [9.1.0] - 2023-01-08 39 | 40 | - Git diffs are now brighter and more transparent which means the syntax should 41 | be easier to read through them, especially comments. 42 | 43 | On a side-note, my "plus" experiment didn't work. My plan was to take the 44 | in-built VSCode Dark+ theme and simply swap the colours with Plastic colours. 45 | This would take all syntax maintenance away from Plastic. However, that theme 46 | makes some colour combination choices that I'm not comfortable with. I'm still 47 | looking into a more semantic-compatible Plastic theme, but not sure on the 48 | approach yet. 49 | 50 | ## [9.0.0] - 2023-01-04 51 | 52 | Reverting the Persian Pink change from 8.0.0. It seems it didn't play nicely 53 | with a few languages. I'm going to leave Plastic main theme as is for now. I 54 | have another idea to solve the problem I was having with Svelte components' 55 | colour. Not sure if it's going to work but for now let's call it _Plastic+_ (no, 56 | it's not a subscription service! 😆). _Plastic+_ will be an additional theme, 57 | along with the main and _deprioritised punctuation_ themes. 58 | 59 | ## [8.0.0] - 2022-12-27 60 | 61 | The first major change to Plastic in over a year and a half, and… 🥁 …we have a 62 | new colour! Please welcome [Persian Pink](https://plastictheme.com/palette) to 63 | the party 🥳 64 | 65 | I've recently started using Svelte and the component tags were the same colour 66 | as the html elements, making them quite hard to see. I tried updating them to 67 | blue, as per the 7.6.0 release below. However, as Svelte component tags are 68 | classified as class names, this meant I 69 | [inadvertently made class names the same colour as the "class" storage keyword](https://github.com/will-stone/plastic/issues/186). 70 | 71 | After some experimentation, I found that it was best to split class names 72 | (including component tag names) and storage key words (`class`, `const`, `let` 73 | etc.), which meant a new colour was required, and Persian Pink is now the colour 74 | of class names and component tags. 75 | 76 | ## [7.6.1] - 2022-12-27 77 | 78 | - Rollback below change as the class storage and class names were now same 79 | colour. 80 | 81 | ## [7.6.0] - 2022-12-24 82 | 83 | - Svelte components blue, same as React components. 84 | 85 | ## [7.5.0] - 2021-09-03 86 | 87 | - Use transparent inlay hint background. I've found having the hints display the 88 | same as comments (as this is, in essence, all they are) makes them less 89 | distracting. 90 | 91 | ## [7.4.1] - 2021-09-03 92 | 93 | - Update changelog. 94 | 95 | ## [7.4.0] - 2021-09-03 96 | 97 | - Add support for inlay hints. 98 | 99 | ## [7.3.0] - 2021-05-06 100 | 101 | - Add toolbar hover background. 102 | 103 | ## [7.2.0] - 2021-04-29 104 | 105 | - Remove unused activityBar.dropBackground. 106 | - Add secondary button colour. 107 | - Declare primary button hover colour. 108 | 109 | ## [7.1.0] - 2021-04-28 110 | 111 | - Add support for ReScript component tags. 112 | 113 | ## [7.0.1] - 2021-04-23 114 | 115 | - Fix changelog. 116 | 117 | ## [7.0.0] - 2021-04-23 118 | 119 | - If you were you using the _Plastic Legacy v2_ theme, this has now been removed 120 | from the main Plastic project and kindly adopted by Hadi Alqattan: 121 | https://marketplace.visualstudio.com/items?itemName=HadiAlqattan.plastic-legacy 122 | 123 | ## [6.0.0] - 2021-04-10 124 | 125 | If you were you using the _Plastic Legacy v2_ theme, this has now been 126 | officially deprecated. The theme is still available, under the name _DEPRECATED 127 | Plastic Legacy v2_, but will be removed in the next major release. If you are 128 | using this, I urge you to volunteer to be its maintainer. See here for more 129 | details: https://github.com/will-stone/plastic/issues/168 130 | 131 | - Added outline to list.inactiveFocusOutline for an increased contrast on active 132 | sidebar item. 133 | 134 | ## [5.5.3] - 2021-04-08 135 | 136 | - Fix readme screenshot not showing. 137 | 138 | ## [5.5.2] - 2021-04-07 139 | 140 | - Rename repo back to "plastic". 141 | 142 | ## [5.5.1] - 2021-04-05 143 | 144 | - Just a test of the new repo architecture. 145 | 146 | ## [5.5.0] - 2021-04-05 147 | 148 | - Update to new PlasticTheme.com icon. 149 | - Update URLs. 150 | - Added `$schema` to themes so that colour swatches are shown (thanks @awkj). 151 | 152 | ## [5.4.0] - 2021-04-02 153 | 154 | - Add caretBlue to tab last pinned border. 155 | 156 | ## [5.3.0] - 2021-03-28 157 | 158 | - Use standard Plastic colours for terminal. 159 | 160 | ## [5.2.0] - 2021-03-26 161 | 162 | - Style the diff editor. 163 | 164 | ## [5.1.4] - 2021-03-26 165 | 166 | - Fix icon's text shadow direction incorrect. 167 | 168 | ## [5.1.3] - 2021-03-22 169 | 170 | ## [5.1.2] - 2021-03-22 171 | 172 | ## [5.1.1] - 2021-03-22 173 | 174 | - Updated icon. 175 | 176 | ## [5.1.0] - 2021-02-25 177 | 178 | - Add harvest gold background colour to the debug statusbar. 179 | 180 | ## [5.0.0] - 2021-01-28 181 | 182 | - Internal build theme rewritten from yaml to js. 183 | - v2 is included but will no longer be maintained; any workbench updates will 184 | now only be applied to the main Plastic themes. 185 | 186 | ## [4.3.0] - 2021-01-06 187 | 188 | - Add sash hover border colour. 189 | 190 | ## [4.2.0] - 2020-10-07 191 | 192 | - Themed gutter and overview ruler git colours. 193 | - Ruler find colours. 194 | 195 | ## [4.1.0] - 2020-08-26 196 | 197 | - Use non-bright colours for bright terminal colours. As most terminals make 198 | bright colors bold, I've found these look better without changing their 199 | colour. 200 | - Use the nearest to yellow for terminal's yellow colour. 201 | 202 | ## [4.0.3] - 2020-05-19 203 | 204 | ## [4.0.2] - 2020-05-19 205 | 206 | - remove note about not supporting semantic highlighting (as this is now turned 207 | on). 208 | 209 | ## [4.0.1] - 2020-05-14 210 | 211 | - testing new release artefacts. 212 | 213 | ## [4.0.0] - 2020-05-14 214 | 215 | - feat: turn on semantic highlighting. 216 | 217 | ## [3.5.1] - 2020-03-25 218 | 219 | ## [3.5.0] - 2020-03-25 220 | 221 | - feat: theme inactive panel titles. 222 | 223 | ## [3.4.0] - 2020-03-09 224 | 225 | - feat: remove tab hover colour (I've found most themes do not use a hover 226 | colour). 227 | 228 | ## [3.3.0] - 2020-03-03 229 | 230 | - feat: theme sidebar foreground and list active selection foreground. 231 | 232 | ## [3.2.0] - 2020-03-03 233 | 234 | - feat: theme git ignored items. 235 | 236 | ## [3.1.0] - 2020-03-02 237 | 238 | - feat: change the bright grey colour to be one in the same spectrum as the rest 239 | of the theme's grey colours. 240 | - feat: theme breadcrumbs. 241 | - feat: dark indent guides and rulers. 242 | - feat: tab hover colour is same as current. 243 | - fix: empty workbench groups breaks build. 244 | 245 | ## [3.0.1] - 2020-02-12 246 | 247 | - fix: markdown headers not styled (thanks @plul). `entity.name.section` now 248 | styled. 249 | 250 | ## [3.0.0] - 2020-02-09 251 | 252 | v3 introduces a new syntax colour: lavender for functions. This helps tone-down 253 | the amount of whiskey colour, which is now mainly used for JSX props. The scopes 254 | have also been simplified further, separating them into clear types. However, 255 | worry not if you preferred v2, this can still be found in the theme-picker under 256 | "Plastic Legacy v2". 257 | 258 | - Feat: Use new Lavender colour for functions, leaving Whiskey for JSX props. 259 | - Simplified config and build script. 260 | 261 | ## [2.9.0] - 2019-11-11 262 | 263 | - Fix: remove active bar item background (didn't go with theme). 264 | 265 | ## [2.8.0] - 2019-11-08 266 | 267 | - Feat: add top border to active tabs. 268 | 269 | ## [2.7.0] - 2019-11-08 270 | 271 | - Feat: add border to notifications. 272 | 273 | ## [2.6.0] - 2019-11-08 274 | 275 | - Feat: Use same colour as terminal's Bright Blue as secondary colour. 276 | - Feat: active activity bar item border has secondary colour. 277 | - Feat: active activity bar item background has panel colour. 278 | - Feat: theme lightbulb. 279 | 280 | ## [2.5.0] - 2019-10-26 281 | 282 | - Feat: changed Bright Green to be less dazzling. Change Bright Yellow to be 283 | same as Warning. Thanks @kinghat 284 | 285 | ## [2.4.0] - 2019-07-05 286 | 287 | - Feat: use Plastic colours for file explorer warnings, errors, git changes. 288 | 289 | ## [2.3.1] - 2019-05-11 290 | 291 | - Docs: forgot to update changelog. 292 | 293 | ## [2.3.0] - 2019-05-11 294 | 295 | - Feat: removed drop shadows from scrollbar and widget to make theme more flat. 296 | (thanks github.com/lowmess). 297 | - Feat: add titlebar border. (thanks github.com/lowmess). 298 | 299 | ## [2.2.0] - 2018-10-09 300 | 301 | - Feat: Darker inactive activity bar icons. Closes #29. 302 | - Fix: low contrast text on git warning. Closes #25. 303 | 304 | ## [2.1.0] - 2018-06-10 305 | 306 | Updates to the upcoming builder/compiler mean slight tweaks to the theme. 307 | 308 | - JS terminator (semi-colons) are same as all other punctuation (use the 309 | deprioritised theme if you need these to be more subtle). This may change back 310 | in the future, depending on public opinion. 311 | - Inactive tab text is darker. 312 | - List active highlight swapped with list hover: active is now the lighter 313 | colour. 314 | 315 | ## [2.0.2] - 2018-06-03 316 | 317 | - Looks like the move worked. Forgot the README though, this update adds it 318 | back. 319 | 320 | ## [2.0.1] - 2018-06-03 321 | 322 | - This is a test to see if I can move the Plastic theme into a sub-directory. If 323 | it breaks the theme, I'll roll it back. 324 | 325 | ## [2.0.0] - 2018-05-30 326 | 327 | - New v2 config system allows you to make your own variation of Plastic. More 328 | info soon. 329 | - Even less specific scopes means Plastic really is a _simple theme_. 330 | - Various workbench tweaks to standardise some colours. 331 | 332 | v2 has been in the making for quite some time. Please report any issues on 333 | GitHub. 334 | 335 | ## [1.11.2] - 2018-05-29 336 | 337 | - v2's compiler ready. 338 | - Deprioritised v2 theme. 339 | 340 | ## [1.11.1] - 2018-05-22 341 | 342 | v2 beta: use v1 syntax colours (mainly). 343 | 344 | ## [1.11.0] - 2018-05-21 345 | 346 | - I have been testing a new version for some time and am nearly ready to release 347 | Plastic v2! 348 | - Most colours have been tweaked to match their name on 349 | [Chirag's website](http://chir.ag/projects/name-that-color/). e.g. Whiskey 350 | is now a solid whiskey colour instead of an approximation. This gives a more 351 | vibrant feel and better contrast. 352 | - Added an easier method to configure the theme. Now there's three config 353 | files: the colour names, syntax, and workbench configurations. A build 354 | script runs through these and outputs the resulting theme file in the themes 355 | folder. Clone the repo and try it yourself using `yarn build`. 356 | - The scope (syntax) have been simplified further, using (even more!) generic 357 | rules. I've tried to keep the scopes to two levels of specification, with a 358 | maximum of three if necessary. 359 | 360 | Note: v2 will soon become the next version of Plastic so please provide 361 | feedback. v1 will no longer be maintained and will eventually be removed. This 362 | is due to the new way that the theme is built and configured (see above). This 363 | theme will also no longer provide a deprioritised-punctuation version. However, 364 | after v2 has been finalised, I will start a _Plastic Forks_ program, and will 365 | add in a Plastic-Deprioritised-Punctuation theme as its first entry. If you rely 366 | on this variation, I suggest sticking with the legacy version for now (I won't 367 | remove it until the new one is released). 368 | 369 | ## [1.10.0] - 2018-04-09 370 | 371 | - Improve INI (properties) syntax highlighting (thanks to @pkazmier). 372 | 373 | ## [1.9.2] - 2018-03-10 374 | 375 | - Brighter terminal bright-colours. 376 | 377 | ## [1.9.1] - 2018-03-10 378 | 379 | - Style default terminal foreground text. 380 | 381 | ## [1.9.0] - 2018-03-09 382 | 383 | - Styled terminal 384 | 385 | ## [1.8.0] - 2018-03-09 386 | 387 | - Styled word highlight background. 388 | - Styled word highlight strong background. 389 | - Styled word highlight strong border. 390 | 391 | ## [1.7.0] - 2018-03-08 392 | 393 | - Styled debug toolbar background. 394 | - Styled Notification Centre and notifications background. 395 | - Styled active line number foreground. 396 | - Styled word highlight border. 397 | 398 | ## [1.6.0] - 2018-03-06 399 | 400 | - Improve Python regexp and docstring highlighting (thanks to @pkazmier). 401 | 402 | ## [1.5.0] - 2018-02-04 403 | 404 | - Enhanced Go and Python support (thanks to @pkazmier). 405 | 406 | ## [1.4.0] - 2018-01-27 407 | 408 | - Themed peek view (thanks to @pkazmier). 409 | - More punctuation themed in the deprioritised theme (thanks to @pkazmier). 410 | 411 | ## [1.3.0] - 2017-10-16 412 | 413 | - Yellow warning squiggles. 414 | - Darker terminal background, to match sidebar. 415 | - Themed scrollbar. 416 | 417 | ## [1.2.0] - 2017-07-15 418 | 419 | - Suggestion and hover widgets now stand out more with a blue border and darker 420 | background. 421 | - Various other minor tweaks to improve contrast. 422 | - Fixed: SVG icon no longer allowed; changed to PNG. 423 | 424 | ## [1.1.4] - 2017-06-19 425 | 426 | - Slightly darkened line numbers, ruler, and whitespace characters. Previous 427 | color (same as comments) was too bright and over powering when many 428 | indents/white-space characters were present. 429 | 430 | ## [1.1.3] - 2017-06-19 431 | 432 | - Line numbers, ruler, and whitespace characters are now the same colour as 433 | comments. 434 | 435 | ## [1.1.2] - 2017-05-19 436 | 437 | - docs updated with colours and more contribution details. screenshot updated to 438 | match 1.1.x 439 | 440 | ## [1.1.1] - 2017-05-18 441 | 442 | - punctuation header (for markdown files) changed from default colour to Sunglo. 443 | 444 | ## [1.1.0] - 2017-05-17 445 | 446 | - Punctuation returned to normal colour (Cadet Blue) and additional 447 | deprioritised-punctuation theme added. 448 | 449 | ## [1.0.9] - 2017-05-16 450 | 451 | - darker contrast border. 452 | 453 | ## [1.0.8] - 2017-05-16 454 | 455 | - added contrast border. 456 | 457 | ## [1.0.7] - 2017-05-14 458 | 459 | - Add homepage link to readme. 460 | 461 | ## [1.0.6] - 2017-05-14 462 | 463 | - fix: readme image links. 464 | 465 | ## [1.0.5] - 2017-05-14 466 | 467 | - remove duplicate function scope. 468 | 469 | ## [1.0.4] - 2017-05-14 470 | 471 | - standardise input and dropdown. 472 | 473 | ## [1.0.3] - 2017-05-14 474 | 475 | - fix for dom functions (blue to orange). 476 | 477 | ## [1.0.2] - 2017-05-14 478 | 479 | - Remove need for CSS specific scope. 480 | 481 | ## [1.0.1] - 2017-05-13 482 | 483 | - keyword.other.unit = Fountain Blue. 484 | - button.background = Sunglo. 485 | - punctuation.definition.keyword = Sunglo. 486 | - punctuation.definition.entity.css = Whiskey. 487 | - Remove diff editor custom highlight colour. 488 | 489 | ## [1.0.0] - 2017-05-13 490 | 491 | - Initial release. 492 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present, Will Stone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Plastic 2 | 3 | _[A simple syntax and UI theme for Visual Studio Code.](https://plastic.wstone.uk/)_ 4 | 5 | --- 6 | 7 | If you were you using the _Plastic Legacy v2_ theme, this has now been removed 8 | from the main Plastic project and kindly adopted by Hadi Alqattan: 9 | https://marketplace.visualstudio.com/items?itemName=HadiAlqattan.plastic-legacy 10 | 11 | --- 12 | 13 | ## Notable features 14 | 15 | - Dark UI elements for all-day coding. 16 | - Small colour palette to avoid visual overload. 17 | - Additional deprioritised-punctuation theme; concentrate on the content. 18 | 19 | Screenshot 20 | 21 | ## License 22 | 23 | MIT 24 | 25 | ## Development 26 | 27 | The themes are created using a generator: `src/index.js`. The configuration can 28 | be found in the `src/theme-main.js` files. 29 | -------------------------------------------------------------------------------- /astro.config.js: -------------------------------------------------------------------------------- 1 | import tailwind from '@astrojs/tailwind' 2 | import { defineConfig } from 'astro/config' 3 | 4 | // https://astro.build/config 5 | export default defineConfig({ 6 | integrations: [tailwind()], 7 | publicDir: './website/public', 8 | // site: 'https://platic.wstone.uk', 9 | srcDir: './website', 10 | }) 11 | -------------------------------------------------------------------------------- /designs/code.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/code.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /designs/code.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/code.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /designs/code.pxd/data/08D14584-93B6-43FE-ACEA-3C52A7E532BF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/code.pxd/data/08D14584-93B6-43FE-ACEA-3C52A7E532BF -------------------------------------------------------------------------------- /designs/code.pxd/data/originalImportedContentDocumentInfo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/code.pxd/data/originalImportedContentDocumentInfo -------------------------------------------------------------------------------- /designs/code.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/code.pxd/metadata.info -------------------------------------------------------------------------------- /designs/github-social.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/github-social.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /designs/github-social.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/github-social.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /designs/github-social.pxd/data/25A742AA-75B2-46DD-B7C8-AA2B8A8A5BF4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/github-social.pxd/data/25A742AA-75B2-46DD-B7C8-AA2B8A8A5BF4 -------------------------------------------------------------------------------- /designs/github-social.pxd/data/561B040C-E4EE-48CC-A13B-C8ECC41DFD22: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/github-social.pxd/data/561B040C-E4EE-48CC-A13B-C8ECC41DFD22 -------------------------------------------------------------------------------- /designs/github-social.pxd/data/F3723612-4B7A-4993-B0A4-FC2CC3C83361: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/github-social.pxd/data/F3723612-4B7A-4993-B0A4-FC2CC3C83361 -------------------------------------------------------------------------------- /designs/github-social.pxd/data/originalImportedContentDocumentInfo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/github-social.pxd/data/originalImportedContentDocumentInfo -------------------------------------------------------------------------------- /designs/github-social.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/github-social.pxd/metadata.info -------------------------------------------------------------------------------- /designs/icon-old.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/icon-old.afdesign -------------------------------------------------------------------------------- /designs/icon.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/icon.afdesign -------------------------------------------------------------------------------- /designs/slack-screenshot.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/slack-screenshot.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /designs/slack-screenshot.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/slack-screenshot.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /designs/slack-screenshot.pxd/data/40323E38-535F-4C23-9866-B9B7263BBF7F: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/slack-screenshot.pxd/data/40323E38-535F-4C23-9866-B9B7263BBF7F -------------------------------------------------------------------------------- /designs/slack-screenshot.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/designs/slack-screenshot.pxd/metadata.info -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from '@will-stone/eslint-config' 2 | 3 | export default [ 4 | ...(await config()), 5 | { 6 | ignores: ['samples'], 7 | }, 8 | ] 9 | -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/images/icon.png -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | '*.{css,json,md}': ['prettier --write'], 3 | '*.{js,cjs,mjs,ts.astro}': ['eslint --fix'], 4 | } 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plastic", 3 | "displayName": "Plastic", 4 | "version": "9.5.0", 5 | "private": true, 6 | "description": "A simple theme.", 7 | "categories": [ 8 | "Themes" 9 | ], 10 | "keywords": [ 11 | "" 12 | ], 13 | "homepage": "https://plastic.wstone.uk/", 14 | "bugs": { 15 | "url": "https://github.com/will-stone/plastic/issues" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/will-stone/plastic" 20 | }, 21 | "author": "Will Stone", 22 | "publisher": "will-stone", 23 | "type": "module", 24 | "files": [ 25 | "" 26 | ], 27 | "scripts": { 28 | "build": "astro build", 29 | "dev": "astro dev", 30 | "generate-theme": "tsx ./src/index.ts", 31 | "lint": "eslint .", 32 | "prepare": "husky", 33 | "prerelease": "npm run generate-theme", 34 | "release": "vsce publish" 35 | }, 36 | "contributes": { 37 | "themes": [ 38 | { 39 | "label": "Plastic", 40 | "uiTheme": "vs-dark", 41 | "path": "./themes/main.json" 42 | }, 43 | { 44 | "label": "Plastic - deprioritised punctuation", 45 | "uiTheme": "vs-dark", 46 | "path": "./themes/deprioritised-punctuation.json" 47 | } 48 | ] 49 | }, 50 | "dependencies": { 51 | "plastic-palette": "^1.0.5" 52 | }, 53 | "devDependencies": { 54 | "@astrojs/tailwind": "^5.1.0", 55 | "@tailwindcss/typography": "^0.5.13", 56 | "@types/node": "^20.12.12", 57 | "@types/tinycolor2": "^1.4.6", 58 | "@vscode/vsce": "^2.26.1", 59 | "@will-stone/eslint-config": "^18.1.0", 60 | "@will-stone/prettier-config": "^11.0.1", 61 | "astro": "^4.9.1", 62 | "eslint": "^9.28.0", 63 | "husky": "^9.0.11", 64 | "lint-staged": "^15.2.5", 65 | "prettier": "^3.2.5", 66 | "prettier-plugin-astro": "^0.14.0", 67 | "tailwindcss": "^3.4.3", 68 | "tinycolor2": "^1.6.0", 69 | "tsx": "^4.11.0", 70 | "typescript": "^5.4.5" 71 | }, 72 | "engines": { 73 | "node": ">=22.0.0", 74 | "vscode": "^1.80.0" 75 | }, 76 | "icon": "images/icon.png", 77 | "plastic": { 78 | "title": "VSCode", 79 | "appLink": "https://code.visualstudio.com/" 80 | }, 81 | "__metadata": { 82 | "id": "0615a8d1-878b-482f-b36c-773d1ed16adb", 83 | "publisherId": "744e71fe-bf60-4aba-94b1-d6e77d16fa27", 84 | "publisherDisplayName": "Will Stone" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | onlyBuiltDependencies: 2 | - '@vscode/vsce-sign' 3 | - esbuild 4 | - keytar 5 | - sharp 6 | - unrs-resolver 7 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | import prettierConfig from '@will-stone/prettier-config' 2 | 3 | export default { 4 | ...prettierConfig, 5 | plugins: ['prettier-plugin-astro'], 6 | } 7 | -------------------------------------------------------------------------------- /samples/css.css: -------------------------------------------------------------------------------- 1 | .class { 2 | padding: 20px; 3 | background-color: blue; 4 | } 5 | 6 | #id { 7 | display: flex; 8 | } 9 | 10 | @media (max-width: 200px) { 11 | .class { 12 | text-align: left; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/go.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2017-present, Pete Kazmier 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | /* 24 | Don't judge me by the code below. My first Go program written after reading 25 | only first chapter of The Go Programming Language. It indexes the xkcd comic 26 | metadata so you can search for comics that match keywords. 27 | */ 28 | 29 | package main 30 | 31 | import ( 32 | "encoding/json" 33 | "flag" 34 | "fmt" 35 | "io" 36 | "io/ioutil" 37 | "log" 38 | "math/rand" 39 | "net/http" 40 | "os" 41 | "regexp" 42 | "strconv" 43 | "time" 44 | ) 45 | 46 | const ( 47 | // XkcdURL is the URL to the XKCD web site 48 | XkcdURL = "http://xkcd.org/%s/info.0.json" 49 | ) 50 | 51 | // Comic represents an XKCD comic's meta-data 52 | type Comic struct { 53 | Number int `json:"num"` 54 | Month int `json:",string"` 55 | Day int `json:",string"` 56 | Year int `json:",string"` 57 | Title string 58 | Transcript string 59 | Alt string 60 | Img string 61 | } 62 | 63 | func (c *Comic) String() string { 64 | return fmt.Sprintf("%d %d/%d/%d \"%s\"\n%s\n%s\n", 65 | c.Number, c.Month, c.Day, c.Year, c.Title, c.Alt, c.Img) 66 | } 67 | 68 | func main() { 69 | var updateFlag = flag.Bool("u", false, "Update cache with latest comics") 70 | var indexPath = flag.String("i", os.Getenv("HOME")+"/.xkcd.dat", "Path to the xkcd index") 71 | var randomFlag = flag.Bool("r", false, "Select a random xkcd") 72 | var verboseFlag = flag.Bool("v", false, "Display verbose messages") 73 | flag.Parse() 74 | 75 | if !*verboseFlag { 76 | log.SetOutput(ioutil.Discard) 77 | } 78 | 79 | fn := loadIndex 80 | if *updateFlag { 81 | fn = updateIndex 82 | } 83 | 84 | comics, err := fn(*indexPath) 85 | if err != nil { 86 | log.Fatal(err) 87 | } 88 | 89 | if *randomFlag { 90 | rand.Seed(time.Now().Unix()) 91 | fmt.Println(comics[rand.Intn(len(comics))]) 92 | os.Exit(0) 93 | } 94 | 95 | if flag.NArg() == 0 { 96 | os.Exit(0) 97 | } 98 | 99 | searchTerms, err := buildMatchers(flag.Args()) 100 | if err != nil { 101 | log.Fatal(err) 102 | } 103 | 104 | OuterLoop: 105 | for _, comic := range comics { 106 | for _, pattern := range searchTerms { 107 | if !(pattern.MatchString(comic.Title) || 108 | pattern.MatchString(comic.Transcript) || 109 | pattern.MatchString(comic.Alt)) { 110 | continue OuterLoop 111 | } 112 | } 113 | fmt.Println(comic) 114 | } 115 | } 116 | 117 | // Utility functions for query building 118 | 119 | func buildMatchers(terms []string) ([]*regexp.Regexp, error) { 120 | var searchTerms []*regexp.Regexp 121 | for _, term := range terms { 122 | pattern, err := regexp.Compile("(?i)" + term) 123 | if err != nil { 124 | return nil, err 125 | } 126 | searchTerms = append(searchTerms, pattern) 127 | } 128 | return searchTerms, nil 129 | } 130 | 131 | // Utility functions to specify comic URLs 132 | 133 | func latest() string { 134 | return fmt.Sprintf(XkcdURL, "") 135 | } 136 | 137 | func issue(n int) string { 138 | return fmt.Sprintf(XkcdURL, strconv.Itoa(n)) 139 | } 140 | 141 | func latestIssue() (int, error) { 142 | comic, err := fetchComic(latest()) 143 | if err != nil { 144 | return 0, err 145 | } 146 | return comic.Number, nil 147 | } 148 | 149 | func fetchComic(url string) (*Comic, error) { 150 | resp, err := http.Get(url) 151 | if err != nil { 152 | return nil, err 153 | } 154 | defer resp.Body.Close() 155 | 156 | if resp.StatusCode != http.StatusOK { 157 | return nil, fmt.Errorf("non-200 status code %s", url) 158 | } 159 | 160 | var c Comic 161 | if err := json.NewDecoder(resp.Body).Decode(&c); err != nil { 162 | return nil, err 163 | } 164 | return &c, nil 165 | } 166 | 167 | // Utility functions to load and build the index 168 | 169 | func loadIndex(path string) ([]*Comic, error) { 170 | f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644) 171 | defer f.Close() 172 | if err != nil { 173 | return nil, err 174 | } 175 | 176 | var comics []*Comic 177 | decoder := json.NewDecoder(f) 178 | for { 179 | var comic Comic 180 | if err := decoder.Decode(&comic); err == io.EOF { 181 | break 182 | } else if err != nil { 183 | return comics, err 184 | } 185 | comics = append(comics, &comic) 186 | } 187 | 188 | log.Println("loaded", len(comics), "cached entries") 189 | return comics, nil 190 | } 191 | 192 | func updateIndex(path string) ([]*Comic, error) { 193 | comics, err := loadIndex(path) 194 | if err != nil { 195 | return comics, err 196 | } 197 | 198 | old := lastCachedIssue(comics) 199 | log.Println("last cached issue was", old) 200 | new, err := latestIssue() 201 | if err != nil { 202 | return comics, err 203 | } 204 | log.Println("latest xkcd issue is", new) 205 | 206 | f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) 207 | if err != nil { 208 | return nil, err 209 | } 210 | defer f.Close() 211 | 212 | encoder := json.NewEncoder(f) 213 | encoder.SetIndent("", " ") 214 | 215 | // When index doesn't exist, `old` will be 0, so this 216 | // block will populate an empty index as well. 217 | for i := old + 1; i <= new; i++ { 218 | log.Println("fetching issue", i) 219 | comic, err := fetchComic(issue(i)) 220 | if err != nil { 221 | log.Println("Error fetching issue, skipping", issue(i)) 222 | continue 223 | } 224 | if err := encoder.Encode(comic); err != nil { 225 | return comics, err 226 | } 227 | comics = append(comics, comic) 228 | } 229 | 230 | log.Println("updated", len(comics), "cached entries") 231 | return comics, nil 232 | } 233 | 234 | func lastCachedIssue(comics []*Comic) (max int) { 235 | for _, comic := range comics { 236 | if comic.Number > max { 237 | max = comic.Number 238 | } 239 | } 240 | return max 241 | } 242 | -------------------------------------------------------------------------------- /samples/html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Title 7 | 8 | 9 | 10 | 11 | 12 |

Heading

13 |

Paragraph

14 | 15 | 16 | -------------------------------------------------------------------------------- /samples/ini.ini: -------------------------------------------------------------------------------- 1 | # Sample INI file to test theme colors 2 | 3 | [package] 4 | name = "xkcd" 5 | version = "0.1.0" 6 | authors = ["Pete Kazmier"] 7 | 8 | [dependencies] 9 | log = "0.3" 10 | env_logger = "0.4.3" 11 | docopt = "0.8" 12 | docopt_macros = "0.8" 13 | reqwest = "0.7" 14 | serde = "1.0.12" 15 | serde_derive = "1.0.12" 16 | serde_json = "1.0.3" 17 | yansi = "0.3.3" 18 | shellexpand = "1.0.0" 19 | rand = "0.3.16" 20 | 21 | -------------------------------------------------------------------------------- /samples/js.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Comment 3 | * 4 | * comment comment comment comment comment comment comment comment comment 5 | * comment comment comment comment comment 6 | */ 7 | 8 | // Comment 9 | 10 | import React, { Component } from 'react' 11 | import PropTypes from 'prop-types' 12 | 13 | var variable = 'string' 14 | var variable2 = variable 15 | var myRe = /d(b+)d/g 16 | 17 | let undef = undefined 18 | 19 | let bigN = BigInt(4) 20 | 21 | const json = JSON.stringify(variable, null, 2) 22 | 23 | let localVar = 'string' 24 | 25 | const constant = 'CONSTANT' 26 | 27 | let numOperator = (3 + 4) / 2 28 | const numPlus = numOperator++ 29 | 30 | let arr = ['one', 'two', numOperator] 31 | 32 | let obj = { 33 | first: 'string', 34 | second: ['one', 'two', numOperator], 35 | } 36 | 37 | let templateLiteral = `this is a var ${variable}` 38 | 39 | if (localVar) { 40 | console.log('log') 41 | } else { 42 | console.log('log') 43 | console.log(window.location.hash) 44 | } 45 | 46 | function name(param) { 47 | let output = param + 'string' 48 | return output 49 | } 50 | 51 | const funcName = (param) => { 52 | return false 53 | } 54 | 55 | class ComponentName extends Component { 56 | static propTypes = { 57 | param: PropTypes.string, 58 | children: PropTypes.node, 59 | } 60 | 61 | constructor() { 62 | super() 63 | this.state = { 64 | one: 'two', 65 | } 66 | } 67 | 68 | classProperty = () => { 69 | const test = 'test' 70 | return test 71 | } 72 | 73 | handleClick() { 74 | return false 75 | } 76 | 77 | render() { 78 | const { one: value } = this.state 79 | const { param } = this.props 80 | 81 | // some comments 82 | const two = name(param, param, { key: value }) 83 | 84 | console.log(two) 85 | 86 | return ( 87 |
88 | {this.props.children} 89 | 90 | 91 |
92 | ) 93 | } 94 | } 95 | 96 | const ComponentName2 = () => { 97 | return text text text 98 | } 99 | 100 | ComponentName2.propTypes = { 101 | prop1: PropTypes.string, 102 | } 103 | 104 | const arr = new Array() 105 | 106 | class Moo {} 107 | 108 | const t = new Moo() 109 | 110 | export default ComponentName2 111 | -------------------------------------------------------------------------------- /samples/markdown.md: -------------------------------------------------------------------------------- 1 | # An h1 header 2 | 3 | Paragraphs are separated by a blank line. 4 | 5 | 2nd paragraph. _Italic_, **bold**, and `monospace`. Itemized lists look like: 6 | 7 | - this one 8 | - that one 9 | - the other one 10 | 11 | Note that --- not considering the asterisk --- the actual text content starts at 12 | 4-columns in. 13 | 14 | > Block quotes are written like so. 15 | > 16 | > They can span multiple paragraphs, if you like. 17 | 18 | Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all in chapters 19 | 12--14"). Three dots ... will be converted to an ellipsis. Unicode is supported. 20 | ☺ 21 | 22 | ## An h2 header 23 | 24 | Here's a numbered list: 25 | 26 | 1. first item 27 | 2. second item 28 | 3. third item 29 | 30 | Note again how the actual text starts at 4 columns in (4 characters from the 31 | left side). Here's a code sample: 32 | 33 | # Let me re-iterate ... 34 | for i in 1 .. 10 { do-something(i) } 35 | 36 | As you probably guessed, indented 4 spaces. By the way, instead of indenting the 37 | block, you can use delimited blocks, if you like: 38 | 39 | ``` 40 | define foobar() { 41 | print "Welcome to flavor country!"; 42 | } 43 | ``` 44 | 45 | (which makes copying & pasting easier). You can optionally mark the delimited 46 | block for Pandoc to syntax highlight it: 47 | 48 | ```python 49 | import time 50 | # Quick, count to ten! 51 | for i in range(10): 52 | # (but not *too* quick) 53 | time.sleep(0.5) 54 | print i 55 | ``` 56 | 57 | ```ts 58 | import blah from 'blah' 59 | 60 | const funcName = (arg: ArgType): ReturnType => { 61 | blah() 62 | return 'hello' 63 | } 64 | ``` 65 | 66 | ### An h3 header 67 | 68 | Now a nested list: 69 | 70 | 1. First, get these ingredients: 71 | 72 | - carrots 73 | - celery 74 | - lentils 75 | 76 | 2. Boil some water. 77 | 78 | 3. Dump everything in the pot and follow this algorithm: 79 | 80 | find wooden spoon 81 | uncover pot 82 | stir 83 | cover pot 84 | balance wooden spoon precariously on pot handle 85 | wait 10 minutes 86 | goto first step (or shut off burner when done) 87 | 88 | Do not bump wooden spoon or it will fall. 89 | 90 | Notice again how text always lines up on 4-space indents (including that last 91 | line which continues item 3 above). 92 | 93 | Here's a link to [a website](http://foo.bar), to a [local doc](local-doc.html), 94 | and to a [section heading in the current doc](#an-h2-header). Here's a footnote 95 | [^1]. 96 | 97 | [^1]: Footnote text goes here. 98 | 99 | Tables can look like this: 100 | 101 | size material color 102 | 103 | --- 104 | 105 | 9 leather brown 10 hemp canvas natural 11 glass transparent 106 | 107 | Table: Shoes, their sizes, and what they're made of 108 | 109 | (The above is the caption for the table.) Pandoc also supports multi-line 110 | tables: 111 | 112 | --- 113 | 114 | keyword text 115 | 116 | --- 117 | 118 | red Sunsets, apples, and other red or reddish things. 119 | 120 | green Leaves, grass, frogs and other things it's not easy being. 121 | 122 | --- 123 | 124 | A horizontal rule follows. 125 | 126 | --- 127 | 128 | Here's a definition list: 129 | 130 | apples : Good for making applesauce. oranges : Citrus! tomatoes : There's no "e" 131 | in tomatoe. 132 | 133 | Again, text is indented 4 spaces. (Put a blank line between each term/definition 134 | pair to spread things out more.) 135 | 136 | Here's a "line block": 137 | 138 | | Line one | Line too | Line tree 139 | 140 | and images can be specified like so: 141 | 142 | ![example image](example-image.jpg 'An exemplary image') 143 | 144 | Inline math equations go in like so: $\omega = d\phi / dt$. Display math should 145 | get its own line and be put in in double-dollarsigns: 146 | 147 | $$I = \int \rho R^{2} dV$$ 148 | 149 | And note that you can backslash-escape any punctuation characters which you wish 150 | to be displayed literally, ex.: \`foo\`, \*bar\*, etc. 151 | -------------------------------------------------------------------------------- /samples/python.python: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright (c) 2001-present, Pete Kazmier 4 | 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | 24 | # Quick script to benchmark the speed of various versions of the same regular 25 | # expression to identify poorly written expressions. 26 | 27 | from typing import Dict, Sequence, List, Optional, Pattern, Match 28 | from abc import ABCMeta, abstractmethod 29 | import re 30 | import sys 31 | import time 32 | 33 | # The following regex is here to test syntax highlighting 34 | _ = re.compile( 35 | r"""\A 36 | word 37 | (?: # a comment 38 | (?P.)? 39 | (?P[<>=^]) (?# another comment) 40 | )? 41 | another word\.\.\. 42 | (?:\.(?P0|(?!0)\d+))? 43 | \Z""", 44 | re.VERBOSE | re.DOTALL, 45 | ) 46 | 47 | 48 | class RegExpResultBase(metaclass=ABCMeta): 49 | """Class inheritance (to test syntax highlighting).""" 50 | 51 | # Some more special syntax to test syntax highlighting. 52 | # A non-builtin decorator @abstractmethod. 53 | @abstractmethod 54 | def greeting(self, other: str) -> str: 55 | """Return a greeting.""" 56 | pass 57 | 58 | # Use a decorator (to test syntax highlighting) 59 | @classmethod 60 | def get_classname(cla) -> str: 61 | return cla.__name__ 62 | 63 | 64 | class RegExpResult(RegExpResultBase): 65 | """RegExpResult holds the results for a regular expression.""" 66 | 67 | def __init__(self) -> None: 68 | self.cumulative_time: float = 0.0 69 | self.successful_matches: Dict[int, Sequence[str]] = {} 70 | 71 | # Use of default parameter value 72 | def greeting(self, other: str = "world") -> str: 73 | # Classname of self 74 | us: str = type(self).__name__ 75 | 76 | # (use f"" style string formatting to test syntax highlighting) 77 | return f"Hello {other} from {us}!" 78 | 79 | 80 | if len(sys.argv) < 2: 81 | print("Usage:", sys.argv[0], "regexp1 [regexp2 regexp3 ...]") 82 | sys.exit(1) 83 | 84 | # Compile all the regular expressions 85 | patterns: List[Pattern[str]] = [re.compile(x) for x in sys.argv[1:]] 86 | 87 | # Create the result map for each pattern 88 | results: Dict[Pattern[str], RegExpResult] = {} 89 | for pattern in patterns: 90 | results[pattern] = RegExpResult() 91 | 92 | # Test each regular expression against every line of input 93 | line_count: int = 0 94 | for line in sys.stdin: 95 | line_count += 1 96 | 97 | for pattern in patterns: 98 | before: float = time.time() 99 | match: Optional[Match[str]] = pattern.search(line) 100 | after: float = time.time() 101 | 102 | result: RegExpResult = results[pattern] 103 | result.cumulative_time += after - before 104 | if match: 105 | result.successful_matches[line_count] = match.groups() 106 | 107 | print("Pattern calls cumulative avgpercall matches [line numbers]") 108 | pattern_count: int = 0 109 | for pattern in patterns: 110 | pattern_count += 1 111 | result = results[pattern] 112 | 113 | print( 114 | "%7d %7d %10.6f %10.6f %7d" 115 | % ( 116 | pattern_count, 117 | line_count, 118 | result.cumulative_time, 119 | result.cumulative_time / line_count, 120 | len(result.successful_matches), 121 | ) 122 | ) 123 | 124 | line_number_keys: List[int] = list(result.successful_matches.keys()) 125 | line_number_keys.sort(key=lambda x: x) 126 | print(line_number_keys) 127 | -------------------------------------------------------------------------------- /samples/terminal-colours.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in `seq 0 1 7` 4 | do 5 | c=$(tput setaf $i) 6 | b=$(tput bold setaf $(($i+8))) 7 | n=$(tput sgr0) 8 | echo ${c}The quick brown fox ${b}jumps${n}${c} over the lazy dog ${n} 9 | done 10 | -------------------------------------------------------------------------------- /samples/tsx.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as DOM from 'react-dom' 3 | 4 | const root = document.querySelector('#app') 5 | 6 | function test(hello) { 7 | console.log(hello) 8 | } 9 | 10 | test() 11 | 12 | const bye = () => console.log('bye') 13 | 14 | type Props = { 15 | readonly vehicleType: 'Car' | 'Motorcycle' | 'Truck' 16 | readonly color: string 17 | readonly numWheels: 2 | 4 18 | readonly age: number 19 | } 20 | type State = {} 21 | 22 | class Main extends React.Component { 23 | static propTypes = { 24 | prop1: PropTypes.number, 25 | } 26 | 27 | constructor(props: Props) { 28 | super(props) 29 | 30 | this.test = props.test 31 | } 32 | 33 | classProperty = ({ hello }, bye) => { 34 | return hello 35 | } 36 | 37 | render() { 38 | return ( 39 |
40 |
VehicleType: {this.props.vehicleType}
41 |
Color: {this.props.color}
42 |
Wheels: {this.props.numWheels}
43 |
Age: {this.props.age}
44 |
45 | ) 46 | } 47 | } 48 | 49 | type WelcomeProps = { 50 | readonly name?: string // Change the required prop to an optional prop. 51 | } 52 | 53 | const Welcome: React.SFC = (props) => { 54 | return

Hello, {props.name}

55 | } 56 | 57 | Welcome.defaultProps = { 58 | name: 'Guest User', // This value is adopted when name prop is omitted. 59 | } 60 | 61 | DOM.render(
, root) 62 | -------------------------------------------------------------------------------- /samples/yaml.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | version: 1.0.0 4 | title: Swagger Petstore 5 | description: 6 | A sample API that uses a petstore as an example to demonstrate features in 7 | the swagger-2.0 specification 8 | termsOfService: http://swagger.io/terms/ 9 | contact: 10 | name: Swagger API Team 11 | email: apiteam@swagger.io 12 | url: http://swagger.io 13 | license: 14 | name: Apache 2.0 15 | url: https://www.apache.org/licenses/LICENSE-2.0.html 16 | host: petstore.swagger.io 17 | basePath: /api 18 | schemes: 19 | - http 20 | consumes: 21 | - application/json 22 | produces: 23 | - application/json 24 | paths: 25 | /pets: 26 | get: 27 | description: | 28 | Returns all pets from the system that the user has access to 29 | operationId: findPets 30 | parameters: 31 | - name: tags 32 | in: query 33 | description: tags to filter by 34 | required: false 35 | type: array 36 | collectionFormat: csv 37 | items: 38 | type: string 39 | - name: limit 40 | in: query 41 | description: maximum number of results to return 42 | required: false 43 | type: integer 44 | format: int32 45 | responses: 46 | '200': 47 | description: pet response 48 | schema: 49 | type: array 50 | items: 51 | $ref: '#/definitions/Pet' 52 | default: 53 | description: unexpected error 54 | schema: 55 | $ref: '#/definitions/Error' 56 | post: 57 | description: Creates a new pet in the store. Duplicates are allowed 58 | operationId: addPet 59 | parameters: 60 | - name: pet 61 | in: body 62 | description: Pet to add to the store 63 | required: true 64 | schema: 65 | $ref: '#/definitions/NewPet' 66 | responses: 67 | '200': 68 | description: pet response 69 | schema: 70 | $ref: '#/definitions/Pet' 71 | default: 72 | description: unexpected error 73 | schema: 74 | $ref: '#/definitions/Error' 75 | /pets/{id}: 76 | get: 77 | description: 78 | Returns a user based on a single ID, if the user does not have access to 79 | the pet 80 | operationId: find pet by id 81 | parameters: 82 | - name: id 83 | in: path 84 | description: ID of pet to fetch 85 | required: true 86 | type: integer 87 | format: int64 88 | responses: 89 | '200': 90 | description: pet response 91 | schema: 92 | $ref: '#/definitions/Pet' 93 | default: 94 | description: unexpected error 95 | schema: 96 | $ref: '#/definitions/Error' 97 | delete: 98 | description: deletes a single pet based on the ID supplied 99 | operationId: deletePet 100 | parameters: 101 | - name: id 102 | in: path 103 | description: ID of pet to delete 104 | required: true 105 | type: integer 106 | format: int64 107 | responses: 108 | '204': 109 | description: pet deleted 110 | default: 111 | description: unexpected error 112 | schema: 113 | $ref: '#/definitions/Error' 114 | definitions: 115 | Pet: 116 | allOf: 117 | - $ref: '#/definitions/NewPet' 118 | - required: 119 | - id 120 | properties: 121 | id: 122 | type: integer 123 | format: int64 124 | 125 | NewPet: 126 | required: 127 | - name 128 | properties: 129 | name: 130 | type: string 131 | tag: 132 | type: string 133 | 134 | Error: 135 | required: 136 | - code 137 | - message 138 | properties: 139 | code: 140 | type: integer 141 | format: int32 142 | message: 143 | type: string 144 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/screenshot.png -------------------------------------------------------------------------------- /src/colors.ts: -------------------------------------------------------------------------------- 1 | import palette from 'plastic-palette' 2 | import tinycolor from 'tinycolor2' 3 | 4 | const { 5 | bunker, 6 | cadetBlue, 7 | cornflowerBlue, 8 | dodgerBlue, 9 | fountainBlue, 10 | ghost, 11 | harvestGold, 12 | lavender, 13 | olivine, 14 | robRoy, 15 | shark, 16 | shuttleGray, 17 | sunglo, 18 | transparent, 19 | valencia, 20 | whiskey, 21 | white, 22 | woodsmoke, 23 | } = palette 24 | 25 | const setAlpha = (hex: string, alpha: number) => 26 | tinycolor(hex).setAlpha(alpha).toHex8String().toUpperCase() 27 | 28 | const brighten = (hex: string, percent: number) => 29 | tinycolor(hex).brighten(percent).toHex8String().toUpperCase() 30 | 31 | // const darken = (hex: string, percent: number) => 32 | // tinycolor(hex).darken(percent).toHex8String().toUpperCase() 33 | 34 | // const desaturate = (hex: string, percent: number) => 35 | // tinycolor(hex).desaturate(percent).toHex8String().toUpperCase() 36 | 37 | const cadetBlue10 = setAlpha(cadetBlue, 0.1) 38 | const cadetBlue20 = setAlpha(cadetBlue, 0.2) 39 | 40 | export const colors = { 41 | 'activityBar.activeBorder': dodgerBlue, 42 | 'activityBar.background': shark, 43 | 'activityBar.border': bunker, 44 | 'activityBar.foreground': ghost, 45 | 'activityBar.inactiveForeground': shuttleGray, 46 | 47 | 'activityBarBadge.background': sunglo, 48 | 'activityBarBadge.foreground': white, 49 | 50 | 'breadcrumb.focusForeground': ghost, 51 | 'breadcrumb.foreground': shuttleGray, 52 | 53 | 'button.background': sunglo, 54 | 'button.foreground': white, 55 | 'button.hoverBackground': tinycolor(sunglo) 56 | .lighten(5) 57 | .toHexString() 58 | .toUpperCase(), 59 | 'button.secondaryBackground': bunker, 60 | 'button.secondaryForeground': white, 61 | 62 | 'checkbox.background': cornflowerBlue, 63 | 'checkbox.foreground': white, 64 | 65 | contrastBorder: bunker, 66 | 67 | 'debugToolBar.background': woodsmoke, 68 | 69 | 'diffEditor.border': bunker, 70 | 'diffEditor.diagonalFill': bunker, 71 | 'diffEditor.insertedLineBackground': setAlpha(brighten(olivine, 20), 0.05), 72 | 'diffEditor.insertedTextBackground': setAlpha(brighten(olivine, 20), 0.1), 73 | 'diffEditor.removedLineBackground': setAlpha(brighten(sunglo, 20), 0.05), 74 | 'diffEditor.removedTextBackground': setAlpha(brighten(sunglo, 20), 0.1), 75 | 76 | 'dropdown.background': woodsmoke, 77 | 'dropdown.border': bunker, 78 | 79 | 'editor.background': shark, 80 | 'editor.findMatchBackground': transparent, 81 | 'editor.findMatchBorder': dodgerBlue, 82 | 'editor.findMatchHighlightBackground': transparent, 83 | 'editor.findMatchHighlightBorder': ghost, 84 | 'editor.foreground': cadetBlue, 85 | 'editor.lineHighlightBackground': cadetBlue10, 86 | 'editor.lineHighlightBorder': transparent, 87 | 'editor.linkedEditingBackground': bunker, 88 | 'editor.rangeHighlightBorder': ghost, 89 | 'editor.selectionBackground': cadetBlue20, 90 | 'editor.selectionHighlightBackground': cadetBlue10, 91 | 'editor.selectionHighlightBorder': ghost, 92 | 'editor.wordHighlightBackground': transparent, 93 | 'editor.wordHighlightBorder': dodgerBlue, 94 | 'editor.wordHighlightStrongBackground': transparent, 95 | 'editor.wordHighlightStrongBorder': dodgerBlue, 96 | 97 | 'editorBracketHighlight.foreground1': cadetBlue, 98 | 'editorBracketHighlight.foreground2': cornflowerBlue, 99 | 'editorBracketHighlight.foreground3': harvestGold, 100 | 'editorBracketHighlight.foreground4': sunglo, 101 | 'editorBracketHighlight.foreground5': olivine, 102 | 'editorBracketHighlight.foreground6': lavender, 103 | 'editorBracketHighlight.unexpectedBracket.foreground': valencia, 104 | 105 | 'editorBracketMatch.background': transparent, 106 | 'editorBracketMatch.border': dodgerBlue, 107 | 108 | 'editorCursor.foreground': cadetBlue, 109 | 110 | 'editorError.foreground': valencia, 111 | 112 | 'editorGroup.border': bunker, 113 | 'editorGroup.emptyBackground': woodsmoke, 114 | 115 | 'editorGroupHeader.tabsBackground': woodsmoke, 116 | 117 | 'editorGutter.addedBackground': olivine, 118 | 'editorGutter.deletedBackground': sunglo, 119 | 'editorGutter.modifiedBackground': whiskey, 120 | 121 | 'editorHoverWidget.background': woodsmoke, 122 | 'editorHoverWidget.border': dodgerBlue, 123 | 124 | 'editorIndentGuide.activeBackground': cadetBlue20, 125 | 'editorIndentGuide.background': bunker, 126 | 127 | 'editorInfo.foreground': dodgerBlue, 128 | 129 | 'editorInlayHint.background': transparent, 130 | 'editorInlayHint.foreground': shuttleGray, 131 | 132 | 'editorLightBulb.foreground': robRoy, 133 | 134 | 'editorLightBulbAutoFix.foreground': dodgerBlue, 135 | 136 | 'editorLineNumber.activeForeground': ghost, 137 | 'editorLineNumber.foreground': shuttleGray, 138 | 139 | 'editorOverviewRuler.addedForeground': olivine, 140 | 'editorOverviewRuler.border': bunker, 141 | 'editorOverviewRuler.deletedForeground': sunglo, 142 | 'editorOverviewRuler.errorForeground': valencia, 143 | 'editorOverviewRuler.findMatchForeground': dodgerBlue, 144 | 'editorOverviewRuler.infoForeground': dodgerBlue, 145 | 'editorOverviewRuler.modifiedForeground': whiskey, 146 | 'editorOverviewRuler.warningForeground': robRoy, 147 | 148 | 'editorRuler.foreground': bunker, 149 | 150 | 'editorStickyScroll.background': woodsmoke, 151 | 'editorStickyScrollHover.background': shark, 152 | 153 | 'editorSuggestWidget.background': woodsmoke, 154 | 'editorSuggestWidget.border': dodgerBlue, 155 | 'editorSuggestWidget.selectedBackground': cadetBlue10, 156 | 157 | 'editorWarning.foreground': robRoy, 158 | 159 | 'editorWhitespace.foreground': cadetBlue10, 160 | 161 | 'editorWidget.background': woodsmoke, 162 | 163 | errorForeground: valencia, 164 | 165 | focusBorder: dodgerBlue, 166 | 167 | 'gitDecoration.deletedResourceForeground': sunglo, 168 | 'gitDecoration.ignoredResourceForeground': shuttleGray, 169 | 'gitDecoration.modifiedResourceForeground': whiskey, 170 | 'gitDecoration.untrackedResourceForeground': olivine, 171 | 172 | 'input.background': bunker, 173 | 174 | 'inputOption.activeBorder': dodgerBlue, 175 | 176 | 'inputValidation.errorBackground': valencia, 177 | 'inputValidation.errorBorder': valencia, 178 | 'inputValidation.infoBackground': dodgerBlue, 179 | 'inputValidation.infoBorder': dodgerBlue, 180 | 'inputValidation.infoForeground': bunker, 181 | 'inputValidation.warningBackground': robRoy, 182 | 'inputValidation.warningBorder': robRoy, 183 | 'inputValidation.warningForeground': bunker, 184 | 185 | 'list.activeSelectionBackground': cadetBlue20, 186 | 'list.activeSelectionForeground': white, 187 | 'list.errorForeground': valencia, 188 | 'list.focusBackground': cadetBlue20, 189 | 'list.hoverBackground': cadetBlue10, 190 | 'list.inactiveFocusOutline': shuttleGray, 191 | 'list.inactiveSelectionBackground': cadetBlue20, 192 | 'list.inactiveSelectionForeground': ghost, 193 | 'list.warningForeground': robRoy, 194 | 195 | 'minimap.findMatchHighlight': dodgerBlue, 196 | 'minimap.selectionHighlight': ghost, 197 | 198 | 'minimapGutter.addedBackground': olivine, 199 | 'minimapGutter.deletedBackground': sunglo, 200 | 'minimapGutter.modifiedBackground': whiskey, 201 | 202 | 'notificationCenter.border': bunker, 203 | 204 | 'notificationCenterHeader.background': woodsmoke, 205 | 206 | 'notifications.background': woodsmoke, 207 | 'notifications.border': bunker, 208 | 209 | 'notificationToast.border': bunker, 210 | 211 | 'panel.background': woodsmoke, 212 | 'panel.border': bunker, 213 | 214 | 'panelTitle.inactiveForeground': shuttleGray, 215 | 216 | 'peekView.border': dodgerBlue, 217 | 218 | 'peekViewEditor.background': woodsmoke, 219 | 'peekViewEditor.matchHighlightBackground': cadetBlue20, 220 | 221 | 'peekViewResult.background': woodsmoke, 222 | 'peekViewResult.matchHighlightBackground': cadetBlue20, 223 | 'peekViewResult.selectionBackground': cadetBlue10, 224 | 'peekViewResult.selectionForeground': ghost, 225 | 226 | 'peekViewTitle.background': woodsmoke, 227 | 228 | 'sash.hoverBorder': cadetBlue20, 229 | 230 | 'scrollbar.shadow': transparent, 231 | 232 | 'scrollbarSlider.activeBackground': cadetBlue20, 233 | 'scrollbarSlider.background': cadetBlue10, 234 | 'scrollbarSlider.hoverBackground': cadetBlue20, 235 | 236 | 'sideBar.background': woodsmoke, 237 | 'sideBar.border': bunker, 238 | 'sideBar.foreground': ghost, 239 | 240 | 'sideBarSectionHeader.background': shark, 241 | 242 | 'statusBar.background': shark, 243 | 'statusBar.border': bunker, 244 | 'statusBar.debuggingBackground': shark, 245 | 'statusBar.debuggingBorder': fountainBlue, 246 | 'statusBar.debuggingForeground': cadetBlue, 247 | 'statusBar.focusBorder': cadetBlue, 248 | 'statusBar.foreground': cadetBlue, 249 | 'statusBar.noFolderBackground': woodsmoke, 250 | 251 | 'statusBarItem.activeBackground': bunker, 252 | 'statusBarItem.errorBackground': shark, 253 | 'statusBarItem.errorForeground': valencia, 254 | 'statusBarItem.focusBorder': cadetBlue, 255 | 'statusBarItem.hoverBackground': woodsmoke, 256 | 'statusBarItem.hoverForeground': cadetBlue, 257 | 'statusBarItem.remoteBackground': shark, 258 | 'statusBarItem.remoteForeground': lavender, 259 | 'statusBarItem.warningBackground': shark, 260 | 'statusBarItem.warningForeground': robRoy, 261 | 262 | 'tab.activeBackground': shark, 263 | 'tab.activeBorderTop': dodgerBlue, 264 | 'tab.activeForeground': ghost, 265 | 'tab.border': bunker, 266 | 'tab.inactiveBackground': woodsmoke, 267 | 'tab.inactiveForeground': shuttleGray, 268 | 'tab.lastPinnedBorder': cadetBlue20, 269 | 270 | 'terminal.ansiBlack': shuttleGray, 271 | 'terminal.ansiBlue': cornflowerBlue, 272 | 'terminal.ansiBrightBlack': shuttleGray, 273 | 'terminal.ansiBrightBlue': cornflowerBlue, 274 | 'terminal.ansiBrightCyan': fountainBlue, 275 | 'terminal.ansiBrightGreen': olivine, 276 | 'terminal.ansiBrightMagenta': lavender, 277 | 'terminal.ansiBrightRed': sunglo, 278 | 'terminal.ansiBrightWhite': cadetBlue, 279 | 'terminal.ansiBrightYellow': harvestGold, 280 | 'terminal.ansiCyan': fountainBlue, 281 | 'terminal.ansiGreen': olivine, 282 | 'terminal.ansiMagenta': lavender, 283 | 'terminal.ansiRed': sunglo, 284 | 'terminal.ansiWhite': cadetBlue, 285 | 'terminal.ansiYellow': harvestGold, 286 | 'terminal.foreground': cadetBlue, 287 | 288 | 'titleBar.activeBackground': shark, 289 | 'titleBar.activeForeground': ghost, 290 | 'titleBar.border': bunker, 291 | 'titleBar.inactiveBackground': shark, 292 | 'titleBar.inactiveForeground': shuttleGray, 293 | 294 | 'toolbar.hoverBackground': cadetBlue20, 295 | 296 | 'widget.shadow': transparent, 297 | } 298 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { promises as fs } from 'node:fs' 4 | 5 | import prettier from 'prettier' 6 | 7 | import { getMainTheme } from './theme-main.js' 8 | 9 | function prettify(object: unknown) { 10 | return prettier.format(JSON.stringify(object, undefined, 2), { 11 | parser: 'json', 12 | }) 13 | } 14 | 15 | await fs.mkdir('./themes', { recursive: true }) 16 | 17 | try { 18 | await Promise.all([ 19 | fs.writeFile('./themes/main.json', await prettify(getMainTheme())), 20 | fs.writeFile( 21 | './themes/deprioritised-punctuation.json', 22 | await prettify(getMainTheme(true)), 23 | ), 24 | ]) 25 | } catch { 26 | process.exit(1) 27 | } 28 | -------------------------------------------------------------------------------- /src/theme-main.ts: -------------------------------------------------------------------------------- 1 | import palette from 'plastic-palette' 2 | 3 | import { colors } from './colors.js' 4 | 5 | const { 6 | cadetBlue, 7 | cornflowerBlue, 8 | fountainBlue, 9 | ghost, 10 | harvestGold, 11 | lavender, 12 | olivine, 13 | shuttleGray, 14 | sunglo, 15 | whiskey, 16 | } = palette 17 | 18 | // TODO is there an official theme type that can be used for the return type? 19 | export function getMainTheme(deprioritised = false): unknown { 20 | return { 21 | $schema: 'vscode://schemas/color-theme', 22 | name: 'Plastic', 23 | type: 'dark', 24 | 25 | semanticHighlighting: true, 26 | semanticTokenColors: {}, 27 | 28 | colors, 29 | tokenColors: [ 30 | // Syntax 31 | ...[ 32 | // comments 33 | [ 34 | [ 35 | 'comment', 36 | // start and end of comment blocks 37 | 'punctuation.definition.comment', 38 | // Diff files 39 | 'source.diff', 40 | ], 41 | shuttleGray, 42 | ], 43 | 44 | // functions 45 | [ 46 | [ 47 | 'entity.name.function', 48 | 'support.function', 49 | // Diff files 50 | 'meta.diff.range', 51 | 'punctuation.definition.range.diff', 52 | ], 53 | lavender, 54 | ], 55 | 56 | // import, export, return etc. 57 | [ 58 | [ 59 | 'keyword', 60 | // css @ in @media queries 61 | 'punctuation.definition.keyword', 62 | // this 63 | 'variable.language', 64 | // Diff files 65 | 'markup.deleted', 66 | 'meta.diff.header.from-file', 67 | 'punctuation.definition.deleted', 68 | 'punctuation.definition.from-file.diff', 69 | ], 70 | sunglo, 71 | ], 72 | 73 | // primitives 74 | [['constant', 'support.constant'], fountainBlue], 75 | 76 | // const, var, class etc. and React JSX component tag 77 | [ 78 | [ 79 | 'storage', 80 | // console and JSX custom components 81 | 'support.class', 82 | // ReScript components 83 | 'entity.name.namespace', 84 | // Diff files 85 | 'meta.diff.header', 86 | ], 87 | cornflowerBlue, 88 | ], 89 | 90 | // anything in quotes 91 | [ 92 | [ 93 | // inline code in markdown 94 | 'markup.inline.raw.string', 95 | 'string', 96 | // Diff files 97 | 'markup.inserted', 98 | 'punctuation.definition.inserted', 99 | 'meta.diff.header.to-file', 100 | 'punctuation.definition.to-file.diff', 101 | ], 102 | olivine, 103 | ], 104 | 105 | // html tags and types 106 | [ 107 | [ 108 | 'entity.name.section', 109 | 'entity.name.tag', 110 | 'entity.name.type', 111 | 'support.type', 112 | ], 113 | harvestGold, 114 | ], 115 | 116 | // variables 117 | [ 118 | [ 119 | // css property names 120 | 'support.type.property-name', 121 | 'support.variable', 122 | 'variable', 123 | ], 124 | ghost, 125 | ], 126 | 127 | // Other 128 | [ 129 | [ 130 | 'entity.other', 131 | // css . and # for CSS classes and IDs 132 | 'punctuation.definition.entity', 133 | 'support.other', 134 | ], 135 | whiskey, 136 | ], 137 | 138 | [ 139 | ['meta.brace', 'punctuation'], 140 | deprioritised ? shuttleGray : cadetBlue, 141 | ], 142 | ].map(([scope, foreground]) => ({ 143 | scope, 144 | settings: { foreground }, 145 | })), 146 | 147 | // Font styles 148 | ...[ 149 | // bold 150 | [ 151 | [ 152 | 'markup.bold', 153 | 'punctuation.definition.bold', 154 | // css ID 155 | 'entity.other.attribute-name.id', 156 | ], 157 | 'bold', 158 | ], 159 | 160 | // italic 161 | [ 162 | ['comment', 'markup.italic', 'punctuation.definition.italic'], 163 | 'italic', 164 | ], 165 | ].map(([scope, style]) => ({ 166 | name: style, 167 | scope, 168 | settings: { fontStyle: style }, 169 | })), 170 | ], 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | import palette from 'plastic-palette' 2 | import defaultTheme from 'tailwindcss/defaultTheme' 3 | import plugin from 'tailwindcss/plugin' 4 | 5 | export default { 6 | content: ['./website/**/*.astro'], 7 | plugins: [ 8 | plugin(({ addBase, theme }) => { 9 | addBase({ 10 | body: { 11 | backgroundColor: palette.shark, 12 | color: palette.cadetBlue, 13 | }, 14 | h1: { 15 | color: palette.sunglo, 16 | fontFamily: theme('fontFamily.comfortaa'), 17 | fontSize: theme('fontSize.5xl'), 18 | letterSpacing: theme('letterSpacing.widest'), 19 | textAlign: 'center', 20 | }, 21 | h2: { 22 | color: palette.ghost, 23 | fontFamily: theme('fontFamily.comfortaa'), 24 | fontSize: theme('fontSize.4xl'), 25 | }, 26 | h3: { 27 | fontFamily: theme('fontFamily.comfortaa'), 28 | fontSize: theme('fontSize.3xl'), 29 | textAlign: 'center', 30 | }, 31 | hr: { 32 | borderColor: palette.bunker, 33 | }, 34 | }) 35 | }), 36 | ], 37 | theme: { 38 | container: { 39 | center: true, 40 | padding: '1.5rem', 41 | }, 42 | extend: { 43 | colors: { ...palette }, 44 | }, 45 | fontFamily: { 46 | ...defaultTheme.fontFamily, 47 | comfortaa: ['Comfortaa', ...defaultTheme.fontFamily.sans], 48 | sans: ['Inter', ...defaultTheme.fontFamily.sans], 49 | }, 50 | screens: { 51 | lg: '1024px', 52 | md: '768px', 53 | sm: '640px', 54 | }, 55 | }, 56 | } 57 | -------------------------------------------------------------------------------- /themes/deprioritised-punctuation.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "vscode://schemas/color-theme", 3 | "name": "Plastic", 4 | "type": "dark", 5 | "semanticHighlighting": true, 6 | "semanticTokenColors": {}, 7 | "colors": { 8 | "activityBar.activeBorder": "#1085FF", 9 | "activityBar.background": "#21252B", 10 | "activityBar.border": "#0D1117", 11 | "activityBar.foreground": "#C6CCD7", 12 | "activityBar.inactiveForeground": "#5F6672", 13 | "activityBarBadge.background": "#E06C75", 14 | "activityBarBadge.foreground": "#ffffff", 15 | "breadcrumb.focusForeground": "#C6CCD7", 16 | "breadcrumb.foreground": "#5F6672", 17 | "button.background": "#E06C75", 18 | "button.foreground": "#ffffff", 19 | "button.hoverBackground": "#E48189", 20 | "button.secondaryBackground": "#0D1117", 21 | "button.secondaryForeground": "#ffffff", 22 | "checkbox.background": "#61AFEF", 23 | "checkbox.foreground": "#ffffff", 24 | "contrastBorder": "#0D1117", 25 | "debugToolBar.background": "#181A1F", 26 | "diffEditor.border": "#0D1117", 27 | "diffEditor.diagonalFill": "#0D1117", 28 | "diffEditor.insertedLineBackground": "#CBF6AC0D", 29 | "diffEditor.insertedTextBackground": "#CBF6AC1A", 30 | "diffEditor.removedLineBackground": "#FF9FA80D", 31 | "diffEditor.removedTextBackground": "#FF9FA81A", 32 | "dropdown.background": "#181A1F", 33 | "dropdown.border": "#0D1117", 34 | "editor.background": "#21252B", 35 | "editor.findMatchBackground": "#00000000", 36 | "editor.findMatchBorder": "#1085FF", 37 | "editor.findMatchHighlightBackground": "#00000000", 38 | "editor.findMatchHighlightBorder": "#C6CCD7", 39 | "editor.foreground": "#A9B2C3", 40 | "editor.lineHighlightBackground": "#A9B2C31A", 41 | "editor.lineHighlightBorder": "#00000000", 42 | "editor.linkedEditingBackground": "#0D1117", 43 | "editor.rangeHighlightBorder": "#C6CCD7", 44 | "editor.selectionBackground": "#A9B2C333", 45 | "editor.selectionHighlightBackground": "#A9B2C31A", 46 | "editor.selectionHighlightBorder": "#C6CCD7", 47 | "editor.wordHighlightBackground": "#00000000", 48 | "editor.wordHighlightBorder": "#1085FF", 49 | "editor.wordHighlightStrongBackground": "#00000000", 50 | "editor.wordHighlightStrongBorder": "#1085FF", 51 | "editorBracketHighlight.foreground1": "#A9B2C3", 52 | "editorBracketHighlight.foreground2": "#61AFEF", 53 | "editorBracketHighlight.foreground3": "#E5C07B", 54 | "editorBracketHighlight.foreground4": "#E06C75", 55 | "editorBracketHighlight.foreground5": "#98C379", 56 | "editorBracketHighlight.foreground6": "#B57EDC", 57 | "editorBracketHighlight.unexpectedBracket.foreground": "#D74E42", 58 | "editorBracketMatch.background": "#00000000", 59 | "editorBracketMatch.border": "#1085FF", 60 | "editorCursor.foreground": "#A9B2C3", 61 | "editorError.foreground": "#D74E42", 62 | "editorGroup.border": "#0D1117", 63 | "editorGroup.emptyBackground": "#181A1F", 64 | "editorGroupHeader.tabsBackground": "#181A1F", 65 | "editorGutter.addedBackground": "#98C379", 66 | "editorGutter.deletedBackground": "#E06C75", 67 | "editorGutter.modifiedBackground": "#D19A66", 68 | "editorHoverWidget.background": "#181A1F", 69 | "editorHoverWidget.border": "#1085FF", 70 | "editorIndentGuide.activeBackground": "#A9B2C333", 71 | "editorIndentGuide.background": "#0D1117", 72 | "editorInfo.foreground": "#1085FF", 73 | "editorInlayHint.background": "#00000000", 74 | "editorInlayHint.foreground": "#5F6672", 75 | "editorLightBulb.foreground": "#E9D16C", 76 | "editorLightBulbAutoFix.foreground": "#1085FF", 77 | "editorLineNumber.activeForeground": "#C6CCD7", 78 | "editorLineNumber.foreground": "#5F6672", 79 | "editorOverviewRuler.addedForeground": "#98C379", 80 | "editorOverviewRuler.border": "#0D1117", 81 | "editorOverviewRuler.deletedForeground": "#E06C75", 82 | "editorOverviewRuler.errorForeground": "#D74E42", 83 | "editorOverviewRuler.findMatchForeground": "#1085FF", 84 | "editorOverviewRuler.infoForeground": "#1085FF", 85 | "editorOverviewRuler.modifiedForeground": "#D19A66", 86 | "editorOverviewRuler.warningForeground": "#E9D16C", 87 | "editorRuler.foreground": "#0D1117", 88 | "editorStickyScroll.background": "#181A1F", 89 | "editorStickyScrollHover.background": "#21252B", 90 | "editorSuggestWidget.background": "#181A1F", 91 | "editorSuggestWidget.border": "#1085FF", 92 | "editorSuggestWidget.selectedBackground": "#A9B2C31A", 93 | "editorWarning.foreground": "#E9D16C", 94 | "editorWhitespace.foreground": "#A9B2C31A", 95 | "editorWidget.background": "#181A1F", 96 | "errorForeground": "#D74E42", 97 | "focusBorder": "#1085FF", 98 | "gitDecoration.deletedResourceForeground": "#E06C75", 99 | "gitDecoration.ignoredResourceForeground": "#5F6672", 100 | "gitDecoration.modifiedResourceForeground": "#D19A66", 101 | "gitDecoration.untrackedResourceForeground": "#98C379", 102 | "input.background": "#0D1117", 103 | "inputOption.activeBorder": "#1085FF", 104 | "inputValidation.errorBackground": "#D74E42", 105 | "inputValidation.errorBorder": "#D74E42", 106 | "inputValidation.infoBackground": "#1085FF", 107 | "inputValidation.infoBorder": "#1085FF", 108 | "inputValidation.infoForeground": "#0D1117", 109 | "inputValidation.warningBackground": "#E9D16C", 110 | "inputValidation.warningBorder": "#E9D16C", 111 | "inputValidation.warningForeground": "#0D1117", 112 | "list.activeSelectionBackground": "#A9B2C333", 113 | "list.activeSelectionForeground": "#ffffff", 114 | "list.errorForeground": "#D74E42", 115 | "list.focusBackground": "#A9B2C333", 116 | "list.hoverBackground": "#A9B2C31A", 117 | "list.inactiveFocusOutline": "#5F6672", 118 | "list.inactiveSelectionBackground": "#A9B2C333", 119 | "list.inactiveSelectionForeground": "#C6CCD7", 120 | "list.warningForeground": "#E9D16C", 121 | "minimap.findMatchHighlight": "#1085FF", 122 | "minimap.selectionHighlight": "#C6CCD7", 123 | "minimapGutter.addedBackground": "#98C379", 124 | "minimapGutter.deletedBackground": "#E06C75", 125 | "minimapGutter.modifiedBackground": "#D19A66", 126 | "notificationCenter.border": "#0D1117", 127 | "notificationCenterHeader.background": "#181A1F", 128 | "notifications.background": "#181A1F", 129 | "notifications.border": "#0D1117", 130 | "notificationToast.border": "#0D1117", 131 | "panel.background": "#181A1F", 132 | "panel.border": "#0D1117", 133 | "panelTitle.inactiveForeground": "#5F6672", 134 | "peekView.border": "#1085FF", 135 | "peekViewEditor.background": "#181A1F", 136 | "peekViewEditor.matchHighlightBackground": "#A9B2C333", 137 | "peekViewResult.background": "#181A1F", 138 | "peekViewResult.matchHighlightBackground": "#A9B2C333", 139 | "peekViewResult.selectionBackground": "#A9B2C31A", 140 | "peekViewResult.selectionForeground": "#C6CCD7", 141 | "peekViewTitle.background": "#181A1F", 142 | "sash.hoverBorder": "#A9B2C333", 143 | "scrollbar.shadow": "#00000000", 144 | "scrollbarSlider.activeBackground": "#A9B2C333", 145 | "scrollbarSlider.background": "#A9B2C31A", 146 | "scrollbarSlider.hoverBackground": "#A9B2C333", 147 | "sideBar.background": "#181A1F", 148 | "sideBar.border": "#0D1117", 149 | "sideBar.foreground": "#C6CCD7", 150 | "sideBarSectionHeader.background": "#21252B", 151 | "statusBar.background": "#21252B", 152 | "statusBar.border": "#0D1117", 153 | "statusBar.debuggingBackground": "#21252B", 154 | "statusBar.debuggingBorder": "#56B6C2", 155 | "statusBar.debuggingForeground": "#A9B2C3", 156 | "statusBar.focusBorder": "#A9B2C3", 157 | "statusBar.foreground": "#A9B2C3", 158 | "statusBar.noFolderBackground": "#181A1F", 159 | "statusBarItem.activeBackground": "#0D1117", 160 | "statusBarItem.errorBackground": "#21252B", 161 | "statusBarItem.errorForeground": "#D74E42", 162 | "statusBarItem.focusBorder": "#A9B2C3", 163 | "statusBarItem.hoverBackground": "#181A1F", 164 | "statusBarItem.hoverForeground": "#A9B2C3", 165 | "statusBarItem.remoteBackground": "#21252B", 166 | "statusBarItem.remoteForeground": "#B57EDC", 167 | "statusBarItem.warningBackground": "#21252B", 168 | "statusBarItem.warningForeground": "#E9D16C", 169 | "tab.activeBackground": "#21252B", 170 | "tab.activeBorderTop": "#1085FF", 171 | "tab.activeForeground": "#C6CCD7", 172 | "tab.border": "#0D1117", 173 | "tab.inactiveBackground": "#181A1F", 174 | "tab.inactiveForeground": "#5F6672", 175 | "tab.lastPinnedBorder": "#A9B2C333", 176 | "terminal.ansiBlack": "#5F6672", 177 | "terminal.ansiBlue": "#61AFEF", 178 | "terminal.ansiBrightBlack": "#5F6672", 179 | "terminal.ansiBrightBlue": "#61AFEF", 180 | "terminal.ansiBrightCyan": "#56B6C2", 181 | "terminal.ansiBrightGreen": "#98C379", 182 | "terminal.ansiBrightMagenta": "#B57EDC", 183 | "terminal.ansiBrightRed": "#E06C75", 184 | "terminal.ansiBrightWhite": "#A9B2C3", 185 | "terminal.ansiBrightYellow": "#E5C07B", 186 | "terminal.ansiCyan": "#56B6C2", 187 | "terminal.ansiGreen": "#98C379", 188 | "terminal.ansiMagenta": "#B57EDC", 189 | "terminal.ansiRed": "#E06C75", 190 | "terminal.ansiWhite": "#A9B2C3", 191 | "terminal.ansiYellow": "#E5C07B", 192 | "terminal.foreground": "#A9B2C3", 193 | "titleBar.activeBackground": "#21252B", 194 | "titleBar.activeForeground": "#C6CCD7", 195 | "titleBar.border": "#0D1117", 196 | "titleBar.inactiveBackground": "#21252B", 197 | "titleBar.inactiveForeground": "#5F6672", 198 | "toolbar.hoverBackground": "#A9B2C333", 199 | "widget.shadow": "#00000000" 200 | }, 201 | "tokenColors": [ 202 | { 203 | "scope": ["comment", "punctuation.definition.comment", "source.diff"], 204 | "settings": { 205 | "foreground": "#5F6672" 206 | } 207 | }, 208 | { 209 | "scope": [ 210 | "entity.name.function", 211 | "support.function", 212 | "meta.diff.range", 213 | "punctuation.definition.range.diff" 214 | ], 215 | "settings": { 216 | "foreground": "#B57EDC" 217 | } 218 | }, 219 | { 220 | "scope": [ 221 | "keyword", 222 | "punctuation.definition.keyword", 223 | "variable.language", 224 | "markup.deleted", 225 | "meta.diff.header.from-file", 226 | "punctuation.definition.deleted", 227 | "punctuation.definition.from-file.diff" 228 | ], 229 | "settings": { 230 | "foreground": "#E06C75" 231 | } 232 | }, 233 | { 234 | "scope": ["constant", "support.constant"], 235 | "settings": { 236 | "foreground": "#56B6C2" 237 | } 238 | }, 239 | { 240 | "scope": [ 241 | "storage", 242 | "support.class", 243 | "entity.name.namespace", 244 | "meta.diff.header" 245 | ], 246 | "settings": { 247 | "foreground": "#61AFEF" 248 | } 249 | }, 250 | { 251 | "scope": [ 252 | "markup.inline.raw.string", 253 | "string", 254 | "markup.inserted", 255 | "punctuation.definition.inserted", 256 | "meta.diff.header.to-file", 257 | "punctuation.definition.to-file.diff" 258 | ], 259 | "settings": { 260 | "foreground": "#98C379" 261 | } 262 | }, 263 | { 264 | "scope": [ 265 | "entity.name.section", 266 | "entity.name.tag", 267 | "entity.name.type", 268 | "support.type" 269 | ], 270 | "settings": { 271 | "foreground": "#E5C07B" 272 | } 273 | }, 274 | { 275 | "scope": ["support.type.property-name", "support.variable", "variable"], 276 | "settings": { 277 | "foreground": "#C6CCD7" 278 | } 279 | }, 280 | { 281 | "scope": [ 282 | "entity.other", 283 | "punctuation.definition.entity", 284 | "support.other" 285 | ], 286 | "settings": { 287 | "foreground": "#D19A66" 288 | } 289 | }, 290 | { 291 | "scope": ["meta.brace", "punctuation"], 292 | "settings": { 293 | "foreground": "#5F6672" 294 | } 295 | }, 296 | { 297 | "name": "bold", 298 | "scope": [ 299 | "markup.bold", 300 | "punctuation.definition.bold", 301 | "entity.other.attribute-name.id" 302 | ], 303 | "settings": { 304 | "fontStyle": "bold" 305 | } 306 | }, 307 | { 308 | "name": "italic", 309 | "scope": ["comment", "markup.italic", "punctuation.definition.italic"], 310 | "settings": { 311 | "fontStyle": "italic" 312 | } 313 | } 314 | ] 315 | } 316 | -------------------------------------------------------------------------------- /themes/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "vscode://schemas/color-theme", 3 | "name": "Plastic", 4 | "type": "dark", 5 | "semanticHighlighting": true, 6 | "semanticTokenColors": {}, 7 | "colors": { 8 | "activityBar.activeBorder": "#1085FF", 9 | "activityBar.background": "#21252B", 10 | "activityBar.border": "#0D1117", 11 | "activityBar.foreground": "#C6CCD7", 12 | "activityBar.inactiveForeground": "#5F6672", 13 | "activityBarBadge.background": "#E06C75", 14 | "activityBarBadge.foreground": "#ffffff", 15 | "breadcrumb.focusForeground": "#C6CCD7", 16 | "breadcrumb.foreground": "#5F6672", 17 | "button.background": "#E06C75", 18 | "button.foreground": "#ffffff", 19 | "button.hoverBackground": "#E48189", 20 | "button.secondaryBackground": "#0D1117", 21 | "button.secondaryForeground": "#ffffff", 22 | "checkbox.background": "#61AFEF", 23 | "checkbox.foreground": "#ffffff", 24 | "contrastBorder": "#0D1117", 25 | "debugToolBar.background": "#181A1F", 26 | "diffEditor.border": "#0D1117", 27 | "diffEditor.diagonalFill": "#0D1117", 28 | "diffEditor.insertedLineBackground": "#CBF6AC0D", 29 | "diffEditor.insertedTextBackground": "#CBF6AC1A", 30 | "diffEditor.removedLineBackground": "#FF9FA80D", 31 | "diffEditor.removedTextBackground": "#FF9FA81A", 32 | "dropdown.background": "#181A1F", 33 | "dropdown.border": "#0D1117", 34 | "editor.background": "#21252B", 35 | "editor.findMatchBackground": "#00000000", 36 | "editor.findMatchBorder": "#1085FF", 37 | "editor.findMatchHighlightBackground": "#00000000", 38 | "editor.findMatchHighlightBorder": "#C6CCD7", 39 | "editor.foreground": "#A9B2C3", 40 | "editor.lineHighlightBackground": "#A9B2C31A", 41 | "editor.lineHighlightBorder": "#00000000", 42 | "editor.linkedEditingBackground": "#0D1117", 43 | "editor.rangeHighlightBorder": "#C6CCD7", 44 | "editor.selectionBackground": "#A9B2C333", 45 | "editor.selectionHighlightBackground": "#A9B2C31A", 46 | "editor.selectionHighlightBorder": "#C6CCD7", 47 | "editor.wordHighlightBackground": "#00000000", 48 | "editor.wordHighlightBorder": "#1085FF", 49 | "editor.wordHighlightStrongBackground": "#00000000", 50 | "editor.wordHighlightStrongBorder": "#1085FF", 51 | "editorBracketHighlight.foreground1": "#A9B2C3", 52 | "editorBracketHighlight.foreground2": "#61AFEF", 53 | "editorBracketHighlight.foreground3": "#E5C07B", 54 | "editorBracketHighlight.foreground4": "#E06C75", 55 | "editorBracketHighlight.foreground5": "#98C379", 56 | "editorBracketHighlight.foreground6": "#B57EDC", 57 | "editorBracketHighlight.unexpectedBracket.foreground": "#D74E42", 58 | "editorBracketMatch.background": "#00000000", 59 | "editorBracketMatch.border": "#1085FF", 60 | "editorCursor.foreground": "#A9B2C3", 61 | "editorError.foreground": "#D74E42", 62 | "editorGroup.border": "#0D1117", 63 | "editorGroup.emptyBackground": "#181A1F", 64 | "editorGroupHeader.tabsBackground": "#181A1F", 65 | "editorGutter.addedBackground": "#98C379", 66 | "editorGutter.deletedBackground": "#E06C75", 67 | "editorGutter.modifiedBackground": "#D19A66", 68 | "editorHoverWidget.background": "#181A1F", 69 | "editorHoverWidget.border": "#1085FF", 70 | "editorIndentGuide.activeBackground": "#A9B2C333", 71 | "editorIndentGuide.background": "#0D1117", 72 | "editorInfo.foreground": "#1085FF", 73 | "editorInlayHint.background": "#00000000", 74 | "editorInlayHint.foreground": "#5F6672", 75 | "editorLightBulb.foreground": "#E9D16C", 76 | "editorLightBulbAutoFix.foreground": "#1085FF", 77 | "editorLineNumber.activeForeground": "#C6CCD7", 78 | "editorLineNumber.foreground": "#5F6672", 79 | "editorOverviewRuler.addedForeground": "#98C379", 80 | "editorOverviewRuler.border": "#0D1117", 81 | "editorOverviewRuler.deletedForeground": "#E06C75", 82 | "editorOverviewRuler.errorForeground": "#D74E42", 83 | "editorOverviewRuler.findMatchForeground": "#1085FF", 84 | "editorOverviewRuler.infoForeground": "#1085FF", 85 | "editorOverviewRuler.modifiedForeground": "#D19A66", 86 | "editorOverviewRuler.warningForeground": "#E9D16C", 87 | "editorRuler.foreground": "#0D1117", 88 | "editorStickyScroll.background": "#181A1F", 89 | "editorStickyScrollHover.background": "#21252B", 90 | "editorSuggestWidget.background": "#181A1F", 91 | "editorSuggestWidget.border": "#1085FF", 92 | "editorSuggestWidget.selectedBackground": "#A9B2C31A", 93 | "editorWarning.foreground": "#E9D16C", 94 | "editorWhitespace.foreground": "#A9B2C31A", 95 | "editorWidget.background": "#181A1F", 96 | "errorForeground": "#D74E42", 97 | "focusBorder": "#1085FF", 98 | "gitDecoration.deletedResourceForeground": "#E06C75", 99 | "gitDecoration.ignoredResourceForeground": "#5F6672", 100 | "gitDecoration.modifiedResourceForeground": "#D19A66", 101 | "gitDecoration.untrackedResourceForeground": "#98C379", 102 | "input.background": "#0D1117", 103 | "inputOption.activeBorder": "#1085FF", 104 | "inputValidation.errorBackground": "#D74E42", 105 | "inputValidation.errorBorder": "#D74E42", 106 | "inputValidation.infoBackground": "#1085FF", 107 | "inputValidation.infoBorder": "#1085FF", 108 | "inputValidation.infoForeground": "#0D1117", 109 | "inputValidation.warningBackground": "#E9D16C", 110 | "inputValidation.warningBorder": "#E9D16C", 111 | "inputValidation.warningForeground": "#0D1117", 112 | "list.activeSelectionBackground": "#A9B2C333", 113 | "list.activeSelectionForeground": "#ffffff", 114 | "list.errorForeground": "#D74E42", 115 | "list.focusBackground": "#A9B2C333", 116 | "list.hoverBackground": "#A9B2C31A", 117 | "list.inactiveFocusOutline": "#5F6672", 118 | "list.inactiveSelectionBackground": "#A9B2C333", 119 | "list.inactiveSelectionForeground": "#C6CCD7", 120 | "list.warningForeground": "#E9D16C", 121 | "minimap.findMatchHighlight": "#1085FF", 122 | "minimap.selectionHighlight": "#C6CCD7", 123 | "minimapGutter.addedBackground": "#98C379", 124 | "minimapGutter.deletedBackground": "#E06C75", 125 | "minimapGutter.modifiedBackground": "#D19A66", 126 | "notificationCenter.border": "#0D1117", 127 | "notificationCenterHeader.background": "#181A1F", 128 | "notifications.background": "#181A1F", 129 | "notifications.border": "#0D1117", 130 | "notificationToast.border": "#0D1117", 131 | "panel.background": "#181A1F", 132 | "panel.border": "#0D1117", 133 | "panelTitle.inactiveForeground": "#5F6672", 134 | "peekView.border": "#1085FF", 135 | "peekViewEditor.background": "#181A1F", 136 | "peekViewEditor.matchHighlightBackground": "#A9B2C333", 137 | "peekViewResult.background": "#181A1F", 138 | "peekViewResult.matchHighlightBackground": "#A9B2C333", 139 | "peekViewResult.selectionBackground": "#A9B2C31A", 140 | "peekViewResult.selectionForeground": "#C6CCD7", 141 | "peekViewTitle.background": "#181A1F", 142 | "sash.hoverBorder": "#A9B2C333", 143 | "scrollbar.shadow": "#00000000", 144 | "scrollbarSlider.activeBackground": "#A9B2C333", 145 | "scrollbarSlider.background": "#A9B2C31A", 146 | "scrollbarSlider.hoverBackground": "#A9B2C333", 147 | "sideBar.background": "#181A1F", 148 | "sideBar.border": "#0D1117", 149 | "sideBar.foreground": "#C6CCD7", 150 | "sideBarSectionHeader.background": "#21252B", 151 | "statusBar.background": "#21252B", 152 | "statusBar.border": "#0D1117", 153 | "statusBar.debuggingBackground": "#21252B", 154 | "statusBar.debuggingBorder": "#56B6C2", 155 | "statusBar.debuggingForeground": "#A9B2C3", 156 | "statusBar.focusBorder": "#A9B2C3", 157 | "statusBar.foreground": "#A9B2C3", 158 | "statusBar.noFolderBackground": "#181A1F", 159 | "statusBarItem.activeBackground": "#0D1117", 160 | "statusBarItem.errorBackground": "#21252B", 161 | "statusBarItem.errorForeground": "#D74E42", 162 | "statusBarItem.focusBorder": "#A9B2C3", 163 | "statusBarItem.hoverBackground": "#181A1F", 164 | "statusBarItem.hoverForeground": "#A9B2C3", 165 | "statusBarItem.remoteBackground": "#21252B", 166 | "statusBarItem.remoteForeground": "#B57EDC", 167 | "statusBarItem.warningBackground": "#21252B", 168 | "statusBarItem.warningForeground": "#E9D16C", 169 | "tab.activeBackground": "#21252B", 170 | "tab.activeBorderTop": "#1085FF", 171 | "tab.activeForeground": "#C6CCD7", 172 | "tab.border": "#0D1117", 173 | "tab.inactiveBackground": "#181A1F", 174 | "tab.inactiveForeground": "#5F6672", 175 | "tab.lastPinnedBorder": "#A9B2C333", 176 | "terminal.ansiBlack": "#5F6672", 177 | "terminal.ansiBlue": "#61AFEF", 178 | "terminal.ansiBrightBlack": "#5F6672", 179 | "terminal.ansiBrightBlue": "#61AFEF", 180 | "terminal.ansiBrightCyan": "#56B6C2", 181 | "terminal.ansiBrightGreen": "#98C379", 182 | "terminal.ansiBrightMagenta": "#B57EDC", 183 | "terminal.ansiBrightRed": "#E06C75", 184 | "terminal.ansiBrightWhite": "#A9B2C3", 185 | "terminal.ansiBrightYellow": "#E5C07B", 186 | "terminal.ansiCyan": "#56B6C2", 187 | "terminal.ansiGreen": "#98C379", 188 | "terminal.ansiMagenta": "#B57EDC", 189 | "terminal.ansiRed": "#E06C75", 190 | "terminal.ansiWhite": "#A9B2C3", 191 | "terminal.ansiYellow": "#E5C07B", 192 | "terminal.foreground": "#A9B2C3", 193 | "titleBar.activeBackground": "#21252B", 194 | "titleBar.activeForeground": "#C6CCD7", 195 | "titleBar.border": "#0D1117", 196 | "titleBar.inactiveBackground": "#21252B", 197 | "titleBar.inactiveForeground": "#5F6672", 198 | "toolbar.hoverBackground": "#A9B2C333", 199 | "widget.shadow": "#00000000" 200 | }, 201 | "tokenColors": [ 202 | { 203 | "scope": ["comment", "punctuation.definition.comment", "source.diff"], 204 | "settings": { 205 | "foreground": "#5F6672" 206 | } 207 | }, 208 | { 209 | "scope": [ 210 | "entity.name.function", 211 | "support.function", 212 | "meta.diff.range", 213 | "punctuation.definition.range.diff" 214 | ], 215 | "settings": { 216 | "foreground": "#B57EDC" 217 | } 218 | }, 219 | { 220 | "scope": [ 221 | "keyword", 222 | "punctuation.definition.keyword", 223 | "variable.language", 224 | "markup.deleted", 225 | "meta.diff.header.from-file", 226 | "punctuation.definition.deleted", 227 | "punctuation.definition.from-file.diff" 228 | ], 229 | "settings": { 230 | "foreground": "#E06C75" 231 | } 232 | }, 233 | { 234 | "scope": ["constant", "support.constant"], 235 | "settings": { 236 | "foreground": "#56B6C2" 237 | } 238 | }, 239 | { 240 | "scope": [ 241 | "storage", 242 | "support.class", 243 | "entity.name.namespace", 244 | "meta.diff.header" 245 | ], 246 | "settings": { 247 | "foreground": "#61AFEF" 248 | } 249 | }, 250 | { 251 | "scope": [ 252 | "markup.inline.raw.string", 253 | "string", 254 | "markup.inserted", 255 | "punctuation.definition.inserted", 256 | "meta.diff.header.to-file", 257 | "punctuation.definition.to-file.diff" 258 | ], 259 | "settings": { 260 | "foreground": "#98C379" 261 | } 262 | }, 263 | { 264 | "scope": [ 265 | "entity.name.section", 266 | "entity.name.tag", 267 | "entity.name.type", 268 | "support.type" 269 | ], 270 | "settings": { 271 | "foreground": "#E5C07B" 272 | } 273 | }, 274 | { 275 | "scope": ["support.type.property-name", "support.variable", "variable"], 276 | "settings": { 277 | "foreground": "#C6CCD7" 278 | } 279 | }, 280 | { 281 | "scope": [ 282 | "entity.other", 283 | "punctuation.definition.entity", 284 | "support.other" 285 | ], 286 | "settings": { 287 | "foreground": "#D19A66" 288 | } 289 | }, 290 | { 291 | "scope": ["meta.brace", "punctuation"], 292 | "settings": { 293 | "foreground": "#A9B2C3" 294 | } 295 | }, 296 | { 297 | "name": "bold", 298 | "scope": [ 299 | "markup.bold", 300 | "punctuation.definition.bold", 301 | "entity.other.attribute-name.id" 302 | ], 303 | "settings": { 304 | "fontStyle": "bold" 305 | } 306 | }, 307 | { 308 | "name": "italic", 309 | "scope": ["comment", "markup.italic", "punctuation.definition.italic"], 310 | "settings": { 311 | "fontStyle": "italic" 312 | } 313 | } 314 | ] 315 | } 316 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "lib": ["ESNext"] 6 | }, 7 | "exclude": ["samples"] 8 | } 9 | -------------------------------------------------------------------------------- /website/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /website/pages/index.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Plastic Theme 5 | 9 | 10 | 11 | 16 | 22 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 42 | 43 | 44 | 45 | 46 | 50 | 55 | 56 | 57 |
58 |
61 |
62 | 69 |

Plastic

70 |

71 |
A simple theme
72 |
for VSCode
73 |

74 |
75 |
76 | Screenshot 81 |
82 |
83 | 84 |
85 | 98 |
99 | 111 |
112 |
113 | 114 |
115 | 116 |
117 |

Palette

118 |

Syntax

119 |
122 |
125 |

Keywords

126 |
127 |
Sunglo
128 |
#E06C75
129 |
130 |
131 |
if
132 |
import
133 |
return
134 |
135 |
136 |
139 |

Constants

140 |
143 |
Fountain Blue
144 |
#56B6C2
145 |
146 |
147 |
1234
148 |
undefined
149 |
true
150 |
151 |
152 |
155 |

Storage

156 |
159 |
Cornflower Blue
160 |
#61AFEF
161 |
162 |
163 |
const
164 |
let
165 |
class
166 |
167 |
168 |
171 |

String Literals

172 |
175 |
Olivine
176 |
#98C379
177 |
178 |
179 |
"lorem"
180 |
'ipsum'
181 |
`dolor`
182 |
183 |
184 |
187 |

Attributes & Props

188 |
191 |
Whiskey
192 |
#D19A66
193 |
194 |
195 |
href
196 |
className
197 |
src
198 |
199 |
200 |
203 |

Tags & Types

204 |
207 |
Harvest Gold
208 |
#E5C07B
209 |
210 |
211 |
div
212 |
span
213 |
boolean
214 |
215 |
216 |
219 |

Function Names

220 |
223 |
Lavender
224 |
#B57EDC
225 |
226 |
227 |
function add() {}
228 |
doThing()
229 |
console.log()
230 |
231 |
232 |
235 |

Comments

236 |
239 |
Shuttle Gray
240 |
#5F6672
241 |
242 |
243 |
// Comment
244 |
/* TODO comment */
245 |
#!/bin/bash
246 |
247 |
248 |
251 |

Text & Punctuation

252 |
255 |
Cadet Blue
256 |
#A9B2C3
257 |
258 |
259 |
{}()[]"'`!<>
260 |
Lorem ipsum dolor.
261 |
Consectetur adipiscing.
262 |
263 |
264 |
267 |

Variables

268 |
269 |
Ghost
270 |
#C6CCD7
271 |
272 |
273 |
const aVariable = true
274 |
275 |
276 |
277 |

UI

278 |
281 |
284 |

Borders

285 |
286 |
Bunker
287 |
#0D1117
288 |
289 |
290 |
293 |

Background

294 |
297 |
Woodsmoke
298 |
#181A1F
299 |
300 |
301 |
304 |

Workspace

305 |
306 |
Shark
307 |
#21252B
308 |
309 |
310 |
313 |

Information

314 |
317 |
Dodger Blue
318 |
#1085FF
319 |
320 |
321 |
324 |

Warning

325 |
328 |
Rob Roy
329 |
#E9D16C
330 |
331 |
332 |
335 |

Error

336 |
339 |
Valencia
340 |
#D74E42
341 |
342 |
343 |
344 |

ANSI

345 |

346 | Being a simple theme, Plastic does not prescribe bright ANSI colours. 347 | It is recommended to use bold text for emphasis. 348 |

349 |
352 |
355 |

ANSI Black

356 |
359 |
Shuttle Gray
360 |
#5F6672
361 |
362 |
363 |
Normal text
364 |
Bold text
365 |
366 |
367 |
370 |

ANSI Red

371 |
372 |
Sunglo
373 |
#E06C75
374 |
375 |
376 |
Normal text
377 |
Bold text
378 |
379 |
380 |
383 |

ANSI Green

384 |
387 |
Olivine
388 |
#98C379
389 |
390 |
391 |
Normal text
392 |
Bold text
393 |
394 |
395 |
398 |

ANSI Yellow

399 |
402 |
Harvest Gold
403 |
#E5C07B
404 |
405 |
406 |
Normal text
407 |
Bold text
408 |
409 |
410 |
413 |

ANSI Blue

414 |
417 |
Cornflower Blue
418 |
#61AFEF
419 |
420 |
421 |
Normal text
422 |
Bold text
423 |
424 |
425 |
428 |

ANSI Magenta

429 |
432 |
Lavender
433 |
#B57EDC
434 |
435 |
436 |
Normal text
437 |
Bold text
438 |
439 |
440 |
443 |

ANSI Cyan

444 |
447 |
Fountain Blue
448 |
#56B6C2
449 |
450 |
451 |
Normal text
452 |
Bold text
453 |
454 |
455 |
458 |

ANSI White

459 |
462 |
Cadet Blue
463 |
#A9B2C3
464 |
465 |
466 |
Normal text
467 |
Bold text
468 |
469 |
470 |
471 |
472 | 473 |
474 | 475 |
476 |

Other Apps

477 |

478 | These are community maintained themes. Please submit a PR for any apps that support the Plastic theme. 482 |

483 |
    484 | { 485 | [ 486 | { 487 | name: 'Warp', 488 | url: 'https://github.com/warpdotdev/themes/blob/main/standard/plastic.yaml', 489 | }, 490 | ].map(({ name, url }) => ( 491 |
  • 492 | 493 | {name} 494 | 495 |
  • 496 | )) 497 | } 498 |
499 |
500 |
501 | 515 | 516 | 517 | -------------------------------------------------------------------------------- /website/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon.ico -------------------------------------------------------------------------------- /website/public/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /website/public/favicon/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/android-chrome-512x512.png -------------------------------------------------------------------------------- /website/public/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /website/public/favicon/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #ffffff 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /website/public/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /website/public/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /website/public/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/favicon.ico -------------------------------------------------------------------------------- /website/public/favicon/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/mstile-144x144.png -------------------------------------------------------------------------------- /website/public/favicon/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/mstile-150x150.png -------------------------------------------------------------------------------- /website/public/favicon/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/mstile-310x150.png -------------------------------------------------------------------------------- /website/public/favicon/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/mstile-310x310.png -------------------------------------------------------------------------------- /website/public/favicon/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/favicon/mstile-70x70.png -------------------------------------------------------------------------------- /website/public/favicon/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /website/public/favicon/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "background_color": "#ffffff", 3 | "display": "standalone", 4 | "icons": [ 5 | { 6 | "sizes": "192x192", 7 | "src": "/favicon/android-chrome-192x192.png?v=WGNOBL3XeM", 8 | "type": "image/png" 9 | }, 10 | { 11 | "sizes": "512x512", 12 | "src": "/favicon/android-chrome-512x512.png?v=WGNOBL3XeM", 13 | "type": "image/png" 14 | } 15 | ], 16 | "name": "Plastic", 17 | "short_name": "Plastic", 18 | "theme_color": "#ffffff" 19 | } 20 | -------------------------------------------------------------------------------- /website/public/images/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/plastic/e8d79934be9f3016da79f265e12bad44872212a4/website/public/images/code.png --------------------------------------------------------------------------------