fix bookmarks being orphanized/stranded
This commit is contained in:
parent
4e87a060f5
commit
ada46e8277
|
@ -264,7 +264,20 @@
|
||||||
const BM_CLS = 'gutter-bookmark';
|
const BM_CLS = 'gutter-bookmark';
|
||||||
const BM_BRAND = 'sublimeBookmark';
|
const BM_BRAND = 'sublimeBookmark';
|
||||||
const BM_CLICKER = 'CodeMirror-linenumbers';
|
const BM_CLICKER = 'CodeMirror-linenumbers';
|
||||||
const {markText} = CodeMirror.prototype;
|
const BM_DATA = Symbol('data');
|
||||||
|
// TODO: revisit when https://github.com/codemirror/CodeMirror/issues/6716 is fixed
|
||||||
|
const tmProto = CodeMirror.TextMarker.prototype;
|
||||||
|
const tmProtoOvr = {};
|
||||||
|
for (const k of ['clear', 'attachLine', 'detachLine']) {
|
||||||
|
tmProtoOvr[k] = function (line) {
|
||||||
|
const {cm} = this.doc;
|
||||||
|
const withOp = !cm.curOp;
|
||||||
|
if (withOp) cm.startOperation();
|
||||||
|
tmProto[k].apply(this, arguments);
|
||||||
|
cm.curOp.ownsGroup.delayedCallbacks.push(toggleMark.bind(this, this.lines[0], line));
|
||||||
|
if (withOp) cm.endOperation();
|
||||||
|
};
|
||||||
|
}
|
||||||
for (const name of ['prevBookmark', 'nextBookmark']) {
|
for (const name of ['prevBookmark', 'nextBookmark']) {
|
||||||
const cmdFn = CodeMirror.commands[name];
|
const cmdFn = CodeMirror.commands[name];
|
||||||
CodeMirror.commands[name] = cm => {
|
CodeMirror.commands[name] = cm => {
|
||||||
|
@ -276,29 +289,9 @@
|
||||||
CodeMirror.defineInitHook(cm => {
|
CodeMirror.defineInitHook(cm => {
|
||||||
cm.on('gutterClick', onGutterClick);
|
cm.on('gutterClick', onGutterClick);
|
||||||
cm.on('gutterContextMenu', onGutterContextMenu);
|
cm.on('gutterContextMenu', onGutterContextMenu);
|
||||||
|
cm.on('markerAdded', onMarkAdded);
|
||||||
});
|
});
|
||||||
// TODO: reimplement bookmarking so next/prev order is decided solely by the line numbers
|
// TODO: reimplement bookmarking so next/prev order is decided solely by the line numbers
|
||||||
Object.assign(CodeMirror.prototype, {
|
|
||||||
markText() {
|
|
||||||
const marker = markText.apply(this, arguments);
|
|
||||||
if (marker[BM_BRAND]) {
|
|
||||||
this.doc.addLineClass(marker.lines[0], 'gutter', BM_CLS);
|
|
||||||
marker.clear = clearMarker;
|
|
||||||
}
|
|
||||||
return marker;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
function clearMarker() {
|
|
||||||
const line = this.lines[0];
|
|
||||||
const spans = line.markedSpans;
|
|
||||||
delete this.clear; // removing our patch from the instance...
|
|
||||||
this.clear(); // ...and using the original prototype
|
|
||||||
if (!spans || spans.some(span => span.marker[BM_BRAND])) {
|
|
||||||
this.doc.removeLineClass(line, 'gutter', BM_CLS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onGutterClick(cm, line, name, e) {
|
function onGutterClick(cm, line, name, e) {
|
||||||
switch (name === BM_CLICKER && e.button) {
|
switch (name === BM_CLICKER && e.button) {
|
||||||
case 0: {
|
case 0: {
|
||||||
|
@ -314,13 +307,27 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGutterContextMenu(cm, line, name, e) {
|
function onGutterContextMenu(cm, line, name, e) {
|
||||||
if (name === BM_CLICKER) {
|
if (name === BM_CLICKER) {
|
||||||
cm.execCommand(e.ctrlKey ? 'prevBookmark' : 'nextBookmark');
|
cm.execCommand(e.ctrlKey ? 'prevBookmark' : 'nextBookmark');
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function onMarkAdded(cm, mark) {
|
||||||
|
if (mark[BM_BRAND]) {
|
||||||
|
// CM bug workaround to keep the mark at line start when the above line is removed
|
||||||
|
mark.inclusiveRight = true;
|
||||||
|
Object.assign(mark, tmProtoOvr);
|
||||||
|
toggleMark.call(mark, true, mark[BM_DATA] = mark.lines[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function toggleMark(state, line = this[BM_DATA]) {
|
||||||
|
this.doc[state ? 'addLineClass' : 'removeLineClass'](line, 'gutter', BM_CLS);
|
||||||
|
if (state) {
|
||||||
|
const bms = this.doc.cm.state.sublimeBookmarks;
|
||||||
|
if (!bms.includes(this)) bms.push(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user