muggle-string
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -1,3 +0,7 @@ | ||
export declare type Segment<T = '--'> = T extends '--' ? SegmentWithoutData : SegmentWithData<T>; | ||
export declare type SegmentWithoutData = [ | ||
declare const NO_DATA_SYMBOL: unique symbol; | ||
export type Segment<T = typeof NO_DATA_SYMBOL> = T extends typeof NO_DATA_SYMBOL ? SegmentWithoutData : SegmentWithData<T>; | ||
export type SegmentWithoutData = WithString<_SegmentWithoutData>; | ||
export type SegmentWithData<T = any> = WithString<_SegmentWithData<T>>; | ||
type WithString<T> = T | string; | ||
type _SegmentWithoutData = [ | ||
string, | ||
@@ -8,4 +12,4 @@ // text | ||
number | [number, number] | ||
] | string; | ||
export declare type SegmentWithData<T> = [ | ||
]; | ||
type _SegmentWithData<T = any> = [ | ||
string, | ||
@@ -17,4 +21,7 @@ // text | ||
T | ||
] | string; | ||
]; | ||
export declare function getLength(segments: Segment<any>[]): number; | ||
export declare function toString(segments: Segment<any>[]): string; | ||
export declare function toString<T extends Segment<any>>(segments: T[]): string; | ||
export declare function replace<T extends Segment<any>>(segments: T[], pattern: string | RegExp, replacer: string | ((match: string) => T)): void; | ||
export declare function update<T extends Segment<any>>(segments: T[], startOffset: number, endOffset: number, newSegment: T): void; | ||
export {}; |
108
out/index.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toString = exports.getLength = void 0; | ||
exports.update = exports.replace = exports.toString = exports.getLength = void 0; | ||
const NO_DATA_SYMBOL = Symbol(); | ||
function getLength(segments) { | ||
@@ -16,1 +17,106 @@ let length = 0; | ||
exports.toString = toString; | ||
function replace(segments, pattern, replacer) { | ||
const str = toString(segments); | ||
const match = str.match(pattern); | ||
if (match && match.index !== undefined) { | ||
const startOffset = match.index; | ||
const endOffset = startOffset + match[0].length; | ||
update(segments, startOffset, endOffset, typeof replacer === 'string' ? replacer : replacer(match[0])); | ||
} | ||
} | ||
exports.replace = replace; | ||
function update(segments, startOffset, endOffset, newSegment) { | ||
const offsets = toOffsets(segments); | ||
const startIndex = binarySearchStartIndex(offsets, startOffset); | ||
const endIndex = binarySearchEndIndex(offsets, endOffset); | ||
const startSegment = segments[startIndex]; | ||
const endSegment = segments[endIndex]; | ||
const startSegmentStart = offsets[startIndex]; | ||
const endSegmentEnd = offsets[endIndex] + (typeof endSegment === 'string' ? endSegment.length : endSegment[0].length); | ||
const inserts = []; | ||
if (startOffset > startSegmentStart) { | ||
inserts.push(trimSegmentEnd(startSegment, startOffset - startSegmentStart)); | ||
} | ||
inserts.push(newSegment); | ||
if (endOffset < endSegmentEnd) { | ||
inserts.push(trimSegmentStart(endSegment, endOffset - startSegmentStart)); | ||
} | ||
combineStrings(inserts); | ||
segments.splice(startIndex, endIndex - startIndex + 1, ...inserts); | ||
} | ||
exports.update = update; | ||
function combineStrings(segments) { | ||
for (let i = segments.length - 1; i >= 1; i--) { | ||
if (typeof segments[i] === 'string' && typeof segments[i - 1] === 'string') { | ||
segments[i - 1] = segments[i - 1] + segments[i]; | ||
segments.splice(i, 1); | ||
} | ||
} | ||
} | ||
function trimSegmentEnd(segment, trimEnd) { | ||
if (typeof segment === 'string') { | ||
return segment.slice(0, trimEnd); | ||
} | ||
const originalString = segment[0]; | ||
const originalRange = segment[2]; | ||
const newString = originalString.slice(0, trimEnd); | ||
const newRange = typeof originalRange === 'number' ? originalRange : [originalRange[0], originalRange[1] - (originalString.length - newString.length)]; | ||
return [ | ||
newString, | ||
segment[1], | ||
newRange, | ||
...segment.slice(3), | ||
]; | ||
} | ||
function trimSegmentStart(segment, trimStart) { | ||
if (typeof segment === 'string') { | ||
return segment.slice(trimStart); | ||
} | ||
const originalString = segment[0]; | ||
const originalRange = segment[2]; | ||
const newString = originalString.slice(trimStart); | ||
const newRange = typeof originalRange === 'number' ? originalRange + trimStart : [originalRange[0] + trimStart, originalRange[1]]; | ||
return [ | ||
newString, | ||
segment[1], | ||
newRange, | ||
...segment.slice(3), | ||
]; | ||
} | ||
function toOffsets(segments) { | ||
const offsets = []; | ||
let offset = 0; | ||
for (const segment of segments) { | ||
offsets.push(offset); | ||
offset += typeof segment == 'string' ? segment.length : segment[0].length; | ||
} | ||
return offsets; | ||
} | ||
function binarySearchStartIndex(offsets, searchOffset) { | ||
let start = 0; | ||
let end = offsets.length - 1; | ||
while (start < end) { | ||
const mid = Math.floor((start + end) / 2); | ||
if (offsets[mid] < searchOffset) { | ||
start = mid + 1; | ||
} | ||
else { | ||
end = mid; | ||
} | ||
} | ||
return start; | ||
} | ||
function binarySearchEndIndex(offsets, searchOffset) { | ||
let start = 0; | ||
let end = offsets.length - 1; | ||
while (start < end) { | ||
const mid = Math.floor((start + end) / 2); | ||
if (offsets[mid] <= searchOffset) { | ||
start = mid + 1; | ||
} | ||
else { | ||
end = mid; | ||
} | ||
} | ||
return start; | ||
} |
{ | ||
"name": "muggle-string", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"main": "out/index.js", | ||
@@ -14,5 +14,10 @@ "license": "MIT", | ||
}, | ||
"scripts": { | ||
"test": "vitest run" | ||
}, | ||
"devDependencies": { | ||
"typescript": "latest" | ||
"typescript": "latest", | ||
"vitest": "latest", | ||
"vite": "latest" | ||
} | ||
} |
@@ -21,4 +21,4 @@ This library aims to provide codegen helpers and data structure for Vue language plugin API v1.x that does not depend on Volar runtime. | ||
import { | ||
toString, | ||
overwrite, // not yet support | ||
toString, | ||
replace, | ||
} from 'muggle-string'; | ||
@@ -29,44 +29,46 @@ | ||
return { | ||
name: 'example-vue-language-plugin', | ||
version: 1, | ||
resolveEmbeddedFile(fileName, sfc, embeddedFile) { | ||
if (embeddedFile.fileName.replace(fileName, '').match(/^\.(js|ts|jsx|tsx)$/)) { | ||
const s = embeddedFile.content; | ||
toString(s); // 'problems = 99' | ||
const s = embeddedFile.content; | ||
toString(s); // 'problems = 99' | ||
overwrite(s, 0, 8, 'answer'); // not yet support | ||
toString(s); // 'answer = 99' | ||
replace(s, 'problems', 'answer'); | ||
toString(s); // 'answer = 99' | ||
overwrite(s, 11, 13, '42'); // not yet support | ||
toString(s); // 'answer = 42' | ||
replace(s, '99', '42'); | ||
toString(s); // 'answer = 42' | ||
// add string by Array method directly | ||
s.unshift('var '); | ||
s.push(';'); | ||
toString(s); // 'var answer = 42;' | ||
// add string by Array method directly | ||
s.unshift('var '); | ||
s.push(';'); | ||
toString(s); // 'var answer = 42;' | ||
for (const block of sfc.customBlocks) { | ||
if (block.type === 'more-script') { | ||
s.push([ | ||
block.content, // text to add | ||
block.name, // source | ||
0, // content offset in source | ||
{ | ||
// langauge capabilities to enable in this segment | ||
hover: true, | ||
references: true, | ||
definition: true, | ||
diagnostic: true, | ||
rename: true, | ||
completion: true, | ||
semanticTokens: true, | ||
}, | ||
]); | ||
toString(s); // 'var answer = 42;console.log( answer )' | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
for (const block of sfc.customBlocks) { | ||
if (block.type === 'more-script') { | ||
s.push([ | ||
block.content, // text to add | ||
block.name, // source | ||
0, // content offset in source | ||
{ | ||
// language capabilities to enable in this segment | ||
hover: true, | ||
references: true, | ||
definition: true, | ||
diagnostic: true, | ||
rename: true, | ||
completion: true, | ||
semanticTokens: true, | ||
}, | ||
]); | ||
toString(s); // 'var answer = 42;console.log( answer )' | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
module.exports = plugin; | ||
``` |
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
8513
146
1
73
3