codess
Version:
vscode代码片段管理器,通过 本地包(本地某个文件夹) 或官网的 远程包(代码片段集合) 生成本地项目的 vscode 代码片段配置。
619 lines (618 loc) • 20.8 kB
JavaScript
;
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;
}