├── .editorconfig ├── .eslintrc ├── .gitignore ├── .travis.yml ├── .vscode ├── launch.json └── settings.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── appveyor.yml ├── extension.js ├── jsconfig.json ├── package.json ├── test ├── extension.test.js ├── index.js └── module-loader.js ├── typings ├── node.d.ts └── vscode-typings.d.ts └── vsc-extension-quickstart.md /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint:recommended", 4 | "plugin:node/recommended" 5 | ], 6 | "plugins": [ 7 | "node" 8 | ], 9 | "env": { 10 | "node": true 11 | }, 12 | "rules": { 13 | "node/no-unpublished-require": [ 14 | "error", 15 | { 16 | "allowModules": [ 17 | "vscode" 18 | ] 19 | } 20 | ], 21 | "node/no-missing-require": [ 22 | "error", 23 | { 24 | "allowModules": [ 25 | "vscode" 26 | ] 27 | } 28 | ], 29 | "semi": "error", 30 | "no-console": "warn", 31 | "node/no-unsupported-features": [ 32 | "error", 33 | { 34 | "version": 5 35 | } 36 | ] 37 | } 38 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.vsix -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | os: 4 | - osx 5 | - linux 6 | 7 | before_install: 8 | - if [ $TRAVIS_OS_NAME == "linux" ]; then 9 | export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0; 10 | sh -e /etc/init.d/xvfb start; 11 | sleep 3; 12 | fi 13 | 14 | install: 15 | - npm install 16 | - npm run vscode:prepublish 17 | 18 | script: 19 | - npm test --silent -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": [ 11 | "--extensionDevelopmentPath=${workspaceRoot}" 12 | ], 13 | "stopOnEntry": false 14 | }, 15 | { 16 | "name": "Launch Tests", 17 | "type": "extensionHost", 18 | "request": "launch", 19 | "runtimeExecutable": "${execPath}", 20 | "args": [ 21 | "--extensionDevelopmentPath=${workspaceRoot}", 22 | "--extensionTestsPath=${workspaceRoot}/test" 23 | ], 24 | "stopOnEntry": false 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // 既定の設定とユーザー設定を上書きするには、このファイル内に設定を挿入します 2 | { 3 | "typescript.tsdk": "node_modules/typescript/lib" 4 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | typings/** 4 | test/** 5 | .gitignore 6 | jsconfig.json 7 | vsc-extension-quickstart.md 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.2.0 - (2016/11/9) 2 | **Closed issues:** 3 | - Add configuration. `sequence.replaceSelection`. [\#1](https://github.com/tomoki1207/vscode-input-sequence/issues/1) 4 | 5 | ## 0.1.0 - (2016/9/28) 6 | First Release -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 tomoki1207 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vscode-input-sequence 2 | 3 | [![Build status](http://img.shields.io/travis/tomoki1207/vscode-input-sequence/master.svg?style=flat-square)](https://travis-ci.org/tomoki1207/vscode-input-sequence) 4 | [![AppVeyor](http://img.shields.io/appveyor/ci/tomoki1207/vscode-input-sequence/master.svg?style=flat-square)](https://ci.appveyor.com/project/tomoki1207/vscode-input-sequence) 5 | [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/tomoki1207/vscode-input-sequence/master/LICENSE) 6 | 7 | [sequential-number](https://atom.io/packages/sequential-number) for VSCode. 8 | 9 | ![screenshot](https://raw.githubusercontent.com/tomoki1207/vscode-input-sequence/images/screenshot.gif) 10 | 11 | ## Usage 12 | 13 | ### Default Keymap 14 | ctrl + alt + 0 => Open the input panel ! 15 | 16 | ### Syntax Rules 17 | 18 | ` : : ` 19 | 20 | | Key | Default | Definition | 21 | | :------------------------------------ | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------- | 22 | | **start** | `""` | It specifies the number that you start typing an integer. | 23 | | **operator** (optional) | `+` | It specifies the generation rules of consecutive numbers in the `+` or `-`. The sign of the increment(`++`) and decrement(`--`) also available. | 24 | | **step** (optional) | `1` | It specifies the integer to be added or subtracted. | 25 | | **digit** (optional) | `0` | It specifies of the number of digits in the integer. | 26 | | **radix** (optional) | `10` | It specifies an integer between 2 and 36 that represents radix. | 27 | 28 | ### More infomation and Examples 29 | 30 | See [sequential-number](https://atom.io/packages/sequential-number). 31 | 32 | ### Configuration 33 | 34 | + `sequence.replaceSelection` 35 | Replace initial selections by sequence or not. 36 | ![replaceScreenshot](https://raw.githubusercontent.com/tomoki1207/vscode-input-sequence/images/replaceSelection.gif) 37 | 38 | ## LICENSE 39 | [LICENSE](./LICENSE) 40 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | ELECTRON_RUN_AS_NODE: 1 3 | VSCODE_BUILD_VERBOSE: true 4 | 5 | install: 6 | - ps: Install-Product node 6.6.0 x64 7 | - npm install -g npm 8 | - npm install -g gulp mocha 9 | 10 | build_script: 11 | - npm install 12 | 13 | test_script: 14 | - node --version 15 | - npm --version 16 | - npm test --silent -------------------------------------------------------------------------------- /extension.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var vscode = require('vscode'); 3 | var Range = vscode.Range; 4 | var Position = vscode.Position; 5 | var syntaxRegex = /^([+\-]?[\da-fA-F]+(?:\.\d+)?)\s*([+\-]|(?:\+\+|\-\-))?\s*(\d+)?\s*(?:\:\s*(\d+))?\s*(?:\:\s*(\d+))?$/; 6 | 7 | // this method is called when your extension is activated 8 | function activate(context) { 9 | var insertCmd = vscode.commands.registerCommand('insertSequentialNumbers', function () { 10 | var editor = vscode.window.activeTextEditor; 11 | var initialSelections = editor.selections.sort(sortSelection); 12 | var inputOptions = {}; 13 | var undoStopBefore = true; 14 | inputOptions.placeHolder = " : : "; 15 | inputOptions.validateInput = function (param) { 16 | if (param === "") { 17 | perform(initialSelections, editor, {}, { undoStopBefore: undoStopBefore, undoStopAfter: false }); 18 | return; 19 | } 20 | var test = parseInput(param); 21 | if (!test) { 22 | return 'Syntax error. The rule is " : : ".'; 23 | } 24 | // realtime simulate 25 | perform(initialSelections, editor, test, { undoStopBefore: undoStopBefore, undoStopAfter: false }); 26 | undoStopBefore &= false; 27 | }; 28 | vscode.window.showInputBox(inputOptions) 29 | .then(function (value) { 30 | if (!value && value !== 0) { 31 | // undo 32 | if (!undoStopBefore) { 33 | vscode.commands.executeCommand("undo"); 34 | } 35 | return; 36 | } 37 | // confirm input. 38 | var options = parseInput(value); 39 | perform(initialSelections, editor, options, { undoStopBefore: false, undoStopAfter: true }); 40 | }); 41 | }); 42 | 43 | context.subscriptions.push(insertCmd); 44 | } 45 | exports.activate = activate; 46 | 47 | // this method is called when your extension is deactivated 48 | function deactivate() { 49 | } 50 | exports.deactivate = deactivate; 51 | 52 | function sortSelection(a, b) { 53 | return a.anchor.line - b.anchor.line || a.anchor.character - b.anchor.character; 54 | } 55 | 56 | function perform(initial, editor, options, undoStop) { 57 | var currentSelection = editor.selections.sort(sortSelection); 58 | var replaceSelection = vscode.workspace.getConfiguration("sequence").replaceSelection; 59 | editor.edit(function (builder) { 60 | initial.forEach(function (selection, index) { 61 | var endOfInitialSelection = replaceSelection ? selection.start.character : selection.end.character + (currentSelection[index].start.character - selection.start.character); 62 | builder.replace(new Range(new Position(selection.end.line, endOfInitialSelection), currentSelection[index].end), calculate(index, options)); 63 | }); 64 | }, undoStop); 65 | } 66 | 67 | function parseInput(input) { 68 | var matches = input.match(syntaxRegex); 69 | if (!matches) { 70 | return null; 71 | } 72 | 73 | var radix = matches[5] ? parseInt(matches[5], 10) : 10; 74 | var start = parseInt(matches[1], radix); 75 | var operator = matches[2] || "+"; 76 | var step = isNaN(matches[3]) ? 1 : parseInt(matches[3], 10); 77 | 78 | var digit = parseInt(matches[4], 10); 79 | if (isNaN(digit)) { 80 | digit = (start.toString() === matches[1]) ? 0 : matches[1].length; 81 | if (/^[+\-]/.test(matches[1])) { 82 | digit = Math.max(digit - 1, 0); 83 | } 84 | } 85 | return { 86 | start: start, 87 | digit: digit, 88 | operator: operator, 89 | step: step, 90 | radix: radix, 91 | input: input 92 | }; 93 | } 94 | 95 | function calculate(index, options) { 96 | var value = NaN; 97 | switch (options.operator) { 98 | case "++": 99 | value = options.start + index; 100 | break; 101 | case "--": 102 | value = options.start - index; 103 | break; 104 | case "+": 105 | value = options.start + (index * options.step); 106 | break; 107 | case "-": 108 | value = options.start - (index * options.step); 109 | break; 110 | default: 111 | return ""; 112 | } 113 | 114 | value = paddingZero(value, options.digit, options.radix); 115 | var hasAlpha = options.input.match(/([a-fA-F])/); 116 | if (hasAlpha) { 117 | // for hex. 118 | return hasAlpha[1] == hasAlpha[1].toLowerCase() ? value.toLowerCase() : value.toUpperCase(); 119 | } 120 | return value; 121 | } 122 | 123 | function paddingZero(num, dig, radix) { 124 | if (!dig) { 125 | dig = 0; 126 | } 127 | if (!radix) { 128 | radix = 10; 129 | } 130 | var number = num.toString(radix); 131 | var numAbs = number.replace("-", ""); 132 | var digit = Math.max(numAbs.length, dig); 133 | var result = ""; 134 | if (0 <= number.indexOf("-")) { 135 | result += "-"; 136 | } 137 | result += (Array(digit).join("0") + numAbs).slice(digit * -1); 138 | return result; 139 | } -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES5", 5 | "noLib": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-input-sequence", 3 | "displayName": "vscode-input-sequence", 4 | "description": "sequential-number in vscode", 5 | "version": "0.2.0", 6 | "publisher": "tomoki1207", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/tomoki1207/vscode-input-sequence.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/tomoki1207/vscode-input-sequence/issues" 13 | }, 14 | "license": "MIT", 15 | "engines": { 16 | "vscode": "^1.5.0" 17 | }, 18 | "categories": [ 19 | "Other" 20 | ], 21 | "activationEvents": [ 22 | "onCommand:insertSequentialNumbers" 23 | ], 24 | "main": "./extension", 25 | "contributes": { 26 | "commands": [ 27 | { 28 | "command": "insertSequentialNumbers", 29 | "title": "Insert Sequential number" 30 | } 31 | ], 32 | "configuration": { 33 | "title": "Input-Sequence configuration", 34 | "properties": { 35 | "sequence.replaceSelection": { 36 | "type": "boolean", 37 | "default": false 38 | } 39 | } 40 | }, 41 | "keybindings": [ 42 | { 43 | "command": "insertSequentialNumbers", 44 | "key": "ctrl+alt+0", 45 | "mac": "cmd+alt+0", 46 | "when": "editorTextFocus" 47 | } 48 | ] 49 | }, 50 | "scripts": { 51 | "postinstall": "node ./node_modules/vscode/bin/install", 52 | "test": "node ./node_modules/vscode/bin/test", 53 | "package": "vsce package" 54 | }, 55 | "devDependencies": { 56 | "eslint": "^3.6.0", 57 | "eslint-plugin-node": "^2.1.1", 58 | "typescript": "^2.0.3", 59 | "vm": "^0.1.0", 60 | "vsce": "^1.14.0", 61 | "vscode": "^0.11.0" 62 | } 63 | } -------------------------------------------------------------------------------- /test/extension.test.js: -------------------------------------------------------------------------------- 1 | /* global suite, test */ 2 | 3 | var assert = require('assert'); 4 | var vscode = require('vscode'); 5 | var ext = require('../extension'); 6 | var loadModule = require('./module-loader').loadModule; 7 | 8 | suite("Extension Tests", function () { 9 | 10 | var appContext = loadModule(__dirname + '/../extension.js'); 11 | 12 | var invalidParseResult = function (input) { 13 | assert.equal(null, appContext.parseInput(input)); 14 | }; 15 | 16 | var expectParseResult = function (input, expected) { 17 | var options = appContext.parseInput(input); 18 | assert.ok(options); 19 | var result = expected.map(function (value, index) { 20 | return appContext.calculate(index, options); 21 | }); 22 | assert.deepEqual(result, expected); 23 | }; 24 | 25 | suite("Invalid input", function () { 26 | test("''", function () { 27 | invalidParseResult(""); 28 | }); 29 | test("--0011 ", function () { 30 | invalidParseResult("--0011"); 31 | }); 32 | test("++1", function () { 33 | invalidParseResult("++1"); 34 | }); 35 | test("+1/", function () { 36 | invalidParseResult("+1/"); 37 | }); 38 | test("1%1", function () { 39 | invalidParseResult("1%1"); 40 | }); 41 | test("1*2", function () { 42 | invalidParseResult("1*2"); 43 | }); 44 | test("-2+++", function () { 45 | invalidParseResult("-2+++"); 46 | }); 47 | test("+34hoge", function () { 48 | invalidParseResult("+34hoge"); 49 | }); 50 | test("alphabet", function () { 51 | invalidParseResult("alphabet"); 52 | }); 53 | }); 54 | 55 | suite("Valid input", function () { 56 | suite("+ operator", function () { 57 | test("0", function () { 58 | expectParseResult("0", ["0", "1", "2", "3", "4"]); 59 | }); 60 | test("1", function () { 61 | expectParseResult("1", ["1", "2", "3", "4", "5"]); 62 | }); 63 | test("-1", function () { 64 | expectParseResult("-1", ["-1", "0", "1", "2", "3"]); 65 | }); 66 | test("1 + 2", function () { 67 | expectParseResult("1 + 2", ["1", "3", "5", "7", "9"]); 68 | }); 69 | test("5++", function () { 70 | expectParseResult("5++", ["5", "6", "7", "8", "9"]); 71 | }); 72 | test("015 + 1", function () { 73 | expectParseResult("015 + 1", ["015", "016", "017", "018", "019"]); 74 | }); 75 | test("09 + 65", function () { 76 | expectParseResult("09 + 65", ["09", "74", "139", "204", "269"]); 77 | }); 78 | test("-20+12", function () { 79 | expectParseResult("-20+12", ["-20", "-8", "4", "16", "28"]); 80 | }); 81 | test("-10 + 1 : 2", function () { 82 | expectParseResult("-10 + 1 : 2", ["-10", "-09", "-08", "-07", "-06"]); 83 | }); 84 | test("-9 + 1000:3", function () { 85 | expectParseResult("-9 + 1000:3", ["-009", "991", "1991", "2991", "3991"]); 86 | }); 87 | }); 88 | suite("- operator", function () { 89 | test("0 -", function () { 90 | expectParseResult("0 -", ["0", "-1", "-2", "-3", "-4"]); 91 | }); 92 | test("10 - 3", function () { 93 | expectParseResult("10 - 3", ["10", "7", "4", "1", "-2"]); 94 | }); 95 | test("15--", function () { 96 | expectParseResult("15--", ["15", "14", "13", "12", "11"]); 97 | }); 98 | test("0020 - 2", function () { 99 | expectParseResult("0020 - 2", ["0020", "0018", "0016", "0014", "0012"]); 100 | }); 101 | test("-003120 - 21", function () { 102 | expectParseResult("-003120 - 21", ["-003120", "-003141", "-003162", "-003183", "-003204"]); 103 | }); 104 | test("-8 -90 : 2", function () { 105 | expectParseResult("-8 -90 : 2", ["-08", "-98", "-188", "-278", "-368"]); 106 | }); 107 | }); 108 | suite("radix 2", function () { 109 | test("0 + 1 : 1 : 2", function () { 110 | expectParseResult("0 + 1 : 1 : 2", ["0", "1", "10", "11", "100"]); 111 | }); 112 | test("-11 - 2 : 2 : 2", function () { 113 | expectParseResult("-11 - 2 : 2 : 2", ["-11", "-101", "-111", "-1001", "-1011"]); 114 | }); 115 | }); 116 | suite("radix 8", function () { 117 | test("6 + 1 : 2 : 8", function () { 118 | expectParseResult("6 + 1 : 2 : 8", ["06", "07", "10", "11", "12"]); 119 | }); 120 | test("-5 - 5 : 2 : 8", function () { 121 | expectParseResult("-5 - 5 : 2 : 8", ["-05", "-12", "-17", "-24", "-31"]); 122 | }); 123 | }); 124 | suite("radix 16", function () { 125 | test("a + 6 : 1 : 16", function () { 126 | expectParseResult("a + 6 : 1 : 16", ["a", "10", "16", "1c", "22"]); 127 | }); 128 | test("C4b + 9 : 6 : 16", function () { 129 | expectParseResult("C4b + 9 : 6 : 16", ["000C4B", "000C54", "000C5D", "000C66", "000C6F"]); 130 | }); 131 | test("b - 12 : 2 : 16", function () { 132 | expectParseResult("b - 12 : 2 : 16", ["0b", "-01", "-0d", "-19", "-25"]); 133 | }); 134 | }); 135 | }); 136 | }); -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 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.js (suite, test, etc.) 19 | useColors: true // colored output from test results 20 | }); 21 | 22 | module.exports = testRunner; -------------------------------------------------------------------------------- /test/module-loader.js: -------------------------------------------------------------------------------- 1 | var vm = require('vm'); 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | 5 | exports.loadModule = function (filePath, mocks) { 6 | mocks = mocks || {}; 7 | 8 | var resolveModule = function (module) { 9 | if (module.charAt(0) !== '.') 10 | return module; 11 | return path.resolve(path.dirname(filePath), module); 12 | }; 13 | 14 | var exports = {}; 15 | var context = { 16 | require: function (name) { 17 | return mocks[name] || require(resolveModule(name)); 18 | }, 19 | console: console, 20 | exports: exports, 21 | module: { 22 | exports: exports 23 | } 24 | }; 25 | vm.runInNewContext(fs.readFileSync(filePath), context); 26 | return context; 27 | }; -------------------------------------------------------------------------------- /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 | * `extension.js` - 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 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 `extension.js` 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.js` or create new test files inside the `test` folder 32 | * by convention, the test runner will only consider files matching the name pattern `**.test.js` 33 | * you can create folders inside the `test` folder to structure your tests any way you want --------------------------------------------------------------------------------