├── .gitattributes
├── .gitignore
├── .vscode
├── extensions.json
├── launch.json
├── settings.json
└── tasks.json
├── .vscodeignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── images
├── icon.png
└── open-in-editor-vscode.gif
├── package.json
├── src
├── extension.ts
└── test
│ ├── extension.test.ts
│ └── index.ts
└── tsconfig.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set default behavior to automatically normalize line endings.
2 | * text=auto
3 |
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | node_modules
3 | .vscode-test/
4 | *.vsix
5 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See http://go.microsoft.com/fwlink/?LinkId=827846
3 | // for the documentation about the extensions.json format
4 | "recommendations": [
5 | "eg2.tslint"
6 | ]
7 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | // A launch configuration that compiles the extension and then opens it inside a new window
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | {
6 | "version": "0.2.0",
7 | "configurations": [
8 | {
9 | "name": "Extension",
10 | "type": "extensionHost",
11 | "request": "launch",
12 | "runtimeExecutable": "${execPath}",
13 | "args": [
14 | "--extensionDevelopmentPath=${workspaceFolder}"
15 | ],
16 | "outFiles": [
17 | "${workspaceFolder}/out/**/*.js"
18 | ],
19 | "preLaunchTask": "npm: watch"
20 | },
21 | {
22 | "name": "Extension Tests",
23 | "type": "extensionHost",
24 | "request": "launch",
25 | "runtimeExecutable": "${execPath}",
26 | "args": [
27 | "--extensionDevelopmentPath=${workspaceFolder}",
28 | "--extensionTestsPath=${workspaceFolder}/out/test"
29 | ],
30 | "outFiles": [
31 | "${workspaceFolder}/out/test/**/*.js"
32 | ],
33 | "preLaunchTask": "npm: watch"
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/.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 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts
10 | "typescript.tsc.autoDetect": "off"
11 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | // See https://go.microsoft.com/fwlink/?LinkId=733558
2 | // for the documentation about the tasks.json format
3 | {
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "type": "npm",
8 | "script": "watch",
9 | "problemMatcher": "$tsc-watch",
10 | "isBackground": true,
11 | "presentation": {
12 | "reveal": "never"
13 | },
14 | "group": {
15 | "kind": "build",
16 | "isDefault": true
17 | }
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .vscode/**
2 | .vscode-test/**
3 | out/test/**
4 | out/**/*.map
5 | src/**
6 | .gitignore
7 | tsconfig.json
8 | vsc-extension-quickstart.md
9 | tslint.json
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 |
6 | ## [1.0.1](https://github.com/generalov/open-in-editor-vscode/compare/v1.0.0...v1.0.1) (2018-06-14)
7 |
8 |
9 | ### Bug Fixes
10 |
11 | * open with keyboard shotcut ([3fa2a69](https://github.com/generalov/open-in-editor-vscode/commit/3fa2a69))
12 |
13 |
14 |
15 |
16 | # [1.0.0](https://github.com/generalov/open-in-editor-vscode/compare/v0.9.7...v1.0.0) (2018-06-14)
17 |
18 |
19 | ### Bug Fixes
20 |
21 | * vscode 1.24 ([c60054a](https://github.com/generalov/open-in-editor-vscode/commit/c60054a))
22 |
23 |
24 |
25 |
26 | ## [0.9.7](https://github.com/generalov/open-in-editor-vscode/compare/v0.9.6...v0.9.7) (2017-08-03)
27 |
28 |
29 | ### Features
30 |
31 | * open the current file with different editors from different shortcuts (fixes [#1](https://github.com/generalov/open-in-editor-vscode/issues/1)). ([ac6fde1](https://github.com/generalov/open-in-editor-vscode/commit/ac6fde1))
32 |
33 |
34 |
35 |
36 | ## [0.9.6](https://github.com/generalov/open-in-editor-vscode/compare/v0.9.5...v0.9.6) (2017-05-17)
37 |
38 |
39 |
40 |
41 | ## [0.9.5](https://github.com/generalov/open-in-editor-vscode/compare/v0.9.4...v0.9.5) (2017-05-12)
42 |
43 |
44 |
45 |
46 | ## [0.9.4](https://github.com/generalov/open-in-editor-vscode/compare/v0.9.3...v0.9.4) (2017-05-10)
47 |
48 |
49 |
50 |
51 | ## [0.9.3](https://github.com/generalov/open-in-editor-vscode/compare/v0.9.2...v0.9.3) (2017-05-05)
52 |
53 |
54 |
55 |
56 | ## [0.9.2](https://github.com/generalov/open-in-editor-vscode/compare/0.9.2...v0.9.2) (2017-05-03)
57 |
58 |
59 |
60 |
61 | ## [0.9.1](https://github.com/generalov/open-in-editor-vscode/compare/0.9.1...v0.9.1) (2017-05-03)
62 |
63 |
64 |
65 |
66 | # 0.9.0 (2017-05-01)
67 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Evgeniy V. Generalov
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 | # Open in Editor extension for Visual Studio Code
2 |
3 | The extension enables you to open a file in an alternative IDE or editor.
4 |
5 | Editor support:
6 |
7 | - [Atom Editor](https://atom.io/)
8 | - [Emacs](https://www.gnu.org/software/emacs/)
9 | - [IDEA 14 Community Edition](https://www.jetbrains.com/idea/download/)
10 | - [Sublime Text](http://www.sublimetext.com/)
11 | - [PhpStorm](https://www.jetbrains.com/phpstorm/)
12 | - [Vim](http://www.vim.org/)
13 | - [Visual Studio](https://www.visualstudio.com/)
14 | - [WebStorm](https://www.jetbrains.com/webstorm/)
15 |
16 | You also can use any other editor that is able to open files from command line.
17 |
18 | ## Features
19 |
20 | - Editor context menu
21 | - File Explorer context menu
22 | - Put a cursor in the same position.
23 |
24 | 
25 |
26 | Use the menu in the editor's tab or the explorer or just press F1 and type `Open in External Editor`. The selected file will be opened in an existing session of an alternative editor and put a cursor in the same position as it was in VS Code.
27 |
28 | ## Keyboard Shortcut
29 |
30 | You can also use `Alt+Shift+E` to open the file in the alternative editor.
31 |
32 | ## Extension Settings
33 |
34 | This extension contributes the following settings:
35 |
36 | **`alt-editor.name`**: a string name of an editor.
37 |
38 | Supported names are:
39 |
40 | | Name | Editor |
41 | | -------------- | ------------------------------------------- |
42 | | `atom` | Atom Editor |
43 | | `emacs` | Emacs (via Terminal, Mac OS and Linux only) |
44 | | `idea14ce` | IDEA 14 CE |
45 | | `phpstorm` | PhpStorm |
46 | | `sublime` | Sublime Text |
47 | | `vim` | Vim (via Terminal, Mac OS and Linux only) |
48 | | `visualstudio` | Visual Studio |
49 | | `webstorm` | WebStorm |
50 |
51 | ### Advanced settings
52 |
53 | Use these setting if the editor currently is not supported or if the editor's path can't be detected automatically.
54 |
55 | **`alt-editor.binary`**: a string path to the editor binary
56 |
57 | **`alt-editor.args`**: a string of command line arguments which will be passed to the `binary`. The `args` can contain placeholders to be replaced by actual values. Supported placeholders: `{filename}`, `{line}` and `{column}`
58 |
59 | **`alt-editor.terminal`**: set this to `true` if the editor should be opened in a terminal. Mac OS and Linux are supported.
60 |
61 | ### Custom editors with key bindings
62 | Use custom [Keyboard Shortcuts](https://code.visualstudio.com/docs/getstarted/keybindings#_advanced-customization) to open the current file with different editors.
63 | ```
64 | [{
65 | "key": "shift+alt+v",
66 | "command": "alt-editor.openFile",
67 | "args": { "name": "vim" },
68 | "when": "editorTextFocus"
69 | }, {
70 | "key": "shift+alt+s",
71 | "command": "alt-editor.openFile",
72 | "args": { "name": "sublime" },
73 | "when": "editorTextFocus"
74 | }]
75 | ```
76 |
77 | ### Examples:
78 |
79 | #### Visual Studio
80 |
81 | Use the Visual Studio IDE as an alternative editor.
82 |
83 | "alt-editor.name": "visualstudio"
84 |
85 | #### Vim
86 |
87 | Override the default arguments to use a single instance of the Vim editor and open files in tabs.
88 |
89 | "alt-editor.name": "vim",
90 | "alt-editor.args": "--servername Code --remote-tab-silent \"+call cursor({line}, {column})\" {filename}"
91 |
92 | The Vim should be compiled with `+clientserver` flag. Please run the `vim --version` and check the output.
93 |
94 | ## For more information
95 |
96 | - Powered by [open-in-editor](https://github.com/lahmatiy/open-in-editor)
97 |
98 | **Enjoy!**
99 |
--------------------------------------------------------------------------------
/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/generalov/open-in-editor-vscode/700cb7268bc76c9d64beec88dd63adc01cfd4361/images/icon.png
--------------------------------------------------------------------------------
/images/open-in-editor-vscode.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/generalov/open-in-editor-vscode/700cb7268bc76c9d64beec88dd63adc01cfd4361/images/open-in-editor-vscode.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-in-editor-vscode",
3 | "displayName": "Open in Editor",
4 | "description": "Open a file in Visual Studio, Atom Editor, Emacs, IntelliJ IDEA Community Edition, Sublime Text, PhpStorm, Vim, WebStorm or any other external editor from VS Code.",
5 | "version": "1.0.1",
6 | "engines": {
7 | "vscode": "^1.11.0"
8 | },
9 | "publisher": "generalov",
10 | "license": "SEE LICENSE IN LICENSE",
11 | "keywords": [
12 | "open",
13 | "edit",
14 | "switch",
15 | "file",
16 | "editor"
17 | ],
18 | "categories": [
19 | "Other"
20 | ],
21 | "icon": "images/icon.png",
22 | "galleryBanner": {
23 | "color": "#ffffff",
24 | "theme": "light"
25 | },
26 | "repository": {
27 | "type": "git",
28 | "url": "https://github.com/generalov/open-in-editor-vscode.git"
29 | },
30 | "bugs": {
31 | "url": "https://github.com/generalov/open-in-editor-vscode/issues",
32 | "email": "e.generalov@gmail.com"
33 | },
34 | "activationEvents": [
35 | "onCommand:alt-editor.openFile"
36 | ],
37 | "contributes": {
38 | "commands": [
39 | {
40 | "command": "alt-editor.openFile",
41 | "title": "Open in External Editor"
42 | }
43 | ],
44 | "keybindings": [
45 | {
46 | "key": "Alt+Shift+E",
47 | "command": "alt-editor.openFile",
48 | "when": "editorTextFocus"
49 | }
50 | ],
51 | "menus": {
52 | "editor/context": [
53 | {
54 | "group": "navigation@99",
55 | "command": "alt-editor.openFile"
56 | }
57 | ],
58 | "editor/title/context": [
59 | {
60 | "group": "alt-editor@1",
61 | "command": "alt-editor.openFile"
62 | }
63 | ],
64 | "explorer/context": [
65 | {
66 | "group": "navigation@99",
67 | "command": "alt-editor.openFile"
68 | }
69 | ]
70 | },
71 | "configuration": {
72 | "type": "object",
73 | "title": "Open in External Editor configuration",
74 | "properties": {
75 | "alt-editor.name": {
76 | "type": [
77 | "string",
78 | null
79 | ],
80 | "enum": [
81 | "atom",
82 | "emacs",
83 | "idea14ce",
84 | "phpstorm",
85 | "sublime",
86 | "vim",
87 | "visualstudio",
88 | "webstorm",
89 | null
90 | ],
91 | "default": null,
92 | "description": "Editor to open a file. Once value is set, we try to detect a command to launch an editor."
93 | },
94 | "alt-editor.binary": {
95 | "type": [
96 | "string",
97 | null
98 | ],
99 | "default": null,
100 | "description": "Command to launch an editor."
101 | },
102 | "alt-editor.args": {
103 | "type": [
104 | "string",
105 | null
106 | ],
107 | "default": null,
108 | "description": "Option to specify arguments for a command. It can contain placeholders to be replaced by actual values. Supported placeholders: {filename}, {line} and {column}."
109 | },
110 | "alt-editor.terminal": {
111 | "type": [
112 | "boolean",
113 | null
114 | ],
115 | "default": null,
116 | "description": "Set to `true` if the editor to be opened in the terminal."
117 | }
118 | }
119 | }
120 | },
121 | "main": "./out/src/extension",
122 | "scripts": {
123 | "vscode:prepublish": "npm run compile",
124 | "compile": "tsc -p ./",
125 | "watch": "tsc -watch -p ./",
126 | "postinstall": "node ./node_modules/vscode/bin/install",
127 | "test": "node ./node_modules/vscode/bin/test",
128 | "release": "standard-version",
129 | "publish": "vsce publish"
130 | },
131 | "devDependencies": {
132 | "@types/mocha": "^2.2.42",
133 | "@types/node": "^7.0.43",
134 | "standard-version": "4.4.0",
135 | "tslint": "^5.8.0",
136 | "typescript": "^2.6.1",
137 | "vscode": "^1.1.6"
138 | },
139 | "dependencies": {
140 | "@generalov/open-in-editor": "^2.3.0"
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import * as vscode from 'vscode';
3 | import { configure as findEditor } from '@generalov/open-in-editor';
4 |
5 | const extension = 'alt-editor';
6 |
7 | interface EditorConfig {
8 | name?: String;
9 | binary?: String;
10 | args?: String;
11 | terminal?: Boolean;
12 | }
13 |
14 | interface EditorOptions {
15 | editor?: String;
16 | cmd?: String;
17 | pattern?: String;
18 | terminal?: Boolean;
19 | }
20 |
21 | interface Editor {
22 | open(path: String): Promise;
23 | }
24 |
25 | function getEditorOptions(config: EditorConfig): EditorOptions {
26 | const editorOptions: EditorOptions = {};
27 |
28 | if (config.name != null) {
29 | editorOptions.editor = String(config.name);
30 | }
31 | if (config.binary != null) {
32 | editorOptions.cmd = String(config.binary);
33 | }
34 | if (config.args != null) {
35 | editorOptions.pattern = String(config.args);
36 | }
37 | if (config.terminal != null) {
38 | editorOptions.terminal = Boolean(config.terminal);
39 | }
40 |
41 | return editorOptions;
42 | }
43 |
44 | function createEditor(editorOptions: EditorOptions) {
45 | return new Promise((resolve, reject) => {
46 | if (!Object.keys(editorOptions)) {
47 | reject(new Error(`No editor configuration found. Please check the "${extension}" settings.`));
48 | return;
49 | }
50 |
51 | const editor = findEditor(editorOptions);
52 |
53 | if (!editor) {
54 | reject(new Error(`External editor not found. Please check the "${extension}" settings.`));
55 | return;
56 | } else {
57 | resolve(editor);
58 | return;
59 | }
60 | });
61 | }
62 |
63 | function openFile(fileName: String, line: Number = 1, column: Number = 1, config: EditorConfig={}) {
64 | if (!config || Object.keys(config).length === 0) {
65 | config = vscode.workspace.getConfiguration(extension);
66 | }
67 | const options = getEditorOptions(config);
68 | const fileLoc = `${fileName}:${line}:${column}`;
69 | const intro = vscode.window.setStatusBarMessage(`Opening ${fileLoc}...`);
70 | const res = createEditor(options)
71 | .then((editor: Editor) => editor.open(fileLoc))
72 | .then((openResult: any) => {
73 | intro.dispose();
74 | vscode.window.setStatusBarMessage(`Opened ${fileLoc}`, 5000);
75 |
76 | return openResult;
77 | })
78 | .catch((err) => {
79 | vscode.window.showErrorMessage(`Can't open the file ${fileLoc}: ${err}`)
80 | .then(() => intro.dispose());
81 | });
82 |
83 | return res;
84 | }
85 |
86 | function openTextEditorFile(textEditor: vscode.TextEditor, config: EditorConfig) {
87 | if (textEditor.document.isUntitled) {
88 | vscode.window.showErrorMessage('Please save the file first.');
89 | return;
90 | }
91 |
92 | const position = textEditor.selection.active;
93 |
94 | return openFile(textEditor.document.fileName,
95 | position.line + 1,
96 | position.character + 1,
97 | config);
98 | }
99 |
100 |
101 | function openFileMenu(uri: vscode.Uri) {
102 | if (!uri || uri.scheme !== 'file' || !uri.fsPath) {
103 | vscode.window.showErrorMessage('Please select a local file.');
104 | return;
105 | }
106 |
107 | return openFile(uri.fsPath);
108 | }
109 |
110 | function openFileCommand(...args: any[]) {
111 | args = args.filter(Boolean)
112 | let uri: vscode.Uri = null;
113 | let editor: vscode.TextEditor = vscode.window.activeTextEditor;
114 | let config: EditorConfig = args.length === 2 ? args[1] : null;
115 |
116 | if (args.length) {
117 | if (args[0].scheme) {
118 | if (!vscode.window.activeTextEditor ||
119 | args[0].path !== vscode.window.activeTextEditor.document.fileName
120 | ) {
121 | uri = args[0]
122 | }
123 | } else if (args[0].document) {
124 | editor = args[0]
125 | } else {
126 | config = args[0]
127 | }
128 | }
129 |
130 | if (uri) {
131 | openFileMenu(uri)
132 | } else {
133 | openTextEditorFile(editor, config);
134 | }
135 | }
136 |
137 | export function activate(context: vscode.ExtensionContext) {
138 | context.subscriptions.push(vscode.commands.registerCommand(`${extension}.openFile`, openFileCommand));
139 | }
140 |
141 | export function deactivate() {
142 | }
143 |
--------------------------------------------------------------------------------
/src/test/extension.test.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Note: This example test is leveraging the Mocha test framework.
3 | // Please refer to their documentation on https://mochajs.org/ for help.
4 | //
5 |
6 | // The module 'assert' provides assertion methods from node
7 | import * as assert from 'assert';
8 |
9 | // You can import and use all API from the 'vscode' module
10 | // as well as import your extension to test it
11 | // import * as vscode from 'vscode';
12 | // import * as myExtension from '../extension';
13 |
14 | // Defines a Mocha test suite to group tests of similar kind together
15 | suite("Extension Tests", function () {
16 |
17 | // Defines a Mocha unit test
18 | test("Something 1", function() {
19 | assert.equal(-1, [1, 2, 3].indexOf(5));
20 | assert.equal(-1, [1, 2, 3].indexOf(0));
21 | });
22 | });
--------------------------------------------------------------------------------
/src/test/index.ts:
--------------------------------------------------------------------------------
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 | import * as testRunner from '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.ts (suite, test, etc.)
19 | useColors: true // colored output from test results
20 | });
21 |
22 | module.exports = testRunner;
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es6",
5 | "outDir": "out",
6 | "lib": [
7 | "es6"
8 | ],
9 | "sourceMap": true,
10 | "rootDir": "./",
11 | /* Strict Type-Checking Option */
12 | // "strict": true, /* enable all strict type-checking options */
13 | /* Additional Checks */
14 | // "noUnusedLocals": true /* Report errors on unused locals. */
15 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
16 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
17 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
18 | },
19 | "exclude": [
20 | "node_modules",
21 | ".vscode-test"
22 | ]
23 | }
--------------------------------------------------------------------------------