diff --git a/top/top.1 b/top/top.1 index ae393fa7..19f1f847 100644 --- a/top/top.1 +++ b/top/top.1 @@ -90,7 +90,7 @@ . .\" Document ///////////////////////////////////////////////////////////// .\" ---------------------------------------------------------------------- -.TH TOP 1 "January 2013" "procps-ng" "User Commands" +.TH TOP 1 "February 2013" "procps-ng" "User Commands" .\" ---------------------------------------------------------------------- .\" ---------------------------------------------------------------------- @@ -208,6 +208,15 @@ Insert this command after \*(We has been suspended but before resuming it. reset restore your \fBterminal settings\fR .Ed +\*(NT the width of \*(We's display will be limited to \*(WX positions. +Displaying all fields requires \*(WF characters. +Remaining screen width is usually allocated to any variable width columns +currently visible. +The variable width columns, such as COMMAND, are noted in topic +3a. DESCRIPTIONS of Fields. +Actual output width may also be influenced by the \-w switch, which is +discussed in topic 1. COMMAND\-LINE Options. + Lastly, some of \*(We's screens or functions require the use of cursor motion keys like the standard \*(KAs plus the Home, End, PgUp and PgDn keys. If your terminal or emulator does not provide those keys, the following @@ -224,14 +233,20 @@ combinations are accepted as alternatives: End alt +\fB Right\fR or alt + ctrl +\fB l \fR .Ed -\*(NT the width of \*(We's display will be limited to \*(WX positions. -Displaying all fields requires \*(WF characters. -Remaining screen width is usually allocated to any variable width columns -currently visible. -The variable width columns, such as COMMAND, are noted in topic -3a. DESCRIPTIONS of Fields. -Actual output width may also be influenced by the \-w switch, which is -discussed in topic 1. COMMAND\-LINE Options. +The \fBUp\fR and \fBDown\fR \*(KAs have special significance when prompted +for line input terminated with the key. +Those keys, or their aliases, can be used to retrieve previous input lines +which can then be edited and re-input. +And there are four additional keys available with line oriented input. +.Bd -literal -compact + \fI key special-significance \fR + Up recall \fBolder\fR strings for re-editing + Down recall \fBnewer\fR strings or \fBerase\fR entire line + Insert toggle between \fBinsert\fR and \fBovertype\fR modes + Delete character \fBremoved\fR at cursor, moving others left + Home jump to \fBbeginning\fR of input line + End jump to \fBend\fR of input line +.Ed .\" ...................................................................... .SS Startup Defaults diff --git a/top/top.c b/top/top.c index 468a48c2..267b7f1e 100644 --- a/top/top.c +++ b/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 diff --git a/top/top.h b/top/top.h index d705a397..d7fe8ff6 100644 --- a/top/top.h +++ b/top/top.h @@ -600,6 +600,9 @@ typedef struct WIN_t { #if (LRGBUFSIZ < SCREENMAX) # error 'LRGBUFSIZ' must NOT be less than 'SCREENMAX' #endif +#if defined(TERMIOS_ONLY) +# warning 'TERMIOS_ONLY' disables input recall and makes man doc incorrect +#endif /*###### Some Prototypes (ha!) #########################################*/