Skip to content

Commit e9e472e

Browse files
committed
修复bash代码模式下的错误高亮
1 parent 27a8f06 commit e9e472e

File tree

3 files changed

+94
-2
lines changed

3 files changed

+94
-2
lines changed

TeXmacs/plugins/bash/progs/code/bash-lang.scm

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@
139139
"##" "#" "%%" "%" ;; ${var##pat} ${var%pat} ...
140140
)))
141141

142+
;; Paths / urls
143+
(tm-define (parser-feature lan key)
144+
(:require (and (== lan "bash") (== key "path")))
145+
`(,(string->symbol key)
146+
(enable)))
147+
142148
;; Numbers
143149
(tm-define (parser-feature lan key)
144150
(:require (and (== lan "bash") (== key "number")))
@@ -163,7 +169,8 @@
163169
(tm-define (parser-feature lan key)
164170
(:require (and (== lan "bash") (== key "comment")))
165171
`(,(string->symbol key)
166-
(inline "#")))
172+
(inline "#")
173+
(inline_require_space)))
167174

168175
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
169176
;; Preferences for syntax highlighting

src/System/Language/impl_language.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,11 @@ struct prog_language_rep : abstract_language_rep {
9090
void customize_string (tree config);
9191
void customize_preprocessor (tree config);
9292
void customize_comment (tree config);
93+
void customize_path (tree config);
9394
tree get_parser_config (string lan, string key);
95+
96+
bool inline_comment_requires_space;
97+
bool path_parser_enabled;
9498
};
9599

96100
struct scheme_language_rep : language_rep {

src/System/Language/prog_language.cpp

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ prog_language_rep::prog_language_rep (string name)
2525
: abstract_language_rep (name) {
2626
if (DEBUG_PARSER)
2727
debug_packrat << "Building the " * name * " language parser" << LF;
28+
inline_comment_requires_space= false;
29+
path_parser_enabled= false;
2830

2931
string use_modules= "(use-modules (code " * name * "-lang))";
3032
eval (use_modules);
@@ -49,6 +51,9 @@ prog_language_rep::prog_language_rep (string name)
4951

5052
tree preprocessor_config= get_parser_config (name, "preprocessor");
5153
customize_preprocessor (preprocessor_config);
54+
55+
tree path_config= get_parser_config (name, "path");
56+
customize_path (path_config);
5257
}
5358

5459
tree
@@ -207,6 +212,9 @@ prog_language_rep::customize_comment (tree config) {
207212
}
208213
inline_comment_parser.set_starts (inline_comment_starts);
209214
}
215+
else if (label == "inline_require_space") {
216+
inline_comment_requires_space= true;
217+
}
210218
}
211219
}
212220

@@ -227,6 +235,73 @@ prog_language_rep::customize_preprocessor (tree config) {
227235
if (DEBUG_PARSER) debug_packrat << preprocessor_parser.to_string ();
228236
}
229237

238+
void
239+
prog_language_rep::customize_path (tree config) {
240+
for (int i= 0; i < N (config); i++) {
241+
tree feature= config[i];
242+
string label = get_label (feature);
243+
if (label == "enable") {
244+
path_parser_enabled= true;
245+
}
246+
}
247+
}
248+
249+
static bool
250+
is_path_token_delim (char c) {
251+
return is_space (c) || c == '(' || c == ')' || c == '{' || c == '}' ||
252+
c == '[' || c == ']' || c == ';' || c == '|' || c == '&' ||
253+
c == '<' || c == '>';
254+
}
255+
256+
static bool
257+
looks_like_path_token (string token) {
258+
if (is_empty (token)) return false;
259+
if (token == "." || token == "..") return false;
260+
261+
url parsed= url_path (token);
262+
if (is_rooted (parsed) || is_rooted_web (parsed) || is_concat (parsed))
263+
return true;
264+
265+
bool has_dot = false;
266+
bool has_alpha= false;
267+
bool has_at = false;
268+
bool has_colon= false;
269+
for (int i= 0; i < N (token); i++) {
270+
char c= token[i];
271+
if (c == '/' || c == '\\') return true;
272+
if (c == '.') has_dot= true;
273+
if (is_alpha (c)) has_alpha= true;
274+
if (c == '@') has_at= true;
275+
if (c == ':') has_colon= true;
276+
if (c == ':' && i + 2 < N (token) && token[i + 1] == '/' &&
277+
token[i + 2] == '/')
278+
return true;
279+
}
280+
281+
if (N (token) >= 2 && token[0] == '.' && token[1] == '/') return true;
282+
if (N (token) >= 3 && token[0] == '.' && token[1] == '.' &&
283+
token[2] == '/')
284+
return true;
285+
if (N (token) >= 2 && token[0] == '~' && token[1] == '/') return true;
286+
if (has_at && has_colon) return true;
287+
if (has_dot && has_alpha) return true;
288+
return false;
289+
}
290+
291+
static bool
292+
parse_path_token (string s, int& pos) {
293+
if (pos >= N (s)) return false;
294+
if (is_path_token_delim (s[pos])) return false;
295+
296+
int start= pos;
297+
int end = pos;
298+
while (end < N (s) && !is_path_token_delim (s[end])) end++;
299+
string token= s (start, end);
300+
if (!looks_like_path_token (token)) return false;
301+
pos= end;
302+
return true;
303+
}
304+
230305
text_property
231306
prog_language_rep::advance (tree t, int& pos) {
232307
string s= t->label;
@@ -255,6 +330,10 @@ prog_language_rep::advance (tree t, int& pos) {
255330
current_parser= string_parser.get_parser_name ();
256331
return &tp_normal_rep;
257332
}
333+
if (path_parser_enabled && parse_path_token (s, pos)) {
334+
current_parser= "path_parser";
335+
return &tp_normal_rep;
336+
}
258337
if (keyword_parser.parse (s, pos)) {
259338
current_parser= keyword_parser.get_parser_name ();
260339
return &tp_normal_rep;
@@ -313,7 +392,9 @@ prog_language_rep::get_color (tree t, int start, int end) {
313392
int pos= 0;
314393
while (pos <= start) {
315394
if (inline_comment_parser.can_parse (s, pos)) {
316-
return decode_color (lan_name, encode_color ("comment"));
395+
if (!inline_comment_requires_space ||
396+
(pos == 0 || is_space (s[pos - 1])))
397+
return decode_color (lan_name, encode_color ("comment"));
317398
}
318399
pos++;
319400
}

0 commit comments

Comments
 (0)