├── .gitignore
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── .vscodeignore
├── README.md
├── package.json
├── screens
├── backticks.gif
├── brackets.gif
├── doublequotes.gif
├── singlequotes.gif
└── tags.gif
├── src
└── extension.ts
├── tsconfig.json
└── vsc-extension-quickstart.md
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | node_modules
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | // A launch configuration that compiles the extension and then opens it 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": ["--extensionDevelopmentPath=${workspaceRoot}" ],
11 | "stopOnEntry": false,
12 | "sourceMaps": true,
13 | "outFiles": ["out/src"],
14 | "preLaunchTask": "npm"
15 | }]
16 | }
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vscode-quick-select
2 |
3 |
4 | Yes I know about the ⌃⇧⌘← and ⌃⇧⌘→ expand/shrink selection. Having come from VIM I think these are still missing.
5 |
6 | It now supports multilines automatic selection, matching correctly.
7 |
8 | **NEW:** you can also now toggle single/double quotes
9 |
10 | See the examples below.
11 |
12 |
13 | ## Installation
14 |
15 | Press F1 and narrow down the list commands by typing `extension`. Pick `Extensions: Install Extension`.
16 | Select the `Quick and Simple Text Selection` extension from the list
17 |
18 |
19 | ## Manual Install
20 |
21 | **Mac & Linux**
22 | ```sh
23 | cd $HOME/.vscode/extensions
24 | ```
25 | **Windows**
26 | ```sh
27 | cd %USERPROFILE%\.vscode\extensions
28 | ```
29 |
30 | **All Platforms**
31 | ```
32 | git clone https://github.com/dbankier/vscode-quick-select.git
33 | cd vscode-quick-select
34 | npm install
35 | ```
36 |
37 |
38 | ## Usage
39 |
40 | Here some examples - and it supports multiple selections.
41 |
42 | In the examples below use CTRL instead of ⌘ for Windows.
43 |
44 | ⌘k "
45 |
46 | 
47 |
48 | ⌘k '
49 |
50 | 
51 |
52 | **NEW:** You can also use this following shortcut to select either single, double quotes or backticks
53 |
54 | ⌘k ;
55 |
56 | **NEW:** You can also use this following shortcut to toggle quotes, e.g. `"word"` to `'word'`
57 |
58 | ⌘k :
59 |
60 | **NOTE:** the extensions can be configured to exclude backticks from selection or switching
61 |
62 | ⌘k `
63 |
64 | 
65 |
66 | ⌘k ( and
67 | ⌘k [ and
68 | ⌘k {
69 |
70 | Using the following performs and outer selection:
71 |
72 | ⌘k ) and
73 | ⌘k ] and
74 | ⌘k }
75 |
76 | Or if you have already made in inner selection, use the same key combination again to expand to an outer selection.
77 |
78 | 
79 |
80 |
81 | ⌘k <
82 |
83 | This also selects the matching tag.
84 |
85 | ⌘k >
86 |
87 | This matches the tag value.
88 |
89 | 
90 |
91 | ### Customisation
92 |
93 | ~~~
94 | extension.selectSingleQuote
95 | extension.selectDoubleQuote
96 | extension.selectEitherQuote
97 | extension.switchQuotes
98 | extension.selectParenthesis
99 | extension.selectBackTick
100 | extension.selectSquareBrackets
101 | extension.selectCurlyBrackets
102 | extension.selectParenthesisOuter
103 | extension.selectSquareBracketsOuter
104 | extension.selectCurlyBracketsOuter
105 | extension.selectAngleBrackets
106 | extension.selectInTag
107 | ~~~
108 |
109 | ## License
110 |
111 | MIT © [David Bankier @dbankier](https://github.com/dbankier)
112 |
113 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vscode-quick-select",
3 | "displayName": "Quick and Simple Text Selection",
4 | "description": "Jump to select between quote, brackets, tags, etc",
5 | "version": "0.2.9",
6 | "publisher": "dbankier",
7 | "engines": {
8 | "vscode": "^1.0.3"
9 | },
10 | "categories": [
11 | "Other"
12 | ],
13 | "activationEvents": [
14 | "onCommand:extension.selectSingleQuote",
15 | "onCommand:extension.selectDoubleQuote",
16 | "onCommand:extension.selectEitherQuote",
17 | "onCommand:extension.switchQuotes",
18 | "onCommand:extension.selectParenthesis",
19 | "onCommand:extension.selectBackTick",
20 | "onCommand:extension.selectSquareBrackets",
21 | "onCommand:extension.selectCurlyBrackets",
22 | "onCommand:extension.selectParenthesisOuter",
23 | "onCommand:extension.selectSquareBracketsOuter",
24 | "onCommand:extension.selectCurlyBracketsOuter",
25 | "onCommand:extension.selectAngleBrackets",
26 | "onCommand:extension.selectInTag"
27 | ],
28 | "main": "./out/src/extension",
29 | "contributes": {
30 | "commands": [
31 | {
32 | "command": "extension.selectSingleQuote",
33 | "title": "Quick Select: Select inside single quote"
34 | },
35 | {
36 | "command": "extension.selectDoubleQuote",
37 | "title": "Quick Select: Select inside double quote"
38 | },
39 | {
40 | "command": "extension.selectEitherQuote",
41 | "title": "Quick Select: Select inside either quote"
42 | },
43 | {
44 | "command": "extension.switchQuotes",
45 | "title": "Quick Select: Switch quotes"
46 | },
47 | {
48 | "command": "extension.selectParenthesis",
49 | "title": "Quick Select: Select inside parenthesis"
50 | },
51 | {
52 | "command": "extension.selectBackTick",
53 | "title": "Quick Select: Select inside back ticks"
54 | },
55 | {
56 | "command": "extension.selectSquareBrackets",
57 | "title": "Quick Select: Select inside square brackets"
58 | },
59 | {
60 | "command": "extension.selectCurlyBrackets",
61 | "title": "Quick Select: Select inside curly brackets"
62 | },
63 | {
64 | "command": "extension.selectParenthesisOuter",
65 | "title": "Quick Select: Select outside parenthesis"
66 | },
67 | {
68 | "command": "extension.selectSquareBracketsOuter",
69 | "title": "Quick Select: Select outside square brackets"
70 | },
71 | {
72 | "command": "extension.selectCurlyBracketsOuter",
73 | "title": "Quick Select: Select outside curly brackets"
74 | },
75 | {
76 | "command": "extension.selectAngleBrackets",
77 | "title": "Quick Select: Select inside angled brackets"
78 | },
79 | {
80 | "command": "extension.selectInTag",
81 | "title": "Quick Select: Select inside tag"
82 | }
83 | ],
84 | "keybindings": [
85 | {
86 | "command": "extension.selectSingleQuote",
87 | "key": "ctrl+k '",
88 | "mac": "cmd+k '",
89 | "when": "editorFocus"
90 | },
91 | {
92 | "command": "extension.selectDoubleQuote",
93 | "key": "ctrl+k shift+'",
94 | "mac": "cmd+k shift+'",
95 | "when": "editorFocus"
96 | },
97 | {
98 | "command": "extension.selectEitherQuote",
99 | "key": "ctrl+k ;",
100 | "mac": "cmd+k ;",
101 | "when": "editorFocus"
102 | },
103 | {
104 | "command": "extension.switchQuotes",
105 | "key": "ctrl+k shift+;",
106 | "mac": "cmd+k shift+;",
107 | "when": "editorFocus"
108 | },
109 | {
110 | "command": "extension.selectParenthesis",
111 | "key": "ctrl+k shift+9",
112 | "mac": "cmd+k shift+9",
113 | "when": "editorFocus"
114 | },
115 | {
116 | "command": "extension.selectBackTick",
117 | "key": "ctrl+k `",
118 | "mac": "cmd+k `",
119 | "when": "editorFocus"
120 | },
121 | {
122 | "command": "extension.selectSquareBrackets",
123 | "key": "ctrl+k [",
124 | "mac": "cmd+k [",
125 | "when": "editorFocus"
126 | },
127 | {
128 | "command": "extension.selectCurlyBrackets",
129 | "key": "ctrl+k shift+[",
130 | "mac": "cmd+k shift+[",
131 | "when": "editorFocus"
132 | },
133 | {
134 | "command": "extension.selectParenthesisOuter",
135 | "key": "ctrl+k shift+0",
136 | "mac": "cmd+k shift+0",
137 | "when": "editorFocus"
138 | },
139 | {
140 | "command": "extension.selectSquareBracketsOuter",
141 | "key": "ctrl+k ]",
142 | "mac": "cmd+k ]",
143 | "when": "editorFocus"
144 | },
145 | {
146 | "command": "extension.selectCurlyBracketsOuter",
147 | "key": "ctrl+k shift+]",
148 | "mac": "cmd+k shift+]",
149 | "when": "editorFocus"
150 | },
151 | {
152 | "command": "extension.selectAngleBrackets",
153 | "key": "ctrl+k shift+,",
154 | "mac": "cmd+k shift+,",
155 | "when": "editorFocus"
156 | },
157 | {
158 | "command": "extension.selectInTag",
159 | "key": "ctrl+k shift+.",
160 | "mac": "cmd+k shift+.",
161 | "when": "editorFocus"
162 | }
163 | ],
164 | "configuration": {
165 | "type": "object",
166 | "title": "Quick Select configuration",
167 | "properties": {
168 | "quick-select.includeBackticks": {
169 | "type": "boolean",
170 | "default": true,
171 | "description": "Include backticks when selecting or switching any quotes"
172 | }
173 | }
174 | }
175 | },
176 | "scripts": {
177 | "vscode:prepublish": "tsc -p ./",
178 | "compile": "tsc -watch -p ./",
179 | "postinstall": "node ./node_modules/vscode/bin/install"
180 | },
181 | "devDependencies": {
182 | "typescript": "^2.0.3",
183 | "vscode": "^1.0.0",
184 | "@types/node": "^6.0.40"
185 | },
186 | "repository": {
187 | "type": "git",
188 | "url": "https://github.com/dbankier/vscode-quick-select/"
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/screens/backticks.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbankier/vscode-quick-select/1c8aaa582381cc9efab558d901ef659afaba3c65/screens/backticks.gif
--------------------------------------------------------------------------------
/screens/brackets.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbankier/vscode-quick-select/1c8aaa582381cc9efab558d901ef659afaba3c65/screens/brackets.gif
--------------------------------------------------------------------------------
/screens/doublequotes.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbankier/vscode-quick-select/1c8aaa582381cc9efab558d901ef659afaba3c65/screens/doublequotes.gif
--------------------------------------------------------------------------------
/screens/singlequotes.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbankier/vscode-quick-select/1c8aaa582381cc9efab558d901ef659afaba3c65/screens/singlequotes.gif
--------------------------------------------------------------------------------
/screens/tags.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dbankier/vscode-quick-select/1c8aaa582381cc9efab558d901ef659afaba3c65/screens/tags.gif
--------------------------------------------------------------------------------
/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 |
5 | // this method is called when your extension is activated
6 | // your extension is activated the very first time the command is executed
7 | export function activate(context: vscode.ExtensionContext) {
8 | var _ = undefined;
9 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectDoubleQuote', singleSelect.bind(_, { char: '"' })));
10 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectSingleQuote', singleSelect.bind(_, { char: "'" })));
11 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectEitherQuote', selectEitherQuote));
12 | context.subscriptions.push(vscode.commands.registerCommand('extension.switchQuotes', switchQuotes));
13 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectBackTick', singleSelect.bind(_, { char: "`", multiline: true })));
14 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectParenthesis', matchingSelect.bind(_, { start_char: "(", end_char: ")" })));
15 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectSquareBrackets', matchingSelect.bind(_, { start_char: "[", end_char: "]" })));
16 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectCurlyBrackets', matchingSelect.bind(_, { start_char: "{", end_char: "}" })));
17 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectParenthesisOuter', matchingSelect.bind(_, { start_char: "(", end_char: ")", outer: true })));
18 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectSquareBracketsOuter', matchingSelect.bind(_, { start_char: "[", end_char: "]", outer: true })));
19 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectCurlyBracketsOuter', matchingSelect.bind(_, { start_char: "{", end_char: "}", outer: true })));
20 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectAngleBrackets', matchingSelect.bind(_, { start_char: "<", end_char: ">" })));
21 | context.subscriptions.push(vscode.commands.registerCommand('extension.selectInTag', matchingSelect.bind(_, { start_char: ">", end_char: "<" })));
22 | }
23 |
24 | // Replacables
25 | const starters = ['"', "'", "`", "(", "[", '{'];
26 | const enders = ['"', "'", "`", ")", "]", '}'];
27 |
28 | function findOccurances(doc: vscode.TextDocument, line: number, char: string): Array {
29 | var content = doc.lineAt(line);
30 | var matches = (content.text + "hack").split(char).reduce((acc, p) => {
31 | var len = p.length + 1;
32 | if (acc.length > 0) {
33 | len += acc[acc.length - 1];
34 | }
35 | acc.push(len);
36 | return acc;
37 | }, []);
38 | matches.pop();
39 | return matches;
40 | }
41 |
42 | function findNext(doc: vscode.TextDocument, line: number, char: string, start_index: number = 0, nest_char: string = undefined, nested: number = 0): vscode.Position {
43 | if (line === doc.lineCount) { return undefined };
44 | var occurances = findOccurances(doc, line, char).filter(n => n >= start_index);
45 | var nests = nest_char ? findOccurances(doc, line, nest_char).filter(n => n >= start_index) : [];
46 | var occurance_index = 0;
47 | var nests_index = 0;
48 | while ((occurance_index < occurances.length || nests_index < nests.length) && nested >= 0) {
49 | if (occurances[occurance_index] < nests[nests_index] || !nests[nests_index]) {
50 | if (nested === 0) {
51 | return new vscode.Position(line, occurances[occurance_index]);
52 | }
53 | nested--
54 | occurance_index++;
55 | } else if (nests[nests_index] < occurances[occurance_index] || !occurances[occurance_index]) {
56 | nested++;
57 | nests_index++;
58 | }
59 | }
60 | return findNext(doc, ++line, char, 0, nest_char, nested);
61 | }
62 | function findPrevious(doc: vscode.TextDocument, line: number, char: string, start_index?: number, nest_char: string = undefined, nested: number = 0): vscode.Position {
63 | if (line === -1) { return undefined };
64 | if (start_index === undefined) { start_index = doc.lineAt(line).text.length; }
65 | var occurances = findOccurances(doc, line, char).filter(n => n <= start_index);
66 | var nests = nest_char ? findOccurances(doc, line, nest_char).filter(n => n <= start_index) : [];
67 | var occurance_index = occurances.length - 1;
68 | var nests_index = nests.length - 1;
69 | while ((occurance_index > -1 || nests_index > -1) && nested >= 0) {
70 | if (occurances[occurance_index] > nests[nests_index] || !nests[nests_index]) {
71 | if (nested === 0) {
72 | return new vscode.Position(line, occurances[occurance_index]);
73 | }
74 | nested--
75 | occurance_index--;
76 | } else if (nests[nests_index] > occurances[occurance_index] || !occurances[occurance_index]) {
77 | nested++;
78 | nests_index--;
79 | }
80 | }
81 | return findPrevious(doc, --line, char, undefined, nest_char, nested);
82 | }
83 |
84 | function findSingleSelect(s: vscode.Selection, doc: vscode.TextDocument, char: string, outer?: boolean, multiline?: boolean) {
85 | let {line, character} = s.active;
86 | let matches = findOccurances(doc, line, char);
87 | let next = matches.find(a => a > character);
88 | let next_index = matches.indexOf(next);
89 | let offset = outer ? char.length : 0;
90 | if (matches.length > 1 && matches.length % 2 === 0) {
91 | // Jump inside the next matching pair
92 | if (next === -1) { return s }
93 | if (next_index % 2 !== 0) {
94 | next_index--;
95 | }
96 | //Automatically grow to outer selection
97 | if (!outer &&
98 | new vscode.Position(line, matches[next_index]).isEqual(s.anchor) &&
99 | new vscode.Position(line, matches[next_index + 1] - 1).isEqual(s.end)) {
100 | offset = char.length
101 | }
102 | return new vscode.Selection(
103 | new vscode.Position(line, matches[next_index] - offset),
104 | new vscode.Position(line, matches[next_index + 1] - 1 + offset)
105 | );
106 | } else if (multiline) {
107 | let start_pos = findPrevious(doc, line, char, character) || new vscode.Position(line, matches[next_index])
108 | if (!start_pos) { return s };
109 | let end_pos: vscode.Position = findNext(doc, start_pos.line, char, start_pos.character + 1);
110 | //Automatically grow to outer selection
111 | if (!outer &&
112 | start_pos.isEqual(s.anchor) &&
113 | new vscode.Position(end_pos.line, end_pos.character - 1).isEqual(s.end)) {
114 | offset = char.length
115 | }
116 | if (start_pos && end_pos) {
117 | start_pos = new vscode.Position(start_pos.line, start_pos.character - offset);
118 | end_pos = new vscode.Position(end_pos.line, end_pos.character - 1 + offset);
119 | return new vscode.Selection(start_pos, end_pos)
120 | }
121 | }
122 | return s;
123 |
124 | }
125 |
126 | interface SingleSelectOptions { char: string; outer?: boolean, multiline?: boolean }
127 | function singleSelect({char, outer = false, multiline = false}: SingleSelectOptions) {
128 | let editor = vscode.window.activeTextEditor;
129 | if (!editor) { return; };
130 | let doc = editor.document
131 | let sel = editor.selections
132 | editor.selections = sel.map(s => findSingleSelect(s, doc, char, outer, multiline))
133 | }
134 |
135 | function getSwitchables() {
136 | const includeBackTicks = vscode.workspace.getConfiguration('quick-select').get('includeBackticks');
137 | return ['"',"'"].concat(includeBackTicks ? ['`']:[])
138 | }
139 |
140 | function selectEitherQuote() {
141 | const switchables = getSwitchables();
142 | let editor = vscode.window.activeTextEditor;
143 | if (!editor) { return; };
144 | let doc = editor.document
145 | let sel = editor.selections
146 | editor.selections = sel.map((s: vscode.Selection) => {
147 | let selections = switchables.map(char => findSingleSelect(s,doc,char, false, false))
148 | .filter(sel => sel !== s)
149 | .filter(sel => sel.start.isBeforeOrEqual(s.start) && sel.end.isAfterOrEqual(s.end))
150 | .sort((a,b) => a.start.isBefore(b.start) ? 1 : -1)
151 | if (selections.length > 0) {
152 | return selections[0]
153 | }
154 | return s;
155 | })
156 | }
157 |
158 | function charRange(p: vscode.Position) {
159 | let end_pos = new vscode.Position(p.line, p.character + 1);
160 | return new vscode.Selection(p, end_pos)
161 | }
162 | function switchQuotes() {
163 | const switchables = getSwitchables();
164 | let editor = vscode.window.activeTextEditor;
165 | let original_sel = editor.selections
166 | selectEitherQuote()
167 | if (!editor) { return; };
168 | let doc = editor.document
169 | let sel = editor.selections
170 | sel.map((s: vscode.Selection) => {
171 | if (s.start.isEqual(s.end)) { return }
172 | //expand selection if needed
173 | let expand_start = switchables.indexOf(doc.getText(charRange(s.start))) === -1 ? 1 : 0
174 | let expand_end = switchables.indexOf(doc.getText(charRange(s.end))) === -1 ? 1 : 0
175 | let start_pos = new vscode.Position(s.start.line, s.start.character - expand_start);
176 | let end_pos = new vscode.Position(s.end.line, s.end.character - expand_end);
177 | s = new vscode.Selection(start_pos, end_pos)
178 | var char = doc.getText(charRange(s.start))
179 | var edit = new vscode.WorkspaceEdit();
180 | let next_index = switchables.indexOf(char)+1;
181 | if (next_index === switchables.length) {
182 | next_index = 0
183 | }
184 | let next_char = switchables[next_index];
185 | edit.replace(doc.uri, charRange(s.start), next_char)
186 | edit.replace(doc.uri, charRange(s.end), next_char)
187 | vscode.workspace.applyEdit(edit)
188 | doc.getText()
189 | })
190 | // restore orignal selection
191 | console.log(original_sel)
192 | editor.selections = original_sel;
193 | console.log(editor.selections)
194 | }
195 | interface MatchingSelectOptions { start_char: string, end_char: string, outer?: boolean }
196 | function matchingSelect({start_char, end_char, outer = false}: MatchingSelectOptions) {
197 | let editor = vscode.window.activeTextEditor;
198 | if (!editor) { return; };
199 | let doc = editor.document
200 | let sel = editor.selections
201 | let success = false;
202 | let start_offset = outer ? start_char.length : 0;
203 | let end_offset = outer ? end_char.length : 0;
204 | editor.selections = sel.map(s => {
205 | let {line, character} = s.active;
206 | let starts = findOccurances(doc, line, start_char);
207 | let ends = findOccurances(doc, line, end_char);
208 | let start = starts.find(a => a > character);
209 | let end = ends.find(a => a > character);
210 | let start_index = starts.indexOf(start);
211 | let end_index = ends.indexOf(end);
212 | let start_pos: vscode.Position = findPrevious(doc, line, start_char, character, end_char) || new vscode.Position(line, starts[start_index]);
213 | if (!start_pos) { return s };
214 | let end_pos: vscode.Position = findNext(doc, start_pos.line, end_char, start_pos.character + 1, start_char);
215 | if (start_pos && end_pos) {
216 | success = true;
217 | //Automatically grow to outer selection
218 | if (!outer &&
219 | start_pos.isEqual(s.anchor) &&
220 | new vscode.Position(end_pos.line, end_pos.character - 1).isEqual(s.end)) {
221 | start_offset = start_char.length;
222 | end_offset = end_char.length;
223 | }
224 | start_pos = new vscode.Position(start_pos.line, start_pos.character - start_offset);
225 | end_pos = new vscode.Position(end_pos.line, end_pos.character - 1 + end_offset);
226 | return new vscode.Selection(start_pos, end_pos)
227 | }
228 | return s;
229 | })
230 | if (success && start_char === "<") {
231 | vscode.commands.executeCommand("editor.action.addSelectionToNextFindMatch")
232 | }
233 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es6",
5 | "outDir": "out",
6 | "lib": ["es6"],
7 | "sourceMap": true,
8 | "rootDir": "."
9 | },
10 | "exclude": [
11 | "node_modules",
12 | ".vscode-test"
13 | ]
14 | }
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------