49 lines
1.2 KiB
TypeScript
49 lines
1.2 KiB
TypeScript
export interface FileMentionRange {
|
|
start: number
|
|
end: number
|
|
query: string
|
|
}
|
|
|
|
interface FindActiveFileMentionInput {
|
|
text: string
|
|
cursorIndex: number
|
|
}
|
|
|
|
interface ApplyFileMentionReplacementInput {
|
|
text: string
|
|
mention: FileMentionRange
|
|
relativePath: string
|
|
}
|
|
|
|
const INVALID_MENTION_QUERY_CHARS = /[\s\n\r\t"']/
|
|
|
|
export function findActiveFileMention(input: FindActiveFileMentionInput): FileMentionRange | null {
|
|
const clampedCursor = Math.max(0, Math.min(input.cursorIndex, input.text.length))
|
|
const beforeCursor = input.text.slice(0, clampedCursor)
|
|
|
|
for (
|
|
let atIndex = beforeCursor.lastIndexOf('@');
|
|
atIndex >= 0;
|
|
atIndex = beforeCursor.lastIndexOf('@', atIndex - 1)
|
|
) {
|
|
const query = beforeCursor.slice(atIndex + 1)
|
|
if (INVALID_MENTION_QUERY_CHARS.test(query)) {
|
|
continue
|
|
}
|
|
return {
|
|
start: atIndex,
|
|
end: clampedCursor,
|
|
query,
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
export function applyFileMentionReplacement(input: ApplyFileMentionReplacementInput): string {
|
|
const safePath = input.relativePath.replace(/"/g, '\\"')
|
|
const before = input.text.slice(0, input.mention.start)
|
|
const after = input.text.slice(input.mention.end)
|
|
return `${before}"${safePath}"${after}`
|
|
}
|