├── .editorconfig ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── .vscode └── launch.json ├── .vscodeignore ├── CHANGELOG.md ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── icon.png ├── package.json ├── src ├── extension.ts ├── managers │ ├── filepaths.spec.ts │ └── filepaths.ts ├── types │ └── index.ts └── utils │ └── prompt.ts ├── tsconfig.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = tab 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [{.travis.yml,appveyor.yml,npm-shrinkwrap.json,package.json}] 12 | indent_style = space 13 | indent_size = 2 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Environment 2 | 3 | * VSCode Version: ... 4 | * OS Version: ... 5 | 6 | ### Actual behavior 7 | 8 | ... 9 | 10 | ### Expected behavior 11 | 12 | ... 13 | 14 | ### Steps to reproduce 15 | 16 | ... 17 | 18 | ### Settings 19 | 20 | ```js 21 | // Paste your configuration here. 22 | ``` 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### What is the purpose of this pull request? 2 | 3 | ... 4 | 5 | ### What changes did you make? (Give an overview) 6 | 7 | ... 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs/ 3 | *.log 4 | npm-debug.log* 5 | 6 | # IDE & editors 7 | .idea 8 | .vscode 9 | 10 | # Dependency directory 11 | node_modules/ 12 | 13 | # Compiled and tempory files 14 | .tmp/ 15 | out/ 16 | 17 | # Other files 18 | package-lock.json 19 | yarn.lock 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '7' 5 | 6 | script: 7 | - npm run build 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "runtimeExecutable": "${execPath}", 9 | "args": [ 10 | "--extensionDevelopmentPath=${workspaceRoot}" 11 | ], 12 | "stopOnEntry": false, 13 | "outFiles": ["${workspaceRoot}/out"] 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | out/**/*.d.ts 2 | .editorconfig 3 | .gitignore 4 | package-lock.json 5 | yarn.lock 6 | tsconfig.json 7 | tslint.json 8 | .travis.yml 9 | 10 | .vscode 11 | src/** 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | We use [GitHub's Releases feature](https://github.com/blog/1547-release-your-software) for changelogs. 2 | 3 | See [the Releases section of our GitHub project](https://github.com/mrmlnc/vscode-duplicate/releases) for changelogs for each release version of this plugin. 4 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at dmalinochkin@rambler.ru. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to my package 2 | 3 | Welcome, and thank you for your interest in contributing to **vscode-duplicate**! 4 | 5 | Please note that this project is released with a [Contributor Code of Conduct](CODE-OF-CONDUCT.md). By participating in this project you agree to abide by its terms. 6 | 7 | ## Contribution Guidelines 8 | 9 | There are a couple of ways you can contribute to this repo: 10 | 11 | * **Ideas, feature requests and bugs**: We are open to all ideas and we want to get rid of bugs! Use the [Issues section](https://github.com/mrmlnc/vscode-duplicate/issues) to either report a new issue, provide your ideas or contribute to existing threads. 12 | * **Documentation**: Found a typo or strangely worded sentences? Submit a PR! 13 | * **Code**: Contribute bug fixes, features or design changes. 14 | 15 | ### Creating an Issue 16 | 17 | Before you create a new Issue: 18 | 19 | * Check the [Issues](https://github.com/mrmlnc/vscode-duplicate/issues) on Github to ensure one doesn't already exist. 20 | * Clearly describe the issue, including the steps to reproduce the issue. 21 | 22 | ### Making Changes 23 | 24 | #### Getting Started 25 | 26 | * Install [Node.js](https://nodejs.org/en/). 27 | * Fork the project and clone the fork repo. ([how to create fork?](https://help.github.com/articles/fork-a-repo/#fork-an-example-repository)). 28 | * Create a topic branch from the master branch. 29 | * Run `yarn` or `npm install` to install the application dependencies. 30 | 31 | #### Setup 32 | 33 | 1. Start watching: 34 | 35 | ``` 36 | $ npm run watch 37 | ``` 38 | 39 | 2. Make changes: 40 | 41 | ``` 42 | $ code . 43 | ``` 44 | 45 | 3. Run tests: 46 | 47 | ``` 48 | $ npm t 49 | ``` 50 | 51 | 4. Test your version of the extension: 52 | 53 | Press F5 in the editor and then test extension commands and functions. 54 | 55 | #### Commit 56 | 57 | Keep git commit messages clear and appropriate. You can use [Angular guide](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines). 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Denis Malinochkin 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-duplicate 2 | 3 | > Ability to duplicate files and directories in VS Code. 4 | 5 | ## Donate 6 | 7 | If you want to thank me, or promote your Issue. 8 | 9 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mrmlnc) 10 | 11 | > Sorry, but I have work and support for plugins and modules requires some time after work. I will be glad of your support or PR's. 12 | 13 | ## Install 14 | 15 | * Press F1 and `select Extensions: Install Extensions`. 16 | * Search for and select `duplicate`. 17 | 18 | See the [extension installation guide](https://code.visualstudio.com/docs/editor/extension-gallery) for details. 19 | 20 | ## Usage 21 | 22 | The first option: 23 | 24 | 1. Hover on a file or directory name in explorer. 25 | 2. Right-click and select `Duplicate file`. 26 | 3. Enter the new path for the duplicate. 27 | 28 | The second option: 29 | 30 | 1. Open the file. 31 | 2. Press `F1` and select `Duplicate file`. 32 | 3. Enter the new path for the duplicate. 33 | 34 | ## About file extension 35 | 36 | > :warning: If you do not specify a new extension, the previous **will be saved**. 37 | 38 | But you can use two special characters: 39 | 40 | * `!!ext` – don't preserve original extension. 41 | * `&&ext` – preserve original extension (available with `duplicate.keepOriginalExtension` option). 42 | 43 | For example: 44 | 45 | * `nameOfFile!!ext` – create filepath without original extension 46 | * `nameOfFile&&ext` – create filepath with original extension 47 | 48 | ## Supported settings 49 | 50 | #### duplicate.openFileAfterCopy 51 | 52 | * Type: `Boolean` 53 | * Default: `true` 54 | 55 | Automatically open newly copied files. 56 | 57 | #### duplicate.keepOriginalExtension 58 | 59 | * Type: `Boolean` 60 | * Default: `true` 61 | 62 | Keep original extension if it not specified. 63 | 64 | ## Keyboard shortcuts 65 | 66 | To change keyboard shortcuts, create a new rule in `File -> Preferences -> Keyboard Shortcuts`: 67 | 68 | ```json 69 | { 70 | "key": "ctrl+shift+d", 71 | "command": "duplicate.execute" 72 | } 73 | ``` 74 | 75 | ## Changelog 76 | 77 | See the [Releases section of our GitHub project](https://github.com/mrmlnc/vscode-duplicate/releases) for changelogs for each release version. 78 | 79 | ## License 80 | 81 | This software is released under the terms of the MIT license. 82 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrmlnc/vscode-duplicate/d1c083c66de6a25ef308b47e64fae13bea6f23ec/icon.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-duplicate", 3 | "displayName": "Duplicate action", 4 | "description": "Ability to duplicate files in VS Code", 5 | "version": "1.2.1", 6 | "publisher": "mrmlnc", 7 | "license": "MIT", 8 | "engines": { 9 | "vscode": "^1.13.0" 10 | }, 11 | "icon": "icon.png", 12 | "homepage": "https://github.com/mrmlnc/vscode-duplicate/blob/master/README.md", 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/mrmlnc/vscode-duplicate" 16 | }, 17 | "keywords": [ 18 | "duplicate", 19 | "copy", 20 | "file", 21 | "directory" 22 | ], 23 | "categories": [ 24 | "Other" 25 | ], 26 | "activationEvents": [ 27 | "onCommand:duplicate.execute" 28 | ], 29 | "main": "./out/extension.js", 30 | "contributes": { 31 | "commands": [ 32 | { 33 | "command": "duplicate.execute", 34 | "title": "Duplicate file or directory" 35 | } 36 | ], 37 | "menus": { 38 | "explorer/context": [ 39 | { 40 | "command": "duplicate.execute" 41 | } 42 | ], 43 | "editor/title/context": [ 44 | { 45 | "command": "duplicate.execute" 46 | } 47 | ] 48 | }, 49 | "configuration": { 50 | "type": "object", 51 | "title": "Duplicate Action Configuration", 52 | "properties": { 53 | "duplicate.openFileAfterCopy": { 54 | "type": "boolean", 55 | "default": true, 56 | "description": "Automatically open newly copied files" 57 | }, 58 | "duplicate.keepOriginalExtension": { 59 | "type": "boolean", 60 | "default": true, 61 | "description": "Keep original extension if it not specified" 62 | } 63 | } 64 | } 65 | }, 66 | "devDependencies": { 67 | "@types/fs-extra": "5.0.1", 68 | "@types/lodash.escaperegexp": "^4.1.3", 69 | "@types/mocha": "^5.0.0", 70 | "@types/node": "^9.6.2", 71 | "mocha": "^5.0.5", 72 | "tslint": "^5.9.1", 73 | "tslint-config-mrmlnc": "^1.0.0", 74 | "typescript": "^2.8.1", 75 | "vscode": "^1.1.14" 76 | }, 77 | "dependencies": { 78 | "fs-extra": "^5.0.0", 79 | "lodash.escaperegexp": "^4.1.2" 80 | }, 81 | "scripts": { 82 | "postinstall": "node ./node_modules/vscode/bin/install", 83 | "clean": "rimraf out", 84 | "lint": "tslint \"src/**/*.ts\" -p . -t stylish", 85 | "compile": "tsc", 86 | "test": "mocha \"out/**/*.spec.js\" -s 0", 87 | "build": "npm run clean && npm run lint && npm run compile && npm test", 88 | "watch": "npm run clean && npm run lint & npm run compile -- --sourceMap --watch" 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | 4 | import escapeRegExp = require('lodash.escaperegexp'); 5 | import * as vscode from 'vscode'; 6 | 7 | import * as filepaths from './managers/filepaths'; 8 | import * as promptUtils from './utils/prompt'; 9 | 10 | import { IPluginSettings } from './types'; 11 | 12 | /** 13 | * Open file after duplicate action. 14 | */ 15 | async function openFile(filepath: string): Promise { 16 | const document = await (vscode.workspace.openTextDocument(filepath) as Promise); 17 | 18 | return vscode.window.showTextDocument(document); 19 | } 20 | 21 | /** 22 | * Duplicate action. 23 | */ 24 | async function duplicator(uri: vscode.Uri, settings: IPluginSettings): Promise { 25 | const oldPath = uri.fsPath; 26 | const oldPathParsed = path.parse(oldPath); 27 | const oldPathStats = await fs.stat(oldPath); 28 | 29 | // Get a new name for the resource 30 | const newName = await promptUtils.name(oldPathParsed.name); 31 | if (!newName) { 32 | return; 33 | } 34 | 35 | // Get the new full path 36 | const newPath = filepaths.buildFilepath(oldPathParsed, oldPathStats, newName, settings); 37 | 38 | // If a user tries to copy a file on the same path 39 | if (uri.fsPath === newPath) { 40 | vscode.window.showErrorMessage('You can\'t copy a file or directory on the same path.'); 41 | 42 | return; 43 | } 44 | 45 | // Check if the current path exists 46 | const newPathExists = await fs.pathExists(newPath); 47 | if (newPathExists) { 48 | const userAnswer = await promptUtils.overwrite(newPath); 49 | if (!userAnswer) { 50 | return; 51 | } 52 | } 53 | 54 | try { 55 | await fs.copy(uri.fsPath, newPath); 56 | 57 | if (settings.openFileAfterCopy && oldPathStats.isFile()) { 58 | return openFile(newPath); 59 | } 60 | } catch (err) { 61 | const errMsgRegExp = new RegExp(escapeRegExp(oldPathParsed.dir), 'g'); 62 | const errMsg = err.message 63 | .replace(errMsgRegExp, '') 64 | .replace(/[\\|\/]/g, '') 65 | .replace(/`|'/g, '**'); 66 | 67 | vscode.window.showErrorMessage(`Error: ${errMsg}`); 68 | } 69 | 70 | return; 71 | } 72 | 73 | export function activate(context: vscode.ExtensionContext): void { 74 | const command = vscode.commands.registerCommand('duplicate.execute', (uri: vscode.TextDocument | vscode.Uri) => { 75 | const settings = vscode.workspace.getConfiguration().get('duplicate') as IPluginSettings; 76 | 77 | if (!uri || !(uri).fsPath) { 78 | const editor = vscode.window.activeTextEditor; 79 | if (!editor) { 80 | return; 81 | } 82 | 83 | return duplicator(editor.document.uri, settings); 84 | } 85 | 86 | return duplicator(uri, settings); 87 | }); 88 | 89 | context.subscriptions.push(command); 90 | } 91 | -------------------------------------------------------------------------------- /src/managers/filepaths.spec.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import * as path from 'path'; 3 | 4 | import * as manager from './filepaths'; 5 | 6 | function getBuildedFilepath(oldName: string, newName: string, isFile: boolean, keep: boolean): string { 7 | const oldPath = path.parse(`/Users/name/Documents/${oldName}`); 8 | 9 | return manager.buildFilepath( 10 | oldPath, 11 | { isFile: () => isFile } as any, /* tslint:disable-line no-any */ 12 | newName, 13 | { keepOriginalExtension: keep, openFileAfterCopy: false } 14 | ); 15 | } 16 | 17 | describe('Managers → Filepaths', () => { 18 | describe('.buildFilepath', () => { 19 | it('should build path to file', () => { 20 | const expected = '/Users/name/Documents/test.ts'; 21 | 22 | const actual = getBuildedFilepath('test.js', 'test.ts', true, true); 23 | 24 | assert.equal(actual, expected); 25 | }); 26 | 27 | it('should build path to directory', () => { 28 | const expected = '/Users/name/Documents/test-copy'; 29 | 30 | const actual = getBuildedFilepath('test', 'test-copy', false, true); 31 | 32 | assert.equal(actual, expected); 33 | }); 34 | 35 | it('should add original extension for new path of non-dot file', () => { 36 | const expected = '/Users/name/Documents/test.js'; 37 | 38 | const actual = getBuildedFilepath('test.js', 'test', true, true); 39 | 40 | assert.equal(actual, expected); 41 | }); 42 | 43 | it('should not add original extension for new path of non-dot file', () => { 44 | const expected = '/Users/name/Documents/test'; 45 | 46 | const actual = getBuildedFilepath('test.js', 'test', false, true); 47 | 48 | assert.equal(actual, expected); 49 | }); 50 | 51 | it('should add original extension for new path of dot file', () => { 52 | const expected = '/Users/name/Documents/.env.sample'; 53 | 54 | const actual = getBuildedFilepath('.env.sample', '.env', true, true); 55 | 56 | assert.equal(actual, expected); 57 | }); 58 | 59 | it('should not add original extension for new path of dot file', () => { 60 | const expected = '/Users/name/Documents/.env'; 61 | 62 | const actual = getBuildedFilepath('.env.sample', '.env', true, false); 63 | 64 | assert.equal(actual, expected); 65 | }); 66 | 67 | it('should not add original extension for new path of dot file with !!ext marker', () => { 68 | const expected = '/Users/name/Documents/.env'; 69 | 70 | const actual = getBuildedFilepath('.env.sample', '.env!!ext', true, true); 71 | 72 | assert.equal(actual, expected); 73 | }); 74 | 75 | it('should add original extension for new path of dot file with &&ext marker', () => { 76 | const expected = '/Users/name/Documents/.env.sample'; 77 | 78 | const actual = getBuildedFilepath('.env.sample', '.env&&ext', true, false); 79 | 80 | assert.equal(actual, expected); 81 | }); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /src/managers/filepaths.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as path from 'path'; 3 | 4 | import { IPluginSettings } from '../types'; 5 | 6 | export function buildFilepath(oldPath: path.ParsedPath, oldStat: fs.Stats, newName: string, settings: IPluginSettings): string { 7 | const newPath = path.parse(newName); 8 | 9 | // Check ability to add original extension 10 | const needAddExtension = (settings.keepOriginalExtension && !newName.endsWith('!!ext')) || newName.endsWith('&&ext'); 11 | 12 | // Clean the new name from special characters 13 | let newStripedName = newName.replace(/(!!|&&)ext$/, ''); 14 | 15 | // The new path has no extension and we must save original extension 16 | if (oldStat.isFile() && newPath.ext === '' && needAddExtension) { 17 | newStripedName += oldPath.ext; 18 | } 19 | 20 | return path.join(oldPath.dir, newStripedName); 21 | } 22 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | export interface IPluginSettings { 2 | openFileAfterCopy: boolean; 3 | keepOriginalExtension: boolean; 4 | } 5 | -------------------------------------------------------------------------------- /src/utils/prompt.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | 3 | export function name(filename: string): Promise { 4 | return vscode.window.showInputBox({ 5 | placeHolder: 'Enter the new path for the duplicate.', 6 | value: filename.split('.').map((el, i) => i === 0 ? `${el}-copy` : el).join('.') 7 | }) as Promise; 8 | } 9 | 10 | export function overwrite(filepath: string): Promise { 11 | const message = `The path **${filepath}** alredy exists. Do you want to overwrite the existing path?`; 12 | const action = { 13 | title: 'OK', 14 | isCloseAffordance: false 15 | }; 16 | 17 | return vscode.window.showWarningMessage(message, action) as Promise; 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "lib": [ 7 | "es2015" 8 | ], 9 | 10 | "rootDir": "src", 11 | "outDir": "out", 12 | 13 | "strict": true, 14 | "alwaysStrict": true, 15 | "strictFunctionTypes": true, 16 | "strictNullChecks": true, 17 | "strictPropertyInitialization": true, 18 | 19 | "forceConsistentCasingInFileNames": true, 20 | "noImplicitAny": true, 21 | "noImplicitReturns": true, 22 | "noImplicitThis": true, 23 | "noFallthroughCasesInSwitch": true, 24 | "noUnusedLocals": true, 25 | "noUnusedParameters": true, 26 | 27 | "emitDecoratorMetadata": true, 28 | "experimentalDecorators": true, 29 | "downlevelIteration": true, 30 | "declaration": true, 31 | 32 | "pretty": true 33 | }, 34 | "include": [ 35 | "typings/**/*", 36 | "src/**/*" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint-config-mrmlnc"], 3 | "rules": { 4 | "no-require-imports": false, 5 | "match-default-export-name": false, 6 | "max-file-line-count": false 7 | } 8 | } 9 | --------------------------------------------------------------------------------