]> granicus.if.org Git - procps-ng/commitdiff
top: extend 'Ctrl' bottom window for focus via tab key <=== port of newlib de22afc4
authorJim Warner <james.warner@comcast.net>
Wed, 15 Jun 2022 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@dropbear.xyz>
Sun, 19 Jun 2022 10:58:51 +0000 (20:58 +1000)
______________________________ original newlib message

This commit introduces the 'tab' key which can be used
to highlight individual elements in that bottom 'Ctrl'
window. This can really help when reviewing such data.

[ note, normal ongoing monitoring continues unabated ]

Signed-off-by: Jim Warner <james.warner@comcast.net>
top/top.c
top/top.h

index a1fa3f5a443934a78b1b890d78bfc9e3c21f9b8f..853a74215f402f157b959b726d056cb0249443a3 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -114,18 +114,23 @@ static int   Screen_cols, Screen_rows, Max_lines;
 
         // these are for the special separate bottom 'window'
 #define      SCREEN_ROWS ( Screen_rows - Bot_rsvd )
+#define      BOT_UNFOCUS  -1           // tab focus not established
+#define      BOT_TAB_YES  -1           // tab focus could be active
 #define      BOT_MISC_NS  +1           // data for namespaces req'd
         // 1 for horizontal separator
 #define      BOT_RSVD  1
 #define      BOT_KEEP  Bot_func = NULL
 #define      BOT_TOSS  do { Bot_func = NULL; Bot_lflg = 0; \
-                Bot_task = Bot_rsvd = Bot_misc = 0; } \
-                while (0)
+                Bot_task = Bot_rsvd = Bot_what = 0; \
+                Bot_indx = BOT_UNFOCUS; \
+                } while(0)
 static int   Bot_task,
-             Bot_misc,
+             Bot_what,
              Bot_rsvd,
+             Bot_indx = BOT_UNFOCUS,
              Bot_lflg;
-static char *Bot_name;
+static char *Bot_name,
+             Bot_sep;
 static void(*Bot_func)(void);
 
         /* This is really the number of lines needed to display the summary
@@ -5084,74 +5089,113 @@ static void forest_excluded (WIN_t *q) {
 /*######  Special Separate Bottom Window support  ########################*/
 
         /*
-         * This guy actually draws the bottom window, |
-         * including the contents passed as a string. | */
-static void bot_do_see (const char *str, const char *pgm) {
+         * This guy actually draws the parsed strings |
+         * including adding a highlight if necessary. | */
+static void bot_do (const char *str, int focus) {
+   while (*str == ' ') putchar(*(str++));
+   putp(fmtmk("%s%s%s"
+      , focus ? Cap_reverse : Cap_norm
+      , str
+      , Cap_norm));
+} // end: bot_do
+
+
+        /*
+         * This guy draws that bottom window's header |
+         * then parses/arranges to show the contents. |
+         * ( returns the number of elements printed ) | */
+static int bot_focus (const char *hdr, const char *str) {
  #define maxRSVD ( Screen_rows - 1 )
-   char buf[SMLBUFSIZ];
+   static char sav[BIGBUFSIZ*2];
+   const char *end, *beg;
+   char tmp[SCREENMAX];
+   int n, x;
 
-   snprintf(buf, sizeof(buf), " %s for pid %d, %s"
-      , Bot_name, Bot_task, pgm);
-   if (!str || !*str || !strcmp(str, "-")) str = "n/a";
-   Bot_rsvd = 1 + BOT_RSVD + (strlen(str) / Screen_cols);
-   if (Bot_rsvd > maxRSVD) Bot_rsvd = maxRSVD;
-   putp(fmtmk("%s%s%-*s", tg2(0, SCREEN_ROWS), Curwin->capclr_hdr, Screen_cols, buf));
-   putp(fmtmk("%s%s", tg2(0, SCREEN_ROWS + 1), Cap_clr_eos));
-   putp(fmtmk("%s%s", tg2(0, SCREEN_ROWS + 1), Cap_norm));
-   fputs(str, stdout);
+   if (str) {
+      if (!*str || !strcmp(str, "-")) strcpy(sav, "n/a");
+      else memccpy(sav, str, '\0', sizeof(sav) - 1);
+      Bot_rsvd = 1 + BOT_RSVD + (strlen(sav) / Screen_cols);
+      if (Bot_rsvd > maxRSVD) Bot_rsvd = maxRSVD;
+      // caller itself may have used fmtmk, so we'll old school it ...
+      snprintf(tmp, sizeof(tmp), "%s%s%-*s", tg2(0, SCREEN_ROWS), Curwin->capclr_hdr, Screen_cols, hdr);
+      putp(tmp);
+   }
+   // now fmtmk is safe to use ...
+   putp(fmtmk("%s%s%s", tg2(0, SCREEN_ROWS + 1), Cap_clr_eos, Cap_norm));
+
+   beg = &sav[0];
+   x = BOT_UNFOCUS;
+
+   while (*beg) {
+      if (!(end = strchr(beg, Bot_sep)))
+         end = beg + strlen(beg);
+      if ((n = end - beg) >= sizeof(tmp))
+         n = sizeof(tmp) - 1;
+      memccpy(tmp, beg, '\0', n);
+      tmp[n] = '\0';
+      bot_do(tmp, (++x == Bot_indx));
+      if (*(beg += n))
+         putchar(*(beg++));
+      while (*beg == ' ') putchar(*(beg++));
+   }
+   return x;
  #undef maxRSVD
-} // end: bot_do_see
+} // end: bot_focus
+
 
         /*
          * This guy manages the bottom margin window, |
          * showing miscellaneous variable width data. | */
 static void bot_item_show (void) {
- #define maxRSVD  ( Screen_rows - 1 )
-   char buf[SMLBUFSIZ];
-   const char *p;
+ #define mkHDR  fmtmk("%s for pid %d, %s", Bot_name, Bot_task, p->cmd)
+   const char *s;
+   proc_t *p;
    int i;
 
    for (i = 0; i < Frame_maxtask; i++) {
-      if (Bot_task == Curwin->ppt[i]->tid)
+      p = Curwin->ppt[i];
+      if (Bot_task == p->tid)
          break;
    }
    if (i < Frame_maxtask) {
-      snprintf(buf, sizeof(buf), " %s for pid %d, %s"
-         , Bot_name, Bot_task, Curwin->ppt[i]->cmd);
       switch (Bot_lflg) {
          case (L_CGROUP):         // Ctrl-G
-            p = *Curwin->ppt[i]->cgroup;
+            s = *p->cgroup;
             break;
          case (L_CMDLINE):        // Ctrl-K
-            p = *Curwin->ppt[i]->cmdline;
+            s = *p->cmdline;
             break;
          case (L_ENVIRON):        // Ctrl-N
-            p = *Curwin->ppt[i]->environ;
+            s = *p->environ;
             break;
          case (L_SUPGRP):         // Ctrl-U
-            p = Curwin->ppt[i]->supgrp;
+            s = p->supgrp;
             break;
       }
-      bot_do_see(p, Curwin->ppt[i]->cmd);
+      bot_focus(mkHDR, s);
    }
-#ifdef BOT_DEAD_ZAP
+#ifdef Bot_DEATH
    else
       BOT_TOSS;
 #else
    BOT_KEEP;
 #endif
+ #undef mkHDR
 } // end: bot_item_show
 
 
         /*
          * This guy toggles between displaying a Ctrl |
          * bottom window or arranging to turn it off. | */
