From 040c4af1588249fcd725447a1b13edfeed0da426 Mon Sep 17 00:00:00 2001 From: Dominique Date: Wed, 1 Nov 2017 14:12:24 +0100 Subject: [PATCH] feat(regreplace): first init --- .gitignore | 3 + .vscode/launch.json | 28 + .vscode/settings.json | 10 + .vscode/symbols.json | 1 + .vscode/tasks.json | 30 + .vscodeignore | 9 + README.md | 88 ++ assets/logo.png | Bin 0 -> 6874 bytes package-lock.json | 2570 ++++++++++++++++++++++++++++++++++++++++ package.json | 122 ++ src/extension.ts | 21 + src/on-save.ts | 61 + src/regreplace.ts | 138 +++ src/utils.ts | 18 + test/extension.test.ts | 22 + test/index.ts | 22 + tsconfig.json | 17 + 17 files changed, 3160 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/symbols.json create mode 100644 .vscode/tasks.json create mode 100644 .vscodeignore create mode 100644 README.md create mode 100644 assets/logo.png create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/extension.ts create mode 100644 src/on-save.ts create mode 100644 src/regreplace.ts create mode 100644 src/utils.ts create mode 100644 test/extension.test.ts create mode 100644 test/index.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0614489 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +out +node_modules +*vsix \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c77b2ad --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +{ + "version": "0.1.0", + "configurations": [ + { + "name": "Launch Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], + "stopOnEntry": false, + "sourceMaps": true, + "outDir": "${workspaceRoot}/out/src", + "preLaunchTask": "npm" + }, + { + "name": "Launch Tests", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], + "stopOnEntry": false, + "sourceMaps": true, + "outDir": "${workspaceRoot}/out/test", + "preLaunchTask": "npm" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7877e3f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + }, + "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version +} \ No newline at end of file diff --git a/.vscode/symbols.json b/.vscode/symbols.json new file mode 100644 index 0000000..734db77 --- /dev/null +++ b/.vscode/symbols.json @@ -0,0 +1 @@ +{"symbols":{"ICommand":{"hasNamespace":false,"type":1,"moduleName":"extension","relativePath":"src/extension"},"IConfig":{"hasNamespace":false,"type":1,"moduleName":"extension","relativePath":"src/extension"},"RunOnSaveExtension":{"hasNamespace":false,"type":0,"moduleName":"extension","relativePath":"src/extension"}},"files":{"src/extension.ts":"2016-11-13T01:43:53.000Z","test/extension.test.ts":"2016-11-13T00:59:24.000Z","test/index.ts":"2016-11-13T00:59:24.000Z","typings/node.d.ts":"2016-11-13T00:59:24.000Z","typings/vscode-typings.d.ts":"2016-11-13T00:59:24.000Z"}} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..fb7f662 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,30 @@ +// Available variables which can be used inside of strings. +// ${workspaceRoot}: the root folder of the team +// ${file}: the current opened file +// ${fileBasename}: the current opened file's basename +// ${fileDirname}: the current opened file's dirname +// ${fileExtname}: the current opened file's extension +// ${cwd}: the current working directory of the spawned process + +// A task runner that calls a custom npm script that compiles the extension. +{ + "version": "0.1.0", + + // we want to run npm + "command": "npm", + + // the command is a shell script + "isShellCommand": true, + + // show the output window only if unrecognized errors occur. + "showOutput": "silent", + + // we run the custom script "compile" as defined in package.json + "args": ["run", "compile", "--loglevel", "silent"], + + // The tsc compiler is started in watching mode + "isWatching": true, + + // use the standard tsc in watch mode problem matcher to find compile problems in the output. + "problemMatcher": "$tsc-watch" +} \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore new file mode 100644 index 0000000..93e28ff --- /dev/null +++ b/.vscodeignore @@ -0,0 +1,9 @@ +.vscode/** +typings/** +out/test/** +test/** +src/** +**/*.map +.gitignore +tsconfig.json +vsc-extension-quickstart.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..b7c26e4 --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +# regreplace README + +Reg Replace is a plugin for Visual Studio Code that allows the creating of commands consisting of sequences of find and replace instructions. + +It is heavily inspired from [Reg Replace for Sublime Text](https://github.com/facelessuser/RegReplace) + +## Features + +- Create find and replace rules that can then be used to create VSCode Commands to call at any time. +- Chain multiple regex find and replace rules together. +- Create rules that can filter regex results by filename. +- Create rules that run on save. + + + +## Extension Settings + +This extension contributes the following settings: + +* `on-save` - defaults to true, run commands on save. +* `suppress-warnings` - (optional) Suppress warnings when regreplace fails. +* `commands` - array of commands that will be run whenever a file is saved. + * `name` - command name for debugging. + * `match` - regex for matching files to run commands on. e.g. \"\\.(ts|js|tsx)$\" + * `exclude` - regex for matching files *not* to run commands on. e.g. \"^\\.$\" exclude dot files + * `priority` - command priority determines order. + * `find` - use simple find command. e.g. \"** what\" + * `regexp` - use regexp find command. Needs to be escaped. e.g. \"(\\n)*\" + * `replace` - replace text. Supports groups. e.g. \"$2\n$1\" + * `global` - run command asynchronously. + + + +### Sample Config +This sample configuration will remove newlines from end of file. +```typescript +"regreplace.commands": [ + { + "match": ".(ts|js|tsx)$", // typescript + "regexp": "\n+$", // escaped regexp + "global": true, // glob + "replace": "" // replace with empty string + } +] +``` + + +## Known Issues + +None yet :) + +## Release Notes + +Users appreciate release notes as you update your extension. + +### 1.0.0 + +Initial release of regreplace. + +----------------------------------------------------------------------------------------------------------- + +## Licence + +MIT License + +Copyright (c) 2017 DomiR + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e89693654a3fd4748b977f2d0cd545ad8e50066f GIT binary patch literal 6874 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 h|96Q0Up=wbuDBEDH@e?0jcQf_U onSave.update()); +} + +export function deactivate() { } \ No newline at end of file diff --git a/src/on-save.ts b/src/on-save.ts new file mode 100644 index 0000000..20e911f --- /dev/null +++ b/src/on-save.ts @@ -0,0 +1,61 @@ +/** + * On save + * + * @author Dominique Rau [domi.github@gmail.com](mailto:domi.github@gmail.com) + * @version 0.0.1 + */ + +import { Disposable, TextDocumentWillSaveEvent, TextEdit, workspace } from 'vscode'; +import { regreplace } from './regreplace'; +import { getConfiguration, getMaxRange } from './utils'; + +let subscription: Disposable; +export default { + + get isEnabled() { + return getConfiguration('on-save'); + }, + + register() { + if (subscription) { + return; + } + + subscription = workspace.onWillSaveTextDocument(listener); + }, + + unregister() { + if (!subscription) { + return; + } + + subscription.dispose(); + subscription = null; + }, + + update() { + if (this.isEnabled) { + this.register(); + } else { + this.unregister(); + } + }, + + bypass(action) { + this.unregister(); + const result = action(); + this.update(); + return result; + } +}; + + +function listener({ document, waitUntil }: TextDocumentWillSaveEvent) { + const regreplacedText = regreplace(document); + if (!regreplacedText) { + return; + } + + const edits = Promise.resolve([ new TextEdit(getMaxRange(), regreplacedText) ]); + waitUntil(edits); +} \ No newline at end of file diff --git a/src/regreplace.ts b/src/regreplace.ts new file mode 100644 index 0000000..6aa240b --- /dev/null +++ b/src/regreplace.ts @@ -0,0 +1,138 @@ +/** + * Regreplace + * + * @author Dominique Rau [domi.github@gmail.com](mailto:domi.github@gmail.com) + * @version 0.0.1 + */ + +import { dirname, extname } from 'path'; +import { TextDocument, window } from 'vscode'; +import { getConfiguration, getMaxRange } from './utils'; +import onSave from './on-save'; + + + + + +// regreplace +// ------------------------------ +export function regreplace(document: TextDocument): string { + try { + const commands = getConfiguration('commands'); + + const currentText = document.getText() + const fileName = document.fileName; + const extension = extname(fileName); + const directory = dirname(fileName); + const fileMatches = (pattern: string) => pattern && pattern.length > 0 && new RegExp(pattern).test(fileName); + + // filter all commands with filematch patterns + const activeCommands = commands + .filter(cfg => { + const matchPattern = cfg.match || ''; + const negatePattern = cfg.exclude || ''; + + // if no match pattern was provided, or if match pattern succeeds + const isMatch = + (typeof matchPattern === "string") + ? matchPattern.length === 0 || fileMatches(matchPattern) + : matchPattern.some(mp => fileMatches(mp)); + + // negation has to be explicitly provided + const isNegate = + (typeof negatePattern === "string") + ? negatePattern.length > 0 && fileMatches(negatePattern) + : negatePattern.some(mp => fileMatches(mp)); + + // negation wins over match + return !isNegate && isMatch; + }); + + // return if no commands + if (activeCommands.length === 0) { + return; + } + + // sort commands with priority + const sortedCommands = activeCommands.sort((a, b) => (a.priority || 0) - (b.priority || 0)) + + // run through all active commands + let resultText = currentText; + activeCommands.forEach(command => { + if (command == null) { return; } + try { + let regexQuery, regexReplace; + + // find via regex or regular find + if (command.regexp && command.regexp.length > 0) { + regexQuery = command.regexp + } else if (command.find && command.find.length > 0) { + regexQuery = command.find.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + } else { + return; + } + + // result + if (command.replace != null) { + regexReplace = command.replace; + } else { + return; + } + + const reg = command.global === false ? new RegExp(regexQuery) : new RegExp(regexQuery, "g"); + resultText = resultText.replace(reg, regexReplace) + + } catch (error) { + if (!getConfiguration('suppress-warnings')) { + window.showWarningMessage(`Error regreplacing in command ${command.name}: ${error}`); + } + return null; + } + }); + + return resultText; + } catch (error) { + if (!getConfiguration('suppress-warnings')) { + window.showWarningMessage(`Error regreplacing: ${error}`); + } + return document.getText(); + } +} + + +export function regreplaceCurrentDocument() { + const { + activeTextEditor: editor, + activeTextEditor: { document } + } = window; + + const regreplacedText = regreplace(document); + if (!regreplacedText) { + return; + } + + return editor.edit(edit => edit.replace(getMaxRange(), regreplacedText)); +} + + +export async function saveWithoutReplacing() { + const { document } = window.activeTextEditor; + onSave.bypass(async () => await document.save()); +} + + + + + +// types +// ------------------------------ +interface ICommand { + name?: string; // just for keepsake + match?: string|string[]; // regex expression e.g. "\\.(ts|js|tsx)$" + exclude?: string|string[]; // will overrule match e.g. "^\\.$" exclude dot files + priority?: number; // execution prio + find?: string; // use regular search e.g. "** what" + regexp?: string // use regexp, need to escape e.g. "(\\n)*" + replace: string; // replace with groups e.g. "$2\n$1" + global?: boolean; // default true, used in regexp +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..9c3ad9f --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,18 @@ +/** + * Utils + * + * @author Dominique Rau [domi.github@gmail.com](mailto:domi.github@gmail.com) + * @version 0.0.1 + */ + +import { Range, workspace } from 'vscode'; + +export const EXTENSION_NAME = 'regreplace'; + +export function getConfiguration(key: string): T { + return workspace.getConfiguration(EXTENSION_NAME).get(key); +} + +export function getMaxRange(): Range { + return new Range(0, 0, Number.MAX_VALUE, Number.MAX_VALUE); +} \ No newline at end of file diff --git a/test/extension.test.ts b/test/extension.test.ts new file mode 100644 index 0000000..fde7dd4 --- /dev/null +++ b/test/extension.test.ts @@ -0,0 +1,22 @@ +// +// Note: This example test is leveraging the Mocha test framework. +// Please refer to their documentation on https://mochajs.org/ for help. +// + +// The module 'assert' provides assertion methods from node +import * as assert from 'assert'; + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from 'vscode'; +import * as myExtension from '../src/extension'; + +// Defines a Mocha test suite to group tests of similar kind together +// suite("Extension Tests", () => { + +// // Defines a Mocha unit test +// test("Something 1", () => { +// assert.equal(-1, [1, 2, 3].indexOf(5)); +// assert.equal(-1, [1, 2, 3].indexOf(0)); +// }); +// }); \ No newline at end of file diff --git a/test/index.ts b/test/index.ts new file mode 100644 index 0000000..50bae45 --- /dev/null +++ b/test/index.ts @@ -0,0 +1,22 @@ +// +// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING +// +// This file is providing the test runner to use when running extension tests. +// By default the test runner in use is Mocha based. +// +// You can provide your own test runner if you want to override it by exporting +// a function run(testRoot: string, clb: (error:Error) => void) that the extension +// host can call to run the tests. The test runner is expected to use console.log +// to report the results back to the caller. When the tests are finished, return +// a possible error to the callback or null if none. + +var testRunner = require('vscode/lib/testrunner'); + +// You can directly control Mocha options by uncommenting the following lines +// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info +testRunner.configure({ + ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) + useColors: true // colored output from test results +}); + +module.exports = testRunner; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..26d32ac --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "out", + "lib": [ "es6" ], + "sourceMap": true, + "rootDir": ".", + "typeRoots": [ + "./node_modules/@types" + ] + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +} \ No newline at end of file