From 3bc2368bbfd0f62537a0dbd0d2bcbb82b62a4659 Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Fri, 29 Dec 2017 09:50:21 +1100 Subject: [PATCH 1/7] fix(remapper): reset isPotentialRemap --- src/configuration/remapper.ts | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/configuration/remapper.ts b/src/configuration/remapper.ts index 83c1e30b878..d3c146fe5d2 100644 --- a/src/configuration/remapper.ts +++ b/src/configuration/remapper.ts @@ -21,12 +21,7 @@ export class Remappers implements IRemapper { } get isPotentialRemap(): boolean { - for (let remapper of this.remappers) { - if (remapper.isPotentialRemap) { - return true; - } - } - return false; + return _.some(this.remappers, r => r.isPotentialRemap); } public async sendKey( @@ -90,12 +85,14 @@ class Remapper implements IRemapper { modeHandler: ModeHandler, vimState: VimState ): Promise { + this._isPotentialRemap = false; + if (this._remappedModes.indexOf(vimState.currentMode) === -1) { return false; } - const longestKeySequence = this._longestKeySequence(); let remapping: IKeybinding | undefined; + const longestKeySequence = this._longestKeySequence(); /** * Check to see if the keystrokes match any user-specified remapping. @@ -120,25 +117,23 @@ class Remapper implements IRemapper { } if (remapping) { + if (!this._recursive) { + vimState.isCurrentlyPerformingRemapping = true; + } + // Record length of remapped command vimState.recordedState.numberOfRemappedKeys += remapping.before.length; - // If we remapped e.g. jj to esc, we have to revert the inserted "jj" + // Revert previously inserted characters + // (e.g. jj remapped to esc, we have to revert the inserted "jj") if (this._remappedModes.indexOf(ModeName.Insert) >= 0) { - // Revert every single inserted character. This is actually a bit of - // a hack since we aren't guaranteed that each insertion inserted - // only a single character. - + // Revert every single inserted character. // We subtract 1 because we haven't actually applied the last key. await vimState.historyTracker.undoAndRemoveChanges( Math.max(0, (remapping.before.length - 1) * vimState.allCursors.length) ); } - if (!this._recursive) { - vimState.isCurrentlyPerformingRemapping = true; - } - // We need to remove the keys that were remapped into different keys // from the state. const numToRemove = remapping.before.length - 1; @@ -174,13 +169,13 @@ class Remapper implements IRemapper { } // Check to see if a remapping could potentially be applied when more keys are received - this._isPotentialRemap = false; for (let remap of this._remappings) { if (keys.join('') === remap.before.slice(0, keys.length).join('')) { this._isPotentialRemap = true; break; } } + return false; } From 980c154a76e63731bf5f933131b4f4eaad9364cb Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Fri, 29 Dec 2017 09:57:14 +1100 Subject: [PATCH 2/7] refactor: stop silently failing. either display error to user or throw back to vscode --- src/cmd_line/commandLine.ts | 15 +++++---------- src/mode/modeHandler.ts | 24 +++++++++++------------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/cmd_line/commandLine.ts b/src/cmd_line/commandLine.ts index b4cae02657a..567becb160e 100644 --- a/src/cmd_line/commandLine.ts +++ b/src/cmd_line/commandLine.ts @@ -14,17 +14,12 @@ export class CommandLine { return; } - try { - let cmdString = - (await vscode.window.showInputBox(this.getInputBoxOptions(initialText))) || ''; - if (cmdString && cmdString[0] === ':' && Configuration.cmdLineInitialColon) { - cmdString = cmdString.slice(1); - } - - await CommandLine.Run(cmdString, vimState); - } catch (e) { - StatusBar.SetText(e.toString(), vimState.currentMode, true); + let cmd = await vscode.window.showInputBox(this.getInputBoxOptions(initialText)); + if (cmd && cmd[0] === ':' && Configuration.cmdLineInitialColon) { + cmd = cmd.slice(1); } + + await CommandLine.Run(cmd!, vimState); } public static async Run(command: string, vimState: VimState): Promise { diff --git a/src/mode/modeHandler.ts b/src/mode/modeHandler.ts index 6b4ae165066..2235b1406e0 100644 --- a/src/mode/modeHandler.ts +++ b/src/mode/modeHandler.ts @@ -344,9 +344,8 @@ export class ModeHandler implements vscode.Disposable { this.vimState = await this.handleKeyEventHelper(key, this.vimState); } } catch (e) { - console.log('error.stack'); - console.log(e); - console.log(e.stack); + console.error(e); + throw e; } this.vimState.lastKeyPressedTimestamp = now; @@ -370,14 +369,15 @@ export class ModeHandler implements vscode.Disposable { vimState.keyHistory.push(key); let result = Actions.getRelevantAction(recordedState.actionKeys, vimState); - - const isPotentialRemap = this._remappers.isPotentialRemap; - - if (result === KeypressState.NoPossibleMatch && !isPotentialRemap) { - vimState.recordedState = new RecordedState(); - return vimState; - } else if (result === KeypressState.WaitingOnKeys) { - return vimState; + switch (result) { + case KeypressState.NoPossibleMatch: + if (!this._remappers.isPotentialRemap) { + vimState.recordedState = new RecordedState(); + return vimState; + } + break; + case KeypressState.WaitingOnKeys: + return vimState; } let action = result as BaseAction; @@ -873,13 +873,11 @@ export class ModeHandler implements vscode.Disposable { case 'replaceText': edit.replace(new vscode.Selection(command.end, command.start), command.text); break; - case 'deleteText': edit.delete( new vscode.Range(command.position, command.position.getLeftThroughLineBreaks()) ); break; - case 'deleteRange': edit.delete(new vscode.Selection(command.range.start, command.range.stop)); break; From 5430bb4fabe42f828c63b1525c9189dfdf2dc302 Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Fri, 29 Dec 2017 10:26:56 +1100 Subject: [PATCH 3/7] fix(gulpfile): git tag on collection completion instead of every file --- gulpfile.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 501766d9465..24c30756696 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -19,8 +19,10 @@ function versionBump(semver) { .src(['./package.json', './package-lock.json']) .pipe(bump({ type: semver })) .pipe(gulp.dest('./')) - .pipe(git.commit('rev package version')) - .pipe(tag_version()); + .pipe(git.commit(semver)) + .on('end', function() { + tag_version(); + }); } gulp.task('typings', function() { From fcf1e3677a5f2c680beed89927ed2a3618540882 Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Fri, 29 Dec 2017 10:31:37 +1100 Subject: [PATCH 4/7] update(package.json): nothing major, patch releases on a few gulp utilities --- package-lock.json | 444 ++++++++++------------------------------------ package.json | 10 +- 2 files changed, 97 insertions(+), 357 deletions(-) diff --git a/package-lock.json b/package-lock.json index 26bdbb78f43..3d4b310f8f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dev": true, "requires": { "@types/minimatch": "3.0.1", - "@types/node": "8.5.1" + "@types/node": "8.5.2" } }, "@types/minimatch": { @@ -21,15 +21,18 @@ "dev": true }, "@types/mocha": { - "version": "2.2.44", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", - "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", - "dev": true + "version": "2.2.45", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.45.tgz", + "integrity": "sha512-tE1SYtNG3I3atRVPELSGN2FJJJtPg3O/G0tycYSyzeDqdAbdLPRH089LhpWYA5M/iHeWHkVZq/b0OVKngcK0Eg==", + "dev": true, + "requires": { + "@types/node": "8.5.2" + } }, "@types/node": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.1.tgz", - "integrity": "sha512-SrmAO+NhnsuG/6TychSl2VdxBZiw/d6V+8j+DFo8O3PwFi+QeYXWHhAw+b170aSc6zYab6/PjEWRZHIDN9mNUw==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.2.tgz", + "integrity": "sha512-KA4GKOpgXnrqEH2eCVhiv2CsxgXGQJgV1X0vsGlh+WCnxbeAE1GT44ZsTU1IN5dEeV/gDupKa7gWo08V5IxWVQ==", "dev": true }, "@types/shelljs": { @@ -39,7 +42,7 @@ "dev": true, "requires": { "@types/glob": "5.0.33", - "@types/node": "8.5.1" + "@types/node": "8.5.2" } }, "@types/which": { @@ -84,6 +87,15 @@ "json-schema-traverse": "0.3.1" } }, + "ansi-colors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.0.1.tgz", + "integrity": "sha512-yopkAU0ZD/WQ56Tms3xLn6jRuX3SyUMAVi0FdmDIbmmnHW3jHiI1sQFdUl3gfVddjnrsP3Y6ywFKvCRopvoVIA==", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, "ansi-cyan": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", @@ -93,6 +105,15 @@ "ansi-wrap": "0.1.0" } }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, "ansi-red": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", @@ -382,9 +403,9 @@ "dev": true }, "bump-regex": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/bump-regex/-/bump-regex-2.8.0.tgz", - "integrity": "sha512-prjTDXzGEbTvCgDVEAKvOGpAqZnz5EmzJNiYi2L72TjNy+T91w3SbPgofnAsLXZZBqZigv+kN4oF5oEIyr6LPw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bump-regex/-/bump-regex-3.0.0.tgz", + "integrity": "sha512-TKMnVs6csJB9R+fs9hl/f2Qm+KrnNe2ffJOVw/cCZpsbuxw7Ko6XWBDS2DL0/hAB1TaxE/NbReLFXAiD+bw65Q==", "dev": true, "requires": { "semver": "5.4.1", @@ -493,6 +514,12 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, "combined-stream": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", @@ -1458,12 +1485,12 @@ } }, "gulp-bump": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/gulp-bump/-/gulp-bump-2.8.0.tgz", - "integrity": "sha512-syvQLax2xQo1EDFJxanUqX1rv+YkVB4/cx/THN+uInmSjMGezT1/6WYLdXqkBAMQUw2KlyB2melz0DzrHdwkLA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gulp-bump/-/gulp-bump-3.0.0.tgz", + "integrity": "sha512-w/1qP+pa+0wZhMg2eSZEfmIZHlVaHqRyJYMtSOL8Jkby6Lne+iIm0PIkyYBZs7nGKDriYGYZuh/+lQ7InHVwIQ==", "dev": true, "requires": { - "bump-regex": "2.8.0", + "bump-regex": "3.0.0", "plugin-error": "0.1.2", "plugin-log": "0.1.0", "semver": "5.4.1", @@ -1501,13 +1528,15 @@ } }, "gulp-git": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/gulp-git/-/gulp-git-2.4.2.tgz", - "integrity": "sha512-YgFW2PmtGSHkUYFql75ByRqFjiEDvOk7jxVkkqH0OSDKc3icxD8GDBR1kbr2zG7oNaIynk2NcKVSypgPHl7ibQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/gulp-git/-/gulp-git-2.5.0.tgz", + "integrity": "sha512-8fjG5mtP42fP+qTaDzwVyKqYEWmMsCoOdtwyPb1yqKmTBJnJc5/EPXktd2q0NUtjy8bALEWFqz3UMEiP8i923A==", "dev": true, "requires": { "any-shell-escape": "0.1.1", - "gulp-util": "3.0.8", + "fancy-log": "1.3.2", + "lodash.template": "4.4.0", + "plugin-error": "0.1.2", "require-dir": "0.3.2", "strip-bom-stream": "3.0.0", "through2": "2.0.3", @@ -1526,6 +1555,36 @@ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", "dev": true }, + "fancy-log": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", + "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", + "dev": true, + "requires": { + "ansi-gray": "0.1.1", + "color-support": "1.1.3", + "time-stamp": "1.1.0" + } + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.templatesettings": "4.1.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0" + } + }, "replace-ext": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", @@ -1970,221 +2029,27 @@ } }, "gulp-tag-version": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/gulp-tag-version/-/gulp-tag-version-1.3.0.tgz", - "integrity": "sha1-hEjIfu0YZtuObLWYvEGb4t98R9s=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/gulp-tag-version/-/gulp-tag-version-1.3.1.tgz", + "integrity": "sha512-bt1LbmGeg6OaiKEdQ+hmi9KeawTXYnunDVCd9cvNoVT89KKXyZEEdR2DCSFR8zk+nunatRnSD3Zaa4R9JGC4Tw==", "dev": true, "requires": { - "gulp-git": "0.3.6", - "gulp-util": "2.2.20", + "ansi-colors": "1.0.1", + "fancy-log": "1.3.2", + "gulp-git": "2.5.0", "map-stream": "0.1.0" }, "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.5", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - } - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" - } - }, - "gulp-git": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/gulp-git/-/gulp-git-0.3.6.tgz", - "integrity": "sha1-d+w9oiklwkbt15bKENQWOWXYFAo=", - "dev": true, - "requires": { - "any-shell-escape": "0.1.1", - "gulp-util": "2.2.20", - "map-stream": "0.1.0", - "through2": "0.4.2" - } - }, - "gulp-util": { - "version": "2.2.20", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", - "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "dateformat": "1.0.12", - "lodash._reinterpolate": "2.4.1", - "lodash.template": "2.4.1", - "minimist": "0.2.0", - "multipipe": "0.1.2", - "through2": "0.5.1", - "vinyl": "0.2.3" - }, - "dependencies": { - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "3.0.0" - } - } - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "fancy-log": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", + "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", "dev": true, "requires": { - "ansi-regex": "0.2.1" + "ansi-gray": "0.1.1", + "color-support": "1.1.3", + "time-stamp": "1.1.0" } - }, - "lodash._reinterpolate": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", - "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", - "dev": true - }, - "lodash.escape": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", - "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", - "dev": true, - "requires": { - "lodash._escapehtmlchar": "2.4.1", - "lodash._reunescapedhtml": "2.4.1", - "lodash.keys": "2.4.1" - } - }, - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - }, - "lodash.template": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", - "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", - "dev": true, - "requires": { - "lodash._escapestringchar": "2.4.1", - "lodash._reinterpolate": "2.4.1", - "lodash.defaults": "2.4.1", - "lodash.escape": "2.4.1", - "lodash.keys": "2.4.1", - "lodash.templatesettings": "2.4.1", - "lodash.values": "2.4.1" - } - }, - "lodash.templatesettings": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", - "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", - "dev": true, - "requires": { - "lodash._reinterpolate": "2.4.1", - "lodash.escape": "2.4.1" - } - }, - "minimist": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", - "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - }, - "through2": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", - "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "2.1.2" - }, - "dependencies": { - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "0.4.0" - } - } - } - }, - "vinyl": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", - "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", - "dev": true, - "requires": { - "clone-stats": "0.0.1" - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true } } }, @@ -3187,51 +3052,18 @@ "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", "dev": true }, - "lodash._escapehtmlchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", - "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1" - } - }, - "lodash._escapestringchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", - "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", - "dev": true - }, "lodash._getnative": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", "dev": true }, - "lodash._htmlescapes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", - "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", - "dev": true - }, "lodash._isiterateecall": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, - "lodash._isnative": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", - "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", - "dev": true - }, - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", - "dev": true - }, "lodash._reescape": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", @@ -3250,67 +3082,12 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, - "lodash._reunescapedhtml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", - "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "lodash._root": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", "dev": true }, - "lodash._shimkeys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", - "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - } - }, - "lodash.defaults": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", - "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "lodash.escape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", @@ -3338,15 +3115,6 @@ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", "dev": true }, - "lodash.isobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", - "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - } - }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", @@ -3409,28 +3177,6 @@ "lodash.escape": "3.2.0" } }, - "lodash.values": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", - "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", - "dev": true, - "requires": { - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -3852,12 +3598,6 @@ "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", "dev": true }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true - }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", diff --git a/package.json b/package.json index f12280f372e..03337ad242c 100644 --- a/package.json +++ b/package.json @@ -576,14 +576,14 @@ "untildify": "^3.0.2" }, "devDependencies": { - "@types/mocha": "^2.2.44", - "@types/node": "^8.5.1", + "@types/mocha": "^2.2.45", + "@types/node": "^8.5.2", "gulp": "^3.9.1", - "gulp-bump": "^2.8.0", - "gulp-git": "^2.4.2", + "gulp-bump": "^3.0.0", + "gulp-git": "^2.5.0", "gulp-inject-string": "^1.1.0", "gulp-shell": "^0.6.3", - "gulp-tag-version": "^1.3.0", + "gulp-tag-version": "^1.3.1", "gulp-tslint": "^8.1.2", "gulp-typings": "^2.0.4", "merge-stream": "^1.0.1", From 4f97784566940c6c1caac953974662914f0f3214 Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Tue, 2 Jan 2018 10:55:07 -0800 Subject: [PATCH 5/7] refactor(vim-state): implement disposable --- src/state/vimState.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/state/vimState.ts b/src/state/vimState.ts index 7d583240808..10beb87da69 100644 --- a/src/state/vimState.ts +++ b/src/state/vimState.ts @@ -21,7 +21,7 @@ import { RecordedState } from './recordedState'; * Actions defined in actions.ts are only allowed to mutate a VimState in order to * indicate what they want to do. */ -export class VimState { +export class VimState implements vscode.Disposable { /** * The column the cursor wants to be at, or Number.POSITIVE_INFINITY if it should always * be the rightmost column. @@ -226,9 +226,14 @@ export class VimState { this.identity = new EditorIdentity(editor); this.historyTracker = new HistoryTracker(this); this.easyMotion = new EasyMotion(); - this.currentMode = startInInsertMode ? ModeName.Insert : ModeName.Normal; } + + dispose() { + if (this.nvim) { + this.nvim.quit(); + } + } } export class ViewChange { From 74fdc901a6b53aba3fd588243bb35c62553ec32a Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Tue, 2 Jan 2018 10:56:40 -0800 Subject: [PATCH 6/7] refactor(register): public fx before private --- src/register/register.ts | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/register/register.ts b/src/register/register.ts index f95501c7999..4d8185ad57c 100644 --- a/src/register/register.ts +++ b/src/register/register.ts @@ -66,27 +66,10 @@ export class Register { ); } - private static isBlackHoleRegister(registerName: string): boolean { - return registerName === '_'; - } - - private static isClipboardRegister(registerName: string): boolean { - const register = Register.registers[registerName]; - return register && register.isClipboardRegister; - } - public static isValidRegisterForMacro(register: string): boolean { return /^[a-zA-Z0-9]+$/.test(register); } - private static isValidLowercaseRegister(register: string): boolean { - return /^[a-z]+$/.test(register); - } - - private static isValidUppercaseRegister(register: string): boolean { - return /^[A-Z]+$/.test(register); - } - /** * Puts content in a register. If none is specified, uses the default * register ". @@ -117,6 +100,23 @@ export class Register { } } + private static isBlackHoleRegister(registerName: string): boolean { + return registerName === '_'; + } + + private static isClipboardRegister(registerName: string): boolean { + const register = Register.registers[registerName]; + return register && register.isClipboardRegister; + } + + private static isValidLowercaseRegister(register: string): boolean { + return /^[a-z]+$/.test(register); + } + + private static isValidUppercaseRegister(register: string): boolean { + return /^[A-Z]+$/.test(register); + } + /** * Puts the content at the specified index of the multicursor Register. * From 3d28c6b6a96b6888fce3b78ae327448346d54436 Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Tue, 2 Jan 2018 10:56:17 -0800 Subject: [PATCH 7/7] refactor(mode-handler): use anonymous fx to handle text transformation removing dupe code, move friendly name to mode class --- src/mode/mode.ts | 4 ++ src/mode/modeHandler.ts | 145 ++++++++++++++++------------------------ 2 files changed, 60 insertions(+), 89 deletions(-) diff --git a/src/mode/mode.ts b/src/mode/mode.ts index cbf4e4f2e9e..6f9bb6b9b12 100644 --- a/src/mode/mode.ts +++ b/src/mode/mode.ts @@ -48,6 +48,10 @@ export abstract class Mode { return this._name; } + get friendlyName(): string { + return ModeName[this._name]; + } + get isActive(): boolean { return this._isActive; } diff --git a/src/mode/modeHandler.ts b/src/mode/modeHandler.ts index 2235b1406e0..d079179090e 100644 --- a/src/mode/modeHandler.ts +++ b/src/mode/modeHandler.ts @@ -50,14 +50,6 @@ export class ModeHandler implements vscode.Disposable { return this._modes.find(mode => mode.isActive)!; } - private get currentModeName(): ModeName { - return this.currentMode.name; - } - - private get currentModeFriendlyName(): string { - return ModeName[this.currentMode.name]; - } - constructor() { this.createRemappers(); @@ -107,6 +99,7 @@ export class ModeHandler implements vscode.Disposable { }); this._disposables.push(disposable); + this._disposables.push(this.vimState); } /** @@ -145,7 +138,7 @@ export class ModeHandler implements vscode.Disposable { return; } - if (this.currentModeName === ModeName.EasyMotionMode) { + if (this.currentMode.name === ModeName.EasyMotionMode) { return; } @@ -503,8 +496,8 @@ export class ModeHandler implements vscode.Disposable { // Update mode (note the ordering allows you to go into search mode, // then return and have the motion immediately applied to an operator). - const prevState = this.currentModeName; - if (vimState.currentMode !== this.currentModeName) { + const prevState = this.currentMode.name; + if (vimState.currentMode !== this.currentMode.name) { this.setCurrentMode(vimState.currentMode); // We don't want to mark any searches as a repeatable action @@ -534,7 +527,7 @@ export class ModeHandler implements vscode.Disposable { // And then we have to do it again because an operator could // have changed it as well. (TODO: do you even decomposition bro) - if (vimState.currentMode !== this.currentModeName) { + if (vimState.currentMode !== this.currentMode.name) { this.setCurrentMode(vimState.currentMode); if (vimState.currentMode === ModeName.Normal) { @@ -613,7 +606,7 @@ export class ModeHandler implements vscode.Disposable { recordedState.actionKeys = []; vimState.currentRegisterMode = RegisterMode.AscertainFromCurrentMode; - if (this.currentModeName === ModeName.Normal) { + if (this.currentMode.name === ModeName.Normal) { vimState.cursorStartPosition = vimState.cursorPosition; } @@ -778,7 +771,7 @@ export class ModeHandler implements vscode.Disposable { stop = stop.getLeftThroughLineBreaks(true); } - if (this.currentModeName === ModeName.VisualLine) { + if (this.currentMode.name === ModeName.VisualLine) { start = start.getLineBegin(); stop = stop.getLineEnd(); @@ -853,6 +846,44 @@ export class ModeHandler implements vscode.Disposable { let accumulatedPositionDifferences: { [key: number]: PositionDiff[] } = {}; + const doTextEditorEdit = (command: TextTransformations, edit: vscode.TextEditorEdit) => { + switch (command.type) { + case 'insertText': + edit.insert(command.position, command.text); + break; + case 'replaceText': + edit.replace(new vscode.Selection(command.end, command.start), command.text); + break; + case 'deleteText': + let matchRange = PairMatcher.immediateMatchingBracket(command.position); + if (matchRange) { + edit.delete(matchRange); + } + edit.delete( + new vscode.Range(command.position, command.position.getLeftThroughLineBreaks()) + ); + break; + case 'deleteRange': + edit.delete(new vscode.Selection(command.range.start, command.range.stop)); + break; + default: + console.warn(`Unhandled text transformation type: ${command.type}.`); + break; + } + + if (command.cursorIndex === undefined) { + throw new Error('No cursor index - this should never ever happen!'); + } + + if (command.diff) { + if (!accumulatedPositionDifferences[command.cursorIndex]) { + accumulatedPositionDifferences[command.cursorIndex] = []; + } + + accumulatedPositionDifferences[command.cursorIndex].push(command.diff); + } + }; + if (textTransformations.length > 0) { if (areAnyTransformationsOverlapping(textTransformations)) { console.log( @@ -863,38 +894,8 @@ export class ModeHandler implements vscode.Disposable { // TODO: Select one transformation for every cursor and run them all // in parallel. Repeat till there are no more transformations. - for (const command of textTransformations) { - await this.vimState.editor.edit(edit => { - switch (command.type) { - case 'insertText': - edit.insert(command.position, command.text); - break; - case 'replaceText': - edit.replace(new vscode.Selection(command.end, command.start), command.text); - break; - case 'deleteText': - edit.delete( - new vscode.Range(command.position, command.position.getLeftThroughLineBreaks()) - ); - break; - case 'deleteRange': - edit.delete(new vscode.Selection(command.range.start, command.range.stop)); - break; - } - - if (command.cursorIndex === undefined) { - throw new Error('No cursor index - this should never ever happen!'); - } - - if (command.diff) { - if (!accumulatedPositionDifferences[command.cursorIndex]) { - accumulatedPositionDifferences[command.cursorIndex] = []; - } - - accumulatedPositionDifferences[command.cursorIndex].push(command.diff); - } - }); + await this.vimState.editor.edit(edit => doTextEditorEdit(command, edit)); } } else { // This is the common case! @@ -906,41 +907,7 @@ export class ModeHandler implements vscode.Disposable { */ await this.vimState.editor.edit(edit => { for (const command of textTransformations) { - switch (command.type) { - case 'insertText': - edit.insert(command.position, command.text); - break; - - case 'replaceText': - edit.replace(new vscode.Selection(command.end, command.start), command.text); - break; - - case 'deleteText': - let matchRange = PairMatcher.immediateMatchingBracket(command.position); - if (matchRange) { - edit.delete(matchRange); - } - edit.delete( - new vscode.Range(command.position, command.position.getLeftThroughLineBreaks()) - ); - break; - - case 'deleteRange': - edit.delete(new vscode.Selection(command.range.start, command.range.stop)); - break; - } - - if (command.cursorIndex === undefined) { - throw new Error('No cursor index - this should never ever happen!'); - } - - if (command.diff) { - if (!accumulatedPositionDifferences[command.cursorIndex]) { - accumulatedPositionDifferences[command.cursorIndex] = []; - } - - accumulatedPositionDifferences[command.cursorIndex].push(command.diff); - } + doTextEditorEdit(command, edit); } }); } @@ -1022,7 +989,9 @@ export class ModeHandler implements vscode.Disposable { accumulatedPositionDifferences[command.cursorIndex].push(command.diff); } - + break; + default: + console.warn(`Unhandled text transformation type: ${command.type}.`); break; } } @@ -1306,7 +1275,7 @@ export class ModeHandler implements vscode.Disposable { } const optionalCursorStyle = - Configuration.cursorStylePerMode[this.currentModeFriendlyName.toLowerCase()]; + Configuration.cursorStylePerMode[this.currentMode.friendlyName.toLowerCase()]; if (optionalCursorStyle !== undefined) { const cursorStyleNum = Configuration.cursorStyleFromString(optionalCursorStyle); if (cursorStyleNum !== undefined) { @@ -1325,7 +1294,7 @@ export class ModeHandler implements vscode.Disposable { ) { // Fake block cursor with text decoration. Unfortunately we can't have a cursor // in the middle of a selection natively, which is what we need for Visual Mode. - if (this.currentModeName === ModeName.Visual) { + if (this.currentMode.name === ModeName.Visual) { for (const { start: cursorStart, stop: cursorStop } of vimState.allCursors) { if (cursorStart.isEarlierThan(cursorStop)) { cursorRange.push(new vscode.Range(cursorStop.getLeft(), cursorStop)); @@ -1354,13 +1323,13 @@ export class ModeHandler implements vscode.Disposable { */ // Draw search highlight + let searchRanges: vscode.Range[] = []; if ( (Configuration.incsearch && this.currentMode.name === ModeName.SearchInProgressMode) || (Configuration.hlsearch && vimState.globalState.hl && vimState.globalState.searchState) ) { const searchState = vimState.globalState.searchState!; - let searchRanges: vscode.Range[] = []; searchRanges.push.apply(searchRanges, searchState.matchRanges); const { pos, match } = searchState.getNextSearchMatchPosition(vimState.cursorPosition); @@ -1368,9 +1337,8 @@ export class ModeHandler implements vscode.Disposable { if (match) { searchRanges.push(new vscode.Range(pos, pos.getRight(searchState.searchString.length))); } - - this.vimState.editor.setDecorations(Decoration.SearchHighlight, searchRanges); } + this.vimState.editor.setDecorations(Decoration.SearchHighlight, searchRanges); const easyMotionHighlightRanges = this.currentMode.name === ModeName.EasyMotionInputMode @@ -1442,7 +1410,7 @@ export class ModeHandler implements vscode.Disposable { private _renderStatusBar(): void { // change status bar color based on mode if (Configuration.statusBarColorControl) { - const colorToSet = Configuration.statusBarColors[this.currentModeFriendlyName.toLowerCase()]; + const colorToSet = Configuration.statusBarColors[this.currentMode.friendlyName.toLowerCase()]; if (colorToSet !== undefined) { StatusBar.SetColor(colorToSet); } @@ -1468,7 +1436,7 @@ export class ModeHandler implements vscode.Disposable { text.push(macroText); } - StatusBar.SetText(text.join(' '), this.currentModeName); + StatusBar.SetText(text.join(' '), this.currentMode.name); } async handleMultipleKeyEvents(keys: string[]): Promise { @@ -1507,7 +1475,6 @@ export class ModeHandler implements vscode.Disposable { } dispose() { - this.vimState.nvim.quit(); this._disposables.map(d => d.dispose()); }