Commit 6df90f57 authored by Chris Allegretta's avatar Chris Allegretta
Browse files

DLR and DB fixes mega-merge

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1235 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
parent cf2f6563
Showing with 377 additions and 575 deletions
+377 -575
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <assert.h>
#include "config.h" #include "config.h"
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
...@@ -50,75 +51,75 @@ int num_of_digits(int n) ...@@ -50,75 +51,75 @@ int num_of_digits(int n)
return i; return i;
} }
/* For non-null-terminated lines. A line, by definition, shouldn't /* Fix the memory allocation for a string. */
normally have newlines in it, so encode its nulls as newlines. */ void align(char **strp)
void unsunder(char *str, int true_len)
{ {
int i; assert(strp != NULL);
if (strlen(str) < true_len) { *strp = nrealloc(*strp, strlen(*strp) + 1);
for (i = 0; i < true_len; i++) {
if (str[i] == '\0')
str[i] = '\n';
}
}
} }
/* For non-null-terminated lines. A line, by definition, shouldn't /* Null a string at a certain index and align it. */
normally have newlines in it, so decode its newlines into nulls. */ void null_at(char **data, size_t index)
void sunder(char *str)
{ {
int i, true_len = strlen(str); assert(data != NULL);
if (strchr(str, '\n')) { *data = (char *)nrealloc(*data, sizeof(char) * (index + 1));
for (i = 0; i < true_len; i++) { (*data)[index] = '\0';
if (str[i] == '\n')
str[i] = '\0';
}
}
} }
/* Lower case a string - must be null terminated */ /* For non-null-terminated lines. A line, by definition, shouldn't
void lowercase(char *src) * normally have newlines in it, so encode its nulls as newlines. */
void unsunder(char *str, size_t true_len)
{ {
long i = 0; assert(str != NULL);
for(; true_len > 0; true_len--, str++)
if (*str == '\0')
*str = '\n';
}
while (src[i] != 0) { /* For non-null-terminated lines. A line, by definition, shouldn't
src[i] = (char) tolower(src[i]); * normally have newlines in it, so decode its newlines into nulls. */
i++; void sunder(char *str)
} {
assert(str != NULL);
for(; *str != '\0'; str++)
if (*str == '\n')
*str = '\0';
} }
/* None of this is needed if we're using NANO_SMALL! */ /* None of this is needed if we're using NANO_SMALL! */
#ifndef NANO_SMALL #ifndef NANO_SMALL
char *revstrstr(char *haystack, char *needle, char *rev_start) static const char *revstrstr(const char *haystack, const char *needle,
const char *rev_start)
{ {
char *p, *q, *r; for(; rev_start >= haystack ; rev_start--) {
const char *r, *q;
for(p = rev_start ; p >= haystack ; --p) { for (r = rev_start, q = needle ; *q == *r && *q != '\0'; r++, q++)
for (r = p, q = needle ; (*q == *r) && (*q != '\0') ; r++, q++)
; ;
if (*q == '\0') if (*q == '\0')
return p; return rev_start;
} }
return 0; return NULL;
} }
char *revstristr(char *haystack, char *needle, char *rev_start) static const char *revstristr(const char *haystack, const char *needle,
const char *rev_start)
{ {
char *p, *q, *r; for (; rev_start >= haystack; rev_start--) {
const char *r = rev_start, *q = needle;
for(p = rev_start ; p >= haystack ; --p) { for (; (tolower(*q) == tolower(*r)) && (*q != '\0') ; r++, q++)
for (r = p, q = needle ; (tolower(*q) == tolower(*r)) && (*q != '\0') ; r++, q++)
; ;
if (*q == '\0') if (*q == '\0')
return p; return rev_start;
} }
return 0; return NULL;
} }
#endif /* NANO_SMALL */ #endif /* !NANO_SMALL */
/* This is now mutt's version (called mutt_stristr) because it doesn't /* This is now mutt's version (called mutt_stristr) because it doesn't
use memory allocation to do a simple search (yuck). */ use memory allocation to do a simple search (yuck). */
char *stristr(char *haystack, char *needle) const char *stristr(const char *haystack, const char *needle)
{ {
const char *p, *q; const char *p, *q;
...@@ -128,43 +129,41 @@ char *stristr(char *haystack, char *needle) ...@@ -128,43 +129,41 @@ char *stristr(char *haystack, char *needle)
return (haystack); return (haystack);
while (*(p = haystack)) { while (*(p = haystack)) {
for (q = needle; *p && *q && tolower (*p) == tolower (*q); p++, q++) for (q = needle; *p && *q && tolower(*p) == tolower(*q); p++, q++)
; ;
if (!*q) if (!*q)
return (haystack); return haystack;
haystack++; haystack++;
} }
return NULL; return NULL;
} }
char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos) const char *strstrwrapper(const char *haystack, const char *needle,
const char *rev_start, int line_pos)
{ {
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
int result;
if (ISSET(USE_REGEXP)) { if (ISSET(USE_REGEXP)) {
if (!ISSET(REVERSE_SEARCH)) { if (!ISSET(REVERSE_SEARCH)) {
result = regexec(&search_regexp, haystack, 10, regmatches, (line_pos > 0) ? REG_NOTBOL : 0); if (!regexec(&search_regexp, haystack, 10, regmatches, (line_pos > 0) ? REG_NOTBOL : 0))
if (!result)
return haystack + regmatches[0].rm_so; return haystack + regmatches[0].rm_so;
}
#ifndef NANO_SMALL #ifndef NANO_SMALL
} else { else {
char *i, *j; const char *i, *j;
/* do a quick search forward first */ /* do a quick search forward first */
if (!(regexec(&search_regexp, haystack, 10, regmatches, 0))) { if (!regexec(&search_regexp, haystack, 10, regmatches, 0)) {
/* there's a match somewhere in the line - now search for it backwards, much slower */ /* there's a match somewhere in the line - now search for it backwards, much slower */
for (i = rev_start; i >= haystack; --i) { for (i = rev_start; i >= haystack; --i) {
if (!(result = regexec(&search_regexp, i, 10, regmatches, (i > haystack) ? REG_NOTBOL : 0))) { if (!regexec(&search_regexp, i, 10, regmatches, (i > haystack) ? REG_NOTBOL : 0)) {
j = i + regmatches[0].rm_so; j = i + regmatches[0].rm_so;
if (j <= rev_start) if (j <= rev_start)
return j; return j;
} }
} }
} }
#endif
} }
#endif
return 0; return 0;
} }
#endif #endif
...@@ -174,7 +173,6 @@ char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos) ...@@ -174,7 +173,6 @@ char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos)
return revstrstr(haystack, needle, rev_start); return revstrstr(haystack, needle, rev_start);
else else
return strstr(haystack, needle); return strstr(haystack, needle);
} else { } else {
if (ISSET(REVERSE_SEARCH)) if (ISSET(REVERSE_SEARCH))
return revstristr(haystack, needle, rev_start); return revstristr(haystack, needle, rev_start);
...@@ -188,8 +186,7 @@ char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos) ...@@ -188,8 +186,7 @@ char *strstrwrapper(char *haystack, char *needle, char *rev_start, int line_pos)
/* This is a wrapper for the perror function. The wrapper takes care of /* This is a wrapper for the perror function. The wrapper takes care of
* ncurses, calls perror (which writes to STDERR), then refreshes the * ncurses, calls perror (which writes to STDERR), then refreshes the
* screen. Note that nperror causes the window to flicker once. * screen. Note that nperror causes the window to flicker once. */
*/
void nperror(const char *s) { void nperror(const char *s) {
/* leave ncurses mode, go to the terminal */ /* leave ncurses mode, go to the terminal */
if (endwin() != ERR) { if (endwin() != ERR) {
...@@ -212,17 +209,17 @@ void *nmalloc(size_t howmuch) ...@@ -212,17 +209,17 @@ void *nmalloc(size_t howmuch)
} }
/* We're going to need this too - Hopefully this will minimize /* We're going to need this too - Hopefully this will minimize
the transition cost of moving to the apropriate function. */ the transition cost of moving to the appropriate function. */
char *charalloc(size_t howmuch) char *charalloc(size_t howmuch)
{ {
void *r; char *r;
/* Panic save? */ /* Panic save? */
if (!(r = calloc(howmuch, sizeof (char)))) if (!(r = (char *)calloc(howmuch, sizeof (char))))
die(_("nano: calloc: out of memory!")); die(_("nano: calloc: out of memory!"));
return (char *) r; return r;
} }
void *nrealloc(void *ptr, size_t howmuch) void *nrealloc(void *ptr, size_t howmuch)
...@@ -235,24 +232,18 @@ void *nrealloc(void *ptr, size_t howmuch) ...@@ -235,24 +232,18 @@ void *nrealloc(void *ptr, size_t howmuch)
return r; return r;
} }
/* Copy one malloc()ed string to another pointer. /* Copy one malloc()ed string to another pointer. Should be used as:
* dest = mallocstrcpy(dest, src); */
Should be used as dest = mallocstrcpy(dest, src); char *mallocstrcpy(char *dest, const char *src)
*/
void *mallocstrcpy(char *dest, char *src)
{ {
if (src == dest) if (src == dest)
return src; return dest;
if (dest != NULL) if (dest)
free(dest); free(dest);
if (src == NULL) { if (!src)
dest = NULL; return NULL;
return(dest);
}
dest = charalloc(strlen(src) + 1); dest = charalloc(strlen(src) + 1);
strcpy(dest, src); strcpy(dest, src);
...@@ -260,8 +251,7 @@ void *mallocstrcpy(char *dest, char *src) ...@@ -260,8 +251,7 @@ void *mallocstrcpy(char *dest, char *src)
return dest; return dest;
} }
/* Append a new magic-line to filebot. */
/* Append a new magic-line to filebot */
void new_magicline(void) void new_magicline(void)
{ {
filebot->next = nmalloc(sizeof(filestruct)); filebot->next = nmalloc(sizeof(filestruct));
...@@ -292,22 +282,22 @@ void new_magicline(void) ...@@ -292,22 +282,22 @@ void new_magicline(void)
*/ */
int check_wildcard_match(const char *text, const char *pattern) int check_wildcard_match(const char *text, const char *pattern)
{ {
const char *retryPat; const char *retrypat;
const char *retryText; const char *retrytext;
int ch; int ch;
int found; int found;
int len; int len;
retryPat = NULL; retrypat = NULL;
retryText = NULL; retrytext = NULL;
while (*text || *pattern) { while (*text || *pattern) {
ch = *pattern++; ch = *pattern++;
switch (ch) { switch (ch) {
case '*': case '*':
retryPat = pattern; retrypat = pattern;
retryText = text; retrytext = text;
break; break;
case '[': case '[':
...@@ -361,15 +351,15 @@ int check_wildcard_match(const char *text, const char *pattern) ...@@ -361,15 +351,15 @@ int check_wildcard_match(const char *text, const char *pattern)
} }
if (*text) { if (*text) {
pattern = retryPat; pattern = retrypat;
text = ++retryText; text = ++retrytext;
break; break;
} }
return FALSE; return FALSE;
} }
if (pattern == NULL) if (!pattern)
return FALSE; return FALSE;
} }
......
...@@ -36,16 +36,13 @@ ...@@ -36,16 +36,13 @@
#define _(string) (string) #define _(string) (string)
#endif #endif
/* winio.c statics */ /* winio.c statics */
static int statblank = 0; /* Number of keystrokes left after static int statblank = 0; /* Number of keystrokes left after
we call statusbar(), before we we call statusbar(), before we
actually blank the statusbar */ actually blank the statusbar */
/* Local Function Prototypes for only winio.c */ /* Local Function Prototypes for only winio.c */
inline int get_page_from_virtual(int virtual); static int get_page_start(int column);
inline int get_page_start_virtual(int page);
inline int get_page_end_virtual(int page);
/* Window I/O */ /* Window I/O */
...@@ -67,6 +64,7 @@ int do_last_line(void) ...@@ -67,6 +64,7 @@ int do_last_line(void)
return 1; return 1;
} }
/* Like xplustabs, but for a specific index of a specific filestruct */ /* Like xplustabs, but for a specific index of a specific filestruct */
int xpt(const filestruct *fileptr, int index) int xpt(const filestruct *fileptr, int index)
{ {
...@@ -87,102 +85,89 @@ int xpt(const filestruct *fileptr, int index) ...@@ -87,102 +85,89 @@ int xpt(const filestruct *fileptr, int index)
; ;
else if (iscntrl((int) fileptr->data[i])) else if (iscntrl((int) fileptr->data[i]))
tabs++; tabs++;
} }
return tabs; return tabs;
} }
/* Return the actual place on the screen of current->data[current_x], which /* Return the placewewant associated with current_x. That is, xplustabs
should always be > current_x */ * is the zero-based column position of the cursor. Value is no smaller
int xplustabs(void) * than current_x. */
size_t xplustabs(void)
{ {
return xpt(current, current_x); return strnlenpt(current->data, current_x);
} }
/* Return what current_x should be, given xplustabs() for the line, /* Return what current_x should be, given xplustabs() for the line. */
* given a start position in the filestruct's data */ size_t actual_x(const filestruct *fileptr, size_t xplus)
int actual_x_from_start(filestruct * fileptr, int xplus, int start)
{ {
int i, tot = 1; size_t i = 0;
/* the position in fileptr->data, returned */
if (fileptr == NULL || fileptr->data == NULL) size_t length = 0;
return 0; /* the screen display width to data[i] */
char *c;
for (i = start; tot <= xplus && fileptr->data[i] != 0; i++, tot++) /* fileptr->data + i */
if (fileptr->data[i] == NANO_CONTROL_I) {
if (tot % tabsize != 0) assert(fileptr != NULL && fileptr->data != NULL);
tot += tabsize - (tot % tabsize);
} else if (fileptr->data[i] & 0x80) for (c = fileptr->data; length < xplus && *c != '\0'; i++, c++) {
tot++; /* Make 8 bit chars only 1 column (again) */ if (*c == '\t')
else if (iscntrl((int) fileptr->data[i])) { length += tabsize - length % tabsize;
i++; else if (iscntrl((int)*c))
tot += 2; length += 2;
} else if ((unsigned char) *c >= 0x80 && (unsigned char) *c <= 0x9f)
length += 4;
if (i > strlen(fileptr->data)) else
i = strlen(fileptr->data); length++;
}
assert(length == strnlenpt(fileptr->data, i));
assert(i <= strlen(fileptr->data));
/* see if we're in the x-plus-tabs column of xplus; if not, look if (length > xplus)
for the closest column to it */ i--;
if (xpt(fileptr, i) < xplus) {
while (xpt(fileptr, i) < xplus && i < strlen(fileptr->data))
i++;
}
else if (xpt(fileptr, i) > xplus) {
while (xpt(fileptr, i) > xplus && i > start)
i--;
}
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, _("actual_x_from_start for xplus=%d returned %d\n"), fprintf(stderr, _("actual_x for xplus=%d returns %d\n"), xplus, i);
xplus, i);
#endif #endif
return i - start; return i;
} }
/* Opposite of xplustabs */ /* A strlen with tabs factored in, similar to xplustabs(). */
int actual_x(filestruct * fileptr, int xplus) size_t strnlenpt(const char *buf, size_t size)
{ {
return actual_x_from_start(fileptr, xplus, 0); size_t length = 0;
}
if (buf != NULL)
/* a strlen with tabs factored in, similar to xplustabs() */ for (; *buf != '\0' && size != 0; size--, buf++) {
int strnlenpt(char *buf, int size) if (*buf == '\t')
{ length += tabsize - (length % tabsize);
int i, tabs = 0; else if (iscntrl((int)*buf))
length += 2;
if (buf == NULL) else if ((unsigned char) *buf >= 0x80 && (unsigned char) *buf <= 0x9f)
return 0; length += 4;
for (i = 0; i < size; i++) {
tabs++;
if (buf[i] == NANO_CONTROL_I) {
if (tabs % tabsize == 0);
else else
tabs += tabsize - (tabs % tabsize); length++;
} else if (buf[i] & 0x80) }
/* Make 8 bit chars only 1 column! */ return length;
;
else if (iscntrl((int) buf[i]))
tabs++;
}
return tabs;
} }
int strlenpt(char *buf) size_t strlenpt(const char *buf)
{ {
return strnlenpt(buf, strlen(buf)); return strnlenpt(buf, -1);
} }
/* resets current_y, based on the position of current, and puts the cursor at /* Resets current_y, based on the position of current, and puts the
(current_y, current_x) */ * cursor at (current_y, current_x). */
void reset_cursor(void) void reset_cursor(void)
{ {
filestruct *ptr = edittop; const filestruct *ptr = edittop;
int x; size_t x;
/* Yuck. This condition can be true after open_file when opening the
* first file. */
if (edittop == NULL)
return;
current_y = 0; current_y = 0;
...@@ -192,20 +177,15 @@ void reset_cursor(void) ...@@ -192,20 +177,15 @@ void reset_cursor(void)
} }
x = xplustabs(); x = xplustabs();
if (x <= COLS - 2) wmove(edit, current_y, x - get_page_start(x));
wmove(edit, current_y, x);
else
wmove(edit, current_y, x -
get_page_start_virtual(get_page_from_virtual(x)));
} }
void blank_bottombars(void) void blank_bottombars(void)
{ {
int i = no_help()? 3 : 1; if (!no_help()) {
mvwaddstr(bottomwin, 1, 0, hblank);
for (; i <= 2; i++) mvwaddstr(bottomwin, 2, 0, hblank);
mvwaddstr(bottomwin, i, 0, hblank); }
} }
void blank_edit(void) void blank_edit(void)
...@@ -229,7 +209,6 @@ void blank_statusbar_refresh(void) ...@@ -229,7 +209,6 @@ void blank_statusbar_refresh(void)
void check_statblank(void) void check_statblank(void)
{ {
if (statblank > 1) if (statblank > 1)
statblank--; statblank--;
else if (statblank == 1 && !ISSET(CONSTUPDATE)) { else if (statblank == 1 && !ISSET(CONSTUPDATE)) {
...@@ -238,70 +217,63 @@ void check_statblank(void) ...@@ -238,70 +217,63 @@ void check_statblank(void)
} }
} }
/* Repaint the statusbar when getting a character in nanogetstr */ /* Repaint the statusbar when getting a character in nanogetstr. buf
void nanoget_repaint(char *buf, char *inputbuf, int x) * should be no longer than COLS - 4.
*
* Note that we must turn on A_REVERSE here, since do_help turns it
* off! */
static void nanoget_repaint(const char *buf, const char *inputbuf,
int x)
{ {
int len = strlen(buf); int len = strlen(buf) + 2;
int wid = COLS - len; int wid = COLS - len;
#ifdef ENABLE_COLOR assert(wid >= 2);
color_on(bottomwin, COLOR_STATUSBAR); assert(0 <= x && x <= strlen(inputbuf));
#else
wattron(bottomwin, A_REVERSE); wattron(bottomwin, A_REVERSE);
#endif
blank_statusbar(); blank_statusbar();
mvwaddstr(bottomwin, 0, 0, buf);
if (x <= COLS - 1) { waddch(bottomwin, ':');
/* Black magic */ waddch(bottomwin, x < wid ? ' ' : '$');
buf[len - 1] = ' '; waddnstr(bottomwin, &inputbuf[wid * (x / wid)], wid);
wmove(bottomwin, 0, (x % wid) + len);
mvwaddstr(bottomwin, 0, 0, buf);
waddnstr(bottomwin, inputbuf, wid);
wmove(bottomwin, 0, (x % COLS));
} else {
/* Black magic */
buf[len - 1] = '$';
mvwaddstr(bottomwin, 0, 0, buf);
waddnstr(bottomwin, &inputbuf[wid * ((x - len) / (wid))], wid);
wmove(bottomwin, 0, ((x - len) % wid) + len);
}
#ifdef ENABLE_COLOR
color_off(bottomwin, COLOR_STATUSBAR);
#else
wattroff(bottomwin, A_REVERSE); wattroff(bottomwin, A_REVERSE);
#endif
} }
/* Get the input from the kb; this should only be called from statusq */ /* Get the input from the kb; this should only be called from
int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s, * statusq(). */
int start_x, int list) static int nanogetstr(int allowtabs, const char *buf, const char *def,
{ const shortcut *s
int kbinput = 0, x = 0, xend, slen;
int x_left = 0, inputlen, tabbed = 0;
char *inputbuf;
shortcut *t;
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
int shift = 0; , int *list
#endif #endif
)
slen = length_of_list(s); {
inputbuf = charalloc(strlen(def) + 1); int kbinput;
inputbuf[0] = '\0'; int x;
/* the cursor position in 'answer' */
x_left = strlen(buf); int xend;
x = strlen(def) + x_left; /* length of 'answer', the status bar text */
int tabbed = 0;
/* used by input_tab() */
const shortcut *t;
xend = strlen(def);
x = xend;
answer = (char *)nrealloc(answer, xend + 1);
if (xend > 0)
strcpy(answer, def);
else
answer[0] = '\0';
#if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE) #if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
currshortcut = s; currshortcut = s;
#endif #endif
/* Get the input! */ /* Get the input! */
if (strlen(def) > 0)
strcpy(inputbuf, def);
nanoget_repaint(buf, inputbuf, x); nanoget_repaint(buf, answer, x);
/* Make sure any editor screen updates are displayed before getting input */ /* Make sure any editor screen updates are displayed before getting input */
wrefresh(edit); wrefresh(edit);
...@@ -321,15 +293,10 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s, ...@@ -321,15 +293,10 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s,
break; break;
} }
#endif #endif
/* We shouldn't discard the answer it gave, just because
we hit a keystroke, GEEZ! */
answer = mallocstrcpy(answer, inputbuf);
free(inputbuf);
return t->val; return t->val;
} }
} }
xend = strlen(buf) + strlen(inputbuf); assert(0 <= x && x <= xend && xend == strlen(answer));
if (kbinput != '\t') if (kbinput != '\t')
tabbed = 0; tabbed = 0;
...@@ -358,65 +325,55 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s, ...@@ -358,65 +325,55 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s,
#endif #endif
case NANO_HOME_KEY: case NANO_HOME_KEY:
case KEY_HOME: case KEY_HOME:
x = x_left; x = 0;
break; break;
case NANO_END_KEY: case NANO_END_KEY:
case KEY_END: case KEY_END:
x = x_left + strlen(inputbuf); x = xend;
break; break;
case KEY_RIGHT: case KEY_RIGHT:
case NANO_FORWARD_KEY: case NANO_FORWARD_KEY:
if (x < xend) if (x < xend)
x++; x++;
wmove(bottomwin, 0, x);
break; break;
case NANO_CONTROL_D: case NANO_CONTROL_D:
if (strlen(inputbuf) > 0 && (x - x_left) != strlen(inputbuf)) { if (x < xend) {
memmove(inputbuf + (x - x_left), memmove(answer + x, answer + x + 1, xend - x);
inputbuf + (x - x_left) + 1, xend--;
strlen(inputbuf) - (x - x_left) - 1);
inputbuf[strlen(inputbuf) - 1] = '\0';
} }
break; break;
case NANO_CONTROL_K: case NANO_CONTROL_K:
case NANO_CONTROL_U: case NANO_CONTROL_U:
*inputbuf = 0; null_at(&answer, 0);
x = x_left; xend = 0;
x = 0;
break; break;
case KEY_BACKSPACE: case KEY_BACKSPACE:
case 127: case 127:
case NANO_CONTROL_H: case NANO_CONTROL_H:
if (strlen(inputbuf) > 0) { if (x > 0) {
if (x == (x_left + strlen(inputbuf))) memmove(answer + x - 1, answer + x, xend - x + 1);
inputbuf[strlen(inputbuf) - 1] = '\0';
else if (x - x_left) {
memmove(inputbuf + (x - x_left) - 1,
inputbuf + (x - x_left),
strlen(inputbuf) - (x - x_left));
inputbuf[strlen(inputbuf) - 1] = '\0';
}
}
if (x > strlen(buf))
x--; x--;
xend--;
}
break; break;
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
case NANO_CONTROL_I: case NANO_CONTROL_I:
if (allowtabs) { if (allowtabs) {
shift = 0; int shift = 0;
inputbuf = input_tab(inputbuf, (x - x_left),
&tabbed, &shift, &list); answer = input_tab(answer, x, &tabbed, &shift, list);
xend = strlen(answer);
x += shift; x += shift;
if (x - x_left > strlen(inputbuf)) if (x > xend)
x = strlen(inputbuf) + x_left; x = xend;
} }
break; break;
#endif #endif
case KEY_LEFT: case KEY_LEFT:
case NANO_BACK_KEY: case NANO_BACK_KEY:
if (x > strlen(buf)) if (x > 0)
x--; x--;
wmove(bottomwin, 0, x);
break; break;
case KEY_UP: case KEY_UP:
case KEY_DOWN: case KEY_DOWN:
...@@ -430,10 +387,10 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s, ...@@ -430,10 +387,10 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s,
case 'O': case 'O':
switch (kbinput = wgetch(edit)) { switch (kbinput = wgetch(edit)) {
case 'F': case 'F':
x = x_left + strlen(inputbuf); x = xend;
break; break;
case 'H': case 'H':
x = x_left; x = 0;
break; break;
} }
break; break;
...@@ -442,30 +399,25 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s, ...@@ -442,30 +399,25 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s,
case 'C': case 'C':
if (x < xend) if (x < xend)
x++; x++;
wmove(bottomwin, 0, x);
break; break;
case 'D': case 'D':
if (x > strlen(buf)) if (x > 0)
x--; x--;
wmove(bottomwin, 0, x);
break; break;
case '1': case '1':
case '7': case '7':
x = x_left; x = 0;
goto skip_tilde; goto skip_tilde;
case '3': case '3':
do_deletekey: do_deletekey:
if (strlen(inputbuf) > 0 if (x < xend) {
&& (x - x_left) != strlen(inputbuf)) { memmove(answer + x, answer + x + 1, xend - x);
memmove(inputbuf + (x - x_left), xend--;
inputbuf + (x - x_left) + 1,
strlen(inputbuf) - (x - x_left) - 1);
inputbuf[strlen(inputbuf) - 1] = '\0';
} }
goto skip_tilde; goto skip_tilde;
case '4': case '4':
case '8': case '8':
x = x_left + strlen(inputbuf); x = xend;
goto skip_tilde; goto skip_tilde;
skip_tilde: skip_tilde:
nodelay(edit, TRUE); nodelay(edit, TRUE);
...@@ -475,6 +427,7 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s, ...@@ -475,6 +427,7 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s,
nodelay(edit, FALSE); nodelay(edit, FALSE);
break; break;
} }
break;
default: default:
for (t = s; t != NULL; t = t->next) { for (t = s; t != NULL; t = t->next) {
...@@ -483,118 +436,82 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s, ...@@ -483,118 +436,82 @@ int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s,
kbinput); kbinput);
#endif #endif
if (kbinput == t->val || kbinput == t->val - 32) { if (kbinput == t->val || kbinput == t->val - 32) {
/* We hit an Alt key. Do like above. We don't /* We hit an Alt key. Do like above. We don't
just ungetch the letter and let it get caught just ungetch the letter and let it get caught
above cause that screws the keypad... */ above cause that screws the keypad... */
answer = mallocstrcpy(answer, inputbuf);
free(inputbuf);
return t->val; return t->val;
} }
} }
} }
break; break;
default: default:
if (kbinput < 32) if (kbinput < 32)
break; break;
answer = nrealloc(answer, xend + 2);
inputlen = strlen(inputbuf); memmove(answer + x + 1, answer + x, xend - x + 1);
inputbuf = nrealloc(inputbuf, inputlen + 2); xend++;
answer[x] = kbinput;
memmove(&inputbuf[x - x_left + 1],
&inputbuf[x - x_left], inputlen - (x - x_left) + 1);
inputbuf[x - x_left] = kbinput;
x++; x++;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, _("input \'%c\' (%d)\n"), kbinput, kbinput); fprintf(stderr, _("input \'%c\' (%d)\n"), kbinput, kbinput);
#endif #endif
} }
nanoget_repaint(buf, inputbuf, x); nanoget_repaint(buf, answer, x);
wrefresh(bottomwin); wrefresh(bottomwin);
} } /* while (kbinput ...) */
#ifndef DISABLE_TABCOMP
/* if we've done tab completion, there might be a list of filename
matches on the edit window at this point; make sure they're
cleared off */
if (list)
edit_refresh();
#endif
answer = mallocstrcpy(answer, inputbuf); /* In Pico mode, just check for a blank answer here */
free(inputbuf);
/* In pico mode, just check for a blank answer here */
if (ISSET(PICO_MODE) && answer[0] == '\0') if (ISSET(PICO_MODE) && answer[0] == '\0')
return -2; return -2;
else else
return 0; return 0;
} }
void horizbar(WINDOW * win, int y) void titlebar(const char *path)
{
wattron(win, A_REVERSE);
mvwaddstr(win, 0, 0, hblank);
wattroff(win, A_REVERSE);
}
void titlebar(char *path)
{ {
int namelen, space; int namelen, space;
char *what = path; const char *what = path;
if (path == NULL) if (path == NULL)
what = filename; what = filename;
#ifdef ENABLE_COLOR
color_on(topwin, COLOR_TITLEBAR);
mvwaddstr(topwin, 0, 0, hblank);
#else
horizbar(topwin, 0);
wattron(topwin, A_REVERSE); wattron(topwin, A_REVERSE);
#endif
mvwaddstr(topwin, 0, 0, hblank);
mvwaddnstr(topwin, 0, 2, VERMSG, COLS - 3); mvwaddnstr(topwin, 0, 2, VERMSG, COLS - 3);
space = COLS - strlen(VERMSG) - strlen(VERSION) - 21; space = COLS - sizeof(VERMSG) - 22;
namelen = strlen(what); namelen = strlen(what);
if (space > 0) { if (space > 0) {
if (what[0] == '\0') if (what[0] == '\0')
mvwaddstr(topwin, 0, COLS / 2 - 6, _("New Buffer")); mvwaddnstr(topwin, 0, COLS / 2 - 6, _("New Buffer"),
else { COLS / 2 + COLS % 2 - 6);
if (namelen > space) { else if (namelen > space) {
if (path == NULL) if (path == NULL)
waddstr(topwin, _(" File: ...")); waddstr(topwin, _(" File: ..."));
else else
waddstr(topwin, _(" DIR: ...")); waddstr(topwin, _(" DIR: ..."));
waddstr(topwin, &what[namelen - space]); waddstr(topwin, &what[namelen - space]);
} else { } else {
if (path == NULL) if (path == NULL)
mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1), mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1),
_("File: ")); _("File: "));
else else
mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1), mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1),
_(" DIR: ")); _(" DIR: "));
waddstr(topwin, what); waddstr(topwin, what);
}
} }
} /* If we don't have space, we shouldn't bother */ } /* If we don't have space, we shouldn't bother */
if (ISSET(MODIFIED)) if (ISSET(MODIFIED))
mvwaddstr(topwin, 0, COLS - 11, _(" Modified ")); mvwaddnstr(topwin, 0, COLS - 11, _(" Modified "), 11);
else if (ISSET(VIEW_MODE)) else if (ISSET(VIEW_MODE))
mvwaddstr(topwin, 0, COLS - 11, _(" View ")); mvwaddnstr(topwin, 0, COLS - 11, _(" View "), 11);
#ifdef ENABLE_COLOR
color_off(topwin, COLOR_TITLEBAR);
#else
wattroff(topwin, A_REVERSE); wattroff(topwin, A_REVERSE);
#endif
wrefresh(topwin); wrefresh(topwin);
reset_cursor(); reset_cursor();
...@@ -620,7 +537,7 @@ static void onekey(const char *keystroke, const char *desc, int len) ...@@ -620,7 +537,7 @@ static void onekey(const char *keystroke, const char *desc, int len)
} }
} }
void clear_bottomwin(void) static void clear_bottomwin(void)
{ {
if (ISSET(NO_HELP)) if (ISSET(NO_HELP))
return; return;
...@@ -644,13 +561,6 @@ void bottombars(const shortcut *s) ...@@ -644,13 +561,6 @@ void bottombars(const shortcut *s)
} else } else
slen = length_of_list(s); slen = length_of_list(s);
#ifdef ENABLE_COLOR
color_on(bottomwin, COLOR_BOTTOMBARS);
if (!colors[COLOR_BOTTOMBARS - FIRST_COLORNUM].set ||
colors[COLOR_BOTTOMBARS - FIRST_COLORNUM].fg != COLOR_BLACK)
wattroff(bottomwin, A_REVERSE);
#endif
/* There will be this many columns of shortcuts */ /* There will be this many columns of shortcuts */
numcols = (slen + (slen % 2)) / 2; numcols = (slen + (slen % 2)) / 2;
...@@ -681,16 +591,12 @@ void bottombars(const shortcut *s) ...@@ -681,16 +591,12 @@ void bottombars(const shortcut *s)
goto break_completely_out; goto break_completely_out;
} }
} }
break_completely_out:
#ifdef ENABLE_COLOR
color_off(bottomwin, COLOR_BOTTOMBARS);
#endif
break_completely_out:
wrefresh(bottomwin); wrefresh(bottomwin);
} }
/* If modified is not already set, set it and update titlebar */ /* If modified is not already set, set it and update titlebar. */
void set_modified(void) void set_modified(void)
{ {
if (!ISSET(MODIFIED)) { if (!ISSET(MODIFIED)) {
...@@ -735,6 +641,13 @@ inline int get_page_end_virtual(int page) ...@@ -735,6 +641,13 @@ inline int get_page_end_virtual(int page)
return get_page_start_virtual(page) + COLS - 1; return get_page_start_virtual(page) + COLS - 1;
} }
static int get_page_start(int column)
{
assert(COLS > 9);
return column < COLS - 1 ? 0 : column - 7 - (column - 8) % (COLS - 9);
}
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* This takes care of the case where there is a mark that covers only */ /* This takes care of the case where there is a mark that covers only */
/* the current line. */ /* the current line. */
...@@ -781,20 +694,11 @@ void add_marked_sameline(int begin, int end, filestruct * fileptr, int y, ...@@ -781,20 +694,11 @@ void add_marked_sameline(int begin, int end, filestruct * fileptr, int y,
sel_data_len = end - begin; sel_data_len = end - begin;
post_data_len = this_page_end - end; post_data_len = this_page_end - end;
#ifdef ENABLE_COLOR
color_on(edit, COLOR_MARKER);
#else
wattron(edit, A_REVERSE); wattron(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
mvwaddnstr(edit, y, begin - this_page_start, mvwaddnstr(edit, y, begin - this_page_start,
&fileptr->data[begin], sel_data_len); &fileptr->data[begin], sel_data_len);
#ifdef ENABLE_COLOR
color_off(edit, COLOR_MARKER);
#else
wattroff(edit, A_REVERSE); wattroff(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
} }
#endif #endif
...@@ -809,7 +713,7 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, ...@@ -809,7 +713,7 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
{ {
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
colortype *tmpcolor = NULL; const colortype *tmpcolor = NULL;
int k, paintlen; int k, paintlen;
filestruct *e, *s; filestruct *e, *s;
regoff_t ematch, smatch; regoff_t ematch, smatch;
...@@ -1011,19 +915,12 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, ...@@ -1011,19 +915,12 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
if (fileptr != mark_beginbuf && fileptr != current) { if (fileptr != mark_beginbuf && fileptr != current) {
/* We are on a completely marked line, paint it all /* We are on a completely marked line, paint it all
* inverse */ * inverse */
#ifdef ENABLE_COLOR
color_on(edit, COLOR_MARKER);
#else
wattron(edit, A_REVERSE); wattron(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
mvwaddnstr(edit, yval, 0, fileptr->data, COLS); mvwaddnstr(edit, yval, 0, fileptr->data, COLS);
#ifdef ENABLE_COLOR
color_off(edit, COLOR_MARKER);
#else
wattroff(edit, A_REVERSE); wattroff(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
} else if (fileptr == mark_beginbuf && fileptr == current) { } else if (fileptr == mark_beginbuf && fileptr == current) {
/* Special case, we're still on the same line we started /* Special case, we're still on the same line we started
...@@ -1051,11 +948,8 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, ...@@ -1051,11 +948,8 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
int target; int target;
if (mark_beginbuf->lineno > current->lineno) { if (mark_beginbuf->lineno > current->lineno) {
#ifdef ENABLE_COLOR
color_on(edit, COLOR_MARKER);
#else
wattron(edit, A_REVERSE); wattron(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
target = target =
(virt_mark_beginx < (virt_mark_beginx <
...@@ -1063,22 +957,13 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, ...@@ -1063,22 +957,13 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
mvwaddnstr(edit, yval, 0, fileptr->data, target); mvwaddnstr(edit, yval, 0, fileptr->data, target);
#ifdef ENABLE_COLOR
color_off(edit, COLOR_MARKER);
#else
wattroff(edit, A_REVERSE); wattroff(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
} }
if (mark_beginbuf->lineno < current->lineno) { if (mark_beginbuf->lineno < current->lineno) {
#ifdef ENABLE_COLOR
color_on(edit, COLOR_MARKER);
#else
wattron(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
wattron(edit, A_REVERSE);
target = (COLS - 1) - virt_mark_beginx; target = (COLS - 1) - virt_mark_beginx;
if (target < 0) if (target < 0)
...@@ -1087,12 +972,7 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, ...@@ -1087,12 +972,7 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
mvwaddnstr(edit, yval, virt_mark_beginx, mvwaddnstr(edit, yval, virt_mark_beginx,
&fileptr->data[virt_mark_beginx], target); &fileptr->data[virt_mark_beginx], target);
#ifdef ENABLE_COLOR
color_off(edit, COLOR_MARKER);
#else
wattroff(edit, A_REVERSE); wattroff(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
} }
} else if (fileptr == current) { } else if (fileptr == current) {
...@@ -1103,11 +983,7 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, ...@@ -1103,11 +983,7 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
if (mark_beginbuf->lineno < current->lineno) { if (mark_beginbuf->lineno < current->lineno) {
#ifdef ENABLE_COLOR
color_on(edit, COLOR_MARKER);
#else
wattron(edit, A_REVERSE); wattron(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
if (virt_cur_x > COLS - 2) { if (virt_cur_x > COLS - 2) {
mvwaddnstr(edit, yval, 0, mvwaddnstr(edit, yval, 0,
...@@ -1116,22 +992,13 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, ...@@ -1116,22 +992,13 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
} else } else
mvwaddnstr(edit, yval, 0, fileptr->data, virt_cur_x); mvwaddnstr(edit, yval, 0, fileptr->data, virt_cur_x);
#ifdef ENABLE_COLOR
color_off(edit, COLOR_MARKER);
#else
wattroff(edit, A_REVERSE); wattroff(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
} }
if (mark_beginbuf->lineno > current->lineno) { if (mark_beginbuf->lineno > current->lineno) {
#ifdef ENABLE_COLOR
color_on(edit, COLOR_MARKER);
#else
wattron(edit, A_REVERSE); wattron(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
if (virt_cur_x > COLS - 2) if (virt_cur_x > COLS - 2)
mvwaddnstr(edit, yval, virt_cur_x - this_page_start, mvwaddnstr(edit, yval, virt_cur_x - this_page_start,
&fileptr->data[virt_cur_x], &fileptr->data[virt_cur_x],
...@@ -1141,11 +1008,7 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x, ...@@ -1141,11 +1008,7 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
&fileptr->data[virt_cur_x], &fileptr->data[virt_cur_x],
COLS - virt_cur_x); COLS - virt_cur_x);
#ifdef ENABLE_COLOR
color_off(edit, COLOR_MARKER);
#else
wattroff(edit, A_REVERSE); wattroff(edit, A_REVERSE);
#endif /* ENABLE_COLOR */
} }
} }
...@@ -1267,47 +1130,48 @@ void center_cursor(void) ...@@ -1267,47 +1130,48 @@ void center_cursor(void)
wmove(edit, current_y, current_x); wmove(edit, current_y, current_x);
} }
/* Refresh the screen without changing the position of lines */ /* Refresh the screen without changing the position of lines. */
void edit_refresh(void) void edit_refresh(void)
{ {
static int noloop = 0; static int noloop = 0;
int nlines = 0, i = 0, currentcheck = 0; int nlines = 0, currentcheck = 0;
filestruct *temp, *hold = current;
/* Neither of these conditions should occur, but they do. edittop is
* NULL when you open an existing file on the command line, and
* ENABLE_COLOR is defined. Yuck. */
if (current == NULL) if (current == NULL)
return; return;
if (edittop == NULL)
edittop = current;
temp = edittop; editbot = edittop;
while (nlines < editwinrows) {
while (nlines <= editwinrows - 1 && nlines <= totlines && temp != NULL) { update_line(editbot, current_x);
hold = temp; if (editbot == current)
update_line(temp, current_x);
if (temp == current)
currentcheck = 1; currentcheck = 1;
temp = temp->next;
nlines++; nlines++;
if (editbot->next == NULL)
break;
editbot = editbot->next;
} }
/* If noloop == 1, then we already did an edit_update without finishing /* If noloop == 1, then we already did an edit_update without finishing
this function. So we don't run edit_update again */ this function. So we don't run edit_update again */
if (!currentcheck && !noloop) { /* Then current has run off the screen... */ if (!currentcheck && !noloop) {
/* Then current has run off the screen... */
edit_update(current, CENTER); edit_update(current, CENTER);
noloop = 1; noloop = 1;
} else if (noloop) } else if (noloop)
noloop = 0; noloop = 0;
if (nlines <= editwinrows - 1) while (nlines < editwinrows) {
while (nlines <= editwinrows - 1) { mvwaddstr(edit, nlines, 0, hblank);
mvwaddstr(edit, nlines, i, hblank); nlines++;
nlines++; }
}
if (temp == NULL)
editbot = hold;
else
editbot = temp;
/* What the hell are we expecting to update the screen if this isn't /* What the hell are we expecting to update the screen if this isn't
here? luck?? */ here? Luck?? */
wrefresh(edit); wrefresh(edit);
} }
...@@ -1325,34 +1189,25 @@ void edit_refresh_clearok(void) ...@@ -1325,34 +1189,25 @@ void edit_refresh_clearok(void)
* Nice generic routine to update the edit buffer, given a pointer to the * Nice generic routine to update the edit buffer, given a pointer to the
* file struct =) * file struct =)
*/ */
void edit_update(filestruct * fileptr, int topmidbotnone) void edit_update(filestruct *fileptr, topmidbotnone location)
{ {
int i = 0;
filestruct *temp;
if (fileptr == NULL) if (fileptr == NULL)
return; return;
temp = fileptr; if (location != TOP) {
if (topmidbotnone == TOP); int goal = location == NONE ? current_y - 1 : editwinrows / 2;
else if (topmidbotnone == NONE)
for (i = 0; i <= current_y - 1 && temp->prev != NULL; i++)
temp = temp->prev;
else if (topmidbotnone == BOTTOM)
for (i = 0; i <= editwinrows - 1 && temp->prev != NULL; i++)
temp = temp->prev;
else
for (i = 0; i <= editwinrows / 2 && temp->prev != NULL; i++)
temp = temp->prev;
edittop = temp; for (; goal >= 0 && fileptr->prev != NULL; goal--)
fileptr = fileptr->prev;
}
edittop = fileptr;
fix_editbot(); fix_editbot();
edit_refresh(); edit_refresh();
} }
/* This function updates current, based on where current_y is; reset_cursor /* This function updates current, based on where current_y is;
does the opposite */ * reset_cursor() does the opposite. */
void update_cursor(void) void update_cursor(void)
{ {
int i = 0; int i = 0;
...@@ -1363,7 +1218,7 @@ void update_cursor(void) ...@@ -1363,7 +1218,7 @@ void update_cursor(void)
#endif #endif
current = edittop; current = edittop;
while (i <= current_y - 1 && current->next != NULL) { while (i < current_y && current->next != NULL) {
current = current->next; current = current->next;
i++; i++;
} }
...@@ -1371,7 +1226,6 @@ void update_cursor(void) ...@@ -1371,7 +1226,6 @@ void update_cursor(void)
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, _("current->data = \"%s\"\n"), current->data); fprintf(stderr, _("current->data = \"%s\"\n"), current->data);
#endif #endif
} }
/* /*
...@@ -1382,12 +1236,12 @@ void update_cursor(void) ...@@ -1382,12 +1236,12 @@ void update_cursor(void)
* *
* New arg tabs tells whether or not to allow tab completion. * New arg tabs tells whether or not to allow tab completion.
*/ */
int statusq(int tabs, shortcut *s, char *def, char *msg, ...) int statusq(int tabs, const shortcut *s, const char *def,
const char *msg, ...)
{ {
va_list ap; va_list ap;
char foo[133]; char *foo = charalloc(COLS - 3);
int ret; int ret;
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
int list = 0; int list = 0;
#endif #endif
...@@ -1395,34 +1249,18 @@ int statusq(int tabs, shortcut *s, char *def, char *msg, ...) ...@@ -1395,34 +1249,18 @@ int statusq(int tabs, shortcut *s, char *def, char *msg, ...)
bottombars(s); bottombars(s);
va_start(ap, msg); va_start(ap, msg);
vsnprintf(foo, 132, msg, ap); vsnprintf(foo, COLS - 4, msg, ap);
va_end(ap); va_end(ap);
strncat(foo, ": ", 132); foo[COLS - 4] = '\0';
#ifdef ENABLE_COLOR
color_on(bottomwin, COLOR_STATUSBAR);
#else
wattron(bottomwin, A_REVERSE);
#endif
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
ret = nanogetstr(tabs, foo, def, s, (strlen(foo) + 3), list); ret = nanogetstr(tabs, foo, def, s, &list);
#else #else
/* if we've disabled tab completion, the value of list won't be ret = nanogetstr(tabs, foo, def, s);
used at all, so it's safe to use 0 (NULL) as a placeholder */
ret = nanogetstr(tabs, foo, def, s, (strlen(foo) + 3), 0);
#endif #endif
free(foo);
#ifdef ENABLE_COLOR
color_off(bottomwin, COLOR_STATUSBAR);
#else
wattroff(bottomwin, A_REVERSE);
#endif
switch (ret) { switch (ret) {
case NANO_FIRSTLINE_KEY: case NANO_FIRSTLINE_KEY:
do_first_line(); do_first_line();
break; break;
...@@ -1430,14 +1268,8 @@ int statusq(int tabs, shortcut *s, char *def, char *msg, ...) ...@@ -1430,14 +1268,8 @@ int statusq(int tabs, shortcut *s, char *def, char *msg, ...)
do_last_line(); do_last_line();
break; break;
case NANO_CANCEL_KEY: case NANO_CANCEL_KEY:
#ifndef DISABLE_TABCOMP ret = -1;
/* if we've done tab completion, there might be a list of break;
filename matches on the edit window at this point; make sure
they're cleared off */
if (list)
edit_refresh();
#endif
return -1;
default: default:
blank_statusbar(); blank_statusbar();
} }
...@@ -1446,6 +1278,14 @@ int statusq(int tabs, shortcut *s, char *def, char *msg, ...) ...@@ -1446,6 +1278,14 @@ int statusq(int tabs, shortcut *s, char *def, char *msg, ...)
fprintf(stderr, _("I got \"%s\"\n"), answer); fprintf(stderr, _("I got \"%s\"\n"), answer);
#endif #endif
#ifndef DISABLE_TABCOMP
/* if we've done tab completion, there might be a list of
filename matches on the edit window at this point; make sure
they're cleared off */
if (list)
edit_refresh();
#endif
return ret; return ret;
} }
...@@ -1453,21 +1293,20 @@ int statusq(int tabs, shortcut *s, char *def, char *msg, ...) ...@@ -1453,21 +1293,20 @@ int statusq(int tabs, shortcut *s, char *def, char *msg, ...)
* Ask a simple yes/no question on the statusbar. Returns 1 for Y, 0 for * Ask a simple yes/no question on the statusbar. Returns 1 for Y, 0 for
* N, 2 for All (if all is non-zero when passed in) and -1 for abort (^C) * N, 2 for All (if all is non-zero when passed in) and -1 for abort (^C)
*/ */
int do_yesno(int all, int leavecursor, char *msg, ...) int do_yesno(int all, int leavecursor, const char *msg, ...)
{ {
va_list ap; va_list ap;
char foo[133]; char foo[133];
int kbinput, ok = -1, i; int kbinput, ok = -1, i;
char *yesstr; /* String of yes characters accepted */ const char *yesstr; /* String of yes characters accepted */
char *nostr; /* Same for no */ const char *nostr; /* Same for no */
char *allstr; /* And all, surprise! */ const char *allstr; /* And all, surprise! */
#ifndef DISABLE_MOUSE #ifndef DISABLE_MOUSE
#ifdef NCURSES_MOUSE_VERSION #ifdef NCURSES_MOUSE_VERSION
MEVENT mevent; MEVENT mevent;
#endif #endif
#endif #endif
/* Yes, no and all are strings of any length. Each string consists of /* Yes, no and all are strings of any length. Each string consists of
all characters accepted as a valid character for that value. all characters accepted as a valid character for that value.
The first value will be the one displayed in the shortcuts. */ The first value will be the one displayed in the shortcuts. */
...@@ -1478,10 +1317,6 @@ int do_yesno(int all, int leavecursor, char *msg, ...) ...@@ -1478,10 +1317,6 @@ int do_yesno(int all, int leavecursor, char *msg, ...)
/* Write the bottom of the screen */ /* Write the bottom of the screen */
clear_bottomwin(); clear_bottomwin();
#ifdef ENABLE_COLOR
color_on(bottomwin, COLOR_BOTTOMBARS);
#endif
/* Remove gettext call for keybindings until we clear the thing up */ /* Remove gettext call for keybindings until we clear the thing up */
if (!ISSET(NO_HELP)) { if (!ISSET(NO_HELP)) {
char shortstr[3]; /* Temp string for Y, N, A */ char shortstr[3]; /* Temp string for Y, N, A */
...@@ -1506,21 +1341,12 @@ int do_yesno(int all, int leavecursor, char *msg, ...) ...@@ -1506,21 +1341,12 @@ int do_yesno(int all, int leavecursor, char *msg, ...)
vsnprintf(foo, 132, msg, ap); vsnprintf(foo, 132, msg, ap);
va_end(ap); va_end(ap);
#ifdef ENABLE_COLOR
color_off(bottomwin, COLOR_BOTTOMBARS);
color_on(bottomwin, COLOR_STATUSBAR);
#else
wattron(bottomwin, A_REVERSE); wattron(bottomwin, A_REVERSE);
#endif /* ENABLE_COLOR */
blank_statusbar(); blank_statusbar();
mvwaddstr(bottomwin, 0, 0, foo); mvwaddstr(bottomwin, 0, 0, foo);
#ifdef ENABLE_COLOR
color_off(bottomwin, COLOR_STATUSBAR);
#else
wattroff(bottomwin, A_REVERSE); wattroff(bottomwin, A_REVERSE);
#endif
wrefresh(bottomwin); wrefresh(bottomwin);
...@@ -1546,22 +1372,17 @@ int do_yesno(int all, int leavecursor, char *msg, ...) ...@@ -1546,22 +1372,17 @@ int do_yesno(int all, int leavecursor, char *msg, ...)
else { else {
/* Rather than a bunch of if statements, set up a matrix /* Rather than a bunch of if statements, set up a matrix
of possible return keystrokes based on the x and y values */ of possible return keystrokes based on the x and y
if (all) { values */
char yesnosquare[2][2] = { char yesnosquare[2][2];
{yesstr[0], allstr[0]}, yesnosquare[0][0] = yesstr[0];
{nostr[0], NANO_CONTROL_C} if (all)
}; yesnosquare[0][1] = allstr[0];
else
ungetch(yesnosquare[mevent.y][mevent.x / (COLS / 6)]); yesnosquare[0][1] = '\0';
} else { yesnosquare[1][0] = nostr[0];
char yesnosquare[2][2] = { yesnosquare[1][1] = NANO_CONTROL_C;
{yesstr[0], '\0'}, ungetch(yesnosquare[mevent.y][mevent.x / (COLS / 6)]);
{nostr[0], NANO_CONTROL_C}
};
ungetch(yesnosquare[mevent.y][mevent.x / (COLS / 6)]);
}
} }
break; break;
#endif #endif
...@@ -1603,38 +1424,37 @@ int do_yesno(int all, int leavecursor, char *msg, ...) ...@@ -1603,38 +1424,37 @@ int do_yesno(int all, int leavecursor, char *msg, ...)
return ok; return ok;
} }
void statusbar(char *msg, ...) void statusbar(const char *msg, ...)
{ {
va_list ap; va_list ap;
char foo[133]; char *foo;
int start_x = 0; int start_x = 0;
size_t foo_len;
assert(COLS >= 4);
foo = charalloc(COLS - 3);
va_start(ap, msg); va_start(ap, msg);
vsnprintf(foo, 132, msg, ap); vsnprintf(foo, COLS - 3, msg, ap);
va_end(ap); va_end(ap);
start_x = COLS / 2 - strlen(foo) / 2 - 1; foo[COLS - 4] = '\0';
foo_len = strlen(foo);
start_x = (COLS - foo_len - 4) / 2;
/* Blank out line */ /* Blank out line */
blank_statusbar(); blank_statusbar();
wmove(bottomwin, 0, start_x); wmove(bottomwin, 0, start_x);
#ifdef ENABLE_COLOR
color_on(bottomwin, COLOR_STATUSBAR);
#else
wattron(bottomwin, A_REVERSE); wattron(bottomwin, A_REVERSE);
#endif
waddstr(bottomwin, "[ "); waddstr(bottomwin, "[ ");
waddstr(bottomwin, foo); waddstr(bottomwin, foo);
free(foo);
waddstr(bottomwin, " ]"); waddstr(bottomwin, " ]");
#ifdef ENABLE_COLOR
color_off(bottomwin, COLOR_STATUSBAR);
#else
wattroff(bottomwin, A_REVERSE); wattroff(bottomwin, A_REVERSE);
#endif
wrefresh(bottomwin); wrefresh(bottomwin);
...@@ -1666,12 +1486,6 @@ int total_refresh(void) ...@@ -1666,12 +1486,6 @@ int total_refresh(void)
return 1; return 1;
} }
void previous_line(void)
{
if (current_y > 0)
current_y--;
}
int do_cursorpos(int constant) int do_cursorpos(int constant)
{ {
filestruct *fileptr; filestruct *fileptr;
...@@ -1688,7 +1502,7 @@ int do_cursorpos(int constant) ...@@ -1688,7 +1502,7 @@ int do_cursorpos(int constant)
if (old_totsize == -1) if (old_totsize == -1)
old_totsize = totsize; old_totsize = totsize;
colpct = 100 * (xplustabs() + 1) / (xpt(current, strlen(current->data)) + 1); colpct = 100 * (xplustabs() + 1) / (strlenpt(current->data) + 1);
for (fileptr = fileage; fileptr != current && fileptr != NULL; for (fileptr = fileage; fileptr != current && fileptr != NULL;
fileptr = fileptr->next) fileptr = fileptr->next)
...@@ -1719,7 +1533,7 @@ int do_cursorpos(int constant) ...@@ -1719,7 +1533,7 @@ int do_cursorpos(int constant)
statusbar(_ statusbar(_
("line %d/%d (%.0f%%), col %ld/%ld (%.0f%%), char %ld/%ld (%.0f%%)"), ("line %d/%d (%.0f%%), col %ld/%ld (%.0f%%), char %ld/%ld (%.0f%%)"),
current->lineno, totlines, linepct, xplustabs() + 1, current->lineno, totlines, linepct, xplustabs() + 1,
xpt(current, strlen(current->data)) + 1, colpct, i, j, bytepct); strlenpt(current->data) + 1, colpct, i, j, bytepct);
} }
old_i = i; old_i = i;
...@@ -1741,7 +1555,7 @@ int do_help(void) ...@@ -1741,7 +1555,7 @@ int do_help(void)
#ifndef DISABLE_HELP #ifndef DISABLE_HELP
int i, j, row = 0, page = 1, kbinput = 0, no_more = 0, kp, kp2; int i, j, row = 0, page = 1, kbinput = 0, no_more = 0, kp, kp2;
int no_help_flag = 0; int no_help_flag = 0;
shortcut *oldshortcut; const shortcut *oldshortcut;
blank_edit(); blank_edit();
curs_set(0); curs_set(0);
...@@ -1889,24 +1703,21 @@ int do_help(void) ...@@ -1889,24 +1703,21 @@ int do_help(void)
kp = keypad_on(edit, kp); kp = keypad_on(edit, kp);
kp2 = keypad_on(bottomwin, kp2); kp2 = keypad_on(bottomwin, kp2);
#elif defined(DISABLE_HELP)
nano_disabled_msg();
#endif
/* The help_init() at the beginning allocated help_text, which has /* The help_init() at the beginning allocated help_text, which has
now been written to screen. */ now been written to screen. */
free(help_text); free(help_text);
help_text = NULL; help_text = NULL;
#elif defined(DISABLE_HELP)
nano_disabled_msg();
#endif
return 1; return 1;
} }
/* Dump the current file structure to stderr */
void dump_buffer(filestruct * inptr)
{
#ifdef DEBUG #ifdef DEBUG
filestruct *fileptr; /* Dump the current file structure to stderr */
void dump_buffer(const filestruct *inptr) {
if (inptr == fileage) if (inptr == fileage)
fprintf(stderr, _("Dumping file buffer to stderr...\n")); fprintf(stderr, _("Dumping file buffer to stderr...\n"));
else if (inptr == cutbuffer) else if (inptr == cutbuffer)
...@@ -1914,54 +1725,60 @@ void dump_buffer(filestruct * inptr) ...@@ -1914,54 +1725,60 @@ void dump_buffer(filestruct * inptr)
else else
fprintf(stderr, _("Dumping a buffer to stderr...\n")); fprintf(stderr, _("Dumping a buffer to stderr...\n"));
fileptr = inptr; while (inptr != NULL) {
while (fileptr != NULL) { fprintf(stderr, "(%d) %s\n", inptr->lineno, inptr->data);
fprintf(stderr, "(%d) %s\n", fileptr->lineno, fileptr->data); inptr = inptr->next;
fflush(stderr);
fileptr = fileptr->next;
} }
#endif /* DEBUG */
} }
#endif /* DEBUG */
void dump_buffer_reverse(filestruct * inptr)
{
#ifdef DEBUG #ifdef DEBUG
filestruct *fileptr; void dump_buffer_reverse(void) {
const filestruct *fileptr = filebot;
fileptr = filebot;
while (fileptr != NULL) { while (fileptr != NULL) {
fprintf(stderr, "(%d) %s\n", fileptr->lineno, fileptr->data); fprintf(stderr, "(%d) %s\n", fileptr->lineno, fileptr->data);
fflush(stderr);
fileptr = fileptr->prev; fileptr = fileptr->prev;
} }
#endif /* DEBUG */
} }
#endif /* DEBUG */
/* Fix editbot, based on the assumption that edittop is correct */ /* Fix editbot, based on the assumption that edittop is correct */
void fix_editbot(void) void fix_editbot(void)
{ {
int i; int i;
editbot = edittop; editbot = edittop;
for (i = 0; (i <= editwinrows - 1) && (editbot->next != NULL) for (i = 0; i < editwinrows && editbot->next != NULL; i++)
&& (editbot != filebot); i++, editbot = editbot->next); editbot = editbot->next;
} }
/* highlight the current word being replaced or spell checked */ /* highlight the current word being replaced or spell checked */
void do_replace_highlight(int highlight_flag, char *word) void do_replace_highlight(int highlight_flag, const char *word)
{ {
char *highlight_word = NULL; char *highlight_word = NULL;
int x, y; int x, y, word_len;
highlight_word = highlight_word =
mallocstrcpy(highlight_word, &current->data[current_x]); mallocstrcpy(highlight_word, &current->data[current_x]);
highlight_word[strlen(word)] = '\0';
#ifdef HAVE_REGEX_H
if (ISSET(USE_REGEXP))
/* if we're using regexps, the highlight is the length of the
search result, not the length of the regexp string */
word_len = regmatches[0].rm_eo - regmatches[0].rm_so;
else
#endif
word_len = strlen(word);
highlight_word[word_len] = '\0';
/* adjust output when word extends beyond screen */ /* adjust output when word extends beyond screen */
x = xplustabs(); x = xplustabs();
y = get_page_end_virtual(get_page_from_virtual(x)) + 1; y = get_page_start(x) + COLS;
if ((COLS - (y - x) + strlen(word)) > COLS) { if ((COLS - (y - x) + word_len) > COLS) {
highlight_word[y - x - 1] = '$'; highlight_word[y - x - 1] = '$';
highlight_word[y - x] = '\0'; highlight_word[y - x] = '\0';
} }
...@@ -1986,18 +1803,17 @@ void do_replace_highlight(int highlight_flag, char *word) ...@@ -1986,18 +1803,17 @@ void do_replace_highlight(int highlight_flag, char *word)
void do_credits(void) void do_credits(void)
{ {
int i, j = 0, k, place = 0, start_x; int i, j = 0, k, place = 0, start_x;
char *what; const char *what;
const char *nanotext = _("The nano text editor");
char *nanotext = _("The nano text editor"); const char *version = _("version ");
char *version = _("version "); const char *brought = _("Brought to you by:");
char *brought = _("Brought to you by:"); const char *specialthx = _("Special thanks to:");
char *specialthx = _("Special thanks to:"); const char *fsf = _("The Free Software Foundation");
char *fsf = _("The Free Software Foundation"); const char *ncurses = _("For ncurses:");
char *ncurses = _("For ncurses:"); const char *anyonelse = _("and anyone else we forgot...");
char *anyonelse = _("and anyone else we forgot..."); const char *thankyou = _("Thank you for using nano!\n");
char *thankyou = _("Thank you for using nano!\n");
const char *credits[CREDIT_LEN] = { nanotext,
char *credits[CREDIT_LEN] = { nanotext,
version, version,
VERSION, VERSION,
"", "",
...@@ -2090,17 +1906,13 @@ void do_credits(void) ...@@ -2090,17 +1906,13 @@ void do_credits(void)
int keypad_on(WINDOW * win, int newval) int keypad_on(WINDOW * win, int newval)
{ {
/* This is taken right from aumix. Don't sue me. */ /* This is taken right from aumix. Don't sue me. */
#ifdef HAVE_USEKEYPAD #ifdef HAVE_USEKEYPAD
int old; int old = win->_use_keypad;
old = win->_use_keypad;
keypad(win, newval); keypad(win, newval);
return old; return old;
#else #else
keypad(win, newval); keypad(win, newval);
return 1; return 1;
#endif /* HAVE_USEKEYPAD */ #endif /* HAVE_USEKEYPAD */
} }
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