Updated codemirror to 5.4.0

This commit is contained in:
Wu Cheng-Han 2015-07-04 11:31:01 +08:00
parent 1d843c8ac2
commit 01685c255f
69 changed files with 2988 additions and 558 deletions

View file

@ -3,42 +3,16 @@
/**
* Supported keybindings:
* Too many to list. Refer to defaultKeyMap below.
*
* Motion:
* h, j, k, l
* gj, gk
* e, E, w, W, b, B, ge, gE
* f<character>, F<character>, t<character>, T<character>
* $, ^, 0, -, +, _
* gg, G
* %
* '<character>, `<character>
*
* Operator:
* d, y, c
* dd, yy, cc
* g~, g~g~
* >, <, >>, <<
*
* Operator-Motion:
* x, X, D, Y, C, ~
*
* Action:
* a, i, s, A, I, S, o, O
* zz, z., z<CR>, zt, zb, z-
* J
* u, Ctrl-r
* m<character>
* r<character>
*
* Modes:
* ESC - leave insert mode, visual mode, and clear input state.
* Ctrl-[, Ctrl-c - same as ESC.
* Supported Ex commands:
* Refer to defaultExCommandMap below.
*
* Registers: unnamed, -, a-z, A-Z, 0-9
* (Does not respect the special case for number registers when delete
* operator is made with these commands: %, (, ), , /, ?, n, N, {, } )
* TODO: Implement the remaining registers.
*
* Marks: a-z, A-Z, and 0-9
* TODO: Implement the remaining special marks. They have more complex
* behavior.
@ -57,6 +31,7 @@
* 6. Motion, operator, and action implementations
* 7. Helper functions for the key handler, motions, operators, and actions
* 8. Set up Vim to work as a keymap for CodeMirror.
* 9. Ex command implementations.
*/
(function(mod) {
@ -227,6 +202,34 @@
{ keys: ':', type: 'ex' }
];
/**
* Ex commands
* Care must be taken when adding to the default Ex command map. For any
* pair of commands that have a shared prefix, at least one of their
* shortNames must not match the prefix of the other command.
*/
var defaultExCommandMap = [
{ name: 'colorscheme', shortName: 'colo' },
{ name: 'map' },
{ name: 'imap', shortName: 'im' },
{ name: 'nmap', shortName: 'nm' },
{ name: 'vmap', shortName: 'vm' },
{ name: 'unmap' },
{ name: 'write', shortName: 'w' },
{ name: 'undo', shortName: 'u' },
{ name: 'redo', shortName: 'red' },
{ name: 'set', shortName: 'se' },
{ name: 'set', shortName: 'se' },
{ name: 'setlocal', shortName: 'setl' },
{ name: 'setglobal', shortName: 'setg' },
{ name: 'sort', shortName: 'sor' },
{ name: 'substitute', shortName: 's', possiblyAsync: true },
{ name: 'nohlsearch', shortName: 'noh' },
{ name: 'delmarks', shortName: 'delm' },
{ name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
{ name: 'global', shortName: 'g' }
];
var Pos = CodeMirror.Pos;
var Vim = function() {
@ -463,7 +466,7 @@
}
// The 'filetype' option proxies to the CodeMirror 'mode' option.
if (name === undefined) {
var mode = cm.getMode().name;
var mode = cm.getOption('mode');
return mode == 'null' ? '' : mode;
} else {
var mode = name == '' ? 'null' : name;
@ -689,7 +692,9 @@
getOption: getOption,
defineOption: defineOption,
defineEx: function(name, prefix, func){
if (name.indexOf(prefix) !== 0) {
if (!prefix) {
prefix = name;
} else if (name.indexOf(prefix) !== 0) {
throw new Error('(Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", command not registered');
}
exCommands[name]=func;
@ -846,6 +851,8 @@
mapCommand: mapCommand,
_mapCommand: _mapCommand,
defineRegister: defineRegister,
exitVisualMode: exitVisualMode,
exitInsertMode: exitInsertMode
};
@ -935,6 +942,25 @@
}
};
/**
* Defines an external register.
*
* The name should be a single character that will be used to reference the register.
* The register should support setText, pushText, clear, and toString(). See Register
* for a reference implementation.
*/
function defineRegister(name, register) {
var registers = vimGlobalState.registerController.registers[name];
if (!name || name.length != 1) {
throw Error('Register name must be 1 character');
}
if (registers[name]) {
throw Error('Register already defined ' + name);
}
registers[name] = register;
validRegisters.push(name);
}
/*
* vim registers allow you to keep many independent copy and paste buffers.
* See http://usevim.com/2012/04/13/registers/ for an introduction.
@ -3635,13 +3661,17 @@
// Translates the replace part of a search and replace from ex (vim) syntax into
// javascript form. Similar to translateRegex, but additionally fixes back references
// (translates '\[0..9]' to '$[0..9]') and follows different rules for escaping '$'.
var charUnescapes = {'\\n': '\n', '\\r': '\r', '\\t': '\t'};
function translateRegexReplace(str) {
var escapeNextChar = false;
var out = [];
for (var i = -1; i < str.length; i++) {
var c = str.charAt(i) || '';
var n = str.charAt(i+1) || '';
if (escapeNextChar) {
if (charUnescapes[c + n]) {
out.push(charUnescapes[c+n]);
i++;
} else if (escapeNextChar) {
// At any point in the loop, escapeNextChar is true if the previous
// character was a '\' and was not escaped.
out.push(c);
@ -3669,6 +3699,7 @@
}
// Unescape \ and / in the replace part, for PCRE mode.
var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'};
function unescapeRegexReplace(str) {
var stream = new CodeMirror.StringStream(str);
var output = [];
@ -3677,13 +3708,15 @@
while (stream.peek() && stream.peek() != '\\') {
output.push(stream.next());
}
if (stream.match('\\/', true)) {
// \/ => /
output.push('/');
} else if (stream.match('\\\\', true)) {
// \\ => \
output.push('\\');
} else {
var matched = false;
for (var matcher in unescapes) {
if (stream.match(matcher, true)) {
matched = true;
output.push(unescapes[matcher]);
break;
}
}
if (!matched) {
// Don't change anything
output.push(stream.next());
}
@ -3913,31 +3946,6 @@
return {top: from.line, bottom: to.line};
}
// Ex command handling
// Care must be taken when adding to the default Ex command map. For any
// pair of commands that have a shared prefix, at least one of their
// shortNames must not match the prefix of the other command.
var defaultExCommandMap = [
{ name: 'colorscheme', shortName: 'colo' },
{ name: 'map' },
{ name: 'imap', shortName: 'im' },
{ name: 'nmap', shortName: 'nm' },
{ name: 'vmap', shortName: 'vm' },
{ name: 'unmap' },
{ name: 'write', shortName: 'w' },
{ name: 'undo', shortName: 'u' },
{ name: 'redo', shortName: 'red' },
{ name: 'set', shortName: 'se' },
{ name: 'set', shortName: 'se' },
{ name: 'setlocal', shortName: 'setl' },
{ name: 'setglobal', shortName: 'setg' },
{ name: 'sort', shortName: 'sor' },
{ name: 'substitute', shortName: 's', possiblyAsync: true },
{ name: 'nohlsearch', shortName: 'noh' },
{ name: 'delmarks', shortName: 'delm' },
{ name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
{ name: 'global', shortName: 'g' }
];
var ExCommandDispatcher = function() {
this.buildCommandMap_();
};
@ -4483,6 +4491,9 @@
var query = state.getQuery();
var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line;
var lineEnd = params.lineEnd || lineStart;
if (lineStart == cm.firstLine() && lineEnd == cm.lastLine()) {
lineEnd = Infinity;
}
if (count) {
lineStart = lineEnd;
lineEnd = lineStart + count - 1;
@ -4601,10 +4612,9 @@
searchCursor.replace(newText);
}
function next() {
var found;
// The below only loops to skip over multiple occurrences on the same
// line when 'global' is not true.
while(found = searchCursor.findNext() &&
while(searchCursor.findNext() &&
isInRange(searchCursor.from(), lineStart, lineEnd)) {
if (!global && lastPos && searchCursor.from().line == lastPos.line) {
continue;
@ -4737,7 +4747,7 @@
}
function _mapCommand(command) {
defaultKeymap.push(command);
defaultKeymap.unshift(command);
}
function mapCommand(keys, type, name, args, extra) {
@ -4779,6 +4789,14 @@
function executeMacroRegister(cm, vim, macroModeState, registerName) {
var register = vimGlobalState.registerController.getRegister(registerName);
if (registerName == ':') {
// Read-only register containing last Ex command.
if (register.keyBuffer[0]) {
exCommandDispatcher.processCommand(cm, register.keyBuffer[0]);
}
macroModeState.isPlaying = false;
return;
}
var keyBuffer = register.keyBuffer;
var imc = 0;
macroModeState.isPlaying = true;
@ -4818,7 +4836,7 @@
if (macroModeState.isPlaying) { return; }
var registerName = macroModeState.latestRegister;
var register = vimGlobalState.registerController.getRegister(registerName);
if (register) {
if (register && register.pushInsertModeChanges) {
register.pushInsertModeChanges(macroModeState.lastInsertModeChanges);
}
}
@ -4827,7 +4845,7 @@
if (macroModeState.isPlaying) { return; }
var registerName = macroModeState.latestRegister;
var register = vimGlobalState.registerController.getRegister(registerName);
if (register) {
if (register && register.pushSearchQuery) {
register.pushSearchQuery(query);
}
}