├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── README.md ├── img └── dart-logo.png ├── package.json ├── snippets ├── dart.json └── pubspec.json ├── src ├── dartAnalyzer.ts ├── dartFormat.ts ├── dartLintResult.ts ├── dartMode.ts ├── extension.ts └── pubCmd.ts ├── syntaxes └── dart.json ├── test ├── extension.test.ts ├── index.ts └── test.dart.txt ├── tsconfig.json ├── typings ├── node.d.ts └── vscode-typings.d.ts └── vsc-extension-quickstart.md /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.2.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], 11 | "stopOnEntry": false, 12 | "sourceMaps": true, 13 | "outDir": "${workspaceRoot}/src" 14 | }, 15 | { 16 | "name": "Launch Tests", 17 | "type": "extensionHost", 18 | "request": "launch", 19 | "runtimeExecutable": "${execPath}", 20 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], 21 | "stopOnEntry": false, 22 | "sourceMaps": true, 23 | "outDir": "${workspaceRoot}/test" 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version 10 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | // A task runner that calls a custom npm script that compiles the extension. 10 | { 11 | "version": "0.1.0", 12 | 13 | // we want to run npm 14 | "command": "npm", 15 | 16 | // the command is a shell script 17 | "isShellCommand": true, 18 | 19 | // show the output window only if unrecognized errors occur. 20 | "showOutput": "silent", 21 | 22 | // we run the custom script "compile" as defined in package.json 23 | "args": ["run", "compile", "--loglevel", "silent"], 24 | 25 | // The tsc compiler is started in watching mode 26 | "isWatching": true, 27 | 28 | // use the standard tsc in watch mode problem matcher to find compile problems in the output. 29 | "problemMatcher": "$tsc-watch" 30 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | typings/** 3 | out/test/** 4 | test/** 5 | src/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | vsc-extension-quickstart.md 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGLOG 2 | 3 | ## Deprecated 4 | 5 | - This extension is no longer maintained, please use [DartCode](https://marketplace.visualstudio.com/items?itemName=DanTup.dart-code) 6 | 7 | ## 0.1.0 8 | 9 | - Update dependencies version for VSCode v1.0.0 10 | - Bug fix [#3](https://github.com/platelk/vscode-dart/issues/3) 11 | 12 | ## 0.0.6 13 | 14 | - Bug fix [#2](https://github.com/platelk/vscode-dart/issues/2) 15 | 16 | 17 | ## 0.0.5 18 | 19 | - Adding `dartanalyzer` integration 20 | - Adding configuration to launch linter on save 21 | - Adding configuration to launch format on save 22 | 23 | 24 | ## 0.0.4 25 | 26 | - Changing logo 27 | - Changing theme 28 | - Adding command for formatting 29 | - Minor correction 30 | 31 | 32 | ## 0.0.3 33 | 34 | - Adding pubspec snippet 35 | - Adding `pub run` for the current document 36 | - Open result of `pub run` in an output window 37 | - Adding file format through `dartfmt` 38 | - Minor correction 39 | 40 | 41 | ## 0.0.2 42 | 43 | - Adding `pub get` command 44 | - Adding `pub build` command 45 | 46 | 47 | ## 0.0.1 48 | 49 | - Syntax coloration 50 | - Simple snippet -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dart support for VSCode 2 | 3 | ## DEPRECATED! 4 | 5 | *Warning*: this extension is no longer maintained, please use [DartCode](https://marketplace.visualstudio.com/items?itemName=DanTup.dart-code) 6 | 7 | --- 8 | 9 | This extension aims to provide support and IDE-like features for Dart language to VS Code 10 | 11 | ## Features 12 | 13 | ### Done 14 | 15 | * Syntax coloration for Dart file 16 | * Simple Snippet for Dart file 17 | * Simple `pub` command integration 18 | * `dartfmt` integration 19 | * Show some command result in a dedicated ouput window 20 | * `pub` command integration 21 | - `pub get` done 22 | - `pub build` done 23 | - `pub run` done 24 | 25 | ### In progress 26 | 27 | * Connect to the `dartanalyzer` to provide better experience 28 | 29 | ### In the future 30 | 31 | * `dartdoc` integration 32 | * `grinder` integration 33 | * Auto completion 34 | 35 | ## Using 36 | 37 | This extension use the following command: 38 | 39 | - `pub` 40 | - `dart` 41 | - `dartfmt` 42 | - `dartanalyzer` 43 | 44 | Be sure that theses command are in your path, or change the path of theses command in the configuration 45 | 46 | ## Usefull links 47 | 48 | Here is some usefull links: 49 | 50 | - *Github* : [repo](https://github.com/platelk/vscode-dart) 51 | 52 | ## Special Thanks 53 | 54 | For this extension, I use as example and resources : 55 | 56 | - the Go language extension done by Microsoft [here](https://github.com/Microsoft/vscode-go) 57 | - the Dart Atom extension available [here](https://github.com/dart-atom/dartlang/) 58 | 59 | ## Contact me ! 60 | 61 | Don't hesitate to email me or contact me on G+ 62 | 63 | - G+ : [+Kevin PLATEL](https://plus.google.com/+KévinPlatel) 64 | - Mail : [Kevin PLATEL](platel.kevin@gmail.com) 65 | 66 | **Enjoy!** 67 | -------------------------------------------------------------------------------- /img/dart-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platelk/vscode-dart/03f7cd46d552a2ede0b4013de3aa60c507de01d0/img/dart-logo.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dart", 3 | "displayName": "Dart", 4 | "description": "Dart support for VSCode", 5 | "version": "0.1.0", 6 | "publisher": "kevinplatel", 7 | "author": { 8 | "name": "PLATEL Kévin" 9 | }, 10 | "categories": [ 11 | "Languages", 12 | "Snippets", 13 | "Linters" 14 | ], 15 | "keywords": [ 16 | "Dart", 17 | "Web", 18 | "Programming" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/platelk/vscode-dart.git" 23 | }, 24 | "icon": "img/dart-logo.png", 25 | "galleryBanner": { 26 | "color": "#006698", 27 | "theme": "dark" 28 | }, 29 | "engines": { 30 | "vscode": "^1.0.0" 31 | }, 32 | "activationEvents": [ 33 | "onLanguage:dart", 34 | "workspaceContains:pubspec.yaml" 35 | ], 36 | "main": "./out/src/extension", 37 | "contributes": { 38 | "commands": [ 39 | { 40 | "command": "dart.pubGet", 41 | "title": "Pub get" 42 | }, 43 | { 44 | "command": "dart.pubBuild", 45 | "title": "Pub build" 46 | }, 47 | { 48 | "command": "dart.pubBuildDebug", 49 | "title": "Pub build debug" 50 | }, 51 | { 52 | "command": "dart.pubRun", 53 | "title": "Pub run current open document" 54 | }, 55 | { 56 | "command": "dart.fmt", 57 | "title": "Dart format" 58 | }, 59 | { 60 | "command": "dart.lint", 61 | "title": "Dart Linter" 62 | } 63 | ], 64 | "keybindings": [ 65 | { 66 | "command": "dart.pubRun", 67 | "key": "ctrl+shift+R", 68 | "mac": "cmd+shift+R" 69 | }, 70 | { 71 | "command": "dart.pubBuild", 72 | "key": "ctrl+shift+B", 73 | "mac": "cmd.shift+B" 74 | } 75 | ], 76 | "languages": [ 77 | { 78 | "id": "dart", 79 | "aliases": ["Dart"], 80 | "extensions": [".dart"] 81 | } 82 | ], 83 | "grammars": [ 84 | { 85 | "language": "dart", 86 | "path": "./syntaxes/dart.json", 87 | "scopeName": "source.dart" 88 | } 89 | ], 90 | "snippets": [ 91 | { 92 | "language": "dart", 93 | "path": "./snippets/dart.json" 94 | }, 95 | { 96 | "language": "yaml", 97 | "path": "./snippets/pubspec.json" 98 | } 99 | ], 100 | "configuration": { 101 | "type": "object", 102 | "title": "Dart configuration", 103 | "properties": { 104 | "dart.pubPath": { 105 | "type": "string", 106 | "description": "path to the pub command", 107 | "default": "pub" 108 | }, 109 | "dart.dartPath": { 110 | "type": "string", 111 | "description": "path to the dart command", 112 | "default": "dart" 113 | }, 114 | "dart.dartiumPath": { 115 | "type": "string", 116 | "description": "path the dartium browser, if the value is empty, it will look at $DART_SDK", 117 | "default": "" 118 | }, 119 | "dart.dartFmtPath": { 120 | "type": "string", 121 | "description": "path of the dartfmt tool", 122 | "default": "dartfmt" 123 | }, 124 | "dart.formatOnSave": { 125 | "type": "boolean", 126 | "description": "run dartfmt on save", 127 | "default": true 128 | }, 129 | "dart.dartAnalyzerPath": { 130 | "type": "string", 131 | "description": "path of the dartanalyzer tool", 132 | "default": "dartanalyzer" 133 | }, 134 | "dart.lintOnSave": { 135 | "type": "boolean", 136 | "description": "run linter on save", 137 | "default": true 138 | } 139 | } 140 | } 141 | }, 142 | "scripts": { 143 | "vscode:prepublish": "node ./node_modules/vscode/bin/compile", 144 | "compile": "node ./node_modules/vscode/bin/compile -watch -p ./", 145 | "postinstall": "node ./node_modules/vscode/bin/install" 146 | }, 147 | "devDependencies": { 148 | "typescript": "^1.8.10", 149 | "vscode": "^0.11.10" 150 | } 151 | } -------------------------------------------------------------------------------- /snippets/dart.json: -------------------------------------------------------------------------------- 1 | { 2 | ".source.dart": { 3 | "import package": { 4 | "prefix": "im", 5 | "body": "import '${1:package}';" 6 | }, 7 | "class": { 8 | "prefix": "class", 9 | "body": "class ${1:className} {\n ${1:className}($2);\n}" 10 | }, 11 | "class extends": { 12 | "prefix": "classex", 13 | "body": "class ${1:className} extends ${2:upperClassName} {\n ${1:className}($3) : super($4);\n}" 14 | }, 15 | "abstract class": { 16 | "prefix": "aclass", 17 | "body": "abstract class ${1:className} {\n ${1:className}();\n}" 18 | }, 19 | "abstract class extends": { 20 | "prefix": "aclassex", 21 | "body": "abstract class ${1:className} extends ${2:upperClassName} {\n ${1:className}($3) : super($4);\n}" 22 | }, 23 | "function": { 24 | "prefix": "fun", 25 | "body": "${1:returnType} ${2:functionName}($3) {\n\t$4\n}" 26 | }, 27 | "main function": { 28 | "prefix": "main", 29 | "body": "void main() {\n\t$0\n}" 30 | }, 31 | "for loop": { 32 | "prefix": "forl", 33 | "body": [ 34 | "for (var ${1:index} = 0; ${1:index} < ${2:array}.length; ${1:index}++) {", 35 | "\tvar ${3:element} = ${2:array}[${1:index}];", 36 | "\t$4", 37 | "}" 38 | ], 39 | "description": "For Loop" 40 | }, 41 | "for in loop": { 42 | "prefix": "fori", 43 | "body": [ 44 | "for (var ${element} : ${list}) {", 45 | "\t$0;", 46 | "}" 47 | ] 48 | }, 49 | "while loop": { 50 | "prefix": "whilel", 51 | "body": [ 52 | "while ($1) {", 53 | "\t$2;", 54 | "}" 55 | ] 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /snippets/pubspec.json: -------------------------------------------------------------------------------- 1 | { 2 | ".source.yaml" : { 3 | "Basic pubspec.yaml" : { 4 | "prefix": "pubspec", 5 | "body": [ 6 | "name: ${1:projectName}", 7 | "version: ${2:projectVersion}", 8 | "description: Description of ${1:projectName}", 9 | "dependencies:", 10 | "\t${3:dependenciesName}: \"^${4:any}\"", 11 | "dev_dependencies:", 12 | "\ttest: any" 13 | ] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/dartAnalyzer.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // The module 'vscode' contains the VS Code extensibility API 4 | // Import the module and reference it with the alias vscode in your code below 5 | import * as vscode from 'vscode'; 6 | import cp = require("child_process"); 7 | 8 | import { LinterResult } from "./dartLintResult"; 9 | 10 | export class DartAnalyzer { 11 | private _dartAnalyzer; 12 | private _severity : Map = new Map(); 13 | 14 | constructor() { 15 | this._dartAnalyzer = vscode.workspace.getConfiguration("dart")["dartAnalyzerPath"]; 16 | this._severity["error"] = vscode.DiagnosticSeverity.Error; 17 | this._severity["hint"] = vscode.DiagnosticSeverity.Hint; 18 | this._severity["warning"] = vscode.DiagnosticSeverity.Warning; 19 | this._severity["information"] = vscode.DiagnosticSeverity.Information; 20 | } 21 | 22 | lintFile(fileName : string) : Promise { 23 | var self = this; 24 | var promise = new Promise((resolve, reject) => { 25 | cp.exec( 26 | this._dartAnalyzer + " --lints " + fileName, 27 | {"cwd": vscode.workspace.rootPath}, 28 | (err, stdout, stderr) => { 29 | let result = stdout.toString().split("\n"); 30 | let diagnostics = []; 31 | 32 | result.shift(); 33 | result.pop(); 34 | result.pop(); 35 | 36 | for (let i = 0; i < result.length; ++i) { 37 | let res = new LinterResult(result[i]); 38 | let range = new vscode.Range(new vscode.Position(res.line-1, res.column), new vscode.Position(res.line-1, Number.MAX_VALUE)); 39 | let diagnostic = new vscode.Diagnostic(range, res.message, self._severity[res.type]); 40 | console.log(diagnostic); 41 | diagnostics.push(diagnostic); 42 | } 43 | console.log(diagnostics); 44 | resolve(diagnostics); 45 | }); 46 | }); 47 | return promise; 48 | } 49 | 50 | lint() { 51 | this.lintFile(vscode.workspace.asRelativePath(vscode.window.activeTextEditor.document.fileName).substr(1)); 52 | } 53 | 54 | setDartAnalyzer(context: vscode.ExtensionContext) { 55 | var self = this; 56 | 57 | context.subscriptions.push(vscode.commands.registerCommand("dart.lint", () => this.lint())); 58 | 59 | if (vscode.workspace.getConfiguration("dart")["lintOnSave"]) { 60 | vscode.workspace.onDidSaveTextDocument((e) => { 61 | self.lintFile(e.fileName).then((result) => { 62 | vscode.languages.createDiagnosticCollection("dart").clear(); 63 | vscode.languages.createDiagnosticCollection("dart").set(vscode.Uri.file(e.fileName), result); 64 | }); 65 | }); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/dartFormat.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // The module 'vscode' contains the VS Code extensibility API 4 | // Import the module and reference it with the alias vscode in your code below 5 | import * as vscode from 'vscode'; 6 | import cp = require("child_process"); 7 | 8 | import { DART_MODE } from "./dartMode"; 9 | 10 | export class DartFormat implements vscode.DocumentFormattingEditProvider { 11 | private dartFmtCmd: string; 12 | private haveRunFormatOnSave: boolean = false; 13 | 14 | constructor() { 15 | this.dartFmtCmd = vscode.workspace.getConfiguration("dart")["dartFmtPath"]; 16 | } 17 | 18 | public provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken): Thenable { 19 | return document.save().then(() => { 20 | return this.doFormatDocument(document, options, token); 21 | }); 22 | } 23 | 24 | private doFormatDocument(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken): Thenable { 25 | return new Promise((resolve, reject) => { 26 | var filename = document.fileName; 27 | console.log("==>> " + filename); 28 | if (!filename.match(/.*\.dart/)) 29 | return; 30 | cp.exec(this.dartFmtCmd + " " + filename, {}, (err, stdout, stderr) => { 31 | try { 32 | if (err && (err).code == "ENOENT") { 33 | vscode.window.showInformationMessage("The '" + this.dartFmtCmd + "' command is not available. Please check your dartfmt user setting and ensure it is installed."); 34 | return resolve(null); 35 | } 36 | console.log("ERROR : " + err); 37 | if (err) { 38 | console.log("Cannot format"); 39 | return reject("Cannot format due to syntax errors."); 40 | } 41 | var text = stdout.toString(); 42 | // TODO: Should use `-d` option to get a diff and then compute the 43 | // specific edits instead of replace whole buffer 44 | var lastLine = document.lineCount; 45 | var lastLineLastCol = document.lineAt(lastLine - 1).range.end.character; 46 | var range = new vscode.Range(0, 0, lastLine - 1, lastLineLastCol); 47 | console.log("File formatted"); 48 | return resolve([new vscode.TextEdit(range, text)]); 49 | } catch (e) { 50 | reject(e); 51 | } 52 | }); 53 | }); 54 | } 55 | 56 | runFmtOnFile(filePath: string, onComplete) { 57 | console.log("FilePATH ==::: " + filePath); 58 | // Check if the file is a dart file 59 | if (!filePath.match(/.*\.dart/)) { 60 | console.log("File isn't a dart file"); 61 | return; 62 | } 63 | cp.exec( 64 | this.dartFmtCmd + " " + filePath, 65 | {}, 66 | (err, stdout, stderr) => { 67 | var errStr = stderr.toString(); 68 | console.log(`stdout: ${stdout}`); 69 | console.log(`stderr: ${stderr}`); 70 | console.log(err); 71 | if (err || errStr) { 72 | console.log("Error during formatting"); 73 | return; 74 | } 75 | let document = vscode.window.activeTextEditor.document; 76 | let text = stdout.toString(); 77 | let previousText = document.getText(); 78 | console.log("Export : " + stdout.toString() + "\n============\n" + previousText); 79 | vscode.window.activeTextEditor.edit((editBuild) => { 80 | var lastLine = document.lineCount; 81 | var lastLineLastCol = document.lineAt(lastLine - 1).range.end.character; 82 | var range = new vscode.Range(0, 0, lastLine - 1, lastLineLastCol); 83 | editBuild.replace(range, stdout.toString()); 84 | }); 85 | if (onComplete != null) { 86 | onComplete() 87 | } 88 | console.log("Format on " + filePath); 89 | } 90 | ); 91 | } 92 | 93 | runFmt() { 94 | this.runFmtOnFile(vscode.workspace.asRelativePath(vscode.window.activeTextEditor.document.fileName).substr(1), null); 95 | } 96 | 97 | setDartFmt(context: vscode.ExtensionContext) { 98 | var self = this; 99 | context.subscriptions.push(vscode.commands.registerCommand("dart.fmt", () => this.runFmt())); 100 | 101 | context.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider(DART_MODE, this)); 102 | if (vscode.workspace.getConfiguration("dart")["formatOnSave"]) { 103 | vscode.workspace.onDidSaveTextDocument((e) => { 104 | if (!self.haveRunFormatOnSave) { 105 | self.runFmtOnFile(e.fileName, () => { 106 | console.log("On saved call"); 107 | self.haveRunFormatOnSave = true; 108 | vscode.window.activeTextEditor.document.save() 109 | }); 110 | } else { 111 | self.haveRunFormatOnSave = false; 112 | } 113 | }); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /src/dartLintResult.ts: -------------------------------------------------------------------------------- 1 | export class LinterResult { 2 | line : number; 3 | column : number; 4 | filename : string; 5 | message : string; 6 | type : string; 7 | 8 | private _re = /\[(.*)\](.*)\((.*)\, line (\d)\, col (\d)\)/g; 9 | 10 | constructor(message : string, format="string") { 11 | this.parse(message, format); 12 | } 13 | 14 | parse(message : string, format="string") { 15 | var result = this._re.exec(message); 16 | 17 | console.log(result); 18 | if (!result) { 19 | return; 20 | } 21 | this.type = result[1]; 22 | this.message = result[2]; 23 | this.filename = result[3]; 24 | this.line = parseInt(result[4]); 25 | this.column = parseInt(result[5]); 26 | } 27 | } -------------------------------------------------------------------------------- /src/dartMode.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // The module 'vscode' contains the VS Code extensibility API 4 | // Import the module and reference it with the alias vscode in your code below 5 | import * as vscode from 'vscode'; 6 | 7 | export const DART_MODE: vscode.DocumentFilter = { language: "dart", scheme: "file" } -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | // The module 'vscode' contains the VS Code extensibility API 2 | // Import the module and reference it with the alias vscode in your code below 3 | import * as vscode from 'vscode'; 4 | import { DART_MODE } from "./dartMode"; 5 | import { Pub } from "./pubCmd"; 6 | import { DartFormat } from "./dartFormat"; 7 | import { DartAnalyzer } from "./dartAnalyzer"; 8 | 9 | // this method is called when your extension is activated 10 | // your extension is activated the very first time the command is executed 11 | export function activate(context: vscode.ExtensionContext) : void { 12 | 13 | // Use the console to output diagnostic information (console.log) and errors (console.error) 14 | // This line of code will only be executed once when your extension is activated 15 | console.log("Congratulations, your extension 'dart' is now active!"); 16 | 17 | init(context); 18 | setLanguageConfiguration(); 19 | } 20 | 21 | function init(context: vscode.ExtensionContext) : void { 22 | let pub = new Pub(); 23 | let fmt = new DartFormat(); 24 | let analyzer = new DartAnalyzer(); 25 | 26 | pub.setPubCmd(context); 27 | fmt.setDartFmt(context); 28 | analyzer.setDartAnalyzer(context); 29 | } 30 | 31 | function setLanguageConfiguration() { 32 | vscode.languages.setLanguageConfiguration(DART_MODE.language, { 33 | indentationRules: { 34 | // ^(.*\*/)?\s*\}.*$ 35 | decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/, 36 | // ^.*\{[^}"']*$ 37 | increaseIndentPattern: /^.*\{[^}"']*$/ 38 | }, 39 | wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, 40 | comments: { 41 | lineComment: "//", 42 | blockComment: ["/*", "*/"] 43 | }, 44 | brackets: [ 45 | ["{", "}"], 46 | ["[", "]"], 47 | ["(", ")"], 48 | ], 49 | __electricCharacterSupport: { 50 | brackets: [ 51 | { tokenType: "delimiter.curly.ts", open: "{", close: "}", isElectric: true }, 52 | { tokenType: "delimiter.square.ts", open: "[", close: "]", isElectric: true }, 53 | { tokenType: "delimiter.paren.ts", open: "(", close: ")", isElectric: true } 54 | ] 55 | }, 56 | __characterPairSupport: { 57 | autoClosingPairs: [ 58 | { open: "{", close: "}" }, 59 | { open: "[", close: "]" }, 60 | { open: "(", close: ")" }, 61 | { open: "'", close: "'", notIn: ["string"] }, 62 | { open: "\"", close: "\"", notIn: ["string", "comment"] } 63 | ] 64 | } 65 | }); 66 | } -------------------------------------------------------------------------------- /src/pubCmd.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // The module 'vscode' contains the VS Code extensibility API 3 | // Import the module and reference it with the alias vscode in your code below 4 | import * as vscode from 'vscode'; 5 | import cp = require("child_process"); 6 | 7 | export class Pub { 8 | private pubCmd: string; 9 | 10 | constructor() { 11 | this.pubCmd = vscode.workspace.getConfiguration("dart")["pubPath"]; 12 | console.log(vscode.workspace.rootPath); 13 | console.log("PubPath: " + this.pubCmd); 14 | } 15 | 16 | private _runRun(filePath : string) { 17 | cp.exec( 18 | "pub run " + filePath, 19 | {"cwd": vscode.workspace.rootPath}, 20 | (err, stdout, stderr) => { 21 | let outputWindow = vscode.window.createOutputChannel("pub run"); 22 | console.log(vscode.window.visibleTextEditors); 23 | outputWindow.hide(); 24 | //vscode.commands.executeCommand("workbench.action.splitEditor"); 25 | outputWindow.show(); 26 | outputWindow.clear(); 27 | 28 | console.log(stdout.toString()); 29 | outputWindow.append(stderr.toString()); 30 | outputWindow.append(stdout.toString()); 31 | } 32 | ); 33 | } 34 | 35 | runRun() { 36 | this._runRun(vscode.workspace.asRelativePath(vscode.window.activeTextEditor.document.fileName).substr(1)); 37 | } 38 | 39 | runGet() { 40 | vscode.window.showInformationMessage("Pub get starting..."); 41 | cp.exec( 42 | this.pubCmd + " get", 43 | {"cwd": vscode.workspace.rootPath}, 44 | (err, stdout: string, stderr: string) => { 45 | console.log(err); 46 | if (err != null) { 47 | let error = stderr.toString(); 48 | console.log(error); 49 | if (error.includes("file named \"pubspec.yaml\"")) { 50 | vscode.window.showErrorMessage("Could not find a file named 'pubspec.yaml'"); 51 | } else { 52 | vscode.window.showErrorMessage("Pub get : " + error); 53 | } 54 | } else { 55 | vscode.window.showInformationMessage("Pub get finish."); 56 | } 57 | }); 58 | } 59 | 60 | runBuild(mode: string) { 61 | cp.exec( 62 | this.pubCmd + " build" + " --mode " + mode, 63 | {"cwd": vscode.workspace.rootPath}, 64 | (err: Error, stdout: string, stderr: string) => { 65 | console.log(stdout.toString()); 66 | console.log(err); 67 | let outputWindow = vscode.window.createOutputChannel("pub build"); 68 | 69 | outputWindow.clear(); 70 | 71 | if (err != null) { 72 | let error = stderr.toString(); 73 | if (error.includes("file named \"pubspec.yaml\"")) { 74 | vscode.window.showErrorMessage("Could not find a file named 'pubspec.yaml'"); 75 | } else { 76 | vscode.window.showErrorMessage("Error during the build process in mode " + mode + "\n" + error); 77 | outputWindow.append(stdout.toString()); 78 | outputWindow.append(error); 79 | outputWindow.show(); 80 | } 81 | } else { 82 | vscode.window.showInformationMessage("Pub build in " + mode + " mode finish."); 83 | } 84 | }); 85 | } 86 | 87 | setPubCmd(context: vscode.ExtensionContext) { 88 | console.log("Set pub cmd"); 89 | context.subscriptions.push(vscode.commands.registerCommand("dart.pubGet", () => this.runGet())); 90 | context.subscriptions.push(vscode.commands.registerCommand("dart.pubBuild", () => this.runBuild("release"))); 91 | context.subscriptions.push(vscode.commands.registerCommand("dart.pubBuildDebug", () => this.runBuild("debug"))); 92 | context.subscriptions.push(vscode.commands.registerCommand("dart.pubRun", () => this.runRun())); 93 | } 94 | } -------------------------------------------------------------------------------- /syntaxes/dart.json: -------------------------------------------------------------------------------- 1 | { 2 | "scopeName": "source.dart", 3 | "name": "Dart", 4 | "comment": "Dart language", 5 | "fileTypes": [ 6 | "dart" 7 | ], 8 | "foldingStartMarker": "\\{\\s*$", 9 | "foldingStopMarker": "^\\s*\\}", 10 | "patterns": [ 11 | { 12 | "match": "^(#!.*)$", 13 | "name": "meta.preprocessor.script.dart" 14 | }, 15 | { 16 | "begin": "^\\w*\\b(library|import|part of|part|export)\\b", 17 | "beginCaptures": { 18 | "0": { 19 | "name": "keyword.other.import.dart" 20 | } 21 | }, 22 | "end": ";", 23 | "endCaptures": { 24 | "0": { 25 | "name": "punctuation.terminator.dart" 26 | } 27 | }, 28 | "name": "meta.declaration.dart", 29 | "patterns": [ 30 | { 31 | "include": "#strings" 32 | }, 33 | { 34 | "match": "\\b(as|show|hide)\\b", 35 | "name": "keyword.other.import.dart" 36 | } 37 | ] 38 | }, 39 | { 40 | "include": "#comments" 41 | }, 42 | { 43 | "include": "#punctuation" 44 | }, 45 | { 46 | "include": "#annotations" 47 | }, 48 | { 49 | "include": "#constants-and-special-vars" 50 | }, 51 | { 52 | "include": "#keywords" 53 | }, 54 | { 55 | "include": "#strings" 56 | } 57 | ], 58 | "repository": { 59 | "dartdoc": { 60 | "patterns": [ 61 | { 62 | "match": "(\\[.*?\\])", 63 | "captures": { 64 | "0": { 65 | "name": "variable.name.source.dart" 66 | } 67 | } 68 | }, 69 | { 70 | "match": "(`.*?`)", 71 | "captures": { 72 | "0": { 73 | "name": "variable.other.source.dart" 74 | } 75 | } 76 | }, 77 | { 78 | "match": "(\\* (( ).*))$", 79 | "captures": { 80 | "2": { 81 | "name": "variable.other.source.dart" 82 | } 83 | } 84 | }, 85 | { 86 | "match": "(\\* .*)$" 87 | } 88 | ] 89 | }, 90 | "comments": { 91 | "patterns": [ 92 | { 93 | "captures": { 94 | "0": { 95 | "name": "punctuation.definition.comment.dart" 96 | } 97 | }, 98 | "match": "/\\*\\*/", 99 | "name": "comment.block.empty.dart" 100 | }, 101 | { 102 | "include": "#comments-doc-oldschool" 103 | }, 104 | { 105 | "include": "#comments-doc" 106 | }, 107 | { 108 | "include": "#comments-inline" 109 | } 110 | ] 111 | }, 112 | "comments-doc-oldschool": { 113 | "patterns": [ 114 | { 115 | "begin": "/\\*\\*", 116 | "end": "\\*/", 117 | "name": "comment.block.documentation.dart", 118 | "patterns": [ 119 | { 120 | "include": "#dartdoc" 121 | } 122 | ] 123 | } 124 | ] 125 | }, 126 | "comments-doc": { 127 | "patterns": [ 128 | { 129 | "match": "(///) (.*?)$", 130 | "captures": { 131 | "1": { 132 | "name": "comment.block.triple-slash.dart" 133 | }, 134 | "2": { 135 | "name": "variable.other.source.dart" 136 | } 137 | } 138 | }, 139 | { 140 | "match": "(///) (.*?)$", 141 | "captures": { 142 | "1": { 143 | "name": "comment.block.triple-slash.dart" 144 | }, 145 | "2": { 146 | "name": "comment.block.documentation.dart", 147 | "patterns": [ 148 | { 149 | "include": "#dartdoc" 150 | } 151 | ] 152 | } 153 | } 154 | } 155 | ] 156 | }, 157 | "comments-inline": { 158 | "patterns": [ 159 | { 160 | "begin": "/\\*", 161 | "end": "\\*/", 162 | "name": "comment.block.dart" 163 | }, 164 | { 165 | "captures": { 166 | "1": { 167 | "name": "comment.line.double-slash.dart" 168 | } 169 | }, 170 | "match": "((//).*)$" 171 | } 172 | ] 173 | }, 174 | "annotations": { 175 | "patterns": [ 176 | { 177 | "match": "@[a-zA-Z]+", 178 | "name": "storage.type.annotation.dart" 179 | } 180 | ] 181 | }, 182 | "constants-and-special-vars": { 183 | "patterns": [ 184 | { 185 | "match": "\\b(true|false|null)\\b", 186 | "name": "constant.language.dart" 187 | }, 188 | { 189 | "match": "\\b(this|super)\\b", 190 | "name": "variable.language.dart" 191 | }, 192 | { 193 | "match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)\\b", 194 | "name": "constant.numeric.dart" 195 | }, 196 | { 197 | "match": "\\b_?[A-Z][a-zA-Z0-9_]+\\b", 198 | "name": "support.class.dart" 199 | }, 200 | { 201 | "match": "(_?[a-z][a-zA-Z0-9_]+)(\\(|\\s+=>)", 202 | "captures": { 203 | "1": { 204 | "name": "entity.name.function.dart" 205 | } 206 | } 207 | }, 208 | { 209 | "match": "\\b[A-Z_0-9]+\\b", 210 | "name": "support.constant.dart" 211 | } 212 | ] 213 | }, 214 | "keywords": { 215 | "patterns": [ 216 | { 217 | "match": "\\bas\\b", 218 | "name": "keyword.cast.dart" 219 | }, 220 | { 221 | "match": "\\b(try|on|catch|finally|throw|rethrow)\\b", 222 | "name": "keyword.control.catch-exception.dart" 223 | }, 224 | { 225 | "match": "\\b(break|case|continue|default|do|else|for|if|in|return|switch|while)\\b", 226 | "name": "keyword.control.dart" 227 | }, 228 | { 229 | "match": "\\b(sync\\*|async(\\*)?|await|yield(\\*)?)\\b", 230 | "name": "keyword.control.dart" 231 | }, 232 | { 233 | "match": "\\bassert\\b", 234 | "name": "keyword.control.dart" 235 | }, 236 | { 237 | "match": "\\b(new)\\b", 238 | "name": "keyword.control.new.dart" 239 | }, 240 | { 241 | "match": "\\b(abstract|class|enum|extends|external|factory|implements|interface|get|native|operator|set|typedef|with)\\b", 242 | "name": "keyword.declaration.dart" 243 | }, 244 | { 245 | "match": "\\b(is\\!?)\\b", 246 | "name": "keyword.operator.dart" 247 | }, 248 | { 249 | "match": "\\?|:", 250 | "name": "keyword.operator.ternary.dart" 251 | }, 252 | { 253 | "match": "(<<|>>>?|~|\\^|\\||&)", 254 | "name": "keyword.operator.bitwise.dart" 255 | }, 256 | { 257 | "match": "((&|\\^|\\||<<|>>>?)=)", 258 | "name": "keyword.operator.assignment.bitwise.dart" 259 | }, 260 | { 261 | "match": "(==|!=|<=?|>=?)", 262 | "name": "keyword.operator.comparison.dart" 263 | }, 264 | { 265 | "match": "(([+*/%-]|\\~)=)", 266 | "name": "keyword.operator.assignment.arithmetic.dart" 267 | }, 268 | { 269 | "match": "(=)", 270 | "name": "keyword.operator.assignment.dart" 271 | }, 272 | { 273 | "match": "(\\-\\-|\\+\\+)", 274 | "name": "keyword.operator.increment-decrement.dart" 275 | }, 276 | { 277 | "match": "(\\-|\\+|\\*|\\/|\\~\\/|%)", 278 | "name": "keyword.operator.arithmetic.dart" 279 | }, 280 | { 281 | "match": "(!|&&|\\|\\|)", 282 | "name": "keyword.operator.logical.dart" 283 | }, 284 | { 285 | "match": "\\b(static|final|const)\\b", 286 | "name": "storage.modifier.dart" 287 | }, 288 | { 289 | "match": "\\b(?:void|bool|num|int|double|dynamic|var)\\b", 290 | "name": "storage.type.primitive.dart" 291 | } 292 | ] 293 | }, 294 | "string-interp": { 295 | "patterns": [ 296 | { 297 | "captures": { 298 | "2": { 299 | "name": "variable.parameter.dart" 300 | }, 301 | "3": { 302 | "name": "variable.parameter.dart" 303 | } 304 | }, 305 | "match": "\\$((\\w+)|\\{(\\w+)\\})" 306 | }, 307 | { 308 | "match": "\\\\.", 309 | "name": "constant.character.escape.dart" 310 | } 311 | ] 312 | }, 313 | "strings": { 314 | "patterns": [ 315 | { 316 | "begin": "(? { 16 | 17 | // Defines a Mocha unit test 18 | test("Something 1", () => { 19 | assert.equal(-1, [1, 2, 3].indexOf(5)); 20 | assert.equal(-1, [1, 2, 3].indexOf(0)); 21 | }); 22 | }); -------------------------------------------------------------------------------- /test/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | var testRunner = require('vscode/lib/testrunner'); 14 | 15 | // You can directly control Mocha options by uncommenting the following lines 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 17 | testRunner.configure({ 18 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 19 | useColors: true // colored output from test results 20 | }); 21 | 22 | module.exports = testRunner; -------------------------------------------------------------------------------- /test/test.dart.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platelk/vscode-dart/03f7cd46d552a2ede0b4013de3aa60c507de01d0/test/test.dart.txt -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES5", 5 | "outDir": "out", 6 | "noLib": true, 7 | "sourceMap": true 8 | }, 9 | "exclude": [ 10 | "node_modules" 11 | ] 12 | } -------------------------------------------------------------------------------- /typings/node.d.ts: -------------------------------------------------------------------------------- 1 | /// -------------------------------------------------------------------------------- /typings/vscode-typings.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your first VS Code Extension 2 | 3 | ## What's in the folder 4 | * This folder contains all of the files necessary for your extension 5 | * `package.json` - this is the manifest file in which you declare your extension and command. 6 | The sample plugin registers a command and defines its title and command name. With this information 7 | VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | The file exports one function, `activate`, which is called the very first time your extension is 10 | activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 11 | We pass the function containing the implementation of the command as the second parameter to 12 | `registerCommand`. 13 | 14 | ## Get up and running straight away 15 | * press `F5` to open a new window with your extension loaded 16 | * run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World` 17 | * set breakpoints in your code inside `src/extension.ts` to debug your extension 18 | * find output from your extension in the debug console 19 | 20 | ## Make changes 21 | * you can relaunch the extension from the debug toolbar after changing code in `src/extension.ts` 22 | * you can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes 23 | 24 | ## Explore the API 25 | * you can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts` 26 | 27 | ## Run tests 28 | * open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Launch Tests` 29 | * press `F5` to run the tests in a new window with your extension loaded 30 | * see the output of the test result in the debug console 31 | * make changes to `test/extension.test.ts` or create new test files inside the `test` folder 32 | * by convention, the test runner will only consider files matching the name pattern `**.test.ts` 33 | * you can create folders inside the `test` folder to structure your tests any way you want --------------------------------------------------------------------------------