open_nextfile_void() switch_to_next_buffer(), rename
write_marked() write_marked_file(), remove load_file(), rename
cancel_fork() cancel_command(), rename open_pipe()
- execute_command(), remove execute_command(), and remove
- resize_variables(). (DLR)
+ execute_command(), remove execute_command(), remove
+ resize_variables(), rename get_buffer() get_key_buffer(), and
+ rename get_buffer_len() get_key_buffer_len(). (DLR)
- Replace all mvwaddstr(hblank) calls with a new function that
does the same thing without the need for hblank. New function
blank_line(); changes to do_browser(), blank_titlebar(),
- Make the static pid variable used by execute_command() and
cancel_command() a pid_t instead of an int, for consistency.
(DLR)
+ - Consistently make the flags global and any variables used to
+ hold it longs. (DLR)
+ - Consistently make the fg and bg colortype struct entries and
+ any variables used to hold them shorts. Changes to
+ do_colorinit() (renamed color_init()), color_to_int() (renamed
+ color_to_short()), and parse_colors(). (DLR)
+ - Change color handling to save only the regex strings
+ constantly, and to actually compile them on an as-needed
+ basis. Also, don't bother doing complete refreshes of the
+ screen when color support is enabled if there's no regex
+ associated with the current file. Changes to update_color()
+ (renamed color_update()), thanks_for_all_the_fish(),
+ do_input(), and do_output(), (DLR)
- files.c:
open_file()
- Assert that filename isn't NULL, and don't do anything special
allow_pending_sigwinch()
- Simplify by using the "?" operator instead of an if clause.
(DLR)
- main()
- - When constant cursor position display is on, only display the
- cursor position if there are no keys waiting in the buffer.
- (DLR)
- nano.h:
- Since we only use vsnprintf() now, remove the #ifdef block for
HAVE_SNPRINTF. (DLR)
+- rcfile.c:
+ nregcomp()
+ - Return TRUE when the compilation succeeds and FALSE otherwise,
+ instead of the other way around. (DLR)
- search.c:
search_init()
- Don't blank out last_replace anymore when we get a new string,
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
+#include <assert.h>
#include "proto.h"
#ifdef ENABLE_COLOR
}
}
-void do_colorinit(void)
+void color_init(void)
{
+ assert(openfile != NULL);
+
if (has_colors()) {
- const colortype *tmpcolor = NULL;
+ const colortype *tmpcolor;
#ifdef HAVE_USE_DEFAULT_COLORS
bool defok;
#endif
start_color();
- /* Add in colors, if available. */
#ifdef HAVE_USE_DEFAULT_COLORS
+ /* Add in colors, if available. */
defok = (use_default_colors() != ERR);
#endif
- for (tmpcolor = colorstrings; tmpcolor != NULL;
+ for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
tmpcolor = tmpcolor->next) {
short background = tmpcolor->bg;
- if (background == -1)
+ if (background == -1) {
#ifdef HAVE_USE_DEFAULT_COLORS
if (!defok)
#endif
background = COLOR_BLACK;
+ }
init_pair(tmpcolor->pairnum, tmpcolor->fg, background);
#ifdef DEBUG
- fprintf(stderr, "init_pair(): fg = %d, bg = %d\n",
+ fprintf(stderr, "init_pair(): fg = %hd, bg = %hd\n",
tmpcolor->fg, tmpcolor->bg);
#endif
}
}
/* Update the color information based on the current filename. */
-void update_color(void)
+void color_update(void)
{
const syntaxtype *tmpsyntax;
+ colortype *tmpcolor;
+
+ assert(openfile != NULL);
- colorstrings = NULL;
+ openfile->colorstrings = NULL;
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
tmpsyntax = tmpsyntax->next) {
const exttype *e;
for (e = tmpsyntax->extensions; e != NULL; e = e->next) {
/* Set colorstrings if we matched the extension regex. */
if (regexec(&e->val, openfile->filename, 0, NULL, 0) == 0)
- colorstrings = tmpsyntax->color;
+ openfile->colorstrings = tmpsyntax->color;
- if (colorstrings != NULL)
+ if (openfile->colorstrings != NULL)
break;
}
}
/* If we haven't found a match, use the override string. */
- if (colorstrings == NULL && syntaxstr != NULL) {
+ if (openfile->colorstrings == NULL && syntaxstr != NULL) {
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
tmpsyntax = tmpsyntax->next) {
- if (mbstrcasecmp(tmpsyntax->desc, syntaxstr) == 0)
- colorstrings = tmpsyntax->color;
+ if (mbstrcasecmp(tmpsyntax->desc, syntaxstr) == 0) {
+ openfile->colorstrings = tmpsyntax->color;
+
+ if (openfile->colorstrings != NULL)
+ break;
+ }
+ }
+ }
+
+ /* tmpcolor->startstr and tmpcolor->endstr have already been checked
+ * for validity elsewhere. Compile their associated regexes if we
+ * haven't already. */
+ for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
+ tmpcolor = tmpcolor->next) {
+ if (tmpcolor->startstr != NULL) {
+ tmpcolor->start = (regex_t *)nmalloc(sizeof(regex_t));
+ nregcomp(tmpcolor->start, tmpcolor->startstr,
+ tmpcolor->icase ? REG_ICASE : 0);
+ }
+ if (tmpcolor->endstr != NULL) {
+ tmpcolor->end = (regex_t *)nmalloc(sizeof(regex_t));
+ nregcomp(tmpcolor->end, tmpcolor->endstr,
+ tmpcolor->icase ? REG_ICASE : 0);
}
}
- do_colorinit();
+
+ color_init();
}
#endif /* ENABLE_COLOR */
memset(&openfile->originalfilestat, 0, sizeof(struct stat));
#endif
+#ifndef ENABLE_COLOR
+ openfile->colorstrings = NULL;
+#endif
}
#ifndef DISABLE_SPELLER
}
#endif
-/* filename is a file to open. We make a new buffer, if necessary, and
- * then open and read the file. */
+/* If it's not "", filename is a file to open. We make a new buffer, if
+ * necessary, and then open and read the file, if applicable. */
void open_buffer(const char *filename)
{
bool new_buffer = (openfile == NULL
* to the first line of the buffer. */
if (rc != -1 && new_buffer)
openfile->current = openfile->fileage;
+
+#ifdef ENABLE_COLOR
+ /* If we're loading into a new buffer, update the buffer's
+ * associated colors, if applicable. */
+ if (new_buffer)
+ color_update();
+#endif
}
/* Update the screen to account for the current buffer. */
void display_buffer(void)
{
titlebar(NULL);
-#ifdef ENABLE_COLOR
- /* Update the buffer's associated colors, if applicable. */
- update_color();
-#endif
edit_refresh();
}
openfile->filename = mallocstrcpy(openfile->filename,
realname);
#ifdef ENABLE_COLOR
- update_color();
- if (!ISSET(NO_COLOR_SYNTAX))
+ /* We might have changed the filename, so update the
+ * buffer's associated colors, if applicable. */
+ color_update();
+
+ /* If color syntaxes are available and turned on, we need to
+ * call edit_refresh(). */
+ if (openfile->colorstrings != NULL &&
+ !ISSET(NO_COLOR_SYNTAX))
edit_refresh();
#endif
}
char *last_search = NULL; /* Last string we searched for */
char *last_replace = NULL; /* Last replacement string */
-unsigned long flags = 0; /* Our flag containing many options */
+long flags = 0; /* Our flag containing many options */
WINDOW *topwin; /* Top buffer */
WINDOW *edit; /* The file portion of the editor */
WINDOW *bottomwin; /* Bottom buffer */
#endif
#ifdef ENABLE_COLOR
-const colortype *colorstrings = NULL;
syntaxtype *syntaxes = NULL;
char *syntaxstr = NULL;
#endif
colortype *bob = syntaxes->color;
syntaxes->color = bob->next;
- regfree(&bob->start);
- if (bob->end != NULL)
+ if (bob->startstr != NULL)
+ free(bob->startstr);
+ if (bob->start != NULL) {
+ regfree(bob->start);
+ free(bob->start);
+ }
+ if (bob->endstr != NULL)
+ free(bob->endstr);
+ if (bob->end != NULL) {
regfree(bob->end);
- free(bob->end);
+ free(bob->end);
+ }
free(bob);
}
syntaxes = syntaxes->next;
set_modified();
#ifdef ENABLE_COLOR
- /* If color syntaxes are turned on, we need to call
+ /* If color syntaxes are available and turned on, we need to call
* edit_refresh(). */
- if (!ISSET(NO_COLOR_SYNTAX))
+ if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX))
do_refresh = TRUE;
#endif
* display all the characters in the input buffer if it isn't
* empty. Note that it should be empty if we're in view
* mode. */
- if (*s_or_t == TRUE || get_buffer_len() == 0) {
+ if (*s_or_t == TRUE || get_key_buffer_len() == 0) {
if (kbinput != NULL) {
/* Display all the characters in the input buffer at
* once, filtering out control characters. */
#endif
#ifdef ENABLE_COLOR
- /* If color syntaxes are turned on, we need to call
- * edit_refresh(). */
- if (!ISSET(NO_COLOR_SYNTAX))
+ /* If color syntaxes are available and turned on, we need to
+ * call edit_refresh(). */
+ if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX))
do_refresh = TRUE;
#endif
}
char *alt_speller_cpy = alt_speller;
#endif
ssize_t tabsize_cpy = tabsize;
- unsigned long flags_cpy = flags;
+ long flags_cpy = flags;
#ifndef DISABLE_OPERATINGDIR
operating_dir = NULL;
/* Make sure the cursor is in the edit window. */
reset_cursor();
- /* If constant cursor position display is on, and there are no
- * keys waiting in the buffer, display the current cursor
- * position on the statusbar. */
- if (ISSET(CONST_UPDATE) && get_buffer_len() == 0)
+ /* If constant cursor position display is on, display the
+ * current cursor position on the statusbar. */
+ if (ISSET(CONST_UPDATE))
do_cursorpos(TRUE);
currshortcut = main_list;
ssize_t lineno; /* The line number. */
} filestruct;
+#ifdef ENABLE_COLOR
+typedef struct colortype {
+ short fg; /* Foreground color. */
+ short bg; /* Background color. */
+ bool bright; /* Is this color A_BOLD? */
+ bool icase; /* Is this regex string case
+ * insensitive? */
+ int pairnum; /* Color pair number used for this
+ * foreground/background. */
+ char *startstr; /* Start (or all) of the regex
+ * string. */
+ regex_t *start; /* Compiled start (or all) of the regex
+ * string. */
+ char *endstr; /* End (if any) of the regex string. */
+ regex_t *end; /* Compiled end (if any) of the regex
+ * string. */
+ struct colortype *next;
+} colortype;
+
+typedef struct exttype {
+ regex_t val; /* The extensions that match this
+ * syntax. */
+ struct exttype *next;
+} exttype;
+
+typedef struct syntaxtype {
+ char *desc; /* Name of this syntax type. */
+ exttype *extensions; /* List of extensions that this syntax
+ * applies to. */
+ colortype *color; /* Color struct for this syntax. */
+ struct syntaxtype *next;
+} syntaxtype;
+#endif /* ENABLE_COLOR */
+
typedef struct openfilestruct {
char *filename; /* Current file's name. */
filestruct *fileage; /* Current file's first line. */
file_format fmt; /* Current file's format. */
struct stat originalfilestat;
/* Current file's stat. */
+#endif
+#ifdef ENABLE_COLOR
+ colortype *colorstrings; /* Current file's associated colors. */
#endif
struct openfilestruct *next;
/* Next node. */
} rcoption;
#endif
-#ifdef ENABLE_COLOR
-typedef struct colortype {
- int fg; /* Foreground color. */
- int bg; /* Background color. */
- bool bright; /* Is this color A_BOLD? */
- int pairnum; /* Color pair number used for this
- * foreground/background. */
- regex_t start; /* Start (or all) of the regex
- * string. */
- regex_t *end; /* End (if any) of the regex string. */
- struct colortype *next;
-} colortype;
-
-typedef struct exttype {
- regex_t val; /* The extensions that match this
- * syntax. */
- struct exttype *next;
-} exttype;
-
-typedef struct syntaxtype {
- char *desc; /* Name of this syntax type. */
- exttype *extensions; /* List of extensions that this syntax
- * applies to. */
- colortype *color; /* Color struct for this syntax. */
- struct syntaxtype *next;
-} syntaxtype;
-#endif
-
/* Bitwise flags so that we can save space (or, more correctly, not
* waste it). */
#define CASE_SENSITIVE (1<<0)
extern ssize_t wrap_at;
#endif
extern int editwinrows;
-extern unsigned long flags;
+extern long flags;
extern ssize_t tabsize;
extern int currslen;
extern openfilestruct *openfile;
#ifdef ENABLE_COLOR
-extern const colortype *colorstrings;
extern syntaxtype *syntaxes;
extern char *syntaxstr;
#endif
/* Public functions in color.c. */
#ifdef ENABLE_COLOR
void set_colorpairs(void);
-void do_colorinit(void);
+void color_init(void);
void update_color(void);
#endif /* ENABLE_COLOR */
char *parse_next_word(char *ptr);
char *parse_argument(char *ptr);
#ifdef ENABLE_COLOR
-int color_to_int(const char *colorname, bool *bright);
+int color_to_short(const char *colorname, bool *bright);
char *parse_next_regex(char *ptr);
bool nregcomp(regex_t *preg, const char *regex, int eflags);
void parse_syntax(char *ptr);
#ifndef NANO_SMALL
void reset_kbinput(void);
#endif
-void get_buffer(WINDOW *win);
-size_t get_buffer_len(void);
+void get_key_buffer(WINDOW *win);
+size_t get_key_buffer_len(void);
void unget_input(int *input, size_t input_len);
void unget_kbinput(int kbinput, bool meta_key, bool func_key);
int *get_input(WINDOW *win, size_t input_len);
}
#ifdef ENABLE_COLOR
-int color_to_int(const char *colorname, bool *bright)
+int color_to_short(const char *colorname, bool *bright)
{
- int mcolor = -1;
+ short mcolor = -1;
assert(colorname != NULL && bright != NULL);
return ptr;
}
-/* Compile the regular expression regex to preg. Return FALSE on
- * success, or TRUE if the expression is invalid. */
+/* Compile the regular expression regex to preg. Return TRUE on
+ * success, or FALSE if the expression is invalid. */
bool nregcomp(regex_t *preg, const char *regex, int eflags)
{
int rc = regcomp(preg, regex, REG_EXTENDED | eflags);
free(str);
}
- return (rc != 0);
+ return (rc == 0);
}
void parse_syntax(char *ptr)
break;
newext = (exttype *)nmalloc(sizeof(exttype));
- if (nregcomp(&newext->val, fileregptr, REG_NOSUB))
+ if (!nregcomp(&newext->val, fileregptr, REG_NOSUB))
free(newext);
else {
if (endext == NULL)
* treat the color stuff as case insensitive. */
void parse_colors(char *ptr, bool icase)
{
- int fg, bg;
+ short fg, bg;
bool bright = FALSE, no_fgcolor = FALSE;
char *fgstr;
bgcolorname);
return;
}
- bg = color_to_int(bgcolorname, &bright);
+ bg = color_to_short(bgcolorname, &bright);
} else
bg = -1;
if (!no_fgcolor) {
- fg = color_to_int(fgstr, &bright);
+ fg = color_to_short(fgstr, &bright);
/* Don't try to parse screwed-up foreground colors. */
if (fg == -1)
if (ptr == NULL)
break;
- if (nregcomp(&newcolor->start, fgstr, icase ? REG_ICASE : 0)) {
- free(newcolor);
- cancelled = TRUE;
- } else {
+ newcolor->start = (regex_t *)nmalloc(sizeof(regex_t));
+ if (nregcomp(newcolor->start, fgstr, icase ? REG_ICASE : 0)) {
+ /* Free this regex, now that we know it's valid, and save
+ * the original string, so that we can recompile this regex
+ * later as needed. */
+ newcolor->startstr = mallocstrcpy(NULL, fgstr);
+ regfree(newcolor->start);
+ free(newcolor->start);
+ newcolor->start = NULL;
+
newcolor->fg = fg;
newcolor->bg = bg;
newcolor->bright = bright;
- newcolor->next = NULL;
+ newcolor->icase = icase;
+ newcolor->endstr = NULL;
newcolor->end = NULL;
+ newcolor->next = NULL;
if (endcolor == NULL) {
endsyntax->color = newcolor;
#ifdef DEBUG
- fprintf(stderr, "Starting a new colorstring for fg %d, bg %d\n", fg, bg);
+ fprintf(stderr, "Starting a new colorstring for fg %hd, bg %hd\n", fg, bg);
#endif
} else {
#ifdef DEBUG
- fprintf(stderr, "Adding new entry for fg %d, bg %d\n", fg, bg);
+ fprintf(stderr, "Adding new entry for fg %hd, bg %hd\n", fg, bg);
#endif
endcolor->next = newcolor;
}
endcolor = newcolor;
+ } else {
+ free(newcolor->start);
+ free(newcolor);
+ cancelled = TRUE;
}
if (expectend) {
newcolor->end = (regex_t *)nmalloc(sizeof(regex_t));
if (nregcomp(newcolor->end, fgstr, icase ? REG_ICASE : 0)) {
- free(newcolor->end);
- newcolor->end = NULL;
+ /* Free this regex, now that we know it's valid, and
+ * save the original string, so that we can recompile
+ * this regex later as needed. */
+ newcolor->endstr = mallocstrcpy(NULL, fgstr);
+ regfree(newcolor->end);
}
+
+ free(newcolor->end);
+ newcolor->end = NULL;
}
}
}
if (!replaceall) {
#ifdef ENABLE_COLOR
- if (!ISSET(NO_COLOR_SYNTAX))
+ /* If color syntaxes are available and turned on, we
+ * need to call edit_refresh(). */
+ if (openfile->colorstrings != NULL &&
+ !ISSET(NO_COLOR_SYNTAX))
edit_refresh();
else
#endif
/* Read in a sequence of keystrokes from win and save them in the
* default keystroke buffer. This should only be called when the
* default keystroke buffer is empty. */
-void get_buffer(WINDOW *win)
+void get_key_buffer(WINDOW *win)
{
int input;
nodelay(win, FALSE);
#ifdef DEBUG
- fprintf(stderr, "get_buffer(): key_buffer_len = %lu\n", (unsigned long)key_buffer_len);
+ fprintf(stderr, "get_key_buffer(): key_buffer_len = %lu\n", (unsigned long)key_buffer_len);
#endif
}
/* Return the length of the default keystroke buffer. */
-size_t get_buffer_len(void)
+size_t get_key_buffer_len(void)
{
return key_buffer_len;
}
if (key_buffer_len == 0) {
if (win != NULL)
- get_buffer(win);
+ get_key_buffer(win);
if (key_buffer_len == 0)
return NULL;
* waiting, we have a true escape sequence, so
* interpret it. */
escapes = 0;
- if (get_buffer_len() == 0) {
+ if (get_key_buffer_len() == 0) {
*meta_key = TRUE;
retval = tolower(*kbinput);
} else {
* sequence into its corresponding key value,
* and save that as the result. */
unget_input(kbinput, 1);
- seq_len = get_buffer_len();
+ seq_len = get_key_buffer_len();
seq = get_input(NULL, seq_len);
retval = get_escape_seq_kbinput(seq, seq_len,
&ignore_seq);
/* Get the complete sequence, and save the characters in it as the
* result. */
- *kbinput_len = get_buffer_len();
+ *kbinput_len = get_key_buffer_len();
retval = get_input(NULL, *kbinput_len);
return retval;
/* If we got a shortcut, or if there aren't any other characters
* waiting after the one we read in, we need to display all the
* characters in the input buffer if it isn't empty. */
- if (*s_or_t == TRUE || get_buffer_len() == 0) {
+ if (*s_or_t == TRUE || get_key_buffer_len() == 0) {
if (kbinput != NULL) {
/* Display all the characters in the input buffer at
* string. */
#endif
- assert(fileptr != NULL && converted != NULL);
+ assert(openfile != NULL && fileptr != NULL && converted != NULL);
assert(strlenpt(converted) <= COLS);
/* Just paint the string in any case (we'll add color or reverse on
mvwaddstr(edit, yval, 0, converted);
#ifdef ENABLE_COLOR
- if (colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
- const colortype *tmpcolor = colorstrings;
+ /* If color syntaxes are available and turned on, we need to display
+ * them. */
+ if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
+ const colortype *tmpcolor = openfile->colorstrings;
for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
int x_start;
* not to match the beginning-of-line character
* unless k is 0. If regexec() returns REG_NOMATCH,
* there are no more matches in the line. */
- if (regexec(&tmpcolor->start, &fileptr->data[k], 1,
+ if (regexec(tmpcolor->start, &fileptr->data[k], 1,
&startmatch, (k == 0) ? 0 :
REG_NOTBOL) == REG_NOMATCH)
break;
/* Where it starts in that line. */
const filestruct *end_line;
- while (start_line != NULL &&
- regexec(&tmpcolor->start, start_line->data, 1,
- &startmatch, 0) == REG_NOMATCH) {
+ while (start_line != NULL && regexec(tmpcolor->start,
+ start_line->data, 1, &startmatch,
+ 0) == REG_NOMATCH) {
/* If there is an end on this line, there is no need
* to look for starts on earlier lines. */
if (regexec(tmpcolor->end, start_line->data, 0,
/* No end found after this start. */
break;
start_col++;
- if (regexec(&tmpcolor->start, start_line->data +
+ if (regexec(tmpcolor->start, start_line->data +
start_col, 1, &startmatch,
REG_NOTBOL) == REG_NOMATCH)
/* No later start on this line. */
start_col = 0;
while (start_col < endpos) {
- if (regexec(&tmpcolor->start,
- fileptr->data + start_col, 1, &startmatch,
- (start_col == 0) ? 0 :
- REG_NOTBOL) == REG_NOMATCH ||
- start_col + startmatch.rm_so >= endpos)
+ if (regexec(tmpcolor->start, fileptr->data +
+ start_col, 1, &startmatch, (start_col == 0) ?
+ 0 : REG_NOTBOL) == REG_NOMATCH || start_col +
+ startmatch.rm_so >= endpos)
/* No more starts on this line. */
break;
/* Translate the match to be relative to the
#endif /* ENABLE_COLOR */
#ifndef NANO_SMALL
+ /* If the mark is on, we need to display it. */
if (openfile->mark_set && (fileptr->lineno <=
openfile->mark_begin->lineno || fileptr->lineno <=
openfile->current->lineno) && (fileptr->lineno >=