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-d3aeb78583b8
master
Chris Allegretta 2001-11-29 02:42:27 +00:00
parent feebeb90ea
commit 08893e08e3
9 changed files with 340 additions and 10 deletions

View File

@ -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
View File

@ -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);

View File

@ -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
View File

@ -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
View File

@ -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)

View File

@ -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,\}\/$ \/\/.*

View File

@ -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
View File

@ -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
View File

@ -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
}
/*