| author | |
| committer | |
| log | 07fb04dc63694876b531a7bb5492a72b8282009d |
| tree | 5cccb35a58a0dc754ba5dd456d9d39224d3429cb |
| parent | ad3721eb5bec31066d162916f700107aab5e125b |
| signature | Signed by PGP key B5690EEEBB952194 |
2 files changed, 0 insertions(+), 89 deletions(-)
apps/web/src/terminal-links.test.ts-42| ... | ... | @@ -6,8 +6,6 @@ import { |
| 6 | 6 | isTerminalLinkActivation, |
| 7 | 7 | isTerminalUrl, |
| 8 | 8 | resolvePathLinkTarget, |
| 9 | resolveWrappedTerminalLinkRange, | |
| 10 | wrappedTerminalLinkRangeIntersectsBufferLine, | |
| 11 | 9 | type TerminalBufferLineLike, |
| 12 | 10 | } from "./terminal-links"; |
| 13 | 11 | |
| ... | ... | @@ -154,46 +152,6 @@ describe("collectWrappedTerminalLinkLine", () => { |
| 154 | 152 | }); |
| 155 | 153 | }); |
| 156 | 154 | |
| 157 | describe("resolveWrappedTerminalLinkRange", () => { | |
| 158 | it("maps wrapped URL matches back to the correct buffer rows", () => { | |
| 159 | const prefix = "see "; | |
| 160 | const firstSegment = `${prefix}https://example.com/a`; | |
| 161 | const secondSegment = "/bc?x=1"; | |
| 162 | const lines = [ | |
| 163 | createBufferLine("prompt> "), | |
| 164 | createBufferLine(firstSegment), | |
| 165 | createBufferLine(secondSegment, true), | |
| 166 | ]; | |
| 167 | const wrappedLine = collectWrappedTerminalLinkLine(2, (index) => lines[index]); | |
| 168 | ||
| 169 | expect(wrappedLine).not.toBeNull(); | |
| 170 | if (!wrappedLine) { | |
| 171 | throw new Error("Expected wrapped terminal line to be present."); | |
| 172 | } | |
| 173 | ||
| 174 | const [match] = extractTerminalLinks(wrappedLine.text); | |
| 175 | expect(match).toEqual({ | |
| 176 | kind: "url", | |
| 177 | text: "https://example.com/a/bc?x=1", | |
| 178 | start: prefix.length, | |
| 179 | end: firstSegment.length + secondSegment.length, | |
| 180 | }); | |
| 181 | if (!match) { | |
| 182 | throw new Error("Expected wrapped URL match to be present."); | |
| 183 | } | |
| 184 | ||
| 185 | const range = resolveWrappedTerminalLinkRange(wrappedLine, match); | |
| 186 | ||
| 187 | expect(range).toEqual({ | |
| 188 | start: { x: prefix.length + 1, y: 2 }, | |
| 189 | end: { x: secondSegment.length, y: 3 }, | |
| 190 | }); | |
| 191 | expect(wrappedTerminalLinkRangeIntersectsBufferLine(range, 2)).toBe(true); | |
| 192 | expect(wrappedTerminalLinkRangeIntersectsBufferLine(range, 3)).toBe(true); | |
| 193 | expect(wrappedTerminalLinkRangeIntersectsBufferLine(range, 4)).toBe(false); | |
| 194 | }); | |
| 195 | }); | |
| 196 | ||
| 197 | 155 | describe("resolvePathLinkTarget", () => { |
| 198 | 156 | it("resolves relative paths against cwd", () => { |
| 199 | 157 | expect( |
apps/web/src/terminal-links.ts-47| ... | ... | @@ -14,16 +14,6 @@ export interface TerminalLinkMatch { |
| 14 | 14 | end: number; |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | export interface TerminalLinkBufferPosition { | |
| 18 | x: number; | |
| 19 | y: number; | |
| 20 | } | |
| 21 | ||
| 22 | export interface TerminalLinkBufferRange { | |
| 23 | start: TerminalLinkBufferPosition; | |
| 24 | end: TerminalLinkBufferPosition; | |
| 25 | } | |
| 26 | ||
| 27 | 17 | export interface TerminalBufferLineLike { |
| 28 | 18 | readonly isWrapped?: boolean; |
| 29 | 19 | translateToString(trimRight?: boolean): string; |
| ... | ... | @@ -199,43 +189,6 @@ export function collectWrappedTerminalLinkLine( |
| 199 | 189 | }; |
| 200 | 190 | } |
| 201 | 191 | |
| 202 | function resolveCharacterPosition( | |
| 203 | segments: ReadonlyArray<WrappedTerminalLinkLineSegment>, | |
| 204 | characterIndex: number, | |
| 205 | ): TerminalLinkBufferPosition { | |
| 206 | for (const segment of segments) { | |
| 207 | if (characterIndex < segment.endIndex) { | |
| 208 | return { | |
| 209 | x: characterIndex - segment.startIndex + 1, | |
| 210 | y: segment.bufferLineNumber, | |
| 211 | }; | |
| 212 | } | |
| 213 | } | |
| 214 | ||
| 215 | const lastSegment = segments[segments.length - 1]; | |
| 216 | return { | |
| 217 | x: Math.max(lastSegment?.text.length ?? 0, 1), | |
| 218 | y: lastSegment?.bufferLineNumber ?? 1, | |
| 219 | }; | |
| 220 | } | |
| 221 | ||
| 222 | export function resolveWrappedTerminalLinkRange( | |
| 223 | wrappedLine: WrappedTerminalLinkLine, | |
| 224 | match: Pick<TerminalLinkMatch, "start" | "end">, | |
| 225 | ): TerminalLinkBufferRange { | |
| 226 | return { | |
| 227 | start: resolveCharacterPosition(wrappedLine.segments, match.start), | |
| 228 | end: resolveCharacterPosition(wrappedLine.segments, match.end - 1), | |
| 229 | }; | |
| 230 | } | |
| 231 | ||
| 232 | export function wrappedTerminalLinkRangeIntersectsBufferLine( | |
| 233 | range: TerminalLinkBufferRange, | |
| 234 | bufferLineNumber: number, | |
| 235 | ): boolean { | |
| 236 | return range.start.y <= bufferLineNumber && bufferLineNumber <= range.end.y; | |
| 237 | } | |
| 238 | ||
| 239 | 192 | export function isTerminalLinkActivation( |
| 240 | 193 | event: Pick<MouseEvent, "metaKey" | "ctrlKey">, |
| 241 | 194 | platform = typeof navigator === "undefined" ? "" : navigator.platform, |