/** * public/link-paths.ts — pure file-path matcher for the terminal link provider (W1). * * Finds `src/app.ts:42`, `README.md`, `../lib/util.rs:10:5` etc. in a line of * terminal text so the terminal-session link provider can turn them into * clickable "open in editor" links. Deliberately DOM-free / xterm-free so it is * unit-testable in node and reusable by the diff/approval-preview views later. * * A candidate token is: an optional `./`, `../` or `dir/…/` prefix, a filename * with a dot-extension, and an optional `:line` / `:line:col` suffix. A candidate * is only linked when it is *probably* a real path — it has a `/` separator, OR a * `:line` suffix, OR its extension is in the CODE_EXT allowlist. This links code * paths while ignoring `example.com`, `v1.2.3`, `foo.bar`, and `12:34`. */ /** File extensions that mark a bare (slash-less, line-less) token as a code path. */ export const CODE_EXT: ReadonlySet = new Set([ 'ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs', 'py', 'go', 'rs', 'rb', 'java', 'kt', 'c', 'h', 'cpp', 'hpp', 'cc', 'cs', 'php', 'swift', 'css', 'scss', 'html', 'json', 'yaml', 'yml', 'toml', 'md', 'txt', 'sh', 'sql', 'vue', 'svelte', ]) export interface PathMatch { /** Exact matched substring, incl. any `:line[:col]` suffix (e.g. "src/app.ts:42"). */ text: string /** The file-path portion only, without the line/column suffix (e.g. "src/app.ts"). */ path: string /** 1-based line number, when a `:line` suffix was present. */ line?: number /** 1-based column, when a `:line:col` suffix was present. */ column?: number /** 1-based column of the first char (maps to an xterm range.start.x). */ startX: number /** 1-based column of the last char, inclusive (maps to an xterm range.end.x). */ endX: number } // A path candidate. The leading negative lookbehind rejects tokens glued to a // preceding word char, '.', '/', ':', '@' or '-' — this keeps the matcher from // grabbing the `path.html` tail of a `https://host/path.html` URL (which the // WebLinksAddon owns) or the middle of a larger identifier. The optional prefix // admits an absolute `/`, a `./` or a `../` before the dir segments. // group 1 = the path (prefix + dirs + filename.ext), no line/col // group 2 = line digits (optional) // group 3 = column digits (optional) const PATH_RE = /(?