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
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);
#ifdef ENABLE_COLOR
colorstruct colors[NUM_NCOLORS];
+ colortype *colorstrings = NULL;
#endif
#if !defined(DISABLE_BROWSER) || !defined(DISABLE_MOUSE) || !defined (DISABLE_HELP)
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"));
#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)
# 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,\}\/$ \/\/.*
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];
#ifndef DISABLE_HELP
void help_init(void);
#endif
+
+
/* 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)
{
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);
struct stat fileinfo;
FILE *rcstream;
+
if (getenv("HOME") == NULL)
return;
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 */
/* 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
+
}
/*