UNPKG

codess

Version:

vscode代码片段管理器,通过 本地包(本地某个文件夹) 或官网的 远程包(代码片段集合) 生成本地项目的 vscode 代码片段配置。

619 lines (618 loc) 20.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.FuzzyScoreOptions = exports.FuzzyScore = exports.matchesPrefix = exports.matchesStrictPrefix = void 0; exports.or = or; exports.matchesContiguousSubString = matchesContiguousSubString; exports.matchesSubString = matchesSubString; exports.isUpper = isUpper; exports.matchesCamelCase = matchesCamelCase; exports.matchesFuzzy = matchesFuzzy; exports.matchesFuzzy2 = matchesFuzzy2; exports.anyScore = anyScore; exports.createMatches = createMatches; exports.isPatternInWord = isPatternInWord; exports.fuzzyScore = fuzzyScore; const map_1 = require("./map"); const strings = __importStar(require("./strings")); function or(...filter) { return function (word, wordToMatchAgainst) { for (let i = 0, len = filter.length; i < len; i++) { const match = filter[i](word, wordToMatchAgainst); if (match) { return match; } } return null; }; } exports.matchesStrictPrefix = _matchesPrefix.bind(undefined, false); exports.matchesPrefix = _matchesPrefix.bind(undefined, true); function _matchesPrefix(ignoreCase, word, wordToMatchAgainst) { if (!wordToMatchAgainst || wordToMatchAgainst.length < word.length) { return null; } let matches; if (ignoreCase) { matches = strings.startsWithIgnoreCase(wordToMatchAgainst, word); } else { matches = wordToMatchAgainst.indexOf(word) === 0; } if (!matches) { return null; } return word.length > 0 ? [{ start: 0, end: word.length }] : []; } function matchesContiguousSubString(word, wordToMatchAgainst) { const index = wordToMatchAgainst.toLowerCase().indexOf(word.toLowerCase()); if (index === -1) { return null; } return [{ start: index, end: index + word.length }]; } function matchesSubString(word, wordToMatchAgainst) { return _matchesSubString(word.toLowerCase(), wordToMatchAgainst.toLowerCase(), 0, 0); } function _matchesSubString(word, wordToMatchAgainst, i, j) { if (i === word.length) { return []; } else if (j === wordToMatchAgainst.length) { return null; } else { if (word[i] === wordToMatchAgainst[j]) { let result = null; if ((result = _matchesSubString(word, wordToMatchAgainst, i + 1, j + 1))) { return join({ start: j, end: j + 1 }, result); } return null; } return _matchesSubString(word, wordToMatchAgainst, i, j + 1); } } function isLower(code) { return 97 <= code && code <= 122; } function isUpper(code) { return 65 <= code && code <= 90; } function isNumber(code) { return 48 <= code && code <= 57; } function isWhitespace(code) { return (code === 32 || code === 9 || code === 10 || code === 13); } const wordSeparators = new Set(); '()[]{}<>`\'"-/;:,.?!'.split('').forEach((s) => wordSeparators.add(s.charCodeAt(0))); function isAlphanumeric(code) { return isLower(code) || isUpper(code) || isNumber(code); } function join(head, tail) { if (tail.length === 0) { tail = [head]; } else if (head.end === tail[0].start) { tail[0].start = head.start; } else { tail.unshift(head); } return tail; } function nextAnchor(camelCaseWord, start) { for (let i = start; i < camelCaseWord.length; i++) { const c = camelCaseWord.charCodeAt(i); if (isUpper(c) || isNumber(c) || (i > 0 && !isAlphanumeric(camelCaseWord.charCodeAt(i - 1)))) { return i; } } return camelCaseWord.length; } function _matchesCamelCase(word, camelCaseWord, i, j) { if (i === word.length) { return []; } else if (j === camelCaseWord.length) { return null; } else if (word[i] !== camelCaseWord[j].toLowerCase()) { return null; } else { let result = null; let nextUpperIndex = j + 1; result = _matchesCamelCase(word, camelCaseWord, i + 1, j + 1); while (!result && (nextUpperIndex = nextAnchor(camelCaseWord, nextUpperIndex)) < camelCaseWord.length) { result = _matchesCamelCase(word, camelCaseWord, i + 1, nextUpperIndex); nextUpperIndex++; } return result === null ? null : join({ start: j, end: j + 1 }, result); } } function analyzeCamelCaseWord(word) { let upper = 0, lower = 0, alpha = 0, numeric = 0, code = 0; for (let i = 0; i < word.length; i++) { code = word.charCodeAt(i); if (isUpper(code)) { upper++; } if (isLower(code)) { lower++; } if (isAlphanumeric(code)) { alpha++; } if (isNumber(code)) { numeric++; } } const upperPercent = upper / word.length; const lowerPercent = lower / word.length; const alphaPercent = alpha / word.length; const numericPercent = numeric / word.length; return { upperPercent, lowerPercent, alphaPercent, numericPercent }; } function isUpperCaseWord(analysis) { const { upperPercent, lowerPercent } = analysis; return lowerPercent === 0 && upperPercent > 0.6; } function isCamelCaseWord(analysis) { const { upperPercent, lowerPercent, alphaPercent, numericPercent } = analysis; return lowerPercent > 0.2 && upperPercent < 0.8 && alphaPercent > 0.6 && numericPercent < 0.2; } function isCamelCasePattern(word) { let upper = 0, lower = 0, code = 0, whitespace = 0; for (let i = 0; i < word.length; i++) { code = word.charCodeAt(i); if (isUpper(code)) { upper++; } if (isLower(code)) { lower++; } if (isWhitespace(code)) { whitespace++; } } if ((upper === 0 || lower === 0) && whitespace === 0) { return word.length <= 30; } else { return upper <= 5; } } function matchesCamelCase(word, camelCaseWord) { if (!camelCaseWord) { return null; } camelCaseWord = camelCaseWord.trim(); if (camelCaseWord.length === 0) { return null; } if (!isCamelCasePattern(word)) { return null; } if (camelCaseWord.length > 60) { camelCaseWord = camelCaseWord.substring(0, 60); } const analysis = analyzeCamelCaseWord(camelCaseWord); if (!isCamelCaseWord(analysis)) { if (!isUpperCaseWord(analysis)) { return null; } camelCaseWord = camelCaseWord.toLowerCase(); } let result = null; let i = 0; word = word.toLowerCase(); while (i < camelCaseWord.length && (result = _matchesCamelCase(word, camelCaseWord, 0, i)) === null) { i = nextAnchor(camelCaseWord, i + 1); } return result; } const fuzzyContiguousFilter = or(exports.matchesPrefix, matchesCamelCase, matchesContiguousSubString); const fuzzySeparateFilter = or(exports.matchesPrefix, matchesCamelCase, matchesSubString); const fuzzyRegExpCache = new map_1.LRUCache(10000); function matchesFuzzy(word, wordToMatchAgainst, enableSeparateSubstringMatching = false) { if (typeof word !== 'string' || typeof wordToMatchAgainst !== 'string') { return null; } let regexp = fuzzyRegExpCache.get(word); if (!regexp) { regexp = new RegExp(strings.convertSimple2RegExpPattern(word), 'i'); fuzzyRegExpCache.set(word, regexp); } const match = regexp.exec(wordToMatchAgainst); if (match) { return [{ start: match.index, end: match.index + match[0].length }]; } return enableSeparateSubstringMatching ? fuzzySeparateFilter(word, wordToMatchAgainst) : fuzzyContiguousFilter(word, wordToMatchAgainst); } function matchesFuzzy2(pattern, word) { const score = fuzzyScore(pattern, pattern.toLowerCase(), 0, word, word.toLowerCase(), 0, { firstMatchCanBeWeak: true, boostFullMatch: true, }); return score ? createMatches(score) : null; } function anyScore(pattern, lowPattern, patternPos, word, lowWord, wordPos) { const max = Math.min(13, pattern.length); for (; patternPos < max; patternPos++) { const result = fuzzyScore(pattern, lowPattern, patternPos, word, lowWord, wordPos, { firstMatchCanBeWeak: true, boostFullMatch: true, }); if (result) { return result; } } return [0, wordPos]; } function createMatches(score) { if (typeof score === 'undefined') { return []; } const res = []; const wordPos = score[1]; for (let i = score.length - 1; i > 1; i--) { const pos = score[i] + wordPos; const last = res[res.length - 1]; if (last && last.end === pos) { last.end = pos + 1; } else { res.push({ start: pos, end: pos + 1 }); } } return res; } const _maxLen = 128; function initTable() { const table = []; const row = []; for (let i = 0; i <= _maxLen; i++) { row[i] = 0; } for (let i = 0; i <= _maxLen; i++) { table.push(row.slice(0)); } return table; } function initArr(maxLen) { const row = []; for (let i = 0; i <= maxLen; i++) { row[i] = 0; } return row; } const _minWordMatchPos = initArr(2 * _maxLen); const _maxWordMatchPos = initArr(2 * _maxLen); const _diag = initTable(); const _table = initTable(); const _arrows = initTable(); const _debug = false; function printTable(table, pattern, patternLen, word, wordLen) { function pad(s, n, pad = ' ') { while (s.length < n) { s = pad + s; } return s; } let ret = ` | |${word .split('') .map((c) => pad(c, 3)) .join('|')}\n`; for (let i = 0; i <= patternLen; i++) { if (i === 0) { ret += ' |'; } else { ret += `${pattern[i - 1]}|`; } ret += table[i] .slice(0, wordLen + 1) .map((n) => pad(n.toString(), 3)) .join('|') + '\n'; } return ret; } function printTables(pattern, patternStart, word, wordStart) { pattern = pattern.substr(patternStart); word = word.substr(wordStart); console.log(printTable(_table, pattern, pattern.length, word, word.length)); console.log(printTable(_arrows, pattern, pattern.length, word, word.length)); console.log(printTable(_diag, pattern, pattern.length, word, word.length)); } function isSeparatorAtPos(value, index) { if (index < 0 || index >= value.length) { return false; } const code = value.codePointAt(index); switch (code) { case 95: case 45: case 46: case 32: case 47: case 92: case 39: case 34: case 58: case 36: case 60: case 62: case 40: case 41: case 91: case 93: case 123: case 125: return true; case undefined: return false; default: if (strings.isEmojiImprecise(code)) { return true; } return false; } } function isWhitespaceAtPos(value, index) { if (index < 0 || index >= value.length) { return false; } const code = value.charCodeAt(index); switch (code) { case 32: case 9: return true; default: return false; } } function isUpperCaseAtPos(pos, word, wordLow) { return word[pos] !== wordLow[pos]; } function isPatternInWord(patternLow, patternPos, patternLen, wordLow, wordPos, wordLen, fillMinWordPosArr = false) { while (patternPos < patternLen && wordPos < wordLen) { if (patternLow[patternPos] === wordLow[wordPos]) { if (fillMinWordPosArr) { _minWordMatchPos[patternPos] = wordPos; } patternPos += 1; } wordPos += 1; } return patternPos === patternLen; } var FuzzyScore; (function (FuzzyScore) { FuzzyScore.Default = [-100, 0]; function isDefault(score) { return !score || (score.length === 2 && score[0] === -100 && score[1] === 0); } FuzzyScore.isDefault = isDefault; })(FuzzyScore || (exports.FuzzyScore = FuzzyScore = {})); class FuzzyScoreOptions { constructor(firstMatchCanBeWeak, boostFullMatch) { this.firstMatchCanBeWeak = firstMatchCanBeWeak; this.boostFullMatch = boostFullMatch; } } exports.FuzzyScoreOptions = FuzzyScoreOptions; FuzzyScoreOptions.default = { boostFullMatch: true, firstMatchCanBeWeak: false }; function fuzzyScore(pattern, patternLow, patternStart, word, wordLow, wordStart, options = FuzzyScoreOptions.default) { const patternLen = pattern.length > _maxLen ? _maxLen : pattern.length; const wordLen = word.length > _maxLen ? _maxLen : word.length; if (patternStart >= patternLen || wordStart >= wordLen || patternLen - patternStart > wordLen - wordStart) { return undefined; } if (!isPatternInWord(patternLow, patternStart, patternLen, wordLow, wordStart, wordLen, true)) { return undefined; } _fillInMaxWordMatchPos(patternLen, wordLen, patternStart, wordStart, patternLow, wordLow); let row = 1; let column = 1; let patternPos = patternStart; let wordPos = wordStart; const hasStrongFirstMatch = [false]; for (row = 1, patternPos = patternStart; patternPos < patternLen; row++, patternPos++) { const minWordMatchPos = _minWordMatchPos[patternPos]; const maxWordMatchPos = _maxWordMatchPos[patternPos]; const nextMaxWordMatchPos = patternPos + 1 < patternLen ? _maxWordMatchPos[patternPos + 1] : wordLen; for (column = minWordMatchPos - wordStart + 1, wordPos = minWordMatchPos; wordPos < nextMaxWordMatchPos; column++, wordPos++) { let score = Number.MIN_SAFE_INTEGER; let canComeDiag = false; if (wordPos <= maxWordMatchPos) { score = _doScore(pattern, patternLow, patternPos, patternStart, word, wordLow, wordPos, wordLen, wordStart, _diag[row - 1][column - 1] === 0, hasStrongFirstMatch); } let diagScore = 0; if (score !== Number.MAX_SAFE_INTEGER) { canComeDiag = true; diagScore = score + _table[row - 1][column - 1]; } const canComeLeft = wordPos > minWordMatchPos; const leftScore = canComeLeft ? _table[row][column - 1] + (_diag[row][column - 1] > 0 ? -5 : 0) : 0; const canComeLeftLeft = wordPos > minWordMatchPos + 1 && _diag[row][column - 1] > 0; const leftLeftScore = canComeLeftLeft ? _table[row][column - 2] + (_diag[row][column - 2] > 0 ? -5 : 0) : 0; if (canComeLeftLeft && (!canComeLeft || leftLeftScore >= leftScore) && (!canComeDiag || leftLeftScore >= diagScore)) { _table[row][column] = leftLeftScore; _arrows[row][column] = 3; _diag[row][column] = 0; } else if (canComeLeft && (!canComeDiag || leftScore >= diagScore)) { _table[row][column] = leftScore; _arrows[row][column] = 2; _diag[row][column] = 0; } else if (canComeDiag) { _table[row][column] = diagScore; _arrows[row][column] = 1; _diag[row][column] = _diag[row - 1][column - 1] + 1; } else { throw new Error(`not possible`); } } } if (_debug) { printTables(pattern, patternStart, word, wordStart); } if (!hasStrongFirstMatch[0] && !options.firstMatchCanBeWeak) { return undefined; } row--; column--; const result = [_table[row][column], wordStart]; let backwardsDiagLength = 0; let maxMatchColumn = 0; while (row >= 1) { let diagColumn = column; do { const arrow = _arrows[row][diagColumn]; if (arrow === 3) { diagColumn = diagColumn - 2; } else if (arrow === 2) { diagColumn = diagColumn - 1; } else { break; } } while (diagColumn >= 1); if (backwardsDiagLength > 1 && patternLow[patternStart + row - 1] === wordLow[wordStart + column - 1] && !isUpperCaseAtPos(diagColumn + wordStart - 1, word, wordLow) && backwardsDiagLength + 1 > _diag[row][diagColumn]) { diagColumn = column; } if (diagColumn === column) { backwardsDiagLength++; } else { backwardsDiagLength = 1; } if (!maxMatchColumn) { maxMatchColumn = diagColumn; } row--; column = diagColumn - 1; result.push(column); } if (wordLen - wordStart === patternLen && options.boostFullMatch) { result[0] += 2; } const skippedCharsCount = maxMatchColumn - patternLen; result[0] -= skippedCharsCount; return result; } function _fillInMaxWordMatchPos(patternLen, wordLen, patternStart, wordStart, patternLow, wordLow) { let patternPos = patternLen - 1; let wordPos = wordLen - 1; while (patternPos >= patternStart && wordPos >= wordStart) { if (patternLow[patternPos] === wordLow[wordPos]) { _maxWordMatchPos[patternPos] = wordPos; patternPos--; } wordPos--; } } function _doScore(pattern, patternLow, patternPos, patternStart, word, wordLow, wordPos, wordLen, wordStart, newMatchStart, outFirstMatchStrong) { if (patternLow[patternPos] !== wordLow[wordPos]) { return Number.MIN_SAFE_INTEGER; } let score = 1; let isGapLocation = false; if (wordPos === patternPos - patternStart) { score = pattern[patternPos] === word[wordPos] ? 7 : 5; } else if (isUpperCaseAtPos(wordPos, word, wordLow) && (wordPos === 0 || !isUpperCaseAtPos(wordPos - 1, word, wordLow))) { score = pattern[patternPos] === word[wordPos] ? 7 : 5; isGapLocation = true; } else if (isSeparatorAtPos(wordLow, wordPos) && (wordPos === 0 || !isSeparatorAtPos(wordLow, wordPos - 1))) { score = 5; } else if (isSeparatorAtPos(wordLow, wordPos - 1) || isWhitespaceAtPos(wordLow, wordPos - 1)) { score = 5; isGapLocation = true; } if (score > 1 && patternPos === patternStart) { outFirstMatchStrong[0] = true; } if (!isGapLocation) { isGapLocation = isUpperCaseAtPos(wordPos, word, wordLow) || isSeparatorAtPos(wordLow, wordPos - 1) || isWhitespaceAtPos(wordLow, wordPos - 1); } if (patternPos === patternStart) { if (wordPos > wordStart) { score -= isGapLocation ? 3 : 5; } } else { if (newMatchStart) { score += isGapLocation ? 2 : 0; } else { score += isGapLocation ? 0 : 1; } } if (wordPos + 1 === wordLen) { score -= isGapLocation ? 3 : 5; } return score; }