add docs programs
This commit is contained in:
165
bin/docs-list.c
Executable file
165
bin/docs-list.c
Executable file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/tcc -run
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void print_man_dir(FILE *menu, const char *dir) {
|
||||
DIR *d = opendir(dir);
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct dirent *ent;
|
||||
while ((ent = readdir(d))) {
|
||||
if (ent->d_name[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
char file[512];
|
||||
snprintf(file, sizeof(file), "%s", ent->d_name);
|
||||
|
||||
const char *suffixes[] = {".gz", ".bz2", ".xz", ".lzma", ".zst"};
|
||||
for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) {
|
||||
size_t flen = strlen(file);
|
||||
size_t slen = strlen(suffixes[i]);
|
||||
if (flen > slen && strcmp(file + flen - slen, suffixes[i]) == 0) {
|
||||
file[flen - slen] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *dot = strrchr(file, '.');
|
||||
if (!dot || dot == file || !dot[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*dot++ = '\0';
|
||||
fprintf(menu, "%s (%s)\tman\n", file, dot);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
void print_man_pages(FILE *menu, const char *root) {
|
||||
DIR *d = opendir(root);
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct dirent *ent;
|
||||
char path[4096];
|
||||
while ((ent = readdir(d))) {
|
||||
if (strncmp(ent->d_name, "man", 3) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s", root, ent->d_name);
|
||||
print_man_dir(menu, path);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
char path[] = "/tmp/docs-list.XXXXXX";
|
||||
int fd = mkstemp(path);
|
||||
if (fd < 0) {
|
||||
perror("mkstemp");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *menu = fdopen(fd, "w");
|
||||
if (!menu) {
|
||||
perror("fdopen");
|
||||
unlink(path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char line[8192];
|
||||
FILE *manpath = popen("manpath 2>/dev/null", "r");
|
||||
if (manpath && fgets(line, sizeof(line), manpath)) {
|
||||
line[strcspn(line, "\n")] = '\0';
|
||||
for (char *dir = strtok(line, ":"); dir; dir = strtok(NULL, ":")) {
|
||||
print_man_pages(menu, dir);
|
||||
}
|
||||
}
|
||||
if (manpath) {
|
||||
pclose(manpath);
|
||||
}
|
||||
|
||||
FILE *pydoc = popen("python -c 'import pkgutil; [print(m) for m in sorted({m.name for m in pkgutil.iter_modules()})]'", "r");
|
||||
if (pydoc) {
|
||||
while (fgets(line, sizeof(line), pydoc)) {
|
||||
line[strcspn(line, "\n")] = '\0';
|
||||
fprintf(menu, "%s\tpydoc\n", line);
|
||||
}
|
||||
pclose(pydoc);
|
||||
}
|
||||
|
||||
fclose(menu);
|
||||
|
||||
char command[1024];
|
||||
snprintf(command, sizeof(command), "wmenu -i -l 20 < '%s'", path);
|
||||
|
||||
FILE *wmenu = popen(command, "r");
|
||||
if (!wmenu) {
|
||||
perror("wmenu");
|
||||
unlink(path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!fgets(line, sizeof(line), wmenu)) {
|
||||
pclose(wmenu);
|
||||
unlink(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int status = pclose(wmenu);
|
||||
unlink(path);
|
||||
if (status != 0) {
|
||||
return WIFEXITED(status) ? WEXITSTATUS(status) : 1;
|
||||
}
|
||||
|
||||
line[strcspn(line, "\n")] = '\0';
|
||||
char *kind = strrchr(line, '\t');
|
||||
if (!kind) {
|
||||
return 0;
|
||||
}
|
||||
*kind++ = '\0';
|
||||
|
||||
if (strcmp(kind, "man") == 0) {
|
||||
char *s = line;
|
||||
char name[256] = {0};
|
||||
char section[64] = {0};
|
||||
size_t i = 0;
|
||||
|
||||
while (*s && !isspace((unsigned char)*s) && *s != '(' && i < sizeof(name) - 1) {
|
||||
name[i++] = *s++;
|
||||
}
|
||||
|
||||
char *open = strchr(s, '(');
|
||||
char *close = open ? strchr(open + 1, ')') : NULL;
|
||||
if (open && close && close > open + 1) {
|
||||
size_t len = close - open - 1;
|
||||
if (len >= sizeof(section)) {
|
||||
len = sizeof(section) - 1;
|
||||
}
|
||||
memcpy(section, open + 1, len);
|
||||
}
|
||||
|
||||
if (name[0] && section[0]) {
|
||||
execlp("foot", "foot", "-e", "man", section, name, NULL);
|
||||
} else if (name[0]) {
|
||||
execlp("foot", "foot", "-e", "man", name, NULL);
|
||||
}
|
||||
} else if (strcmp(kind, "pydoc") == 0 && line[0]) {
|
||||
execlp("foot", "foot", "-e", "python", "-m", "pydoc", line, NULL);
|
||||
}
|
||||
|
||||
perror("foot");
|
||||
return 1;
|
||||
}
|
||||
2
bin/man-list
Executable file
2
bin/man-list
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
man -k . | wmenu -i -l 20 | awk '{print $1}' | xargs -r man
|
||||
9
bin/pydoc-list
Executable file
9
bin/pydoc-list
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
module="$(
|
||||
python - <<'PY' | wmenu -i -l 20
|
||||
import pkgutil
|
||||
for m in sorted({m.name for m in pkgutil.iter_modules()}):
|
||||
print(m)
|
||||
PY
|
||||
)"
|
||||
[ -n "$module" ] && foot -e python -m pydoc "$module"
|
||||
Reference in New Issue
Block a user