forked from codinit-dev/codinit-dev
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtoolMentionParser.ts
More file actions
127 lines (99 loc) · 3.54 KB
/
Copy pathtoolMentionParser.ts
File metadata and controls
127 lines (99 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
export interface AutocompleteState {
isOpen: boolean;
searchQuery: string;
atPosition: number;
}
export type ReferenceType = 'file' | 'tool' | 'mixed';
export function shouldShowAutocomplete(text: string, cursorPos: number): AutocompleteState {
const textBeforeCursor = text.slice(0, cursorPos);
const lastAtIndex = textBeforeCursor.lastIndexOf('@');
if (lastAtIndex === -1) {
return { isOpen: false, searchQuery: '', atPosition: -1 };
}
const textAfterAt = textBeforeCursor.slice(lastAtIndex + 1);
if (textAfterAt.includes(' ')) {
return { isOpen: false, searchQuery: '', atPosition: -1 };
}
if (lastAtIndex > 0 && !/\s/.test(text[lastAtIndex - 1])) {
return { isOpen: false, searchQuery: '', atPosition: -1 };
}
return {
isOpen: true,
searchQuery: textAfterAt,
atPosition: lastAtIndex,
};
}
export function extractSearchQuery(text: string, cursorPos: number): string {
const state = shouldShowAutocomplete(text, cursorPos);
return state.searchQuery;
}
export function detectReferenceType(searchQuery: string): ReferenceType {
// If explicitly looking for file patterns (contains slash or dot)
if (searchQuery && /[\/\.]/.test(searchQuery)) {
return 'file';
}
// Default to tool for simple strings or empty queries
return 'tool';
}
function getTextWidth(text: string, font: string): number {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
if (!context) {
return text.length * 8;
}
context.font = font;
return context.measureText(text).width;
}
export function calculateDropdownPosition(
textarea: HTMLTextAreaElement,
atPosition: number,
): { x: number; y: number } | null {
if (!textarea) {
return null;
}
const text = textarea.value.slice(0, atPosition);
const lines = text.split('\n');
const currentLine = lines.length - 1;
const textBeforeCursor = lines[lines.length - 1];
const style = window.getComputedStyle(textarea);
const fontSize = parseFloat(style.fontSize);
const lineHeight = parseFloat(style.lineHeight) || fontSize * 1.2;
const paddingLeft = parseFloat(style.paddingLeft);
const paddingTop = parseFloat(style.paddingTop);
const font = `${style.fontSize} ${style.fontFamily}`;
const textWidth = getTextWidth(textBeforeCursor, font);
const rect = textarea.getBoundingClientRect();
const x = rect.left + paddingLeft + textWidth - textarea.scrollLeft;
const y = rect.top + paddingTop + (currentLine + 1) * lineHeight;
return { x, y };
}
export function insertToolMention(
text: string,
cursorPos: number,
toolName: string,
): { newText: string; newCursorPos: number } {
const state = shouldShowAutocomplete(text, cursorPos);
if (!state.isOpen) {
return { newText: text, newCursorPos: cursorPos };
}
const beforeAt = text.slice(0, state.atPosition);
const afterCursor = text.slice(cursorPos);
const newText = `${beforeAt}@${toolName} ${afterCursor}`;
const newCursorPos = state.atPosition + toolName.length + 2;
return { newText, newCursorPos };
}
export function insertFileReference(
text: string,
cursorPos: number,
filePath: string,
): { newText: string; newCursorPos: number } {
const state = shouldShowAutocomplete(text, cursorPos);
if (!state.isOpen) {
return { newText: text, newCursorPos: cursorPos };
}
const beforeAt = text.slice(0, state.atPosition);
const afterCursor = text.slice(cursorPos);
const newText = `${beforeAt}@${filePath} ${afterCursor}`;
const newCursorPos = state.atPosition + filePath.length + 2;
return { newText, newCursorPos };
}