overhaul the history code to work more consistently, and clean up
various parts of it; note that history tab completion has been removed git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2533 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
7ae4cc6964
commit
934f9687bb
|
@ -20,6 +20,15 @@ CVS code -
|
|||
do_gotolinecolumn()), do_gotoline_void() (renamed
|
||||
do_gotolinecolumn_void()), nano.1, and nano.texi. (DLR,
|
||||
suggested by PFTank)
|
||||
- Overhaul the history code to work more consistently, and clean
|
||||
up various parts of it. Note that history tab completion has
|
||||
been removed. New function history_has_changed(); changes to
|
||||
load_history(), writehist(), thanks_for_all_the_fish(),
|
||||
history_init(), find_node() (renamed find_history()),
|
||||
update_history(), get_history_older(), get_history_newer(),
|
||||
do_search(), do_replace(), nanogetstr(), and statusq();
|
||||
removal of remove_node(), insert_node(), and
|
||||
get_history_completion(). (DLR)
|
||||
- cut.c:
|
||||
cut_line()
|
||||
- Set placewewant properly after cutting a line, to avoid a
|
||||
|
|
39
src/files.c
39
src/files.c
|
@ -2866,7 +2866,12 @@ void load_history(void)
|
|||
;
|
||||
}
|
||||
} else {
|
||||
historyheadtype *history = &search_history;
|
||||
/* Load a history (first the search history, then the
|
||||
* replace history) from oldest to newest. Assume the last
|
||||
* history entry is a blank line. */
|
||||
filestruct **history = &search_history;
|
||||
filestruct **historyage = &searchage;
|
||||
filestruct **historybot = &searchbot;
|
||||
char *line = NULL;
|
||||
size_t buflen = 0;
|
||||
ssize_t read;
|
||||
|
@ -2878,31 +2883,38 @@ void load_history(void)
|
|||
}
|
||||
if (read > 0) {
|
||||
unsunder(line, read);
|
||||
update_history(history, line);
|
||||
} else
|
||||
update_history(history, historyage, historybot,
|
||||
line);
|
||||
} else {
|
||||
history = &replace_history;
|
||||
historyage = &replaceage;
|
||||
historybot = &replacebot;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(hist);
|
||||
free(line);
|
||||
UNSET(HISTORY_CHANGED);
|
||||
}
|
||||
free(nanohist);
|
||||
}
|
||||
}
|
||||
|
||||
bool writehist(FILE *hist, historyheadtype *histhead)
|
||||
bool writehist(FILE *hist, filestruct *h)
|
||||
{
|
||||
historytype *p;
|
||||
filestruct *p;
|
||||
|
||||
/* Write oldest history first. */
|
||||
for (p = histhead->tail; p->prev != NULL; p = p->prev) {
|
||||
/* Write history from oldest to newest. Assume the last history
|
||||
* entry is a blank line. */
|
||||
for (p = h; p != NULL; p = p->next) {
|
||||
size_t p_len = strlen(p->data);
|
||||
|
||||
sunder(p->data);
|
||||
|
||||
if (fwrite(p->data, sizeof(char), p_len, hist) < p_len ||
|
||||
putc('\n', hist) == EOF)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2912,8 +2924,8 @@ void save_history(void)
|
|||
char *nanohist;
|
||||
|
||||
/* Don't save unchanged or empty histories. */
|
||||
if (!ISSET(HISTORY_CHANGED) || (search_history.count == 0 &&
|
||||
replace_history.count == 0))
|
||||
if (!history_has_changed() || (searchbot->lineno == 1 &&
|
||||
replacebot->lineno == 1))
|
||||
return;
|
||||
|
||||
nanohist = histfilename();
|
||||
|
@ -2929,13 +2941,14 @@ void save_history(void)
|
|||
* history file. */
|
||||
chmod(nanohist, S_IRUSR | S_IWUSR);
|
||||
|
||||
if (!writehist(hist, &search_history) ||
|
||||
putc('\n', hist) == EOF ||
|
||||
!writehist(hist, &replace_history))
|
||||
if (!writehist(hist, searchage) || !writehist(hist,
|
||||
replaceage))
|
||||
rcfile_error(N_("Error writing %s: %s"), nanohist,
|
||||
strerror(errno));
|
||||
|
||||
fclose(hist);
|
||||
}
|
||||
|
||||
free(nanohist);
|
||||
}
|
||||
}
|
||||
|
|
12
src/global.c
12
src/global.c
|
@ -168,8 +168,12 @@ toggle *toggles = NULL;
|
|||
#endif
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
historyheadtype search_history;
|
||||
historyheadtype replace_history;
|
||||
filestruct *search_history = NULL;
|
||||
filestruct *searchage = NULL;
|
||||
filestruct *searchbot = NULL;
|
||||
filestruct *replace_history = NULL;
|
||||
filestruct *replaceage = NULL;
|
||||
filestruct *replacebot = NULL;
|
||||
#endif
|
||||
|
||||
/* Regular expressions */
|
||||
|
@ -1260,8 +1264,8 @@ void thanks_for_all_the_fish(void)
|
|||
#endif /* ENABLE_COLOR */
|
||||
#ifndef NANO_SMALL
|
||||
/* Free the history lists. */
|
||||
free_history(&search_history);
|
||||
free_history(&replace_history);
|
||||
free_filestruct(searchage);
|
||||
free_filestruct(replaceage);
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
free(homedir);
|
||||
|
|
35
src/nano.h
35
src/nano.h
|
@ -265,25 +265,6 @@ typedef struct syntaxtype {
|
|||
} syntaxtype;
|
||||
#endif
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
typedef struct historytype {
|
||||
struct historytype *next;
|
||||
struct historytype *prev;
|
||||
char *data;
|
||||
} historytype;
|
||||
|
||||
typedef struct historyheadtype {
|
||||
struct historytype *next; /* Keep *next and *prev members
|
||||
* together. */
|
||||
struct historytype *prev; /* And in the same order as in
|
||||
* historytype. */
|
||||
struct historytype *tail;
|
||||
struct historytype *current;
|
||||
int count;
|
||||
int len;
|
||||
} historyheadtype;
|
||||
#endif
|
||||
|
||||
/* Bitwise flags so that we can save space (or, more correctly, not
|
||||
* waste it). */
|
||||
#define MODIFIED (1<<0)
|
||||
|
@ -310,13 +291,12 @@ typedef struct historyheadtype {
|
|||
#define NO_RCFILE (1<<21)
|
||||
#define NO_COLOR_SYNTAX (1<<22)
|
||||
#define PRESERVE (1<<23)
|
||||
#define HISTORY_CHANGED (1<<24)
|
||||
#define HISTORYLOG (1<<25)
|
||||
#define RESTRICTED (1<<26)
|
||||
#define SMART_HOME (1<<27)
|
||||
#define WHITESPACE_DISPLAY (1<<28)
|
||||
#define MORE_SPACE (1<<29)
|
||||
#define NO_UTF8 (1<<30)
|
||||
#define HISTORYLOG (1<<24)
|
||||
#define RESTRICTED (1<<25)
|
||||
#define SMART_HOME (1<<26)
|
||||
#define WHITESPACE_DISPLAY (1<<27)
|
||||
#define MORE_SPACE (1<<28)
|
||||
#define NO_UTF8 (1<<29)
|
||||
|
||||
/* Control key sequences. Changing these would be very, very bad. */
|
||||
#define NANO_CONTROL_SPACE 0
|
||||
|
@ -518,7 +498,8 @@ typedef struct historyheadtype {
|
|||
/* Default width of a tab. */
|
||||
#define WIDTH_OF_TAB 8
|
||||
|
||||
/* Maximum number of search/replace history strings saved. */
|
||||
/* Maximum number of search/replace history strings saved, not counting
|
||||
* the blank lines at their ends. */
|
||||
#define MAX_SEARCH_HISTORY 100
|
||||
|
||||
/* Maximum number of bytes we read from a file at one time. */
|
||||
|
|
30
src/proto.h
30
src/proto.h
|
@ -144,8 +144,12 @@ extern toggle *toggles;
|
|||
#endif
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
extern historyheadtype search_history;
|
||||
extern historyheadtype replace_history;
|
||||
extern filestruct *search_history;
|
||||
extern filestruct *searchage;
|
||||
extern filestruct *searchbot;
|
||||
extern filestruct *replace_history;
|
||||
extern filestruct *replaceage;
|
||||
extern filestruct *replacebot;
|
||||
#endif
|
||||
|
||||
extern bool curses_ended;
|
||||
|
@ -316,7 +320,7 @@ char *do_browse_from(const char *inpath);
|
|||
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
||||
char *histfilename(void);
|
||||
void load_history(void);
|
||||
bool writehist(FILE *hist, historyheadtype *histhead);
|
||||
bool writehist(FILE *hist, filestruct *histhead);
|
||||
void save_history(void);
|
||||
#endif
|
||||
|
||||
|
@ -524,17 +528,13 @@ void do_gotopos(int line, size_t pos_x, int pos_y, size_t pos_pww);
|
|||
#endif
|
||||
void do_find_bracket(void);
|
||||
#ifndef NANO_SMALL
|
||||
bool history_has_changed(void);
|
||||
void history_init(void);
|
||||
historytype *find_node(historytype *h, const char *s);
|
||||
void remove_node(historytype *r);
|
||||
void insert_node(historytype *h, const char *s);
|
||||
void update_history(historyheadtype *h, const char *s);
|
||||
char *get_history_older(historyheadtype *h);
|
||||
char *get_history_newer(historyheadtype *h);
|
||||
char *get_history_completion(historyheadtype *h, char *s);
|
||||
#ifdef DEBUG
|
||||
void free_history(historyheadtype *h);
|
||||
#endif
|
||||
filestruct *find_history(filestruct *h, const char *s);
|
||||
void update_history(filestruct **h, filestruct **hage, filestruct
|
||||
**hbot, const char *s);
|
||||
char *get_history_older(filestruct **h);
|
||||
char *get_history_newer(filestruct **h);
|
||||
#endif
|
||||
|
||||
/* Public functions in utils.c. */
|
||||
|
@ -652,7 +652,7 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
|
|||
void nanoget_repaint(const char *buf, const char *inputbuf, size_t x);
|
||||
int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
||||
#ifndef NANO_SMALL
|
||||
historyheadtype *history_list,
|
||||
filestruct *history_list,
|
||||
#endif
|
||||
const shortcut *s
|
||||
#ifndef DISABLE_TABCOMP
|
||||
|
@ -661,7 +661,7 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
|||
);
|
||||
int statusq(bool allow_tabs, const shortcut *s, const char *curranswer,
|
||||
#ifndef NANO_SMALL
|
||||
historyheadtype *history_list,
|
||||
filestruct *history_list,
|
||||
#endif
|
||||
const char *msg, ...);
|
||||
void statusq_abort(void);
|
||||
|
|
224
src/search.c
224
src/search.c
|
@ -35,6 +35,10 @@
|
|||
|
||||
static bool search_last_line = FALSE;
|
||||
/* Have we gone past the last line while searching? */
|
||||
#ifndef NANO_SMALL
|
||||
static bool history_changed = FALSE;
|
||||
/* Have any of the history lists changed? */
|
||||
#endif
|
||||
#ifdef HAVE_REGEX_H
|
||||
static bool regexp_compiled = FALSE;
|
||||
/* Have we compiled any regular expressions? */
|
||||
|
@ -145,10 +149,6 @@ int search_init(bool replacing, bool use_answer)
|
|||
|
||||
search_init_globals();
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
search_history.current = (historytype *)&search_history.next;
|
||||
#endif
|
||||
|
||||
if (last_search[0] != '\0') {
|
||||
char *disp = display_string(last_search, 0, COLS / 3, FALSE);
|
||||
|
||||
|
@ -165,7 +165,7 @@ int search_init(bool replacing, bool use_answer)
|
|||
i = statusq(FALSE, replacing ? replace_list : whereis_list,
|
||||
backupstring,
|
||||
#ifndef NANO_SMALL
|
||||
&search_history,
|
||||
search_history,
|
||||
#endif
|
||||
"%s%s%s%s%s%s", _("Search"),
|
||||
|
||||
|
@ -212,9 +212,6 @@ int search_init(bool replacing, bool use_answer)
|
|||
if (i == -1 || (i < 0 && last_search[0] == '\0') ||
|
||||
(!replacing && i == 0 && answer[0] == '\0')) {
|
||||
statusbar(_("Cancelled"));
|
||||
#ifndef NANO_SMALL
|
||||
search_history.current = search_history.next;
|
||||
#endif
|
||||
return -1;
|
||||
} else {
|
||||
switch (i) {
|
||||
|
@ -252,9 +249,6 @@ int search_init(bool replacing, bool use_answer)
|
|||
backupstring = mallocstrcpy(backupstring, answer);
|
||||
return -2; /* Call the opposite search function. */
|
||||
case NANO_TOGOTOLINE_KEY:
|
||||
#ifndef NANO_SMALL
|
||||
search_history.current = search_history.next;
|
||||
#endif
|
||||
do_gotolinecolumn(current->lineno, placewewant, TRUE,
|
||||
TRUE, FALSE);
|
||||
/* Put answer up on the statusbar and
|
||||
|
@ -481,7 +475,7 @@ void do_search(void)
|
|||
/* If answer is not "", add this search string to the search history
|
||||
* list. */
|
||||
if (answer[0] != '\0')
|
||||
update_history(&search_history, answer);
|
||||
update_history(&search_history, &searchage, &searchbot, answer);
|
||||
#endif
|
||||
|
||||
findnextstr_wrap_reset();
|
||||
|
@ -910,19 +904,14 @@ void do_replace(void)
|
|||
* copy answer into last_search. */
|
||||
if (answer[0] != '\0') {
|
||||
#ifndef NANO_SMALL
|
||||
update_history(&search_history, answer);
|
||||
update_history(&search_history, &searchage, &searchbot, answer);
|
||||
#endif
|
||||
last_search = mallocstrcpy(last_search, answer);
|
||||
}
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
replace_history.current = (historytype *)&replace_history.next;
|
||||
last_replace = mallocstrcpy(last_replace, "");
|
||||
#endif
|
||||
|
||||
i = statusq(FALSE, replace_list_2, last_replace,
|
||||
#ifndef NANO_SMALL
|
||||
&replace_history,
|
||||
replace_history,
|
||||
#endif
|
||||
_("Replace with"));
|
||||
|
||||
|
@ -930,7 +919,8 @@ void do_replace(void)
|
|||
/* Add this replace string to the replace history list. i == 0
|
||||
* means that the string is not "". */
|
||||
if (i == 0)
|
||||
update_history(&replace_history, answer);
|
||||
update_history(&replace_history, &replaceage, &replacebot,
|
||||
answer);
|
||||
#endif
|
||||
|
||||
if (i != 0 && i != -2) {
|
||||
|
@ -1126,129 +1116,123 @@ void do_find_bracket(void)
|
|||
#endif
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
/*
|
||||
* search and replace history list support functions
|
||||
*/
|
||||
|
||||
/* initialize search and replace history lists */
|
||||
void history_init(void)
|
||||
/* Indicate whether any of the history lists have changed. */
|
||||
bool history_has_changed(void)
|
||||
{
|
||||
search_history.next = (historytype *)&search_history.prev;
|
||||
search_history.prev = NULL;
|
||||
search_history.tail = (historytype *)&search_history.next;
|
||||
search_history.current = search_history.next;
|
||||
search_history.count = 0;
|
||||
search_history.len = 0;
|
||||
|
||||
replace_history.next = (historytype *)&replace_history.prev;
|
||||
replace_history.prev = NULL;
|
||||
replace_history.tail = (historytype *)&replace_history.next;
|
||||
replace_history.current = replace_history.next;
|
||||
replace_history.count = 0;
|
||||
replace_history.len = 0;
|
||||
return history_changed;
|
||||
}
|
||||
|
||||
/* find first node containing string *s in history list *h */
|
||||
historytype *find_node(historytype *h, const char *s)
|
||||
/* Initialize the search and replace history lists. */
|
||||
void history_init(void)
|
||||
{
|
||||
search_history = make_new_node(NULL);
|
||||
search_history->data = mallocstrcpy(NULL, "");
|
||||
searchage = search_history;
|
||||
searchbot = search_history;
|
||||
|
||||
replace_history = make_new_node(NULL);
|
||||
replace_history->data = mallocstrcpy(NULL, "");
|
||||
replaceage = replace_history;
|
||||
replacebot = replace_history;
|
||||
}
|
||||
|
||||
/* Return the first node containing the string s in the history list,
|
||||
* starting at h, or NULL if there isn't one. */
|
||||
filestruct *find_history(filestruct *h, const char *s)
|
||||
{
|
||||
assert(h != NULL);
|
||||
|
||||
for (; h->next != NULL; h = h->next) {
|
||||
if (strcmp(s, h->data) == 0)
|
||||
return h;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* remove node *r */
|
||||
void remove_node(historytype *r)
|
||||
/* Update a history list. h should be the current position in the list,
|
||||
* hage should be the top of the list, and hbot should be the bottom of
|
||||
* the list. */
|
||||
void update_history(filestruct **h, filestruct **hage, filestruct
|
||||
**hbot, const char *s)
|
||||
{
|
||||
r->prev->next = r->next;
|
||||
r->next->prev = r->prev;
|
||||
free(r->data);
|
||||
free(r);
|
||||
}
|
||||
filestruct *p;
|
||||
|
||||
/* add a node after node *h */
|
||||
void insert_node(historytype *h, const char *s)
|
||||
{
|
||||
historytype *a;
|
||||
assert(h != NULL && hage != NULL && hbot != NULL && s != NULL);
|
||||
|
||||
a = (historytype *)nmalloc(sizeof(historytype));
|
||||
a->next = h->next;
|
||||
a->prev = h;
|
||||
h->next->prev = a;
|
||||
h->next = a;
|
||||
a->data = mallocstrcpy(NULL, s);
|
||||
}
|
||||
/* If this string is already in the history, delete it. */
|
||||
p = find_history(*hage, s);
|
||||
|
||||
/* update history list */
|
||||
void update_history(historyheadtype *h, const char *s)
|
||||
{
|
||||
historytype *p;
|
||||
if (p != NULL) {
|
||||
filestruct *foo, *bar;
|
||||
|
||||
if ((p = find_node(h->next, s)) != NULL) {
|
||||
if (p == h->next) /* catch delete and re-insert of
|
||||
same string in 1st node */
|
||||
goto up_hs;
|
||||
remove_node(p); /* delete identical older string */
|
||||
h->count--;
|
||||
/* If the string is at the current position, don't do
|
||||
* anything. */
|
||||
if (p == *h)
|
||||
return;
|
||||
|
||||
/* If the string is at the beginning, move the beginning down to
|
||||
* the next string. */
|
||||
if (p == *hage)
|
||||
*hage = (*hage)->next;
|
||||
|
||||
/* Delete the string. */
|
||||
foo = p;
|
||||
bar = p->next;
|
||||
unlink_node(foo);
|
||||
delete_node(foo);
|
||||
renumber(bar);
|
||||
}
|
||||
if (h->count == MAX_SEARCH_HISTORY) { /* list 'full', delete oldest */
|
||||
remove_node(h->tail);
|
||||
h->count--;
|
||||
|
||||
/* If the history is full, delete the beginning entry to make room
|
||||
* for the new entry at the end. */
|
||||
if ((*hbot)->lineno == MAX_SEARCH_HISTORY + 1) {
|
||||
filestruct *foo = *hage;
|
||||
|
||||
*hage = (*hage)->next;
|
||||
unlink_node(foo);
|
||||
delete_node(foo);
|
||||
renumber(*hage);
|
||||
}
|
||||
insert_node((historytype *)h, s);
|
||||
h->count++;
|
||||
SET(HISTORY_CHANGED);
|
||||
up_hs:
|
||||
h->current = h->next;
|
||||
|
||||
/* Add the new entry to the end. */
|
||||
(*hbot)->data = mallocstrcpy(NULL, s);
|
||||
splice_node(*hbot, make_new_node(*hbot), (*hbot)->next);
|
||||
*hbot = (*hbot)->next;
|
||||
(*hbot)->data = mallocstrcpy(NULL, "");
|
||||
|
||||
/* Indicate that the history's been changed. */
|
||||
history_changed = TRUE;
|
||||
|
||||
/* Set the current position in the list to the bottom. */
|
||||
*h = *hbot;
|
||||
}
|
||||
|
||||
/* return a pointer to either the next older history or NULL if no more */
|
||||
char *get_history_older(historyheadtype *h)
|
||||
/* Return the string in the history list just before h, or NULL if there
|
||||
* isn't one. */
|
||||
char *get_history_older(filestruct **h)
|
||||
{
|
||||
if (h->current->next != NULL) { /* any older entries? */
|
||||
h->current = h->current->next; /* yes */
|
||||
return h->current->data; /* return it */
|
||||
}
|
||||
return NULL; /* end of list */
|
||||
assert(h != NULL);
|
||||
|
||||
if ((*h)->prev == NULL)
|
||||
return NULL;
|
||||
|
||||
*h = (*h)->prev;
|
||||
|
||||
return (*h)->data;
|
||||
}
|
||||
|
||||
char *get_history_newer(historyheadtype *h)
|
||||
/* Return the string in the history list just after h, or NULL if there
|
||||
* isn't one. */
|
||||
char *get_history_newer(filestruct **h)
|
||||
{
|
||||
if (h->current->prev != NULL) {
|
||||
h->current = h->current->prev;
|
||||
if (h->current->prev != NULL)
|
||||
return h->current->data;
|
||||
}
|
||||
return NULL;
|
||||
assert(h != NULL);
|
||||
|
||||
if ((*h)->next == NULL)
|
||||
return NULL;
|
||||
|
||||
*h = (*h)->next;
|
||||
|
||||
return (*h)->data;
|
||||
}
|
||||
|
||||
/* get a completion */
|
||||
char *get_history_completion(historyheadtype *h, char *s)
|
||||
{
|
||||
historytype *p;
|
||||
|
||||
for (p = h->current->next; p->next != NULL; p = p->next) {
|
||||
if (strncmp(s, p->data, h->len) == 0 && strlen(p->data) != h->len) {
|
||||
h->current = p;
|
||||
return p->data;
|
||||
}
|
||||
}
|
||||
h->current = (historytype *)h;
|
||||
null_at(&s, h->len);
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* free a history list */
|
||||
void free_history(historyheadtype *h)
|
||||
{
|
||||
historytype *p;
|
||||
|
||||
for (p = h->next; p->next != NULL; p = p->next)
|
||||
remove_node(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* end of history support functions */
|
||||
#endif /* !NANO_SMALL */
|
||||
|
|
139
src/winio.c
139
src/winio.c
|
@ -2430,7 +2430,7 @@ void nanoget_repaint(const char *buf, const char *inputbuf, size_t x)
|
|||
* statusq(). */
|
||||
int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
||||
#ifndef NANO_SMALL
|
||||
historyheadtype *history_list,
|
||||
filestruct *history_list,
|
||||
#endif
|
||||
const shortcut *s
|
||||
#ifndef DISABLE_TABCOMP
|
||||
|
@ -2443,23 +2443,15 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
|||
size_t answer_len = strlen(curranswer);
|
||||
#ifndef DISABLE_TABCOMP
|
||||
bool tabbed = FALSE;
|
||||
/* Used by input_tab(). */
|
||||
/* Whether we've pressed Tab more than once consecutively. */
|
||||
#endif
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
/* For history. */
|
||||
char *history = NULL;
|
||||
char *currentbuf = NULL;
|
||||
char *complete = NULL;
|
||||
int last_kbinput = 0;
|
||||
|
||||
/* This variable is used in the search history code. use_cb == 0
|
||||
* means that we're using the existing history and ignoring
|
||||
* currentbuf. use_cb == 1 means that the entry in answer should be
|
||||
* moved to currentbuf or restored from currentbuf to answer.
|
||||
* use_cb == 2 means that the entry in currentbuf should be moved to
|
||||
* answer or restored from answer to currentbuf. */
|
||||
int use_cb = 0;
|
||||
/* The current history string. */
|
||||
char *magichistory = NULL;
|
||||
/* The temporary string typed at the bottom of the history, if
|
||||
* any. */
|
||||
#endif
|
||||
|
||||
/* Only put statusbar_x at the end of the string if it's
|
||||
|
@ -2500,28 +2492,6 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
|||
|
||||
switch (kbinput) {
|
||||
case NANO_TAB_KEY:
|
||||
#ifndef NANO_SMALL
|
||||
/* Tab history completion. */
|
||||
if (history_list != NULL) {
|
||||
if (complete == NULL ||
|
||||
last_kbinput != NANO_TAB_KEY) {
|
||||
history_list->current =
|
||||
(historytype *)history_list;
|
||||
history_list->len = strlen(answer);
|
||||
}
|
||||
|
||||
if (history_list->len > 0) {
|
||||
complete = get_history_completion(history_list,
|
||||
answer);
|
||||
answer = mallocstrcpy(answer, complete);
|
||||
answer_len = strlen(answer);
|
||||
statusbar_x = answer_len;
|
||||
}
|
||||
}
|
||||
#ifndef DISABLE_TABCOMP
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_TABCOMP
|
||||
if (allow_tabs) {
|
||||
answer = input_tab(answer, &statusbar_x, &tabbed,
|
||||
|
@ -2533,43 +2503,23 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
|||
case NANO_PREVLINE_KEY:
|
||||
#ifndef NANO_SMALL
|
||||
if (history_list != NULL) {
|
||||
/* If currentbuf is NULL, or if use_cb is 1 and
|
||||
* currentbuf is different from answer, it means
|
||||
* that we're scrolling up at the top of the search
|
||||
* history, and we need to save the current answer
|
||||
* in currentbuf. Do this and reset use_cb to 0. */
|
||||
if (currentbuf == NULL || (use_cb == 1 &&
|
||||
strcmp(currentbuf, answer) != 0)) {
|
||||
currentbuf = mallocstrcpy(currentbuf, answer);
|
||||
use_cb = 0;
|
||||
}
|
||||
/* If we're scrolling up at the bottom of the
|
||||
* history list, answer isn't blank, and
|
||||
* magichistory isn't set, save answer in
|
||||
* magichistory. */
|
||||
if (history_list->next == NULL &&
|
||||
answer[0] != '\0' && magichistory == NULL)
|
||||
magichistory = mallocstrcpy(NULL, answer);
|
||||
|
||||
/* If currentbuf isn't NULL, use_cb is 2, and
|
||||
* currentbuf is different from answer, it means
|
||||
* that we're scrolling up at the bottom of the
|
||||
* search history, and we need to restore the
|
||||
* current answer from currentbuf. Do this, blow
|
||||
* away currentbuf since we don't need it anymore,
|
||||
* and reset use_cb to 0. */
|
||||
if (currentbuf != NULL && use_cb == 2 &&
|
||||
strcmp(currentbuf, answer) != 0) {
|
||||
answer = mallocstrcpy(answer, currentbuf);
|
||||
answer_len = strlen(answer);
|
||||
free(currentbuf);
|
||||
currentbuf = NULL;
|
||||
use_cb = 0;
|
||||
/* Otherwise, get the older search from the history
|
||||
* list and save it in answer. If there is no older
|
||||
* search, blank out answer. */
|
||||
} else if ((history =
|
||||
get_history_older(history_list)) != NULL) {
|
||||
/* Get the older search from the history list and
|
||||
* save it in answer. If there is no older search,
|
||||
* don't do anything. */
|
||||
if ((history =
|
||||
get_history_older(&history_list)) != NULL) {
|
||||
answer = mallocstrcpy(answer, history);
|
||||
answer_len = strlen(history);
|
||||
} else {
|
||||
answer = mallocstrcpy(answer, "");
|
||||
answer_len = 0;
|
||||
answer_len = strlen(answer);
|
||||
statusbar_x = answer_len;
|
||||
}
|
||||
statusbar_x = answer_len;
|
||||
|
||||
/* This key has a shortcut list entry when it's used
|
||||
* to move to an older search, which means that
|
||||
|
@ -2584,39 +2534,25 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
|||
#ifndef NANO_SMALL
|
||||
if (history_list != NULL) {
|
||||
/* Get the newer search from the history list and
|
||||
* save it in answer. */
|
||||
* save it in answer. If there is no newer search,
|
||||
* don't do anything. */
|
||||
if ((history =
|
||||
get_history_newer(history_list)) != NULL) {
|
||||
get_history_newer(&history_list)) != NULL) {
|
||||
answer = mallocstrcpy(answer, history);
|
||||
answer_len = strlen(history);
|
||||
/* If currentbuf isn't NULL and use_cb isn't 2, it
|
||||
* means that we're scrolling down at the bottom of
|
||||
* the search history and we need to restore the
|
||||
* current answer from currentbuf. Do this, blow
|
||||
* away currentbuf since we don't need it anymore,
|
||||
* and set use_cb to 1. */
|
||||
} else if (currentbuf != NULL && use_cb != 2) {
|
||||
answer = mallocstrcpy(answer, currentbuf);
|
||||
answer_len = strlen(answer);
|
||||
free(currentbuf);
|
||||
currentbuf = NULL;
|
||||
use_cb = 1;
|
||||
/* Otherwise, if currentbuf is NULL and use_cb isn't
|
||||
* 2, it means that we're scrolling down at the
|
||||
* bottom of the search history and we need to save
|
||||
* the current answer (if it's not blank) in
|
||||
* currentbuf. Do this, blank out answer, and set
|
||||
* use_cb to 2. */
|
||||
} else if (use_cb != 2) {
|
||||
if (answer[0] != '\0') {
|
||||
currentbuf = mallocstrcpy(currentbuf,
|
||||
answer);
|
||||
answer = mallocstrcpy(answer, "");
|
||||
}
|
||||
answer_len = 0;
|
||||
use_cb = 2;
|
||||
statusbar_x = answer_len;
|
||||
}
|
||||
|
||||
/* If, after scrolling down, we're at the bottom of
|
||||
* the history list, answer is blank, and
|
||||
* magichistory is set, save magichistory in
|
||||
* answer. */
|
||||
if (history_list->next == NULL &&
|
||||
answer[0] == '\0' && magichistory != NULL) {
|
||||
answer = mallocstrcpy(answer, magichistory);
|
||||
answer_len = strlen(answer);
|
||||
statusbar_x = answer_len;
|
||||
}
|
||||
statusbar_x = answer_len;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
@ -2628,9 +2564,6 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
|||
if (finished)
|
||||
break;
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
last_kbinput = kbinput;
|
||||
#endif
|
||||
nanoget_repaint(buf, answer, statusbar_x);
|
||||
wrefresh(bottomwin);
|
||||
}
|
||||
|
@ -2653,7 +2586,7 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *curranswer,
|
|||
* completion. */
|
||||
int statusq(bool allow_tabs, const shortcut *s, const char *curranswer,
|
||||
#ifndef NANO_SMALL
|
||||
historyheadtype *history_list,
|
||||
filestruct *history_list,
|
||||
#endif
|
||||
const char *msg, ...)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue