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