├── .gitignore ├── contrib ├── find.gif ├── icon.png ├── findSelected.gif ├── findSelectedMenu.gif ├── findSelectedShortcut.gif └── icon.svg ├── .vscodeignore ├── tsconfig.json ├── LICENSE ├── README.md ├── package.json └── src └── extension.ts /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | out/ 3 | *.vsix 4 | -------------------------------------------------------------------------------- /contrib/find.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chubin/vscode-snippet/HEAD/contrib/find.gif -------------------------------------------------------------------------------- /contrib/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chubin/vscode-snippet/HEAD/contrib/icon.png -------------------------------------------------------------------------------- /contrib/findSelected.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chubin/vscode-snippet/HEAD/contrib/findSelected.gif -------------------------------------------------------------------------------- /contrib/findSelectedMenu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chubin/vscode-snippet/HEAD/contrib/findSelectedMenu.gif -------------------------------------------------------------------------------- /contrib/findSelectedShortcut.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chubin/vscode-snippet/HEAD/contrib/findSelectedShortcut.gif -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | # Ignore everything 2 | * 3 | */** 4 | 5 | # Whitelist what you need 6 | !contrib/icon.png 7 | !out/extension.js 8 | !CHANGELOG.md 9 | !LICENSE 10 | !README.md 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src" 11 | }, 12 | "include": [ 13 | "src" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Matthias Endler 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vscode-snippet 2 | 3 | [![The MIT License](https://img.shields.io/badge/license-MIT-orange.svg?style=flat-square)](http://opensource.org/licenses/MIT) 4 | [![GitHub](https://img.shields.io/github/release/mre/vscode-snippet.svg?style=flat-square)](https://github.com/mre/vscode-snippet/releases) 5 | [![Visual Studio Marketplace](https://vsmarketplacebadge.apphb.com/installs/vscode-snippet.Snippet.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=vscode-snippet.Snippet) 6 | 7 | A Visual Studio Code extension for [cht.sh](https://cht.sh/). 8 | 9 | ## Features 10 | 11 | * Zero configuration: works out of the box. 12 | * Automatically detects programming language from current editor window. 13 | 14 | ## Config options 15 | 16 | * `openInNewEditor`: open snippets or in new editor window (default) in line with current document. 17 | * `verbose`: add comments around code snippets. 18 | 19 | ## Installation 20 | 21 | Install this extension from the [VSCode 22 | Marketplace](https://marketplace.visualstudio.com/items?itemName=vscode-snippet.Snippet) 23 | 24 | ## Usage 25 | 26 | ## Search for a snippet 27 | 28 | 1. Hit ⌘ Command + ⇧ Shift + p 29 | 2. Run `Snippet: Find`. 30 | 3. Type your query and hit enter. 31 | 32 | ![Preview](/contrib/find.gif) 33 | 34 | ### Search for snippet based on selected text 35 | 36 | 1. Select some text in an editor window. 37 | 2. Right click and choose "Find snippet from selected text" 38 | 39 | ![Preview](/contrib/findSelectedMenu.gif) 40 | 41 | Alternatively, you can also run the `Snippet: Find Selected Text` from the 42 | command menu: 43 | 44 | ![Preview](/contrib/findSelected.gif) 45 | 46 | You can configure a keyboard shortcut. By default this is ⌘ Command + ⇧ Shift + s: 47 | 48 | ![Preview](/contrib/findSelectedShortcut.gif) 49 | 50 | ## Contributing 51 | 52 | This plugin is far from feature-complete. 53 | If you want to improve it, feel free to pick one of the [open issues](https://github.com/mre/vscode-snippet/issues) and give it a shot. 54 | In case you need any help, just add a comment to the issue to get a conversation started. :smiley: 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Snippet", 3 | "version": "0.2.3", 4 | "publisher": "vscode-snippet", 5 | "engines": { 6 | "vscode": "^1.19.0" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/mre/vscode-snippet.git" 11 | }, 12 | "license": "MIT", 13 | "displayName": "Snippet", 14 | "description": "Insert a snippet from cht.sh for Python, JavaScript, Ruby, C#, Go, Rust (and any other language)", 15 | "icon": "contrib/icon.png", 16 | "galleryBanner": { 17 | "color": "#6cfff9", 18 | "theme": "light" 19 | }, 20 | "categories": [ 21 | "Programming Languages", 22 | "Snippets", 23 | "Other" 24 | ], 25 | "tags": [ 26 | "python", 27 | "ruby", 28 | "php", 29 | "rust", 30 | "C#", 31 | "go", 32 | "haskell", 33 | "typescript", 34 | "shell", 35 | "javascript", 36 | "node", 37 | "snippet", 38 | "examples", 39 | "documentation", 40 | "help", 41 | "tldr", 42 | "helper", 43 | "cheatsheet" 44 | ], 45 | "main": "./out/extension", 46 | "contributes": { 47 | "commands": [ 48 | { 49 | "title": "Find", 50 | "command": "snippet.find", 51 | "category": "Snippet" 52 | }, 53 | { 54 | "title": "Find Inplace", 55 | "command": "snippet.findInplace", 56 | "category": "Snippet" 57 | }, 58 | { 59 | "title": "Find in new editor window", 60 | "command": "snippet.findInNewEditor", 61 | "category": "Snippet" 62 | }, 63 | { 64 | "title": "Find snippet from selected text", 65 | "command": "snippet.findSelectedText", 66 | "category": "Snippet" 67 | } 68 | ], 69 | "configuration": { 70 | "title": "Snippet Configuration", 71 | "properties": { 72 | "snippet.openInNewEditor": { 73 | "type": "boolean", 74 | "default": true, 75 | "description": "Open snippet result in new editor." 76 | }, 77 | "snippet.verbose": { 78 | "type": "boolean", 79 | "default": false, 80 | "description": "Also show explanations for code snippets." 81 | } 82 | } 83 | }, 84 | "menus": { 85 | "editor/context": [ 86 | { 87 | "when": "editorHasSelection", 88 | "command": "snippet.findSelectedText", 89 | "group": "1_modification" 90 | } 91 | ] 92 | }, 93 | "keybindings": [ 94 | { 95 | "command": "snippet.findSelectedText", 96 | "key": "ctrl+shift+s", 97 | "mac": "cmd+shift+s", 98 | "when": "editorHasSelection" 99 | } 100 | ] 101 | }, 102 | "activationEvents": [ 103 | "onCommand:snippet.find", 104 | "onCommand:snippet.findSelectedText", 105 | "onCommand:snippet.findInplace", 106 | "onCommand:snippet.findInNewEditor" 107 | ], 108 | "devDependencies": { 109 | "typescript": "^2.6.1", 110 | "vscode": "^1.1.6", 111 | "@types/node": "^7.0.43", 112 | "@types/mocha": "^2.2.42" 113 | }, 114 | "scripts": { 115 | "vscode:prepublish": "npm run compile", 116 | "compile": "tsc -p ./", 117 | "watch": "tsc -watch -p ./", 118 | "postinstall": "node ./node_modules/vscode/bin/install", 119 | "test": "npm run compile && node ./node_modules/vscode/bin/test" 120 | } 121 | } -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import * as cp from 'child_process' 3 | import * as http from 'http' 4 | import * as vscode from 'vscode' 5 | 6 | export function activate(ctx: vscode.ExtensionContext) { 7 | ctx.subscriptions.push(vscode.commands.registerCommand( 8 | 'snippet.find', find)) 9 | ctx.subscriptions.push(vscode.commands.registerCommand( 10 | 'snippet.findInplace', findInplace)) 11 | ctx.subscriptions.push(vscode.commands.registerCommand( 12 | 'snippet.findInNewEditor', findInNewEditor)) 13 | ctx.subscriptions.push(vscode.commands.registerCommand( 14 | 'snippet.findSelectedText', findSelectedText)) 15 | } 16 | 17 | function find() { 18 | let configuration = vscode.workspace.getConfiguration('snippet') 19 | let openInNewEditor: boolean = configuration["openInNewEditor"] 20 | 21 | vscode.window.showInputBox() 22 | .then(query => { 23 | asyncRequest(query, function (data) { 24 | insertText(data, openInNewEditor) 25 | }) 26 | }); 27 | } 28 | 29 | function findInplace() { 30 | vscode.window.showInputBox() 31 | .then(query => { 32 | asyncRequest(query, function (data) { 33 | insertText(data, false) 34 | }) 35 | }); 36 | } 37 | 38 | function findInNewEditor() { 39 | vscode.window.showInputBox() 40 | .then(query => { 41 | asyncRequest(query, function (data) { 42 | insertText(data, true) 43 | }) 44 | }); 45 | } 46 | 47 | function findSelectedText() { 48 | let editor = vscode.window.activeTextEditor 49 | if (!editor) { 50 | vscode.window.showErrorMessage('There is no open editor window'); 51 | return 52 | } 53 | 54 | let selection = editor.selection; 55 | let query = editor.document.getText(selection); 56 | 57 | let configuration = vscode.workspace.getConfiguration('snippet') 58 | let openInNewEditor: boolean = configuration["openInNewEditor"] 59 | 60 | asyncRequest(query, function (data) { 61 | insertText(data, openInNewEditor) 62 | }) 63 | } 64 | 65 | 66 | var requestCache = new Object() 67 | function asyncRequest(queryRaw: string, callback: (data: string) => void) { 68 | let query = encodeURI(queryRaw.replace(" ", "+").replace("\t", "+")) 69 | let language = vscode.window.activeTextEditor.document.languageId 70 | 71 | let configuration = vscode.workspace.getConfiguration('snippet') 72 | let verbose: boolean = configuration["verbose"] 73 | let params = "QT" 74 | if (verbose) { 75 | params = "qT" 76 | } 77 | 78 | let path = `/${language}/${query}?${params}&style=bw`; 79 | 80 | let data = requestCache[path] 81 | if (data) { 82 | callback(data) 83 | return 84 | } 85 | 86 | console.log(`asyncRequest: ${query}`) 87 | 88 | http.get({ 89 | 'host': 'cht.sh', 90 | 'path': path, 91 | // Fake user agent to get plain-text output. 92 | // See https://github.com/chubin/cheat.sh/blob/1e21d96d065b6cce7d198c1a3edba89081c78a0b/bin/srv.py#L47 93 | 'headers': { 94 | 'User-Agent': 'curl/7.43.0' 95 | } 96 | }, function (message) { 97 | let data = "" 98 | 99 | message.on("data", function (chunk) { 100 | data += chunk 101 | }) 102 | 103 | message.on("end", function () { 104 | requestCache[path] = data 105 | callback(data) 106 | }) 107 | }).on("error", function (err) { 108 | vscode.window.showInformationMessage(err.message) 109 | }) 110 | } 111 | 112 | function insertText(content: string, openInNewEditor = true) { 113 | 114 | if (openInNewEditor) { 115 | let language = vscode.window.activeTextEditor.document.languageId 116 | vscode.workspace.openTextDocument({ language, content }).then( 117 | document => vscode.window.showTextDocument(document, vscode.ViewColumn.Two) 118 | ) 119 | } 120 | else { 121 | let editor = vscode.window.activeTextEditor 122 | if (!editor) { 123 | vscode.window.showErrorMessage('There is no open editor window'); 124 | return; 125 | } 126 | editor.edit( 127 | edit => editor.selections.forEach( 128 | selection => { 129 | edit.insert(selection.end, "\n" + content); 130 | } 131 | ) 132 | ); 133 | } 134 | } -------------------------------------------------------------------------------- /contrib/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 25 | 29 | 30 | 33 | 37 | 38 | 41 | 45 | 46 | 49 | 53 | 54 | 57 | 61 | 62 | 65 | 69 | 70 | 73 | 77 | 78 | 85 | 88 | 91 | 93 | 95 | 98 | 106 | 107 | 108 | 109 | 110 | 111 | 118 | 124 | 125 | 128 | 132 | 133 | 136 | 140 | 141 | 144 | 148 | 149 | 152 | 156 | 157 | 160 | 164 | 165 | 168 | 172 | 173 | 176 | 180 | 181 | 184 | 188 | 189 | 196 | 199 | 202 | 204 | 206 | 209 | 217 | 218 | 219 | 220 | 221 | 222 | 229 | 235 | 236 | 239 | 243 | 244 | 247 | 251 | 252 | 255 | 259 | 260 | 263 | 267 | 268 | 271 | 275 | 276 | 279 | 283 | 284 | 287 | 291 | 292 | 299 | 302 | 305 | 307 | 309 | 312 | 320 | 321 | 322 | 323 | 324 | 325 | 332 | 338 | 339 | 342 | 346 | 347 | 350 | 354 | 355 | 358 | 362 | 363 | 366 | 370 | 371 | 374 | 378 | 379 | 382 | 386 | 387 | 394 | 397 | 400 | 402 | 404 | 407 | 415 | 416 | 417 | 418 | 419 | 420 | 427 | 433 | 434 | 437 | 441 | 442 | 445 | 449 | 450 | 453 | 457 | 458 | 461 | 465 | 466 | 469 | 473 | 474 | 477 | 481 | 482 | 485 | 489 | 490 | 497 | 500 | 503 | 505 | 507 | 510 | 518 | 519 | 520 | 521 | 522 | 523 | 530 | 536 | 537 | 540 | 544 | 545 | 548 | 552 | 553 | 556 | 560 | 561 | 564 | 568 | 569 | 572 | 576 | 577 | 580 | 584 | 585 | 588 | 592 | 593 | 600 | 603 | 606 | 608 | 610 | 613 | 621 | 622 | 623 | 624 | 625 | 626 | 633 | 639 | 640 | 643 | 647 | 648 | 651 | 655 | 656 | 659 | 663 | 664 | 667 | 671 | 672 | 675 | 679 | 680 | 683 | 687 | 688 | 689 | 707 | 709 | 710 | 712 | image/svg+xml 713 | 715 | 716 | 717 | 718 | 719 | 723 | 726 | 730 | 732 | 735 | 737 | 742 | 747 | 752 | 757 | 762 | 767 | 768 | 770 | 771 | 772 | 773 | --------------------------------------------------------------------------------