Skip to content

Commit 0b85226

Browse files
Fix issue with XML/HTML output
1 parent 4b7786c commit 0b85226

File tree

3 files changed

+48
-104
lines changed

3 files changed

+48
-104
lines changed

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "Files2Prompt",
44
"icon": "./files2prompt-icon.webp",
55
"description": "Copy file contents for LLM prompts",
6-
"version": "1.7.1",
6+
"version": "1.7.2",
77
"publisher": "thomas-mckanna",
88
"keywords": [
99
"files",
@@ -192,4 +192,4 @@
192192
"fast-xml-parser": "^4.5.0",
193193
"ignore": "^6.0.2"
194194
}
195-
}
195+
}

src/extension.ts

Lines changed: 41 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ export function activate(context: vscode.ExtensionContext) {
1616
manageCheckboxStateManually: true,
1717
});
1818

19-
// Add fileTreeProvider to ensure proper disposal
2019
context.subscriptions.push(fileTreeProvider);
2120

2221
let history: string[][] = [];
@@ -34,41 +33,32 @@ export function activate(context: vscode.ExtensionContext) {
3433
return;
3534
}
3635

37-
// Before saving the current selection to history, check if it's the same as the last selection
3836
const lastSelection = history[historyPosition] || [];
3937
if (!arraysEqual(checkedFiles, lastSelection)) {
40-
// Save the current selection to the history
4138
if (historyPosition < history.length - 1) {
4239
history = history.slice(0, historyPosition + 1);
4340
}
44-
history.push([...checkedFiles]); // Save a copy of the current selection
41+
history.push([...checkedFiles]);
4542
historyPosition++;
4643
}
4744

4845
const xmlOutput = await generateXmlOutput(checkedFiles);
4946

50-
// Include system message if provided
5147
const config = vscode.workspace.getConfiguration("files2prompt");
5248
const systemMessage = config.get<string>("systemMessage");
5349

5450
let finalOutput = xmlOutput;
5551

5652
if (systemMessage && systemMessage.trim() !== "") {
57-
// Escape any ']]>' sequences in systemMessage
58-
const safeSystemMessage = systemMessage.replace(
59-
/]]>/g,
60-
"]]]]><![CDATA[>"
61-
);
6253
finalOutput =
6354
`<systemMessage>
6455
<![CDATA[
65-
${safeSystemMessage}
66-
>
56+
${systemMessage}
57+
]]>
6758
</systemMessage>
6859
` + finalOutput;
6960
}
7061

71-
// Copy to clipboard
7262
await vscode.env.clipboard.writeText(finalOutput);
7363

7464
vscode.window.showInformationMessage(
@@ -83,11 +73,8 @@ ${safeSystemMessage}
8373
if (historyPosition > 0) {
8474
historyPosition--;
8575
const previousSelection = history[historyPosition];
86-
87-
// Update the file selections in the FileTreeProvider
8876
await fileTreeProvider.setCheckedFiles(previousSelection);
8977
} else {
90-
// Show warning message
9178
vscode.window.showWarningMessage(
9279
"No previous selection to go back to."
9380
);
@@ -97,11 +84,8 @@ ${safeSystemMessage}
9784
if (historyPosition < history.length - 1) {
9885
historyPosition++;
9986
const nextSelection = history[historyPosition];
100-
101-
// Update the file selections in the FileTreeProvider
10287
await fileTreeProvider.setCheckedFiles(nextSelection);
10388
} else {
104-
// Show warning message
10589
vscode.window.showWarningMessage(
10690
"No next selection to go forward to."
10791
);
@@ -111,69 +95,57 @@ ${safeSystemMessage}
11195
const clipboardContent = await vscode.env.clipboard.readText();
11296
await processXmlContent(clipboardContent);
11397
}),
114-
vscode.commands.registerCommand(
115-
"files2prompt.copyOpenFiles",
116-
async () => {
117-
const tabGroups: ReadonlyArray<vscode.TabGroup> =
118-
vscode.window.tabGroups.all;
119-
120-
let xmlContent = "";
121-
122-
for (const group of tabGroups) {
123-
for (const tab of group.tabs) {
124-
if (tab.input instanceof vscode.TabInputText) {
125-
const fileUri = tab.input.uri;
126-
const filePath = fileUri.fsPath;
127-
if (fs.existsSync(filePath)) {
128-
const content = fs.readFileSync(filePath, "utf-8");
129-
// Escape any ']]>' sequences in content
130-
const safeContent = content.replace(
131-
/]]>/g,
132-
"]]]]><![CDATA[>"
133-
);
134-
135-
const fileName = path.relative(
136-
vscode.workspace.workspaceFolders![0].uri.fsPath,
137-
filePath
138-
);
139-
140-
xmlContent += `<file name="${fileName}">
98+
vscode.commands.registerCommand("files2prompt.copyOpenFiles", async () => {
99+
const tabGroups: ReadonlyArray<vscode.TabGroup> =
100+
vscode.window.tabGroups.all;
101+
102+
let xmlContent = "";
103+
104+
for (const group of tabGroups) {
105+
for (const tab of group.tabs) {
106+
if (tab.input instanceof vscode.TabInputText) {
107+
const fileUri = tab.input.uri;
108+
const filePath = fileUri.fsPath;
109+
if (fs.existsSync(filePath)) {
110+
const content = fs.readFileSync(filePath, "utf-8");
111+
112+
const fileName = path.relative(
113+
vscode.workspace.workspaceFolders![0].uri.fsPath,
114+
filePath
115+
);
116+
117+
xmlContent += `<file name="${fileName}">
141118
<![CDATA[
142-
${safeContent}
143-
>
119+
${content}
120+
]]>
144121
</file>
145122
`;
146-
}
147123
}
148124
}
149125
}
126+
}
150127

151-
if (xmlContent === "") {
152-
vscode.window.showWarningMessage("No open files to copy.");
153-
return;
154-
}
128+
if (xmlContent === "") {
129+
vscode.window.showWarningMessage("No open files to copy.");
130+
return;
131+
}
155132

156-
const finalOutput = `<files>
133+
const finalOutput = `<files>
157134
${xmlContent}</files>`;
158135

159-
// Copy to clipboard
160-
await vscode.env.clipboard.writeText(finalOutput);
161-
162-
vscode.window.showInformationMessage(
163-
"Open file contents copied to clipboard."
164-
);
165-
}
166-
)
136+
await vscode.env.clipboard.writeText(finalOutput);
137+
vscode.window.showInformationMessage(
138+
"Open file contents copied to clipboard."
139+
);
140+
})
167141
);
168142

