UNPKG

@krassowski/jupyterlab_go_to_definition

Version:

Jump to definition of a variable or function in JupyterLab

80 lines 2.81 kB
import { LanguageWithOptionalSemicolons } from './analyzer'; export class RAnalyzer extends LanguageWithOptionalSemicolons { constructor() { super(...arguments); this.definitionRules = [ this.isStandaloneAssignment, this.isImport, this.isForLoop ]; } isAssignment(token) { return ((token.type === 'operator' && token.value === '=') || (token.type === 'operator arrow' && (token.value === '<-' || token.value === '<<-'))); } // Matching standalone variable assignment: isStandaloneAssignment(context) { let { previous, next } = context; return ( // standard, leftwards assignments: (next.exists && this.isAssignment(next)) || // rightwards assignments: (previous.exists && previous.type === 'operator arrow' && (previous.value === '->' || previous.value === '->>'))); } // Matching imports: isImport(context) { let { previous } = context; if (previous.exists && previous.type === 'variable' && (previous.value === 'library' || previous.value === 'require')) { return true; } previous = this.traverse_left(previous, ', '); if (previous.exists && previous.value === 'here' && previous.type === 'variable' && previous.previous.value === '::' && previous.previous.previous.value === 'import') { return true; } return false; } // Matching `for` loop and comprehensions: isForLoop(context) { let { previous, next } = context; return (previous.exists && previous.type === 'keyword' && previous.value === 'for' && next.exists && next.type === 'keyword' && next.value === 'in'); } guessReferencePath(context) { let { next } = context; if (context.value === 'source') { return [next.next.value.slice(0, -1)]; } // TODO for now only works when alt-clicking on ".from" // ideally clicking on the file name would be preferred return [next.next.next.value.slice(0, -1)]; } isCrossFileReference(context) { // case: "source('test.R')" - clicking on source will open test.R let { next } = context; if (context.type === 'variable' && context.value === 'source' && next.exists && (next.value === "'" || next.value === '"') && next.next.exists) { return true; } if (this.isImport(context.previous)) { return true; } return false; } } //# sourceMappingURL=r.js.map