MCPcopy Index your code
hub / github.com/codeaashu/claude-code / findPlainTextUrlAt

Function findPlainTextUrlAt

src/ink/selection.ts:272–359  ·  view source on GitHub ↗
(
  screen: Screen,
  col: number,
  row: number,
)

Source from the content-addressed store, hash-verified

270 * cell has no OSC 8 hyperlink.
271 */
272export function findPlainTextUrlAt(
273 screen: Screen,
274 col: number,
275 row: number,
276): string | undefined {
277 if (row < 0 || row >= screen.height) return undefined
278 const width = screen.width
279 const noSelect = screen.noSelect
280 const rowOff = row * width
281
282 let c = col
283 if (c > 0) {
284 const cell = cellAt(screen, c, row)
285 if (cell && cell.width === CellWidth.SpacerTail) c -= 1
286 }
287 if (c < 0 || c >= width || noSelect[rowOff + c] === 1) return undefined
288
289 const startCell = cellAt(screen, c, row)
290 if (!startCell || !isUrlChar(startCell.char)) return undefined
291
292 // Expand left/right to the bounds of the URL-char run. URLs are ASCII
293 // (CellWidth.Narrow, 1 codeunit), so hitting a non-ASCII/wide/spacer
294 // cell is a boundary — no need to step over spacers like wordBoundsAt.
295 let lo = c
296 while (lo > 0) {
297 const prev = lo - 1
298 if (noSelect[rowOff + prev] === 1) break
299 const pc = cellAt(screen, prev, row)
300 if (!pc || pc.width !== CellWidth.Narrow || !isUrlChar(pc.char)) break
301 lo = prev
302 }
303 let hi = c
304 while (hi < width - 1) {
305 const next = hi + 1
306 if (noSelect[rowOff + next] === 1) break
307 const nc = cellAt(screen, next, row)
308 if (!nc || nc.width !== CellWidth.Narrow || !isUrlChar(nc.char)) break
309 hi = next
310 }
311
312 let token = ''
313 for (let i = lo; i <= hi; i++) token += cellAt(screen, i, row)!.char
314
315 // 1 cell = 1 char across [lo, hi] (ASCII-only run), so string index =
316 // column offset. Find the last scheme anchor at or before the click —
317 // a run like `https://a.com,https://b.com` has two, and clicking the
318 // second should return the second URL, not the greedy match of both.
319 const clickIdx = c - lo
320 const schemeRe = /(?:https?|file):\/\//g
321 let urlStart = -1
322 let urlEnd = token.length
323 for (let m; (m = schemeRe.exec(token)); ) {
324 if (m.index > clickIdx) {
325 urlEnd = m.index
326 break
327 }
328 urlStart = m.index
329 }

Callers 1

getHyperlinkAtMethod · 0.85

Calls 2

cellAtFunction · 0.85
isUrlCharFunction · 0.85

Tested by

no test coverage detected