1export interface CodeBlock {
2  start: number;
3  end: number;
4  code: string;
5}
6
7/**
8 * Insert contents at given offset
9 * @param srcContents source contents
10 * @param insertion content to insert
11 * @param offset `srcContents` offset to insert `insertion`
12 * @returns updated contents
13 */
14export function insertContentsAtOffset(
15  srcContents: string,
16  insertion: string,
17  offset: number
18): string {
19  const srcContentsLength = srcContents.length;
20  if (offset < 0 || offset > srcContentsLength) {
21    throw new Error('Invalid parameters.');
22  }
23  if (offset === 0) {
24    return `${insertion}${srcContents}`;
25  } else if (offset === srcContentsLength) {
26    return `${srcContents}${insertion}`;
27  }
28
29  const prefix = srcContents.substring(0, offset);
30  const suffix = srcContents.substring(offset);
31  return `${prefix}${insertion}${suffix}`;
32}
33
34/**
35 * Replace contents at given start and end offset
36 *
37 * @param contents source contents
38 * @param replacement new contents to place in [startOffset:endOffset]
39 * @param startOffset `contents` start offset for replacement
40 * @param endOffset `contents` end offset for replacement
41 * @returns updated contents
42 */
43export function replaceContentsWithOffset(
44  contents: string,
45  replacement: string,
46  startOffset: number,
47  endOffset: number
48): string {
49  const contentsLength = contents.length;
50  if (
51    startOffset < 0 ||
52    endOffset < 0 ||
53    startOffset >= contentsLength ||
54    endOffset >= contentsLength ||
55    startOffset > endOffset
56  ) {
57    throw new Error('Invalid parameters.');
58  }
59  const prefix = contents.substring(0, startOffset);
60  const suffix = contents.substring(endOffset + 1);
61  return `${prefix}${replacement}${suffix}`;
62}
63
64/**
65 * String.prototype.search() with offset support
66 *
67 * @param source source string to search
68 * @param regexp RegExp pattern to search
69 * @param offset start offset of `source` to search `regexp` pattern
70 * @returns The index of the first match between the regular expression and the given string, or -1 if no match was found.
71 */
72export function searchFromOffset(source: string, regexp: RegExp, offset: number): number {
73  const target = source.substring(offset);
74  const matchedIndex = target.search(regexp);
75  return matchedIndex < 0 ? matchedIndex : matchedIndex + offset;
76}
77