NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/58579: man(1) should make use of terminal width
>Number: 58579
>Category: bin
>Synopsis: man(1) should make use of terminal width
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Aug 11 06:20:00 +0000 2024
>Originator: RVP
>Release: NetBSD/amd64 10.99.11
>Organization:
>Environment:
NetBSD/amd64 10.99.11
>Description:
mandoc(1) has a `-O width=NNN' option which can be used for displaying
man-pages at some specified width. But, man(1) makes no use of this,
always formatting the display for 80 columns. It can do better...
>How-To-Repeat:
`man anything' on a wide terminal, then note the wasted real-estate on
the right.
>Fix:
This old patch (but, still applies cleanly) is the most non-instrusive
way that I could think of (ie. aside from fiddling with /etc/man.conf)
to fix this wastage. It makes man honour a MANWIDTH env. var. which can
be set to a COLUMN value or the special token `tty' which just means use
the current tty-width.
---START patch---
diff -urN a/man/man.c b/man/man.c
--- a/man/man.c 2020-04-09 11:28:32.000000000 +0000
+++ b/man/man.c 2020-11-14 08:21:48.576113574 +0000
@@ -44,6 +44,7 @@
#endif
#endif /* not lint */
+#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
@@ -51,6 +52,7 @@
#include <ctype.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <glob.h>
@@ -101,6 +103,7 @@
/* other misc stuff */
const char *pager; /* pager to use */
size_t pagerlen; /* length of the above */
+ int manwidth; /* pass -O width= to mandoc(1) if > RMRG */
const char *machine; /* machine */
const char *machclass; /* machine class */
};
@@ -120,6 +123,9 @@
static void addpath(struct manstate *, const char *, size_t, const char *);
static const char *getclass(const char *);
static void printmanpath(struct manstate *);
+static int get_mw(void);
+static char *ins_mw(const char *, const char *, struct manstate *);
+
/*
* main function
@@ -222,6 +228,7 @@
else
m.pager = _PATH_PAGER;
m.pagerlen = strlen(m.pager);
+ m.manwidth = get_mw();
}
}
@@ -804,8 +811,11 @@
(void)cleanup();
exit(EXIT_FAILURE);
}
+ if ((b = ins_mw(fmt, "/usr/bin/mandoc", mp)) != NULL)
+ fmt = b;
(void)snprintf(buf, sizeof(buf), "%s > %s", fmt, tpath);
(void)snprintf(cmd, sizeof(cmd), fmtcheck_ok(buf, "%s"), p);
+ free(b);
(void)system(cmd);
(void)close(fd);
if ((*pathp = strdup(tpath)) == NULL) {
@@ -1077,3 +1087,61 @@
globfree(&pg);
}
}
+
+/*
+ * get_mw --
+ * Return a user-defined MANWIDTH or determine one if set to "tty",
+ * or -1 on errors.
+ */
+int
+get_mw(void)
+{
+ char *p, *ep;
+ int wid;
+
+ if ((p = getenv("MANWIDTH")) == NULL)
+ return -1;
+ if (strcmp(p, "tty") == 0) {
+ struct winsize ws;
+ if (!isatty(STDOUT_FILENO) ||
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
+ return -1;
+ return ws.ws_col;
+ }
+ errno = 0;
+ wid = (int)strtol(p, &ep, 10);
+ if (ep == p || *ep != '\0' || errno)
+ return -1;
+ return wid;
+}
+
+/*
+ * ins_mw --
+ * Insert a " -O width=NN " option right after the "/usr/bin/mandoc"
+ * command.
+ * Turns:
+ * 1. _build stuff /usr/bin/mandoc ->
+ * _build stuff /usr/bin/mandoc -O width=NN
+ * 2. _build stuff /usr/bin/mandoc stuff %s ->
+ * _build stuff /usr/bin/mandoc -O width=NN stuff %s
+ * etc.
+ * We do it this way because mandoc(1) doesn't allow options after
+ * filenames, so a simple append won't work.
+ */
+static char*
+ins_mw(const char* line, const char* s, struct manstate* mp)
+{
+ enum { RMRG = 3 }; /* Right margin to match mandoc's LHS */
+ const char* p;
+ char* ret;
+
+ if (mp->manwidth <= RMRG)
+ return NULL;
+ if ((p = strstr(line, s)) == NULL)
+ return NULL; /* not mandoc */
+ p += strlen(s);
+ if (asprintf(&ret, "%.*s -O width=%d %s",
+ (int)(p - line), line, mp->manwidth - RMRG, p) == -1)
+ return NULL;
+ return ret;
+}
---END patch---
Home |
Main Index |
Thread Index |
Old Index