├── .gitignore ├── .travis.yml ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── README.md ├── icon.png ├── package.json ├── src ├── CopySyntax.ts └── extension.ts ├── tsconfig.json ├── typings ├── node.d.ts └── vscode-typings.d.ts ├── usage.gif ├── usage.png └── vsc-extension-quickstart.md /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode 4 | .vscode-test 5 | .idea -------------------------------------------------------------------------------- /.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 -------------------------------------------------------------------------------- /.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 | "outDir": "${workspaceRoot}/out/src", 14 | "preLaunchTask": "npm" 15 | }, 16 | { 17 | "name": "Launch Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "runtimeExecutable": "${execPath}", 21 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], 22 | "stopOnEntry": false, 23 | "sourceMaps": true, 24 | "outDir": "${workspaceRoot}/out/test", 25 | "preLaunchTask": "npm" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /.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 | .vscode-test/** 3 | typings/** 4 | out/test/** 5 | test/** 6 | src/** 7 | **/*.map 8 | .gitignore 9 | tsconfig.json 10 | vsc-extension-quickstart.md 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | 0.5.1 / 2017-03-04 3 | ================== 4 | 5 | * docs: add vscode 1.1.0 build-in support announcement 6 | 7 | 0.5.0 / 2016-10-24 8 | ================== 9 | 10 | * feat: change default config: fontsize: 24, showMessage: false 11 | 12 | 0.4.2 / 2016-10-12 13 | ================== 14 | 15 | * doc: rtf formater fontsize 16 | * chore: fix README code style 17 | * chore: markdown style fix 18 | 19 | 0.4.1 / 2016-09-27 20 | ================== 21 | 22 | * docs: add window tip 23 | * docs: update usage static 24 | * feat: static usage 25 | 26 | 0.4.0 / 2016-09-26 27 | ================== 28 | 29 | * feat: configuration flatten 30 | 31 | 0.3.0 / 2016-09-26 32 | ================== 33 | 34 | * init project 35 | 36 | 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # copy-syntax 2 | 3 | [![Marketplace Version](http://vsmarketplacebadge.apphb.com/version/atian25.copy-syntax.svg)](https://marketplace.visualstudio.com/items?itemName=atian25.copy-syntax) 4 | [![Installs](http://vsmarketplacebadge.apphb.com/installs/atian25.copy-syntax.svg)](https://marketplace.visualstudio.com/items?itemName=atian25.copy-syntax) 5 | [![Rating](http://vsmarketplacebadge.apphb.com/rating/atian25.copy-syntax.svg)](https://marketplace.visualstudio.com/items?itemName=atian25.copy-syntax) 6 | [![Build Status](https://img.shields.io/travis/atian25/vscode-copy-syntax.svg)](https://travis-ci.org/atian25/vscode-copy-syntax) 7 | 8 | copy your code with syntax highlight, can be used at your slide. 9 | 10 | > Now with vscode 1.10 it supports copy syntax without extra plugin. 11 | > https://code.visualstudio.com/updates/v1_10#_copy-with-syntax-highlighting 12 | > But it's copy as HTML format, maybe not work with keynote. 13 | > This Plugin copy as RTF format to make keynote happy. 14 | 15 | ![Usage](https://github.com/atian25/vscode-copy-syntax/raw/master/usage.png) 16 | 17 | ## Features 18 | 19 | - Copy code as RTF 20 | - Auto detect language: `markdown syntax` -> `vscode languageId` -> `file extension` 21 | - Support language to highlight 22 | - Use [pygmentize](http://pygments.org/docs/cmdline/) and [copy-paste](https://github.com/xavi-/node-copy-paste) 23 | 24 | > Known issues: Can't work in windows until `copy-paste` support [this feature](https://github.com/xavi-/node-copy-paste/issues/52) 25 | 26 | ## Usages 27 | 28 | ![Usage](https://github.com/atian25/vscode-copy-syntax/raw/master/usage.gif) 29 | - Open code file or select code snippet in Text Editor, then press `F1` and then select/type `Copy Syntax`, or right click the Text Editor and then click `Copy Syntax` in context menu, the code with syntax highlight will copy to clipboard. 30 | - To select language to run, use press `F1` and then select/type `Copy Syntax as ...`, then type the language: e.g `php, js, bash...` 31 | 32 | 33 | ## Installation 34 | 35 | - Press `F1` in VSCode, type `ext install` and then look for `copy-syntax`. 36 | - `python` is required by `pygmentize` 37 | 38 | ## Configuration 39 | 40 | - `copy-syntax.defaults.lang`: the default language is `js` 41 | - `copy-syntax.defaults.format`: currently is only support `rtf`, feel free to PR. 42 | - `copy-syntax.showMessage`: set to `false` to skip boring success message 43 | - `copy-syntax.formatters.rtf`: RtfFormatter options 44 | - `fonsize` is specified in half points. The default is 24 half-points, giving a size 12 font. 45 | - see http://pygments.org/docs/formatters/#RtfFormatter 46 | 47 | ```json 48 | { 49 | "copy-syntax.defaults.lang": "js", 50 | "copy-syntax.showMessage": false, 51 | "copy-syntax.formatters.rtf": { 52 | "style": "default", 53 | "fontsize": 24, 54 | "fontface": "Monaco" 55 | } 56 | } 57 | ``` 58 | 59 | ## Issues 60 | Submit the [issues](https://github.com/atian25/vscode-copy-syntax/issues) if you find any bug or have any suggestion. 61 | 62 | ## Contribution 63 | Fork the [repository](https://github.com/atian25/vscode-copy-syntax) and submit pull requests. 64 | 65 | ## Release Notes 66 | see [CHANGELOG](https://github.com/atian25/vscode-copy-syntax/blob/master/CHANGELOG.md) -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atian25/vscode-copy-syntax/59a96511596ec326892f4ea3f140efbdf2ebb0c8/icon.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copy-syntax", 3 | "displayName": "Copy Syntax", 4 | "description": "copy your code with syntax highlight, can be used at your slide.", 5 | "version": "0.5.1", 6 | "publisher": "atian25", 7 | "engines": { 8 | "vscode": "^1.5.0" 9 | }, 10 | "categories": [ 11 | "Other" 12 | ], 13 | "icon": "icon.png", 14 | "license": "MIT", 15 | "homepage": "https://github.com/atian25/vscode-copy-syntax", 16 | "repository": "https://github.com/atian25/vscode-copy-syntax", 17 | "activationEvents": [ 18 | "onCommand:copySyntax.copy", 19 | "onCommand:copySyntax.copyWithOptions" 20 | ], 21 | "main": "./out/src/extension", 22 | "contributes": { 23 | "commands": [ 24 | { 25 | "command": "copySyntax.copy", 26 | "title": "Copy syntax" 27 | }, 28 | { 29 | "command": "copySyntax.copyWithOptions", 30 | "title": "Copy syntax as ..." 31 | } 32 | ], 33 | 34 | "menus": { 35 | "editor/context": [ 36 | { 37 | "command": "copySyntax.copy", 38 | "group": "9_cutcopypaste" 39 | }, 40 | { 41 | "command": "copySyntax.copyWithOptions", 42 | "group": "9_cutcopypaste" 43 | } 44 | ] 45 | }, 46 | 47 | "configuration": { 48 | "type": "object", 49 | "title": "copy-syntax extension configuration", 50 | "properties": { 51 | "copy-syntax.defaults.lang": { 52 | "description": "source language/lexer name, default as js", 53 | "type": "string", 54 | "default": "js" 55 | }, 56 | 57 | "copy-syntax.defaults.format": { 58 | "description": "output formatter name, default as rtf, see http://pygments.org/docs/formatters", 59 | "type": "string", 60 | "default": "rtf" 61 | }, 62 | 63 | "copy-syntax.defaults.python": { 64 | "description": "the full path to the `python` command on the current system", 65 | "type": "string", 66 | "default": "python" 67 | }, 68 | 69 | "copy-syntax.showMessage": { 70 | "description": "set to `false` to skip the boring success message", 71 | "type": "boolean", 72 | "default": false 73 | }, 74 | 75 | "copy-syntax.formatters.rtf": { 76 | "description": "custom style/fontsize/fontface for RtfFormatter, see http://pygments.org/docs/formatters/#RtfFormatter", 77 | "type": "object", 78 | "default": { 79 | "style": "default", 80 | "fontsize": 24, 81 | "fontface": "Monaco" 82 | } 83 | }, 84 | 85 | "copy-syntax.formatters.html": { 86 | "description": "see http://pygments.org/docs/formatters/#HtmlFormatter", 87 | "type": "object", 88 | "default": { 89 | "style": "default" 90 | } 91 | }, 92 | 93 | "copy-syntax.formatters.img": { 94 | "description": "see http://pygments.org/docs/formatters/#ImageFormatter", 95 | "type": "object", 96 | "default": { 97 | "style": "default" 98 | } 99 | }, 100 | 101 | "copy-syntax.mapping.markdown": { 102 | "description": "markdown code to pygments lang option", 103 | "type": "object", 104 | "default": { 105 | "sh": "bash", 106 | "shell": "bash" 107 | } 108 | }, 109 | 110 | "copy-syntax.mapping.language": { 111 | "description": "vscode languageId to pygments lang option, see http://pygments.org/docs/lexers/", 112 | "type": "object", 113 | "default": { 114 | "typescript": "js" 115 | } 116 | }, 117 | 118 | "copy-syntax.mapping.fileExtension": { 119 | "description": "file extension to pygments lang option", 120 | "type": "object", 121 | "default": { 122 | "ts": "js" 123 | } 124 | } 125 | } 126 | } 127 | }, 128 | "scripts": { 129 | "vscode:prepublish": "node ./node_modules/vscode/bin/compile", 130 | "compile": "node ./node_modules/vscode/bin/compile -watch -p ./", 131 | "postinstall": "node ./node_modules/vscode/bin/install", 132 | "test": "node ./node_modules/vscode/bin/test" 133 | }, 134 | "devDependencies": { 135 | "typescript": "^2.0.3", 136 | "vscode": "^1.0.1" 137 | }, 138 | "dependencies": { 139 | "copy-paste": "^1.3.0", 140 | "pygmentize-bundled": "^2.3.0" 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/CopySyntax.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | const path = require('path'); 6 | const pygmentize = require('pygmentize-bundled'); 7 | const ncp = require('copy-paste'); 8 | 9 | export default class CopySyntax { 10 | 11 | exec(code?:String, options: { lang?:String, format?:String, options?} = {}, callback?:Function) { 12 | const editor = vscode.window.activeTextEditor; 13 | 14 | // get code string 15 | const selection = editor.selection; 16 | if (!selection.isEmpty) { 17 | code = editor.document.getText(selection); 18 | } else { 19 | code = editor.document.getText(); 20 | } 21 | 22 | if (!options.lang) { 23 | // guest language 24 | const fileName = editor.document.fileName; 25 | const extName = (path.extname(fileName) + '').replace(/^\./, ''); 26 | const languageId = editor.document.languageId; 27 | let lang; 28 | 29 | // get language by markdown code: ```javascript 30 | if (/^```(.*)\s*/.test(code.toString())) { 31 | lang = this.config.get('mapping.markdown')[RegExp.$1] || RegExp.$1; 32 | code = code.replace(/^```.*\r?\n/, '').replace(/```\s*\r?\n?$/, ''); 33 | } 34 | 35 | // get language by vscode languageId 36 | if (!lang && languageId && languageId !== 'plaintext') { 37 | lang = this.config.get('mapping.language')[languageId] || languageId; 38 | } 39 | 40 | // get language by file extension 41 | if (!lang && extName) { 42 | lang = this.config.get('mapping.fileExtension')[extName] || extName 43 | } 44 | options.lang = lang || this.config.get('defaults.lang') || undefined; 45 | } 46 | 47 | // normalize options 48 | options.format = options.format || this.config.get('defaults.format').toString(); 49 | options.options = Object.assign({}, this.config.get('formatters.' + options.format), options.options); 50 | 51 | // default callback handler 52 | if (!callback) { 53 | callback = (err, result) => { 54 | // Display a message box to the user 55 | if (err) { 56 | console.warn(err); 57 | vscode.window.showErrorMessage(err.message); 58 | } else { 59 | const msg = `copy-syntax (${options.lang}, ${options.format}) success!`; 60 | // console.log(result); 61 | if (this.config.get('showMessage')) { 62 | vscode.window.showInformationMessage(msg); 63 | } 64 | vscode.window.setStatusBarMessage(msg, 3000); 65 | } 66 | }; 67 | } 68 | 69 | console.log(`copy syntax with options: ${JSON.stringify(options)}`); 70 | 71 | // highlight 72 | pygmentize(options, code, (err, result) => { 73 | if (err) { 74 | return callback(err, result && result.toString()); 75 | } else { 76 | // copy to clipboard 77 | ncp.copy(result.toString(), callback); 78 | } 79 | }); 80 | } 81 | 82 | get config() { 83 | return vscode.workspace.getConfiguration('copy-syntax'); 84 | } 85 | } -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as vscode from 'vscode'; 4 | import CopySyntax from './CopySyntax'; 5 | 6 | // this method is called when your extension is activated 7 | // your extension is activated the very first time the command is executed 8 | export function activate(context: vscode.ExtensionContext) { 9 | const copySyntax = new CopySyntax(); 10 | 11 | const ext = vscode.extensions.all; 12 | 13 | console.log('Congratulations, your extension "vscode-copy-syntax" is now active!'); 14 | 15 | context.subscriptions.push(vscode.commands.registerCommand('copySyntax.copy', () => { 16 | copySyntax.exec(); 17 | })); 18 | 19 | context.subscriptions.push(vscode.commands.registerCommand('copySyntax.copyWithOptions', () => { 20 | const config = vscode.workspace.getConfiguration('copy-syntax'); 21 | const defaultLanguage = config.get('defaults.lang').toString(); 22 | vscode.window.showInputBox({ 23 | prompt: 'copy syntax as language', 24 | placeHolder: 'default as ' + defaultLanguage 25 | }).then(result => { 26 | copySyntax.exec(null, { lang: result || defaultLanguage }); 27 | }); 28 | })); 29 | } 30 | 31 | // this method is called when your extension is deactivated 32 | export function deactivate() { 33 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "outDir": "out", 6 | "noLib": true, 7 | "sourceMap": true, 8 | "rootDir": "." 9 | }, 10 | "exclude": [ 11 | "node_modules", 12 | ".vscode-test" 13 | ] 14 | } -------------------------------------------------------------------------------- /typings/node.d.ts: -------------------------------------------------------------------------------- 1 | /// -------------------------------------------------------------------------------- /typings/vscode-typings.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /usage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atian25/vscode-copy-syntax/59a96511596ec326892f4ea3f140efbdf2ebb0c8/usage.gif -------------------------------------------------------------------------------- /usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atian25/vscode-copy-syntax/59a96511596ec326892f4ea3f140efbdf2ebb0c8/usage.png -------------------------------------------------------------------------------- /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 --------------------------------------------------------------------------------