mirror of
https://gitlab.com/procps-ng/procps.git
synced 2024-12-05 07:54:39 +08:00
top: add intra-column horizontal scrolling
This commit introduces horizontal scrolling within any variable width column. Thus, an entire command line, complete list of control groups, etc. can now be viewed -- not just a screen width's portion. It is activated when any variable width column: . is (via field selection) or . has become (via the right arrow key) the only displayed field. Then, the right and left arrow keys can be used in the normal way to continue scrolling within that column. The amount scrolled with each key press is currently set as the normal tab stop increment of 8 characters. Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
f4666e1743
commit
a652ba8c9d
105
top/top.c
105
top/top.c
@ -680,6 +680,9 @@ static int show_pmt (const char *str) {
|
||||
* Show a special coordinate message, in support of scrolling */
|
||||
static inline void show_scroll (void) {
|
||||
char tmp[SMLBUFSIZ];
|
||||
#ifndef SCROLLVAR_NO
|
||||
char tmp2[SMLBUFSIZ];
|
||||
#endif
|
||||
int totpflgs = Curwin->totpflgs;
|
||||
int begpflgs = Curwin->begpflg + 1;
|
||||
|
||||
@ -695,7 +698,12 @@ static inline void show_scroll (void) {
|
||||
, N_fmt(SCROLL_coord_fmt)
|
||||
, Curwin->begtask + 1, Frame_maxtask
|
||||
, begpflgs, totpflgs);
|
||||
#ifndef SCROLLVAR_NO
|
||||
snprintf(tmp2, sizeof(tmp2), Curwin->varcolbeg ? " + %d" : "", Curwin->varcolbeg);
|
||||
PUTT("%s%s %.*s%s%s", tg2(0, Msg_row), Caps_off, Screen_cols - 2, tmp, tmp2, Cap_clr_eol);
|
||||
#else
|
||||
PUTT("%s%s %.*s%s", tg2(0, Msg_row), Caps_off, Screen_cols - 2, tmp, Cap_clr_eol);
|
||||
#endif
|
||||
putp(tg2(0, Msg_row));
|
||||
} // end: show_scroll
|
||||
|
||||
@ -1391,7 +1399,7 @@ static void build_headers (void) {
|
||||
h = Fieldstab[f].head;
|
||||
if (P_WCH == f) needpsdb = 1;
|
||||
if (P_CMD == f && CHKw(w, Show_CMDLIN)) Frames_libflags |= L_CMDLINE;
|
||||
if (Fieldstab[f].fmts) s = scat(s, h);
|
||||
if (!VARcol(f)) s = scat(s, h);
|
||||
else s = scat(s, fmtmk(VARCOL_fmts, w->varcolsz, w->varcolsz, h));
|
||||
Frames_libflags |= Fieldstab[w->procflgs[i]].lflg;
|
||||
#ifdef USE_X_COLHDR
|
||||
@ -1507,7 +1515,7 @@ static void calibrate_fields (void) {
|
||||
h = Fieldstab[f].head;
|
||||
// oops, won't fit -- we're outta here...
|
||||
if (Screen_cols < ((int)(s - w->columnhdr) + (int)strlen(h))) break;
|
||||
if (!Fieldstab[f].fmts) { ++varcolcnt; w->varcolsz += strlen(h) - 1; }
|
||||
if (VARcol(f)) { ++varcolcnt; w->varcolsz += strlen(h) - 1; }
|
||||
s = scat(s, h);
|
||||
}
|
||||
#ifndef USE_X_COLHDR
|
||||
@ -1640,7 +1648,11 @@ static void display_fields (int focus, int extend) {
|
||||
/*
|
||||
* Manage all fields aspects (order/toggle/sort), for all windows. */
|
||||
static void fields_utility (void) {
|
||||
#ifndef SCROLLVAR_NO
|
||||
#define unSCRL { w->begpflg = w->varcolbeg = 0; OFFw(w, Show_HICOLS); }
|
||||
#else
|
||||
#define unSCRL { w->begpflg = 0; OFFw(w, Show_HICOLS); }
|
||||
#endif
|
||||
#define swapEM { char c; unSCRL; c = w->rc.fieldscur[i]; \
|
||||
w->rc.fieldscur[i] = *p; *p = c; p = &w->rc.fieldscur[i]; }
|
||||
#define spewFI { char *t; f = w->rc.sortindx; t = strchr(w->rc.fieldscur, f + FLD_OFFSET); \
|
||||
@ -2730,7 +2742,11 @@ static void wins_reflag (int what, int flg) {
|
||||
/* a flag with special significance -- user wants to rebalance
|
||||
display so we gotta' off some stuff then force on two flags... */
|
||||
if (EQUWINS_xxx == flg) {
|
||||
#ifndef SCROLLVAR_NO
|
||||
w->rc.maxtasks = w->usrseltyp = w->begpflg = w->begtask = w->varcolbeg = 0;
|
||||
#else
|
||||
w->rc.maxtasks = w->usrseltyp = w->begpflg = w->begtask = 0;
|
||||
#endif
|
||||
Monpidsidx = 0;
|
||||
SETw(w, Show_IDLEPS | Show_TASKON);
|
||||
}
|
||||
@ -3169,7 +3185,11 @@ static void keys_window (int ch) {
|
||||
break;
|
||||
case '=':
|
||||
SETw(w, Show_IDLEPS | Show_TASKON);
|
||||
#ifndef SCROLLVAR_NO
|
||||
w->rc.maxtasks = w->usrseltyp = w->begpflg = w->begtask = w->varcolbeg = 0;
|
||||
#else
|
||||
w->rc.maxtasks = w->usrseltyp = w->begpflg = w->begtask = 0;
|
||||
#endif
|
||||
Monpidsidx = 0;
|
||||
break;
|
||||
case '_':
|
||||
@ -3203,28 +3223,71 @@ static void keys_window (int ch) {
|
||||
case kbd_DOWN:
|
||||
if (VIZCHKw(w)) if (w->begtask < Frame_maxtask - 1) w->begtask += 1;
|
||||
break;
|
||||
#ifdef USE_X_COLHDR
|
||||
#ifdef USE_X_COLHDR // ------------------------------------
|
||||
case kbd_LEFT:
|
||||
#ifndef SCROLLVAR_NO
|
||||
if (VIZCHKw(w)) {
|
||||
if (VARleft(w))
|
||||
w->varcolbeg -= SCROLLAMT;
|
||||
else if (0 < w->begpflg)
|
||||
w->begpflg -= 1;
|
||||
}
|
||||
#else
|
||||
if (VIZCHKw(w)) if (0 < w->begpflg) w->begpflg -= 1;
|
||||
#endif
|
||||
break;
|
||||
case kbd_RIGHT:
|
||||
if (VIZCHKw(w)) if (w->begpflg + 1 < w->totpflgs) w->begpflg += 1;
|
||||
break;
|
||||
#ifndef SCROLLVAR_NO
|
||||
if (VIZCHKw(w)) {
|
||||
if (VARright(w)) {
|
||||
w->varcolbeg += SCROLLAMT;
|
||||
if (0 > w->varcolbeg) w->varcolbeg = 0;
|
||||
} else if (w->begpflg + 1 < w->totpflgs)
|
||||
w->begpflg += 1;
|
||||
}
|
||||
#else
|
||||
if (VIZCHKw(w)) if (w->begpflg + 1 < w->totpflgs) w->begpflg += 1;
|
||||
#endif
|
||||
break;
|
||||
#else // USE_X_COLHDR ------------------------------------
|
||||
case kbd_LEFT:
|
||||
#ifndef SCROLLVAR_NO
|
||||
if (VIZCHKw(w)) {
|
||||
if (VARleft(w))
|
||||
w->varcolbeg -= SCROLLAMT;
|
||||
else if (0 < w->begpflg) {
|
||||
w->begpflg -= 1;
|
||||
if (P_MAXPFLGS < w->pflgsall[w->begpflg]) w->begpflg -= 2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (VIZCHKw(w)) if (0 < w->begpflg) {
|
||||
w->begpflg -= 1;
|
||||
if (P_MAXPFLGS < w->pflgsall[w->begpflg]) w->begpflg -= 2;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case kbd_RIGHT:
|
||||
#ifndef SCROLLVAR_NO
|
||||
if (VIZCHKw(w)) {
|
||||
if (VARright(w)) {
|
||||
w->varcolbeg += SCROLLAMT;
|
||||
if (0 > w->varcolbeg) w->varcolbeg = 0;
|
||||
} else if (w->begpflg + 1 < w->totpflgs) {
|
||||
if (P_MAXPFLGS < w->pflgsall[w->begpflg])
|
||||
w->begpflg += (w->begpflg + 3 < w->totpflgs) ? 3 : 0;
|
||||
else w->begpflg += 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (VIZCHKw(w)) if (w->begpflg + 1 < w->totpflgs) {
|
||||
if (P_MAXPFLGS < w->pflgsall[w->begpflg])
|
||||
w->begpflg += (w->begpflg + 3 < w->totpflgs) ? 3 : 0;
|
||||
else w->begpflg += 1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
#endif // USE_X_COLHDR ------------------------------------
|
||||
case kbd_PGUP:
|
||||
if (VIZCHKw(w)) if (0 < w->begtask) {
|
||||
w->begtask -= (w->winlines - 1);
|
||||
@ -3239,13 +3302,20 @@ static void keys_window (int ch) {
|
||||
}
|
||||
break;
|
||||
case kbd_HOME:
|
||||
#ifndef SCROLLVAR_NO
|
||||
if (VIZCHKw(w)) w->begtask = w->begpflg = w->varcolbeg = 0;
|
||||
#else
|
||||
if (VIZCHKw(w)) w->begtask = w->begpflg = 0;
|
||||
#endif
|
||||
break;
|
||||
case kbd_END:
|
||||
if (VIZCHKw(w)) {
|
||||
w->begtask = (Frame_maxtask - w->winlines) + 1;
|
||||
if (0 > w->begtask) w->begtask = 0;
|
||||
w->begpflg = w->endpflg;
|
||||
#ifndef SCROLLVAR_NO
|
||||
w->varcolbeg = 0;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default: // keep gcc happy
|
||||
@ -3352,7 +3422,11 @@ static void forest_create (WIN_t *q) {
|
||||
* This guy adds the artwork to either p->cmd or p->cmdline
|
||||
* when in forest view mode, otherwise he just returns 'em. */
|
||||
static inline const char *forest_display (const WIN_t *q, const proc_t *p) {
|
||||
#ifndef SCROLLVAR_NO
|
||||
static char buf[1024*64*2]; // the same as readproc's MAX_BUFSZ
|
||||
#else
|
||||
static char buf[ROWMINSIZ];
|
||||
#endif
|
||||
const char *which = (CHKw(q, Show_CMDLIN)) ? *p->cmdline : p->cmd;
|
||||
|
||||
if (!CHKw(q, Show_FOREST) || 1 == p->pad_3) return which;
|
||||
@ -3556,7 +3630,13 @@ static void summary_show (void) {
|
||||
* display the results or return them to the caller. */
|
||||
static void task_show (const WIN_t *q, const proc_t *p, char *ptr) {
|
||||
#define makeCOL(va...) snprintf(cbuf, sizeof(cbuf), f, ## va)
|
||||
#ifndef SCROLLVAR_NO
|
||||
#define makeVAR(v) { const char *pv = v; f = VARCOL_fmts; \
|
||||
if (!q->varcolbeg) makeCOL(q->varcolsz, q->varcolsz, pv); \
|
||||
else makeCOL(q->varcolsz, q->varcolsz, q->varcolbeg < (int)strlen(pv) ? pv + q->varcolbeg : ""); }
|
||||
#else
|
||||
#define makeVAR(v) { f = VARCOL_fmts; makeCOL(q->varcolsz, q->varcolsz, v); }
|
||||
#endif
|
||||
#define pages2K(n) (unsigned long)( (n) << Pg2K_shft )
|
||||
char rbuf[ROWMINSIZ], *rp;
|
||||
int j, x;
|
||||
@ -3723,14 +3803,17 @@ static void task_show (const WIN_t *q, const proc_t *p, char *ptr) {
|
||||
makeCOL(scale_num(pages2K(p->size), w, s));
|
||||
break;
|
||||
case P_WCH:
|
||||
if (No_ksyms) {
|
||||
{ const char *u;
|
||||
if (No_ksyms)
|
||||
#ifdef CASEUP_HEXES
|
||||
makeVAR(fmtmk("%08" KLF "X", p->wchan))
|
||||
u = fmtmk("%08" KLF "X", p->wchan);
|
||||
#else
|
||||
makeVAR(fmtmk("%08" KLF "x", p->wchan))
|
||||
u = fmtmk("%08" KLF "x", p->wchan);
|
||||
#endif
|
||||
} else
|
||||
makeVAR(lookup_wchan(p->wchan, p->tid))
|
||||
else
|
||||
u = lookup_wchan(p->wchan, p->tid);
|
||||
makeVAR(u);
|
||||
}
|
||||
break;
|
||||
default: // keep gcc happy
|
||||
break;
|
||||
|
16
top/top.h
16
top/top.h
@ -39,6 +39,7 @@
|
||||
//#define PRETENDNOCAP /* use a terminal without essential caps */
|
||||
//#define RCFILE_NOERR /* rcfile errs silently default, vs. fatal */
|
||||
//#define RMAN_IGNORED /* don't consider auto right margin glitch */
|
||||
//#define SCROLLVAR_NO /* disable intra-column horizontal scroll */
|
||||
//#define STRINGCASENO /* case insenstive compare/locate versions */
|
||||
//#define TERMIO_PROXY /* true line editing, beyond native input */
|
||||
//#define TREE_NORESET /* sort keys do NOT force forest view OFF */
|
||||
@ -331,6 +332,9 @@ typedef struct WIN_t {
|
||||
begpflg, // scrolled beginning pos into pflgsall array
|
||||
endpflg, // scrolled ending pos into pflgsall array
|
||||
begtask, // scrolled beginning pos into Frame_maxtask
|
||||
#ifndef SCROLLVAR_NO
|
||||
varcolbeg, // scrolled position within variable width col
|
||||
#endif
|
||||
varcolsz, // max length of variable width column(s)
|
||||
usrseluid, // validated uid for 'u/U' user selection
|
||||
usrseltyp, // the basis for matching above uid
|
||||
@ -379,6 +383,18 @@ typedef struct WIN_t {
|
||||
#define ENUviz(w,E) (NULL != memchr((w)->procflgs, E, (w)->maxpflgs))
|
||||
#define ENUpos(w,E) ((int)((FLG_t*)memchr((w)->pflgsall, E, (w)->totpflgs) - (w)->pflgsall))
|
||||
|
||||
// Support for variable width columns (and potentially scrolling too)
|
||||
#define VARcol(E) (NULL == Fieldstab[E].fmts)
|
||||
#ifndef SCROLLVAR_NO
|
||||
#ifdef USE_X_COLHDR
|
||||
#define VARright(w) (1 == w->maxpflgs && VARcol(w->procflgs[0]))
|
||||
#else
|
||||
#define VARright(w) ((1 == w->maxpflgs && VARcol(w->procflgs[0])) || \
|
||||
(3 == w->maxpflgs && X_XON == w->procflgs[0] && VARcol(w->procflgs[1])))
|
||||
#endif
|
||||
#define VARleft(w) (w->varcolbeg && VARright(w))
|
||||
#define SCROLLAMT 8
|
||||
#endif
|
||||
|
||||
/* Special Section: end ------------------------------------------ */
|
||||
/* /////////////////////////////////////////////////////////////// */
|
||||
|
Loading…
Reference in New Issue
Block a user