1 /* editor syntax highlighting.
3 Copyright (C) 1996, 1997, 1998 the Free Software Foundation
5 Authors: 1998 Paul Sheer
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 #include "edit-widget.h"
26 #include "../src/color.h" /* use_colors */
27 #include "../src/main.h" /* mc_home */
28 #include "../src/wtools.h" /* message() */
31 #define SYNTAX_MARKER_DENSITY 512
34 Mispelled words are flushed from the syntax highlighting rules
35 when they have been around longer than
36 TRANSIENT_WORD_TIME_OUT seconds. At a cursor rate of 30
37 chars per second and say 3 chars + a space per word, we can
38 accumulate 450 words absolute max with a value of 60. This is
39 below this limit of 1024 words in a context.
41 #define TRANSIENT_WORD_TIME_OUT 60
43 #define UNKNOWN_FORMAT "unknown"
45 #define MAX_WORDS_PER_CONTEXT 1024
46 #define MAX_CONTEXTS 128
48 #define RULE_ON_LEFT_BORDER 1
49 #define RULE_ON_RIGHT_BORDER 2
51 #define SYNTAX_TOKEN_STAR '\001'
52 #define SYNTAX_TOKEN_PLUS '\002'
53 #define SYNTAX_TOKEN_BRACKET '\003'
54 #define SYNTAX_TOKEN_BRACE '\004'
59 char *whole_word_chars_left
;
60 char *whole_word_chars_right
;
67 unsigned char first_left
;
69 unsigned char first_right
;
71 char line_start_right
;
72 int between_delimiters
;
73 char *whole_word_chars_left
;
74 char *whole_word_chars_right
;
75 char *keyword_first_chars
;
77 /* first word is word[1] */
78 struct key_word
**keyword
;
81 struct _syntax_marker
{
83 struct syntax_rule rule
;
84 struct _syntax_marker
*next
;
87 int option_syntax_highlighting
= 1;
89 #define syntax_g_free(x) do {if(x) {g_free(x); (x)=0;}} while (0)
92 mc_defines_destroy (gpointer key
, gpointer value
, gpointer data
)
94 char **values
= value
;
104 /* Completely destroys the defines tree */
106 destroy_defines (GTree
**defines
)
108 g_tree_traverse (*defines
, mc_defines_destroy
, G_POST_ORDER
, NULL
);
109 g_tree_destroy (*defines
);
114 subst_defines (GTree
*defines
, char **argv
, char **argv_end
)
118 while (*argv
&& argv
< argv_end
) {
119 if ((t
= g_tree_lookup (defines
, *argv
))) {
121 /* Count argv array members */
123 for (p
= &argv
[1]; *p
; p
++)
125 /* Count members of definition array */
128 p
= &argv
[count
+ argc
];
129 /* Buffer overflow or infinitive loop in define */
132 /* Move rest of argv after definition members */
134 *p
-- = argv
[argc
-- + 1];
135 /* Copy definition members to argv */
136 for (p
= argv
; *t
; *p
++ = *t
++);
143 compare_word_to_right (WEdit
*edit
, long i
, const char *text
,
144 const char *whole_left
, const char *whole_right
,
147 const unsigned char *p
, *q
;
151 c
= edit_get_byte (edit
, i
- 1);
156 if (strchr (whole_left
, c
))
158 for (p
= (unsigned char *) text
, q
= p
+ strlen ((char *) p
); p
< q
; p
++, i
++) {
160 case SYNTAX_TOKEN_STAR
:
164 c
= edit_get_byte (edit
, i
);
167 if (!strchr (whole_right
, c
))
176 case SYNTAX_TOKEN_PLUS
:
181 c
= edit_get_byte (edit
, i
);
184 if (*p
== *text
&& !p
[1]) /* handle eg '+' and @+@ keywords properly */
187 if (j
&& strchr ((char *) p
+ 1, c
)) /* c exists further down, so it will get matched later */
189 if (c
== '\n' || c
== '\t' || c
== ' ') {
200 if (!strchr (whole_right
, c
)) {
213 case SYNTAX_TOKEN_BRACKET
:
219 c
= edit_get_byte (edit
, i
);
220 for (j
= 0; p
[j
] != SYNTAX_TOKEN_BRACKET
&& p
[j
]; j
++)
225 ; /* dummy command */
228 while (*p
!= SYNTAX_TOKEN_BRACKET
&& p
<= q
)
235 case SYNTAX_TOKEN_BRACE
:
238 c
= edit_get_byte (edit
, i
);
239 for (; *p
!= SYNTAX_TOKEN_BRACE
&& *p
; p
++)
244 while (*p
!= SYNTAX_TOKEN_BRACE
&& p
< q
)
248 if (*p
!= edit_get_byte (edit
, i
))
253 if (strchr (whole_right
, edit_get_byte (edit
, i
)))
259 if (*s < '\005' || *s == (unsigned char) c) \
263 static inline char *xx_strchr (const unsigned char *s
, int c
)
266 XXX XXX XXX XXX XXX XXX XXX XXX
;
267 XXX XXX XXX XXX XXX XXX XXX XXX
;
273 static inline struct syntax_rule
apply_rules_going_right (WEdit
* edit
, long i
, struct syntax_rule rule
)
275 struct context_rule
*r
;
276 int contextchanged
= 0, c
;
277 int found_right
= 0, found_left
= 0, keyword_foundleft
= 0, keyword_foundright
= 0;
280 struct syntax_rule _rule
= rule
;
281 if (!(c
= edit_get_byte (edit
, i
)))
283 is_end
= (rule
.end
== (unsigned char) i
);
284 /* check to turn off a keyword */
286 if (edit_get_byte (edit
, i
- 1) == '\n')
290 keyword_foundleft
= 1;
293 /* check to turn off a context */
294 if (_rule
.context
&& !_rule
.keyword
) {
296 r
= edit
->rules
[_rule
.context
];
297 if (r
->first_right
== c
&& !(rule
.border
& RULE_ON_RIGHT_BORDER
) && (e
= compare_word_to_right (edit
, i
, r
->right
, r
->whole_word_chars_left
, r
->whole_word_chars_right
, r
->line_start_right
)) > 0) {
300 _rule
.border
= RULE_ON_RIGHT_BORDER
;
301 if (r
->between_delimiters
)
303 } else if (is_end
&& rule
.border
& RULE_ON_RIGHT_BORDER
) {
304 /* always turn off a context at 4 */
307 if (!keyword_foundleft
)
309 } else if (is_end
&& rule
.border
& RULE_ON_LEFT_BORDER
) {
310 /* never turn off a context at 2 */
315 /* check to turn on a keyword */
316 if (!_rule
.keyword
) {
318 p
= (r
= edit
->rules
[_rule
.context
])->keyword_first_chars
;
320 while (*(p
= xx_strchr ((unsigned char *) p
+ 1, c
))) {
324 count
= p
- r
->keyword_first_chars
;
325 k
= r
->keyword
[count
];
326 e
= compare_word_to_right (edit
, i
, k
->keyword
, k
->whole_word_chars_left
, k
->whole_word_chars_right
, k
->line_start
);
330 _rule
.keyword
= count
;
331 keyword_foundright
= 1;
336 /* check to turn on a context */
337 if (!_rule
.context
) {
338 if (!found_left
&& is_end
) {
339 if (rule
.border
& RULE_ON_RIGHT_BORDER
) {
344 } else if (rule
.border
& RULE_ON_LEFT_BORDER
) {
345 r
= edit
->rules
[_rule
._context
];
347 if (r
->between_delimiters
) {
349 _rule
.context
= _rule
._context
;
352 if (r
->first_right
== c
&& (e
= compare_word_to_right (edit
, i
, r
->right
, r
->whole_word_chars_left
, r
->whole_word_chars_right
, r
->line_start_right
)) >= end
) {
355 _rule
.border
= RULE_ON_RIGHT_BORDER
;
363 struct context_rule
**rules
= edit
->rules
;
364 for (count
= 1; rules
[count
]; count
++) {
366 if (r
->first_left
== c
) {
368 e
= compare_word_to_right (edit
, i
, r
->left
, r
->whole_word_chars_left
, r
->whole_word_chars_right
, r
->line_start_left
);
369 if (e
>= end
&& (!_rule
.keyword
|| keyword_foundright
)) {
372 _rule
.border
= RULE_ON_LEFT_BORDER
;
373 _rule
._context
= count
;
374 if (!r
->between_delimiters
)
375 if (!_rule
.keyword
) {
376 _rule
.context
= count
;
385 /* check again to turn on a keyword if the context switched */
386 if (contextchanged
&& !_rule
.keyword
) {
388 p
= (r
= edit
->rules
[_rule
.context
])->keyword_first_chars
;
389 while (*(p
= xx_strchr ((unsigned char *) p
+ 1, c
))) {
393 count
= p
- r
->keyword_first_chars
;
394 k
= r
->keyword
[count
];
395 e
= compare_word_to_right (edit
, i
, k
->keyword
, k
->whole_word_chars_left
, k
->whole_word_chars_right
, k
->line_start
);
398 _rule
.keyword
= count
;
406 static struct syntax_rule
edit_get_rule (WEdit
* edit
, long byte_index
)
409 if (byte_index
> edit
->last_get_rule
) {
410 for (i
= edit
->last_get_rule
+ 1; i
<= byte_index
; i
++) {
411 edit
->rule
= apply_rules_going_right (edit
, i
, edit
->rule
);
412 if (i
> (edit
->syntax_marker
? edit
->syntax_marker
->offset
+ SYNTAX_MARKER_DENSITY
: SYNTAX_MARKER_DENSITY
)) {
413 struct _syntax_marker
*s
;
414 s
= edit
->syntax_marker
;
415 edit
->syntax_marker
= g_malloc0 (sizeof (struct _syntax_marker
));
416 edit
->syntax_marker
->next
= s
;
417 edit
->syntax_marker
->offset
= i
;
418 edit
->syntax_marker
->rule
= edit
->rule
;
421 } else if (byte_index
< edit
->last_get_rule
) {
422 struct _syntax_marker
*s
;
424 if (!edit
->syntax_marker
) {
425 memset (&edit
->rule
, 0, sizeof (edit
->rule
));
426 for (i
= -1; i
<= byte_index
; i
++)
427 edit
->rule
= apply_rules_going_right (edit
, i
, edit
->rule
);
430 if (byte_index
>= edit
->syntax_marker
->offset
) {
431 edit
->rule
= edit
->syntax_marker
->rule
;
432 for (i
= edit
->syntax_marker
->offset
+ 1; i
<= byte_index
; i
++)
433 edit
->rule
= apply_rules_going_right (edit
, i
, edit
->rule
);
436 s
= edit
->syntax_marker
->next
;
437 syntax_g_free (edit
->syntax_marker
);
438 edit
->syntax_marker
= s
;
441 edit
->last_get_rule
= byte_index
;
445 static void translate_rule_to_color (WEdit
* edit
, struct syntax_rule rule
, int *color
)
448 k
= edit
->rules
[rule
.context
]->keyword
[rule
.keyword
];
452 void edit_get_syntax_color (WEdit
* edit
, long byte_index
, int *color
)
454 if (edit
->rules
&& byte_index
< edit
->last_byte
&&
455 option_syntax_highlighting
&& use_colors
) {
456 translate_rule_to_color (edit
, edit_get_rule (edit
, byte_index
), color
);
458 *color
= use_colors
? EDITOR_NORMAL_COLOR_INDEX
: 0;
464 Returns 0 on error/eof or a count of the number of bytes read
465 including the newline. Result must be free'd.
467 static int read_one_line (char **line
, FILE * f
)
470 int len
= 256, c
, r
= 0, i
= 0;
482 } else if (c
== '\n') {
483 r
= i
+ 1; /* extra 1 for the newline just read */
488 q
= g_malloc0 (len
* 2);
502 static char *convert (char *s
)
535 *p
= SYNTAX_TOKEN_BRACKET
;
539 *p
= SYNTAX_TOKEN_BRACE
;
550 *p
= SYNTAX_TOKEN_STAR
;
553 *p
= SYNTAX_TOKEN_PLUS
;
566 #define whiteness(x) ((x) == '\t' || (x) == '\n' || (x) == ' ')
568 static void get_args (char *l
, char **args
, int *argc
)
573 while (*p
&& whiteness (*p
))
577 for (l
= p
+ 1; *l
&& !whiteness (*l
); l
++);
588 #define break_a {result=line;break;}
589 #define check_a {if(!*a){result=line;break;}}
590 #define check_not_a {if(*a){result=line;break;}}
593 this_try_alloc_color_pair (char *fg
, char *bg
)
595 char f
[80], b
[80], *p
;
603 strncpy (f
, fg
, sizeof (f
) - 1);
604 f
[sizeof (f
) - 1] = 0;
611 strncpy (b
, bg
, sizeof (b
) - 1);
612 b
[sizeof (b
) - 1] = 0;
618 return try_alloc_color_pair (fg
, bg
);
621 static char *error_file_name
= 0;
623 static FILE *open_include_file (const char *filename
)
627 syntax_g_free (error_file_name
);
628 error_file_name
= g_strdup (filename
);
629 if (*filename
== PATH_SEP
)
630 return fopen (filename
, "r");
632 g_free (error_file_name
);
633 error_file_name
= g_strconcat (home_dir
, EDIT_DIR PATH_SEP_STR
,
635 f
= fopen (error_file_name
, "r");
639 g_free (error_file_name
);
640 error_file_name
= g_strconcat (mc_home
, PATH_SEP_STR
"syntax" PATH_SEP_STR
,
642 return fopen (error_file_name
, "r");
645 /* returns line number on error */
647 edit_read_syntax_rules (WEdit
*edit
, FILE *f
, char **args
)
651 char last_fg
[32] = "", last_bg
[32] = "";
652 char whole_right
[512];
653 char whole_left
[512];
655 int save_line
= 0, line
= 0;
656 struct context_rule
**r
, *c
= 0;
657 int num_words
= -1, num_contexts
= -1;
658 int argc
, result
= 0;
663 strcpy (whole_left
, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
664 strcpy (whole_right
, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
666 r
= edit
->rules
= g_malloc0 (MAX_CONTEXTS
* sizeof (struct context_rule
*));
669 edit
->defines
= g_tree_new ((GCompareFunc
) strcmp
);
675 if (!read_one_line (&l
, f
)) {
680 line
= save_line
+ 1;
681 syntax_g_free (error_file_name
);
684 if (!read_one_line (&l
, f
))
690 get_args (l
, args
, &argc
);
694 } else if (!strcmp (args
[0], "include")) {
695 if (g
|| argc
!= 2) {
700 f
= open_include_file (args
[1]);
702 syntax_g_free (error_file_name
);
708 } else if (!strcmp (args
[0], "wholechars")) {
710 if (!strcmp (*a
, "left")) {
712 strncpy (whole_left
, *a
, sizeof (whole_left
) - 1);
713 whole_left
[sizeof (whole_left
) - 1] = 0;
714 } else if (!strcmp (*a
, "right")) {
716 strncpy (whole_right
, *a
, sizeof (whole_right
) - 1);
717 whole_right
[sizeof (whole_right
) - 1] = 0;
719 strncpy (whole_left
, *a
, sizeof (whole_left
) - 1);
720 whole_left
[sizeof (whole_left
) - 1] = 0;
721 strncpy (whole_right
, *a
, sizeof (whole_right
) - 1);
722 whole_right
[sizeof (whole_right
) - 1] = 0;
726 } else if (!strcmp (args
[0], "context")) {
728 if (num_contexts
== -1) {
729 if (strcmp (*a
, "default")) { /* first context is the default */
733 c
= r
[0] = g_malloc0 (sizeof (struct context_rule
));
734 c
->left
= g_strdup (" ");
735 c
->right
= g_strdup (" ");
738 c
= r
[num_contexts
] = g_malloc0 (sizeof (struct context_rule
));
739 if (!strcmp (*a
, "exclusive")) {
741 c
->between_delimiters
= 1;
744 if (!strcmp (*a
, "whole")) {
746 c
->whole_word_chars_left
= g_strdup (whole_left
);
747 c
->whole_word_chars_right
= g_strdup (whole_right
);
748 } else if (!strcmp (*a
, "wholeleft")) {
750 c
->whole_word_chars_left
= g_strdup (whole_left
);
751 } else if (!strcmp (*a
, "wholeright")) {
753 c
->whole_word_chars_right
= g_strdup (whole_right
);
756 if (!strcmp (*a
, "linestart")) {
758 c
->line_start_left
= 1;
761 c
->left
= g_strdup (*a
++);
763 if (!strcmp (*a
, "linestart")) {
765 c
->line_start_right
= 1;
768 c
->right
= g_strdup (*a
++);
769 c
->first_left
= *c
->left
;
770 c
->first_right
= *c
->right
;
772 c
->keyword
= g_malloc0 (MAX_WORDS_PER_CONTEXT
* sizeof (struct key_word
*));
774 c
->max_words
= MAX_WORDS_PER_CONTEXT
;
777 c
->keyword
[0] = g_malloc0 (sizeof (struct key_word
));
778 subst_defines (edit
->defines
, a
, &args
[1024]);
785 strncpy (last_fg
, fg
? fg
: "", sizeof (last_fg
) - 1);
786 last_fg
[sizeof (last_fg
) - 1] = 0;
787 strncpy (last_bg
, bg
? bg
: "", sizeof (last_bg
) - 1);
788 last_bg
[sizeof (last_bg
) - 1] = 0;
789 c
->keyword
[0]->color
= this_try_alloc_color_pair (fg
, bg
);
790 c
->keyword
[0]->keyword
= g_strdup (" ");
793 } else if (!strcmp (args
[0], "spellcheck")) {
799 } else if (!strcmp (args
[0], "keyword")) {
804 k
= r
[num_contexts
- 1]->keyword
[num_words
] = g_malloc0 (sizeof (struct key_word
));
805 if (!strcmp (*a
, "whole")) {
807 k
->whole_word_chars_left
= g_strdup (whole_left
);
808 k
->whole_word_chars_right
= g_strdup (whole_right
);
809 } else if (!strcmp (*a
, "wholeleft")) {
811 k
->whole_word_chars_left
= g_strdup (whole_left
);
812 } else if (!strcmp (*a
, "wholeright")) {
814 k
->whole_word_chars_right
= g_strdup (whole_right
);
817 if (!strcmp (*a
, "linestart")) {
822 if (!strcmp (*a
, "whole")) {
825 k
->keyword
= g_strdup (*a
++);
826 k
->first
= *k
->keyword
;
827 subst_defines (edit
->defines
, a
, &args
[1024]);
838 k
->color
= this_try_alloc_color_pair (fg
, bg
);
841 } else if (*(args
[0]) == '#') {
842 /* do nothing for comment */
843 } else if (!strcmp (args
[0], "file")) {
845 } else if (!strcmp (args
[0], "define")) {
851 if ((argv
= g_tree_lookup (edit
->defines
, key
))) {
852 mc_defines_destroy (NULL
, argv
, NULL
);
854 key
= g_strdup (key
);
856 argv
= g_new (char *, argc
- 1);
857 g_tree_insert (edit
->defines
, key
, argv
);
859 *argv
++ = g_strdup (*a
++);
862 } else { /* anything else is an error */
872 syntax_g_free (edit
->rules
);
877 if (num_contexts
== -1) {
882 char first_chars
[MAX_WORDS_PER_CONTEXT
+ 2], *p
;
883 for (i
= 0; edit
->rules
[i
]; i
++) {
887 for (j
= 1; c
->keyword
[j
]; j
++)
888 *p
++ = c
->keyword
[j
]->first
;
890 c
->keyword_first_chars
= g_strdup (first_chars
);
897 void edit_free_syntax_rules (WEdit
* edit
)
903 destroy_defines (&edit
->defines
);
906 edit_get_rule (edit
, -1);
907 syntax_g_free (edit
->syntax_type
);
908 edit
->syntax_type
= 0;
909 for (i
= 0; edit
->rules
[i
]; i
++) {
910 if (edit
->rules
[i
]->keyword
) {
911 for (j
= 0; edit
->rules
[i
]->keyword
[j
]; j
++) {
912 syntax_g_free (edit
->rules
[i
]->keyword
[j
]->keyword
);
913 syntax_g_free (edit
->rules
[i
]->keyword
[j
]->whole_word_chars_left
);
914 syntax_g_free (edit
->rules
[i
]->keyword
[j
]->whole_word_chars_right
);
915 syntax_g_free (edit
->rules
[i
]->keyword
[j
]);
918 syntax_g_free (edit
->rules
[i
]->left
);
919 syntax_g_free (edit
->rules
[i
]->right
);
920 syntax_g_free (edit
->rules
[i
]->whole_word_chars_left
);
921 syntax_g_free (edit
->rules
[i
]->whole_word_chars_right
);
922 syntax_g_free (edit
->rules
[i
]->keyword
);
923 syntax_g_free (edit
->rules
[i
]->keyword_first_chars
);
924 syntax_g_free (edit
->rules
[i
]);
926 while (edit
->syntax_marker
) {
927 struct _syntax_marker
*s
= edit
->syntax_marker
->next
;
928 syntax_g_free (edit
->syntax_marker
);
929 edit
->syntax_marker
= s
;
931 syntax_g_free (edit
->rules
);
934 /* returns -1 on file error, line number on error in file syntax */
936 edit_read_syntax_file (WEdit
* edit
, char **names
, const char *syntax_file
,
937 const char *editor_file
, const char *first_line
,
942 regmatch_t pmatch
[1];
943 char *args
[1024], *l
= 0;
951 f
= fopen (syntax_file
, "r");
953 lib_file
= concat_dir_and_file (mc_home
, "syntax" PATH_SEP_STR
"Syntax");
954 f
= fopen (lib_file
, "r");
963 if (!read_one_line (&l
, f
))
965 get_args (l
, args
, &argc
);
968 /* Looking for `include ...` lines before first `file ...` ones */
969 if (!found
&& !strcmp (args
[0], "include")) {
972 if (!args
[1] || !(g
= open_include_file (args
[1]))) {
978 /* looking for `file ...' lines only */
979 if (strcmp (args
[0], "file")) {
983 /* must have two args or report error */
984 if (!args
[1] || !args
[2]) {
989 /* 1: just collecting a list of names of rule sets */
990 names
[count
++] = g_strdup (args
[2]);
993 /* 2: rule set was explicitly specified by the caller */
994 if (!strcmp (type
, args
[2]))
996 } else if (editor_file
&& edit
) {
997 /* 3: auto-detect rule set from regular expressions */
999 if (regcomp (&r
, args
[1], REG_EXTENDED
)) {
1003 /* does filename match arg 1 ? */
1004 q
= !regexec (&r
, editor_file
, 1, pmatch
, 0);
1006 if (!q
&& args
[3]) {
1007 if (regcomp (&r
, args
[3], REG_EXTENDED
)) {
1011 /* does first line match arg 3 ? */
1012 q
= !regexec (&r
, first_line
, 1, pmatch
, 0);
1019 syntax_type
= args
[2];
1020 line_error
= edit_read_syntax_rules (edit
, g
? g
: f
, args
);
1022 if (!error_file_name
) /* an included file */
1023 result
= line
+ line_error
;
1025 result
= line_error
;
1027 syntax_g_free (edit
->syntax_type
);
1028 edit
->syntax_type
= g_strdup (syntax_type
);
1029 /* if there are no rules then turn off syntax highlighting for speed */
1030 if (!g
&& !edit
->rules
[1])
1031 if (!edit
->rules
[0]->keyword
[1] && !edit
->rules
[0]->spelling
) {
1032 edit_free_syntax_rules (edit
);
1050 static char *get_first_editor_line (WEdit
* edit
)
1057 for (i
= 0; i
< 255; i
++) {
1058 s
[i
] = edit_get_byte (edit
, i
);
1069 * Load rules into edit struct. Either edit or names must be NULL. If
1070 * edit is NULL, a list of types will be stored into names. If type is
1071 * NULL, then the type will be selected according to the filename.
1074 edit_load_syntax (WEdit
*edit
, char **names
, char *type
)
1079 edit_free_syntax_rules (edit
);
1084 if (!option_syntax_highlighting
)
1088 if (!edit
->filename
)
1090 if (!*edit
->filename
&& !type
)
1093 f
= catstrs (home_dir
, SYNTAX_FILE
, 0);
1094 r
= edit_read_syntax_file (edit
, names
, f
, edit
? edit
->filename
: 0,
1095 get_first_editor_line (edit
), type
);
1097 edit_free_syntax_rules (edit
);
1098 message (D_ERROR
, _(" Load syntax file "),
1099 _(" Cannot open file %s \n %s "), f
,
1100 unix_error_string (errno
));
1104 edit_free_syntax_rules (edit
);
1105 message (D_ERROR
, _(" Load syntax file "),
1106 _(" Error in file %s on line %d "),
1107 error_file_name
? error_file_name
: f
, r
);
1108 syntax_g_free (error_file_name
);