From f35761c1abb1e977c8d594a47913648a4a865dca Mon Sep 17 00:00:00 2001 From: Jeffrey Chen <78434827+TCOTC@users.noreply.github.com> Date: Sat, 15 Nov 2025 17:16:23 +0800 Subject: [PATCH] Improve virtual reference keyword handling and support line breaks (#16298) * :art: Improve virtual reference keyword handling and support line breaks https://ld246.com/article/1762474775795 * Update text --- app/appearance/langs/ar_SA.json | 2 +- app/appearance/langs/de_DE.json | 2 +- app/appearance/langs/en_US.json | 2 +- app/appearance/langs/es_ES.json | 2 +- app/appearance/langs/fr_FR.json | 2 +- app/appearance/langs/he_IL.json | 2 +- app/appearance/langs/it_IT.json | 2 +- app/appearance/langs/ja_JP.json | 2 +- app/appearance/langs/pl_PL.json | 2 +- app/appearance/langs/pt_BR.json | 2 +- app/appearance/langs/ru_RU.json | 2 +- app/appearance/langs/zh_CHT.json | 2 +- app/appearance/langs/zh_CN.json | 2 +- app/src/assets/scss/business/_config.scss | 4 + app/src/assets/scss/main/_mobile.scss | 4 + app/src/config/editor.ts | 20 ++--- app/src/mobile/settings/editor.ts | 8 +- kernel/model/virutalref.go | 102 ++++++++++++++++------ 18 files changed, 110 insertions(+), 54 deletions(-) diff --git a/app/appearance/langs/ar_SA.json b/app/appearance/langs/ar_SA.json index 044a05d21..04aeb7dda 100644 --- a/app/appearance/langs/ar_SA.json +++ b/app/appearance/langs/ar_SA.json @@ -1143,7 +1143,7 @@ "md33": "المرجع الافتراضي", "md34": "بعد التمكين، سيحدد تلقائيا العلاقة المرجعية المحتملة وفقا للمعرف، الاسم المستعار ونص مرساة لمراجع الكتلة الموجودة", "md35": "قائمة استبعاد الكلمات المفتاحية المرجعية الافتراضية", - "md36": "‫استخدم الفاصلة في وضع اللغة الإنجليزية ‪,‬ للفصل، ويمكن إدراج الفاصلة نفسها باستخدام ‪\\,‬‬", + "md36": "‫استخدم الفاصلة في وضع اللغة الإنجليزية ‪,‬ أو فاصل سطر للفصل، ويمكن إدراج الفاصلة نفسها باستخدام ‪\\,‬‬", "md37": "الحد الأقصى لطول نص المرساة الديناميكي لمرجع الكتلة", "md38": "‫الحد الأقصى لطول نص المرساة الذي يتم تقديمه تلقائياً عند عدم تخصيص نص مرساة مرجع الكتلة، والافتراضي هو ‪96‬ حرفاً‬", "md39": "‫عنوان خدمة PlantUML‬", diff --git a/app/appearance/langs/de_DE.json b/app/appearance/langs/de_DE.json index 831d32fc9..4a21b43ae 100644 --- a/app/appearance/langs/de_DE.json +++ b/app/appearance/langs/de_DE.json @@ -1143,7 +1143,7 @@ "md33": "Virtuelle Referenz", "md34": "Nach der Aktivierung wird sie automatisch mögliche Referenzbeziehungen nach Name, Alias und Ankertext des bestehenden Blockrefs erkennen.", "md35": "Virtuelle Referenz-Stichwort-Ausschlussliste", - "md36": "Verwende das englische Komma , zum Trennen, das Komma selbst kann mit \\, escaped werden.", + "md36": "Verwende das englische Komma , oder Zeilenumbruch zum Trennen, das Komma selbst kann mit \\, escaped werden.", "md37": "Die maximale Länge des dynamischen Ankertextes des Blockrefs", "md38": "Die maximale Länge des Ankertextes, die automatisch gerendert wird, wenn der Ankertext des Blockrefs nicht angepasst ist, beträgt standardmäßig 96 Zeichen", "md39": "PlantUML-Serveradresse", diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index fa0d4431a..f4c48a332 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1143,7 +1143,7 @@ "md33": "Virtual Reference", "md34": "When enabled, it will automatically identify the possible reference relationship according to the name, alias and anchor text of the existing block ref", "md35": "Virtual Reference keyword exclusion list", - "md36": "Use the English comma , to separate, the comma itself can be escaped by \\,", + "md36": "Use the English comma , or line break to separate, the comma itself can be escaped by \\,", "md37": "The maximum length of block ref dynamic anchor text", "md38": "The maximum length of the anchor text that is automatically rendered when the block ref anchor text is not customized, the default is 96 characters", "md39": "PlantUML Serve Address", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index e38188a95..afd5288f7 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1143,7 +1143,7 @@ "md33": "Referencia virtual", "md34": "Una vez habilitado, identificará automáticamente la posible relación de referencia según el nombre, el alias y el texto de anclaje del bloque existente ref", "md35": "Lista de exclusión de palabras clave de referencia virtual", - "md36": "Utilice la coma inglesa , para separar, la propia coma puede escaparse con \\,", + "md36": "Utilice la coma inglesa , o salto de línea para separar, la propia coma puede escaparse con \\,", "md37": "La longitud máxima del bloque de texto de anclaje dinámico", "md38": "La longitud máxima del texto de anclaje que se renderiza automáticamente cuando el texto de anclaje del bloque ref no está personalizado, el valor por defecto es 96 caracteres", "md39": "Dirección de PlantUML Serve", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index a73178724..ad6734885 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1143,7 +1143,7 @@ "md33": "Référence virtuelle", "md34": "Après ouverture, il identifiera automatiquement les relations de référence possibles en fonction du nom, de l'alias et du texte d'ancrage des guillemets de bloc existants", "md35": "Liste d'exclusion des mots-clés de la référence virtuelle", - "md36": "Utiliser la virgule anglaise , pour séparer, la virgule elle-même peut être échappée par \\,", + "md36": "Utiliser la virgule anglaise , ou saut de ligne pour séparer, la virgule elle-même peut être échappée par \\,", "md37": "La longueur maximale du texte d'ancrage dynamique de référence de bloc", "md38": "La longueur maximale du texte d'ancrage qui est automatiquement rendu lorsque le texte d'ancrage de la référence de bloc n'est pas personnalisé, la valeur par défaut est de 96 caractères", "md39": "Adresse Servo PlantUML", diff --git a/app/appearance/langs/he_IL.json b/app/appearance/langs/he_IL.json index 2f6840936..bbcaa3ff7 100644 --- a/app/appearance/langs/he_IL.json +++ b/app/appearance/langs/he_IL.json @@ -1143,7 +1143,7 @@ "md33": "הפניה וירטואלית", "md34": "לאחר הפעלת אפשרות זו, זה יזהה אוטומטית את הקשר ההפניה האפשרי לפי השם, הכינוי וטקסט העוגן של בלוק ההפניה הקיים", "md35": "סימני מילות מפתח של הפניה וירטואלית לא לכלול", - "md36": "השתמש בסימן פסיק אנגלי , להפריד, הפסיק עצמו יכול להתחמק על ידי \\,", + "md36": "השתמש בסימן פסיק אנגלי , או מעבר שורה להפריד, הפסיק עצמו יכול להתחמק על ידי \\,", "md37": "אורך מקסימלי של טקסט העוגן הדינמי של בלוק ההפניה", "md38": "אורך מקסימלי של טקסט העוגן שמוצג אוטומטית כאשר טקסט העוגן של בלוק ההפניה אינו מותאם אישית, ברירת המחדל היא 96 תווים", "md39": "כתובת PlantUML Serve", diff --git a/app/appearance/langs/it_IT.json b/app/appearance/langs/it_IT.json index dd6bccbb4..5e4c5ae1a 100644 --- a/app/appearance/langs/it_IT.json +++ b/app/appearance/langs/it_IT.json @@ -1143,7 +1143,7 @@ "md33": "Riferimento virtuale", "md34": "Dopo l'abilitazione, identificherà automaticamente la possibile relazione di riferimento in base al nome, alias e testo di ancoraggio del riferimento al blocco esistente", "md35": "Lista di esclusione delle parole chiave di riferimento virtuale", - "md36": "Utilizzare la virgola inglese , per separare, la virgola stessa può essere sfuggita con \\,", + "md36": "Utilizzare la virgola inglese , o interruzione di riga per separare, la virgola stessa può essere sfuggita con \\,", "md37": "Lunghezza massima del testo di ancoraggio dinamico del riferimento al blocco", "md38": "La lunghezza massima del testo di ancoraggio che viene automaticamente reso quando il testo di ancoraggio del riferimento al blocco non è personalizzato, il valore predefinito è 96 caratteri", "md39": "Indirizzo del server PlantUML", diff --git a/app/appearance/langs/ja_JP.json b/app/appearance/langs/ja_JP.json index bd6ca2d3c..3cc04bff9 100644 --- a/app/appearance/langs/ja_JP.json +++ b/app/appearance/langs/ja_JP.json @@ -1143,7 +1143,7 @@ "md33": "仮想参照", "md34": "既存のブロック参照の名前、エイリアス、アンカーテキストに基づいて、考えられる参照関係を自動的に識別します", "md35": "仮想参照に含めないキーワードのリスト", - "md36": "リストを区切るにはカンマ , を使用します。カンマ自体は \\, でエスケープできます", + "md36": "リストを区切るにはカンマ , または改行を使用します。カンマ自体は \\, でエスケープできます", "md37": "ブロック参照の動的アンカーテキストの最大長", "md38": "ブロック参照のアンカーテキストをカスタマイズしていないときに自動的にレンダリングされるアンカーテキストの最大長。デフォルトは 96 文字です", "md39": "PlantUML サーバーアドレス", diff --git a/app/appearance/langs/pl_PL.json b/app/appearance/langs/pl_PL.json index 866508554..7c9cb1649 100644 --- a/app/appearance/langs/pl_PL.json +++ b/app/appearance/langs/pl_PL.json @@ -1143,7 +1143,7 @@ "md33": "Wirtualna referencja", "md34": "Po włączeniu, automatycznie zidentyfikuje możliwą relację referencyjną według nazwy, aliasu i tekstu zakotwienia istniejącego odniesienia bloku", "md35": "Lista słów kluczowych wykluczenia referencji wirtualnych", - "md36": "Używaj angielskiego przecinka , jako separatora, przecinek sam w sobie można eskapować przez \\,", + "md36": "Używaj angielskiego przecinka , lub znaku nowej linii jako separatora, przecinek sam w sobie można eskapować przez \\,", "md37": "Maksymalna długość dynamicznego tekstu zakotwienia referencji bloku", "md38": "Maksymalna długość tekstu zakotwienia, która jest automatycznie renderowana, gdy tekst zakotwienia dla referencji bloku nie jest dostosowany, domyślnie 96 znaków", "md39": "Adres serwera PlantUML", diff --git a/app/appearance/langs/pt_BR.json b/app/appearance/langs/pt_BR.json index a4f009413..c9fe95fc4 100644 --- a/app/appearance/langs/pt_BR.json +++ b/app/appearance/langs/pt_BR.json @@ -1143,7 +1143,7 @@ "md33": "Referência Virtual", "md34": "Quando ativado, identificará automaticamente a possível relação de referência de acordo com o nome, apelido e texto âncora da referência de bloco existente", "md35": "Lista de exclusão de palavras-chave de Referência Virtual", - "md36": "Use a vírgula inglesa , para separar, a própria vírgula pode ser escapada por \\,", + "md36": "Use a vírgula inglesa , ou quebra de linha para separar, a própria vírgula pode ser escapada por \\,", "md37": "O comprimento máximo do texto âncora dinâmico da referência de bloco", "md38": "O comprimento máximo do texto âncora que é renderizado automaticamente quando o texto âncora da referência de bloco não é personalizado, o padrão é 96 caracteres", "md39": "Endereço do Servidor PlantUML", diff --git a/app/appearance/langs/ru_RU.json b/app/appearance/langs/ru_RU.json index c2fcf7572..d6b7df642 100644 --- a/app/appearance/langs/ru_RU.json +++ b/app/appearance/langs/ru_RU.json @@ -1143,7 +1143,7 @@ "md33": "Виртуальная ссылка", "md34": "После включения она автоматически определит возможные отношения ссылок по имени, псевдониму и тексту якоря существующих ссылок", "md35": "Список ключевых слов исключений виртуальной ссылки", - "md36": "Используйте английскую запятую , для разделения, сама запятая может быть экранирована \\,", + "md36": "Используйте английскую запятую , или перенос строки для разделения, сама запятая может быть экранирована \\,", "md37": "Максимальная длина динамического текста якоря ссылки блока", "md38": "Максимальная длина текста якоря, который автоматически отображается, когда текст якоря ссылки блока не настроен, по умолчанию 96 символов", "md39": "Адрес сервера PlantUML", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index 53082796d..b6b3846cf 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1143,7 +1143,7 @@ "md33": "虛擬引用", "md34": "啟用後將自動根據已有塊引的命名、別名和錨文字來標識出可能存在的引用關係", "md35": "虛擬引用關鍵字排除列表", - "md36": "使用英文狀態下的逗號 , 進行分隔,逗號自身可通過 \\, 轉義", + "md36": "使用英文狀態下的逗號 , 或換行符進行分隔,逗號自身可通過 \\, 轉義", "md37": "塊引動態錨文字最大長度", "md38": "不自訂塊引錨文字時自動渲染錨文字的最大長度,預設為 96 個字元", "md39": "PlantUML 伺服地址", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 0b831a44c..cff52f368 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1143,7 +1143,7 @@ "md33": "虚拟引用", "md34": "启用后将自动根据已有块引的命名、别名和锚文本来标识出可能存在的引用关系", "md35": "虚拟引用关键字排除列表", - "md36": "使用英文状态下的逗号 , 进行分隔,逗号自身可通过 \\, 转义", + "md36": "使用英文状态下的逗号 , 或换行符进行分隔,逗号自身可通过 \\, 转义", "md37": "块引动态锚文本最大长度", "md38": "不自定义块引锚文本时自动渲染锚文本的最大长度,默认为 96 个字符", "md39": "PlantUML 伺服地址", diff --git a/app/src/assets/scss/business/_config.scss b/app/src/assets/scss/business/_config.scss index 4e6991197..d2842d4df 100644 --- a/app/src/assets/scss/business/_config.scss +++ b/app/src/assets/scss/business/_config.scss @@ -41,6 +41,10 @@ margin-top: -16px; height: calc(100% + 16px); } + + textarea.b3-text-field { + resize: vertical; + } } &__panel > .b3-tab-bar { diff --git a/app/src/assets/scss/main/_mobile.scss b/app/src/assets/scss/main/_mobile.scss index ab32bac61..d93e7972f 100644 --- a/app/src/assets/scss/main/_mobile.scss +++ b/app/src/assets/scss/main/_mobile.scss @@ -255,6 +255,10 @@ padding: 0 8px; } } + + .b3-label textarea.b3-text-field { + resize: vertical; + } } #menu { diff --git a/app/src/config/editor.ts b/app/src/config/editor.ts index f90ad58a8..8dfcb4573 100644 --- a/app/src/config/editor.ts +++ b/app/src/config/editor.ts @@ -145,22 +145,22 @@ export const editor = { -
-
+
+
${window.siyuan.languages.md9}
${window.siyuan.languages.md36}
+
+
- -
-
-
+
+
${window.siyuan.languages.md35}
${window.siyuan.languages.md36}
${window.siyuan.languages.md41}
+
+
- -
@@ -450,8 +450,8 @@ export const editor = { katexMacros: (editor.element.querySelector("#katexMacros") as HTMLTextAreaElement).value, codeLineWrap: (editor.element.querySelector("#codeLineWrap") as HTMLInputElement).checked, virtualBlockRef: (editor.element.querySelector("#virtualBlockRef") as HTMLInputElement).checked, - virtualBlockRefInclude: (editor.element.querySelector("#virtualBlockRefInclude") as HTMLInputElement).value, - virtualBlockRefExclude: (editor.element.querySelector("#virtualBlockRefExclude") as HTMLInputElement).value, + virtualBlockRefInclude: (editor.element.querySelector("#virtualBlockRefInclude") as HTMLTextAreaElement).value, + virtualBlockRefExclude: (editor.element.querySelector("#virtualBlockRefExclude") as HTMLTextAreaElement).value, blockRefDynamicAnchorTextMaxLen: parseInt((editor.element.querySelector("#blockRefDynamicAnchorTextMaxLen") as HTMLInputElement).value), backlinkExpandCount: parseInt((editor.element.querySelector("#backlinkExpandCount") as HTMLInputElement).value), backmentionExpandCount: parseInt((editor.element.querySelector("#backmentionExpandCount") as HTMLInputElement).value), diff --git a/app/src/mobile/settings/editor.ts b/app/src/mobile/settings/editor.ts index 6b11dc35b..fe5b5507b 100644 --- a/app/src/mobile/settings/editor.ts +++ b/app/src/mobile/settings/editor.ts @@ -42,8 +42,8 @@ const setEditor = (modelMainElement: Element) => { window.siyuan.config.editor.katexMacros = (modelMainElement.querySelector("#katexMacros") as HTMLTextAreaElement).value; window.siyuan.config.editor.codeLineWrap = (modelMainElement.querySelector("#codeLineWrap") as HTMLInputElement).checked; window.siyuan.config.editor.virtualBlockRef = (modelMainElement.querySelector("#virtualBlockRef") as HTMLInputElement).checked; - window.siyuan.config.editor.virtualBlockRefInclude = (modelMainElement.querySelector("#virtualBlockRefInclude") as HTMLInputElement).value; - window.siyuan.config.editor.virtualBlockRefExclude = (modelMainElement.querySelector("#virtualBlockRefExclude") as HTMLInputElement).value; + window.siyuan.config.editor.virtualBlockRefInclude = (modelMainElement.querySelector("#virtualBlockRefInclude") as HTMLTextAreaElement).value; + window.siyuan.config.editor.virtualBlockRefExclude = (modelMainElement.querySelector("#virtualBlockRefExclude") as HTMLTextAreaElement).value; window.siyuan.config.editor.blockRefDynamicAnchorTextMaxLen = parseInt((modelMainElement.querySelector("#blockRefDynamicAnchorTextMaxLen") as HTMLInputElement).value); window.siyuan.config.editor.backlinkExpandCount = parseInt((modelMainElement.querySelector("#backlinkExpandCount") as HTMLInputElement).value); window.siyuan.config.editor.backmentionExpandCount = parseInt((modelMainElement.querySelector("#backmentionExpandCount") as HTMLInputElement).value); @@ -193,13 +193,13 @@ export const initEditor = () => {
${window.siyuan.languages.md9} - +
${window.siyuan.languages.md36}
${window.siyuan.languages.md35} - +
${window.siyuan.languages.md36}
${window.siyuan.languages.md41}
diff --git a/kernel/model/virutalref.go b/kernel/model/virutalref.go index 67a899028..a3923806e 100644 --- a/kernel/model/virutalref.go +++ b/kernel/model/virutalref.go @@ -45,6 +45,9 @@ var virtualBlockRefCache, _ = ristretto.NewCache(&ristretto.Config{ BufferItems: 64, }) +// newlineRegexp 用于匹配连续或单个换行符的正则表达式 +var newlineRegexp = regexp.MustCompile(`[\r\n]+`) + func getBlockVirtualRefKeywords(root *ast.Node) (ret []string) { val, ok := virtualBlockRefCache.Get(root.ID) if !ok { @@ -121,18 +124,54 @@ func ResetVirtualBlockRefCache() { virtualBlockRefCache.Set("virtual_ref", keywords, 1) } +// addNewKeywords 将新关键字添加到虚拟引用关键字列表中,如果不存在则追加,保留空白字符 +func addNewKeywords(keywordsStr string, newKeywords []string) string { + keywordsStr = strings.TrimSpace(keywordsStr) + if 0 == len(newKeywords) { + return keywordsStr + } + + var builder strings.Builder + if "" != keywordsStr { + if !strings.HasSuffix(keywordsStr, "\\,") { + keywordsStr = strings.TrimSuffix(keywordsStr, ",") + } + builder.WriteString(keywordsStr) + builder.WriteString(",") + } + + keywords := gulu.Str.RemoveDuplicatedElem(parseKeywords(keywordsStr)) + newKeywords = gulu.Str.RemoveDuplicatedElem(newKeywords) + allKeys := make(map[string]bool) + + // 添加新关键字 + for _, keyword := range newKeywords { + keywordTrimmed := strings.TrimSpace(keyword) + if "" == keywordTrimmed { + continue + } + if gulu.Str.Contains(keywordTrimmed, keywords) { + // 剔除已存在的关键字 + continue + } + if _, value := allKeys[keywordTrimmed]; value { + // 剔除重复的关键字 + continue + } + allKeys[keywordTrimmed] = true + builder.WriteString(strings.ReplaceAll(keyword, ",", "\\,")) // 字符串切片转换为字符串,需要转义逗号 + builder.WriteString(",") + } + + return strings.TrimSuffix(builder.String(), ",") +} + func AddVirtualBlockRefInclude(keyword []string) { if 1 > len(keyword) { return } - - include := strings.ReplaceAll(Conf.Editor.VirtualBlockRefInclude, "\\,", "__comma@sep__") - includes := strings.Split(include, ",") - includes = append(includes, keyword...) - includes = gulu.Str.RemoveDuplicatedElem(includes) - Conf.Editor.VirtualBlockRefInclude = strings.Join(includes, ",") + Conf.Editor.VirtualBlockRefInclude = addNewKeywords(Conf.Editor.VirtualBlockRefInclude, keyword) Conf.Save() - ResetVirtualBlockRefCache() } @@ -140,14 +179,8 @@ func AddVirtualBlockRefExclude(keyword []string) { if 1 > len(keyword) { return } - - exclude := strings.ReplaceAll(Conf.Editor.VirtualBlockRefExclude, "\\,", "__comma@sep__") - excludes := strings.Split(exclude, ",") - excludes = append(excludes, keyword...) - excludes = gulu.Str.RemoveDuplicatedElem(excludes) - Conf.Editor.VirtualBlockRefExclude = strings.Join(excludes, ",") + Conf.Editor.VirtualBlockRefExclude = addNewKeywords(Conf.Editor.VirtualBlockRefExclude, keyword) Conf.Save() - ResetVirtualBlockRefCache() } @@ -213,6 +246,30 @@ func processVirtualRef(n *ast.Node, unlinks *[]*ast.Node, virtualBlockRefKeyword return false } +// parseKeywords 将字符串转换为关键字切片,并剔除前后的空白字符 +func parseKeywords(keywordsStr string) (keywords []string) { + keywords = []string{} + keywordsStr = strings.TrimSpace(keywordsStr) + if "" == keywordsStr { + return + } + // 先处理转义的逗号 + keywordsStr = strings.ReplaceAll(keywordsStr, "\\,", "__comma@sep__") + // 再将连续或单个换行符替换为一个逗号,避免把 `\\\n` 转换为 `\,` + keywordsStr = newlineRegexp.ReplaceAllString(keywordsStr, ",") + // 按逗号分隔 + for part := range strings.SplitSeq(keywordsStr, ",") { + part = strings.TrimSpace(part) // 剔除前后的空白字符 + if "" == part { + continue + } + // 恢复转义的逗号 + part = strings.ReplaceAll(part, "__comma@sep__", ",") + keywords = append(keywords, part) + } + return +} + func getVirtualRefKeywords(root *ast.Node) (ret []string) { if !Conf.Editor.VirtualBlockRef { return @@ -222,25 +279,16 @@ func getVirtualRefKeywords(root *ast.Node) (ret []string) { ret = val.([]string) } - if "" != strings.TrimSpace(Conf.Editor.VirtualBlockRefInclude) { - include := strings.ReplaceAll(Conf.Editor.VirtualBlockRefInclude, "\\,", "__comma@sep__") - includes := strings.Split(include, ",") - var tmp []string - for _, e := range includes { - e = strings.ReplaceAll(e, "__comma@sep__", ",") - tmp = append(tmp, e) - } - includes = tmp + includes := parseKeywords(Conf.Editor.VirtualBlockRefInclude) + if 0 < len(includes) { ret = append(ret, includes...) ret = gulu.Str.RemoveDuplicatedElem(ret) } - if "" != strings.TrimSpace(Conf.Editor.VirtualBlockRefExclude) { - exclude := strings.ReplaceAll(Conf.Editor.VirtualBlockRefExclude, "\\,", "__comma@sep__") - excludes := strings.Split(exclude, ",") + excludes := parseKeywords(Conf.Editor.VirtualBlockRefExclude) + if 0 < len(excludes) { var tmp, regexps []string for _, e := range excludes { - e = strings.ReplaceAll(e, "__comma@sep__", ",") if strings.HasPrefix(e, "/") && strings.HasSuffix(e, "/") { regexps = append(regexps, e[1:len(e)-1]) } else {