mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 10:55:55 +01:00
codemirror 5.65.9
This commit is contained in:
394
libraries/codemirror/keymap/vim.js
vendored
394
libraries/codemirror/keymap/vim.js
vendored
@@ -1,5 +1,14 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../lib/codemirror"), require("../addon/search/searchcursor"), require("../addon/dialog/dialog"), require("../addon/edit/matchbrackets.js"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/dialog/dialog", "../addon/edit/matchbrackets"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
'use strict';
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
|
||||
|
||||
/**
|
||||
* Supported keybindings:
|
||||
@@ -34,15 +43,7 @@
|
||||
* 9. Ex command implementations.
|
||||
*/
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../lib/codemirror"), require("../addon/search/searchcursor"), require("../addon/dialog/dialog"), require("../addon/edit/matchbrackets.js"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/dialog/dialog", "../addon/edit/matchbrackets"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
'use strict';
|
||||
function initVim$1(CodeMirror) {
|
||||
|
||||
var Pos = CodeMirror.Pos;
|
||||
|
||||
@@ -87,6 +88,8 @@
|
||||
{ keys: '<C-c>', type: 'keyToKey', toKeys: '<Esc>' },
|
||||
{ keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },
|
||||
{ keys: '<C-c>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },
|
||||
{ keys: '<C-Esc>', type: 'keyToKey', toKeys: '<Esc>' }, // ipad keyboard sends C-Esc instead of C-[
|
||||
{ keys: '<C-Esc>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },
|
||||
{ keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' },
|
||||
{ keys: 's', type: 'keyToKey', toKeys: 'c', context: 'visual'},
|
||||
{ keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' },
|
||||
@@ -225,8 +228,8 @@
|
||||
{ keys: 'z.', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },
|
||||
{ keys: 'zt', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }},
|
||||
{ keys: 'z<CR>', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },
|
||||
{ keys: 'z-', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }},
|
||||
{ keys: 'zb', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },
|
||||
{ keys: 'zb', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }},
|
||||
{ keys: 'z-', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },
|
||||
{ keys: '.', type: 'action', action: 'repeatLastEdit' },
|
||||
{ keys: '<C-a>', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: true, backtrack: false}},
|
||||
{ keys: '<C-x>', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: false, backtrack: false}},
|
||||
@@ -276,7 +279,6 @@
|
||||
{ name: 'global', shortName: 'g' }
|
||||
];
|
||||
|
||||
var Vim = function() {
|
||||
function enterVimMode(cm) {
|
||||
cm.setOption('disableInput', true);
|
||||
cm.setOption('showCursorWhenSelecting', false);
|
||||
@@ -642,8 +644,8 @@
|
||||
register.clear();
|
||||
this.latestRegister = registerName;
|
||||
if (cm.openDialog) {
|
||||
this.onRecordingDone = cm.openDialog(
|
||||
document.createTextNode('(recording)['+registerName+']'), null, {bottom:true});
|
||||
var template = dom('span', {class: 'cm-vim-message'}, 'recording @' + registerName);
|
||||
this.onRecordingDone = cm.openDialog(template, null, {bottom:true});
|
||||
}
|
||||
this.isRecording = true;
|
||||
}
|
||||
@@ -716,7 +718,8 @@
|
||||
}
|
||||
|
||||
var lastInsertModeKeyTimer;
|
||||
var vimApi= {
|
||||
var vimApi = {
|
||||
enterVimMode: enterVimMode,
|
||||
buildKeyMap: function() {
|
||||
// TODO: Convert keymap into dictionary format for fast lookup.
|
||||
},
|
||||
@@ -838,6 +841,8 @@
|
||||
return command();
|
||||
}
|
||||
},
|
||||
multiSelectHandleKey: multiSelectHandleKey,
|
||||
|
||||
/**
|
||||
* This is the outermost function called by CodeMirror, after keys have
|
||||
* been mapped to their Vim equivalents.
|
||||
@@ -865,13 +870,17 @@
|
||||
}
|
||||
function handleEsc() {
|
||||
if (key == '<Esc>') {
|
||||
// Clear input state and get back to normal mode.
|
||||
clearInputState(cm);
|
||||
if (vim.visualMode) {
|
||||
// Get back to normal mode.
|
||||
exitVisualMode(cm);
|
||||
} else if (vim.insertMode) {
|
||||
// Get back to normal mode.
|
||||
exitInsertMode(cm);
|
||||
} else {
|
||||
// We're already in normal mode. Let '<Esc>' be handled normally.
|
||||
return;
|
||||
}
|
||||
clearInputState(cm);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -939,9 +948,10 @@
|
||||
var match = commandDispatcher.matchCommand(mainKey, defaultKeymap, vim.inputState, context);
|
||||
if (match.type == 'none') { clearInputState(cm); return false; }
|
||||
else if (match.type == 'partial') { return true; }
|
||||
else if (match.type == 'clear') { clearInputState(cm); return true; }
|
||||
|
||||
vim.inputState.keyBuffer = '';
|
||||
var keysMatcher = /^(\d*)(.*)$/.exec(keys);
|
||||
keysMatcher = /^(\d*)(.*)$/.exec(keys);
|
||||
if (keysMatcher[1] && keysMatcher[1] != '0') {
|
||||
vim.inputState.pushRepeatDigit(keysMatcher[1]);
|
||||
}
|
||||
@@ -1243,7 +1253,7 @@
|
||||
}
|
||||
if (bestMatch.keys.slice(-11) == '<character>') {
|
||||
var character = lastChar(keys);
|
||||
if (!character) return {type: 'none'};
|
||||
if (!character || character.length > 1) return {type: 'clear'};
|
||||
inputState.selectedCharacter = character;
|
||||
}
|
||||
return {type: 'full', command: bestMatch};
|
||||
@@ -1270,8 +1280,6 @@
|
||||
case 'keyToEx':
|
||||
this.processEx(cm, vim, command);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
processMotion: function(cm, vim, command) {
|
||||
@@ -1487,6 +1495,7 @@
|
||||
vimGlobalState.exCommandHistoryController.pushInput(input);
|
||||
vimGlobalState.exCommandHistoryController.reset();
|
||||
exCommandDispatcher.processCommand(cm, input);
|
||||
clearInputState(cm);
|
||||
}
|
||||
function onPromptKeyDown(e, input, close) {
|
||||
var keyName = CodeMirror.keyName(e), up, offset;
|
||||
@@ -2007,7 +2016,7 @@
|
||||
}
|
||||
var orig = cm.charCoords(head, 'local');
|
||||
motionArgs.repeat = repeat;
|
||||
var curEnd = motions.moveByDisplayLines(cm, head, motionArgs, vim);
|
||||
curEnd = motions.moveByDisplayLines(cm, head, motionArgs, vim);
|
||||
if (!curEnd) {
|
||||
return null;
|
||||
}
|
||||
@@ -2150,6 +2159,20 @@
|
||||
}
|
||||
} else if (character === 't') {
|
||||
tmp = expandTagUnderCursor(cm, head, inclusive);
|
||||
} else if (character === 's') {
|
||||
// account for cursor on end of sentence symbol
|
||||
var content = cm.getLine(head.line);
|
||||
if (head.ch > 0 && isEndOfSentenceSymbol(content[head.ch])) {
|
||||
head.ch -= 1;
|
||||
}
|
||||
var end = getSentence(cm, head, motionArgs.repeat, 1, inclusive);
|
||||
var start = getSentence(cm, head, motionArgs.repeat, -1, inclusive);
|
||||
// closer vim behaviour, 'a' only takes the space after the sentence if there is one before and after
|
||||
if (isWhiteSpaceString(cm.getLine(start.line)[start.ch])
|
||||
&& isWhiteSpaceString(cm.getLine(end.line)[end.ch -1])) {
|
||||
start = {line: start.line, ch: start.ch + 1};
|
||||
}
|
||||
tmp = {start: start, end: end};
|
||||
} else {
|
||||
// No text object defined for this, don't move.
|
||||
return null;
|
||||
@@ -2232,7 +2255,7 @@
|
||||
} else if (args.fullLine) {
|
||||
head.ch = Number.MAX_VALUE;
|
||||
head.line--;
|
||||
cm.setSelection(anchor, head)
|
||||
cm.setSelection(anchor, head);
|
||||
text = cm.getSelection();
|
||||
cm.replaceSelection("");
|
||||
finalHead = anchor;
|
||||
@@ -2284,22 +2307,30 @@
|
||||
},
|
||||
indent: function(cm, args, ranges) {
|
||||
var vim = cm.state.vim;
|
||||
var startLine = ranges[0].anchor.line;
|
||||
var endLine = vim.visualBlock ?
|
||||
ranges[ranges.length - 1].anchor.line :
|
||||
ranges[0].head.line;
|
||||
// In visual mode, n> shifts the selection right n times, instead of
|
||||
// shifting n lines right once.
|
||||
var repeat = (vim.visualMode) ? args.repeat : 1;
|
||||
if (args.linewise) {
|
||||
// The only way to delete a newline is to delete until the start of
|
||||
// the next line, so in linewise mode evalInput will include the next
|
||||
// line. We don't want this in indent, so we go back a line.
|
||||
endLine--;
|
||||
}
|
||||
for (var i = startLine; i <= endLine; i++) {
|
||||
if (cm.indentMore) {
|
||||
var repeat = (vim.visualMode) ? args.repeat : 1;
|
||||
for (var j = 0; j < repeat; j++) {
|
||||
cm.indentLine(i, args.indentRight);
|
||||
if (args.indentRight) cm.indentMore();
|
||||
else cm.indentLess();
|
||||
}
|
||||
} else {
|
||||
var startLine = ranges[0].anchor.line;
|
||||
var endLine = vim.visualBlock ?
|
||||
ranges[ranges.length - 1].anchor.line :
|
||||
ranges[0].head.line;
|
||||
// In visual mode, n> shifts the selection right n times, instead of
|
||||
// shifting n lines right once.
|
||||
var repeat = (vim.visualMode) ? args.repeat : 1;
|
||||
if (args.linewise) {
|
||||
// The only way to delete a newline is to delete until the start of
|
||||
// the next line, so in linewise mode evalInput will include the next
|
||||
// line. We don't want this in indent, so we go back a line.
|
||||
endLine--;
|
||||
}
|
||||
for (var i = startLine; i <= endLine; i++) {
|
||||
for (var j = 0; j < repeat; j++) {
|
||||
cm.indentLine(i, args.indentRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor);
|
||||
@@ -2412,11 +2443,14 @@
|
||||
var charCoords = cm.charCoords(new Pos(lineNum, 0), 'local');
|
||||
var height = cm.getScrollInfo().clientHeight;
|
||||
var y = charCoords.top;
|
||||
var lineHeight = charCoords.bottom - y;
|
||||
switch (actionArgs.position) {
|
||||
case 'center': y = y - (height / 2) + lineHeight;
|
||||
case 'center': y = charCoords.bottom - height / 2;
|
||||
break;
|
||||
case 'bottom': y = y - height + lineHeight;
|
||||
case 'bottom':
|
||||
var lineLastCharPos = new Pos(lineNum, cm.getLine(lineNum).length - 1);
|
||||
var lineLastCharCoords = cm.charCoords(lineLastCharPos, 'local');
|
||||
var lineHeight = lineLastCharCoords.bottom - y;
|
||||
y = y - height + lineHeight;
|
||||
break;
|
||||
}
|
||||
cm.scrollTo(null, y);
|
||||
@@ -2866,13 +2900,13 @@
|
||||
}
|
||||
if (!actionArgs.backtrack && (end <= cur.ch))return;
|
||||
if (match) {
|
||||
var baseStr = match[2] || match[4]
|
||||
var digits = match[3] || match[5]
|
||||
var baseStr = match[2] || match[4];
|
||||
var digits = match[3] || match[5];
|
||||
var increment = actionArgs.increase ? 1 : -1;
|
||||
var base = {'0b': 2, '0': 8, '': 10, '0x': 16}[baseStr.toLowerCase()];
|
||||
var number = parseInt(match[1] + digits, base) + (increment * actionArgs.repeat);
|
||||
numberStr = number.toString(base);
|
||||
var zeroPadding = baseStr ? new Array(digits.length - numberStr.length + 1 + match[1].length).join('0') : ''
|
||||
var zeroPadding = baseStr ? new Array(digits.length - numberStr.length + 1 + match[1].length).join('0') : '';
|
||||
if (numberStr.charAt(0) === '-') {
|
||||
numberStr = '-' + baseStr + zeroPadding + numberStr.substr(1);
|
||||
} else {
|
||||
@@ -3244,9 +3278,8 @@
|
||||
fromCh = anchor.ch,
|
||||
bottom = Math.max(anchor.line, head.line),
|
||||
toCh = head.ch;
|
||||
if (fromCh < toCh) { toCh += 1 }
|
||||
else { fromCh += 1 };
|
||||
var height = bottom - top + 1;
|
||||
if (fromCh < toCh) { toCh += 1; }
|
||||
else { fromCh += 1; } var height = bottom - top + 1;
|
||||
var primary = head.line == top ? 0 : height - 1;
|
||||
var ranges = [];
|
||||
for (var i = 0; i < height; i++) {
|
||||
@@ -3798,21 +3831,156 @@
|
||||
start = new Pos(i, 0);
|
||||
return { start: start, end: end };
|
||||
}
|
||||
|
||||
function findSentence(cm, cur, repeat, dir) {
|
||||
|
||||
/*
|
||||
Takes an index object
|
||||
{
|
||||
line: the line string,
|
||||
ln: line number,
|
||||
pos: index in line,
|
||||
dir: direction of traversal (-1 or 1)
|
||||
function getSentence(cm, cur, repeat, dir, inclusive /*includes whitespace*/) {
|
||||
/*
|
||||
Takes an index object
|
||||
{
|
||||
line: the line string,
|
||||
ln: line number,
|
||||
pos: index in line,
|
||||
dir: direction of traversal (-1 or 1)
|
||||
}
|
||||
and modifies the pos member to represent the
|
||||
next valid position or sets the line to null if there are
|
||||
no more valid positions.
|
||||
*/
|
||||
function nextChar(curr) {
|
||||
if (curr.pos + curr.dir < 0 || curr.pos + curr.dir >= curr.line.length) {
|
||||
curr.line = null;
|
||||
}
|
||||
and modifies the line, ln, and pos members to represent the
|
||||
next valid position or sets them to null if there are
|
||||
no more valid positions.
|
||||
*/
|
||||
else {
|
||||
curr.pos += curr.dir;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Performs one iteration of traversal in forward direction
|
||||
Returns an index object of the new location
|
||||
*/
|
||||
function forward(cm, ln, pos, dir) {
|
||||
var line = cm.getLine(ln);
|
||||
|
||||
var curr = {
|
||||
line: line,
|
||||
ln: ln,
|
||||
pos: pos,
|
||||
dir: dir,
|
||||
};
|
||||
|
||||
if (curr.line === "") {
|
||||
return { ln: curr.ln, pos: curr.pos };
|
||||
}
|
||||
|
||||
var lastSentencePos = curr.pos;
|
||||
|
||||
// Move one step to skip character we start on
|
||||
nextChar(curr);
|
||||
|
||||
while (curr.line !== null) {
|
||||
lastSentencePos = curr.pos;
|
||||
if (isEndOfSentenceSymbol(curr.line[curr.pos])) {
|
||||
if (!inclusive) {
|
||||
return { ln: curr.ln, pos: curr.pos + 1 };
|
||||
} else {
|
||||
nextChar(curr);
|
||||
while (curr.line !== null ) {
|
||||
if (isWhiteSpaceString(curr.line[curr.pos])) {
|
||||
lastSentencePos = curr.pos;
|
||||
nextChar(curr);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { ln: curr.ln, pos: lastSentencePos + 1, };
|
||||
}
|
||||
}
|
||||
nextChar(curr);
|
||||
}
|
||||
return { ln: curr.ln, pos: lastSentencePos + 1 };
|
||||
}
|
||||
|
||||
/*
|
||||
Performs one iteration of traversal in reverse direction
|
||||
Returns an index object of the new location
|
||||
*/
|
||||
function reverse(cm, ln, pos, dir) {
|
||||
var line = cm.getLine(ln);
|
||||
|
||||
var curr = {
|
||||
line: line,
|
||||
ln: ln,
|
||||
pos: pos,
|
||||
dir: dir,
|
||||
};
|
||||
|
||||
if (curr.line === "") {
|
||||
return { ln: curr.ln, pos: curr.pos };
|
||||
}
|
||||
|
||||
var lastSentencePos = curr.pos;
|
||||
|
||||
// Move one step to skip character we start on
|
||||
nextChar(curr);
|
||||
|
||||
while (curr.line !== null) {
|
||||
if (!isWhiteSpaceString(curr.line[curr.pos]) && !isEndOfSentenceSymbol(curr.line[curr.pos])) {
|
||||
lastSentencePos = curr.pos;
|
||||
}
|
||||
|
||||
else if (isEndOfSentenceSymbol(curr.line[curr.pos]) ) {
|
||||
if (!inclusive) {
|
||||
return { ln: curr.ln, pos: lastSentencePos };
|
||||
} else {
|
||||
if (isWhiteSpaceString(curr.line[curr.pos + 1])) {
|
||||
return { ln: curr.ln, pos: curr.pos + 1, };
|
||||
} else {
|
||||
return {ln: curr.ln, pos: lastSentencePos};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextChar(curr);
|
||||
}
|
||||
curr.line = line;
|
||||
if (inclusive && isWhiteSpaceString(curr.line[curr.pos])) {
|
||||
return { ln: curr.ln, pos: curr.pos };
|
||||
} else {
|
||||
return { ln: curr.ln, pos: lastSentencePos };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var curr_index = {
|
||||
ln: cur.line,
|
||||
pos: cur.ch,
|
||||
};
|
||||
|
||||
while (repeat > 0) {
|
||||
if (dir < 0) {
|
||||
curr_index = reverse(cm, curr_index.ln, curr_index.pos, dir);
|
||||
}
|
||||
else {
|
||||
curr_index = forward(cm, curr_index.ln, curr_index.pos, dir);
|
||||
}
|
||||
repeat--;
|
||||
}
|
||||
|
||||
return new Pos(curr_index.ln, curr_index.pos);
|
||||
}
|
||||
|
||||
function findSentence(cm, cur, repeat, dir) {
|
||||
|
||||
/*
|
||||
Takes an index object
|
||||
{
|
||||
line: the line string,
|
||||
ln: line number,
|
||||
pos: index in line,
|
||||
dir: direction of traversal (-1 or 1)
|
||||
}
|
||||
and modifies the line, ln, and pos members to represent the
|
||||
next valid position or sets them to null if there are
|
||||
no more valid positions.
|
||||
*/
|
||||
function nextChar(cm, idx) {
|
||||
if (idx.pos + idx.dir < 0 || idx.pos + idx.dir >= idx.line.length) {
|
||||
idx.ln += idx.dir;
|
||||
@@ -3843,12 +4011,12 @@
|
||||
ln: ln,
|
||||
pos: pos,
|
||||
dir: dir,
|
||||
}
|
||||
};
|
||||
|
||||
var last_valid = {
|
||||
ln: curr.ln,
|
||||
pos: curr.pos,
|
||||
}
|
||||
};
|
||||
|
||||
var skip_empty_lines = (curr.line === "");
|
||||
|
||||
@@ -3904,7 +4072,7 @@
|
||||
ln: ln,
|
||||
pos: pos,
|
||||
dir: dir,
|
||||
}
|
||||
};
|
||||
|
||||
var last_valid = {
|
||||
ln: curr.ln,
|
||||
@@ -3933,7 +4101,7 @@
|
||||
}
|
||||
else if (curr.line !== "" && !isWhiteSpaceString(curr.line[curr.pos])) {
|
||||
skip_empty_lines = false;
|
||||
last_valid = { ln: curr.ln, pos: curr.pos }
|
||||
last_valid = { ln: curr.ln, pos: curr.pos };
|
||||
}
|
||||
|
||||
nextChar(cm, curr);
|
||||
@@ -4325,7 +4493,7 @@
|
||||
}
|
||||
|
||||
function showConfirm(cm, template) {
|
||||
var pre = dom('pre', {$color: 'red', class: 'cm-vim-message'}, template);
|
||||
var pre = dom('div', {$color: 'red', $whiteSpace: 'pre', class: 'cm-vim-message'}, template);
|
||||
if (cm.openNotification) {
|
||||
cm.openNotification(pre, {bottom: true, duration: 5000});
|
||||
} else {
|
||||
@@ -4920,7 +5088,7 @@
|
||||
for (var registerName in registers) {
|
||||
var text = registers[registerName].toString();
|
||||
if (text.length) {
|
||||
regInfo += '"' + registerName + ' ' + text + '\n'
|
||||
regInfo += '"' + registerName + ' ' + text + '\n';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -4932,7 +5100,7 @@
|
||||
continue;
|
||||
}
|
||||
var register = registers[registerName] || new Register();
|
||||
regInfo += '"' + registerName + ' ' + register.toString() + '\n'
|
||||
regInfo += '"' + registerName + ' ' + register.toString() + '\n';
|
||||
}
|
||||
}
|
||||
showConfirm(cm, regInfo);
|
||||
@@ -5726,9 +5894,85 @@
|
||||
}
|
||||
}
|
||||
|
||||
// multiselect support
|
||||
function cloneVimState(state) {
|
||||
var n = new state.constructor();
|
||||
Object.keys(state).forEach(function(key) {
|
||||
var o = state[key];
|
||||
if (Array.isArray(o))
|
||||
o = o.slice();
|
||||
else if (o && typeof o == "object" && o.constructor != Object)
|
||||
o = cloneVimState(o);
|
||||
n[key] = o;
|
||||
});
|
||||
if (state.sel) {
|
||||
n.sel = {
|
||||
head: state.sel.head && copyCursor(state.sel.head),
|
||||
anchor: state.sel.anchor && copyCursor(state.sel.anchor)
|
||||
};
|
||||
}
|
||||
return n;
|
||||
}
|
||||
function multiSelectHandleKey(cm, key, origin) {
|
||||
var isHandled = false;
|
||||
var vim = vimApi.maybeInitVimState_(cm);
|
||||
var visualBlock = vim.visualBlock || vim.wasInVisualBlock;
|
||||
|
||||
var wasMultiselect = cm.isInMultiSelectMode();
|
||||
if (vim.wasInVisualBlock && !wasMultiselect) {
|
||||
vim.wasInVisualBlock = false;
|
||||
} else if (wasMultiselect && vim.visualBlock) {
|
||||
vim.wasInVisualBlock = true;
|
||||
}
|
||||
|
||||
if (key == '<Esc>' && !vim.insertMode && !vim.visualMode && wasMultiselect && vim.status == "<Esc>") {
|
||||
// allow editor to exit multiselect
|
||||
clearInputState(cm);
|
||||
} else if (visualBlock || !wasMultiselect || cm.inVirtualSelectionMode) {
|
||||
isHandled = vimApi.handleKey(cm, key, origin);
|
||||
} else {
|
||||
var old = cloneVimState(vim);
|
||||
|
||||
cm.operation(function() {
|
||||
cm.curOp.isVimOp = true;
|
||||
cm.forEachSelection(function() {
|
||||
var head = cm.getCursor("head");
|
||||
var anchor = cm.getCursor("anchor");
|
||||
var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0;
|
||||
var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0;
|
||||
head = offsetCursor(head, 0, headOffset);
|
||||
anchor = offsetCursor(anchor, 0, anchorOffset);
|
||||
cm.state.vim.sel.head = head;
|
||||
cm.state.vim.sel.anchor = anchor;
|
||||
|
||||
isHandled = vimApi.handleKey(cm, key, origin);
|
||||
if (cm.virtualSelection) {
|
||||
cm.state.vim = cloneVimState(old);
|
||||
}
|
||||
});
|
||||
if (cm.curOp.cursorActivity && !isHandled)
|
||||
cm.curOp.cursorActivity = false;
|
||||
cm.state.vim = vim;
|
||||
}, true);
|
||||
}
|
||||
// some commands may bring visualMode and selection out of sync
|
||||
if (isHandled && !vim.visualMode && !vim.insert && vim.visualMode != cm.somethingSelected()) {
|
||||
handleExternalSelection(cm, vim);
|
||||
}
|
||||
return isHandled;
|
||||
}
|
||||
resetVimGlobalState();
|
||||
return vimApi;
|
||||
};
|
||||
// Initialize Vim and make it available as an API.
|
||||
CodeMirror.Vim = Vim();
|
||||
});
|
||||
|
||||
return vimApi;
|
||||
}
|
||||
|
||||
function initVim(CodeMirror5) {
|
||||
CodeMirror5.Vim = initVim$1(CodeMirror5);
|
||||
return CodeMirror5.Vim;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CodeMirror.Vim = initVim(CodeMirror);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user