1222 lines
166 KiB
JavaScript
1222 lines
166 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
var obsidian = require('obsidian');
|
||
|
|
||
|
/*! *****************************************************************************
|
||
|
Copyright (c) Microsoft Corporation.
|
||
|
|
||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||
|
purpose with or without fee is hereby granted.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||
|
PERFORMANCE OF THIS SOFTWARE.
|
||
|
***************************************************************************** */
|
||
|
/* global Reflect, Promise */
|
||
|
|
||
|
var extendStatics = function(d, b) {
|
||
|
extendStatics = Object.setPrototypeOf ||
|
||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||
|
return extendStatics(d, b);
|
||
|
};
|
||
|
|
||
|
function __extends(d, b) {
|
||
|
extendStatics(d, b);
|
||
|
function __() { this.constructor = d; }
|
||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
|
}
|
||
|
|
||
|
function __awaiter(thisArg, _arguments, P, generator) {
|
||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function __generator(thisArg, body) {
|
||
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||
|
function step(op) {
|
||
|
if (f) throw new TypeError("Generator is already executing.");
|
||
|
while (_) try {
|
||
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||
|
switch (op[0]) {
|
||
|
case 0: case 1: t = op; break;
|
||
|
case 4: _.label++; return { value: op[1], done: false };
|
||
|
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||
|
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||
|
default:
|
||
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||
|
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||
|
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||
|
if (t[2]) _.ops.pop();
|
||
|
_.trys.pop(); continue;
|
||
|
}
|
||
|
op = body.call(thisArg, _);
|
||
|
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const modifiers = /^(CommandOrControl|CmdOrCtrl|Command|Cmd|Control|Ctrl|AltGr|Option|Alt|Shift|Super)/i;
|
||
|
const keyCodes = /^(Plus|Space|Tab|Backspace|Delete|Insert|Return|Enter|Up|Down|Left|Right|Home|End|PageUp|PageDown|Escape|Esc|VolumeUp|VolumeDown|VolumeMute|MediaNextTrack|MediaPreviousTrack|MediaStop|MediaPlayPause|PrintScreen|F24|F23|F22|F21|F20|F19|F18|F17|F16|F15|F14|F13|F12|F11|F10|F9|F8|F7|F6|F5|F4|F3|F2|F1|[0-9A-Z)!@#$%^&*(:+<_>?~{|}";=,\-./`[\\\]'])/i;
|
||
|
const UNSUPPORTED = {};
|
||
|
|
||
|
function _command(accelerator, event, modifier) {
|
||
|
if (process.platform !== 'darwin') {
|
||
|
return UNSUPPORTED;
|
||
|
}
|
||
|
|
||
|
if (event.metaKey) {
|
||
|
throw new Error('Double `Command` modifier specified.');
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {metaKey: true}),
|
||
|
accelerator: accelerator.slice(modifier.length)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function _super(accelerator, event, modifier) {
|
||
|
if (event.metaKey) {
|
||
|
throw new Error('Double `Super` modifier specified.');
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {metaKey: true}),
|
||
|
accelerator: accelerator.slice(modifier.length)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function _commandorcontrol(accelerator, event, modifier) {
|
||
|
if (process.platform === 'darwin') {
|
||
|
if (event.metaKey) {
|
||
|
throw new Error('Double `Command` modifier specified.');
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {metaKey: true}),
|
||
|
accelerator: accelerator.slice(modifier.length)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
if (event.ctrlKey) {
|
||
|
throw new Error('Double `Control` modifier specified.');
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {ctrlKey: true}),
|
||
|
accelerator: accelerator.slice(modifier.length)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function _alt(accelerator, event, modifier) {
|
||
|
if (modifier === 'option' && process.platform !== 'darwin') {
|
||
|
return UNSUPPORTED;
|
||
|
}
|
||
|
|
||
|
if (event.altKey) {
|
||
|
throw new Error('Double `Alt` modifier specified.');
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {altKey: true}),
|
||
|
accelerator: accelerator.slice(modifier.length)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function _shift(accelerator, event, modifier) {
|
||
|
if (event.shiftKey) {
|
||
|
throw new Error('Double `Shift` modifier specified.');
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {shiftKey: true}),
|
||
|
accelerator: accelerator.slice(modifier.length)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function _control(accelerator, event, modifier) {
|
||
|
if (event.ctrlKey) {
|
||
|
throw new Error('Double `Control` modifier specified.');
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {ctrlKey: true}),
|
||
|
accelerator: accelerator.slice(modifier.length)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function reduceModifier({accelerator, event}, modifier) {
|
||
|
switch (modifier) {
|
||
|
case 'command':
|
||
|
case 'cmd': {
|
||
|
return _command(accelerator, event, modifier);
|
||
|
}
|
||
|
|
||
|
case 'super': {
|
||
|
return _super(accelerator, event, modifier);
|
||
|
}
|
||
|
|
||
|
case 'control':
|
||
|
case 'ctrl': {
|
||
|
return _control(accelerator, event, modifier);
|
||
|
}
|
||
|
|
||
|
case 'commandorcontrol':
|
||
|
case 'cmdorctrl': {
|
||
|
return _commandorcontrol(accelerator, event, modifier);
|
||
|
}
|
||
|
|
||
|
case 'option':
|
||
|
case 'altgr':
|
||
|
case 'alt': {
|
||
|
return _alt(accelerator, event, modifier);
|
||
|
}
|
||
|
|
||
|
case 'shift': {
|
||
|
return _shift(accelerator, event, modifier);
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
console.error(modifier);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function reducePlus({accelerator, event}) {
|
||
|
return {
|
||
|
event,
|
||
|
accelerator: accelerator.trim().slice(1)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const virtualKeyCodes = {
|
||
|
0: 'Digit0',
|
||
|
1: 'Digit1',
|
||
|
2: 'Digit2',
|
||
|
3: 'Digit3',
|
||
|
4: 'Digit4',
|
||
|
5: 'Digit5',
|
||
|
6: 'Digit6',
|
||
|
7: 'Digit7',
|
||
|
8: 'Digit8',
|
||
|
9: 'Digit9',
|
||
|
'-': 'Minus',
|
||
|
'=': 'Equal',
|
||
|
Q: 'KeyQ',
|
||
|
W: 'KeyW',
|
||
|
E: 'KeyE',
|
||
|
R: 'KeyR',
|
||
|
T: 'KeyT',
|
||
|
Y: 'KeyY',
|
||
|
U: 'KeyU',
|
||
|
I: 'KeyI',
|
||
|
O: 'KeyO',
|
||
|
P: 'KeyP',
|
||
|
'[': 'BracketLeft',
|
||
|
']': 'BracketRight',
|
||
|
A: 'KeyA',
|
||
|
S: 'KeyS',
|
||
|
D: 'KeyD',
|
||
|
F: 'KeyF',
|
||
|
G: 'KeyG',
|
||
|
H: 'KeyH',
|
||
|
J: 'KeyJ',
|
||
|
K: 'KeyK',
|
||
|
L: 'KeyL',
|
||
|
';': 'Semicolon',
|
||
|
'\'': 'Quote',
|
||
|
'`': 'Backquote',
|
||
|
'/': 'Backslash',
|
||
|
Z: 'KeyZ',
|
||
|
X: 'KeyX',
|
||
|
C: 'KeyC',
|
||
|
V: 'KeyV',
|
||
|
B: 'KeyB',
|
||
|
N: 'KeyN',
|
||
|
M: 'KeyM',
|
||
|
',': 'Comma',
|
||
|
'.': 'Period',
|
||
|
'\\': 'Slash',
|
||
|
' ': 'Space'
|
||
|
};
|
||
|
|
||
|
function reduceKey({accelerator, event}, key) {
|
||
|
if (key.length > 1 || event.key) {
|
||
|
throw new Error(`Unvalid keycode \`${key}\`.`);
|
||
|
}
|
||
|
|
||
|
const code =
|
||
|
key.toUpperCase() in virtualKeyCodes ?
|
||
|
virtualKeyCodes[key.toUpperCase()] :
|
||
|
null;
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {key}, code ? {code} : null),
|
||
|
accelerator: accelerator.trim().slice(key.length)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const domKeys = Object.assign(Object.create(null), {
|
||
|
plus: 'Add',
|
||
|
space: 'Space',
|
||
|
tab: 'Tab',
|
||
|
backspace: 'Backspace',
|
||
|
delete: 'Delete',
|
||
|
insert: 'Insert',
|
||
|
return: 'Return',
|
||
|
enter: 'Return',
|
||
|
up: 'ArrowUp',
|
||
|
down: 'ArrowDown',
|
||
|
left: 'ArrowLeft',
|
||
|
right: 'ArrowRight',
|
||
|
home: 'Home',
|
||
|
end: 'End',
|
||
|
pageup: 'PageUp',
|
||
|
pagedown: 'PageDown',
|
||
|
escape: 'Escape',
|
||
|
esc: 'Escape',
|
||
|
volumeup: 'AudioVolumeUp',
|
||
|
volumedown: 'AudioVolumeDown',
|
||
|
volumemute: 'AudioVolumeMute',
|
||
|
medianexttrack: 'MediaTrackNext',
|
||
|
mediaprevioustrack: 'MediaTrackPrevious',
|
||
|
mediastop: 'MediaStop',
|
||
|
mediaplaypause: 'MediaPlayPause',
|
||
|
printscreen: 'PrintScreen'
|
||
|
});
|
||
|
|
||
|
// Add function keys
|
||
|
for (let i = 1; i <= 24; i++) {
|
||
|
domKeys[`f${i}`] = `F${i}`;
|
||
|
}
|
||
|
|
||
|
function reduceCode({accelerator, event}, {code, key}) {
|
||
|
if (event.code) {
|
||
|
throw new Error(`Duplicated keycode \`${key}\`.`);
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
event: Object.assign({}, event, {key}, code ? {code} : null),
|
||
|
accelerator: accelerator.trim().slice((key && key.length) || 0)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This function transform an Electron Accelerator string into
|
||
|
* a DOM KeyboardEvent object.
|
||
|
*
|
||
|
* @param {string} accelerator an Electron Accelerator string, e.g. `Ctrl+C` or `Shift+Space`.
|
||
|
* @return {object} a DOM KeyboardEvent object derivate from the `accelerator` argument.
|
||
|
*/
|
||
|
function toKeyEvent(accelerator) {
|
||
|
let state = {accelerator, event: {}};
|
||
|
while (state.accelerator !== '') {
|
||
|
const modifierMatch = state.accelerator.match(modifiers);
|
||
|
if (modifierMatch) {
|
||
|
const modifier = modifierMatch[0].toLowerCase();
|
||
|
state = reduceModifier(state, modifier);
|
||
|
if (state === UNSUPPORTED) {
|
||
|
return {unsupportedKeyForPlatform: true};
|
||
|
}
|
||
|
} else if (state.accelerator.trim()[0] === '+') {
|
||
|
state = reducePlus(state);
|
||
|
} else {
|
||
|
const codeMatch = state.accelerator.match(keyCodes);
|
||
|
if (codeMatch) {
|
||
|
const code = codeMatch[0].toLowerCase();
|
||
|
if (code in domKeys) {
|
||
|
state = reduceCode(state, {
|
||
|
code: domKeys[code],
|
||
|
key: code
|
||
|
});
|
||
|
} else {
|
||
|
state = reduceKey(state, code);
|
||
|
}
|
||
|
} else {
|
||
|
throw new Error(`Unvalid accelerator: "${state.accelerator}"`);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return state.event;
|
||
|
}
|
||
|
|
||
|
var keyboardeventFromElectronAccelerator = {
|
||
|
UNSUPPORTED,
|
||
|
reduceModifier,
|
||
|
reducePlus,
|
||
|
reduceKey,
|
||
|
reduceCode,
|
||
|
toKeyEvent
|
||
|
};
|
||
|
|
||
|
var DEFAULT_SETTINGS = {
|
||
|
vimrcFileName: ".obsidian.vimrc",
|
||
|
displayChord: false,
|
||
|
displayVimMode: false,
|
||
|
fixedNormalModeLayout: false,
|
||
|
capturedKeyboardMap: {},
|
||
|
supportJsCommands: false
|
||
|
};
|
||
|
// NOTE: to future maintainers, please make sure all mapping commands are included in this array.
|
||
|
var mappingCommands = [
|
||
|
"map",
|
||
|
"nmap",
|
||
|
"noremap",
|
||
|
"iunmap",
|
||
|
"nunmap",
|
||
|
"vunmap",
|
||
|
];
|
||
|
function sleep(ms) {
|
||
|
return new Promise(function (resolve) { return setTimeout(resolve, ms); });
|
||
|
}
|
||
|
var VimrcPlugin = /** @class */ (function (_super) {
|
||
|
__extends(VimrcPlugin, _super);
|
||
|
function VimrcPlugin() {
|
||
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||
|
_this.codeMirrorVimObject = null;
|
||
|
_this.initialized = false;
|
||
|
_this.lastYankBuffer = [""];
|
||
|
_this.lastSystemClipboard = "";
|
||
|
_this.yankToSystemClipboard = false;
|
||
|
_this.currentKeyChord = [];
|
||
|
_this.vimChordStatusBar = null;
|
||
|
_this.vimStatusBar = null;
|
||
|
_this.currentVimStatus = "\uD83D\uDFE2" /* vimStatus.normal */;
|
||
|
_this.customVimKeybinds = {};
|
||
|
_this.currentSelection = null;
|
||
|
_this.isInsertMode = false;
|
||
|
_this.logVimModeChange = function (cm) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var _a;
|
||
|
return __generator(this, function (_b) {
|
||
|
if (!cm)
|
||
|
return [2 /*return*/];
|
||
|
this.isInsertMode = cm.mode === 'insert';
|
||
|
switch (cm.mode) {
|
||
|
case "insert":
|
||
|
this.currentVimStatus = "\uD83D\uDFE0" /* vimStatus.insert */;
|
||
|
break;
|
||
|
case "normal":
|
||
|
this.currentVimStatus = "\uD83D\uDFE2" /* vimStatus.normal */;
|
||
|
break;
|
||
|
case "visual":
|
||
|
this.currentVimStatus = "\uD83D\uDFE1" /* vimStatus.visual */;
|
||
|
break;
|
||
|
case "replace":
|
||
|
this.currentVimStatus = "\uD83D\uDD34" /* vimStatus.replace */;
|
||
|
break;
|
||
|
}
|
||
|
if (this.settings.displayVimMode)
|
||
|
(_a = this.vimStatusBar) === null || _a === void 0 ? void 0 : _a.setText(this.currentVimStatus);
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); };
|
||
|
_this.onVimKeypress = function (vimKey) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var tempS, _i, _a, s;
|
||
|
var _b;
|
||
|
return __generator(this, function (_c) {
|
||
|
if (vimKey != "<Esc>") { // TODO figure out what to actually look for to exit commands.
|
||
|
this.currentKeyChord.push(vimKey);
|
||
|
if (this.customVimKeybinds[this.currentKeyChord.join("")] != undefined) { // Custom key chord exists.
|
||
|
this.currentKeyChord = [];
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
this.currentKeyChord = [];
|
||
|
}
|
||
|
tempS = "";
|
||
|
for (_i = 0, _a = this.currentKeyChord; _i < _a.length; _i++) {
|
||
|
s = _a[_i];
|
||
|
tempS += " " + s;
|
||
|
}
|
||
|
if (tempS != "") {
|
||
|
tempS += "-";
|
||
|
}
|
||
|
(_b = this.vimChordStatusBar) === null || _b === void 0 ? void 0 : _b.setText(tempS);
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); };
|
||
|
_this.onVimCommandDone = function (reason) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var _a;
|
||
|
return __generator(this, function (_b) {
|
||
|
(_a = this.vimChordStatusBar) === null || _a === void 0 ? void 0 : _a.setText("");
|
||
|
this.currentKeyChord = [];
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); };
|
||
|
_this.onKeydown = function (ev) {
|
||
|
if (_this.settings.fixedNormalModeLayout) {
|
||
|
var keyMap = _this.settings.capturedKeyboardMap;
|
||
|
if (!_this.isInsertMode && !ev.shiftKey &&
|
||
|
ev.code in keyMap && ev.key != keyMap[ev.code]) {
|
||
|
var view = _this.getActiveView();
|
||
|
if (view) {
|
||
|
var cmEditor = _this.getCodeMirror(view);
|
||
|
if (cmEditor) {
|
||
|
_this.codeMirrorVimObject.handleKey(cmEditor, keyMap[ev.code], 'mapping');
|
||
|
}
|
||
|
}
|
||
|
ev.preventDefault();
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
return _this;
|
||
|
}
|
||
|
VimrcPlugin.prototype.captureKeyboardLayout = function () {
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
var keyMap, layout, doneIterating;
|
||
|
return __generator(this, function (_a) {
|
||
|
switch (_a.label) {
|
||
|
case 0:
|
||
|
keyMap = {};
|
||
|
return [4 /*yield*/, navigator.keyboard.getLayoutMap()];
|
||
|
case 1:
|
||
|
layout = _a.sent();
|
||
|
doneIterating = new Promise(function (resolve, reject) {
|
||
|
var counted = 0;
|
||
|
layout.forEach(function (value, index) {
|
||
|
keyMap[index] = value;
|
||
|
counted += 1;
|
||
|
if (counted === layout.size)
|
||
|
resolve();
|
||
|
});
|
||
|
});
|
||
|
return [4 /*yield*/, doneIterating];
|
||
|
case 2:
|
||
|
_a.sent();
|
||
|
new obsidian.Notice('Keyboard layout captured');
|
||
|
return [2 /*return*/, keyMap];
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.initialize = function () {
|
||
|
var _a;
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
var _this = this;
|
||
|
return __generator(this, function (_b) {
|
||
|
if (this.initialized)
|
||
|
return [2 /*return*/];
|
||
|
this.codeMirrorVimObject = (_a = window.CodeMirrorAdapter) === null || _a === void 0 ? void 0 : _a.Vim;
|
||
|
this.registerYankEvents(activeWindow);
|
||
|
this.app.workspace.on("window-open", function (workspaceWindow, w) {
|
||
|
_this.registerYankEvents(w);
|
||
|
});
|
||
|
// Two events cos
|
||
|
// this don't trigger on loading/reloading obsidian with note opened
|
||
|
this.app.workspace.on("active-leaf-change", function () { return __awaiter(_this, void 0, void 0, function () {
|
||
|
return __generator(this, function (_a) {
|
||
|
this.updateSelectionEvent();
|
||
|
this.updateVimEvents();
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); });
|
||
|
// and this don't trigger on opening same file in new pane
|
||
|
this.app.workspace.on("file-open", function () { return __awaiter(_this, void 0, void 0, function () {
|
||
|
return __generator(this, function (_a) {
|
||
|
this.updateSelectionEvent();
|
||
|
this.updateVimEvents();
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); });
|
||
|
this.initialized = true;
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.registerYankEvents = function (win) {
|
||
|
var _this = this;
|
||
|
this.registerDomEvent(win.document, 'click', function () {
|
||
|
_this.captureYankBuffer(win);
|
||
|
});
|
||
|
this.registerDomEvent(win.document, 'keyup', function () {
|
||
|
_this.captureYankBuffer(win);
|
||
|
});
|
||
|
this.registerDomEvent(win.document, 'focusin', function () {
|
||
|
_this.captureYankBuffer(win);
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.updateSelectionEvent = function () {
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
var view, cm;
|
||
|
var _this = this;
|
||
|
return __generator(this, function (_a) {
|
||
|
view = this.getActiveView();
|
||
|
if (!view)
|
||
|
return [2 /*return*/];
|
||
|
cm = this.getCodeMirror(view);
|
||
|
if (this.getCursorActivityHandlers(cm).some(function (e) { return e.name === "updateSelection"; }))
|
||
|
return [2 /*return*/];
|
||
|
cm.on("cursorActivity", function (cm) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
||
|
return [2 /*return*/, this.updateSelection(cm)];
|
||
|
}); }); });
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.updateSelection = function (cm) {
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
return __generator(this, function (_a) {
|
||
|
this.currentSelection = cm.listSelections();
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.getCursorActivityHandlers = function (cm) {
|
||
|
return cm._handlers.cursorActivity;
|
||
|
};
|
||
|
VimrcPlugin.prototype.updateVimEvents = function () {
|
||
|
var _a;
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
var view, cmEditor;
|
||
|
return __generator(this, function (_b) {
|
||
|
view = this.getActiveView();
|
||
|
if (view) {
|
||
|
cmEditor = this.getCodeMirror(view);
|
||
|
// See https://codemirror.net/doc/manual.html#vimapi_events for events.
|
||
|
this.isInsertMode = false;
|
||
|
this.currentVimStatus = "\uD83D\uDFE2" /* vimStatus.normal */;
|
||
|
if (this.settings.displayVimMode)
|
||
|
(_a = this.vimStatusBar) === null || _a === void 0 ? void 0 : _a.setText(this.currentVimStatus);
|
||
|
cmEditor.off('vim-mode-change', this.logVimModeChange);
|
||
|
cmEditor.on('vim-mode-change', this.logVimModeChange);
|
||
|
this.currentKeyChord = [];
|
||
|
cmEditor.off('vim-keypress', this.onVimKeypress);
|
||
|
cmEditor.on('vim-keypress', this.onVimKeypress);
|
||
|
cmEditor.off('vim-command-done', this.onVimCommandDone);
|
||
|
cmEditor.on('vim-command-done', this.onVimCommandDone);
|
||
|
CodeMirror.off(cmEditor.getInputField(), 'keydown', this.onKeydown);
|
||
|
CodeMirror.on(cmEditor.getInputField(), 'keydown', this.onKeydown);
|
||
|
}
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.onload = function () {
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
var _this = this;
|
||
|
return __generator(this, function (_a) {
|
||
|
switch (_a.label) {
|
||
|
case 0: return [4 /*yield*/, this.loadSettings()];
|
||
|
case 1:
|
||
|
_a.sent();
|
||
|
this.addSettingTab(new SettingsTab(this.app, this));
|
||
|
console.log('loading Vimrc plugin');
|
||
|
this.app.workspace.on('active-leaf-change', function () { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var fileName, vimrcContent, e_1;
|
||
|
return __generator(this, function (_a) {
|
||
|
switch (_a.label) {
|
||
|
case 0:
|
||
|
if (!!this.initialized) return [3 /*break*/, 2];
|
||
|
return [4 /*yield*/, this.initialize()];
|
||
|
case 1:
|
||
|
_a.sent();
|
||
|
_a.label = 2;
|
||
|
case 2:
|
||
|
if (this.codeMirrorVimObject.loadedVimrc)
|
||
|
return [2 /*return*/];
|
||
|
fileName = this.settings.vimrcFileName;
|
||
|
if (!fileName || fileName.trim().length === 0) {
|
||
|
fileName = DEFAULT_SETTINGS.vimrcFileName;
|
||
|
console.log('Configured Vimrc file name is illegal, falling-back to default');
|
||
|
}
|
||
|
vimrcContent = '';
|
||
|
_a.label = 3;
|
||
|
case 3:
|
||
|
_a.trys.push([3, 5, , 6]);
|
||
|
return [4 /*yield*/, this.app.vault.adapter.read(fileName)];
|
||
|
case 4:
|
||
|
vimrcContent = _a.sent();
|
||
|
return [3 /*break*/, 6];
|
||
|
case 5:
|
||
|
e_1 = _a.sent();
|
||
|
console.log('Error loading vimrc file', fileName, 'from the vault root', e_1.message);
|
||
|
return [3 /*break*/, 6];
|
||
|
case 6:
|
||
|
this.readVimInit(vimrcContent);
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
}); });
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.loadSettings = function () {
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
var data;
|
||
|
return __generator(this, function (_a) {
|
||
|
switch (_a.label) {
|
||
|
case 0: return [4 /*yield*/, this.loadData()];
|
||
|
case 1:
|
||
|
data = _a.sent();
|
||
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, data);
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.saveSettings = function () {
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
return __generator(this, function (_a) {
|
||
|
switch (_a.label) {
|
||
|
case 0: return [4 /*yield*/, this.saveData(this.settings)];
|
||
|
case 1:
|
||
|
_a.sent();
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.onunload = function () {
|
||
|
console.log('unloading Vimrc plugin (but Vim commands that were already loaded will still work)');
|
||
|
};
|
||
|
VimrcPlugin.prototype.getActiveView = function () {
|
||
|
return this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
|
||
|
};
|
||
|
VimrcPlugin.prototype.getCodeMirror = function (view) {
|
||
|
var _a, _b, _c;
|
||
|
return (_c = (_b = (_a = view.editMode) === null || _a === void 0 ? void 0 : _a.editor) === null || _b === void 0 ? void 0 : _b.cm) === null || _c === void 0 ? void 0 : _c.cm;
|
||
|
};
|
||
|
VimrcPlugin.prototype.readVimInit = function (vimCommands) {
|
||
|
var view = this.getActiveView();
|
||
|
if (view) {
|
||
|
var cmEditor = this.getCodeMirror(view);
|
||
|
if (cmEditor && !this.codeMirrorVimObject.loadedVimrc) {
|
||
|
this.defineBasicCommands(this.codeMirrorVimObject);
|
||
|
this.defineSendKeys(this.codeMirrorVimObject);
|
||
|
this.defineObCommand(this.codeMirrorVimObject);
|
||
|
this.defineSurround(this.codeMirrorVimObject);
|
||
|
this.defineJsCommand(this.codeMirrorVimObject);
|
||
|
this.defineJsFile(this.codeMirrorVimObject);
|
||
|
this.defineSource(this.codeMirrorVimObject);
|
||
|
this.loadVimCommands(vimCommands);
|
||
|
this.prepareChordDisplay();
|
||
|
this.prepareVimModeDisplay();
|
||
|
// Make sure that we load it just once per CodeMirror instance.
|
||
|
// This is supposed to work because the Vim state is kept at the keymap level, hopefully
|
||
|
// there will not be bugs caused by operations that are kept at the object level instead
|
||
|
this.codeMirrorVimObject.loadedVimrc = true;
|
||
|
}
|
||
|
if (cmEditor) {
|
||
|
cmEditor.off('vim-mode-change', this.logVimModeChange);
|
||
|
cmEditor.on('vim-mode-change', this.logVimModeChange);
|
||
|
CodeMirror.off(cmEditor.getInputField(), 'keydown', this.onKeydown);
|
||
|
CodeMirror.on(cmEditor.getInputField(), 'keydown', this.onKeydown);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
VimrcPlugin.prototype.loadVimCommands = function (vimCommands) {
|
||
|
var view = this.getActiveView();
|
||
|
if (view) {
|
||
|
var cmEditor = this.getCodeMirror(view);
|
||
|
vimCommands.split("\n").forEach(function (line, index, arr) {
|
||
|
if (line.trim().length > 0 && line.trim()[0] != '"') {
|
||
|
var split = line.split(" ");
|
||
|
if (mappingCommands.includes(split[0])) {
|
||
|
// Have to do this because "vim-command-done" event doesn't actually work properly, or something.
|
||
|
this.customVimKeybinds[split[1]] = true;
|
||
|
}
|
||
|
this.codeMirrorVimObject.handleEx(cmEditor, line);
|
||
|
}
|
||
|
}.bind(this) // Faster than an arrow function. https://stackoverflow.com/questions/50375440/binding-vs-arrow-function-for-react-onclick-event
|
||
|
);
|
||
|
}
|
||
|
};
|
||
|
VimrcPlugin.prototype.defineBasicCommands = function (vimObject) {
|
||
|
var _this = this;
|
||
|
vimObject.defineOption('clipboard', '', 'string', ['clip'], function (value, cm) {
|
||
|
if (value) {
|
||
|
if (value.trim() == 'unnamed' || value.trim() == 'unnamedplus') {
|
||
|
if (!_this.yankToSystemClipboard) {
|
||
|
_this.yankToSystemClipboard = true;
|
||
|
console.log("Vim is now set to yank to system clipboard.");
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
throw new Error("Unrecognized clipboard option, supported are 'unnamed' and 'unnamedplus' (and they do the same)");
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
vimObject.defineOption('tabstop', 4, 'number', [], function (value, cm) {
|
||
|
if (value && cm) {
|
||
|
cm.setOption('tabSize', value);
|
||
|
}
|
||
|
});
|
||
|
vimObject.defineEx('iunmap', '', function (cm, params) {
|
||
|
if (params.argString.trim()) {
|
||
|
_this.codeMirrorVimObject.unmap(params.argString.trim(), 'insert');
|
||
|
}
|
||
|
});
|
||
|
vimObject.defineEx('nunmap', '', function (cm, params) {
|
||
|
if (params.argString.trim()) {
|
||
|
_this.codeMirrorVimObject.unmap(params.argString.trim(), 'normal');
|
||
|
}
|
||
|
});
|
||
|
vimObject.defineEx('vunmap', '', function (cm, params) {
|
||
|
if (params.argString.trim()) {
|
||
|
_this.codeMirrorVimObject.unmap(params.argString.trim(), 'visual');
|
||
|
}
|
||
|
});
|
||
|
vimObject.defineEx('noremap', '', function (cm, params) {
|
||
|
var _a;
|
||
|
if (!((_a = params === null || params === void 0 ? void 0 : params.args) === null || _a === void 0 ? void 0 : _a.length)) {
|
||
|
throw new Error('Invalid mapping: noremap');
|
||
|
}
|
||
|
if (params.argString.trim()) {
|
||
|
_this.codeMirrorVimObject.noremap.apply(_this.codeMirrorVimObject, params.args);
|
||
|
}
|
||
|
});
|
||
|
// Allow the user to register an Ex command
|
||
|
vimObject.defineEx('exmap', '', function (cm, params) {
|
||
|
var _a;
|
||
|
if (((_a = params === null || params === void 0 ? void 0 : params.args) === null || _a === void 0 ? void 0 : _a.length) && params.args.length < 2) {
|
||
|
throw new Error("exmap requires at least 2 parameters: [name] [actions...]");
|
||
|
}
|
||
|
var commandName = params.args[0];
|
||
|
params.args.shift();
|
||
|
var commandContent = params.args.join(' ');
|
||
|
// The content of the user's Ex command is just the remaining parameters of the exmap command
|
||
|
_this.codeMirrorVimObject.defineEx(commandName, '', function (cm, params) {
|
||
|
_this.codeMirrorVimObject.handleEx(cm, commandContent);
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.defineSendKeys = function (vimObject) {
|
||
|
var _this = this;
|
||
|
vimObject.defineEx('sendkeys', '', function (cm, params) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var allGood, events, _i, _a, key, delay, keyEvent, _b, events_1;
|
||
|
var _c;
|
||
|
return __generator(this, function (_d) {
|
||
|
switch (_d.label) {
|
||
|
case 0:
|
||
|
if (!((_c = params === null || params === void 0 ? void 0 : params.args) === null || _c === void 0 ? void 0 : _c.length)) {
|
||
|
console.log(params);
|
||
|
throw new Error("The sendkeys command requires a list of keys, e.g. sendKeys Ctrl+p a b Enter");
|
||
|
}
|
||
|
allGood = true;
|
||
|
events = [];
|
||
|
_i = 0, _a = params.args;
|
||
|
_d.label = 1;
|
||
|
case 1:
|
||
|
if (!(_i < _a.length)) return [3 /*break*/, 5];
|
||
|
key = _a[_i];
|
||
|
if (!key.startsWith('wait')) return [3 /*break*/, 3];
|
||
|
delay = key.slice(4);
|
||
|
return [4 /*yield*/, sleep(delay * 1000)];
|
||
|
case 2:
|
||
|
_d.sent();
|
||
|
return [3 /*break*/, 4];
|
||
|
case 3:
|
||
|
keyEvent = null;
|
||
|
try {
|
||
|
keyEvent = new KeyboardEvent('keydown', keyboardeventFromElectronAccelerator.toKeyEvent(key));
|
||
|
events.push(keyEvent);
|
||
|
}
|
||
|
catch (e) {
|
||
|
allGood = false;
|
||
|
throw new Error("Key '".concat(key, "' couldn't be read as an Electron Accelerator"));
|
||
|
}
|
||
|
if (allGood) {
|
||
|
for (_b = 0, events_1 = events; _b < events_1.length; _b++) {
|
||
|
keyEvent = events_1[_b];
|
||
|
window.postMessage(JSON.parse(JSON.stringify(keyEvent)), '*');
|
||
|
}
|
||
|
// view.containerEl.dispatchEvent(keyEvent);
|
||
|
}
|
||
|
_d.label = 4;
|
||
|
case 4:
|
||
|
_i++;
|
||
|
return [3 /*break*/, 1];
|
||
|
case 5: return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
}); });
|
||
|
};
|
||
|
VimrcPlugin.prototype.defineObCommand = function (vimObject) {
|
||
|
var _this = this;
|
||
|
vimObject.defineEx('obcommand', '', function (cm, params) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var availableCommands, view, editor, command, callback, checkCallback, editorCallback, editorCheckCallback;
|
||
|
var _a;
|
||
|
return __generator(this, function (_b) {
|
||
|
availableCommands = this.app.commands.commands;
|
||
|
if (!((_a = params === null || params === void 0 ? void 0 : params.args) === null || _a === void 0 ? void 0 : _a.length) || params.args.length != 1) {
|
||
|
console.log("Available commands: ".concat(Object.keys(availableCommands).join('\n')));
|
||
|
throw new Error("obcommand requires exactly 1 parameter");
|
||
|
}
|
||
|
view = this.getActiveView();
|
||
|
editor = view.editor;
|
||
|
command = params.args[0];
|
||
|
if (command in availableCommands) {
|
||
|
callback = availableCommands[command].callback;
|
||
|
checkCallback = availableCommands[command].checkCallback;
|
||
|
editorCallback = availableCommands[command].editorCallback;
|
||
|
editorCheckCallback = availableCommands[command].editorCheckCallback;
|
||
|
if (editorCheckCallback)
|
||
|
editorCheckCallback(false, editor, view);
|
||
|
else if (editorCallback)
|
||
|
editorCallback(editor, view);
|
||
|
else if (checkCallback)
|
||
|
checkCallback(false);
|
||
|
else if (callback)
|
||
|
callback();
|
||
|
else
|
||
|
throw new Error("Command ".concat(command, " doesn't have an Obsidian callback"));
|
||
|
}
|
||
|
else
|
||
|
throw new Error("Command ".concat(command, " was not found, try 'obcommand' with no params to see in the developer console what's available"));
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); });
|
||
|
};
|
||
|
VimrcPlugin.prototype.defineSurround = function (vimObject) {
|
||
|
var _this = this;
|
||
|
// Function to surround selected text or highlighted word.
|
||
|
var surroundFunc = function (params) {
|
||
|
var _a;
|
||
|
var editor = _this.getActiveView().editor;
|
||
|
if (!params.length) {
|
||
|
throw new Error("surround requires exactly 2 parameters: prefix and postfix text.");
|
||
|
}
|
||
|
var newArgs = params.join(" ").match(/(\\.|[^\s\\\\]+)+/g);
|
||
|
if (newArgs.length != 2) {
|
||
|
throw new Error("surround requires exactly 2 parameters: prefix and postfix text.");
|
||
|
}
|
||
|
var beginning = newArgs[0].replace("\\\\", "\\").replace("\\ ", " "); // Get the beginning surround text
|
||
|
var ending = newArgs[1].replace("\\\\", "\\").replace("\\ ", " "); // Get the ending surround text
|
||
|
var currentSelections = _this.currentSelection;
|
||
|
var chosenSelection = currentSelections && currentSelections.length > 0 ? currentSelections[0] : null;
|
||
|
if (_this.currentSelection && (currentSelections === null || currentSelections === void 0 ? void 0 : currentSelections.length) > 1) {
|
||
|
console.log("WARNING: Multiple selections in surround. Attempt to select matching cursor. (obsidian-vimrc-support)");
|
||
|
var cursorPos = editor.getCursor();
|
||
|
for (var _i = 0, currentSelections_1 = currentSelections; _i < currentSelections_1.length; _i++) {
|
||
|
var selection = currentSelections_1[_i];
|
||
|
if (selection.head.line == cursorPos.line && selection.head.ch == cursorPos.ch) {
|
||
|
console.log("RESOLVED: Selection matching cursor found. (obsidian-vimrc-support)");
|
||
|
chosenSelection = selection;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (JSON.stringify(chosenSelection.anchor) === JSON.stringify(chosenSelection.head)) {
|
||
|
// No range of selected text, so select word.
|
||
|
var line = editor.getLine(chosenSelection.anchor.line);
|
||
|
if (line.length === 0)
|
||
|
throw new Error("can't surround on an empty line");
|
||
|
// Go to the beginning of the word
|
||
|
var wordStart = chosenSelection.anchor.ch;
|
||
|
for (; wordStart >= 0; wordStart--)
|
||
|
if (line[wordStart].match(/\s/))
|
||
|
break;
|
||
|
wordStart++;
|
||
|
var wordEnd = chosenSelection.anchor.ch;
|
||
|
for (; wordEnd < line.length; wordEnd++)
|
||
|
if (line[wordEnd].match(/\s/))
|
||
|
break;
|
||
|
var word = line.substring(wordStart, wordEnd);
|
||
|
chosenSelection.anchor.ch = wordStart;
|
||
|
chosenSelection.head.ch = wordEnd;
|
||
|
chosenSelection = {
|
||
|
anchor: { line: chosenSelection.anchor.line, ch: wordStart },
|
||
|
head: { line: chosenSelection.head.line, ch: wordEnd }
|
||
|
};
|
||
|
}
|
||
|
// If the selection is reverse, switch the variables
|
||
|
if (chosenSelection.anchor.line > chosenSelection.head.line ||
|
||
|
(chosenSelection.anchor.line == chosenSelection.head.line && chosenSelection.anchor.ch > chosenSelection.head.ch))
|
||
|
_a = [chosenSelection.head, chosenSelection.anchor], chosenSelection.anchor = _a[0], chosenSelection.head = _a[1];
|
||
|
var currText = editor.getRange(chosenSelection.anchor, chosenSelection.head);
|
||
|
editor.replaceRange(beginning + currText + ending, chosenSelection.anchor, chosenSelection.head);
|
||
|
};
|
||
|
vimObject.defineEx("surround", "", function (cm, params) { surroundFunc(params.args); });
|
||
|
vimObject.defineEx("pasteinto", "", function (cm, params) {
|
||
|
// Using the register for when this.yankToSystemClipboard == false
|
||
|
surroundFunc(['[',
|
||
|
'](' + vimObject.getRegisterController().getRegister('yank').keyBuffer + ")"]);
|
||
|
});
|
||
|
var editor = this.getActiveView().editor;
|
||
|
// Handle the surround dialog input
|
||
|
var surroundDialogCallback = function (value) {
|
||
|
if ((/^\[+$/).test(value)) { // check for 1-inf [ and match them with ]
|
||
|
surroundFunc([value, "]".repeat(value.length)]);
|
||
|
}
|
||
|
else if ((/^\(+$/).test(value)) { // check for 1-inf ( and match them with )
|
||
|
surroundFunc([value, ")".repeat(value.length)]);
|
||
|
}
|
||
|
else if ((/^\{+$/).test(value)) { // check for 1-inf { and match them with }
|
||
|
surroundFunc([value, "}".repeat(value.length)]);
|
||
|
}
|
||
|
else { // Else, just put it before and after.
|
||
|
surroundFunc([value, value]);
|
||
|
}
|
||
|
};
|
||
|
vimObject.defineOperator("surroundOperator", function () {
|
||
|
var p = "<span>Surround with: <input type='text'></span>";
|
||
|
CodeMirror.openDialog(p, surroundDialogCallback, { bottom: true, selectValueOnOpen: false });
|
||
|
});
|
||
|
vimObject.mapCommand("<A-y>s", "operator", "surroundOperator");
|
||
|
};
|
||
|
VimrcPlugin.prototype.captureYankBuffer = function (win) {
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
var yankRegister, currentYankBuffer, buf, _a, currentClipboardText, e_2;
|
||
|
return __generator(this, function (_b) {
|
||
|
switch (_b.label) {
|
||
|
case 0:
|
||
|
if (!this.yankToSystemClipboard) {
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
yankRegister = this.codeMirrorVimObject.getRegisterController().getRegister('yank');
|
||
|
currentYankBuffer = yankRegister.keyBuffer;
|
||
|
buf = currentYankBuffer[0];
|
||
|
if (!(buf !== this.lastYankBuffer[0])) return [3 /*break*/, 3];
|
||
|
return [4 /*yield*/, win.navigator.clipboard.writeText(buf)];
|
||
|
case 1:
|
||
|
_b.sent();
|
||
|
this.lastYankBuffer = currentYankBuffer;
|
||
|
_a = this;
|
||
|
return [4 /*yield*/, win.navigator.clipboard.readText()];
|
||
|
case 2:
|
||
|
_a.lastSystemClipboard = _b.sent();
|
||
|
return [2 /*return*/];
|
||
|
case 3:
|
||
|
_b.trys.push([3, 5, , 6]);
|
||
|
return [4 /*yield*/, win.navigator.clipboard.readText()];
|
||
|
case 4:
|
||
|
currentClipboardText = _b.sent();
|
||
|
if (currentClipboardText !== this.lastSystemClipboard) {
|
||
|
yankRegister.setText(currentClipboardText);
|
||
|
this.lastYankBuffer = yankRegister.keyBuffer;
|
||
|
this.lastSystemClipboard = currentClipboardText;
|
||
|
}
|
||
|
return [3 /*break*/, 6];
|
||
|
case 5:
|
||
|
e_2 = _b.sent();
|
||
|
return [3 /*break*/, 6];
|
||
|
case 6: return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.prepareChordDisplay = function () {
|
||
|
if (this.settings.displayChord) {
|
||
|
// Add status bar item
|
||
|
this.vimChordStatusBar = this.addStatusBarItem();
|
||
|
// Move vimChordStatusBar to the leftmost position and center it.
|
||
|
var parent_1 = this.vimChordStatusBar.parentElement;
|
||
|
this.vimChordStatusBar.parentElement.insertBefore(this.vimChordStatusBar, parent_1.firstChild);
|
||
|
this.vimChordStatusBar.style.marginRight = "auto";
|
||
|
var cmEditor = this.getCodeMirror(this.getActiveView());
|
||
|
// See https://codemirror.net/doc/manual.html#vimapi_events for events.
|
||
|
cmEditor.off('vim-keypress', this.onVimKeypress);
|
||
|
cmEditor.on('vim-keypress', this.onVimKeypress);
|
||
|
cmEditor.off('vim-command-done', this.onVimCommandDone);
|
||
|
cmEditor.on('vim-command-done', this.onVimCommandDone);
|
||
|
}
|
||
|
};
|
||
|
VimrcPlugin.prototype.prepareVimModeDisplay = function () {
|
||
|
if (this.settings.displayVimMode) {
|
||
|
this.vimStatusBar = this.addStatusBarItem(); // Add status bar item
|
||
|
this.vimStatusBar.setText("\uD83D\uDFE2" /* vimStatus.normal */); // Init the vimStatusBar with normal mode
|
||
|
}
|
||
|
};
|
||
|
VimrcPlugin.prototype.defineJsCommand = function (vimObject) {
|
||
|
var _this = this;
|
||
|
vimObject.defineEx('jscommand', '', function (cm, params) {
|
||
|
if (!_this.settings.supportJsCommands)
|
||
|
throw new Error("JS commands are turned off; enable them via the Vimrc plugin configuration if you're sure you know what you're doing");
|
||
|
var jsCode = params.argString.trim();
|
||
|
if (jsCode[0] != '{' || jsCode[jsCode.length - 1] != '}')
|
||
|
throw new Error("Expected an argument which is JS code surrounded by curly brackets: {...}");
|
||
|
var currentSelections = _this.currentSelection;
|
||
|
var chosenSelection = currentSelections && currentSelections.length > 0 ? currentSelections[0] : null;
|
||
|
var command = Function('editor', 'view', 'selection', jsCode);
|
||
|
var view = _this.getActiveView();
|
||
|
command(view.editor, view, chosenSelection);
|
||
|
});
|
||
|
};
|
||
|
VimrcPlugin.prototype.defineJsFile = function (vimObject) {
|
||
|
var _this = this;
|
||
|
vimObject.defineEx('jsfile', '', function (cm, params) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var extraCode, fileName, currentSelections, chosenSelection, content, e_3, command, view;
|
||
|
var _a;
|
||
|
return __generator(this, function (_b) {
|
||
|
switch (_b.label) {
|
||
|
case 0:
|
||
|
if (!this.settings.supportJsCommands)
|
||
|
throw new Error("JS commands are turned off; enable them via the Vimrc plugin configuration if you're sure you know what you're doing");
|
||
|
if (((_a = params === null || params === void 0 ? void 0 : params.args) === null || _a === void 0 ? void 0 : _a.length) < 1)
|
||
|
throw new Error("Expected format: fileName {extraCode}");
|
||
|
extraCode = '';
|
||
|
fileName = params.args[0];
|
||
|
if (params.args.length > 1) {
|
||
|
params.args.shift();
|
||
|
extraCode = params.args.join(' ').trim();
|
||
|
if (extraCode[0] != '{' || extraCode[extraCode.length - 1] != '}')
|
||
|
throw new Error("Expected an extra code argument which is JS code surrounded by curly brackets: {...}");
|
||
|
}
|
||
|
currentSelections = this.currentSelection;
|
||
|
chosenSelection = currentSelections && currentSelections.length > 0 ? currentSelections[0] : null;
|
||
|
content = '';
|
||
|
_b.label = 1;
|
||
|
case 1:
|
||
|
_b.trys.push([1, 3, , 4]);
|
||
|
return [4 /*yield*/, this.app.vault.adapter.read(fileName)];
|
||
|
case 2:
|
||
|
content = _b.sent();
|
||
|
return [3 /*break*/, 4];
|
||
|
case 3:
|
||
|
e_3 = _b.sent();
|
||
|
throw new Error("Cannot read file ".concat(params.args[0], " from vault root: ").concat(e_3.message));
|
||
|
case 4:
|
||
|
command = Function('editor', 'view', 'selection', content + extraCode);
|
||
|
view = this.getActiveView();
|
||
|
command(view.editor, view, chosenSelection);
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
}); });
|
||
|
};
|
||
|
VimrcPlugin.prototype.defineSource = function (vimObject) {
|
||
|
var _this = this;
|
||
|
vimObject.defineEx('source', '', function (cm, params) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var fileName;
|
||
|
var _this = this;
|
||
|
var _a;
|
||
|
return __generator(this, function (_b) {
|
||
|
if (((_a = params === null || params === void 0 ? void 0 : params.args) === null || _a === void 0 ? void 0 : _a.length) > 1)
|
||
|
throw new Error("Expected format: source [fileName]");
|
||
|
fileName = params.argString.trim();
|
||
|
try {
|
||
|
this.app.vault.adapter.read(fileName).then(function (vimrcContent) {
|
||
|
_this.loadVimCommands(vimrcContent);
|
||
|
});
|
||
|
}
|
||
|
catch (e) {
|
||
|
console.log('Error loading vimrc file', fileName, 'from the vault root', e.message);
|
||
|
}
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); });
|
||
|
};
|
||
|
return VimrcPlugin;
|
||
|
}(obsidian.Plugin));
|
||
|
var SettingsTab = /** @class */ (function (_super) {
|
||
|
__extends(SettingsTab, _super);
|
||
|
function SettingsTab(app, plugin) {
|
||
|
var _this = _super.call(this, app, plugin) || this;
|
||
|
_this.plugin = plugin;
|
||
|
return _this;
|
||
|
}
|
||
|
SettingsTab.prototype.display = function () {
|
||
|
var _this = this;
|
||
|
var containerEl = this.containerEl;
|
||
|
containerEl.empty();
|
||
|
containerEl.createEl('h2', { text: 'Vimrc Settings' });
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName('Vimrc file name')
|
||
|
.setDesc('Relative to vault directory (requires restart)')
|
||
|
.addText(function (text) {
|
||
|
text.setPlaceholder(DEFAULT_SETTINGS.vimrcFileName);
|
||
|
text.setValue(_this.plugin.settings.vimrcFileName || DEFAULT_SETTINGS.vimrcFileName);
|
||
|
text.onChange(function (value) {
|
||
|
_this.plugin.settings.vimrcFileName = value;
|
||
|
_this.plugin.saveSettings();
|
||
|
});
|
||
|
});
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName('Vim chord display')
|
||
|
.setDesc('Displays the current chord until completion. Ex: "<Space> f-" (requires restart)')
|
||
|
.addToggle(function (toggle) {
|
||
|
toggle.setValue(_this.plugin.settings.displayChord || DEFAULT_SETTINGS.displayChord);
|
||
|
toggle.onChange(function (value) {
|
||
|
_this.plugin.settings.displayChord = value;
|
||
|
_this.plugin.saveSettings();
|
||
|
});
|
||
|
});
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName('Vim mode display')
|
||
|
.setDesc('Displays the current vim mode (requires restart)')
|
||
|
.addToggle(function (toggle) {
|
||
|
toggle.setValue(_this.plugin.settings.displayVimMode || DEFAULT_SETTINGS.displayVimMode);
|
||
|
toggle.onChange(function (value) {
|
||
|
_this.plugin.settings.displayVimMode = value;
|
||
|
_this.plugin.saveSettings();
|
||
|
});
|
||
|
});
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName('Use a fixed keyboard layout for Normal mode')
|
||
|
.setDesc('Define a keyboard layout to always use when in Normal mode, regardless of the input language (experimental).')
|
||
|
.addButton(function (button) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var _this = this;
|
||
|
return __generator(this, function (_a) {
|
||
|
button.setButtonText('Capture current layout');
|
||
|
button.onClick(function () { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var _a;
|
||
|
return __generator(this, function (_b) {
|
||
|
switch (_b.label) {
|
||
|
case 0:
|
||
|
_a = this.plugin.settings;
|
||
|
return [4 /*yield*/, this.plugin.captureKeyboardLayout()];
|
||
|
case 1:
|
||
|
_a.capturedKeyboardMap = _b.sent();
|
||
|
this.plugin.saveSettings();
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
}); });
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); })
|
||
|
.addToggle(function (toggle) {
|
||
|
toggle.setValue(_this.plugin.settings.fixedNormalModeLayout || DEFAULT_SETTINGS.fixedNormalModeLayout);
|
||
|
toggle.onChange(function (value) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var _a;
|
||
|
return __generator(this, function (_b) {
|
||
|
switch (_b.label) {
|
||
|
case 0:
|
||
|
this.plugin.settings.fixedNormalModeLayout = value;
|
||
|
if (!(value && Object.keys(this.plugin.settings.capturedKeyboardMap).length === 0)) return [3 /*break*/, 2];
|
||
|
_a = this.plugin.settings;
|
||
|
return [4 /*yield*/, this.plugin.captureKeyboardLayout()];
|
||
|
case 1:
|
||
|
_a.capturedKeyboardMap = _b.sent();
|
||
|
_b.label = 2;
|
||
|
case 2:
|
||
|
this.plugin.saveSettings();
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
}); });
|
||
|
});
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName('Support JS commands (beware!)')
|
||
|
.setDesc("Support the 'jscommand' and 'jsfile' commands, which allow defining Ex commands using Javascript. WARNING! Review the README to understand why this may be dangerous before enabling.")
|
||
|
.addToggle(function (toggle) {
|
||
|
var _a;
|
||
|
toggle.setValue((_a = _this.plugin.settings.supportJsCommands) !== null && _a !== void 0 ? _a : DEFAULT_SETTINGS.supportJsCommands);
|
||
|
toggle.onChange(function (value) {
|
||
|
_this.plugin.settings.supportJsCommands = value;
|
||
|
_this.plugin.saveSettings();
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
return SettingsTab;
|
||
|
}(obsidian.PluginSettingTab));
|
||
|
|
||
|
module.exports = VimrcPlugin;
|
||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm5vZGVfbW9kdWxlcy9rZXlib2FyZGV2ZW50LWZyb20tZWxlY3Ryb24tYWNjZWxlcmF0b3IvaW5kZXguanMiLCJtYWluLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5
|