Ken's search history patch, minus the .nano_history stuff

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1334 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2003-01-05 20:41:21 +00:00
parent 95e0cf584c
commit 5beed509a6
9 changed files with 418 additions and 62 deletions

View File

@ -1,5 +1,11 @@
CVS code -
Changes
- General:
- Search history and replace history up/down cursor arrows, w/history
tab completion, not available w/NANO_SMALL. Changes to
statusq, others (Ken Tyler). Added shortcut to search/replace
shortcuts so people will know it's there, forced KEY_UP and KEY_DOWN
defs in nano.h (Chris, in case blame needs to be placed later).
- Translation updates (see po/ChangeLog for details).
- Forward-ported Chris' --disable-wrapping-as-root option from
1.0.9. Per Jordi's suggestions, have it override
@ -62,6 +68,8 @@ CVS code -
- If there's a page or less of text, do an edit_update() if the
mark is on; otherwise, the highlight won't be displayed. (DLR)
- nano.c:
- Added free_history list calls clean up, added init of list headers
modified statusq calls (Ken Tyler).
do_prev_word()
- Make the assert match that in do_next_word(). (DLR)
do_enter()

36
files.c
View File

@ -426,21 +426,21 @@ int do_insertfile(int loading_file)
if (operating_dir != NULL && strcmp(operating_dir, ".") != 0)
#ifdef ENABLE_MULTIBUFFER
if (ISSET(MULTIBUFFER))
i = statusq(1, insertfile_list, inspath, _("File to insert into new buffer [from %s] "),
i = statusq(1, insertfile_list, inspath, 0, _("File to insert into new buffer [from %s] "),
operating_dir);
else
#endif
i = statusq(1, insertfile_list, inspath, _("File to insert [from %s] "),
i = statusq(1, insertfile_list, inspath, 0, _("File to insert [from %s] "),
operating_dir);
else
#endif
#ifdef ENABLE_MULTIBUFFER
if (ISSET(MULTIBUFFER))
i = statusq(1, insertfile_list, inspath, _("File to insert into new buffer [from ./] "));
i = statusq(1, insertfile_list, inspath, 0, _("File to insert into new buffer [from ./] "));
else
#endif
i = statusq(1, insertfile_list, inspath, _("File to insert [from ./] "));
i = statusq(1, insertfile_list, inspath, 0, _("File to insert [from ./] "));
if (i != -1) {
inspath = mallocstrcpy(inspath, answer);
@ -492,7 +492,7 @@ int do_insertfile(int loading_file)
#endif /* ENABLE_MULTIBUFFER */
if (i == NANO_EXTCMD_KEY) {
int ts;
ts = statusq(1, extcmd_list, "", _("Command to execute "));
ts = statusq(1, extcmd_list, "", 0, _("Command to execute "));
if (ts == -1 || answer == NULL || answer[0] == '\0') {
statusbar(_("Cancelled"));
UNSET(KEEP_CUTBUFFER);
@ -1711,34 +1711,34 @@ int do_writeout(const char *path, int exiting, int append)
/* Be nice to the translation folks */
if (ISSET(MARK_ISSET) && !exiting) {
if (append == 2)
i = statusq(1, writefile_list, "",
i = statusq(1, writefile_list, "", 0,
"%s%s%s", _("Prepend Selection to File"), formatstr, backupstr);
else if (append == 1)
i = statusq(1, writefile_list, "",
else if (append)
i = statusq(1, writefile_list, "", 0,
"%s%s%s", _("Append Selection to File"), formatstr, backupstr);
else
i = statusq(1, writefile_list, "",
i = statusq(1, writefile_list, "", 0,
"%s%s%s", _("Write Selection to File"), formatstr, backupstr);
} else {
if (append == 2)
i = statusq(1, writefile_list, answer,
i = statusq(1, writefile_list, answer, 0,
"%s%s%s", _("File Name to Prepend to"), formatstr, backupstr);
else if (append == 1)
i = statusq(1, writefile_list, answer,
else if (append)
i = statusq(1, writefile_list, answer, 0,
"%s%s%s", _("File Name to Append to"), formatstr, backupstr);
else
i = statusq(1, writefile_list, answer,
i = statusq(1, writefile_list, answer, 0,
"%s%s%s", _("File Name to Write"), formatstr, backupstr);
}
#else
if (append == 2)
i = statusq(1, writefile_list, answer,
i = statusq(1, writefile_list, answer, 0,
"%s", _("File Name to Prepend to"));
else if (append == 1)
i = statusq(1, writefile_list, answer,
else if (append)
i = statusq(1, writefile_list, answer, 0,
"%s", _("File Name to Append to"));
else
i = statusq(1, writefile_list, answer,
i = statusq(1, writefile_list, answer, 0,
"%s", _("File Name to Write"));
#endif /* !NANO_SMALL */
@ -2650,7 +2650,7 @@ char *do_browser(const char *inpath)
case NANO_GOTO_KEY:
curs_set(1);
j = statusq(0, gotodir_list, "", _("Goto Directory"));
j = statusq(0, gotodir_list, "", 0, _("Goto Directory"));
bottombars(browser_list);
curs_set(0);

View File

@ -36,6 +36,7 @@ int wrap_at = -CHARS_FROM_EOL;/* Right justified fill value, allows resize */
char *last_search = NULL; /* Last string we searched for */
char *last_replace = NULL; /* Last replacement string */
int search_last_line; /* Is this the last search line? */
int past_editbuff; /* search lines not displayed */
int flags = 0; /* Our new flag containing many options */
WINDOW *edit; /* The file portion of the editor */
@ -134,6 +135,11 @@ const shortcut *currshortcut; /* Current shortcut list we're using */
toggle *toggles = NULL;
#endif
#ifndef NANO_SMALL
historyheadtype search_history;
historyheadtype replace_history;
#endif
/* Regular expressions */
#ifdef HAVE_REGEX_H
@ -327,7 +333,7 @@ void shortcut_init(int unjustify)
"", *nano_gotodir_msg = "", *nano_case_msg =
"", *nano_reverse_msg = "", *nano_execute_msg =
"", *nano_dos_msg = "", *nano_mac_msg =
"", *nano_backup_msg = "";
"", *nano_backup_msg = "", *nano_editstr_msg = "";
#ifdef ENABLE_MULTIBUFFER
const char *nano_openprev_msg = "", *nano_opennext_msg =
@ -383,6 +389,7 @@ void shortcut_init(int unjustify)
nano_dos_msg = _("Write file out in DOS format");
nano_mac_msg = _("Write file out in Mac format");
nano_backup_msg = _("Back up original file when saving");
nano_editstr_msg = _("Edit the previous search/replace strings");
#ifdef HAVE_REGEX_H
nano_regexp_msg = _("Use regular expressions");
nano_bracket_msg = _("Find other bracket");
@ -606,6 +613,14 @@ void shortcut_init(int unjustify)
sc_init_one(&whereis_list, TOGGLE_REGEXP_KEY, _("Regexp"),
IFHELP(nano_regexp_msg, 0), 0, 0, VIEW, 0);
#endif
#ifndef NANO_SMALL
sc_init_one(&whereis_list, KEY_UP, _("History"),
IFHELP(nano_editstr_msg, 0), 0, 0, VIEW, 0);
#endif
#endif /* !NANO_SMALL */
free_shortcutage(&replace_list);
@ -639,6 +654,12 @@ void shortcut_init(int unjustify)
sc_init_one(&replace_list, TOGGLE_REGEXP_KEY, _("Regexp"),
IFHELP(nano_regexp_msg, 0), 0, 0, VIEW, 0);
#endif
#ifndef NANO_SMALL
sc_init_one(&replace_list, KEY_UP, _("History"),
IFHELP(nano_editstr_msg, 0), 0, 0, VIEW, 0);
#endif
#endif /* !NANO_SMALL */
free_shortcutage(&replace_list_2);
@ -655,6 +676,11 @@ void shortcut_init(int unjustify)
sc_init_one(&replace_list_2, NANO_LASTLINE_KEY, _("Last Line"),
IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line);
#ifndef NANO_SMALL
sc_init_one(&replace_list_2, KEY_UP, _("History"),
IFHELP(nano_editstr_msg, 0), 0, 0, VIEW, 0);
#endif
free_shortcutage(&goto_list);
sc_init_one(&goto_list, NANO_HELP_KEY, _("Get Help"),
@ -885,5 +911,10 @@ void thanks_for_all_the_fish(void)
free(bill);
}
#endif /* ENABLE_COLOR */
#ifndef NANO_SMALL
/* free history lists */
free_history(&search_history);
free_history(&replace_history);
#endif
}
#endif /* DEBUG */

13
nano.c
View File

@ -66,6 +66,12 @@ static sigjmp_buf jmpbuf; /* Used to return to mainloop after SIGWINCH */
/* What we do when we're all set to exit */
RETSIGTYPE finish(int sigage)
{
#ifndef NANO_SMALL
free_history(&search_history);
free_history(&replace_history);
#endif
keypad(edit, TRUE);
keypad(bottomwin, TRUE);
@ -1633,7 +1639,7 @@ int do_int_spell_fix(const char *word)
do_replace_highlight(TRUE, word);
/* allow replace word to be corrected */
i = statusq(0, spell_list, last_replace, _("Edit a replacement"));
i = statusq(0, spell_list, last_replace, 0, _("Edit a replacement"));
do_replace_highlight(FALSE, word);
@ -3093,6 +3099,7 @@ int main(int argc, char *argv[])
#endif
}
}
if (!ISSET(NO_RCFILE))
do_rcfile();
#else
@ -3334,6 +3341,10 @@ int main(int argc, char *argv[])
keypad(bottomwin, TRUE);
}
#ifndef NANO_SMALL
history_init();
#endif
#ifdef ENABLE_COLOR
do_colorinit();
#endif /* ENABLE_COLOR */

25
nano.h
View File

@ -90,6 +90,14 @@
#define KEY_END -1
#endif /* KEY_END */
/* Snatch these out of the ncurse sdefs, so we can use them in search
history regardless of whethere we're using ncurses or not */
#ifndef KEY_UP
#define KEY_UP 0403
#define KEY_DOWN 0402
#endif /* KEY_UP */
#define VERMSG "GNU nano " VERSION
#if defined(DISABLE_WRAPPING) && defined(DISABLE_JUSTIFY)
@ -190,6 +198,21 @@ typedef struct syntaxtype {
#endif /* ENABLE_COLOR */
#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 same order as in historytype */
struct historytype *tail;
struct historytype *current;
int count;
int len;
} historyheadtype;
#endif /* !NANO_SMALL */
/* Bitwise flags so we can save space (or more correctly, not waste it) */
@ -397,4 +420,6 @@ typedef enum {
/* Minimum fill length (space available for text before wrapping occurs) */
#define MIN_FILL_LENGTH 10
/* Maximum number of search history strings saved, same value used for replace history */
#define MAX_SEARCH_HISTORY 100
#endif /* !NANO_H */

23
proto.h
View File

@ -40,6 +40,7 @@ extern long totsize;
extern int temp_opt;
extern int wrap_at, flags, tabsize;
extern int search_last_line;
extern int past_editbuff;
extern int currslen;
#ifndef DISABLE_JUSTIFY
@ -109,6 +110,11 @@ extern regmatch_t synfilematches[1];
extern toggle *toggles;
#endif
#ifndef NANO_SMALL
extern historyheadtype search_history;
extern historyheadtype replace_history;
#endif
/* Functions we want available */
/* Public functions in color.c */
@ -355,6 +361,17 @@ int do_gotoline_void(void);
void do_gotopos(int line, int pos_x, int pos_y, int pos_placewewant);
#endif
int do_find_bracket(void);
#ifndef NANO_SMALL
void history_init(void);
historytype *find_node(historytype *h, char *s);
void remove_node(historytype *r);
void insert_node(historytype *h, const char *s);
void update_history(historyheadtype *h, char *s);
char *get_history_older(historyheadtype *h);
char *get_history_newer(historyheadtype *h);
char *get_history_completion(historyheadtype *h, char *s);
void free_history(historyheadtype *h);
#endif
/* Public functions in utils.c */
int is_cntrl_char(int c);
@ -398,6 +415,9 @@ void blank_statusbar_refresh(void);
void check_statblank(void);
void nanoget_repaint(const char *buf, const char *inputbuf, int x);
int nanogetstr(int allowtabs, const char *buf, const char *def,
#ifndef NANO_SMALL
historyheadtype *history_list,
#endif
const shortcut *s
#ifndef DISABLE_TABCOMP
, int *list
@ -426,6 +446,9 @@ void edit_refresh(void);
void edit_refresh_clearok(void);
void edit_update(filestruct *fileptr, topmidbotnone location);
int statusq(int tabs, const shortcut *s, const char *def,
#ifndef NANO_SMALL
historyheadtype *history_list,
#endif
const char *msg, ...);
int do_yesno(int all, int leavecursor, const char *msg, ...);
int total_refresh(void);

View File

@ -607,9 +607,10 @@ void do_rcfile(void)
lineno = 0;
if (userage == NULL)
if (userage == NULL) {
rcfile_error(_("I can't find my home directory! Wah!"));
else {
SET(NO_RCFILE); /* if no .nanorc, don't try to read .nano_history */
} else {
nanorc = nrealloc(nanorc, strlen(userage->pw_dir) + 9);
sprintf(nanorc, "%s/.nanorc", userage->pw_dir);
@ -621,9 +622,11 @@ void do_rcfile(void)
#endif
if ((rcstream = fopen(nanorc, "r")) == NULL) {
/* Don't complain about the file not existing */
if (errno != ENOENT)
if (errno != ENOENT) {
rcfile_error(_("Unable to open ~/.nanorc file, %s"),
strerror(errno));
SET(NO_RCFILE);
}
} else {
parse_rcfile(rcstream);
fclose(rcstream);

227
search.c
View File

@ -26,10 +26,17 @@
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include "proto.h"
#include "nano.h"
#ifndef NANO_SMALL
#ifdef ENABLE_NANORC
#include <pwd.h>
#endif
#endif
static int past_editbuff;
/* findnextstr() is now searching lines not displayed */
@ -89,7 +96,7 @@ void search_init_globals(void)
}
/* Set up the system variables for a search or replace. Returns -1 on
abort, 0 on success, and 1 on rerun calling program
abort, 0 on success, and 1 on rerun calling program
Return -2 to run opposite program (search -> replace, replace ->
search).
@ -110,24 +117,37 @@ int search_init(int replacing)
backupstring = NULL;
UNSET(CLEAR_BACKUPSTRING);
}
/* Okay, fun time. backupstring is our holder for what is being
/* Okay, fun time. backupstring is our holder for what is being
returned from the statusq call. Using answer for this would be tricky.
Here, if we're using PICO_MODE, we only want nano to put the
old string back up as editable if it's not the same as last_search.
Otherwise, if we don't already have a backupstring, set it to
last_search. */
#if 0
/* might need again ;)*/
if (ISSET(PICO_MODE)) {
if (backupstring == NULL || !strcmp(backupstring, last_search)) {
/* backupstring = mallocstrcpy(backupstring, ""); */
backupstring = charalloc(1);
backupstring[0] = '\0';
}
}
else if (backupstring == NULL)
} else
#endif
if (backupstring == NULL)
#ifndef NANO_SMALL
backupstring = mallocstrcpy(backupstring, search_history.current->data);
#else
backupstring = mallocstrcpy(backupstring, last_search);
#endif
/* NEW TEST */
if (ISSET(PICO_MODE)) {
backupstring = mallocstrcpy(backupstring, "");
search_history.current = (historytype *)&search_history.next;
}
/* */
/* If using Pico messages, we do things the old fashioned way... */
if (ISSET(PICO_MODE) && last_search[0] != '\0') {
buf = charalloc(COLS / 3 + 7);
@ -141,7 +161,10 @@ int search_init(int replacing)
/* This is now one simple call. It just does a lot */
i = statusq(0, replacing ? replace_list : whereis_list, backupstring,
"%s%s%s%s%s%s",
#ifndef NANO_SMALL
&search_history,
#endif
"%s%s%s%s%s%s",
_("Search"),
/* This string is just a modifier for the search prompt,
@ -168,6 +191,9 @@ int search_init(int replacing)
reset_cursor();
free(backupstring);
backupstring = NULL;
#ifndef NANO_SMALL
search_history.current = search_history.next;
#endif
return -1;
} else {
switch (i) {
@ -210,7 +236,14 @@ int search_init(int replacing)
case NANO_FROMSEARCHTOGOTO_KEY:
free(backupstring);
backupstring = NULL;
do_gotoline_void();
#ifndef NANO_SMALL
search_history.current = search_history.next;
#endif
i = (int)strtol(answer, &buf, 10); /* just testing answer here */
if (!(errno == ERANGE || *answer == '\0' || *buf != '\0'))
do_gotoline(-1, 0);
else
do_gotoline_void();
return -3;
default:
do_early_abort();
@ -301,7 +334,7 @@ filestruct *findnextstr(int quiet, int bracket_mode,
not_found_msg(needle);
return NULL;
}
}
}
#ifndef NANO_SMALL
else { /* reverse search */
current_x_find = current_x - 1;
@ -403,6 +436,9 @@ int do_search(void)
/* The sneaky user deleted the previous search string */
if (!ISSET(PICO_MODE) && answer[0] == '\0') {
statusbar(_("Search Cancelled"));
#ifndef NANO_SMALL
search_history.current = search_history.next;
#endif
search_abort();
return 0;
}
@ -415,6 +451,11 @@ int do_search(void)
else
last_search = mallocstrcpy(last_search, answer);
#ifndef NANO_SMALL
/* add this search string to the search history list */
update_history(&search_history, answer);
#endif /* !NANO_SMALL */
search_last_line = 0;
didfind = findnextstr(FALSE, FALSE, current, current_x, answer);
@ -697,6 +738,10 @@ int do_replace(void)
return 0;
}
#ifndef NANO_SMALL
update_history(&search_history, answer);
#endif /* !NANO_SMALL */
/* Again, there was a previous string, but they deleted it and hit enter */
if (!ISSET(PICO_MODE) && answer[0] == '\0') {
statusbar(_("Replace Cancelled"));
@ -710,6 +755,7 @@ int do_replace(void)
answer = mallocstrcpy(answer, last_search);
else
last_search = mallocstrcpy(last_search, answer);
prevanswer = mallocstrcpy(prevanswer, last_search);
if (ISSET(PICO_MODE) && last_replace[0] != '\0') {
@ -718,16 +764,34 @@ int do_replace(void)
strncpy(buf, last_replace, COLS / 3 - 1);
strcpy(buf + COLS / 3 - 1, "...");
i = statusq(0, replace_list_2, "", _("Replace with [%s]"),
buf);
i = statusq(0, replace_list_2, "",
#ifndef NANO_SMALL
&replace_history,
#endif
_("Replace with [%s]"), buf);
free(buf);
} else
i = statusq(0, replace_list_2, "", _("Replace with [%s]"),
last_replace);
} else
i = statusq(0, replace_list_2, last_replace, _("Replace with"));
i = statusq(0, replace_list_2, "",
#ifndef NANO_SMALL
&replace_history,
#endif
_("Replace with [%s]") ,last_replace);
} else {
#ifndef NANO_SMALL
replace_history.current = (historytype *)&replace_history.next;
last_replace = mallocstrcpy(last_replace, "");
#endif
i = statusq(0, replace_list_2, last_replace,
#ifndef NANO_SMALL
&replace_history,
#endif
_("Replace with"));
}
#ifndef NANO_SMALL
if (i == 0)
update_history(&replace_history, answer);
#endif /* !NANO_SMALL */
/* save where we are */
begin = current;
beginx = current_x;
search_last_line = 0;
@ -753,7 +817,7 @@ void goto_abort(void)
int do_gotoline(int line, int save_pos)
{
if (line <= 0) { /* Ask for it */
if (statusq(0, goto_list, "", _("Enter line number"))) {
if (statusq(0, goto_list, (line ? answer : ""), 0, _("Enter line number"))) {
statusbar(_("Aborted"));
goto_abort();
return 0;
@ -780,9 +844,9 @@ int do_gotoline(int line, int save_pos)
edit_update(current, NONE);
else
edit_update(current, CENTER);
placewewant = 0;
goto_abort();
blank_statusbar_refresh();
return 1;
}
@ -820,7 +884,9 @@ int do_find_bracket(void)
filestruct *current_save;
ch_under_cursor = current->data[current_x];
/* if ((!(pos = strchr(brackets, ch_under_cursor))) || (!((offset = pos - brackets) < 8))) { */
if (((pos = strchr(brackets, ch_under_cursor)) == NULL) || (((offset = pos - brackets) < 8) == 0)) {
statusbar(_("Not a bracket"));
return 1;
@ -880,3 +946,126 @@ int do_find_bracket(void)
return 0;
}
#endif
#ifndef NANO_SMALL
/*
* search and replace history list support functions
*/
/* initialize search and replace history lists */
void history_init(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;
}
/* find first node containing string *s in history list *h */
historytype *find_node(historytype *h, char *s)
{
for ( ; h->next ; h = h->next)
if (strcmp(s, h->data) == 0)
return h;
return NULL;
}
/* remove node *r */
void remove_node(historytype *r)
{
r->prev->next = r->next;
r->next->prev = r->prev;
free(r->data);
free(r);
}
/* add a node after node *h */
void insert_node(historytype *h, const char *s)
{
historytype *a;
a = nmalloc(sizeof(historytype));
a->next = h->next;
a->prev = h->next->prev;
h->next->prev = a;
h->next = a;
a->data = mallocstrcpy(NULL, s);
}
/* update history list */
void update_history(historyheadtype *h, char *s)
{
historytype *p;
if ((p = find_node(h->next, s))) {
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 (h->count == MAX_SEARCH_HISTORY) { /* list 'full', delete oldest */
remove_node(h->tail);
h->count--;
}
insert_node((historytype *)h, s);
h->count++;
up_hs:
h->current = h->next;
}
/* return a pointer to either the next older history or NULL if no more */
char *get_history_older(historyheadtype *h)
{
if (h->current->next) { /* any older entries ? */
h->current = h->current->next; /* yes */
return h->current->data; /* return it */
}
return NULL; /* end of list */
}
char *get_history_newer(historyheadtype *h)
{
if (h->current->prev) {
h->current = h->current->prev;
if (h->current->prev)
return h->current->data;
}
return NULL;
}
/* get a completion */
char *get_history_completion(historyheadtype *h, char *s)
{
historytype *p;
for (p = h->current->next ; p->next ; 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;
}
/* free a history list */
void free_history(historyheadtype *h)
{
historytype *p, *n;
for (p = h->next ; (n = p->next) ; p = n)
remove_node(p);
}
/* end of history support functions */
#endif /* !NANO_SMALL */

106
winio.c
View File

@ -187,6 +187,9 @@ void nanoget_repaint(const char *buf, const char *inputbuf, int x)
/* Get the input from the kb; this should only be called from
* statusq(). */
int nanogetstr(int allowtabs, const char *buf, const char *def,
#ifndef NANO_SMALL
historyheadtype *history_list,
#endif
const shortcut *s
#ifndef DISABLE_TABCOMP
, int *list
@ -202,6 +205,12 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
/* used by input_tab() */
const shortcut *t;
#ifndef NANO_SMALL
/* for history */
char *history = NULL;
char *complete = NULL;
int last_kbinput = 0;
#endif
xend = strlen(def);
x = xend;
answer = (char *)nrealloc(answer, xend + 1);
@ -300,28 +309,74 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
xend--;
}
break;
#ifndef DISABLE_TABCOMP
case NANO_CONTROL_I:
if (allowtabs) {
int shift = 0;
#ifndef NANO_SMALL
/* tab history completion */
if (history_list) {
if ((!complete) || (last_kbinput != NANO_CONTROL_I)) {
history_list->current = (historytype *)history_list;
history_list->len = strlen(answer);
}
answer = input_tab(answer, x, &tabbed, &shift, list);
xend = strlen(answer);
x += shift;
if (x > xend)
if (history_list->len) {
complete = get_history_completion(history_list, answer);
xend = strlen(complete);
x = xend;
answer = mallocstrcpy(answer, complete);
}
}
break;
#ifndef DISABLE_TABCOMP
else {
#endif
#endif
#ifndef DISABLE_TABCOMP
if (allowtabs) {
int shift = 0;
answer = input_tab(answer, x, &tabbed, &shift, list);
xend = strlen(answer);
x += shift;
if (x > xend)
x = xend;
}
}
#endif
break;
case KEY_LEFT:
case NANO_BACK_KEY:
if (x > 0)
x--;
break;
case KEY_UP:
case KEY_DOWN:
#ifndef NANO_SMALL
if (history_list) {
/* get older search from the history list */
if ((history = get_history_older(history_list))) {
answer = mallocstrcpy(answer, history);
xend = strlen(history);
} else {
answer = mallocstrcpy(answer, "");
xend = 0;
}
x = xend;
}
break;
#endif
case KEY_DOWN:
#ifndef NANO_SMALL
if (history_list) {
/* get newer search from the history list */
if ((history = get_history_newer(history_list))) {
answer = mallocstrcpy(answer, history);
xend = strlen(history);
} else {
answer = mallocstrcpy(answer, "");
xend = 0;
}
x = xend;
}
#endif
break;
case KEY_DC:
goto do_deletekey;
@ -400,7 +455,8 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
#ifdef DEBUG
fprintf(stderr, _("input \'%c\' (%d)\n"), kbinput, kbinput);
#endif
}
} /* switch (kbinput) */
last_kbinput = kbinput;
nanoget_repaint(buf, answer, x);
wrefresh(bottomwin);
} /* while (kbinput ...) */
@ -496,11 +552,13 @@ void bottombars(const shortcut *s)
wmove(bottomwin, 1 + j, i * (COLS / numcols));
#ifndef NANO_SMALL
/* Yucky sentinel values we can't handle a better way */
if (s->val == NANO_CONTROL_SPACE)
strcpy(keystr, "^ ");
else
#endif /* !NANO_SMALL */
if (s->val > 0) {
else if (s->val == KEY_UP)
strcpy(keystr, _("Up"));
#endif /* NANO_SMALL */
else if (s->val > 0) {
if (s->val < 64)
sprintf(keystr, "^%c", s->val + 64);
else
@ -526,6 +584,7 @@ void bottombars(const shortcut *s)
* very small and keystroke and desc are long. */
void onekey(const char *keystroke, const char *desc, int len)
{
wattron(bottomwin, A_REVERSE);
waddnstr(bottomwin, keystroke, len);
wattroff(bottomwin, A_REVERSE);
@ -911,8 +970,8 @@ void update_line(filestruct *fileptr, int index)
original = fileptr->data;
converted = charalloc(strlenpt(original) + 1);
/* Next, convert all the tabs to spaces, so everything else is easy.
/* Next, convert all the tabs to spaces, so everything else is easy.
* Note the internal speller sends us index == -1. */
index = fileptr == current && index > 0 ? strnlenpt(original, index) : 0;
#ifndef NANO_SMALL
@ -1070,6 +1129,9 @@ void edit_update(filestruct *fileptr, topmidbotnone location)
* New arg tabs tells whether or not to allow tab completion.
*/
int statusq(int tabs, const shortcut *s, const char *def,
#ifndef NANO_SMALL
historyheadtype *which_history,
#endif
const char *msg, ...)
{
va_list ap;
@ -1086,11 +1148,15 @@ int statusq(int tabs, const shortcut *s, const char *def,
va_end(ap);
foo[COLS - 4] = '\0';
#ifndef DISABLE_TABCOMP
ret = nanogetstr(tabs, foo, def, s, &list);
#else
ret = nanogetstr(tabs, foo, def, s);
ret = nanogetstr(tabs, foo, def,
#ifndef NANO_SMALL
which_history,
#endif
s
#ifndef DISABLE_TABCOMP
, &list
#endif
);
free(foo);
switch (ret) {