(
input: string,
searchStartIndex: number,
openToken: string,
closeToken: string,
excludeRanges: TextRange[],
)
| 94 | } |
| 95 | |
| 96 | export function getOpenCloseRange( |
| 97 | input: string, |
| 98 | searchStartIndex: number, |
| 99 | openToken: string, |
| 100 | closeToken: string, |
| 101 | excludeRanges: TextRange[], |
| 102 | ): TextRange | null { |
| 103 | let indexOf: (token: string, pos: number) => number; |
| 104 | if (excludeRanges.length === 0) { |
| 105 | indexOf = (token: string, pos: number) => input.indexOf(token, pos); |
| 106 | } else { |
| 107 | indexOf = (token: string, pos: number) => indexOfExcluding(input, token, pos, excludeRanges); |
| 108 | } |
| 109 | |
| 110 | const {length} = input; |
| 111 | let depth = 0; |
| 112 | let firstOpenIndex = -1; |
| 113 | for (let i = searchStartIndex; i < length; i++) { |
| 114 | if (depth === 0) { |
| 115 | const openIndex = indexOf(openToken, i); |
| 116 | if (openIndex < 0) { |
| 117 | break; |
| 118 | } |
| 119 | firstOpenIndex = openIndex; |
| 120 | depth++; |
| 121 | i = openIndex; |
| 122 | } else { |
| 123 | const closeIndex = indexOf(closeToken, i); |
| 124 | if (closeIndex < 0) { |
| 125 | break; |
| 126 | } |
| 127 | const openIndex = indexOf(openToken, i); |
| 128 | if (openIndex < 0 || closeIndex <= openIndex) { |
| 129 | depth--; |
| 130 | if (depth === 0) { |
| 131 | return {start: firstOpenIndex, end: closeIndex + 1}; |
| 132 | } |
| 133 | i = closeIndex; |
| 134 | } else { |
| 135 | depth++; |
| 136 | i = openIndex; |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | return null; |
| 141 | } |
| 142 | |
| 143 | function indexOfExcluding(input: string, search: string, position: number, excludeRanges: TextRange[]) { |
| 144 | const i = input.indexOf(search, position); |
no test coverage detected