📄 syntax.c
字号:
/* check to turn off a keyword */
if (keyword) {
struct key_word *k;
k = edit->rules[context]->keyword[keyword];
if (c2 == '\n')
keyword = 0;
if ((k->first == c2 && compare_word_to_right (edit, i + 1, k->keyword, k->whole_word_chars_right, k->whole_word_chars_left, k->line_start)) || (c2 == '\n')) {
keyword = 0;
keyword_foundright = 1;
debug_printf ("keyword=%d ", keyword);
}
}
debug_printf ("border=%s ", border ? ((border & RULE_ON_RIGHT_BORDER) ? "right" : "left") : "off");
/* check to turn off a context */
if (context && !keyword) {
r = edit->rules[context];
if (r->last_left == c1 && compare_word_to_left (edit, i, r->left, r->whole_word_chars_right, r->whole_word_chars_left, r->line_start_left) \
&&!(rule & RULE_ON_LEFT_BORDER)) {
debug_printf ("A:2 ", 0);
found_left = 1;
border = RULE_ON_LEFT_BORDER;
if (r->between_delimiters)
context = 0;
} else if (!found_right) {
if (r->first_left == c2 && compare_word_to_right (edit, i + 1, r->left, r->whole_word_chars_right, r->whole_word_chars_left, r->line_start_left) \
&&(rule & RULE_ON_LEFT_BORDER)) {
/* always turn off a context at 4 */
debug_printf ("A:1 ", 0);
found_right = 1;
border = 0;
if (!keyword_foundright)
context = 0;
} else if (r->first_right == c2 && compare_word_to_right (edit, i + 1, r->right, r->whole_word_chars_right, r->whole_word_chars_left, r->line_start_right) \
&&(rule & RULE_ON_RIGHT_BORDER)) {
/* never turn off a context at 2 */
debug_printf ("A:3 ", 0);
found_right = 1;
border = 0;
}
}
}
debug_printf ("\n", 0);
/* check to turn on a keyword */
if (!keyword) {
char *p;
p = (r = edit->rules[context])->keyword_last_chars;
while ((p = strchr (p + 1, c1))) {
struct key_word *k;
int count;
count = (unsigned long) p - (unsigned long) r->keyword_last_chars;
k = r->keyword[count];
if (compare_word_to_left (edit, i, k->keyword, k->whole_word_chars_right, k->whole_word_chars_left, k->line_start)) {
keyword = count;
debug_printf ("keyword=%d ", keyword);
break;
}
}
}
/* check to turn on a context */
if (!context) {
int count;
for (count = 1; edit->rules[count] && !done; count++) {
r = edit->rules[count];
if (!found_right) {
if (r->first_left == c2 && compare_word_to_right (edit, i + 1, r->left, r->whole_word_chars_right, r->whole_word_chars_left, r->line_start_left) \
&&(rule & RULE_ON_LEFT_BORDER)) {
debug_printf ("B:1 count=%d", count);
found_right = 1;
border = 0;
context = 0;
contextchanged = 1;
keyword = 0;
} else if (r->first_right == c2 && compare_word_to_right (edit, i + 1, r->right, r->whole_word_chars_right, r->whole_word_chars_left, r->line_start_right) \
&&(rule & RULE_ON_RIGHT_BORDER)) {
if (!(c2 == '\n' && r->single_char)) {
debug_printf ("B:3 ", 0);
found_right = 1;
border = 0;
if (r->between_delimiters) {
debug_printf ("context=%d ", context);
context = resolve_left_delim (edit, i, r, count);
contextchanged = 1;
keyword = 0;
if (r->last_left == c1 && compare_word_to_left (edit, i, r->left, r->whole_word_chars_right, r->whole_word_chars_left, r->line_start_left)) {
debug_printf ("B:2 ", 0);
found_left = 1;
border = RULE_ON_LEFT_BORDER;
context = 0;
}
}
break;
}
}
}
if (!found_left) {
if (r->last_right == c1 && compare_word_to_left (edit, i, r->right, r->whole_word_chars_right, r->whole_word_chars_left, r->line_start_right)) {
if (!(c1 == '\n' && r->single_char)) {
debug_printf ("B:4 ", 0);
found_left = 1;
border = RULE_ON_RIGHT_BORDER;
if (!keyword)
if (!r->between_delimiters)
context = resolve_left_delim (edit, i - 1, r, count);
break;
}
}
}
}
}
if (!keyword && contextchanged) {
char *p;
p = (r = edit->rules[context])->keyword_last_chars;
while ((p = strchr (p + 1, c1))) {
struct key_word *k;
int coutner;
coutner = (unsigned long) p - (unsigned long) r->keyword_last_chars;
k = r->keyword[coutner];
if (compare_word_to_left (edit, i, k->keyword, k->whole_word_chars_right, k->whole_word_chars_left, k->line_start)) {
keyword = coutner;
debug_printf ("keyword=%d ", keyword);
break;
}
}
}
debug_printf ("border=%s ", border ? ((border & RULE_ON_RIGHT_BORDER) ? "right" : "left") : "off");
debug_printf ("keyword=%d ", keyword);
debug_printf (" %d#\n\n", context);
return (context << RULE_CONTEXT_SHIFT) | (keyword << RULE_WORD_SHIFT) | border;
}
static unsigned long edit_get_rule (WEdit * edit, long byte_index)
{
long i;
if (byte_index < 0) {
edit->last_get_rule = -1;
edit->rule = 0;
return 0;
}
#if 0
if (byte_index < edit->last_get_rule_start_display) {
/* this is for optimisation */
for (i = edit->last_get_rule_start_display - 1; i >= byte_index; i--)
edit->rule_start_display = apply_rules_going_left (edit, i, edit->rule_start_display);
edit->last_get_rule_start_display = byte_index;
edit->rule = edit->rule_start_display;
} else
#endif
if (byte_index > edit->last_get_rule) {
for (i = edit->last_get_rule + 1; i <= byte_index; i++)
edit->rule = apply_rules_going_right (edit, i, edit->rule);
} else if (byte_index < edit->last_get_rule) {
for (i = edit->last_get_rule - 1; i >= byte_index; i--)
edit->rule = apply_rules_going_left (edit, i, edit->rule);
}
edit->last_get_rule = byte_index;
return edit->rule;
}
static void translate_rule_to_color (WEdit * edit, unsigned long rule, int *fg, int *bg)
{
struct key_word *k;
k = edit->rules[(rule & RULE_CONTEXT) >> RULE_CONTEXT_SHIFT]->keyword[(rule & RULE_WORD) >> RULE_WORD_SHIFT];
*bg = k->bg;
*fg = k->fg;
}
void edit_get_syntax_color (WEdit * edit, long byte_index, int *fg, int *bg)
{
unsigned long rule;
if (!edit->rules || byte_index >= edit->last_byte || !option_syntax_highlighting) {
#ifdef MIDNIGHT
*fg = NORMAL_COLOR;
#else
*fg = NO_COLOR;
*bg = NO_COLOR;
#endif
} else {
rule = edit_get_rule (edit, byte_index);
translate_rule_to_color (edit, rule, fg, bg);
}
}
/*
Returns 0 on error/eof or a count of the number of bytes read
including the newline. Result must be free'd.
*/
static int read_one_line (char **line, FILE * f)
{
char *p;
int len = 256, c, r = 0, i = 0;
p = syntax_malloc (len);
for (;;) {
c = fgetc (f);
if (c == -1) {
r = 0;
break;
} else if (c == '\n') {
r = i + 1; /* extra 1 for the newline just read */
break;
} else {
if (i >= len - 1) {
char *q;
q = syntax_malloc (len * 2);
memcpy (q, p, len);
syntax_free (p);
p = q;
len *= 2;
}
p[i++] = c;
}
}
p[i] = 0;
*line = p;
return r;
}
static char *strdup_convert (char *s)
{
#if 0
int e = 0;
#endif
char *r, *p;
p = r = strdup (s);
while (*s) {
switch (*s) {
case '\\':
s++;
switch (*s) {
case 'n':
*p = '\n';
break;
case 'r':
*p = '\r';
break;
case 't':
*p = '\t';
break;
case 's':
*p = ' ';
break;
case '*':
*p = '*';
break;
case '\\':
*p = '\\';
break;
case '[':
case ']':
if ((unsigned long) p == (unsigned long) r || strlen (s) == 1)
*p = *s;
else {
#if 0
if (!strncmp (s, "[^", 2)) {
*p = '\004';
e = 1;
s++;
} else {
if (e)
*p = '\004';
else
#endif
*p = '\003';
#if 0
e = 0;
}
#endif
}
break;
default:
*p = *s;
break;
}
break;
case '*':
/* a * or + at the beginning or end of the line must be interpreted literally */
if ((unsigned long) p == (unsigned long) r || strlen (s) == 1)
*p = '*';
else
*p = '\001';
break;
case '+':
if ((unsigned long) p == (unsigned long) r || strlen (s) == 1)
*p = '+';
else
*p = '\002';
break;
default:
*p = *s;
break;
}
s++;
p++;
}
*p = 0;
return r;
}
#define whiteness(x) ((x) == '\t' || (x) == '\n' || (x) == ' ')
static void get_args (char *l, char **args, int *argc)
{
*argc = 0;
l--;
for (;;) {
char *p;
for (p = l + 1; *p && whiteness (*p); p++);
if (!*p)
break;
for (l = p + 1; *l && !whiteness (*l); l++);
*l = '\0';
*args = strdup_convert (p);
(*argc)++;
args++;
}
*args = 0;
}
static void free_args (char **args)
{
while (*args) {
syntax_free (*args);
*args = 0;
args++;
}
}
#define check_a {if(!*a){result=line;break;}}
#define check_not_a {if(*a){result=line;break;}}
#ifdef MIDNIGHT
int try_alloc_color_pair (char *fg, char *bg);
int this_try_alloc_color_pair (char *fg, char *bg)
{
char f[80], b[80], *p;
if (fg) {
strcpy (f, fg);
p = strchr (f, '/');
if (p)
*p = '\0';
fg = f;
}
if (bg) {
strcpy (b, bg);
p = strchr (b, '/');
if (p)
*p = '\0';
bg = b;
}
return try_alloc_color_pair (fg, bg);
}
#else
int this_allocate_color (char *fg)
{
char *p;
if (!fg)
return allocate_color (0);
p = strchr (fg, '/');
if (!p)
return allocate_color (fg);
return allocate_color (p + 1);
}
#endif
/* returns line number on error */
static int edit_read_syntax_rules (WEdit * edit, FILE * f)
{
char *fg, *bg;
char whole_right[256];
char whole_left[256];
char *args[1024], *l = 0;
int line = 0;
struct context_rule **r, *c;
int num_words = -1, num_contexts = -1;
int argc, result = 0;
int i, j;
args[0] = 0;
strcpy (whole_left, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
strcpy (whole_right, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
r = edit->rules = syntax_malloc (256 * sizeof (struct context_rule *));
for (;;) {
char **a;
line++;
if (!read_one_line (&l, f))
break;
get_args (l, args, &argc);
a = args + 1;
if (!args[0]) {
/* do nothing */
} else if (!strcmp (args[0], "wholechars")) {
check_a;
if (!strcmp (*a, "left")) {
a++;
strcpy (whole_left, *a);
} else if (!strcmp (*a, "right")) {
a++;
strcpy (whole_right, *a);
} else {
strcpy (whole_left, *a);
strcpy (whole_right, *a);
}
a++;
check_not_a;
} else if (!strcmp (args[0], "context")) {
check_a;
if (num_contexts == -1) {
if (strcmp (*a, "default")) { /* first context is the default */
*a = 0;
check_a;
}
a++;
c = r[0] = syntax_malloc (sizeof (struct context_rule));
c->left = strdup (" ");
c->right = strdup (" ");
num_contexts = 0;
} else {
c = r[num_contexts] = syntax_malloc (sizeof (struct context_rule));
if (!strcmp (*a, "exclusive")) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -