mirror of
https://github.com/VSCodeVim/Vim.git
synced 2024-08-16 15:50:35 +03:00
Stop using jsdiff. Use diff-match-patch.
This commit is contained in:
parent
cba507db79
commit
3352a05859
454
package.json
454
package.json
@ -1,233 +1,233 @@
|
||||
{
|
||||
"name": "vim",
|
||||
"displayName": "Vim",
|
||||
"description": "Vim emulation for Visual Studio Code",
|
||||
"icon": "images/icon.png",
|
||||
"version": "0.1.6",
|
||||
"publisher": "vscodevim",
|
||||
"galleryBanner": {
|
||||
"color": "#a5c9a2",
|
||||
"theme": "light"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"vim",
|
||||
"vi",
|
||||
"vscodevim",
|
||||
"vsc-vim"
|
||||
"name": "vim",
|
||||
"displayName": "Vim",
|
||||
"description": "Vim emulation for Visual Studio Code",
|
||||
"icon": "images/icon.png",
|
||||
"version": "0.1.6",
|
||||
"publisher": "vscodevim",
|
||||
"galleryBanner": {
|
||||
"color": "#a5c9a2",
|
||||
"theme": "light"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"vim",
|
||||
"vi",
|
||||
"vscodevim",
|
||||
"vsc-vim"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/VSCodeVim/Vim.git"
|
||||
},
|
||||
"homepage": "https://github.com/VSCodeVim/Vim",
|
||||
"bugs": {
|
||||
"url": "https://github.com/VSCodeVim/Vim/issues"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.0.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "extension.showCmdLine",
|
||||
"title": "Vim: Show Command Line"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/VSCodeVim/Vim.git"
|
||||
},
|
||||
"homepage": "https://github.com/VSCodeVim/Vim",
|
||||
"bugs": {
|
||||
"url": "https://github.com/VSCodeVim/Vim/issues"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.0.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
"keybindings": [
|
||||
{
|
||||
"key": "Escape",
|
||||
"command": "extension.vim_escape",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "Backspace",
|
||||
"command": "extension.vim_backspace",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "Delete",
|
||||
"command": "extension.vim_delete",
|
||||
"when": "editorTextFocus && vim.mode == 'Normal Mode'"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+r",
|
||||
"command": "extension.vim_ctrl+r",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+f",
|
||||
"command": "extension.vim_ctrl+f",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+b",
|
||||
"command": "extension.vim_ctrl+b",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+e",
|
||||
"command": "extension.vim_ctrl+e",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+y",
|
||||
"command": "extension.vim_ctrl+y",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+u",
|
||||
"command": "extension.vim_ctrl+u",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+v",
|
||||
"command": "extension.vim_ctrl+v",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+d",
|
||||
"command": "extension.vim_ctrl+d",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+[",
|
||||
"command": "extension.vim_ctrl+[",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+w",
|
||||
"command": "extension.vim_ctrl+w",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+c",
|
||||
"command": "extension.vim_ctrl+c",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+a",
|
||||
"command": "extension.vim_ctrl+a",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+x",
|
||||
"command": "extension.vim_ctrl+x",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "left",
|
||||
"command": "extension.vim_left",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "right",
|
||||
"command": "extension.vim_right",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "up",
|
||||
"command": "extension.vim_up",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "down",
|
||||
"command": "extension.vim_down",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
}
|
||||
],
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "extension.showCmdLine",
|
||||
"title": "Vim: Show Command Line"
|
||||
}
|
||||
],
|
||||
"keybindings": [
|
||||
{
|
||||
"key": "Escape",
|
||||
"command": "extension.vim_escape",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "Backspace",
|
||||
"command": "extension.vim_backspace",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "Delete",
|
||||
"command": "extension.vim_delete",
|
||||
"when": "editorTextFocus && vim.mode == 'Normal Mode'"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+r",
|
||||
"command": "extension.vim_ctrl+r",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+f",
|
||||
"command": "extension.vim_ctrl+f",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+b",
|
||||
"command": "extension.vim_ctrl+b",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+e",
|
||||
"command": "extension.vim_ctrl+e",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+y",
|
||||
"command": "extension.vim_ctrl+y",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+u",
|
||||
"command": "extension.vim_ctrl+u",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+v",
|
||||
"command": "extension.vim_ctrl+v",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+d",
|
||||
"command": "extension.vim_ctrl+d",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+[",
|
||||
"command": "extension.vim_ctrl+[",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+w",
|
||||
"command": "extension.vim_ctrl+w",
|
||||
"when": "editorTextFocus"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+c",
|
||||
"command": "extension.vim_ctrl+c",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+a",
|
||||
"command": "extension.vim_ctrl+a",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "ctrl+x",
|
||||
"command": "extension.vim_ctrl+x",
|
||||
"when": "editorTextFocus && vim.useCtrlKeys"
|
||||
},
|
||||
{
|
||||
"key": "left",
|
||||
"command": "extension.vim_left",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "right",
|
||||
"command": "extension.vim_right",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "up",
|
||||
"command": "extension.vim_up",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
},
|
||||
{
|
||||
"key": "down",
|
||||
"command": "extension.vim_down",
|
||||
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
"title": "Vim Configuration",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"vim.otherModesKeyBindings": {
|
||||
"type": "array",
|
||||
"description": "Keybinding overrides to use for normal mode."
|
||||
},
|
||||
"vim.otherModesKeyBindingsNonRecursive": {
|
||||
"type": "array",
|
||||
"description": "Non-recursive keybinding overrides to use for normal mode."
|
||||
},
|
||||
"vim.useCtrlKeys": {
|
||||
"type": "boolean",
|
||||
"description": "Enable some vim ctrl key commands that override otherwise common operations, like ctrl+c"
|
||||
},
|
||||
"vim.insertModeKeyBindings": {
|
||||
"type": "array",
|
||||
"description": "Keybinding overrides to use for insert mode."
|
||||
},
|
||||
"vim.insertModeKeyBindingsNonRecursive": {
|
||||
"type": "array",
|
||||
"description": "Non-recursive keybinding overrides to use for insert mode."
|
||||
},
|
||||
"vim.useSolidBlockCursor": {
|
||||
"type": "boolean",
|
||||
"description": "Use a non blinking block cursor.",
|
||||
"default": false
|
||||
},
|
||||
"vim.scroll": {
|
||||
"type": "number",
|
||||
"description": "Number of lines to scroll with CTRL-U and CTRL-D commands.",
|
||||
"default": 20
|
||||
},
|
||||
"vim.iskeyword": {
|
||||
"type": "string",
|
||||
"description": "keywords contain alphanumeric characters and '_'",
|
||||
"default": "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"
|
||||
},
|
||||
"vim.ignorecase": {
|
||||
"type": "boolean",
|
||||
"description": "Ignore case in search patterns.",
|
||||
"default": true
|
||||
},
|
||||
"vim.smartcase": {
|
||||
"type": "boolean",
|
||||
"description": "Override the 'ignorecase' option if the search pattern contains upper case characters.",
|
||||
"default": true
|
||||
},
|
||||
"vim.hlsearch": {
|
||||
"type": "boolean",
|
||||
"description": "When there is a previous search pattern, highlight all its matches.",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
"configuration": {
|
||||
"title": "Vim Configuration",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"vim.otherModesKeyBindings": {
|
||||
"type": "array",
|
||||
"description": "Keybinding overrides to use for normal mode."
|
||||
},
|
||||
"vim.otherModesKeyBindingsNonRecursive": {
|
||||
"type": "array",
|
||||
"description": "Non-recursive keybinding overrides to use for normal mode."
|
||||
},
|
||||
"vim.useCtrlKeys": {
|
||||
"type": "boolean",
|
||||
"description": "Enable some vim ctrl key commands that override otherwise common operations, like ctrl+c"
|
||||
},
|
||||
"vim.insertModeKeyBindings": {
|
||||
"type": "array",
|
||||
"description": "Keybinding overrides to use for insert mode."
|
||||
},
|
||||
"vim.insertModeKeyBindingsNonRecursive": {
|
||||
"type": "array",
|
||||
"description": "Non-recursive keybinding overrides to use for insert mode."
|
||||
},
|
||||
"vim.useSolidBlockCursor": {
|
||||
"type": "boolean",
|
||||
"description": "Use a non blinking block cursor.",
|
||||
"default": false
|
||||
},
|
||||
"vim.scroll": {
|
||||
"type": "number",
|
||||
"description": "Number of lines to scroll with CTRL-U and CTRL-D commands.",
|
||||
"default": 20
|
||||
},
|
||||
"vim.iskeyword": {
|
||||
"type": "string",
|
||||
"description": "keywords contain alphanumeric characters and '_'",
|
||||
"default": "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"
|
||||
},
|
||||
"vim.ignorecase": {
|
||||
"type": "boolean",
|
||||
"description": "Ignore case in search patterns.",
|
||||
"default": true
|
||||
},
|
||||
"vim.smartcase": {
|
||||
"type": "boolean",
|
||||
"description": "Override the 'ignorecase' option if the search pattern contains upper case characters.",
|
||||
"default": true
|
||||
},
|
||||
"vim.hlsearch": {
|
||||
"type": "boolean",
|
||||
"description": "When there is a previous search pattern, highlight all its matches.",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "node ./node_modules/vscode/bin/compile -p ./",
|
||||
"compile": "node ./node_modules/vscode/bin/compile -watch -p ./",
|
||||
"test": "node ./node_modules/vscode/bin/test",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install && gulp init"
|
||||
},
|
||||
"dependencies": {
|
||||
"copy-paste": "^1.3.0",
|
||||
"diff": "^2.2.3",
|
||||
"lodash": "^4.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-bump": "^2.1.0",
|
||||
"gulp-filter": "^4.0.0",
|
||||
"gulp-git": "^1.7.1",
|
||||
"gulp-inject-string": "^1.1.0",
|
||||
"gulp-shell": "^0.5.2",
|
||||
"gulp-soften": "^0.0.1",
|
||||
"gulp-tag-version": "^1.3.0",
|
||||
"gulp-trimlines": "^1.0.0",
|
||||
"gulp-tslint": "^5.0.0",
|
||||
"gulp-typescript": "^2.13.4",
|
||||
"gulp-typings": "^2.0.0",
|
||||
"merge-stream": "^1.0.0",
|
||||
"tslint": "^3.10.2",
|
||||
"typescript": "2.0.0",
|
||||
"typings": "^1.0.4",
|
||||
"vscode": "^0.11.13"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "node ./node_modules/vscode/bin/compile -p ./",
|
||||
"compile": "node ./node_modules/vscode/bin/compile -watch -p ./",
|
||||
"test": "node ./node_modules/vscode/bin/test",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install && gulp init"
|
||||
},
|
||||
"dependencies": {
|
||||
"copy-paste": "^1.3.0",
|
||||
"diff-match-patch": "^1.0.0",
|
||||
"lodash": "^4.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-bump": "^2.1.0",
|
||||
"gulp-filter": "^4.0.0",
|
||||
"gulp-git": "^1.7.1",
|
||||
"gulp-inject-string": "^1.1.0",
|
||||
"gulp-shell": "^0.5.2",
|
||||
"gulp-soften": "^0.0.1",
|
||||
"gulp-tag-version": "^1.3.0",
|
||||
"gulp-trimlines": "^1.0.0",
|
||||
"gulp-tslint": "^5.0.0",
|
||||
"gulp-typescript": "^2.13.4",
|
||||
"gulp-typings": "^2.0.0",
|
||||
"merge-stream": "^1.0.0",
|
||||
"tslint": "^3.10.2",
|
||||
"typescript": "2.0.0",
|
||||
"typings": "^1.0.4",
|
||||
"vscode": "^0.11.13"
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,10 @@ import * as _ from "lodash";
|
||||
import { Position } from './../motion/position';
|
||||
import { TextEditor } from './../textEditor';
|
||||
|
||||
import jsdiff = require('diff');
|
||||
import DiffMatchPatch = require("diff-match-patch");
|
||||
|
||||
const diffEngine = new DiffMatchPatch.diff_match_patch();
|
||||
diffEngine.Diff_Timeout = 1000;
|
||||
|
||||
export class DocumentChange {
|
||||
start : Position;
|
||||
@ -339,17 +342,30 @@ export class HistoryTracker {
|
||||
// multiple changes in different places simultaneously. For those, we could require
|
||||
// them to call addChange manually, I guess...
|
||||
|
||||
const diffs = jsdiff.diffChars(this.oldText, newText);
|
||||
const diffs = diffEngine.diff_main(this.oldText, newText);
|
||||
|
||||
/*
|
||||
this.historySteps.push(new HistoryStep({
|
||||
changes : [new DocumentChange(new Position(0, 0), TextEditor.getAllText(), true)],
|
||||
isFinished : true,
|
||||
cursorStart: new Position(0, 0)
|
||||
}));
|
||||
*/
|
||||
|
||||
let currentPosition = new Position(0, 0);
|
||||
|
||||
for (const diff of diffs) {
|
||||
const [whatHappened, text] = diff;
|
||||
const added = whatHappened === DiffMatchPatch.DIFF_INSERT;
|
||||
const removed = whatHappened === DiffMatchPatch.DIFF_DELETE;
|
||||
const same = whatHappened === DiffMatchPatch.DIFF_EQUAL;
|
||||
|
||||
let change: DocumentChange;
|
||||
// let lastChange = this.currentHistoryStep.changes.length > 1 &&
|
||||
// this.currentHistoryStep.changes[this.currentHistoryStep.changes.length - 2];
|
||||
|
||||
if (diff.added || diff.removed) {
|
||||
change = new DocumentChange(currentPosition, diff.value, !!diff.added);
|
||||
if (added || removed) {
|
||||
change = new DocumentChange(currentPosition, text, !!added);
|
||||
|
||||
this.currentHistoryStep.changes.push(change);
|
||||
|
||||
@ -358,8 +374,8 @@ export class HistoryTracker {
|
||||
}
|
||||
}
|
||||
|
||||
if (!diff.removed) {
|
||||
currentPosition = currentPosition.advancePositionByText(diff.value);
|
||||
if (!removed) {
|
||||
currentPosition = currentPosition.advancePositionByText(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
9
testing
Normal file
9
testing
Normal file
@ -0,0 +1,9 @@
|
||||
one two blah
|
||||
one two blah
|
||||
one two blah
|
||||
one two blah two blah
|
||||
one two blah
|
||||
one two blah
|
||||
one two blah
|
||||
one two blah
|
||||
one two blah
|
12
tsd.json
Normal file
12
tsd.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": "v4",
|
||||
"repo": "borisyankov/DefinitelyTyped",
|
||||
"ref": "master",
|
||||
"path": "typings",
|
||||
"bundle": "typings/tsd.d.ts",
|
||||
"installed": {
|
||||
"diff-match-patch/diff-match-patch.d.ts": {
|
||||
"commit": "67557f18a898462614ed14063a54ca33a1cfab12"
|
||||
}
|
||||
}
|
||||
}
|
39
typings/diff-match-patch/diff-match-patch.d.ts
vendored
Normal file
39
typings/diff-match-patch/diff-match-patch.d.ts
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// Type definitions for diff-match-patch v1.0.0
|
||||
// Project: https://www.npmjs.com/package/diff-match-patch
|
||||
// Definitions by: Asana <https://asana.com>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
declare module "diff-match-patch" {
|
||||
type Diff = [number, string];
|
||||
|
||||
export class diff_match_patch {
|
||||
static new (): diff_match_patch;
|
||||
|
||||
Diff_Timeout: number;
|
||||
Diff_EditCost: number;
|
||||
Match_Threshold: number;
|
||||
Match_Distance: number;
|
||||
Patch_DeleteThreshold: number;
|
||||
Patch_Margin: number;
|
||||
Match_MaxBits: number;
|
||||
|
||||
diff_main(text1: string, text2: string, opt_checklines?: boolean, opt_deadline?: number): Diff[];
|
||||
diff_commonPrefix(text1: string, text2: string): number;
|
||||
diff_commonSuffix(text1: string, text2: string): number;
|
||||
diff_cleanupSemantic(diffs: Diff[]): void;
|
||||
diff_cleanupSemanticLossless(diffs: Diff[]): void;
|
||||
diff_cleanupEfficiency(diffs: Diff[]): void;
|
||||
diff_cleanupMerge(diffs: Diff[]): void;
|
||||
diff_xIndex(diffs: Diff[], loc: number): number;
|
||||
diff_prettyHtml(diffs: Diff[]): string;
|
||||
diff_text1(diffs: Diff[]): string;
|
||||
diff_text2(diffs: Diff[]): string;
|
||||
diff_levenshtein(diffs: Diff[]): number;
|
||||
diff_toDelta(diffs: Diff[]): string;
|
||||
diff_fromDelta(text1: string, delta: string): Diff[];
|
||||
}
|
||||
|
||||
export var DIFF_DELETE: number;
|
||||
export var DIFF_INSERT: number;
|
||||
export var DIFF_EQUAL: number;
|
||||
}
|
1
typings/tsd.d.ts
vendored
Normal file
1
typings/tsd.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference path="diff-match-patch/diff-match-patch.d.ts" />
|
Loading…
Reference in New Issue
Block a user