From 7d7c32a04ab207667264e4a4df48b7d2fd3d1404 Mon Sep 17 00:00:00 2001 From: Simon Winter Date: Mon, 15 Apr 2024 17:26:43 +1200 Subject: [PATCH 1/5] fix: initial setup of the light theme looking at colours and icons --- README.md | 13 +++++++++++++ icons/images/stencila-icon-32x32.svg | 13 +++++++++++++ icons/stencila-icon-theme.json | 12 ++++++++++++ package.json | 15 +++++++++++++++ src/extension.ts | 5 +++++ themes/stencila-light-color-theme.json | 18 ++++++++++++++++++ 6 files changed, 76 insertions(+) create mode 100644 icons/images/stencila-icon-32x32.svg create mode 100644 icons/stencila-icon-theme.json create mode 100644 themes/stencila-light-color-theme.json diff --git a/README.md b/README.md index 66f813b..ecb4043 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,19 @@ This is the README for your extension "stencila". After writing up a brief description, we recommend including the following sections. +## Testing locally + +In order to test the extension in `VSCode`, you will need to do the following: + +1. run `npm install` +2. run `npm run compile` +3. open a `.smd` file (e.g. `src/fixtures/syntax.smd`) & hit `F5` to open a + debug session with the extension installed. + +> [!WARNING] +> The following sections are the ones defined by the initial template. We intend +> to rewrite as we go. + ## Features Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. diff --git a/icons/images/stencila-icon-32x32.svg b/icons/images/stencila-icon-32x32.svg new file mode 100644 index 0000000..6ea720b --- /dev/null +++ b/icons/images/stencila-icon-32x32.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/icons/stencila-icon-theme.json b/icons/stencila-icon-theme.json new file mode 100644 index 0000000..0462e91 --- /dev/null +++ b/icons/stencila-icon-theme.json @@ -0,0 +1,12 @@ +{ + "iconDefinitions": { + "_stencila_light": { + "iconPath": "./images/stencila-icon-32x32.svg" + } + }, + "light": { + "fileExtensions": { + "smd": "_stencila_light" + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index e0b4760..f031d7a 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,21 @@ "language": "smd", "path": "./syntaxes/smd/snippets.json" } + ], + "themes": [ + { + "id": "Stencila Light", + "label": "Stencila light", + "uiTheme": "vs", + "path": "./themes/stencila-light-color-theme.json" + } + ], + "iconThemes": [ + { + "id": "stencila", + "label": "Stencila Icons", + "path": "./icons/stencila-icon-theme.json" + } ] }, "scripts": { diff --git a/src/extension.ts b/src/extension.ts index eb22c2d..c5bdf1b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,6 +19,11 @@ export function activate(context: vscode.ExtensionContext) { vscode.window.showInformationMessage('Hello World from Stencila!'); }); + // Define the default theme for this extension. + // Inside your extension's activation code + vscode.workspace.getConfiguration('workbench') + .update('colorTheme', 'Stencila Light', vscode.ConfigurationTarget.Global); + context.subscriptions.push(disposable); } diff --git a/themes/stencila-light-color-theme.json b/themes/stencila-light-color-theme.json new file mode 100644 index 0000000..90d195a --- /dev/null +++ b/themes/stencila-light-color-theme.json @@ -0,0 +1,18 @@ +{ + "name": "Stencila Light", + "colors": { + "activityBar.activeBorder": "#2568EF", + "activityBar.background": "#F5F5F5", + "activityBar.dropBorder": "#2568EF", + "activityBar.foreground": "#2568EF", + "activityBar.inactiveForeground": "#666666", + "activityBarBadge.background": "#2568EF", + "activityBarBadge.foreground": "#ffffff", + "statusBar.background": "#2568EF", + "statusBar.border": "#2568EF", + "statusBar.foreground": "#FFFFFF", + "statusBarItem.hoverBackground": "#215DD7", + "statusBar.debuggingBackground": "#2568EF", + "statusBar.noFolderBackground": "#2568EF" + } +} \ No newline at end of file From 9bdc6b372c066205ce244448210d105cc3c5ceb3 Mon Sep 17 00:00:00 2001 From: Simon Winter Date: Tue, 16 Apr 2024 17:07:39 +1200 Subject: [PATCH 2/5] fix: added syntax highlighting to the light theme --- src/fixtures/syntax.smd | 62 ++++++++++++++ syntaxes/smd/configuration.json | 2 +- syntaxes/smd/tmGrammar.yaml | 42 +++++---- themes/stencila-light-color-theme.json | 114 ++++++++++++++++++++++++- 4 files changed, 198 insertions(+), 22 deletions(-) diff --git a/src/fixtures/syntax.smd b/src/fixtures/syntax.smd index 3baa30a..15b2619 100644 --- a/src/fixtures/syntax.smd +++ b/src/fixtures/syntax.smd @@ -36,11 +36,73 @@ The area of a circle is $2 \pi r^2$. ```js // Javascript code function foo(){} + +import { VIEWS } from '../views/views' + +import './main.css' + +import './shoelace' + +/** + * Application Wrapper + * + * Wraps the application in the `app-chrome`. Contains the main header and + * footer. + */ +@customElement('stencila-main-app') +@withTwind() +export class App extends LitElement { + /** + * The currently open documents + * + * This property is initialized (as an HTML attribute) with one document id, + * by the server, based on the URL path (including paths that resolved to main.*, + * index.*, or README.* in the home directory of the server (the directory it was started in)). + * + * While the app is running [document id, file name] pairs are added or removed + * from this list (e.g. by clicking on the directory tree, closing a tab). + * + * A list is used here (rather than say an object with `DocumentId` as the key) + * to allow for reordering of tabs by the user. + */ + @property({ type: Array }) + docs: (File & { docId: DocumentId })[] = [] + + /** + * The id of the document, in `docs`, that is currently active + */ + @state() + activeDoc: DocumentId | null + + /** + * The current view of the current document + * + * If there is no `view` attribute then this will be dynamically + * determined based on the maximum access level that the user has for + * the document. + */ + @property() + view?: DocumentView = 'live' +} ``` ```py # Python code def foo: pass +from stencila import _stencila + +async def from_string(string: str, format: str | None = "json") -> Node: + """ + Decode a Stencila Schema node from a string. + + Args: + string (str): The string to decode to a node. + format (Optional[str]): The format to decode from. Defaults to "json". + + Returns: + Node: A Stencila Schema node. + """ + return from_json(await _stencila.convert.from_string(string, {"format": format})) ``` ```r diff --git a/syntaxes/smd/configuration.json b/syntaxes/smd/configuration.json index d269163..c66f1d3 100644 --- a/syntaxes/smd/configuration.json +++ b/syntaxes/smd/configuration.json @@ -26,7 +26,7 @@ "folding": { "$comment": "Basic folding. More advanced folding to be provided by language server.", "markers": { - "start": "^:{3,}\\s*(if|for|with|insert|delete)", + "start": "^:{3,}\\s*(if|for|with|insert|delete|table|figure)", "end": "^:{3,}\\s*$" } }, diff --git a/syntaxes/smd/tmGrammar.yaml b/syntaxes/smd/tmGrammar.yaml index 6af7dd4..bedad0d 100644 --- a/syntaxes/smd/tmGrammar.yaml +++ b/syntaxes/smd/tmGrammar.yaml @@ -16,6 +16,7 @@ repository: block: patterns: # Order is important for matching! + - include: "#heading" - include: "#math-block" - include: "#code-chunk" - include: "#code-block" @@ -206,9 +207,9 @@ repository: $ captures: "1": { name: markup.heading } # semicolons - "2": { name: keyword.control } # do - "3": { name: punctuation.definition } # @ - "4": { name: variable.name } # assignee + "2": { name: meta.stencila.keyword.control } # do + "3": { name: meta.stencila.decorator.keyword } # @ + "4": { name: meta.stencila.decorator.keyword } # assignee "5": { name: comment.line } # message with-block: @@ -238,9 +239,9 @@ repository: )? \]\] captures: - "1": { name: keyword.control } # do - "2": { name: punctuation.definition } # @ - "3": { name: variable.name } # assignee + "1": { name: meta.stencila.keyword.control } # do + "2": { name: meta.stencila.decorator.keyword } # @ + "3": { name: meta.stencila.decorator.keyword } # assignee "4": { name: comment.line } # message "5": { name: keyword.control } # >> @@ -264,9 +265,9 @@ repository: $ captures: "1": { name: markup.heading } # semicolons - "2": { name: keyword.control } # insert - "3": { name: token.info-token } # accept - "4": { name: token.error-token } # reject + "2": { name: meta.stencila.keyword.control } # insert + "3": { name: meta.stencila.accept-token } # accept + "4": { name: meta.stencila.error-token } # reject insert-inline: name: meta.stencila.insert-inline @@ -279,7 +280,7 @@ repository: (.*?) \]\] captures: - "1": { name: keyword.control } # insert + "1": { name: meta.stencila.keyword.control } # insert delete-block: name: meta.stencila.delete-block @@ -300,8 +301,8 @@ repository: captures: "1": { name: markup.heading } # semicolons "2": { name: keyword.control } # delete - "3": { name: token.info-token } # accept - "4": { name: token.error-token } # reject + "3": { name: meta.stencila.accept-token } # accept + "4": { name: meta.stencila.error-token } # reject delete-inline: name: meta.stencila.delete-inline @@ -335,8 +336,8 @@ repository: captures: "1": { name: markup.heading } # semicolons "2": { name: keyword.control } # replace - "3": { name: token.info-token } # accept - "4": { name: token.error-token } # reject + "3": { name: meta.stencila.accept-token } # accept + "4": { name: meta.stencila.error-token } # reject replace-inline: name: meta.stencila.replace-inline @@ -361,8 +362,8 @@ repository: match: ^(:{3,})\s*(include)\s+(.*)$ captures: "1": { name: markup.heading } # semicolons - "2": { name: keyword.control } # include - "3": { name: variable.name } # source + "2": { name: meta.stencila.keyword.control } # include + "3": { name: meta.stencila.variable.name } # source ########## CallBlock ########## @@ -371,8 +372,8 @@ repository: match: ^(:{3,})\s*(call)\s+(.*)$ captures: "1": { name: markup.heading } # semicolons - "2": { name: keyword.control } # call - "3": { name: variable.name } # source + "2": { name: meta.stencila.keyword.control } # include + "3": { name: meta.stencila.variable.name } # source ########## IfBlock ########## @@ -476,6 +477,11 @@ repository: # The following grammar rules are taken from the VSCode builtin Markdown grammar at # https://github.com/microsoft/vscode-markdown-tm-grammar/blob/main/markdown.tmLanguage.base.yaml # usually with little modification, particularly to regular expressions. + heading: + name: meta.stencila.heading + match: (?:^|\G)[ ]{0,3}(#{1,6}\s+(.*?)(\s+#{1,6})?\s*)$ + patterns: + - { include: punctuation.definition.heading.markdown } paragraph: name: meta.stencila.paragraph diff --git a/themes/stencila-light-color-theme.json b/themes/stencila-light-color-theme.json index 90d195a..9fa5d59 100644 --- a/themes/stencila-light-color-theme.json +++ b/themes/stencila-light-color-theme.json @@ -1,4 +1,5 @@ { + "$schema": "vscode://schemas/color-theme", "name": "Stencila Light", "colors": { "activityBar.activeBorder": "#2568EF", @@ -8,11 +9,118 @@ "activityBar.inactiveForeground": "#666666", "activityBarBadge.background": "#2568EF", "activityBarBadge.foreground": "#ffffff", + "editorGutter.modifiedBackground": "#66FF66", + "editorGutter.addedBackground": "#BCFFBC", + "editorLineNumber.foreground": "#B0B0B0", + "editorLineNumber.activeForeground": "#2568EF", "statusBar.background": "#2568EF", "statusBar.border": "#2568EF", "statusBar.foreground": "#FFFFFF", "statusBarItem.hoverBackground": "#215DD7", "statusBar.debuggingBackground": "#2568EF", - "statusBar.noFolderBackground": "#2568EF" - } -} \ No newline at end of file + "statusBar.noFolderBackground": "#2568EF", + }, + "tokenColors": [{ + "scope": [ + "meta.embedded", + "comment.line", + "comment", + "support.type" + ], + "settings": { + "foreground": "#1B8951", + } + }, { + "scope": ["string"], + "settings": { + "foreground": "#8C1A40" + } + }, { + "scope": [ + "keyword.operator", + "meta.stencila.paragraph" + ], + "settings": { + "foreground": "#666666", + } + }, { + "scope": [ + "keyword.operator.star", + "meta.stencila" + ], + "settings": { + "foreground": "#171817", + } + }, { + "scope": [ + "meta.stencila.error-token", + "meta.stencila.instruction-inline", + "meta.stencila.parameter" + ], + "settings": { + "foreground": "#D94D7B", + } + }, { + "scope": [ + "constant.language", + "entity.name.tag.yaml", + "entity.name.type.js", + "keyword.other", + "meta.brace", + "meta.stencila.accept-token", + "meta.stencila.decorator.keyword", + "meta.stencila.variable.name", + "punctuation.separator.key-value.mapping.yaml", + "storage.type", + "storage", + ], + "settings": { + "foreground": "#2568EF", + } + }, { + "scope": [ + "meta.decorator.js", + "support.function" + ], + "settings": { + "foreground": "#5C8EF3", + } + }, { + "scope": [ + "meta.object-literal", + "meta.object.type", + "variable.object.property" + ], + "settings": { + "foreground": "#092D77", + } + }, { + "scope": [ + "keyword.control.flow", + "keyword.control.export", + "keyword.control.from", + "keyword.control.import", + "keyword.control.preamble.latex", + "meta.stencila.keyword.control", + ], + "settings": { + "foreground": "#7957D5" + } + }, { + "scope": [ + "entity.name.type.class", + "entity.other.inherited-class" + ], + "settings": { + "fontStyle": "italic" + } + }, { + "scope": [ + "meta.stencila.heading", + ], + "settings": { + "fontStyle": "underline" + } + }] +} + From 90d0a3699d66c0f576cf1160c3f1d12de9fbe7af Mon Sep 17 00:00:00 2001 From: Simon Winter Date: Wed, 17 Apr 2024 15:51:12 +1200 Subject: [PATCH 3/5] fix(theme): updated grammar to only use meta.stencila for defining new blocks all capture matches use x.x.stencila as a naming convention --- syntaxes/smd/configuration.json | 3 ++- syntaxes/smd/tmGrammar.yaml | 36 +++++++++++++------------- themes/stencila-light-color-theme.json | 10 +++---- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/syntaxes/smd/configuration.json b/syntaxes/smd/configuration.json index c66f1d3..e6ebfd9 100644 --- a/syntaxes/smd/configuration.json +++ b/syntaxes/smd/configuration.json @@ -11,7 +11,8 @@ { "open": "[", "close": "]" }, { "open": "(", "close": ")" }, { "open": "'", "close": "'", "notIn": ["string"] }, - { "open": "\"", "close": "\"", "notIn": ["string"] } + { "open": "\"", "close": "\"", "notIn": ["string"] }, + { "open": "```", "close": "```"} ], "surroundingPairs": [ { "open": "{", "close": "}" }, diff --git a/syntaxes/smd/tmGrammar.yaml b/syntaxes/smd/tmGrammar.yaml index bedad0d..41e53bc 100644 --- a/syntaxes/smd/tmGrammar.yaml +++ b/syntaxes/smd/tmGrammar.yaml @@ -207,9 +207,9 @@ repository: $ captures: "1": { name: markup.heading } # semicolons - "2": { name: meta.stencila.keyword.control } # do - "3": { name: meta.stencila.decorator.keyword } # @ - "4": { name: meta.stencila.decorator.keyword } # assignee + "2": { name: keyword.control.stencila } # do + "3": { name: decorator.keyword.stencila } # @ + "4": { name: decorator.keyword.stencila } # assignee "5": { name: comment.line } # message with-block: @@ -239,9 +239,9 @@ repository: )? \]\] captures: - "1": { name: meta.stencila.keyword.control } # do - "2": { name: meta.stencila.decorator.keyword } # @ - "3": { name: meta.stencila.decorator.keyword } # assignee + "1": { name: keyword.control.stencila } # do + "2": { name: decorator.keyword.stencila } # @ + "3": { name: decorator.keyword.stencila } # assignee "4": { name: comment.line } # message "5": { name: keyword.control } # >> @@ -265,9 +265,9 @@ repository: $ captures: "1": { name: markup.heading } # semicolons - "2": { name: meta.stencila.keyword.control } # insert - "3": { name: meta.stencila.accept-token } # accept - "4": { name: meta.stencila.error-token } # reject + "2": { name: keyword.control.stencila } # insert + "3": { name: accept.stencila } # accept + "4": { name: error.stencila } # reject insert-inline: name: meta.stencila.insert-inline @@ -280,7 +280,7 @@ repository: (.*?) \]\] captures: - "1": { name: meta.stencila.keyword.control } # insert + "1": { name: keyword.control.stencila } # insert delete-block: name: meta.stencila.delete-block @@ -301,8 +301,8 @@ repository: captures: "1": { name: markup.heading } # semicolons "2": { name: keyword.control } # delete - "3": { name: meta.stencila.accept-token } # accept - "4": { name: meta.stencila.error-token } # reject + "3": { name: accept.stencila } # accept + "4": { name: error.stencila } # reject delete-inline: name: meta.stencila.delete-inline @@ -336,8 +336,8 @@ repository: captures: "1": { name: markup.heading } # semicolons "2": { name: keyword.control } # replace - "3": { name: meta.stencila.accept-token } # accept - "4": { name: meta.stencila.error-token } # reject + "3": { name: accept.stencila } # accept + "4": { name: error.stencila } # reject replace-inline: name: meta.stencila.replace-inline @@ -362,8 +362,8 @@ repository: match: ^(:{3,})\s*(include)\s+(.*)$ captures: "1": { name: markup.heading } # semicolons - "2": { name: meta.stencila.keyword.control } # include - "3": { name: meta.stencila.variable.name } # source + "2": { name: keyword.control.stencila } # include + "3": { name: variable.name.stencila } # source ########## CallBlock ########## @@ -372,8 +372,8 @@ repository: match: ^(:{3,})\s*(call)\s+(.*)$ captures: "1": { name: markup.heading } # semicolons - "2": { name: meta.stencila.keyword.control } # include - "3": { name: meta.stencila.variable.name } # source + "2": { name: keyword.control.stencila } # include + "3": { name: variable.name.stencila } # source ########## IfBlock ########## diff --git a/themes/stencila-light-color-theme.json b/themes/stencila-light-color-theme.json index 9fa5d59..9a3ebea 100644 --- a/themes/stencila-light-color-theme.json +++ b/themes/stencila-light-color-theme.json @@ -53,7 +53,7 @@ } }, { "scope": [ - "meta.stencila.error-token", + "error.stencila", "meta.stencila.instruction-inline", "meta.stencila.parameter" ], @@ -67,9 +67,9 @@ "entity.name.type.js", "keyword.other", "meta.brace", - "meta.stencila.accept-token", - "meta.stencila.decorator.keyword", - "meta.stencila.variable.name", + "accept.stencila", + "decorator.stencila.keyword", + "variable.name.stencila", "punctuation.separator.key-value.mapping.yaml", "storage.type", "storage", @@ -101,7 +101,7 @@ "keyword.control.from", "keyword.control.import", "keyword.control.preamble.latex", - "meta.stencila.keyword.control", + "keyword.control.stencila", ], "settings": { "foreground": "#7957D5" From c649f16e57edca34f1e48af7b6a0c676dc772781 Mon Sep 17 00:00:00 2001 From: Simon Winter Date: Wed, 17 Apr 2024 15:55:34 +1200 Subject: [PATCH 4/5] docs(README): minor edits to docs --- README.md | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index ecb4043..e29bd94 100644 --- a/README.md +++ b/README.md @@ -42,23 +42,11 @@ This extension contributes the following settings: ## Known Issues -Calling out known issues can help limit users opening duplicate issues against your extension. -## Release Notes - -Users appreciate release notes as you update your extension. - -### 1.0.0 - -Initial release of ... -### 1.0.1 - -Fixed issue #. - -### 1.1.0 +## Release Notes -Added features X, Y, and Z. +See [the changelog](./CHANGELOG.md) --- @@ -67,18 +55,3 @@ Added features X, Y, and Z. Ensure that you've read through the extensions guidelines and follow the best practices for creating your extension. * [Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines) - -## Working with Markdown - -You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: - -* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux). -* Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux). -* Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets. - -## For more information - -* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) -* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) - -**Enjoy!** From 3ffad2a86279090c2036f2866f854bb9f97d944f Mon Sep 17 00:00:00 2001 From: vhe20 Date: Thu, 18 Apr 2024 14:51:53 +1200 Subject: [PATCH 5/5] feat(smd): adding snippets for elif and else blocks. --- syntaxes/smd/snippets.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/syntaxes/smd/snippets.json b/syntaxes/smd/snippets.json index 0595c6b..b871c4d 100644 --- a/syntaxes/smd/snippets.json +++ b/syntaxes/smd/snippets.json @@ -65,6 +65,16 @@ "prefix": ["::: if"], "body": ["::: if ${1:expression}", "", "$0", "", ":::"] }, + "Elif Block": { + "description": "Only show block content if the preceeding 'if' conditions are false and its own condition is true.", + "prefix": ["::: elif"], + "body": ["::: elif ${1:expression}", "", "$0", "", ":::"] + }, + "Else Block": { + "description": "Only show block content if none of the preceeding conditions are true.", + "prefix": ["::: else"], + "body": ["::: else", "", "$0", "", ":::"] + }, "For Block": { "description": "Repeat block content for each value of a variable in an expression.", "prefix": ["::: for"],