Skip to content

Commit 729574c

Browse files
Merge pull request #59 from BlakeNeko/feature/trim-surrounding-spaces
Feature/#58 trim surrounding spaces
2 parents f8cbd27 + e4decf9 commit 729574c

8 files changed

Lines changed: 125 additions & 14 deletions

File tree

locales/en/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,9 @@
8585
},
8686
"AutocompletePlus_AutoFormatter_EnableAutoFormat": {
8787
"name": "Enable Auto Format"
88+
},
89+
"AutocompletePlus_AutoFormatter_TrimSurroundingSpaces": {
90+
"name": "Trim Surrounding Spaces",
91+
"tooltip": "When enabled, trim any blank lines from the beginning and end of the prompt."
8892
}
8993
}

locales/ja/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,9 @@
8585
},
8686
"AutocompletePlus_AutoFormatter_EnableAutoFormat": {
8787
"name": "自動フォーマット機能の有効化"
88+
},
89+
"AutocompletePlus_AutoFormatter_TrimSurroundingSpaces": {
90+
"name": "先頭・末尾の空白を削除",
91+
"tooltip": "有効時、プロンプトの先頭と末尾にある空行やスペースをすべて削除します。"
8892
}
8993
}

locales/zh-TW/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,9 @@
8585
},
8686
"AutocompletePlus_AutoFormatter_EnableAutoFormat": {
8787
"name": "啟用自動格式化"
88+
},
89+
"AutocompletePlus_AutoFormatter_TrimSurroundingSpaces": {
90+
"name": "去除首尾空白",
91+
"tooltip": "啟用時,清除提示詞開頭和結尾的所有空行和空格。"
8892
}
8993
}

locales/zh/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,9 @@
8585
},
8686
"AutocompletePlus_AutoFormatter_EnableAutoFormat": {
8787
"name": "启用自动格式化"
88+
},
89+
"AutocompletePlus_AutoFormatter_TrimSurroundingSpaces": {
90+
"name": "去除首尾空白",
91+
"tooltip": "启用时,清除提示词开头和结尾的所有空行和空格。"
8892
}
8993
}

