Skip to content

Commit 44e04c4

Browse files
author
Charlie Gordon
committed
improve c-mode, add mode_flags to handle language mode flavors
* add mode_flags and mode_name in EditState * pass mode_flags to ColorizeFuncs * define several CLANG mode flavors for C, C++, Javascript, Java, etc. * add flavor specific keyword lists for c-mode * add regex support in c-mode for Javascript flavor
1 parent 4a1ab74 commit 44e04c4

14 files changed

+201
-82
lines changed

bufed.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ static void build_bufed_list(EditState *s)
103103
mode_name = "none";
104104
for (e = qs->first_window; e != NULL; e = e->next_window) {
105105
if (e->b == b1) {
106-
if (e->mode) {
107-
mode_name = e->mode->name;
106+
if (e->mode_name) {
107+
mode_name = e->mode_name;
108108
break;
109109
}
110110
}

clang.c

+124-26
Original file line numberDiff line numberDiff line change
@@ -21,41 +21,51 @@
2121

2222
#include "qe.h"
2323

24-
#if 0
25-
static const char cc_keywords[] =
24+
static const char cc_keywords[] = {
2625
"asm|catch|class|delete|friend|inline|new|operator|"
27-
"private|protected|public|template|try|this|virtual|throw|";
26+
"private|protected|public|template|try|this|virtual|throw|"
27+
};
28+
29+
static const char js_keywords[] = {
30+
"break|continue|delete|else|for|function|if|in|new|return|"
31+
"this|typeof|var|void|while|with|case|catch|class|const|"
32+
"debugger|default|do|enum|export|extends|finally|import|super|"
33+
"switch|throw|try|undefined|null|true|false|"
34+
};
2835

29-
static const char java_keywords[] =
30-
"abstract|boolean|byte|catch|class|extends|false|final|"
31-
"finally|function|implements|import|in|instanceof|"
32-
"interface|native|new|null|package|private|protected|"
33-
"public|super|synchronized|this|throw|throws|transient|"
34-
"true|try|var|with|";
35-
#endif
36+
static const char java_keywords[] = {
37+
"abstract|boolean|break|byte|case|catch|class|const|continue|"
38+
"default|do|alse|extends|false|final|finally|for|function|"
39+
"if|implements|import|in|instanceof|interface|native|new|null|"
40+
"package|private|protected|public|return|"
41+
"static|super|switch|synchronized|"
42+
"this|throw|throws|transient|true|try|var|while|with|"
43+
};
3644

37-
static const char *c_mode_keywords =
45+
static const char c_keywords[] = {
3846
"auto|break|case|const|continue|default|do|else|enum|extern|for|goto|"
3947
"if|inline|register|restrict|return|sizeof|static|struct|switch|"
40-
"typedef|union|volatile|while|";
48+
"typedef|union|volatile|while|"
49+
};
4150

4251
/* NOTE: 'var' is added for javascript */
43-
static const char *c_mode_types =
52+
static const char c_mode_types[] = {
4453
"char|double|float|int|long|unsigned|short|signed|void|var|"
45-
"_Bool|_Complex|_Imaginary|";
54+
"_Bool|_Complex|_Imaginary|"
55+
};
4656

47-
static const char c_mode_extensions[] =
57+
static const char c_mode_extensions[] = {
4858
"c|h|C|H|" /* C language */
4959
"y|l|lex|" /* yacc, lex */
5060
"cc|hh|cpp|hpp|cxx|hxx|CPP|CC|c++|" /* C++ */
5161
"m|" /* Objective-C */
52-
"e|qe|cs|idl|"
62+
"e|qe|cs|idl|st|"
5363
"jav|java|js|json|" /* Java, Javascript, JSon */
5464
"ec|ecp|" /* Informix embedded C */
5565
"pgc|" /* Postgres embedded C */
5666
"pcc|" /* Oracle C++ */
5767
"cal" /* GNU Calc */
58-
;
68+
};
5969

6070
/* grab a C identifier from a uchar buf, stripping color.
6171
* return char count.
@@ -86,19 +96,23 @@ enum {
8696
C_STRING = 4, /* double quoted string spanning multiple lines */
8797
C_STRING_Q = 8, /* single quoted string spanning multiple lines */
8898
C_PREPROCESS = 16, /* preprocessor directive with \ at EOL */
99+
C_REGEX = 32, /* regex with \ at EOL */
89100
};
90101

91-
void c_colorize_line(unsigned int *buf, int len,
102+
void c_colorize_line(unsigned int *str, int n, int mode_flags,
92103
int *colorize_state_ptr, __unused__ int state_only)
93104
{
94-
int c, state, style, style1, type_decl, klen, delim;
105+
int i = 0, j = i, indent, c, state, style, style1, type_decl, klen, delim;
95106
unsigned int *p, *p_start, *p_end, *p1, *p2;
96107
char kbuf[32];
97108

109+
for (indent = 0; qe_isspace(str[indent]); indent++)
110+
continue;
111+
98112
state = *colorize_state_ptr;
99-
p = buf;
113+
p = str;
100114
p_start = p;
101-
p_end = p + len;
115+
p_end = p + n;
102116
type_decl = 0;
103117

104118
if (p >= p_end)
@@ -119,6 +133,8 @@ void c_colorize_line(unsigned int *buf, int len,
119133
goto parse_string;
120134
if (state & C_STRING_Q)
121135
goto parse_string_q;
136+
if (state & C_REGEX)
137+
goto parse_regex;
122138
}
123139

124140
while (p < p_end) {
@@ -152,6 +168,44 @@ void c_colorize_line(unsigned int *buf, int len,
152168
set_color(p_start, p, QE_STYLE_COMMENT);
153169
goto the_end;
154170
}
171+
i = p - str - 1;
172+
if ((mode_flags & CLANG_REGEX)
173+
&& (i == indent
174+
|| (str[i + 1] != ' ' && str[i + 1] != '='
175+
&& !qe_isalnum(str[i - 1] & CHAR_MASK)
176+
&& str[i - 1] != ')'))) {
177+
/* XXX: should use mode context to tell regex from divide */
178+
/* parse regex */
179+
j = i + 1;
180+
state = C_REGEX;
181+
parse_regex:
182+
while (j < n) {
183+
/* XXX: should ignore / inside char classes */
184+
c = str[j++];
185+
if (c == '\\') {
186+
if (j < n) {
187+
j += 1;
188+
}
189+
} else
190+
if (c == '#' && str[j] == '{') {
191+
/* should parse full syntax */
192+
while (j < n && str[j++] != '}')
193+
continue;
194+
} else
195+
if (c == '/') {
196+
while (qe_findchar("ensuimox", str[j])) {
197+
j++;
198+
}
199+
state = 0;
200+
break;
201+
}
202+
}
203+
#define QE_STYLE_REGEX QE_STYLE_STRING_Q
204+
SET_COLOR(str, i, j, QE_STYLE_REGEX);
205+
i = j;
206+
p = str + i;
207+
continue;
208+
}
155209
break;
156210
case '#': /* preprocessor */
157211
state = C_PREPROCESS;
@@ -231,7 +285,11 @@ void c_colorize_line(unsigned int *buf, int len,
231285
} while (qe_isalnum_(c));
232286
kbuf[klen] = '\0';
233287

234-
if (strfind(c_mode_keywords, kbuf)) {
288+
if (((mode_flags & (CLANG_C|CLANG_CPP|CLANG_OBJC)) && strfind(c_keywords, kbuf))
289+
|| ((mode_flags & CLANG_CPP) && strfind(cc_keywords, kbuf))
290+
|| ((mode_flags & CLANG_JS) && strfind(js_keywords, kbuf))
291+
|| ((mode_flags & CLANG_JAVA) && strfind(java_keywords, kbuf))
292+
) {
235293
set_color(p_start, p, QE_STYLE_KEYWORD);
236294
continue;
237295
}
@@ -254,18 +312,18 @@ void c_colorize_line(unsigned int *buf, int len,
254312
continue;
255313
}
256314

257-
if (*p == '(') {
315+
if (*p == '(' || (p[0] == ' ' && p[1] == '(')) {
258316
/* function call */
259317
/* XXX: different styles for call and definition */
260318
set_color(p_start, p, QE_STYLE_FUNCTION);
261319
continue;
262320
}
263321
/* assume typedef if starting at first column */
264-
if (p_start == buf)
322+
if (p_start == str)
265323
type_decl = 1;
266324

267325
if (type_decl) {
268-
if (p_start == buf) {
326+
if (p_start == str) {
269327
/* assume type if first column */
270328
set_color(p_start, p, QE_STYLE_TYPE);
271329
} else {
@@ -280,7 +338,7 @@ void c_colorize_line(unsigned int *buf, int len,
280338
}
281339
the_end:
282340
/* strip state if not overflowing from a comment */
283-
if (!(state & C_COMMENT) && p > buf && ((p[-1] & CHAR_MASK) != '\\'))
341+
if (!(state & C_COMMENT) && p > str && ((p[-1] & CHAR_MASK) != '\\'))
284342
state &= ~(C_COMMENT1 | C_PREPROCESS);
285343
*colorize_state_ptr = state;
286344
}
@@ -793,6 +851,45 @@ static int c_mode_probe(ModeDef *mode, ModeProbeData *p)
793851
return 1;
794852
}
795853

854+
static int c_mode_init(EditState *s, ModeSavedData *saved_data)
855+
{
856+
text_mode.mode_init(s, saved_data);
857+
858+
/* Select C like flavor */
859+
if (match_extension(s->b->filename, "c|h|C|H")) {
860+
s->mode_flags = CLANG_C;
861+
} else
862+
if (match_extension(s->b->filename, "cc|hh|cpp|hpp|cxx|hxx|CPP|CC|c++")) {
863+
s->mode_name = "CPP";
864+
s->mode_flags = CLANG_CPP;
865+
} else
866+
if (match_extension(s->b->filename, "m")) {
867+
s->mode_name = "ObjC";
868+
s->mode_flags = CLANG_OBJC;
869+
} else
870+
if (match_extension(s->b->filename, "js|json")) {
871+
s->mode_name = "Javascript";
872+
s->mode_flags = CLANG_JS | CLANG_REGEX;
873+
} else
874+
if (match_extension(s->b->filename, "st")) {
875+
s->mode_name = "Syntax";
876+
s->mode_flags = CLANG_C | CLANG_REGEX;
877+
} else
878+
if (match_extension(s->b->filename, "jav|java")) {
879+
s->mode_name = "Java";
880+
s->mode_flags = CLANG_JAVA;
881+
} else
882+
if (match_extension(s->b->filename, "l|lex")) {
883+
s->mode_name = "Lex";
884+
s->mode_flags = CLANG_C | CLANG_LEX;
885+
} else
886+
if (match_extension(s->b->filename, "y")) {
887+
s->mode_name = "Yacc";
888+
s->mode_flags = CLANG_C | CLANG_YACC;
889+
}
890+
return 0;
891+
}
892+
796893
/* C mode specific commands */
797894
static CmdDef c_commands[] = {
798895
CMD2( KEY_CTRL('i'), KEY_NONE,
@@ -822,6 +919,7 @@ static int c_init(void)
822919
c_mode.name = "C";
823920
c_mode.extensions = c_mode_extensions;
824921
c_mode.mode_probe = c_mode_probe;
922+
c_mode.mode_init = c_mode_init;
825923
c_mode.colorize_func = c_colorize_line;
826924
c_mode.indent_func = c_indent_line;
827925

extra-modes.c

+23-20
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ enum {
7979
ASM_IDENTIFIER = QE_STYLE_VARIABLE,
8080
};
8181

82-
static void asm_colorize_line(unsigned int *str, int n, int *statep,
83-
__unused__ int state_only)
82+
static void asm_colorize_line(unsigned int *str, int n, int mode_flags,
83+
int *statep, __unused__ int state_only)
8484
{
8585
int i = 0, j, w;
8686
int wn = 0; /* word number on line */
@@ -246,8 +246,8 @@ enum {
246246
BASIC_IDENTIFIER = QE_STYLE_VARIABLE,
247247
};
248248

249-
static void basic_colorize_line(unsigned int *str, int n, int *statep,
250-
__unused__ int state_only)
249+
static void basic_colorize_line(unsigned int *str, int n, int mode_flags,
250+
int *statep, __unused__ int state_only)
251251
{
252252
int i = 0, j;
253253

@@ -367,8 +367,8 @@ enum {
367367
PAS_FUNCTION = QE_STYLE_FUNCTION,
368368
};
369369

370-
static void pascal_colorize_line(unsigned int *str, int n, int *statep,
371-
__unused__ int state_only)
370+
static void pascal_colorize_line(unsigned int *str, int n, int mode_flags,
371+
int *statep, __unused__ int state_only)
372372
{
373373
int i = 0, j = i, k;
374374
int colstate = *statep;
@@ -545,8 +545,8 @@ enum {
545545
INI_PREPROCESS = QE_STYLE_PREPROCESS,
546546
};
547547

548-
static void ini_colorize_line(unsigned int *str, int n, int *statep,
549-
__unused__ int state_only)
548+
static void ini_colorize_line(unsigned int *str, int n, int mode_flags,
549+
int *statep, __unused__ int state_only)
550550
{
551551
int i = 0, j;
552552
int bol = 1;
@@ -694,8 +694,8 @@ enum {
694694
#define ispssep(c) (qe_findchar(" \t\r\n,()<>[]{}/", c))
695695
#define wrap 0
696696

697-
static void ps_colorize_line(unsigned int *str, int n, int *statep,
698-
__unused__ int state_only)
697+
static void ps_colorize_line(unsigned int *str, int n, int mode_flags,
698+
int *statep, __unused__ int state_only)
699699
{
700700
int i = 0, j;
701701
int colstate = *statep;
@@ -783,6 +783,9 @@ static int ps_mode_probe(ModeDef *mode, ModeProbeData *p)
783783
if (match_extension(p->filename, mode->extensions))
784784
return 80;
785785

786+
if (*p->buf == '%' && qe_stristr((const char *)p->buf, "script"))
787+
return 40;
788+
786789
return 1;
787790
}
788791

@@ -819,8 +822,8 @@ enum {
819822
SQL_PREPROCESS = QE_STYLE_PREPROCESS,
820823
};
821824

822-
static void sql_colorize_line(unsigned int *str, int n, int *statep,
823-
__unused__ int state_only)
825+
static void sql_colorize_line(unsigned int *str, int n, int mode_flags,
826+
int *statep, __unused__ int state_only)
824827
{
825828
int i = 0, j = i;
826829
int state = *statep;
@@ -963,8 +966,8 @@ static int lua_long_bracket(unsigned int *str, int *level)
963966
}
964967
}
965968

966-
void lua_colorize_line(unsigned int *str, int n, int *statep,
967-
__unused__ int state_only)
969+
void lua_colorize_line(unsigned int *str, int n, int mode_flags,
970+
int *statep, __unused__ int state_only)
968971
{
969972
int i = 0, j = i, c, sep = 0, level = 0, level1, klen, style;
970973
int state = *statep;
@@ -1152,8 +1155,8 @@ static inline int haskell_is_symbol(int c)
11521155
return qe_findchar("!#$%&+./<=>?@\\^|-~:", c);
11531156
}
11541157

1155-
void haskell_colorize_line(unsigned int *str, int n, int *statep,
1156-
__unused__ int state_only)
1158+
void haskell_colorize_line(unsigned int *str, int n, int mode_flags,
1159+
int *statep, __unused__ int state_only)
11571160
{
11581161
int i = 0, j = i, c, sep = 0, level = 0, klen;
11591162
int state = *statep;
@@ -1386,8 +1389,8 @@ enum {
13861389
PYTHON_FUNCTION = QE_STYLE_FUNCTION,
13871390
};
13881391

1389-
void python_colorize_line(unsigned int *str, int n, int *statep,
1390-
__unused__ int state_only)
1392+
void python_colorize_line(unsigned int *str, int n, int mode_flags,
1393+
int *statep, __unused__ int state_only)
13911394
{
13921395
int i = 0, j = i, c, sep = 0, klen;
13931396
int state = *statep;
@@ -1672,8 +1675,8 @@ static int ruby_get_name(char *buf, int size, unsigned int *str)
16721675
return j - i;
16731676
}
16741677

1675-
void ruby_colorize_line(unsigned int *str, int n, int *statep,
1676-
__unused__ int state_only)
1678+
void ruby_colorize_line(unsigned int *str, int n, int mode_flags,
1679+
int *statep, __unused__ int state_only)
16771680
{
16781681
int i = 0, j = i, c, indent, sig;
16791682
static int sep, sep0, level; /* XXX: ugly patch */

htmlsrc.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ enum {
6666
HTML_SCRIPT = 0x80, /* <SCRIPT> [...] </SCRIPT> */
6767
};
6868

69-
void htmlsrc_colorize_line(unsigned int *buf, int len,
69+
void htmlsrc_colorize_line(unsigned int *buf, int len, int mode_flags,
7070
int *colorize_state_ptr, int state_only)
7171
{
7272
int c, state, js_state, l;
@@ -107,7 +107,8 @@ void htmlsrc_colorize_line(unsigned int *buf, int len,
107107
c = *p; /* save char to set '\0' delimiter */
108108
*p = '\0';
109109
/* XXX: should have javascript specific colorize_func */
110-
c_colorize_line(p_start, p - p_start, &js_state, state_only);
110+
c_colorize_line(p_start, p - p_start, CLANG_JS | CLANG_REGEX,
111+
&js_state, state_only);
111112
*p = c;
112113
state = js_state | HTML_SCRIPT;
113114
if (p < p_end) {

0 commit comments

Comments
 (0)