Skip to content

Commit 3c82832

Browse files
committed
Refactor copy context command to a dedicated file to improve code organization and maintainability
- 'copy context' commands should live in `apps/editor/src/commands`
1 parent 12d7169 commit 3c82832

7 files changed

Lines changed: 157 additions & 120 deletions

File tree

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import * as vscode from 'vscode'
2+
import * as path from 'path'
3+
import { dictionary } from '@shared/constants/dictionary'
4+
import { PromptBuilder } from '../utils/prompt-builder'
5+
import { is_binary_file } from '../utils/is-binary'
6+
import { FilesCollector } from '../utils/files-collector'
7+
import { WorkspaceProvider } from '../context/providers/workspace/workspace-provider'
8+
import { OpenEditorsProvider } from '../context/providers/open-editors/open-editors-provider'
9+
import { t } from '../i18n'
10+
11+
export const copy_context_commands = (
12+
workspace_provider: WorkspaceProvider,
13+
open_editors_provider: OpenEditorsProvider
14+
) => {
15+
const files_collector = new FilesCollector({
16+
workspace_provider,
17+
open_editors_provider
18+
})
19+
20+
return [
21+
vscode.commands.registerCommand('codeWebChat.copyContext', async () => {
22+
let context_text = ''
23+
24+
try {
25+
const collected = await files_collector.collect_files()
26+
context_text = collected.other_files + collected.recent_files
27+
} catch (error: any) {
28+
console.error('Error collecting files:', error)
29+
vscode.window.showErrorMessage(
30+
dictionary.error_message.ERROR_COLLECTING_FILES(error.message)
31+
)
32+
return
33+
}
34+
35+
if (context_text == '') {
36+
vscode.window.showWarningMessage(
37+
t('command.copy-context.warning.no-files-selected')
38+
)
39+
return
40+
}
41+
42+
context_text =
43+
PromptBuilder.build_prompt({ context_text }).full_prompt + '\n'
44+
await vscode.env.clipboard.writeText(context_text)
45+
vscode.window.showInformationMessage(
46+
dictionary.information_message.CONTEXT_COPIED_TO_CLIPBOARD
47+
)
48+
}),
49+
50+
vscode.commands.registerCommand(
51+
'codeWebChat.copyContextOpenEditors',
52+
async () => {
53+
if (!open_editors_provider) return
54+
const checked_files = open_editors_provider.get_checked_files()
55+
56+
if (checked_files.length == 0) {
57+
vscode.window.showWarningMessage(
58+
dictionary.warning_message.NO_OPEN_EDITORS_SELECTED
59+
)
60+
return
61+
}
62+
63+
let context_text = ''
64+
const workspace_folders = vscode.workspace.workspaceFolders
65+
const is_multi_root =
66+
!!workspace_folders && workspace_folders.length > 1
67+
68+
for (const file_path of checked_files) {
69+
try {
70+
const file_uri = vscode.Uri.file(file_path)
71+
const content_uint8_array =
72+
await vscode.workspace.fs.readFile(file_uri)
73+
74+
let display_path: string
75+
const workspace_folder =
76+
vscode.workspace.getWorkspaceFolder(file_uri)
77+
78+
if (is_multi_root && workspace_folder) {
79+
const relative_path = path.relative(
80+
workspace_folder.uri.fsPath,
81+
file_path
82+
)
83+
display_path = `${workspace_folder.name}/${relative_path}`
84+
} else {
85+
display_path = vscode.workspace.asRelativePath(file_path)
86+
}
87+
88+
if (is_binary_file(file_path, content_uint8_array)) {
89+
context_text += PromptBuilder.build_file_context({
90+
filepath: display_path,
91+
is_binary: true
92+
})
93+
continue
94+
}
95+
96+
let content = new TextDecoder().decode(content_uint8_array)
97+
98+
const range = workspace_provider.get_range(file_path)
99+
if (range) {
100+
content = workspace_provider.apply_range_to_content(
101+
content,
102+
range
103+
)
104+
}
105+
106+
context_text += PromptBuilder.build_file_context({
107+
filepath: display_path,
108+
content
109+
})
110+
} catch (error: any) {
111+
vscode.window.showErrorMessage(
112+
dictionary.error_message.ERROR_READING_FILE(
113+
file_path,
114+
error.message
115+
)
116+
)
117+
}
118+
}
119+
120+
if (context_text == '') return
121+
122+
context_text =
123+
PromptBuilder.build_prompt({ context_text }).full_prompt + '\n'
124+
await vscode.env.clipboard.writeText(context_text)
125+
vscode.window.showInformationMessage(
126+
dictionary.information_message
127+
.CONTEXT_FROM_OPEN_EDITORS_COPIED_TO_CLIPBOARD
128+
)
129+
}
130+
)
131+
]
132+
}

