├── .gitignore ├── README.md ├── package.js ├── package.json ├── remote_vs.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | VoiceCode command package for the Visual Studio Code editor. 2 | 3 | ## Configuration 4 | 5 | To make everything work, change the following setting in VSCode: 6 | 7 | ```"editor.emptySelectionClipboard": false``` 8 | 9 | # Features 10 | 11 | This package exposes two new api methods that interact with VSCode: 12 | 13 | - executeVSCodeCommand : (command: String, options: Any) => Any 14 | 15 | Executes a VSCode command remotely. 16 | 17 | - executeVSCodeExposedMethod : (method: String, options: Any) => Any 18 | 19 | Executes a VSCode exposed method, found in the VSCode extension (https://github.com/VoiceCode/vscode-voicecode) 20 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | const remote = require('./remote_vs'); 2 | 3 | const pack = Packages.register({ 4 | name: 'vscode', 5 | applications: ['com.microsoft.VSCode'], 6 | description: 'VSCode IDE integration' 7 | }); 8 | 9 | pack.api({ 10 | 'executeVSCodeCommand': { 11 | description: 'execute VSCode command remotely', 12 | signature: 'executeVSCodeCommand : (command: String, options: Any) => Any', 13 | action: (command, options) => { 14 | const times = _.get(options, 'times', 1); 15 | const params = _.get(options, 'params', []); 16 | remote.call({ 17 | method: 'executeCommand', 18 | params: { 19 | command, 20 | params, 21 | times 22 | } 23 | }); 24 | } 25 | }, 26 | 'executeVSCodeExposedMethod': { 27 | description: 'Invoke remote VSCode method', 28 | signature: 'executeVSCodeExposedMethod : (method: String, options: Any) => Any', 29 | action: (method, options) => { 30 | remote.call({ 31 | method, 32 | params: { 33 | options 34 | } 35 | }) 36 | } 37 | } 38 | }); 39 | 40 | pack.commands({ 41 | 'navigateCursorBack': { 42 | spoken: 'cursor back', 43 | continuous: false, 44 | description: 'move the cursor to the previous position in history', 45 | action: function () { 46 | this.executeVSCodeCommand('workbench.action.navigateBack'); 47 | } 48 | }, 49 | 'navigateCursorForward': { 50 | spoken: 'cursor next', 51 | continuous: false, 52 | description: 'move the cursor to the next position in history', 53 | action: function () { 54 | this.executeVSCodeCommand('workbench.action.navigateForward'); 55 | } 56 | } 57 | }) 58 | 59 | pack.implement({ 60 | scope: 'vscode', 61 | }, { 62 | 'os:redo': function () { 63 | this.executeVSCodeCommand('redo'); 64 | }, 65 | 'os:undo': function () { 66 | this.executeVSCodeCommand('undo'); 67 | }, 68 | 'delete:partial-word': function () { 69 | this.key('delete', 'option'); 70 | }, 71 | 'delete:partial-word-forward': function () { 72 | this.key('d', 'option'); 73 | }, 74 | 'delete:way-right': function () { 75 | this.executeVSCodeCommand('deleteAllRight'); 76 | }, 77 | 'delete:way-left': function () { 78 | this.executeVSCodeCommand('deleteAllLeft'); 79 | }, 80 | 'cursor:new-line-below': function () { 81 | this.executeVSCodeCommand('editor.action.insertLineAfter'); 82 | }, 83 | 'cursor:new-line-above': function () { 84 | this.executeVSCodeCommand('editor.action.insertLineBefore'); 85 | }, 86 | 'editor:move-to-line-number': function (input) { 87 | let lineNumber = null; 88 | try { 89 | lineNumber = parseInt(input); 90 | } catch (e) { 91 | lineNumber = null; 92 | } 93 | 94 | if (lineNumber) { 95 | this.executeVSCodeExposedMethod('moveCursorToLine', { line: lineNumber }); 96 | } else { 97 | this.key('g', 'control'); 98 | } 99 | }, 100 | 'editor:insert-code-template': function ({ codesnippet }) { 101 | if (codesnippet) { 102 | this.executeVSCodeCommand('editor.action.showSnippets'); 103 | this.delay(200); 104 | this.string(codesnippet); 105 | this.key('enter'); 106 | } 107 | }, 108 | 'selection:block': function () { 109 | this.executeVSCodeCommand('editor.action.smartSelect.grow'); 110 | }, 111 | 'editor:move-to-line-number-and-way-left': function (input) { 112 | let lineNumber = null; 113 | try { 114 | lineNumber = parseInt(input); 115 | } catch (e) { 116 | lineNumber = null; 117 | } 118 | 119 | if (lineNumber) { 120 | this.executeVSCodeExposedMethod('moveCursorToLine', { line: lineNumber }); 121 | } else { 122 | this.key('g', 'control'); 123 | } 124 | }, 125 | 'editor:move-to-line-number-and-way-right': function (input) { 126 | let lineNumber = null; 127 | try { 128 | lineNumber = parseInt(input); 129 | } catch (e) { 130 | lineNumber = null; 131 | } 132 | 133 | if (lineNumber) { 134 | this.executeVSCodeExposedMethod('moveCursorToLine', { line: lineNumber, cursorEnd: true }); 135 | } else { 136 | this.key('g', 'control'); 137 | } 138 | }, 139 | 'editor:insert-under-line-number': true, 140 | 'editor:select-line-number': function (input) { 141 | let lineNumber = null; 142 | try { 143 | lineNumber = parseInt(input); 144 | } catch (e) { 145 | lineNumber = null; 146 | } 147 | 148 | if (lineNumber) { 149 | this.do('editor:move-to-line-number', lineNumber); 150 | this.delay(40); 151 | } 152 | this.do('selection:current-line'); 153 | }, 154 | 'object:duplicate': function () { 155 | this.executeVSCodeCommand('editor.action.copyLinesDownAction'); 156 | }, 157 | 'selection:current-line': function () { 158 | this.executeVSCodeExposedMethod('selectLines'); 159 | }, 160 | 'delete:lines': function () { 161 | const { first, last } = arguments[0] || {}; 162 | 163 | this.executeVSCodeExposedMethod('selectLines', { from: first, to: last }); 164 | this.delay(40); 165 | this.key('delete'); 166 | }, 167 | 'selection:previous-selection-occurrence': function () { 168 | this.executeVSCodeCommand('editor.action.previousSelectionMatchFindAction'); 169 | }, 170 | 'selection:next-selection-occurrence': function () { 171 | this.executeVSCodeCommand('editor.action.nextSelectionMatchFindAction'); 172 | }, 173 | 'editor:select-line-number-range': function (input) { 174 | if (input) { 175 | number = input.toString(); 176 | length = Math.floor(number.length / 2); 177 | first = number.substr(0, length); 178 | last = number.substr(length, length + 1); 179 | first = parseInt(first); 180 | last = parseInt(last); 181 | if (last < first) { 182 | temp = last; 183 | last = first; 184 | first = temp; 185 | } 186 | this.executeVSCodeExposedMethod('selectLines', { from: first, to: last }); 187 | } 188 | }, 189 | 'editor:toggle-comments': function () { 190 | const { first, last } = arguments[0] || {}; 191 | 192 | this.executeVSCodeExposedMethod('selectLines', { from: first, to: last }); 193 | this.delay(40); 194 | this.executeVSCodeCommand('editor.action.commentLine'); 195 | }, 196 | 'editor:expand-selection-to-scope': function () { 197 | this.executeVSCodeExposedMethod('expandSelectionToScope'); 198 | }, 199 | 'editor:click-expand-selection-to-scope': true, 200 | 'editor:extend-selection-to-line-number': function (input) { 201 | let lineNumber = null; 202 | try { 203 | lineNumber = parseInt(input); 204 | } catch (e) { 205 | lineNumber = null; 206 | } 207 | 208 | if (lineNumber) { 209 | this.executeVSCodeExposedMethod('selectLines', { to: lineNumber }); 210 | } 211 | }, 212 | 'editor:insert-from-line-number': function (input) { 213 | let lineNumber = null; 214 | try { 215 | lineNumber = parseInt(input); 216 | } catch (e) { 217 | lineNumber = null; 218 | } 219 | 220 | if (lineNumber) { 221 | this.executeVSCodeExposedMethod('insertFromLine', { line: lineNumber }); 222 | } 223 | }, 224 | 'selection:previous-word-by-surrounding-characters': function (input) { 225 | if (!input || !input.value || input.value.length != 2) { 226 | return; 227 | } 228 | const first = input.value[0]; 229 | const last = input.value[1]; 230 | 231 | this.executeVSCodeExposedMethod('selectBySurroundingCharacters', { first, last }); 232 | }, 233 | 'selection:next-word-by-surrounding-characters': function (input) { 234 | if (!input || !input.value || input.value.length != 2) { 235 | return; 236 | } 237 | const first = input.value[0]; 238 | const last = input.value[1]; 239 | 240 | this.executeVSCodeExposedMethod('selectBySurroundingCharacters', { first, last, nextWord: true }); 241 | }, 242 | 'selection:next-word': function(){ 243 | this.executeVSCodeExposedMethod('selectNextWord'); 244 | }, 245 | 'selection:previous-word': function(){ 246 | this.executeVSCodeExposedMethod('selectNextWord', { backwards: true}); 247 | } 248 | }); 249 | 250 | pack.commands({ 251 | 'file-finder': { 252 | spoken: 'fopen', 253 | description: 'open file finder window in vscode', 254 | continuous: false, 255 | action: function () { 256 | this.executeVSCodeCommand('workbench.action.quickOpen'); 257 | } 258 | }, 259 | 'show-sidebar': { 260 | spoken: 'code sidebar', 261 | description: 'open sidebar in vscode', 262 | continuous: false, 263 | action: function () { 264 | this.executeVSCodeCommand('workbench.action.toggleSidebarVisibility'); 265 | } 266 | }, 267 | 'show-explorer': { 268 | spoken: 'code explorer', 269 | description: 'open explorer in vscode', 270 | continuous: false, 271 | action: function () { 272 | this.executeVSCodeCommand('workbench.view.explorer'); 273 | } 274 | }, 275 | 'show-git': { 276 | spoken: 'code git', 277 | description: 'open git menu in vscode', 278 | continuous: false, 279 | action: function () { 280 | this.executeVSCodeCommand('workbench.view.git'); 281 | } 282 | }, 283 | 'show-search': { 284 | spoken: 'code search', 285 | description: 'open search menu in vscode', 286 | continuous: false, 287 | action: function () { 288 | this.executeVSCodeCommand('workbench.view.search'); 289 | } 290 | }, 291 | 'show-debug': { 292 | spoken: 'code debug', 293 | description: 'open debug menu in vscode', 294 | continuous: false, 295 | action: function () { 296 | this.executeVSCodeCommand('workbench.view.debug'); 297 | } 298 | }, 299 | 'show-extensions': { 300 | spoken: 'code extensions', 301 | description: 'open extensions menu in vscode', 302 | continuous: false, 303 | action: function () { 304 | this.executeVSCodeCommand('workbench.view.extensions'); 305 | } 306 | }, 307 | 'show-terminal': { 308 | spoken: 'code terminal', 309 | description: 'open terminal in vscode', 310 | continuous: false, 311 | action: function () { 312 | this.executeVSCodeCommand('workbench.action.terminal.toggleTerminal'); 313 | } 314 | } 315 | }) 316 | 317 | 318 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "atomic_rpc": "git+https://github.com/dimatter/atomic_rpc.git" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "", 14 | "license": "ISC" 15 | } 16 | -------------------------------------------------------------------------------- /remote_vs.js: -------------------------------------------------------------------------------- 1 | const rpc = require('atomic_rpc'); 2 | 3 | class RemoteVS { 4 | constructor() { 5 | this.remote = new rpc({ 6 | server: true, 7 | port: 7778 8 | }); 9 | 10 | this.remote.initialize(); 11 | } 12 | 13 | call() { 14 | this.remote.call.apply(this.remote, arguments); 15 | } 16 | 17 | expose() { 18 | this.remote.expose.apply(this.remote, arguments); 19 | } 20 | } 21 | 22 | module.exports = new RemoteVS(); 23 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "atomic_rpc@git+https://github.com/dimatter/atomic_rpc.git": 6 | version "2.0.2" 7 | resolved "git+https://github.com/dimatter/atomic_rpc.git#871dd5beba979bc7f11127d1d4f1fbc4b1cd9add" 8 | dependencies: 9 | lodash "^4.11.1" 10 | ws "^1.1.0" 11 | 12 | lodash@^4.11.1: 13 | version "4.17.4" 14 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 15 | 16 | options@>=0.0.5: 17 | version "0.0.6" 18 | resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" 19 | 20 | ultron@1.0.x: 21 | version "1.0.2" 22 | resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" 23 | 24 | ws@^1.1.0: 25 | version "1.1.4" 26 | resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.4.tgz#57f40d036832e5f5055662a397c4de76ed66bf61" 27 | dependencies: 28 | options ">=0.0.5" 29 | ultron "1.0.x" 30 | --------------------------------------------------------------------------------