UNPKG

@jupyter-lsp/jupyterlab-lsp

Version:

Language Server Protocol integration for JupyterLab

125 lines 5.45 kB
import { positionAtOffset } from '@jupyterlab/lsp'; export function getIndexOfCaptureGroup(expression, matchedString, valueOfCapturedGroup) { // TODO: use https://github.com/tc39/proposal-regexp-match-indices once supported in >95% of browsers // (probably around 2025) // get index of the part that is being extracted to foreign document let capturedGroups = expression.exec(matchedString); if (capturedGroups == null) { console.warn(`No capture group found for ${expression} in ${matchedString}`); return -1; } let offsetInMatch = 0; // first element is a full match let fullMatched = capturedGroups[0]; for (let group of capturedGroups.slice(1)) { if (typeof group === 'undefined') { continue; } if (group === valueOfCapturedGroup) { offsetInMatch += fullMatched.indexOf(group); break; } let groupEndOffset = fullMatched.indexOf(group) + group.length; fullMatched = fullMatched.slice(groupEndOffset); offsetInMatch += groupEndOffset; } return offsetInMatch; } export class RegExpForeignCodeExtractor { constructor(options) { this.cellType = ['code']; this.language = options.language; this.options = options; this.globalExpression = new RegExp(options.pattern, 'g'); this.testExpression = new RegExp(options.pattern, 'g'); this.expression = new RegExp(options.pattern); this.standalone = this.options.isStandalone; this.fileExtension = this.options.fileExtension; } hasForeignCode(code) { const result = this.testExpression.test(code); this.testExpression.lastIndex = 0; return result; } extractForeignCode(code) { const lines = code.split('\n'); const extracts = new Array(); let startedFrom = this.globalExpression.lastIndex; let match = this.globalExpression.exec(code); let hostCodeFragment; let chosenReplacer; let isNewApiReplacer = false; if (typeof this.options.foreignReplacer !== 'undefined') { chosenReplacer = this.options.foreignReplacer; isNewApiReplacer = true; } else if (typeof this.options.foreignCaptureGroups !== 'undefined') { chosenReplacer = '$' + this.options.foreignCaptureGroups.join('$'); isNewApiReplacer = true; } else if (this.options.extractToForeign) { chosenReplacer = this.options.extractToForeign; } else { console.warn(`Foreign replacer not defined for extractor: {this.expression} - this is deprecated; use 'foreignReplacer' to define it`); return []; } while (match != null) { let matchedString = match[0]; let positionShift = null; let foreignCodeFragment = matchedString.replace(this.expression, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore chosenReplacer); let prefix = ''; if (typeof this.options.extractArguments !== 'undefined') { prefix = matchedString.replace(this.expression, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.options.extractArguments); positionShift = positionAtOffset(prefix.length, prefix.split('\n')); } // NOTE: // match.index + matchedString.length === this.sticky_expression.lastIndex let endIndex = this.globalExpression.lastIndex; if (this.options.keepInHost || this.options.keepInHost == null) { hostCodeFragment = code.substring(startedFrom, endIndex); } else { if (startedFrom === match.index) { hostCodeFragment = ''; } else { hostCodeFragment = code.substring(startedFrom, match.index) + '\n'; } } let foreignCodeGroupValue = foreignCodeFragment; if (isNewApiReplacer) { foreignCodeGroupValue = matchedString.replace(this.expression, '$' + Math.min(...this.options.foreignCaptureGroups)); } const foreignGroupIndexInMatch = getIndexOfCaptureGroup(this.expression, matchedString, foreignCodeGroupValue); let startOffset = match.index + foreignGroupIndexInMatch; let start = positionAtOffset(startOffset, lines); let end = positionAtOffset(startOffset + foreignCodeFragment.length, lines); extracts.push({ hostCode: hostCodeFragment, foreignCode: prefix + foreignCodeFragment, range: { start, end }, virtualShift: positionShift }); startedFrom = this.globalExpression.lastIndex; match = this.globalExpression.exec(code); } if (startedFrom !== code.length) { let finalHostCodeFragment = code.substring(startedFrom, code.length); extracts.push({ hostCode: finalHostCodeFragment, foreignCode: null, range: null, virtualShift: null }); } return extracts; } } //# sourceMappingURL=regexp.js.map