‎apps/editor/src/commands/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './apply-chat-response-command'
2+
export * from './copy-context-command'
23
export * from './add-file-to-context-command'
34
export * from './remove-file-from-context-command'
45
export * from './close-all-editors-command'

‎apps/editor/src/context/context-initialization.ts‎

Lines changed: 0 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import * as vscode from 'vscode'
2-
import * as path from 'path'
32
import {
43
WorkspaceProvider,
54
FileItem
65
} from './providers/workspace/workspace-provider'
7-
import { FilesCollector } from '../utils/files-collector'
86
import { OpenEditorsProvider } from './providers/open-editors/open-editors-provider'
97
import { SharedContextState } from './shared-context-state'
108
import { EventEmitter } from 'events'
11-
import { dictionary } from '@shared/constants/dictionary'
129
import {
1310
CONTEXT_CHECKED_PATHS_STATE_KEY,
1411
CONTEXT_CHECKED_TIMESTAMPS_STATE_KEY,
@@ -17,8 +14,6 @@ import {
1714
type DuplicateWorkspaceContext
1815
} from '../constants/state-keys'
1916
import { SelectedFilesProvider } from './providers/selected-files/selected-files-provider'
20-
import { is_binary_file } from '../utils/is-binary'
21-
import { PromptBuilder } from '../utils/prompt-builder'
2217

2318
export const token_count_emitter = new EventEmitter()
2419

@@ -127,11 +122,6 @@ export const context_initialization = async (
127122
shared_context_state
128123
})
129124

130-
const files_collector = new FilesCollector({
131-
workspace_provider,
132-
open_editors_provider
133-
})
134-
135125
const update_view_badges = async () => {
136126
let context_token_count = 0
137127
if (selected_files_provider && selected_files_view) {
@@ -209,115 +199,6 @@ export const context_initialization = async (
209199
)
210200

211201
context.subscriptions.push(
212-
vscode.commands.registerCommand('codeWebChat.copyContext', async () => {
213-
let context_text = ''
214-
215-
try {
216-
const collected = await files_collector.collect_files()
217-
context_text = collected.other_files + collected.recent_files
218-
} catch (error: any) {
219-
console.error('Error collecting files:', error)
220-
vscode.window.showErrorMessage(
221-
dictionary.error_message.ERROR_COLLECTING_FILES(error.message)
222-
)
223-
return
224-
}
225-
226-
if (context_text == '') {
227-
vscode.window.showWarningMessage(
228-
dictionary.warning_message.NO_FILES_SELECTED
229-
)
230-
return
231-
}
232-
233-
context_text =
234-
PromptBuilder.build_prompt({ context_text }).full_prompt + '\n'
235-
await vscode.env.clipboard.writeText(context_text)
236-
vscode.window.showInformationMessage(
237-
dictionary.information_message.CONTEXT_COPIED_TO_CLIPBOARD
238-
)
239-
}),
240-
vscode.commands.registerCommand(
241-
'codeWebChat.copyContextOpenEditors',
242-
async () => {
243-
if (!open_editors_provider) return
244-
const checked_files = open_editors_provider.get_checked_files()
245-
246-
if (checked_files.length == 0) {
247-
vscode.window.showWarningMessage(
248-
dictionary.warning_message.NO_OPEN_EDITORS_SELECTED
249-
)
250-
return
251-
}
252-
253-
let context_text = ''
254-
const workspace_folders = vscode.workspace.workspaceFolders
255-
const is_multi_root =
256-
!!workspace_folders && workspace_folders.length > 1
257-
258-
for (const file_path of checked_files) {
259-
try {
260-
const file_uri = vscode.Uri.file(file_path)
261-
const content_uint8_array =
262-
await vscode.workspace.fs.readFile(file_uri)
263-
264-
let display_path: string
265-
const workspace_folder =
266-
vscode.workspace.getWorkspaceFolder(file_uri)
267-
268-
if (is_multi_root && workspace_folder) {
269-
const relative_path = path.relative(
270-
workspace_folder.uri.fsPath,
271-
file_path
272-
)
273-
display_path = `${workspace_folder.name}/${relative_path}`
274-
} else {
275-
display_path = vscode.workspace.asRelativePath(file_path)
276-
}
277-
278-
if (is_binary_file(file_path, content_uint8_array)) {
279-
context_text += PromptBuilder.build_file_context({
280-
filepath: display_path,
281-
is_binary: true
282-
})
283-
continue
284-
}
285-
286-
let content = new TextDecoder().decode(content_uint8_array)
287-
288-
const range = workspace_provider.get_range(file_path)
289-
if (range) {
290-
content = workspace_provider.apply_range_to_content(
291-
content,
292-
range
293-
)
294-
}
295-
296-
context_text += PromptBuilder.build_file_context({
297-
filepath: display_path,
298-
content
299-
})
300-
} catch (error: any) {
301-
vscode.window.showErrorMessage(
302-
dictionary.error_message.ERROR_READING_FILE(
303-
file_path,
304-
error.message
305-
)
306-
)
307-
}
308-
}
309-
310-
if (context_text == '') return
311-
312-
context_text =
313-
PromptBuilder.build_prompt({ context_text }).full_prompt + '\n'
314-
await vscode.env.clipboard.writeText(context_text)
315-
vscode.window.showInformationMessage(
316-
dictionary.information_message
317-
.CONTEXT_FROM_OPEN_EDITORS_COPIED_TO_CLIPBOARD
318-
)
319-
}
320-
),
321202
vscode.commands.registerCommand(
322203
'codeWebChat.expandContextFolders',
323204
async () => {

‎apps/editor/src/extension.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from './migrations'
1111
import {
1212
apply_chat_response_command,
13+
copy_context_commands,
1314
save_file_selection_command,
1415
restore_file_selection_command,
1516
add_file_to_context_command,
@@ -100,6 +101,7 @@ export const activate = async (context: vscode.ExtensionContext) => {
100101
const settings_provider = new SettingsProvider(context.extensionUri, context)
101102

102103
context.subscriptions.push(
104+
...copy_context_commands(workspace_provider, open_editors_provider),
103105
open_file_from_workspace_command(open_editors_provider),
104106
close_editor_command(),
105107
close_all_editors_command(),

‎apps/editor/src/i18n/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from 'vscode'
22
import { translations as commands } from './translations/commands'
33
import { translations as common } from './translations/common'
4+
import { translations as commands_copy_context } from './translations/commands/copy-context'
45
import { translations as views_settings_handlers_open_allow_patterns_settings } from './translations/views/settings/handlers/open-allow-patterns-settings'
56
import { translations as views_settings_handlers_open_ignore_patterns_settings } from './translations/views/settings/handlers/open-ignore-patterns-settings'
67
import { translations as views_settings_handlers_select_default_api_configuration } from './translations/views/settings/handlers/select-default-api-configuration'
@@ -24,6 +25,7 @@ export type TranslationKey = keyof typeof translations
2425

2526
const translations = {
2627
...commands,
28+
...commands_copy_context,
2729
...common,
2830
...views_settings_handlers_open_allow_patterns_settings,
2931
...views_settings_handlers_open_ignore_patterns_settings,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export const translations = {
2+
'command.copy-context.warning.no-files-selected': {
3+
en: 'No files selected.',
4+
pl: 'Nie wybrano plików.',
5+
'zh-cn': '未选择文件。',
6+
ja: 'ファイルが選択されていません。',
7+
'zh-tw': '未選擇檔案。',
8+
de: 'Keine Dateien ausgewählt.',
9+
es: 'No hay archivos seleccionados.',
10+
fr: 'Aucun fichier sélectionné.',
11+
'pt-br': 'Nenhum arquivo selecionado.',
12+
ru: 'Файлы не выбраны.',
13+
ko: '선택된 파일이 없습니다.',
14+
it: 'Nessun file selezionato.',
15+
tr: 'Dosya seçilmedi.',
16+
cs: 'Nebyly vybrány žádné soubory.',
17+
hu: 'Nincsenek fájlok kiválasztva.',
18+
bg: 'Няма избрани файлове.'
19+
}
20+
} as const

‎packages/shared/src/constants/dictionary.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ export const dictionary = {
122122
NOTHING_IN_CONTEXT_TO_SAVE: 'There is nothing in your context to save.',
123123
CONTEXTS_FILE_NOT_VALID_ARRAY:
124124
'Contexts file is not a valid array. Starting with empty contexts list.',
125-
NO_FILES_SELECTED: 'No files selected or open.',
126125
NOTHING_SELECTED_IN_CONTEXT: 'Nothing is selected in context.',
127126
NO_OPEN_EDITORS_SELECTED: 'No open editors selected.',
128127
NO_EDITOR_OPEN: 'No editor is open.',

0 commit comments

Comments
 (0)