Skip to content

Commit 123fecc

Browse files
committed
Use position mapping to accurately locate symbol indices during click deletion
- if the text has 2 identical symbols, the first one deletes regardless of which one is actually intended to be deleted └── packages └── ui └── src └── components └── editor └── common └── prompts ├── PromptField │ ├── PromptField.module.scss │ ├── PromptField.stories.tsx │ ├── PromptField.tsx │ ├── components │ │ ├── Tooltip.module.scss │ │ ├── Tooltip.tsx │ │ └── index.ts │ ├── hooks │ │ ├── use-drag-drop.ts │ │ ├── use-dropdown.ts │ │ ├── use-ghost-text.ts │ │ ├── use-handlers │ │ │ ├── handle-copy.ts │ │ │ ├── handle-cut.ts │ │ │ ├── handle-input-change.ts │ │ │ ├── handle-input-click.ts │ │ │ ├── handle-key-down.ts │ │ │ ├── handle-paste.ts │ │ │ ├── handle-submit.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── use-handlers.ts │ │ │ └── utils.ts │ │ └── use-keyboard-shortcuts.ts │ └── index.ts ├── Template │ ├── Template.module.scss │ ├── Template.tsx │ └── index.ts └── shared └── symbols ├── caret.ts ├── get-highlighted-text.tsx ├── index.ts ├── position-mapping.ts ├── prompt-symbols.module.scss ├── reconstruct-raw-value.ts └── use-symbol-deletion.ts
1 parent 583e1ac commit 123fecc

1 file changed

Lines changed: 42 additions & 13 deletions

File tree

