"git@gitlab.caltech.edu:cs24-19fa/git_rec_nano.git" did not exist on "cb776fad88417dadc472ce5eef5c010f7cf78137"
Commit 08893e08 authored by Chris Allegretta's avatar Chris Allegretta
Browse files

Preliminary syntax highlighting support. New functions colortoint() and...

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
parent feebeb90
Showing with 339 additions and 9 deletions
+339 -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
......
......@@ -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);
......
......@@ -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)
......
......@@ -2871,12 +2871,14 @@ int main(int argc, char *argv[])
fprintf(stderr, _("Main: set up windows\n"));
#endif
window_init();
mouse_init();
#ifdef ENABLE_COLOR
do_colorinit();
#endif /* ENABLE_COLOR */
window_init();
mouse_init();
fprintf(stderr, "COLORS = %d, COLOR_PAIRS = %d\n", COLORS, COLOR_PAIRS);
#endif /* ENABLE_COLOR */
#ifdef DEBUG
fprintf(stderr, _("Main: bottom win\n"));
......
......@@ -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,\}\/$ \/\/.*
......@@ -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
......@@ -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;
......
......@@ -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
}
/*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment