Skip to content

Commit 6d54bbc

Browse files
Merge pull request #51 from newtextdoc1111/dev
Merge dev
2 parents 8f6d451 + bda6f4f commit 6d54bbc

File tree

11 files changed

+505
-14
lines changed

11 files changed

+505
-14
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- **:zap:No setup required**: Automatically downloads CSV data optimized for Danbooru tags.
1414
- **:mag:Autocomplete**: Displays tag suggestions in real-time based on your input as you type.
1515
- **:file_cabinet:Related Tags Display**: Shows a list of tags highly related to the selected tag.
16+
- **:triangular_ruler:Auto Formatter**: Automatically formats prompt text when the textarea loses focus, cleaning up extra spaces and commas.
1617
- **:earth_asia:Multilingual Support**: Supports input completion in Japanese, Chinese, and Korean.
1718
- **:computer_mouse:Intuitive Operation**:
1819
- Supports both mouse and keyboard operations.
@@ -55,6 +56,20 @@ When you select any tag in a text input area, a list of highly related tags is d
5556
- Tags that have already been entered are displayed grayed out. If you try to insert a grayed-out tag, the already entered tag will instead be selected.
5657
- You can display related tags for the cursor position by pressing `Ctrl+Shift+Space`.
5758

59+
## Auto Formatter
60+
61+
When a text input area loses focus (e.g., by clicking outside or pressing Tab), the prompt text is automatically formatted. This feature improves readability when editing large amounts of text.
62+
63+
Detailed behavior is as follows:
64+
- Automatically adds a comma and space after each tag for proper separation
65+
- Removes extra commas and spaces between tags
66+
- You can manually trigger formatting using the keyboard shortcut `Alt+Shift+F` (keybinding can be customized in ComfyUI settings)
67+
- You can enable/disable this feature in the settings
68+
69+
> [!NOTE]
70+
> Auto-formatting is disabled for certain nodes to prevent errors.
71+
> Example: [Power Puter (rgthree)](https://github.com/rgthree/rgthree-comfy/wiki/Node:-Power-Puter) `code` field, [LoraLoaderBlockWeight (Inspire)](https://github.com/ltdrdata/ComfyUI-Inspire-Pack) `block_vector` field
72+
5873
## CSV Data
5974

6075
Two basic CSV data files are required for operation. These are managed on [HuggingFace](https://huggingface.co/datasets/newtextdoc1111/danbooru-tag-csv) and are automatically downloaded when ComfyUI is first launched after installation, so no setup is required.
@@ -166,6 +181,13 @@ For example, by preparing the following CSV, you can quickly insert correspondin
166181

167182
- **Hide Alias**: Hide/show the Alias ​​column in autocomplete and related tags (default is show)
168183

184+
### Auto Formatter
185+
186+
- **Enable Auto Format**: Enable/disable the automatically format prompt text when the textarea loses focus.
187+
- **Auto Format Trigger**: Choose when formatting is applied.
188+
- **Auto**: Format automatically when leaving text field
189+
- **Manual**: Format only via keyboard shortcut (default: `Alt+Shift+F`)
190+
169191
## Advanced Settings
170192

171193
### Disabling CSV Update Check on Startup

docs/README_jp.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- **:zap:セットアップ不要**: Danbooruタグに最適化された CSV データを自動でダウンロード
1212
- **:mag:オートコンプリート**: テキスト入力中に、入力内容に基づいてタグ候補をリアルタイムで表示
1313
- **:file_cabinet:関連タグ表示機能**: 選択したタグと関連性の高いタグを一覧表示
14+
- **:triangular_ruler:自動フォーマット**: テキストエリアがフォーカスを失った際に、プロンプトテキストを自動的にフォーマットし、余分なスペースやカンマを整理
1415
- **:earth_asia:多言語対応**: 日本語、中国語、韓国語での入力補完をサポート
1516
- **:computer_mouse:直感的な操作**:
1617
- マウスとキーボードどちらの操作にも対応
@@ -53,6 +54,20 @@
5354
- 入力済みのタグはグレーアウトで表示されます。グレーアウトしたタグを挿入しようとした場合、代わりに入力済みのタグを選択状態にします
5455
- `Ctrl+Shift+Space` キーでカーソル位置の関連タグを表示できます
5556

57+
## 自動フォーマット
58+
59+
テキスト入力エリアがフォーカスを失った際(例:外側をクリック、Tabキーを押す)、プロンプトテキストを自動的にフォーマットする機能です。大量のテキストを編集する際に可読性を向上させる事が出来ます。
60+
61+
詳細な動作は以下になります:
62+
- 各タグの後に自動的にカンマとスペースを追加し、適切に区切ります
63+
- タグ間の余分なカンマとスペースを削除します
64+
- キーボードショートカット `Alt+Shift+F` を使って手動でフォーマットすることも出来ます(キーバインドはComfyUIの設定から変更可能です)
65+
- 設定から機能の有効化/無効化を切り替えられます
66+
67+
> [!NOTE]
68+
> 一部のノードはエラーに繋がるため、自動フォーマットは実行されません。
69+
> 例: [Power Puter (rgthree)](https://github.com/rgthree/rgthree-comfy/wiki/Node:-Power-Puter)`code` フィールド、 [LoraLoaderBlockWeight (Inspire)](https://github.com/ltdrdata/ComfyUI-Inspire-Pack)`block_vector` フィールド
70+
5671
## CSV データ
5772

5873
動作には基本となる CSV データが2つ必要です。これらは [HuggingFace](https://huggingface.co/datasets/newtextdoc1111/danbooru-tag-csv) で管理されており、 ComfyUI にインストール後の初回起動時に自動でダウンロードされるのでセットアップは不要です。
@@ -164,6 +179,13 @@ worst_quality,5,9999999,
164179

165180
- **Hide Alias**: オートコンプリートと関連タグで表示されるエイリアス列の非表示/表示を切り替え(デフォルトは表示です)
166181

182+
### 自動フォーマット
183+
184+
- **Enable Auto Format**: テキストエリアがフォーカスを失った際にプロンプトテキストを自動的にフォーマットする機能の有効化/無効化
185+
- **Auto Format Trigger**: フォーマットを適用するタイミングを選択します
186+
- **自動**: テキスト欄からフォーカスが外れた際に自動でフォーマットします
187+
- **手動**: キーボードショートカットでのみフォーマットします(デフォルト: `Alt+Shift+F`
188+
167189
## 上級者向け設定
168190

169191
### 起動時のCSV更新チェックを無効化する

locales/en/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,16 @@
7070
"AutocompletePlus_Display_HideAlias": {
7171
"name": "Hide Alias",
7272
"tooltip": "Hide alias column in the autocomplete and related tags display."
73+
},
74+
"AutocompletePlus_AutoFormatter_Trigger": {
75+
"name": "Auto Format Trigger",
76+
"tooltip": "Auto: Format automatically when leaving text field.\nManual: Format only via keyboard shortcut. default keybind: (Alt+Shift+F)",
77+
"options": {
78+
"auto": "Auto",
79+
"manual": "Manual"
80+
}
81+
},
82+
"AutocompletePlus_AutoFormatter_EnableAutoFormat": {
83+
"name": "Enable Auto Format"
7384
}
7485
}

locales/ja/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,16 @@
7070
"AutocompletePlus_Display_HideAlias": {
7171
"name": "エイリアスを非表示",
7272
"tooltip": "オートコンプリートと関連タグで表示されるエイリアス列を非表示にします"
73+
},
74+
"AutocompletePlus_AutoFormatter_Trigger": {
75+
"name": "自動フォーマットのトリガー",
76+
"tooltip": "自動: テキスト欄からフォーカスが外れた際に自動でフォーマットします\n手動: キーボードショートカットでのみフォーマットします。デフォルトのキーバインド: (Alt+Shift+F)",
77+
"options": {
78+
"auto": "自動",
79+
"manual": "手動"
80+
}
81+
},
82+
"AutocompletePlus_AutoFormatter_EnableAutoFormat": {
83+
"name": "自動フォーマット機能の有効化"
7384
}
7485
}

locales/zh-TW/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,16 @@
7070
"AutocompletePlus_Display_HideAlias": {
7171
"name": "隱藏別名",
7272
"tooltip": "隱藏自動完成和相關標籤顯示中的別名欄"
73+
},
74+
"AutocompletePlus_AutoFormatter_Trigger": {
75+
"name": "自動格式化觸發方式",
76+
"tooltip": "自動: 離開文字方塊時自動格式化\n手動: 僅透過鍵盤快速鍵格式化。預設快速鍵: (Alt+Shift+F)",
77+
"options": {
78+
"auto": "自動",
79+
"manual": "手動"
80+
}
81+
},
82+
"AutocompletePlus_AutoFormatter_EnableAutoFormat": {
83+
"name": "啟用自動格式化"
7384
}
7485
}

locales/zh/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,16 @@
7070
"AutocompletePlus_Display_HideAlias": {
7171
"name": "隐藏别名",
7272
"tooltip": "隐藏自动完成和相关标签显示中的别名列"
73+
},
74+
"AutocompletePlus_AutoFormatter_Trigger": {
75+
"name": "自动格式化触发方式",
76+
"tooltip": "自动: 离开文本框时自动格式化\n手动: 仅通过键盘快捷键格式化。默认快捷键: (Alt+Shift+F)",
77+
"options": {
78+
"auto": "自动",
79+
"manual": "手动"
80+
}
81+
},
82+
"AutocompletePlus_AutoFormatter_EnableAutoFormat": {
83+
"name": "启用自动格式化"
7384
}
7485
}

tests/js/auto-formatter.test.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import {
2+
formatPromptText,
3+
__test__
4+
} from "../../web/js/auto-formatter.js";
5+
6+
const {
7+
shouldAutoFormat
8+
} = __test__;
9+
10+
describe('AutoFormatter Functions', () => {
11+
12+
describe('shouldAutoFormat', () => {
13+
const mockNodeInfo = (nodeType, inputName) => ({
14+
nodeType,
15+
inputName
16+
});
17+
18+
test('should return false for empty text', () => {
19+
expect(shouldAutoFormat('', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(false);
20+
expect(shouldAutoFormat(' ', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(false);
21+
});
22+
23+
test('should return false for blocklisted nodes', () => {
24+
expect(shouldAutoFormat('some text,', mockNodeInfo('Power Puter (rgthree)', 'code'))).toBe(false);
25+
expect(shouldAutoFormat('some text,', mockNodeInfo('LoraLoaderBlockWeight //Inspire', 'block_vector'))).toBe(false);
26+
});
27+
28+
test('should return false for numeric data or single-letter placeholders', () => {
29+
expect(shouldAutoFormat('0,0,0,1,1,1', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(false);
30+
expect(shouldAutoFormat('0.5, -1.2, 0.8', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(false);
31+
expect(shouldAutoFormat('A,B,R', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(false);
32+
expect(shouldAutoFormat('X, 1.5, Y', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(false);
33+
});
34+
35+
test('should return true for text with "word + comma" pattern', () => {
36+
expect(shouldAutoFormat('1girl, blue hair,', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(true);
37+
expect(shouldAutoFormat('tag1, tag2', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(true);
38+
});
39+
40+
test('should return false if "word + comma" pattern is not found', () => {
41+
expect(shouldAutoFormat('hello world', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(false);
42+
expect(shouldAutoFormat('tag1 tag2', mockNodeInfo('CLIPTextEncode', 'text'))).toBe(false);
43+
});
44+
});
45+
46+
describe('formatPromptText', () => {
47+
test('should format text by adding comma and space after tags', () => {
48+
const input = 'tag1,tag2,tag3';
49+
const expected = 'tag1, tag2, tag3, ';
50+
expect(formatPromptText(input)).toBe(expected);
51+
});
52+
53+
test('should remove extra spaces around tags', () => {
54+
const input = ' tag1 , tag2 ';
55+
const expected = 'tag1, tag2, ';
56+
expect(formatPromptText(input)).toBe(expected);
57+
});
58+
59+
test('should preserve special syntax like weights', () => {
60+
const input = '(tag1:1.2), [tag2]';
61+
// Note: The current implementation splits by comma.
62+
// If the input is "(tag1:1.2), [tag2]", it splits into "(tag1:1.2)" and "[tag2]".
63+
// Then joins with ", ".
64+
const expected = '(tag1:1.2), [tag2], ';
65+
expect(formatPromptText(input)).toBe(expected);
66+
});
67+
68+
test('should handle multiple lines', () => {
69+
const input = 'tag1, tag2\ntag3, tag4';
70+
const expected = 'tag1, tag2, \ntag3, tag4, ';
71+
expect(formatPromptText(input)).toBe(expected);
72+
});
73+
74+
test('should keep empty lines unchanged', () => {
75+
const input = 'tag1, tag2\n\ntag3, tag4';
76+
const expected = 'tag1, tag2, \n\ntag3, tag4, ';
77+
expect(formatPromptText(input)).toBe(expected);
78+
});
79+
80+
test('should handle empty input', () => {
81+
expect(formatPromptText('')).toBe('');
82+
expect(formatPromptText(null)).toBe(null);
83+
expect(formatPromptText(undefined)).toBe(undefined);
84+
});
85+
86+
test('should handle input with only spaces', () => {
87+
expect(formatPromptText(' ')).toBe(' ');
88+
});
89+
});
90+
});

0 commit comments

Comments
 (0)