-static void bot_item_toggle (int flg, const char *str) {
+static void bot_item_toggle (int flg, const char *str, char sep) {
    // if already targeted, assume user wants to turn it off ...
    if (Bot_lflg == flg) {
       BOT_TOSS;
    } else {
       Bot_lflg = flg;
+      Bot_sep = sep;
+      Bot_what = BOT_TAB_YES;
+      Bot_indx = BOT_UNFOCUS;
       Bot_name = (char*)str;
       Bot_func = bot_item_show;
       Bot_task = Curwin->ppt[Curwin->begtask]->tid;
@@ -5166,15 +5210,21 @@ static char *bot_misc_hlp (proc_t *p) {
    static enum ns_type ns_tab[] = {
    // eu_ns1  eu_ns2  eu_ns3  eu_ns4  eu_ns5  eu_ns6
       IPCNS,  MNTNS,  NETNS,  PIDNS,  USERNS, UTSNS };
-   static char buf[BIGBUFSIZ], *b;
+   static char tmp[SMLBUFSIZ], buf[BIGBUFSIZ], *b;
    int i;
 
    buf[0] = '\0';
-   switch (Bot_misc) {
+   switch (Bot_what) {
       case BOT_MISC_NS:
          b = &buf[0];
-         for (i = 0; i < MAXTBL(ns_tab); i++)
-            b = scat(b, fmtmk("%s: %-10lu  ", get_ns_name(ns_tab[i]), p->ns[i]));
+         for (i = 0; i < MAXTBL(ns_tab); i++) {
+            // caller itself may have used fmtmk, so we'll old school it ...
+            snprintf(tmp, sizeof(tmp), "%s: %-10lu"
+               , get_ns_name(ns_tab[i])
+               , p->ns[i]);
+            b = scat(b, tmp);
+            if (i < (MAXTBL(ns_tab) - 1)) b = scat(b, ", ");
+         }
          break;
       default:
          break;
@@ -5187,6 +5237,7 @@ static char *bot_misc_hlp (proc_t *p) {
          * This guy manages the bottom margin window, |
          * showing misc data based on multiple items. | */
 static void bot_misc_show (void) {
+ #define mkHDR  fmtmk("%s for pid %d, %s", Bot_name, Bot_task, p->cmd)
    proc_t *p;
    int i;
 
@@ -5196,23 +5247,24 @@ static void bot_misc_show (void) {
          break;
    }
    if (i < Frame_maxtask) {
-      bot_do_see(bot_misc_hlp(p), p->cmd);
+      bot_focus(mkHDR, bot_misc_hlp(p));
    }
-#ifdef BOT_DEAD_ZAP
+#ifdef Bot_DEATH
    else
       BOT_TOSS;
 #else
    BOT_KEEP;
 #endif
+ #undef mkHDR
 } // end: bot_misc_show
 
 
         /*
          * This guy toggles between displaying a Ctrl |
          * bottom window or arranging to turn it off. | */
-static void bot_misc_toggle (int what) {
+static void bot_misc_toggle (int what, char sep) {
    // if already targeted, assume user wants to turn it off ...
-   if (Bot_misc == what) {
+   if (Bot_what == what) {
       BOT_TOSS;
    } else {
       switch (what) {
@@ -5223,7 +5275,9 @@ static void bot_misc_toggle (int what) {
          default:
             break;
       }
-      Bot_misc = what;
+      Bot_sep = sep;
+      Bot_what = what;
+      Bot_indx = BOT_UNFOCUS;
       Bot_func = bot_misc_show;
       Bot_task = Curwin->ppt[Curwin->begtask]->tid;
    }
@@ -5598,19 +5652,26 @@ static void keys_global (int ch) {
 #endif
          break;
       case kbd_CtrlG:
-         bot_item_toggle((L_CGROUP), "control groups");
+         bot_item_toggle((L_CGROUP), "control groups", '/');
          break;
+      case kbd_CtrlI:
+         if (Bot_what) {
+            ++Bot_indx;
+            if (Bot_indx > bot_focus(NULL, NULL))
+               Bot_indx = BOT_UNFOCUS;
+         }
+          break;
       case kbd_CtrlK:
-         bot_item_toggle((L_CMDLINE), "command line");
+         bot_item_toggle((L_CMDLINE), "command line", ' ');
          break;
       case kbd_CtrlN:
-         bot_item_toggle((L_ENVIRON), "environment");
+         bot_item_toggle((L_ENVIRON), "environment", ' ');
          break;
       case kbd_CtrlP:
-         bot_misc_toggle(BOT_MISC_NS);
+         bot_misc_toggle(BOT_MISC_NS, ',');
          break;
       case kbd_CtrlU:
-         bot_item_toggle((L_SUPGRP), "supplementary groups");
+         bot_item_toggle((L_SUPGRP), "supplementary groups", ',');
          break;
       case kbd_ENTER:             // these two have the effect of waking us
       case kbd_SPACE:             // from 'pselect', refreshing the display
@@ -6425,7 +6486,7 @@ static void do_key (int ch) {
       { keys_global,
          { '?', 'B', 'd', 'E', 'e', 'f', 'g', 'H', 'h'
          , 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0'
-         , kbd_CtrlE, kbd_CtrlG, kbd_CtrlK, kbd_CtrlN, kbd_CtrlP, kbd_CtrlU
+         , kbd_CtrlE, kbd_CtrlG, kbd_CtrlI, kbd_CtrlK, kbd_CtrlN, kbd_CtrlP, kbd_CtrlU
          , kbd_ENTER, kbd_SPACE, '\0' } },
       { keys_summary,
          { '!', '1', '2', '3', '4', 'C', 'l', 'm', 't', '\0' } },
index f2703c9715aa3e3c88b4e555d0839d1bb71c525b..d7eac62881769936693df614853332ef25016b19 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -185,6 +185,7 @@ char *strcasestr(const char *haystack, const char *needle);
 #define kbd_DEL    139
 #define kbd_CtrlE  '\005'
 #define kbd_CtrlG  '\007'
+#define kbd_CtrlI  '\011'
 #define kbd_CtrlK  '\013'
 #define kbd_CtrlN  '\016'
 #define kbd_CtrlO  '\017'
@@ -821,12 +822,13 @@ typedef struct WIN_t {
 //atic inline const char *forest_display (const WIN_t *q, int idx);
 //atic void          forest_excluded (WIN_t *q);
 /*------  Special Separate Bottom Window support  ------------------------*/
-//atic void          bot_do_see (const char *str, const char *pgm);
+//atic void          bot_do (const char *str, int focus);
+//atic int           bot_focus (const char *hdr, const char *str);
 //atic void          bot_item_show (void);
-//atic void          bot_item_toggle (enum pflag item, const char *name);
+//atic void          bot_item_toggle (enum pflag item, const char *name, char sep);
 //atic char         *bot_misc_hlp (proc_t *p);
 //atic void          bot_misc_show (void);
-//atic void          bot_misc_toggle (int what);
+//atic void          bot_misc_toggle (int what, char sep);
 /*------  Interactive Input Tertiary support  ----------------------------*/
 //atic inline int    find_ofs (const WIN_t *q, const char *buf);
 //atic void          find_string (int ch);