Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/jupyter/util/find.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6This code is inspired by the BSD licensed Jupyter code, in order to maintain7a compatible interpretation of how things work:89notebook/notebook/static/notebook/js/searchandreplace.js10*/1112/*13Escape a Regular expression to act as a pure search string,14though it will still have the case sensitivity options and all the benefits.15*/16function escape_regexp(string: string) {17return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");18}1920function construct_regexp(21string: string,22flags: string,23is_regexp: false24): RegExp;25function construct_regexp(26string: RegExp,27flags: string,28is_regexp: true29): RegExp;30function construct_regexp(string, flags, is_regexp) {31// return a Pseudo RegExp object that acts32// either as a plain RegExp Object, or as a pure string matching.33if (is_regexp) {34return new RegExp(string, flags);35} else {36return new RegExp(escape_regexp(string), flags);37}38}3940/*41Find all occurrences of `pattern` in `string`, match in a `case_sensitive` manner.4243Return {matches:[...], abort:abort, error:error}44matches = list of matches {start:start, stop:stop} indexes in the string.45abort = abort Boolean, if more that 100 matches and the matches were aborted.46error = in case of problems compling regular expression47*/48export function find_matches(49pattern: string | RegExp,50string: string,51is_case_sensitive = false,52is_regexp = false,53max_matches = 10054): {55matches?: Array<{ start: number; stop: number }>;56abort?: boolean;57error?: string;58} {59let flags = "g";60if (!is_case_sensitive) {61flags += "i";62}63try {64pattern = construct_regexp(pattern as any, flags, is_regexp as any);65} catch (error) {66return { error: `${error}` };67}6869const matches: any = [];70let match: any = undefined;71let escape_hatch = 0;72let abort = false;73while ((match = (pattern as any).exec(string)) != null) {74match = { start: match.index, stop: match.index + match[0].length };75if (match.stop === match.start) {76// e.g., an empty search77return { matches: [] };78}79matches.push(match);80escape_hatch++;81if (escape_hatch >= max_matches) {82abort = true;83break;84}85}8687const x: any = { matches };88if (abort) {89x.abort = abort;90}91return x;92}939495