Preliminary syntax highlighting support. New functions colortoint() and parse_color() in rcfile.c, new code in edit_add() in winio.c to actually do the highlighting. It's not even close to pretty yet :P
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@910 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
feebeb90ea
commit
08893e08e3
|
@ -1,4 +1,9 @@
|
|||
CVS Code -
|
||||
- General
|
||||
- Preliminary syntax highlighting support. New functions
|
||||
colortoint() and parse_color() in rcfile.c, new code in
|
||||
edit_add() in winio.c to actually do the highlighting. It's
|
||||
not even close to pretty yet :P
|
||||
- files.c:
|
||||
add_open_file()
|
||||
- Get rid of unsetting MARK_ISSET because otherwise writing
|
||||
|
|
62
color.c
62
color.c
|
@ -98,14 +98,70 @@ void colorinit_one(int colortoset, short fg, short bg, int bold)
|
|||
|
||||
int do_colorinit(void)
|
||||
{
|
||||
int i, fg, bg;
|
||||
colortype *tmpcolor = NULL;
|
||||
colorstr *tmpstr = NULL;
|
||||
int defok = 0;
|
||||
|
||||
if (has_colors()) {
|
||||
start_color();
|
||||
/* Add in colors, if available */
|
||||
|
||||
#ifdef HAVE_USE_DEFAULT_COLORS
|
||||
/* Use if at all possible for transparent terminals =-) */
|
||||
use_default_colors();
|
||||
if (use_default_colors() != ERR) {
|
||||
defok = 1;
|
||||
#endif
|
||||
/* Some defaults values to play with */
|
||||
|
||||
i = 1;
|
||||
for (tmpcolor = colorstrings; tmpcolor != NULL;
|
||||
tmpcolor = tmpcolor->next) {
|
||||
|
||||
if (tmpcolor->fg > 8)
|
||||
fg = tmpcolor->fg - 8;
|
||||
else
|
||||
fg = tmpcolor->fg;
|
||||
|
||||
if (tmpcolor->bg > 8)
|
||||
bg = tmpcolor->bg - 8;
|
||||
else
|
||||
bg = tmpcolor->bg;
|
||||
|
||||
if (defok && bg == -1)
|
||||
init_pair(i, fg, -1);
|
||||
else if (bg == -1)
|
||||
init_pair(i, fg, COLOR_BLACK);
|
||||
else /* They picked a fg and bg color */
|
||||
init_pair(i, fg, bg);
|
||||
|
||||
fprintf(stderr, "Running init_pair with fg = %d and bg = %d\n", fg, bg);
|
||||
|
||||
tmpcolor->pairnum = i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (use_default_colors() != ERR) {
|
||||
init_pair(COLOR_BLACK, -1, -1);
|
||||
init_pair(COLOR_GREEN, COLOR_GREEN, -1);
|
||||
init_pair(COLOR_WHITE, COLOR_WHITE, -1);
|
||||
init_pair(COLOR_RED, COLOR_RED, -1);
|
||||
init_pair(COLOR_CYAN, COLOR_CYAN, -1);
|
||||
init_pair(COLOR_MAGENTA, COLOR_MAGENTA, -1);
|
||||
init_pair(COLOR_BLUE, COLOR_BLUE, -1);
|
||||
init_pair(COLOR_YELLOW, COLOR_YELLOW, -1);
|
||||
|
||||
} else {
|
||||
init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
|
||||
init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
|
||||
init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
|
||||
init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
|
||||
init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
|
||||
init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
|
||||
init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
|
||||
}
|
||||
*/
|
||||
|
||||
/* Okay I'll be nice and comment these out for the commit =)
|
||||
colorinit_one(COLOR_TITLEBAR, COLOR_GREEN, COLOR_BLUE, 1);
|
||||
|
|
1
global.c
1
global.c
|
@ -100,6 +100,7 @@ shortcut browser_list[BROWSER_LIST_LEN];
|
|||
|
||||
#ifdef ENABLE_COLOR
|
||||
colorstruct colors[NUM_NCOLORS];
|
||||
colortype *colorstrings = NULL;
|
||||
#endif
|
||||
|
||||
#if !defined(DISABLE_BROWSER) || !defined(DISABLE_MOUSE) || !defined (DISABLE_HELP)
|
||||
|
|
10
nano.c
10
nano.c
|
@ -2871,13 +2871,15 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, _("Main: set up windows\n"));
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
do_colorinit();
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
window_init();
|
||||
mouse_init();
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
do_colorinit();
|
||||
|
||||
fprintf(stderr, "COLORS = %d, COLOR_PAIRS = %d\n", COLORS, COLOR_PAIRS);
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, _("Main: bottom win\n"));
|
||||
#endif
|
||||
|
|
20
nano.h
20
nano.h
|
@ -117,6 +117,26 @@ typedef struct rcoption {
|
|||
|
||||
#endif /* ENABLE_NANORC */
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
#define COLORSTRNUM 16
|
||||
|
||||
typedef struct colorstr {
|
||||
char *val;
|
||||
struct colorstr *next;
|
||||
} colorstr;
|
||||
|
||||
typedef struct colortype {
|
||||
int fg;
|
||||
int bg;
|
||||
int pairnum;
|
||||
colorstr *str;
|
||||
struct colortype *next;
|
||||
} colortype;
|
||||
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
|
||||
/* Bitwise flags so we can save space (or more correctly, not waste it) */
|
||||
|
||||
#define MODIFIED (1<<0)
|
||||
|
|
|
@ -55,3 +55,26 @@
|
|||
# this to work
|
||||
#
|
||||
# set multibuffer
|
||||
|
||||
#
|
||||
# Color setup
|
||||
# Format: color foreground,background regex [regex...]
|
||||
#
|
||||
# Legal colors are: white, black, red, blue, green, yellow, purple, cyan
|
||||
# You may use the preefix "bright" to mean a stronger color hilight
|
||||
#
|
||||
# If your system supports transparency, not specifying a background
|
||||
# color will use a transparent color. If you don't want this, be sure
|
||||
# to set the background color to black or white.
|
||||
#
|
||||
#color brightred float\ char\ int\ void\ NULL [A-Z_]\{2,\} static
|
||||
#color brightred [\ ]struct ^struct if\ while[\ \n\(] do[\ \n\(] else[\ \n] case\ switch\ break;
|
||||
#color brightcyan #define #include #ifn*def #endif #elif #else
|
||||
|
||||
# You will in general want your comments and strings to come last, becase
|
||||
# syntax highlighting rules will be applied in the order they are read in
|
||||
|
||||
#color brightyellow <.*> ".*"
|
||||
#color brightblue /\*.**/
|
||||
# multi-line comment hack
|
||||
#color brightblue /\*.* [^\/][^\*]*\*\/ ^.*\*+*\**$ ^\ *\*\{1,\}\/$ \/\/.*
|
||||
|
|
6
proto.h
6
proto.h
|
@ -59,6 +59,10 @@ extern filestruct *cutbuffer, *mark_beginbuf;
|
|||
extern filestruct *open_files;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
colortype *colorstrings;
|
||||
#endif
|
||||
|
||||
extern shortcut *shortcut_list;
|
||||
extern shortcut main_list[MAIN_LIST_LEN], whereis_list[WHEREIS_LIST_LEN];
|
||||
extern shortcut replace_list[REPLACE_LIST_LEN], goto_list[GOTO_LIST_LEN];
|
||||
|
@ -245,3 +249,5 @@ filestruct *open_file_dup_search(int update);
|
|||
#ifndef DISABLE_HELP
|
||||
void help_init(void);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
164
rcfile.c
164
rcfile.c
|
@ -107,18 +107,171 @@ void rcfile_msg(int *errors, char *msg, ...)
|
|||
/* Parse the next word from the string. Returns NULL if we hit EOL */
|
||||
char *parse_next_word(char *ptr)
|
||||
{
|
||||
while (*ptr != ' ' && *ptr != '\n' && ptr != '\0')
|
||||
while (*ptr != ' ' && *ptr != '\t' && *ptr != '\n' && ptr != '\0')
|
||||
ptr++;
|
||||
|
||||
if (*ptr == '\0')
|
||||
if (*ptr == '\0' || *ptr == '\n')
|
||||
return NULL;
|
||||
|
||||
|
||||
/* Null terminate and advance ptr */
|
||||
*ptr++ = 0;
|
||||
|
||||
while ((*ptr == ' ' || *ptr == '\t') && *ptr != '\0')
|
||||
ptr++;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int colortoint(char *colorname, char *filename, int *lineno)
|
||||
{
|
||||
int mcolor = 0;
|
||||
|
||||
if (colorname == NULL)
|
||||
return -1;
|
||||
|
||||
if (strcasestr(colorname, "bright")) {
|
||||
mcolor += 8;
|
||||
colorname += 6;
|
||||
}
|
||||
|
||||
if (!strcasecmp(colorname, "green"))
|
||||
mcolor += COLOR_GREEN;
|
||||
else if (!strcasecmp(colorname, "red"))
|
||||
mcolor += COLOR_RED;
|
||||
else if (!strcasecmp(colorname, "blue"))
|
||||
mcolor += COLOR_BLUE;
|
||||
else if (!strcasecmp(colorname, "white"))
|
||||
mcolor += COLOR_WHITE;
|
||||
else if (!strcasecmp(colorname, "yellow"))
|
||||
mcolor += COLOR_YELLOW;
|
||||
else if (!strcasecmp(colorname, "cyan"))
|
||||
mcolor += COLOR_CYAN;
|
||||
else if (!strcasecmp(colorname, "magenta"))
|
||||
mcolor += COLOR_MAGENTA;
|
||||
else if (!strcasecmp(colorname, "black"))
|
||||
mcolor += COLOR_BLACK;
|
||||
else {
|
||||
printf("Error in %s on line %d: color %s not understood.\n",
|
||||
filename, *lineno, colorname);
|
||||
printf("Valid colors are \"green\", \"red\", \"blue\", "
|
||||
"\"white\", \"yellow\", \"cyan\", \"magenta\" and "
|
||||
"\"black\", with the optional prefix \"bright\".\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return mcolor;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
/* Parse the color stuff into the colorstrings array */
|
||||
void parse_colors(FILE *rcstream, char *filename, int *lineno, char *buf, char *ptr)
|
||||
{
|
||||
int i = 0, fg, bg;
|
||||
char prev = '\\';
|
||||
char *tmp = NULL, *beginning, *fgstr, *bgstr;
|
||||
colortype *tmpcolor = NULL;
|
||||
colorstr *tmpstr = NULL;
|
||||
|
||||
fgstr = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
printf("Error in %s on line %d: Missing color name.\n",
|
||||
filename, *lineno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strstr(fgstr, ",")) {
|
||||
strtok(fgstr, ",");
|
||||
bgstr = strtok(NULL, ",");
|
||||
} else
|
||||
bgstr = NULL;
|
||||
|
||||
fg = colortoint(fgstr, filename, lineno);
|
||||
bg = colortoint(bgstr, filename, lineno);
|
||||
|
||||
/* Now the fun part, start adding regexps to individual strings
|
||||
in the colorstrings array, woo! */
|
||||
|
||||
i = 0;
|
||||
beginning = ptr;
|
||||
while (*ptr != '\0') {
|
||||
switch (*ptr) {
|
||||
case '\n':
|
||||
*ptr = ' ';
|
||||
i++;
|
||||
case ' ':
|
||||
if (prev != '\\') {
|
||||
/* This is the end of the regex, uh I guess.
|
||||
Add it to the colorstrings array for this color */
|
||||
|
||||
tmp = NULL;
|
||||
tmp = charalloc(i + 1);
|
||||
strncpy(tmp, beginning, i);
|
||||
tmp[i] = '\0';
|
||||
|
||||
ptr = parse_next_word(ptr);
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
if (colorstrings == NULL) {
|
||||
colorstrings = nmalloc(sizeof(colortype));
|
||||
colorstrings->fg = fg;
|
||||
colorstrings->bg = bg;
|
||||
colorstrings->str = NULL;
|
||||
colorstrings->str = nmalloc(sizeof(colorstr));
|
||||
colorstrings->str->val = tmp;
|
||||
colorstrings->str->next = NULL;
|
||||
colorstrings->next = NULL;
|
||||
} else {
|
||||
for (tmpcolor = colorstrings;
|
||||
tmpcolor->next != NULL && !(tmpcolor->fg == fg
|
||||
&& tmpcolor->bg == bg); tmpcolor = tmpcolor->next)
|
||||
;
|
||||
|
||||
/* An entry for this color pair already exists, add it
|
||||
to the str list */
|
||||
if (tmpcolor->fg == fg && tmpcolor->bg == bg) {
|
||||
for (tmpstr = tmpcolor->str; tmpstr->next != NULL;
|
||||
tmpstr = tmpstr->next)
|
||||
;
|
||||
|
||||
fprintf(stderr, "Adding to existing entry for fg %d bg %d\n", fg, bg);
|
||||
|
||||
tmpstr->next = nmalloc (sizeof(colorstr));
|
||||
tmpstr->next->val = tmp;
|
||||
tmpstr->next->next = NULL;
|
||||
} else {
|
||||
|
||||
fprintf(stderr, "Adding new entry for fg %d bg %d\n", fg, bg);
|
||||
|
||||
tmpcolor->next = nmalloc(sizeof(colortype));
|
||||
tmpcolor->next->fg = fg;
|
||||
tmpcolor->next->bg = bg;
|
||||
tmpcolor->next->str = nmalloc(sizeof(colorstr));
|
||||
tmpcolor->next->str->val = tmp;
|
||||
tmpcolor->next->str->next = NULL;
|
||||
tmpcolor->next->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
beginning = ptr;
|
||||
break;
|
||||
}
|
||||
/* Else drop through to the default case */
|
||||
default:
|
||||
i++;
|
||||
prev = *ptr;
|
||||
ptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* Parse the RC file, once it has been opened successfully */
|
||||
void parse_rcfile(FILE *rcstream, char *filename)
|
||||
{
|
||||
|
@ -155,6 +308,10 @@ void parse_rcfile(FILE *rcstream, char *filename)
|
|||
set = 1;
|
||||
else if (!strcasecmp(keyword, "unset"))
|
||||
set = -1;
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (!strcasecmp(keyword, "color"))
|
||||
parse_colors(rcstream, filename, &lineno, buf, ptr);
|
||||
#endif /* ENABLE_COLOR */
|
||||
else {
|
||||
rcfile_msg(&errors, _("Error in %s on line %d: command %s not understood"),
|
||||
filename, lineno, keyword);
|
||||
|
@ -248,6 +405,7 @@ void do_rcfile(void)
|
|||
struct stat fileinfo;
|
||||
FILE *rcstream;
|
||||
|
||||
|
||||
if (getenv("HOME") == NULL)
|
||||
return;
|
||||
|
||||
|
|
59
winio.c
59
winio.c
|
@ -772,6 +772,7 @@ void add_marked_sameline(int begin, int end, filestruct * fileptr, int y,
|
|||
void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
|
||||
int virt_mark_beginx, int this_page)
|
||||
{
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
/* There are quite a few cases that could take place; we'll deal
|
||||
* with them each in turn */
|
||||
|
@ -940,6 +941,64 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
|
|||
/* Just paint the string (no mark on this line) */
|
||||
mvwaddnstr(edit, yval, 0, &fileptr->data[start],
|
||||
get_page_end_virtual(this_page) - start + 1);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
{
|
||||
colortype *tmpcolor = NULL;
|
||||
colorstr *tmpstr = NULL;
|
||||
int k, paintlen;
|
||||
|
||||
if (colorstrings != NULL)
|
||||
for (tmpcolor = colorstrings; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
|
||||
for (tmpstr = tmpcolor->str; tmpstr != NULL; tmpstr = tmpstr->next) {
|
||||
|
||||
k = start;
|
||||
regcomp(&search_regexp, tmpstr->val, 0);
|
||||
while (!regexec(&search_regexp, &fileptr->data[k], 1,
|
||||
regmatches, 0)) {
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Match! (%d chars) \"%s\"\n",
|
||||
regmatches[0].rm_eo - regmatches[0].rm_so,
|
||||
&fileptr->data[k + regmatches[0].rm_so]);
|
||||
#endif
|
||||
if (regmatches[0].rm_so < COLS - 1) {
|
||||
if (tmpcolor->fg > 8 || tmpcolor->bg > 8) {
|
||||
wattron(edit, A_BOLD);
|
||||
wattron(edit, COLOR_PAIR(tmpcolor->pairnum));
|
||||
}
|
||||
else
|
||||
wattron(edit, COLOR_PAIR(tmpcolor->pairnum));
|
||||
|
||||
if (regmatches[0].rm_eo - regmatches[0].rm_so
|
||||
+ k <= COLS)
|
||||
paintlen = regmatches[0].rm_eo - regmatches[0].rm_so;
|
||||
else
|
||||
paintlen = COLS - (regmatches[0].rm_eo
|
||||
- regmatches[0].rm_so);
|
||||
|
||||
mvwaddnstr(edit, yval, regmatches[0].rm_so + k,
|
||||
&fileptr->data[k + regmatches[0].rm_so],
|
||||
paintlen);
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (tmpcolor->fg > 8 || tmpcolor->bg > 8) {
|
||||
wattroff(edit, A_BOLD);
|
||||
wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
|
||||
}
|
||||
else
|
||||
wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
|
||||
|
||||
k += regmatches[0].rm_eo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue