UNPKG

@krassowski/jupyterlab-lsp

Version:

Language Server Protocol integration for JupyterLab

124 lines 5.57 kB
import { position_at_offset } from '../positioning'; export function getIndexOfCaptureGroup(expression, matched_string, value_of_captured_group) { // 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 captured_groups = expression.exec(matched_string); if (captured_groups == null) { console.warn(`No capture group found for ${expression} in ${matched_string}`); return -1; } let offset_in_match = 0; // first element is a full match let full_matched = captured_groups[0]; for (let group of captured_groups.slice(1)) { if (typeof group === 'undefined') { continue; } if (group === value_of_captured_group) { offset_in_match += full_matched.indexOf(group); break; } let group_end_offset = full_matched.indexOf(group) + group.length; full_matched = full_matched.slice(group_end_offset); offset_in_match += group_end_offset; } return offset_in_match; } export class RegExpForeignCodeExtractor { constructor(options) { this.language = options.language; this.options = options; this.global_expression = new RegExp(options.pattern, 'g'); this.test_expression = new RegExp(options.pattern, 'g'); this.expression = new RegExp(options.pattern); this.standalone = this.options.is_standalone; this.file_extension = this.options.file_extension; } has_foreign_code(code) { let result = this.test_expression.test(code); this.test_expression.lastIndex = 0; return result; } extract_foreign_code(code) { let lines = code.split('\n'); let extracts = new Array(); let started_from = this.global_expression.lastIndex; let match = this.global_expression.exec(code); let host_code_fragment; let chosen_replacer; let is_new_api_replacer = false; if (typeof this.options.foreign_replacer !== 'undefined') { chosen_replacer = this.options.foreign_replacer; is_new_api_replacer = true; } else if (typeof this.options.foreign_capture_groups !== 'undefined') { chosen_replacer = '$' + this.options.foreign_capture_groups.join('$'); is_new_api_replacer = true; } else if (this.options.extract_to_foreign) { chosen_replacer = this.options.extract_to_foreign; } else { console.warn(`Foreign replacer not defined for extractor: {this.expression} - this is deprecated; use 'foreign_replacer' to define it`); return []; } while (match != null) { let matched_string = match[0]; let position_shift = null; let foreign_code_fragment = matched_string.replace(this.expression, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore chosen_replacer); let prefix = ''; if (typeof this.options.extract_arguments !== 'undefined') { prefix = matched_string.replace(this.expression, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.options.extract_arguments); position_shift = position_at_offset(prefix.length, prefix.split('\n')); } // NOTE: // match.index + matched_string.length === this.sticky_expression.lastIndex let end_index = this.global_expression.lastIndex; if (this.options.keep_in_host || this.options.keep_in_host == null) { host_code_fragment = code.substring(started_from, end_index); } else { if (started_from === match.index) { host_code_fragment = ''; } else { host_code_fragment = code.substring(started_from, match.index) + '\n'; } } let foreign_code_group_value = foreign_code_fragment; if (is_new_api_replacer) { foreign_code_group_value = matched_string.replace(this.expression, '$' + Math.min(...this.options.foreign_capture_groups)); } const foreign_group_index_in_match = getIndexOfCaptureGroup(this.expression, matched_string, foreign_code_group_value); let start_offset = match.index + foreign_group_index_in_match; let start = position_at_offset(start_offset, lines); let end = position_at_offset(start_offset + foreign_code_fragment.length, lines); extracts.push({ host_code: host_code_fragment, foreign_code: prefix + foreign_code_fragment, range: { start, end }, virtual_shift: position_shift }); started_from = this.global_expression.lastIndex; match = this.global_expression.exec(code); } if (started_from !== code.length) { let final_host_code_fragment = code.substring(started_from, code.length); extracts.push({ host_code: final_host_code_fragment, foreign_code: null, range: null, virtual_shift: null }); } return extracts; } } //# sourceMappingURL=regexp.js.map