(line: string)
| 98 | |
| 99 | // Replace all matches (longest match first) in a line. |
| 100 | replaceAll(line: string): replaceAction { |
| 101 | let newText = ''; |
| 102 | let idxInOld = 0; |
| 103 | let idxInNew = 0; |
| 104 | const mapRanges: Record<number, Record<number, charRange>> = {}; |
| 105 | const mapNames: Record<string, string> = {}; |
| 106 | // Loop over each possible replacement point in the line. |
| 107 | // Walk the prefix tree to find the longest replacement at the current index. If no match is found, emit the |
| 108 | // current character; otherwise emit the replacement and advance by the matched length. |
| 109 | while (idxInOld < line.length) { |
| 110 | const [oldValue, newValue] = this.findLongestMatch(line, idxInOld); |
| 111 | if (oldValue) { |
| 112 | // We found a replacement. |
| 113 | newText += newValue; |
| 114 | mapNames[oldValue] = newValue; |
| 115 | |
| 116 | idxInOld += oldValue.length; |
| 117 | idxInNew += newValue.length; |
| 118 | |
| 119 | // The annoying +1 ultimately comes from monaco.Position being 1-based. |
| 120 | const oldStart = idxInOld - oldValue.length + 1; |
| 121 | const oldEnd = idxInOld + 1; |
| 122 | const newStart = idxInNew - newValue.length + 1; |
| 123 | const newEnd = idxInNew + 1; |
| 124 | |
| 125 | // JS/TS don't allow using an object such as {oldStart, oldEnd} as a key in a dictionary/Map, |
| 126 | // we use a nested dictionary instead. |
| 127 | if (!mapRanges[oldStart]) mapRanges[oldStart] = {}; |
| 128 | mapRanges[oldStart][oldEnd] = {startCol: newStart, endCol: newEnd}; |
| 129 | } else { |
| 130 | // No match; output the unmatched character, and keep looking. |
| 131 | newText += line[idxInOld]; |
| 132 | idxInOld++; |
| 133 | idxInNew++; |
| 134 | } |
| 135 | } |
| 136 | return { |
| 137 | newText: newText, |
| 138 | mapRanges: mapRanges, |
| 139 | mapNames: mapNames, |
| 140 | }; |
| 141 | } |
| 142 | |
| 143 | // Like replaceAll, but only computes the replaced text. Skips building the |
| 144 | // mapRanges/mapNames metadata, which callers that don't need source-position |
no test coverage detected