diff options
| author | hachem <im@hachem.wtf> | 2026-09-03 00:59:51 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-03 00:59:51 +0200 |
| commit | 97a80d04489dd74c6d756eac75f9355b315d3b40 (patch) | |
| tree | 1acba755c647ef722ca32495118029be1e3ce50f | |
| parent | 0893b9de6610f0b94e79203afa094340487a9d93 (diff) | |
docs: man page and README
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | README.md | 63 | ||||
| -rw-r--r-- | jafm.1 | 132 |
3 files changed, 195 insertions, 5 deletions
@@ -35,7 +35,9 @@ TARGET := jafm SRC := jafm.c PREFIX ?= /usr/local +MANPREFIX ?= $(PREFIX)/share/man BINDIR := $(DESTDIR)$(PREFIX)/bin +MANDIR := $(DESTDIR)$(MANPREFIX)/man1 all: $(TARGET) @@ -52,9 +54,12 @@ check: install: $(TARGET) install -d $(BINDIR) install -m 755 $(TARGET) $(BINDIR)/$(TARGET) + install -d $(MANDIR) + install -m 644 $(TARGET).1 $(MANDIR)/$(TARGET).1 uninstall: rm -f $(BINDIR)/$(TARGET) + rm -f $(MANDIR)/$(TARGET).1 clean: rm -rf $(TARGET) $(TARGET).dSYM @@ -1,15 +1,68 @@ # just a fucking manual -jafm is just a convenient utility program that searches through your man pages instead of making you find the man page yourself. I find it genuinely insane how illiterate the default `man` command can be. I was making a simple HTTP server in C, and, as you know, I wanted to look up the man page for `sockaddr_in`. But every single time I tried `man sockaddr_in`, `man` would go: `No manual entry for sockaddr_in`. And this *should* work, because it works on Linux. But, as it so happens, I am not on Linux all the time. +`jafm` searches through **all your man pages** for a symbol, figures out which +page actually documents it, and opens it for you. -The documentation for `sockaddr_in` was there. It was inside another man page. So naturally, I had to somehow figure out which random man page contained the thing I was looking for. jafm fixes that. It just looks through **all your man pages**, tells you where it found your query, gives you a selector, and opens the man page for you. +I find it genuinely insane how fucking illiterate the default `man` command can be. I was making a simple HTTP server in C and wanted the man page for `sockaddr_in`. Every single time I tried `man sockaddr_in` it went: `No manual entry for sockaddr_in`. And this *should* work, because it works on Linux. But, as it so happens, I am not on Linux all the time. The docs for `sockaddr_in` were right there, inside another page (`inet`). So I had to somehow guess which random man page contained the thing I was looking for. `jafm` fixes that. It reads every page, ranks the hits so the real one is on top, shows you a picker with a live preview, and opens whatever you choose. ```sh -$ jafm sockaddr_in +$ jafm sockaddr ``` That's it. I find it genuinely unacceptable that this is not an already solved issue. -## License +## What you get + +`jafm` searches every page in your `manpath`, in parallel, in a fraction of a second. It **ranks by relevance** so the page that actually documents your symbol floats to the top, tells you *what* it found and its **kind** (`sockaddr_in (struct)`), and gives you an **interactive picker** with a live `man` **preview** on the side and the match highlighted in the page. + +## Usage + +```text +$ jafm --help +jafm 0.1.0 - just a fucking manual + +greps your whole manpath for a symbol and opens the page that actually +documents it, because `man <symbol>` gives up way too easily. + +usage: jafm [-1] [-l] [-e] [-t type] [-j threads] <symbol> + jafm [-v | -h] + +options: + -1, --first open the best match without asking + -l, --list just print what it found, open nothing + -e, --exact match the symbol as a whole word only + -t, --type KIND only show matches where the symbol is a KIND + (struct, union, enum, typedef, function) + -j, --jobs N scan with N worker threads (default 8) + -v, --version print version and bail + -h, --help print this and bail + +by hachem <im@hachem.wtf> +``` + +In the picker: `↑`/`↓` or `k`/`j` to move, `Enter` to open, `q` to bail. Pipe +its stdin instead of a tty and it drops to a numbered prompt. + +```sh +$ jafm sockaddr # pick from the list +$ jafm -1 getentropy # open the best match straight away +$ jafm -t struct -l sockaddr # every struct named *sockaddr*, printed +$ jafm -e -1 inet # whole word, open the winner +``` + +## Build +Needs a C17 compiler, `zlib`, and pthreads. Nothing else. + +```sh +$ sudo make install # -> /usr/local/bin + man page +$ make install PREFIX=~/.local # or somewhere without sudo +``` -jafm is licensed under the MIT License. See [LICENSE](LICENSE) for more information. +It really is one file, so if you don't want the Makefile: + +```sh +cc -O2 -std=c17 jafm.c -o jafm -lz -lpthread +``` + +## License +`jafm` is licensed under the MIT License. See [LICENSE](LICENSE) for more. @@ -0,0 +1,132 @@ +.TH JAFM 1 2026-09-03 "jafm 0.1.0" "General Commands Manual" +.SH NAME +jafm \- just a fucking manual: find a symbol across every man page and open it +.SH SYNOPSIS +.B jafm +.RB [ \-1 ] +.RB [ \-l ] +.RB [ \-e ] +.RB [ \-t +.IR type ] +.RB [ \-j +.IR threads ] +.I symbol +.br +.B jafm +.RB [ \-v | \-h ] +.SH DESCRIPTION +.B jafm +greps every man page in your +.B manpath +for +.IR symbol , +ranks the hits so the page that actually documents it floats to the top, and +drops you into an interactive picker with a live preview. Pick one and it opens +in +.BR man (1). +.PP +It exists because +.B "man <symbol>" +gives up the moment the thing you want lives inside some other page. +.BR sockaddr_in , +for example, is documented inside +.BR inet (4). +jafm just reads all of them and finds it. +.PP +When standard input is not a terminal (say, a pipe), jafm skips the interactive +UI: it prints the numbered matches and reads a selection number from stdin. +.SH OPTIONS +.TP +.BR \-1 ", " \-\-first +Open the best (top\-ranked) match immediately, without the picker. +.TP +.BR \-l ", " \-\-list +Print the matches and exit. Opens nothing. +.TP +.BR \-e ", " \-\-exact +Match +.I symbol +as a whole word only, so +.B sockaddr +no longer drags in +.BR sockaddr_in . +.TP +.BR \-t ", " \-\-type " " \fIkind\fR +Only show pages where the symbol appears as +.IR kind : +one of +.BR struct ", " union ", " enum ", " typedef ", or " function . +.TP +.BR \-j ", " \-\-jobs " " \fIn\fR +Scan with +.I n +worker threads (default 8, capped at 64). +.TP +.BR \-v ", " \-\-version +Print version and exit. +.TP +.BR \-h ", " \-\-help +Print a usage summary and exit. +.SH KEYS +Inside the picker: +.TP +.BR \(ua ", " \(da ", " k ", " j +Move the selection. +.TP +.B Enter +Open the highlighted page in +.BR man (1). +.TP +.BR q ", Ctrl-C" +Quit without opening anything. +.SH RANKING +Matches are scored by where the symbol shows up, best first: its filename, then +the NAME section, then a type definition +.RB ( "struct ... {" ), +then the SYNOPSIS, then anywhere in the body. Pages in the core sections +(headers and sections 2, 4, 5, 7, 9) are weighted above library and command +pages, and a page found under several man roots is collapsed to one entry. +.SH COMPRESSION +Plain and +.B gzip +pages are read directly; +.BR zstd ", " xz ", and " bzip2 +pages are read through the matching decompressor if it is installed, which +it will be on any system that stores its pages that way. +.SH EXAMPLES +.nf +.RS +# find the page that documents sockaddr, pick from a list +jafm sockaddr + +# skip the picker, open the best match +jafm -1 getentropy + +# only structs, printed rather than opened +jafm -t struct -l sockaddr + +# whole word, open the winner +jafm -e -1 inet +.RE +.fi +.SH EXIT STATUS +.TP +.B 0 +A page was opened, or +.B \-l +listed matches. +.TP +.B 1 +Bad usage, no matches, or nothing was selected. +.SH ENVIRONMENT +.TP +.B MANPATH +Honored via +.BR manpath (1), +which jafm runs to find where your pages live. +.SH SEE ALSO +.BR man (1), +.BR manpath (1), +.BR apropos (1) +.SH AUTHOR +hachem <im@hachem.wtf> |
