UNPKG

@theia/core

Version:

Theia is a cloud & desktop IDE framework implemented in TypeScript.

96 lines 3.55 kB
"use strict"; // ***************************************************************************** // Copyright (C) 2026 EclipseSource and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** Object.defineProperty(exports, "__esModule", { value: true }); exports.findSubstringIndex = findSubstringIndex; exports.hasSubstringMatch = hasSubstringMatch; exports.hasPrefixMatch = hasPrefixMatch; exports.matchRank = matchRank; /** * Returns the index of the first case-insensitive substring match of `pattern` in `text`, * or `-1` if `pattern` is not a substring. Returns `0` for an empty pattern. */ function findSubstringIndex(text, pattern) { if (!pattern) { return 0; } return text.toLowerCase().indexOf(pattern.toLowerCase()); } function hasSubstringMatch(text, pattern) { return findSubstringIndex(text, pattern) !== -1; } const SEGMENT_SEPARATOR = /[\p{P}\s]+/u; /** * Tests whether `pattern` is a "prefix match" for `text`, accounting for punctuation-separated segments. * * The pattern is split on punctuation into query parts. The text is split on punctuation into segments. * It is a prefix match when the first query part matches the start of segment 0, and each subsequent * query part matches the start of a later segment, in order. * * Examples: * - `hasPrefixMatch("workspace-server", "works-ser")` → true * - `hasPrefixMatch("backend-workspace-service", "works-ser")` → false (first segment doesn't match) * - `hasPrefixMatch("fontSize", "font")` → true (single-part prefix) */ function hasPrefixMatch(text, pattern) { if (!pattern) { return true; } const queryParts = pattern.toLowerCase().split(SEGMENT_SEPARATOR).filter(Boolean); if (queryParts.length === 0) { return true; } const textSegments = text.toLowerCase().split(SEGMENT_SEPARATOR).filter(Boolean); if (textSegments.length === 0) { return false; } // First query part must match the start of the first text segment. if (!textSegments[0].startsWith(queryParts[0])) { return false; } let segIdx = 1; for (let qIdx = 1; qIdx < queryParts.length; qIdx++) { let found = false; while (segIdx < textSegments.length) { if (textSegments[segIdx].startsWith(queryParts[qIdx])) { segIdx++; found = true; break; } segIdx++; } if (!found) { return false; } } return true; } /** * Returns a numeric rank for how well `pattern` matches `text`: * - 0: prefix match (best) * - 1: substring match * - 2: fuzzy-only match (worst) */ function matchRank(text, pattern) { if (hasPrefixMatch(text, pattern)) { return 0; } if (hasSubstringMatch(text, pattern)) { return 1; } return 2; } //# sourceMappingURL=fuzzy-match-utils.js.map