169-
// Handle checkbox state changes asynchronously
170143
treeView.onDidChangeCheckboxState(async (e) => {
171144
for (const [item, state] of e.items) {
172145
await fileTreeProvider.updateCheckState(item, state);
173146
}
174147
});
175148

176-
// Listen for configuration changes to update behavior dynamically
177149
context.subscriptions.push(
178150
vscode.workspace.onDidChangeConfiguration((event) => {
179151
if (event.affectsConfiguration("files2prompt.systemMessage")) {
@@ -190,24 +162,20 @@ ${xmlContent}</files>`;
190162

191163
export function deactivate() { }
192164

193-
// Helper function to generate XML output
194165
async function generateXmlOutput(filePaths: string[]): Promise<string> {
195166
let xmlContent = "";
196167

197168
for (const filePath of filePaths) {
198169
const content = fs.readFileSync(filePath, "utf-8");
199-
// Escape any ']]>' sequences in file content
200-
const safeContent = content.replace(/]]>/g, "]]]]><![CDATA[>");
201-
202170
const fileName = path.relative(
203171
vscode.workspace.workspaceFolders![0].uri.fsPath,
204172
filePath
205173
);
206174

207175
xmlContent += `<file name="${fileName}">
208176
<![CDATA[
209-
${safeContent}
210-
>
177+
${content}
178+
]]>
211179
</file>
212180
`;
213181
}
@@ -216,7 +184,6 @@ ${safeContent}
216184
${xmlContent}</files>`;
217185
}
218186

219-
// Helper function to compare arrays of strings
220187
function arraysEqual(a: string[], b: string[]): boolean {
221188
if (a.length !== b.length) return false;
222189
const sortedA = [...a].sort();
@@ -227,28 +194,16 @@ function arraysEqual(a: string[], b: string[]): boolean {
227194
return true;
228195
}
229196

230-
// Function to process XML content from clipboard
231197
async function processXmlContent(xmlContent: string) {
232-
// Extract only XML content
233-
const xmlOnly = extractXmlContent(xmlContent);
234-
if (!xmlOnly) {
235-
vscode.window.showErrorMessage("No valid XML content found in clipboard.");
236-
return;
237-
}
238-
239198
const parser = new XMLParser({
240199
ignoreAttributes: false,
241-
allowBooleanAttributes: true,
242-
parseTagValue: true,
243-
parseAttributeValue: false,
244-
trimValues: false,
245200
cdataPropName: "__cdata",
246-
tagValueProcessor: (val, tagName) => val, // Prevent default processing
201+
trimValues: false
247202
});
248203

249204
let jsonObj;
250205
try {
251-
jsonObj = parser.parse(xmlOnly);
206+
jsonObj = parser.parse(xmlContent);
252207
} catch (error) {
253208
vscode.window.showErrorMessage("Error parsing XML content from clipboard.");
254209
return;
@@ -270,7 +225,6 @@ async function processXmlContent(xmlContent: string) {
270225
if (fileObj["__cdata"]) {
271226
fileContent = fileObj["__cdata"];
272227
} else {
273-
// If no CDATA, get text content
274228
fileContent = fileObj["#text"] || "";
275229
}
276230

@@ -285,14 +239,4 @@ async function processXmlContent(xmlContent: string) {
285239
}
286240

287241
vscode.window.showInformationMessage("Files have been updated successfully.");
288-
}
289-
290-
function extractXmlContent(text: string): string | null {
291-
const xmlMatch = text.match(/<files>[\s\S]*<\/files>/);
292-
if (xmlMatch) {
293-
return xmlMatch[0];
294-
}
295-
296-
// If no <files> tag found, return null
297-
return null;
298-
}
242+
}

0 commit comments

Comments
 (0)