21
21
22
22
#include "qe.h"
23
23
24
- #if 0
25
- static const char cc_keywords [] =
24
+ static const char cc_keywords [] = {
26
25
"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
+ };
28
35
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
+ };
36
44
37
- static const char * c_mode_keywords =
45
+ static const char c_keywords [] = {
38
46
"auto|break|case|const|continue|default|do|else|enum|extern|for|goto|"
39
47
"if|inline|register|restrict|return|sizeof|static|struct|switch|"
40
- "typedef|union|volatile|while|" ;
48
+ "typedef|union|volatile|while|"
49
+ };
41
50
42
51
/* NOTE: 'var' is added for javascript */
43
- static const char * c_mode_types =
52
+ static const char c_mode_types [] = {
44
53
"char|double|float|int|long|unsigned|short|signed|void|var|"
45
- "_Bool|_Complex|_Imaginary|" ;
54
+ "_Bool|_Complex|_Imaginary|"
55
+ };
46
56
47
- static const char c_mode_extensions [] =
57
+ static const char c_mode_extensions [] = {
48
58
"c|h|C|H|" /* C language */
49
59
"y|l|lex|" /* yacc, lex */
50
60
"cc|hh|cpp|hpp|cxx|hxx|CPP|CC|c++|" /* C++ */
51
61
"m|" /* Objective-C */
52
- "e|qe|cs|idl|"
62
+ "e|qe|cs|idl|st| "
53
63
"jav|java|js|json|" /* Java, Javascript, JSon */
54
64
"ec|ecp|" /* Informix embedded C */
55
65
"pgc|" /* Postgres embedded C */
56
66
"pcc|" /* Oracle C++ */
57
67
"cal" /* GNU Calc */
58
- ;
68
+ } ;
59
69
60
70
/* grab a C identifier from a uchar buf, stripping color.
61
71
* return char count.
@@ -86,19 +96,23 @@ enum {
86
96
C_STRING = 4 , /* double quoted string spanning multiple lines */
87
97
C_STRING_Q = 8 , /* single quoted string spanning multiple lines */
88
98
C_PREPROCESS = 16 , /* preprocessor directive with \ at EOL */
99
+ C_REGEX = 32 , /* regex with \ at EOL */
89
100
};
90
101
91
- void c_colorize_line (unsigned int * buf , int len ,
102
+ void c_colorize_line (unsigned int * str , int n , int mode_flags ,
92
103
int * colorize_state_ptr , __unused__ int state_only )
93
104
{
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 ;
95
106
unsigned int * p , * p_start , * p_end , * p1 , * p2 ;
96
107
char kbuf [32 ];
97
108
109
+ for (indent = 0 ; qe_isspace (str [indent ]); indent ++ )
110
+ continue ;
111
+
98
112
state = * colorize_state_ptr ;
99
- p = buf ;
113
+ p = str ;
100
114
p_start = p ;
101
- p_end = p + len ;
115
+ p_end = p + n ;
102
116
type_decl = 0 ;
103
117
104
118
if (p >= p_end )
@@ -119,6 +133,8 @@ void c_colorize_line(unsigned int *buf, int len,
119
133
goto parse_string ;
120
134
if (state & C_STRING_Q )
121
135
goto parse_string_q ;
136
+ if (state & C_REGEX )
137
+ goto parse_regex ;
122
138
}
123
139
124
140
while (p < p_end ) {
@@ -152,6 +168,44 @@ void c_colorize_line(unsigned int *buf, int len,
152
168
set_color (p_start , p , QE_STYLE_COMMENT );
153
169
goto the_end ;
154
170
}
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
+ }
155
209
break ;
156
210
case '#' : /* preprocessor */
157
211
state = C_PREPROCESS ;
@@ -231,7 +285,11 @@ void c_colorize_line(unsigned int *buf, int len,
231
285
} while (qe_isalnum_ (c ));
232
286
kbuf [klen ] = '\0' ;
233
287
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
+ ) {
235
293
set_color (p_start , p , QE_STYLE_KEYWORD );
236
294
continue ;
237
295
}
@@ -254,18 +312,18 @@ void c_colorize_line(unsigned int *buf, int len,
254
312
continue ;
255
313
}
256
314
257
- if (* p == '(' ) {
315
+ if (* p == '(' || ( p [ 0 ] == ' ' && p [ 1 ] == '(' ) ) {
258
316
/* function call */
259
317
/* XXX: different styles for call and definition */
260
318
set_color (p_start , p , QE_STYLE_FUNCTION );
261
319
continue ;
262
320
}
263
321
/* assume typedef if starting at first column */
264
- if (p_start == buf )
322
+ if (p_start == str )
265
323
type_decl = 1 ;
266
324
267
325
if (type_decl ) {
268
- if (p_start == buf ) {
326
+ if (p_start == str ) {
269
327
/* assume type if first column */
270
328
set_color (p_start , p , QE_STYLE_TYPE );
271
329
} else {
@@ -280,7 +338,7 @@ void c_colorize_line(unsigned int *buf, int len,
280
338
}
281
339
the_end :
282
340
/* 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 ) != '\\' ))
284
342
state &= ~(C_COMMENT1 | C_PREPROCESS );
285
343
* colorize_state_ptr = state ;
286
344
}
@@ -793,6 +851,45 @@ static int c_mode_probe(ModeDef *mode, ModeProbeData *p)
793
851
return 1 ;
794
852
}
795
853
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
+
796
893
/* C mode specific commands */
797
894
static CmdDef c_commands [] = {
798
895
CMD2 ( KEY_CTRL ('i' ), KEY_NONE ,
@@ -822,6 +919,7 @@ static int c_init(void)
822
919
c_mode .name = "C" ;
823
920
c_mode .extensions = c_mode_extensions ;
824
921
c_mode .mode_probe = c_mode_probe ;
922
+ c_mode .mode_init = c_mode_init ;
825
923
c_mode .colorize_func = c_colorize_line ;
826
924
c_mode .indent_func = c_indent_line ;
827
925
0 commit comments