tests/js/auto-formatter.test.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,18 @@ describe('AutoFormatter Functions', () => {
4747
describe('formatPromptText', () => {
4848
// Store original setting value to restore after tests
4949
const originalUseTrailingComma = settingValues.useTrailingComma;
50+
const originalTrimSurroundingSpaces = settingValues.trimSurroundingSpaces;
5051

5152
afterEach(() => {
5253
// Restore original setting after each test
5354
settingValues.useTrailingComma = originalUseTrailingComma;
55+
settingValues.trimSurroundingSpaces = originalTrimSurroundingSpaces;
5456
});
5557

5658
describe('with useTrailingComma enabled', () => {
5759
beforeEach(() => {
5860
settingValues.useTrailingComma = true;
61+
settingValues.trimSurroundingSpaces = false;
5962
});
6063

6164
test('should format text by adding comma and space after tags', () => {
@@ -101,6 +104,7 @@ describe('AutoFormatter Functions', () => {
101104
describe('with useTrailingComma disabled', () => {
102105
beforeEach(() => {
103106
settingValues.useTrailingComma = false;
107+
settingValues.trimSurroundingSpaces = false;
104108
});
105109

106110
test('should format text by adding comma and space after tags without trailing comma', () => {
@@ -143,6 +147,59 @@ describe('AutoFormatter Functions', () => {
143147
});
144148
});
145149

150+
describe('with trimSurroundingSpaces enabled', () => {
151+
beforeEach(() => {
152+
settingValues.trimSurroundingSpaces = true;
153+
settingValues.useTrailingComma = false;
154+
});
155+
156+
test('should remove trailing newlines and spaces', () => {
157+
const input = 'tag1, tag2\n\n ';
158+
const expected = 'tag1, tag2';
159+
expect(formatPromptText(input)).toBe(expected);
160+
});
161+
162+
test('should remove leading newlines and spaces', () => {
163+
const input = ' \n\ntag1, tag2';
164+
const expected = 'tag1, tag2';
165+
expect(formatPromptText(input)).toBe(expected);
166+
});
167+
168+
test('should remove both leading and trailing whitespaces but keep middle empty lines', () => {
169+
const input = ' \n\ntag1\n\ntag2\n\n ';
170+
const expected = 'tag1\n\ntag2';
171+
expect(formatPromptText(input)).toBe(expected);
172+
});
173+
174+
test('should return empty string if input is only whitespace', () => {
175+
const input = ' \n ';
176+
expect(formatPromptText(input)).toBe('');
177+
});
178+
});
179+
180+
describe('with trimSurroundingSpaces disabled', () => {
181+
beforeEach(() => {
182+
settingValues.trimSurroundingSpaces = false;
183+
settingValues.useTrailingComma = false;
184+
});
185+
186+
test('should preserve trailing newlines', () => {
187+
const input = 'tag1, tag2\n\n';
188+
const expected = 'tag1, tag2\n\n';
189+
expect(formatPromptText(input)).toBe(expected);
190+
});
191+
192+
test('should preserve leading spaces (as first line content)', () => {
193+
const input = ' \ntag1';
194+
const expected = '\ntag1';
195+
expect(formatPromptText(input)).toBe(expected);
196+
});
197+
198+
test('should handle input with only spaces', () => {
199+
expect(formatPromptText(' ')).toBe(' ');
200+
});
201+
});
202+
146203
test('should handle empty input', () => {
147204
expect(formatPromptText('')).toBe('');
148205
expect(formatPromptText(null)).toBe(null);

web/js/auto-formatter.js

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@ import { NodeInfo } from './node-info.js';
77
*
88
* Format conditions:
99
* 1. Skip formatting if node is in blocklist
10-
* 2. Skip formatting if text contains only numbers or single letters (separated by commas)
11-
* 3. Format if text contains "word + comma" pattern at least twice
12-
* 4. Otherwise, don't format
10+
* 2. If text is empty after trimming, format only if trimSurroundingSpaces is enabled, otherwise don't format
11+
* 3. Skip formatting if text contains only numbers or single letters (separated by commas)
12+
* 4. Format if text contains "word + comma" pattern
13+
* 5. Format if trimSurroundingSpaces is enabled and there are surrounding spaces or line breaks
14+
* 6. Otherwise, don't format
1315
*
1416
* @param {NodeInfo} nodeInfo - The node information.
1517
* @returns {boolean} - True if the text should be formatted, false otherwise.
1618
*/
1719
function shouldAutoFormat(text, nodeInfo) {
18-
if (!text || text.trim().length === 0) return false;
20+
if (!text) return false;
1921

2022
// 1. Check if the node name is in the blocklist
2123
const blocklist = [
@@ -34,10 +36,14 @@ function shouldAutoFormat(text, nodeInfo) {
3436
// console.debug(`[Autocomplete-Plus] auto-formatter on blur => nodeType: ${nodeInfo.nodeType}, inputName: ${nodeInfo.inputName}`);
3537
}
3638

37-
3839
const trimmedText = text.trim();
3940

40-
// 2. Check if the text is purely numeric data or single-letter placeholders with commas
41+
// 2. Check if the text is completely empty after trimming
42+
if (trimmedText.length === 0) {
43+
return settingValues.trimSurroundingSpaces;
44+
}
45+
46+
// 3. Check if the text is purely numeric data or single-letter placeholders with commas
4147
// (e.g., "0,0,0,1,1,1" or "0.5, -1.2, 0.8" or "A,B,R" for LoRA Block Weight)
4248
const elements = trimmedText.split(',').map(el => el.trim());
4349
const isSingleLetterOrNumeric = elements.every(el => {
@@ -50,15 +56,18 @@ function shouldAutoFormat(text, nodeInfo) {
5056
return false; // Don't format numeric data or single-letter template patterns
5157
}
5258

53-
// 3. Check if the text contains the pattern "word + comma"
59+
// 4. If text contains "word + comma" pattern, format it
5460
const wordCommaPattern = /\w+\s*,/g;
55-
const matches = trimmedText.match(wordCommaPattern);
56-
57-
if (matches == null) {
58-
return false;
61+
if (trimmedText.match(wordCommaPattern)) {
62+
return true;
5963
}
6064

61-
return true; // Text should be formatted
65+
// 5. If trimSurroundingSpaces is enabled and there are surrounding spaces, format to trim them
66+
if (settingValues.trimSurroundingSpaces && text !== trimmedText) {
67+
return true;
68+
}
69+
70+
return false; // Otherwise, don't format
6271
}
6372

6473
/**
@@ -68,10 +77,27 @@ function shouldAutoFormat(text, nodeInfo) {
6877
* @returns {string} - The formatted text.
6978
*/
7079
export function formatPromptText(text) {
71-
if (!text || text.trim().length === 0) return text;
80+
// Handle null or undefined input
81+
if (text == null) return text;
82+
83+
// If the text is empty or contains only spaces...
84+
if (text.trim().length === 0) {
85+
if (settingValues.trimSurroundingSpaces) {
86+
// ...And trimSurroundingSpaces is enabled, return an empty string
87+
return '';
88+
} else {
89+
// ...Otherwise, return the original text
90+
return text;
91+
}
92+
}
93+
94+
let processedText = text;
95+
if (settingValues.trimSurroundingSpaces) {
96+
processedText = text.trim();
97+
}
7298

7399
// Split text into individual lines for processing
74-
const lines = text.split('\n');
100+
const lines = processedText.split('\n');
75101
const formattedLines = [];
76102

77103
for (const line of lines) {

web/js/main.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,17 @@ app.registerExtension({
490490
},
491491

492492
// --- Auto format settings ---
493+
{
494+
id: id + '.AutoFormatter.TrimSurroundingSpaces',
495+
name: 'Trim Surrounding Spaces',
496+
tooltip: 'When enabled, trim any blank lines from the beginning and end of the prompt.',
497+
type: 'boolean',
498+
defaultValue: false,
499+
category: [name, 'AutoFormatter', 'Trim Surrounding Spaces'],
500+
onChange: (newVal, oldVal) => {
501+
settingValues.trimSurroundingSpaces = newVal;
502+
},
503+
},
493504
{
494505
id: id + '.AutoFormatter.UseTrailingComma',
495506
name: 'Use Trailing Comma',

web/js/settings.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const settingValues = {
2525
enableAutoFormat: true,
2626
autoFormatTrigger: 'auto', // Options: 'auto' (format on blur + shortcut), 'manual' (shortcut only)
2727
useTrailingComma: false, // Whether to add comma at the end of each line
28+
trimSurroundingSpaces: false, // Trim spaces around each tag
2829

2930

3031
// Internal logic settings

0 commit comments

Comments
 (0)