top: enable recall of previous input lines for re-edit
With this commit, users can now retrieve previous line input for re-editing and/or re-input using the Up/Down arrow keys (or their aliases). This mirrors the 'bash' or 'less' interface and represents a major enhancement achieved via a somewhat minor impact to our code base. [ 33 lines of code, 5 closing braces & some comments ] [ all in 1 function, when TERMIOS_ONLY isn't defined ] Currently, the upper limit for such recallable strings has been set at 50 but that could be easily increased. (everything is perfectly justified plus right margins) (are completely filled, but of course it must be luck) Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
51
top/top.c
51
top/top.c
@ -1073,8 +1073,10 @@ static char *ioline (const char *prompt) {
|
||||
* Get line oriented interactive input from the user,
|
||||
* going way beyond native tty support by providing:
|
||||
* . true line editing, not just destructive backspace
|
||||
* . an input limit sensitive to current screen dimensions */
|
||||
* . an input limit sensitive to current screen dimensions
|
||||
* . ability to recall prior strings for re-input/re-editing */
|
||||
static char *ioline (const char *prompt) {
|
||||
#define savMAX 50
|
||||
// thank goodness memmove allows the two strings to overlap
|
||||
#define sqzSTR { memmove(&buf[pos], &buf[pos+1], bufMAX-pos); \
|
||||
buf[sizeof(buf)-1] = '\0'; }
|
||||
@ -1084,8 +1086,19 @@ static char *ioline (const char *prompt) {
|
||||
#define phyCOL (beg+pos+1)
|
||||
#define bufMAX ((int)sizeof(buf)-2) // -1 for '\0' string delimeter
|
||||
static char buf[MEDBUFSIZ+1]; // +1 for '\0' string delimeter
|
||||
int beg, pos, len, key, ovt;
|
||||
int beg, pos, len, key, ovt, i;
|
||||
struct lin_s {
|
||||
struct lin_s *bkw; // ptr to older saved strs
|
||||
struct lin_s *fwd; // ptr to newer saved strs
|
||||
char *str; // the saved string
|
||||
};
|
||||
static struct lin_s *anchor, *plin;
|
||||
|
||||
if (!anchor) {
|
||||
anchor = alloc_c(sizeof(struct lin_s));
|
||||
anchor->str = alloc_s(""); // top-of-stack == empty str
|
||||
}
|
||||
plin = anchor;
|
||||
pos = ovt = 0;
|
||||
beg = show_pmt(prompt);
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
@ -1122,6 +1135,18 @@ static char *ioline (const char *prompt) {
|
||||
case kbd_END:
|
||||
pos = len;
|
||||
break;
|
||||
case kbd_UP:
|
||||
if (plin->bkw) {
|
||||
plin = plin->bkw;
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
pos = snprintf(buf, sizeof(buf), "%s", plin->str);
|
||||
}
|
||||
break;
|
||||
case kbd_DOWN:
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
if (plin->fwd) plin = plin->fwd;
|
||||
pos = snprintf(buf, sizeof(buf), "%s", plin->str);
|
||||
break;
|
||||
default: // what we REALLY wanted (maybe)
|
||||
if (isprint(key) && logCOL < bufMAX && phyCOL < Screen_cols) {
|
||||
if (!ovt) expSTR
|
||||
@ -1133,7 +1158,27 @@ static char *ioline (const char *prompt) {
|
||||
putp(tg2(beg+pos, Msg_row));
|
||||
} while (key != kbd_ENTER && key != kbd_ESC);
|
||||
|
||||
return buf;
|
||||
// weed out duplicates, including empty strings (top-of-stack)...
|
||||
for (i = 0, plin = anchor; ; i++) {
|
||||
if (!STRCMP(plin->str, buf)) return buf;
|
||||
if (!plin->bkw) break; // let i equal total stacked strings
|
||||
plin = plin->bkw; // ( with plin representing bottom )
|
||||
}
|
||||
if (i < savMAX)
|
||||
plin = alloc_c(sizeof(struct lin_s));
|
||||
else { // when a new string causes overflow
|
||||
plin->fwd->bkw = NULL; // make next-to-last string new last
|
||||
free(plin->str); // and toss copy but keep the struct
|
||||
}
|
||||
plin->str = alloc_s(buf); // copy user's new unique input line
|
||||
plin->bkw = anchor->bkw; // keep empty string as top-of-stack
|
||||
if (plin->bkw) // did we have some already stacked?
|
||||
plin->bkw->fwd = plin; // yep, so point prior to new string
|
||||
plin->fwd = anchor; // and prepare to be a second banana
|
||||
anchor->bkw = plin; // by sliding it in as new number 2!
|
||||
|
||||
return buf; // protect our copy, return original
|
||||
#undef savMAX
|
||||
#undef sqzSTR
|
||||
#undef expSTR
|
||||
#undef logCOL
|
||||
|
Reference in New Issue
Block a user