‎packages/ui/src/components/editor/common/prompts/shared/symbols/use-symbol-deletion.ts‎

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,43 @@ export const use_symbol_deletion = (params: {
2323
params.on_delete(new_value, new_raw_cursor_pos)
2424
}
2525

26+
const get_start_index = (
27+
symbol_element: HTMLElement,
28+
search_pattern: string
29+
): number => {
30+
if (params.input_ref.current) {
31+
const pre_node_range = document.createRange()
32+
pre_node_range.selectNodeContents(params.input_ref.current)
33+
pre_node_range.setEndBefore(symbol_element)
34+
const display_pos = pre_node_range.toString().length
35+
36+
const raw_pos = map_display_pos_to_raw_pos({
37+
display_pos,
38+
raw_text: params.value,
39+
context_file_paths: params.context_file_paths
40+
})
41+
42+
if (params.value.startsWith(search_pattern, raw_pos)) {
43+
return raw_pos
44+
}
45+
46+
const start = Math.max(0, raw_pos - 10)
47+
const possible_index = params.value.indexOf(search_pattern, start)
48+
if (possible_index !== -1 && possible_index <= raw_pos + 10) {
49+
return possible_index
50+
}
51+
}
52+
return params.value.indexOf(search_pattern)
53+
}
54+
2655
const handle_symbol_deletion_by_click = (symbol_element: HTMLElement) => {
2756
const symbol_type = symbol_element.dataset.type
2857
if (symbol_type == 'file-symbol') {
2958
const file_path = symbol_element.dataset.path
3059
if (!file_path || !params.context_file_paths?.includes(file_path)) return
3160

3261
const search_pattern = `\`${file_path}\``
33-
const start_index = params.value.indexOf(search_pattern)
62+
const start_index = get_start_index(symbol_element, search_pattern)
3463

3564
if (start_index != -1) {
3665
apply_symbol_deletion(start_index, start_index + search_pattern.length)
@@ -40,7 +69,7 @@ export const use_symbol_deletion = (params: {
4069
if (!branch_name) return
4170

4271
const search_pattern = `#Changes(${branch_name})`
43-
const start_index = params.value.indexOf(search_pattern)
72+
const start_index = get_start_index(symbol_element, search_pattern)
4473

4574
if (start_index != -1) {
4675
apply_symbol_deletion(start_index, start_index + search_pattern.length)
@@ -53,21 +82,21 @@ export const use_symbol_deletion = (params: {
5382
const search_pattern = `#SavedContext(${context_type} "${context_name
5483
.replace(/\\/g, '\\\\')
5584
.replace(/"/g, '\\"')}")`
56-
const start_index = params.value.indexOf(search_pattern)
85+
const start_index = get_start_index(symbol_element, search_pattern)
5786

5887
if (start_index != -1) {
5988
apply_symbol_deletion(start_index, start_index + search_pattern.length)
6089
}
6190
} else if (symbol_type == 'selection-symbol') {
6291
const search_pattern = '#Selection'
63-
const start_index = params.value.indexOf(search_pattern)
92+
const start_index = get_start_index(symbol_element, search_pattern)
6493

6594
if (start_index != -1) {
6695
apply_symbol_deletion(start_index, start_index + search_pattern.length)
6796
}
6897
} else if (symbol_type == 'clipboard-paths-symbol') {
6998
const search_pattern = '#ClipboardPaths'
70-
const start_index = params.value.indexOf(search_pattern)
99+
const start_index = get_start_index(symbol_element, search_pattern)
71100

72101
if (start_index != -1) {
73102
apply_symbol_deletion(start_index, start_index + search_pattern.length)
@@ -87,7 +116,7 @@ export const use_symbol_deletion = (params: {
87116
/"/g,
88117
'\\\\"'
89118
)}")`
90-
const start_index = params.value.indexOf(search_pattern)
119+
const start_index = get_start_index(symbol_element, search_pattern)
91120

92121
if (start_index != -1) {
93122
apply_symbol_deletion(start_index, start_index + search_pattern.length)
@@ -99,7 +128,7 @@ export const use_symbol_deletion = (params: {
99128
if (!agent || !repo || !skillName) return
100129

101130
const search_pattern = `#Skill(${agent}:${repo}:${skillName})`
102-
const start_index = params.value.indexOf(search_pattern)
131+
const start_index = get_start_index(symbol_element, search_pattern)
103132

104133
if (start_index != -1) {
105134
apply_symbol_deletion(start_index, start_index + search_pattern.length)
@@ -124,11 +153,11 @@ export const use_symbol_deletion = (params: {
124153
const search_pattern_old = `<fragment ${attributes}>\n${content}\n</fragment>`
125154

126155
let search_pattern = search_pattern_new
127-
let start_index = params.value.indexOf(search_pattern)
156+
let start_index = get_start_index(symbol_element, search_pattern)
128157

129158
if (start_index == -1) {
130159
search_pattern = search_pattern_old
131-
start_index = params.value.indexOf(search_pattern)
160+
start_index = get_start_index(symbol_element, search_pattern)
132161
}
133162

134163
if (start_index != -1) {
@@ -139,7 +168,7 @@ export const use_symbol_deletion = (params: {
139168
if (!hash) return
140169

141170
const search_pattern = `#Image(${hash})`
142-
const start_index = params.value.indexOf(search_pattern)
171+
const start_index = get_start_index(symbol_element, search_pattern)
143172

144173
if (start_index != -1) {
145174
apply_symbol_deletion(start_index, start_index + search_pattern.length)
@@ -150,7 +179,7 @@ export const use_symbol_deletion = (params: {
150179
if (!hash || !token_count) return
151180

152181
const search_pattern = `#PastedText(${hash}:${token_count})`
153-
const start_index = params.value.indexOf(search_pattern)
182+
const start_index = get_start_index(symbol_element, search_pattern)
154183

155184
if (start_index != -1) {
156185
apply_symbol_deletion(start_index, start_index + search_pattern.length)
@@ -160,7 +189,7 @@ export const use_symbol_deletion = (params: {
160189
if (!url) return
161190

162191
const search_pattern = `#Website(${url})`
163-
const start_index = params.value.indexOf(search_pattern)
192+
const start_index = get_start_index(symbol_element, search_pattern)
164193

165194
if (start_index != -1) {
166195
apply_symbol_deletion(start_index, start_index + search_pattern.length)
@@ -170,7 +199,7 @@ export const use_symbol_deletion = (params: {
170199
if (!url) return
171200

172201
const search_pattern = `#Url(${url})`
173-
const start_index = params.value.indexOf(search_pattern)
202+
const start_index = get_start_index(symbol_element, search_pattern)
174203

175204
if (start_index != -1) {
176205
apply_symbol_deletion(start_index, start_index + search_pattern.length)

0 commit comments

Comments
 (0)