@jupyter-lsp/code-jumpers
Version:
Implementation underlying the jump to definition functionality in JupyterLab-LSP
112 lines • 4.11 kB
JavaScript
import { EditorView } from '@codemirror/view';
import { Dialog, showDialog } from '@jupyterlab/apputils';
const movementKeys = [
'ArrowRight',
'ArrowLeft',
'ArrowUp',
'ArrowDown',
'Home',
'End',
'PageUp',
'PageDown'
];
const modifiers = ['Alt', 'AltGraph', 'Control', 'Shift'];
const systemKeys = [
'F1',
'F2',
'F3',
'F4',
'F5',
'F6',
'F7',
'F8',
'F9',
'F10',
'F11',
'F12',
'ContextMenu'
];
export class CodeJumper {
goToPosition(documentWidget, jumper, column, lineNumber, inputNumber = 0) {
let documentJumper;
let position = { line: lineNumber, column: column };
let documentJumperType = jumpers.get(jumper);
documentJumper = new documentJumperType(documentWidget, this.documentManager);
let jumpPosition = documentJumper.getJumpPosition(position, inputNumber);
documentJumper.jump(jumpPosition);
}
_globalJump(position) {
let documentWidget = this.documentManager.openOrReveal(position.contentsPath);
if (!documentWidget) {
console.log('Widget failed to open for jump');
return;
}
let isSymlink = position.isSymlink;
documentWidget.revealed
.then(() => {
this.goToPosition(documentWidget, position.contentsPath.endsWith('.ipynb') ? 'notebook' : 'fileeditor', position.column, position.line, position.editorIndex);
// protect external files from accidental edition
if (isSymlink) {
this.protectFromAccidentalEditing(documentWidget);
}
})
.catch(console.warn);
}
protectFromAccidentalEditing(documentWidget) {
let editorWidget = documentWidget;
// We used to adjust `editorWidget.title.label` here but an upstream
// bug (https://github.com/jupyterlab/jupyterlab/issues/10856) prevents
// us from doing so anymore.
let editor = editorWidget.content.editor;
let active = true;
editor.injectExtension(EditorView.domEventHandlers({
keydown: (event) => {
if (!active) {
return false;
}
// allow to move around, select text and use modifiers & browser keys freely
if (movementKeys.indexOf(event.key) !== -1 ||
modifiers.indexOf(event.key) !== -1 ||
systemKeys.indexOf(event.key) !== -1) {
return false;
}
// allow to copy text (here assuming that, as on majority of OSs, copy is associated with ctrl+c)
// this is not foolproof, but should work in majority of sane settings (unfortunately, not in vim)
if (event.key === 'c' && event.ctrlKey) {
return false;
}
let dialogPromise = showDialog({
title: 'Edit external file?',
body: 'This file is located outside of the root of the JupyterLab start directory. ' +
'do you really wish to edit it?',
buttons: [
Dialog.cancelButton({ label: 'Cancel' }),
Dialog.warnButton({ label: 'Edit anyway' })
]
});
dialogPromise
.then(result => {
if (result.button.accept) {
active = false;
}
})
.catch(console.warn);
// prevent default
return true;
}
}));
}
globalJumpBack() {
let previousPosition = this.history.recollect();
if (previousPosition) {
this._globalJump(previousPosition);
}
}
globalJump(position) {
const currentPosition = this.getCurrentPosition();
this.history.store(currentPosition);
this._globalJump(position);
}
}
export let jumpers = new Map();
//# sourceMappingURL=jumper.js.map