Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TeXmacs/plugins/bash/progs/code/bash-lang.scm
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
(tm-define (parser-feature lan key)
(:require (and (== lan "bash") (== key "comment")))
`(,(string->symbol key)
(bool_features "space_before")
(inline "#")))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
39 changes: 38 additions & 1 deletion TeXmacs/tests/tmu/209_7.tmu
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<TMU|<tuple|1.1.0|2026.1.1>>
<TMU|<tuple|1.1.0|2026.1.2>>

<style|<tuple|generic|chinese|table-captions-above|number-europe|preview-ref|bash>>

Expand Down Expand Up @@ -26,6 +26,43 @@

\;

<<<<<<< Updated upstream
=======
# --------- comment----------

if [[ $# -gt 0 ]]; then

\ \ \ \ echo "参数个数: $#"

\ \ \ \ echo "参数列表: $@"

else

\ \ \ \ echo "未传入任何参数"

fi

\;

count=${#backups[@]}

\;

>>>>>>> Stashed changes
# --------- file/url----------

tar xzvf nvim-linux-x86_64.tar.gz

cd ~/.local/share/nvim/lazy

cat chapter-3.1.tmu

git clone git@gitee.com:XmacsLabs/mogan.git

curl wttr.in

\;

# ---------- globals ----------

NAME="Mogan"
Expand Down
152 changes: 146 additions & 6 deletions devel/209_7.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,163 @@
- 高亮功能:TeXmacs/plugins/bash/progs/code/bash-lang.scm
- 文档:TeXmacs/plugins/bash/doc/bash.en.tmu

## 2026/01/26 修复 Bash 代码模式下 `#` 被误识别为注释


**特殊参数/参数展开中的 `#` 被错误识别为注释起始符**

- `$#`(参数个数)中的 `#` 被渲染为注释颜色
- `${#backups[@]}`(数组长度)中的 `#` 被渲染为注释颜色

### Why

Bash 中的 `#` 同时出现在注释、特殊参数和参数展开语法中,一律按注释处理会导致误导。

### How

#### 1. 修复注释识别逻辑(仅针对 Bash)

文件:`src/System/Language/prog_language.cpp:312-335`

- 在 `get_color()` 函数中增加 Bash 特殊处理规则:
- 仅当 `#` 位于行首或前面为空白字符时,才识别为注释
- `$#` 与 `${#...}` 中的 `#` 不再被识别为注释

覆盖用例:

- `$#`
- `${#var}`
- `${#arr[@]}`

## 2026/01/23 修复bash代码模式下文件名路径等的错误高亮
### What

修复了 Bash代码模式下,路径、文件名、URL、连字符等场景中命令名和数字被错误高亮的问题,包括:

- 路径 / 文件名中的命令误高亮(abc.git、abc/git、nvim-linux.taz)
- URL 中的命令误高亮(git clone git@gitee.com:xxx.git)
- 文件名中的数字误高亮(209.in、209_9.tmu、file-1.txt)
- 负数与算术表达式高亮异常(-1、1-2)

同时保证独立命令、独立数字及算术表达式仍能正确高亮,仅影响 Bash 语言。


### How

#### 1. 关键字解析器边界检查

文件:src/Data/Parser/keyword_parser.cpp

- 增加 check_path_boundaries 开关
- 在 can_parse() 中补充边界判断:
- 禁止在路径、URL、单词字符、连字符、下划线后匹配关键字
- 禁止关键字后直接连接路径符号或连字符

避免 abc.git、abc/git、nvim-linux.taz 等误高亮。


#### 2. 数字解析器边界检查

文件:src/Data/Parser/number_parser.cpp

- 增加 check_path_boundaries 开关
- 在 can_parse() 中:
- 禁止路径、URL、单词字符前匹配数字
- 对连字符进行智能判断(区分 file-1 与 -1)
- 在 do_parse() 中:
- 避免 1-file.txt 误解析
- 保留 1-2 等算术表达式

同时将 parse\_\* 的严格检查限制为仅在边界模式下生效,避免影响其他语言。


#### 3. Bash 专用启用

文件:src/System/Language/prog_language.cpp

- 仅为 Bash 启用关键字与数字解析器的边界检查
- 其他语言保持原有行为

### Why

- 避免路径、文件名、URL 中的命令误高亮
- 避免文件名中的数字被错误识别
- 保证负数与算术表达式正常显示
- 保持 Bash 代码可读性
- 限定修改范围,避免影响其他语言


## 2026/01/23 修复bash代码模式下文件名路径等的错误高亮
### What

修复了 Bash代码模式下,路径、文件名、URL、连字符等场景中命令名和数字被错误高亮的问题,包括:

- 路径 / 文件名中的命令误高亮(abc.git、abc/git、nvim-linux.taz)
- URL 中的命令误高亮(git clone git@gitee.com:xxx.git)
- 文件名中的数字误高亮(209.in、209_9.tmu、file-1.txt)
- 负数与算术表达式高亮异常(-1、1-2)

同时保证独立命令、独立数字及算术表达式仍能正确高亮,仅影响 Bash 语言。


### How

#### 1. 关键字解析器边界检查

文件:src/Data/Parser/keyword_parser.cpp

- 增加 check_path_boundaries 开关
- 在 can_parse() 中补充边界判断:
- 禁止在路径、URL、单词字符、连字符、下划线后匹配关键字
- 禁止关键字后直接连接路径符号或连字符

避免 abc.git、abc/git、nvim-linux.taz 等误高亮。


#### 2. 数字解析器边界检查

文件:src/Data/Parser/number_parser.cpp

- 增加 check_path_boundaries 开关
- 在 can_parse() 中:
- 禁止路径、URL、单词字符前匹配数字
- 对连字符进行智能判断(区分 file-1 与 -1)
- 在 do_parse() 中:
- 避免 1-file.txt 误解析
- 保留 1-2 等算术表达式

同时将 parse\_\* 的严格检查限制为仅在边界模式下生效,避免影响其他语言。


#### 3. Bash 专用启用

文件:src/System/Language/prog_language.cpp

- 仅为 Bash 启用关键字与数字解析器的边界检查
- 其他语言保持原有行为

### Why

- 避免路径、文件名、URL 中的命令误高亮
- 避免文件名中的数字被错误识别
- 保证负数与算术表达式正常显示
- 保持 Bash 代码可读性
- 限定修改范围,避免影响其他语言

## 2025/01/22
### What
补充了bash-lang.scm中语法高亮的定义,增加了
- **外部命令高亮(external_command)**
- GNU coreutils
- 常用开发工具,如 `git`、`gh`、`code`、`claude`
- **外部命令高亮(external_command)**
- GNU coreutils
- 常用开发工具,如 `git`、`gh`、`code`、`claude`
- 常用 alias(如 `ll`、`gco`)


## 2025/01/20
## 2025/01/20
### What
为Mogan STEM添加Bash代码的语法高亮支持,包括语言定义文件和样式包。

### Why
满足用户的插入Bash代码需求

关联 issue #2607

关联 issue #2607
11 changes: 10 additions & 1 deletion src/Data/Parser/inline_comment_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,26 @@

inline_comment_parser_rep::inline_comment_parser_rep () {
m_starts= array<string> ();
m_require_space_before= false;
}

void
inline_comment_parser_rep::set_starts (const array<string>& p_starts) {
m_starts= p_starts;
}

void
inline_comment_parser_rep::set_require_space_before (bool require) {
m_require_space_before= require;
}

bool
inline_comment_parser_rep::can_parse (string s, int pos) {
if (pos >= N (s)) return false;
if (N (m_starts) == 0) return false;
if (m_require_space_before && pos > 0 && !is_space (s[pos - 1])) {
return false;
}

int i= 0;
while (i < N (m_starts)) {
Expand All @@ -40,4 +49,4 @@ inline_comment_parser_rep::can_parse (string s, int pos) {
void
inline_comment_parser_rep::do_parse (string s, int& pos) {
pos= N (s);
}
}
4 changes: 3 additions & 1 deletion src/Data/Parser/inline_comment_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ class inline_comment_parser_rep : public parser_rep {
string get_parser_name () { return "inline_comment_parser"; }

void set_starts (const array<string>& p_starts);
void set_require_space_before (bool require);
bool can_parse (string s, int pos);

private:
array<string> m_starts;
bool m_require_space_before;
void do_parse (string s, int& pos);
};

#endif
#endif
44 changes: 39 additions & 5 deletions src/Data/Parser/keyword_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
#include "tree_helper.hpp"

keyword_parser_rep::keyword_parser_rep () {
current_keyword= "";
keyword_group = hashmap<string, string> ();
extra_chars = array<char> ();
start_chars = array<char> ();
current_keyword = "";
keyword_group = hashmap<string, string> ();
extra_chars = array<char> ();
start_chars = array<char> ();
check_path_boundaries= false;
}

void
Expand Down Expand Up @@ -54,10 +55,43 @@ read_keyword (string s, int& i, string& result, array<char> extras,

bool
keyword_parser_rep::can_parse (string s, int pos) {
// Check that the preceding character is not a word character if path boundary
// checking is enabled
if (check_path_boundaries && pos > 0) {
char prev= s[pos - 1];
if (is_alpha (prev) || is_digit (prev) || contains (prev, extra_chars) ||
contains (prev, start_chars)) {
return false;
}
// Additionally, avoid matching keywords after '.' or '/' (common in paths)
// Also avoid matching after '@' (email/git user separator) and ':'
// (URL/Windows drive separator) Also avoid matching after '-' and '_'
// (common in filenames)
if (prev == '.' || prev == '/' || prev == '\\' || prev == '@' ||
prev == ':' || prev == '-' || prev == '_') {
return false;
}
}

string word;
bool hit= read_keyword (s, pos, word, extra_chars, start_chars) &&
keyword_group->contains (word);
if (hit) current_keyword= word;

if (hit) {
// Avoid matching keywords before '.' or '/' (common in paths) if path
// boundary checking is enabled Also avoid matching before '@' (email/git
// user separator) and ':' (URL/Windows drive separator) Also avoid matching
// before '-' and '_' (common in filenames)
if (check_path_boundaries && pos < N (s)) {
char next= s[pos];
if (next == '.' || next == '/' || next == '\\' || next == '@' ||
next == ':' || next == '-' || next == '_') {
return false;
}
}
current_keyword= word;
}

return hit;
}

Expand Down
2 changes: 2 additions & 0 deletions src/Data/Parser/keyword_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ class keyword_parser_rep : public parser_rep {
void use_keywords_of_lang (string lang_code);
void insert_start_char (char start_char);
void insert_extra_char (char extra_char);
void set_check_path_boundaries (bool check) { check_path_boundaries= check; }

private:
void do_parse (string s, int& pos);
hashmap<string, string> keyword_group;
string current_keyword;
array<char> extra_chars;
array<char> start_chars;
bool check_path_boundaries;
};

#endif
Loading