summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2015-07-17 22:38:29 +0000
committerIngo Schwarze <schwarze@openbsd.org>2015-07-17 22:38:29 +0000
commit7cdeeeae6409bfe474baf9dd555cf51d8212d6ed (patch)
treea478c8d9379a05b3382406a30c1149d50e7700dc /main.c
parent2b56f6d999fa4eaa5790ac8a55e49a0060a44a7f (diff)
downloadmandoc-7cdeeeae6409bfe474baf9dd555cf51d8212d6ed.tar.gz
Initial, still somewhat experimental implementation to leverage
less(1) -T and :t ctags(1)-like functionality to jump to the definitions of various terms inside manual pages. To be polished in the tree, so bear with me and report issues. Technically, if less(1) is used as a pager, information is collected by the mdoc(7) terminal formatter, first stored using the ohash library, then ultimately written to a temporary file which is passed to less via -T. No change intended for other output formatters or when running without a pager. Based on an idea from Kristaps using feedback from many, in particular phessler@ nicm@ millert@ halex@ doug@ kspillner@ deraadt@.
Diffstat (limited to 'main.c')
-rw-r--r--main.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/main.c b/main.c
index 61aba7ae..75f6e4e0 100644
--- a/main.c
+++ b/main.c
@@ -39,6 +39,7 @@
#include "roff.h"
#include "mdoc.h"
#include "man.h"
+#include "tag.h"
#include "main.h"
#include "manconf.h"
#include "mansearch.h"
@@ -497,7 +498,9 @@ out:
if (pager_pid != 0 && pager_pid != 1) {
fclose(stdout);
+ tag_write();
waitpid(pager_pid, NULL, 0);
+ tag_unlink();
}
return((int)rc);
@@ -959,10 +962,50 @@ spawn_pager(void)
char *argv[MAX_PAGER_ARGS];
const char *pager;
char *cp;
+ size_t cmdlen;
int fildes[2];
int argc;
pid_t pager_pid;
+ pager = getenv("MANPAGER");
+ if (pager == NULL || *pager == '\0')
+ pager = getenv("PAGER");
+ if (pager == NULL || *pager == '\0')
+ pager = "more -s";
+ cp = mandoc_strdup(pager);
+
+ /*
+ * Parse the pager command into words.
+ * Intentionally do not do anything fancy here.
+ */
+
+ argc = 0;
+ while (argc + 4 < MAX_PAGER_ARGS) {
+ argv[argc++] = cp;
+ cp = strchr(cp, ' ');
+ if (cp == NULL)
+ break;
+ *cp++ = '\0';
+ while (*cp == ' ')
+ cp++;
+ if (*cp == '\0')
+ break;
+ }
+
+ /* Read all text right away and use the tag file. */
+
+ if ((cmdlen = strlen(argv[0])) >= 4) {
+ cp = argv[0] + cmdlen - 4;
+ if (strcmp(cp, "less") == 0 ||
+ strcmp(cp, "more") == 0) {
+ tag_init();
+ argv[argc++] = mandoc_strdup("+G1G");
+ argv[argc++] = mandoc_strdup("-T");
+ argv[argc++] = tag_filename();
+ }
+ }
+ argv[argc] = NULL;
+
if (pipe(fildes) == -1) {
fprintf(stderr, "%s: pipe: %s\n",
progname, strerror(errno));
@@ -998,32 +1041,6 @@ spawn_pager(void)
}
close(fildes[0]);
- pager = getenv("MANPAGER");
- if (pager == NULL || *pager == '\0')
- pager = getenv("PAGER");
- if (pager == NULL || *pager == '\0')
- pager = "more -s";
- cp = mandoc_strdup(pager);
-
- /*
- * Parse the pager command into words.
- * Intentionally do not do anything fancy here.
- */
-
- argc = 0;
- while (argc + 1 < MAX_PAGER_ARGS) {
- argv[argc++] = cp;
- cp = strchr(cp, ' ');
- if (cp == NULL)
- break;
- *cp++ = '\0';
- while (*cp == ' ')
- cp++;
- if (*cp == '\0')
- break;
- }
- argv[argc] = NULL;
-
/* Hand over to the pager. */
execvp(argv[0], argv);