about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile15
-rw-r--r--README.md2
-rw-r--r--doc/build.md2
-rw-r--r--doc/cha-api.795
-rw-r--r--doc/cha-config.5140
-rw-r--r--doc/cha-protocols.79
-rw-r--r--doc/cha-terminal.776
-rw-r--r--doc/cha.12
-rw-r--r--doc/config.md2
-rw-r--r--doc/protocols.md15
-rw-r--r--doc/terminal.md (renamed from doc/terminals.md)11
11 files changed, 344 insertions, 25 deletions
diff --git a/Makefile b/Makefile
index 20fd7689..0492253d 100644
--- a/Makefile
+++ b/Makefile
@@ -197,11 +197,14 @@ $(OBJDIR)/man/cha-%.md: doc/%.md md2manpreproc
 	@mkdir -p "$(OBJDIR)/man"
 	./md2manpreproc $< > $@
 
-doc/cha-%.5: $(OBJDIR)/man/cha-%.md
+$(OBJDIR)/man/cha-%.md.roff: $(OBJDIR)/man/cha-%.md
 	pandoc --standalone --to man $< -o $@
 
-doc/cha-%.7: $(OBJDIR)/man/cha-%.md
-	pandoc --standalone --to man $< -o $@
+doc/cha-%.5: $(OBJDIR)/man/cha-%.md.roff
+	awk 'last=="T}" && $$1=="T{" {print "_"} {last=$$1} 1' $< > $@
+
+doc/cha-%.7: $(OBJDIR)/man/cha-%.md.roff
+	awk 'last=="T}" && $$1=="T{" {print "_"} {last=$$1} 1' $< > $@
 
 .PHONY: clean
 clean:
@@ -215,7 +218,7 @@ distclean: clean
 manpages1 = cha.1 mancha.1
 manpages5 = cha-config.5 cha-mailcap.5 cha-mime.types.5 cha-localcgi.5 \
 	cha-urimethodmap.5
-manpages7 = cha-protocols.7 cha-api.7 cha-troubleshooting.7 cha-image.7 cha-css.7
+manpages7 = cha-protocols.7 cha-api.7 cha-troubleshooting.7 cha-image.7 cha-css.7 cha-terminal.7
 
 manpages = $(manpages1) $(manpages5) $(manpages7)
 
@@ -284,10 +287,6 @@ uninstall:
 	for f in cha-protocols.5 cha-api.5 cha-troubleshooting.5 cha-image.5; do rm -f "$(DESTDIR)$(MANPREFIX5)/$$f"; done
 	for f in $(manpages1); do rm -f "$(DESTDIR)$(MANPREFIX1)/$$f"; done
 
-.PHONY: submodule
-submodule:
-	echo 'We no longer use submodules; you can safely drop "make submodule" from build scripts.'
-
 test/net/run: test/net/run.nim
 	$(NIMC) test/net/run.nim
 
diff --git a/README.md b/README.md
index f8f95f54..99eecfd9 100644
--- a/README.md
+++ b/README.md
@@ -95,7 +95,7 @@ Markdown files.
 * protocols: [doc/protocols.md](doc/protocols.md)
 * inline images: [doc/image.md](doc/image.md)
 * CSS: [doc/css.md](doc/css.md)
-* terminals: [doc/terminals.md](doc/terminals.md)
+* terminal compatibility: [doc/terminal.md](doc/terminal.md)
 * troubleshooting: [doc/troubleshooting.md](doc/troubleshooting.md)
 
 If you're interested in modifying the code:
diff --git a/doc/build.md b/doc/build.md
index 4ec6ae77..c7c9c7f8 100644
--- a/doc/build.md
+++ b/doc/build.md
@@ -67,8 +67,6 @@ a limited set of C compilers. If you want to override the C compiler:
 * `install`: install the `cha` binary, and if man pages were generated,
   those as well
 * `uninstall`: remove the `cha` binary and Chawan man pages
-* `submodule`: no longer used
-* `subtree`: pull in new commits from subtrees (for development)
 
 ## Cross-compiling
 
diff --git a/doc/cha-api.7 b/doc/cha-api.7
index e470cf19..ddd1be4d 100644
--- a/doc/cha-api.7
+++ b/doc/cha-api.7
@@ -69,6 +69,7 @@ T}@T{
 Exit the browser.
 T}@T{
 T}
+_
 T{
 \f[CR]suspend()\f[R]
 T}@T{
@@ -77,6 +78,7 @@ SIGTSTP signal.
 Note: this suspends the entire process group.
 T}@T{
 T}
+_
 T{
 \f[CR]readFile(path)\f[R]
 T}@T{
@@ -85,6 +87,7 @@ Returns the file\[cq]s content as a string, or null if the file does not
 exist.
 T}@T{
 T}
+_
 T{
 \f[CR]writeFile(path, content)\f[R]
 T}@T{
@@ -92,6 +95,7 @@ Write \f[CR]content\f[R] to the file at \f[CR]path\f[R].
 Throws a TypeError if this failed for whatever reason.
 T}@T{
 T}
+_
 T{
 \f[CR]getenv(name, fallback = null)\f[R]
 T}@T{
@@ -99,6 +103,7 @@ Get an environment variable by \f[CR]name\f[R].
 Returns \f[CR]fallback\f[R] if the variable does not exist.
 T}@T{
 T}
+_
 T{
 \f[CR]setenv(name, value)\f[R]
 T}@T{
@@ -107,6 +112,7 @@ Throws a type error if the operation failed (e.g.\ because the
 variable\[cq]s size exceeded an OS\-specified limit.)
 T}@T{
 T}
+_
 T{
 \f[CR]pager\f[R]
 T}@T{
@@ -114,6 +120,7 @@ The pager object.
 Implements \f[CR]Pager\f[R], as described below.
 T}@T{
 T}
+_
 T{
 \f[CR]line\f[R]
 T}@T{
@@ -161,6 +168,7 @@ If this string ends with a newline
 loaded directly.
 T}@T{
 T}
+_
 T{
 \f[CR]loadSubmit(url)\f[R]
 T}@T{
@@ -168,6 +176,7 @@ Act as if \f[CR]url\f[R] had been input into the address bar.
 Same as \f[CR]pager.load(url + \[dq]\[rs]n\[dq])\f[R].
 T}@T{
 T}
+_
 T{
 \f[CR]gotoURL(url, options = {replace: null, contentType: null, save: false})\f[R]
 T}@T{
@@ -182,6 +191,7 @@ When \f[CR]save\f[R] is true, the user is prompted to save the resource
 instead of displaying it in a buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]nextBuffer()\f[R], \f[CR]prevBuffer()\f[R],
 \f[CR]nextSiblingBufer()\f[R], \f[CR]prevSiblingBuffer()\f[R],
@@ -194,12 +204,14 @@ traversal; \[ga]\f[CR]nextSiblingBufer()\f[R],
 \f[CR]parentBuffer()\f[R] returns to the parent.
 T}@T{
 T}
+_
 T{
 \f[CR]dupeBuffer()\f[R]
 T}@T{
 Duplicate the current buffer by loading its source to a new buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]discardBuffer(buffer = pager.buffer, dir = pager.navDirection)\f[R]
 T}@T{
@@ -210,12 +222,14 @@ Possible values of \f[CR]dir\f[R] are: \[lq]prev\[rq], \[lq]next\[rq],
 \[lq]first\-child\[rq], \[lq]any\[rq].
 T}@T{
 T}
+_
 T{
 \f[CR]discardTree()\f[R]
 T}@T{
 Discard all child buffers of the current buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]reload()\f[R]
 T}@T{
@@ -223,12 +237,14 @@ Open a new buffer with the current buffer\[cq]s URL, replacing the
 current buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]reshape()\f[R]
 T}@T{
 Reshape the current buffer (=render the current page anew.)
 T}@T{
 T}
+_
 T{
 \f[CR]redraw()\f[R]
 T}@T{
@@ -236,6 +252,7 @@ Redraw screen contents.
 Useful if something messed up the display.
 T}@T{
 T}
+_
 T{
 \f[CR]toggleSource()\f[R]
 T}@T{
@@ -243,18 +260,21 @@ If viewing an HTML buffer, open a new buffer with its source.
 Otherwise, open the current buffer\[cq]s contents as HTML.
 T}@T{
 T}
+_
 T{
 \f[CR]lineInfo()\f[R]
 T}@T{
 Display information about the current line.
 T}@T{
 T}
+_
 T{
 \f[CR]searchForward()\f[R], \f[CR]searchBackward()\f[R]
 T}@T{
 Search forward/backward for a string in the current buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]isearchForward()\f[R], \f[CR]isearchBackward()\f[R]
 T}@T{
@@ -262,6 +282,7 @@ Incremental\-search forward/backward for a string, highlighting the
 first result.
 T}@T{
 T}
+_
 T{
 \f[CR]gotoLine(n?)\f[R]
 T}@T{
@@ -270,18 +291,21 @@ If no arguments were specified, an input window for entering a line is
 shown.
 T}@T{
 T}
+_
 T{
 \f[CR]searchNext(n = 1)\f[R], \f[CR]searchPrev(n = 1)\f[R]
 T}@T{
 Jump to the nth next/previous search result.
 T}@T{
 T}
+_
 T{
 \f[CR]peek()\f[R]
 T}@T{
 Display an alert message of the current URL.
 T}@T{
 T}
+_
 T{
 \f[CR]peekCursor()\f[R]
 T}@T{
@@ -290,12 +314,14 @@ Multiple calls allow cycling through the two.
 (i.e.\ by default, press u once \-> title, press again \-> URL)
 T}@T{
 T}
+_
 T{
 \f[CR]showFullAlert()\f[R]
 T}@T{
 Show the last alert inside the line editor.
 T}@T{
 T}
+_
 T{
 \f[CR]ask(prompt)\f[R]
 T}@T{
@@ -306,6 +332,7 @@ Can be used to implement an exit prompt like this:
 \f[CR]q = \[aq]pager.ask(\[dq]Do you want to exit Chawan?\[dq]).then(x => x ? pager.quit() : void(0))\[aq]\f[R]
 T}@T{
 T}
+_
 T{
 \f[CR]askChar(prompt)\f[R]
 T}@T{
@@ -313,6 +340,7 @@ Ask the user for any character.
 Like \f[CR]pager.ask\f[R], but the return value is a character.
 T}@T{
 T}
+_
 T{
 \f[CR]extern(cmd, options = {env: { ... }, suspend: true, wait: false})\f[R]
 T}@T{
@@ -329,6 +357,7 @@ Redirect to /dev/null in the command if this is not desired.
 (This will be fixed in the future.)
 T}@T{
 T}
+_
 T{
 \f[CR]externCapture(cmd)\f[R]
 T}@T{
@@ -338,6 +367,7 @@ null is returned if the command wasn\[cq]t executed successfully, or if
 the command returned a non\-zero exit value.
 T}@T{
 T}
+_
 T{
 \f[CR]externInto(cmd, ins)\f[R]
 T}@T{
@@ -347,6 +377,7 @@ standard input stream.
 the return value is \f[CR]false\f[R].
 T}@T{
 T}
+_
 T{
 \f[CR]externFilterSource(cmd, buffer = null, contentType = null)\f[R]
 T}@T{
@@ -359,6 +390,7 @@ Returns \f[CR]undefined\f[R].
 (It should return a promise; TODO.)
 T}@T{
 T}
+_
 T{
 \f[CR]buffer\f[R]
 T}@T{
@@ -400,6 +432,7 @@ Move the cursor upwards/downwards by n lines, or if n is unspecified, by
 1.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorLeft(n = 1)\f[R], \f[CR]cursorRight(n = 1)\f[R]
 T}@T{
@@ -411,18 +444,21 @@ represent characters.
 broken for double\-width chars.)
 T}@T{
 T}
+_
 T{
 \f[CR]cursorLineBegin()\f[R], \f[CR]cursorLineEnd()\f[R]
 T}@T{
 Move the cursor to the first/last cell of the line.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorLineTextStart()\f[R]
 T}@T{
 Move the cursor to the first non\-blank character of the line.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorNextWord()\f[R], \f[CR]cursorNextViWord()\f[R],
 \f[CR]cursorNextBigWord()\f[R]
@@ -430,6 +466,7 @@ T}@T{
 Move the cursor to the beginning of the next word.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorPrevWord()\f[R], \f[CR]cursorPrevViWord()\f[R],
 \f[CR]cursorPrevBigWord()\f[R]
@@ -437,6 +474,7 @@ T}@T{
 Move the cursor to the end of the previous word.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorWordEnd()\f[R], \f[CR]cursorViWordEnd()\f[R],
 \f[CR]cursorBigWordEnd()\f[R]
@@ -445,6 +483,7 @@ Move the cursor to the end of the current word, or if already there, to
 the end of the next word.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorWordBegin()\f[R], \f[CR]cursorViWordBegin()\f[R],
 \f[CR]cursorBigWordBegin()\f[R]
@@ -453,12 +492,14 @@ Move the cursor to the beginning of the current word, or if already
 there, to the end of the previous word.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorNextLink()\f[R], \f[CR]cursorPrevLink()\f[R]
 T}@T{
 Move the cursor to the beginning of the next/previous clickable element.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorLinkNavDown(n = 1)\f[R], \f[CR]cursorLinkNavUp(n = 1)\f[R]
 T}@T{
@@ -467,6 +508,7 @@ Buffer scrolls pagewise, wrap to beginning/end if content is less than
 one page length.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorNextParagraph(n = 1)\f[R],
 \f[CR]cursorPrevParagraph(n = 1)\f[R]
@@ -474,12 +516,14 @@ T}@T{
 Move the cursor to the beginning/end of the nth next/previous paragraph.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorNthLink(n = 1)\f[R]
 T}@T{
 Move the cursor to the nth link of the document.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorRevNthLink(n = 1)\f[R]
 T}@T{
@@ -487,6 +531,7 @@ Move the cursor to the nth link of the document, counting backwards from
 the document\[cq]s last line.
 T}@T{
 T}
+_
 T{
 \f[CR]pageUp(n = 1)\f[R], \f[CR]pageDown(n = 1)\f[R],
 \f[CR]pageLeft(n = 1)\f[R], \f[CR]pageRight(n = 1)\f[R]
@@ -494,6 +539,7 @@ T}@T{
 Scroll up/down/left/right by n pages.
 T}@T{
 T}
+_
 T{
 \f[CR]halfPageUp(n = 1)\f[R], \f[CR]halfPageDown(n = 1)\f[R],
 \f[CR]halfPageLeft(n = 1)\f[R], \f[CR]halfPageRight(n = 1)\f[R]
@@ -501,6 +547,7 @@ T}@T{
 Scroll up/down/left/right by n half pages.
 T}@T{
 T}
+_
 T{
 \f[CR]scrollUp(n = 1)\f[R], \f[CR]scrollDown(n = 1)\f[R],
 \f[CR]scrollLeft(n = 1)\f[R], \f[CR]scrollRight(n = 1)\f[R]
@@ -508,18 +555,21 @@ T}@T{
 Scroll up/down/left/right by n lines.
 T}@T{
 T}
+_
 T{
 \f[CR]click()\f[R]
 T}@T{
 Click the HTML element currently under the cursor.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorFirstLine()\f[R], \f[CR]cursorLastLine()\f[R]
 T}@T{
 Move to the first/last line in the buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorTop()\f[R], \f[CR]cursorMiddle()\f[R],
 \f[CR]cursorBottom()\f[R]
@@ -528,6 +578,7 @@ Move to the first/middle/bottom line on the screen.
 (Equivalent to H/M/L in vi.)
 T}@T{
 T}
+_
 T{
 \f[CR]lowerPage(n = this.cursory)\f[R]
 T}@T{
@@ -536,6 +587,7 @@ line on the screen.
 (\f[CR]zt\f[R] in vim.)
 T}@T{
 T}
+_
 T{
 \f[CR]lowerPageBegin(n = this.cursory)\f[R]
 T}@T{
@@ -544,12 +596,14 @@ so that the cursor is on the top line on the screen.
 (\f[CR]z<CR>\f[R] in vi.)
 T}@T{
 T}
+_
 T{
 \f[CR]centerLine(n = this.cursory)\f[R]
 T}@T{
 Center screen around line n.\ (\f[CR]zz\f[R] in vim.)
 T}@T{
 T}
+_
 T{
 \f[CR]centerLineBegin(n = this.cursory)\f[R]
 T}@T{
@@ -558,6 +612,7 @@ non\-blank character.
 (\f[CR]z.\f[R] in vi.)
 T}@T{
 T}
+_
 T{
 \f[CR]raisePage(n = this.cursory)\f[R]
 T}@T{
@@ -566,6 +621,7 @@ line on the screen.
 (zb in vim.)
 T}@T{
 T}
+_
 T{
 \f[CR]lowerPageBegin(n = this.cursory)\f[R]
 T}@T{
@@ -574,6 +630,7 @@ so that the cursor is on the last line on the screen.
 (\f[CR]z\[ha]\f[R] in vi.)
 T}@T{
 T}
+_
 T{
 \f[CR]nextPageBegin(n = this.cursory)\f[R]
 T}@T{
@@ -583,6 +640,7 @@ Otherwise, go to the previous screen\[cq]s last line and raise the page.
 (\f[CR]z+\f[R] in vi.)
 T}@T{
 T}
+_
 T{
 \f[CR]cursorLeftEdge()\f[R], \f[CR]cursorMiddleColumn()\f[R],
 \f[CR]cursorRightEdge()\f[R]
@@ -590,12 +648,14 @@ T}@T{
 Move to the first/middle/last column on the screen.
 T}@T{
 T}
+_
 T{
 \f[CR]centerColumn()\f[R]
 T}@T{
 Center screen around the current column.
 T}@T{
 T}
+_
 T{
 \f[CR]findNextMark(x = this.cursorx, y = this.cursory)\f[R],
 \f[CR]findPrevMark(x = this.cursorx, y = this.cursory)\f[R]
@@ -604,6 +664,7 @@ Find the next/previous mark after/before \f[CR]x\f[R], \f[CR]y\f[R], if
 any; and return its id (or null if none were found.)
 T}@T{
 T}
+_
 T{
 \f[CR]setMark(id, x = this.cursorx, y = this.cursory)\f[R]
 T}@T{
@@ -613,6 +674,7 @@ If one already exists, it will be overridden and the function returns
 false.
 T}@T{
 T}
+_
 T{
 \f[CR]clearMark(id)\f[R]
 T}@T{
@@ -620,6 +682,7 @@ Clear the mark with the name \f[CR]id\f[R].
 Returns true if the mark existed, false otherwise.
 T}@T{
 T}
+_
 T{
 \f[CR]gotoMark(id)\f[R]
 T}@T{
@@ -627,6 +690,7 @@ If the mark \f[CR]id\f[R] exists, jump to its position and return true.
 Otherwise, do nothing and return false.
 T}@T{
 T}
+_
 T{
 \f[CR]gotoMarkY(id)\f[R]
 T}@T{
@@ -635,6 +699,7 @@ its Y position and return true.
 Otherwise, do nothing and return false.
 T}@T{
 T}
+_
 T{
 \f[CR]getMarkPos(id)\f[R]
 T}@T{
@@ -644,6 +709,7 @@ position.
 If the mark does not exist, return null.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorToggleSelection(n = 1, opts = {selectionType: \[dq]normal\[dq]})\f[R]
 T}@T{
@@ -654,6 +720,7 @@ selectionType may be \[lq]normal\[rq] (regular selection),
 (column\-based selection).
 T}@T{
 T}
+_
 T{
 \f[CR]getSelectionText()\f[R]
 T}@T{
@@ -662,30 +729,35 @@ Returns a promise, so consumers must \f[CR]await\f[R] it to get the
 text.
 T}@T{
 T}
+_
 T{
 \f[CR]markURL()\f[R]
 T}@T{
 Convert URL\-like strings to anchors on the current page.
 T}@T{
 T}
+_
 T{
 \f[CR]toggleImages()\f[R]
 T}@T{
 Toggle display of images in this buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]saveLink()\f[R]
 T}@T{
 Save URL pointed to by the cursor.
 T}@T{
 T}
+_
 T{
 \f[CR]saveSource()\f[R]
 T}@T{
 Save the source of this buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]setCursorX(x)\f[R], \f[CR]setCursorY(y)\f[R],
 \f[CR]setCursorXY(x, y)\f[R], \f[CR]setCursorXCenter(x)\f[R],
@@ -697,6 +769,7 @@ Variants that end with \[lq]Center\[rq] will also center the screen
 around the position if it is outside the screen.
 T}@T{
 T}
+_
 T{
 \f[CR]url\f[R]
 T}@T{
@@ -704,6 +777,7 @@ Getter for the buffer\[cq]s URL.
 Note: this returns a \f[CR]URL\f[R] object, not a string.
 T}@T{
 T}
+_
 T{
 \f[CR]hoverTitle\f[R], \f[CR]hoverLink\f[R], \f[CR]hoverImage\f[R]
 T}@T{
@@ -712,6 +786,7 @@ currently under the cursor.
 Returns the empty string if no title is found.
 T}@T{
 T}
+_
 T{
 \f[CR]cursorx\f[R], \f[CR]cursory\f[R]
 T}@T{
@@ -720,18 +795,21 @@ Note that although the status line is 1\-based, these values are
 0\-based.
 T}@T{
 T}
+_
 T{
 \f[CR]fromx\f[R], \f[CR]fromy\f[R]
 T}@T{
 The x/y position of the first line displayed on the screen.
 T}@T{
 T}
+_
 T{
 \f[CR]numLines\f[R]
 T}@T{
 The number of lines currently loaded in the buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]width\f[R], \f[CR]height\f[R]
 T}@T{
@@ -739,12 +817,14 @@ The width and height of the buffer\[cq]s window (i.e.\ the visible part
 of the canvas).
 T}@T{
 T}
+_
 T{
 \f[CR]process\f[R]
 T}@T{
 The process ID of the buffer.
 T}@T{
 T}
+_
 T{
 \f[CR]title\f[R]
 T}@T{
@@ -752,6 +832,7 @@ Text from the \f[CR]title\f[R] element, or the buffer\[cq]s URL if there
 is no title.
 T}@T{
 T}
+_
 T{
 \f[CR]parent\f[R]
 T}@T{
@@ -759,12 +840,14 @@ Parent buffer in the buffer tree.
 May be null.
 T}@T{
 T}
+_
 T{
 \f[CR]children\f[R]
 T}@T{
 Array of child buffers in the buffer tree.
 T}@T{
 T}
+_
 T{
 \f[CR]select\f[R]
 T}@T{
@@ -805,72 +888,84 @@ T}@T{
 Submit line.
 T}@T{
 T}
+_
 T{
 \f[CR]cancel()\f[R]
 T}@T{
 Cancel operation.
 T}@T{
 T}
+_
 T{
 \f[CR]backspace()\f[R]
 T}@T{
 Delete character before cursor.
 T}@T{
 T}
+_
 T{
 \f[CR]delete()\f[R]
 T}@T{
 Delete character after cursor.
 T}@T{
 T}
+_
 T{
 \f[CR]clear()\f[R]
 T}@T{
 Clear text before cursor.
 T}@T{
 T}
+_
 T{
 \f[CR]kill()\f[R]
 T}@T{
 Clear text after cursor.
 T}@T{
 T}
+_
 T{
 \f[CR]clearWord()\f[R]
 T}@T{
 Delete word before cursor.
 T}@T{
 T}
+_
 T{
 \f[CR]killWord()\f[R]
 T}@T{
 Delete word after cursor.
 T}@T{
 T}
+_
 T{
 \f[CR]backward()\f[R], \f[CR]forward()\f[R]
 T}@T{
 Move cursor backward/forward by one character.
 T}@T{
 T}
+_
 T{
 \f[CR]nextWord()\f[R], \f[CR]prevWord()\f[R]
 T}@T{
 Move cursor to the next/previous word by one character.
 T}@T{
 T}
+_
 T{
 \f[CR]begin()\f[R], \f[CR]end()\f[R]
 T}@T{
 Move cursor to the beginning/end of the line.
 T}@T{
 T}
+_
 T{
 \f[CR]escape()\f[R]
 T}@T{
 Ignore keybindings for next character.
 T}@T{
 T}
+_
 T{
 \f[CR]nextHist()\f[R], \f[CR]prevHist()\f[R]
 T}@T{
diff --git a/doc/cha-config.5 b/doc/cha-config.5
index bd883e34..5b51eb8a 100644
--- a/doc/cha-config.5
+++ b/doc/cha-config.5
@@ -64,6 +64,7 @@ Page opened when Chawan is called with the \-V option and no other pages
 are passed as arguments.
 T}@T{
 T}
+_
 T{
 startup\-script
 T}@T{
@@ -77,6 +78,7 @@ Pages will not be loaded until this function exits.
 loading.)
 T}@T{
 T}
+_
 T{
 headless
 T}@T{
@@ -97,6 +99,7 @@ Piping \f[CR]cha\f[R] to an external program or passing the
 \[lq]dump\[rq].
 T}@T{
 T}
+_
 T{
 console\-buffer
 T}@T{
@@ -157,6 +160,7 @@ Note that disabling this does not affect user styles set in
 \f[CR][css]\f[R].
 T}@T{
 T}
+_
 T{
 scripting
 T}@T{
@@ -173,6 +177,7 @@ For security reasons, users are encouraged to selectively enable
 JavaScript with \f[CR][[siteconf]]\f[R] instead of using this setting.
 T}@T{
 T}
+_
 T{
 images
 T}@T{
@@ -183,6 +188,7 @@ T}@T{
 Enable/disable inline image display.
 T}@T{
 T}
+_
 T{
 cookie
 T}@T{
@@ -200,6 +206,7 @@ You may use the \f[CR][[siteconf]]\f[R] \[lq]share\-cookie\-jar\[rq]
 setting to adjust this behavior for specific sites.
 T}@T{
 T}
+_
 T{
 referer\-from
 T}@T{
@@ -213,6 +220,7 @@ For privacy reasons, users are encouraged to leave this option disabled,
 only enabling it for specific sites in \f[CR][[siteconf]]\f[R].
 T}@T{
 T}
+_
 T{
 autofocus
 T}@T{
@@ -225,6 +233,7 @@ focused on automatically after the buffer is loaded.
 If scripting is enabled, this also allows scripts to focus on elements.
 T}@T{
 T}
+_
 T{
 meta\-refresh
 T}@T{
@@ -238,6 +247,7 @@ respected.
 accepts all of them, \[lq]ask\[rq] brings up a pop\-up menu.
 T}@T{
 T}
+_
 T{
 history
 T}@T{
@@ -248,6 +258,7 @@ T}@T{
 Whether or not browsing history should be saved to the disk.
 T}@T{
 T}
+_
 T{
 mark\-links
 T}@T{
@@ -259,6 +270,7 @@ Add numeric markers before links.
 In headless/dump mode, this also prints a list of URLs after the page.
 T}@T{
 T}
+_
 T{
 user\-style
 T}@T{
@@ -303,6 +315,7 @@ T}@T{
 Whether on\-page searches should wrap around the document.
 T}@T{
 T}
+_
 T{
 ignore\-case
 T}@T{
@@ -355,6 +368,7 @@ charset, so long as the specified charset can decode the document
 correctly.
 T}@T{
 T}
+_
 T{
 display\-charset
 T}@T{
@@ -398,6 +412,7 @@ T}@T{
 Directory used to save temporary files.
 T}@T{
 T}
+_
 T{
 sockdir
 T}@T{
@@ -410,6 +425,7 @@ communication.
 This is currently unused.
 T}@T{
 T}
+_
 T{
 editor
 T}@T{
@@ -421,6 +437,7 @@ External editor command.
 %s is substituted for the file name, %d for the line number.
 T}@T{
 T}
+_
 T{
 mailcap
 T}@T{
@@ -432,17 +449,19 @@ Search path for mailcap files.
 (See \f[B]cha\-mailcap\f[R](5) for details.)
 T}@T{
 T}
+_
 T{
 mime\-types
 T}@T{
 array of paths
 T}@T{
-{see mime.types docs
+{see mime.types docs}
 T}@T{
 Search path for mime.types files.
 (See \f[B]cha\-mime.types\f[R](5) for details.)
 T}@T{
 T}
+_
 T{
 auto\-mailcap
 T}@T{
@@ -454,6 +473,7 @@ Mailcap file for entries that are automatically executed.
 The \[lq]Open as\[rq] prompt also saves entries in this file.
 T}@T{
 T}
+_
 T{
 cgi\-dir
 T}@T{
@@ -465,6 +485,7 @@ Search path for local CGI scripts.
 (See \f[B]cha\-localcgi\f[R](5) for details.)
 T}@T{
 T}
+_
 T{
 urimethodmap
 T}@T{
@@ -476,6 +497,7 @@ Search path for urimethodmap files.
 (See \f[B]cha\-urimethodmap\f[R](5) for details.)
 T}@T{
 T}
+_
 T{
 w3m\-cgi\-compat
 T}@T{
@@ -489,6 +511,7 @@ In short, it redirects \f[CR]file:///cgi\-bin/*\f[R] and
 For further details, see \f[B]cha\-localcgi\f[R](5).
 T}@T{
 T}
+_
 T{
 download\-dir
 T}@T{
@@ -499,6 +522,7 @@ T}@T{
 Path to pre\-fill for \[lq]Save to:\[rq] prompts.
 T}@T{
 T}
+_
 T{
 copy\-cmd
 T}@T{
@@ -509,6 +533,7 @@ T}@T{
 Command to use for \[lq]copy to clipboard\[rq] operations.
 T}@T{
 T}
+_
 T{
 paste\-cmd
 T}@T{
@@ -519,6 +544,7 @@ T}@T{
 Command to use for \[lq]read from clipboard\[rq] operations.
 T}@T{
 T}
+_
 T{
 bookmark
 T}@T{
@@ -531,6 +557,7 @@ Path to the bookmark.md file.
 be correctly deduced.)
 T}@T{
 T}
+_
 T{
 history\-file
 T}@T{
@@ -541,6 +568,7 @@ T}@T{
 Path to the history file.
 T}@T{
 T}
+_
 T{
 history\-size
 T}@T{
@@ -551,6 +579,7 @@ T}@T{
 Maximum length of the history file.
 T}@T{
 T}
+_
 T{
 cookie\-file
 T}@T{
@@ -595,6 +624,7 @@ T}@T{
 Whether vi\-style numeric prefixes to commands should be accepted.
 Only applies for keybindings defined in \f[CR][page]\f[R].
 T}
+_
 T{
 use\-mouse
 T}@T{
@@ -647,6 +677,7 @@ T}@T{
 Maximum number of redirections to follow.
 T}@T{
 T}
+_
 T{
 prepend\-scheme
 T}@T{
@@ -660,6 +691,7 @@ first; only if this fails, Chawan will retry the request with
 \f[CR]prepend\-scheme\f[R] set as the scheme.
 T}@T{
 T}
+_
 T{
 prepend\-https
 T}@T{
@@ -672,6 +704,7 @@ When set to false, Chawan will act as if prepend\-scheme were set to
 \[lq]\[lq].
 T}@T{
 T}
+_
 T{
 proxy
 T}@T{
@@ -684,6 +717,7 @@ All proxies supported by cURL may be used.
 Can be overridden by siteconf.
 T}@T{
 T}
+_
 T{
 default\-headers
 T}@T{
@@ -729,6 +763,7 @@ on white, \[lq]ansi\[rq] for ansi colors, \[lq]eight\-bit\[rq] for
 256\-color mode, and \[lq]true\-color\[rq] for true colors.
 T}@T{
 T}
+_
 T{
 format\-mode
 T}@T{
@@ -743,6 +778,7 @@ Accepts the string \[lq]auto\[rq] or an array of specific attributes.
 An empty array (\f[CR][]\f[R]) disables formatting completely.
 T}@T{
 T}
+_
 T{
 no\-format\-mode
 T}@T{
@@ -755,6 +791,7 @@ T}@T{
 Disable specific formatting modes.
 T}@T{
 T}
+_
 T{
 image\-mode
 T}@T{
@@ -772,6 +809,7 @@ This is the default setting, but you must also enable
 \f[CR]buffer.images\f[R] for images to work.
 T}@T{
 T}
+_
 T{
 sixel\-colors
 T}@T{
@@ -784,6 +822,7 @@ Setting a number overrides the number of sixel color registers reported
 by the terminal.
 T}@T{
 T}
+_
 T{
 alt\-screen
 T}@T{
@@ -794,6 +833,7 @@ T}@T{
 Enable/disable the alternative screen.
 T}@T{
 T}
+_
 T{
 highlight\-color
 T}@T{
@@ -805,6 +845,7 @@ Set the highlight color.
 Both hex values and CSS color names are accepted.
 T}@T{
 T}
+_
 T{
 highlight\-marks
 T}@T{
@@ -815,6 +856,7 @@ T}@T{
 Enable/disable highlighting of marks.
 T}@T{
 T}
+_
 T{
 double\-width\-ambiguous
 T}@T{
@@ -827,6 +869,7 @@ category as double\-width characters.
 Useful when e.g.\ ○ occupies two cells.
 T}@T{
 T}
+_
 T{
 minimum\-contrast
 T}@T{
@@ -840,6 +883,7 @@ background and the foreground.
 background, etc).
 T}@T{
 T}
+_
 T{
 force\-clear
 T}@T{
@@ -850,6 +894,7 @@ T}@T{
 Force the screen to be completely cleared every time it is redrawn.
 T}@T{
 T}
+_
 T{
 set\-title
 T}@T{
@@ -861,6 +906,7 @@ Set the terminal emulator\[cq]s window title to that of the current
 page.
 T}@T{
 T}
+_
 T{
 default\-background\-color
 T}@T{
@@ -872,6 +918,7 @@ Overrides the assumed background color of the terminal.
 \[lq]auto\[rq] leaves background color detection to Chawan.
 T}@T{
 T}
+_
 T{
 default\-foreground\-color
 T}@T{
@@ -883,6 +930,7 @@ Sets the assumed foreground color of the terminal.
 \[lq]auto\[rq] leaves foreground color detection to Chawan.
 T}@T{
 T}
+_
 T{
 query\-da1
 T}@T{
@@ -896,6 +944,7 @@ Do not alter this value unless Chawan told you so; the output will look
 awful.
 T}@T{
 T}
+_
 T{
 columns, lines, pixels\-per\-column, pixels\-per\-line
 T}@T{
@@ -909,6 +958,7 @@ automatically.
 (For example, these values are used in dump mode.)
 T}@T{
 T}
+_
 T{
 force\-columns, force\-lines, force\-pixels\-per\-column,
 force\-pixels\-per\-line
@@ -1003,6 +1053,7 @@ Note: regexes are handled according to the match mode regex handling
 rules.
 T}@T{
 T}
+_
 T{
 substitute\-url
 T}@T{
@@ -1097,6 +1148,7 @@ Note: regexes are handled according to the match mode regex handling
 rules.
 T}@T{
 T}
+_
 T{
 host
 T}@T{
@@ -1111,6 +1163,7 @@ Note: regexes are handled according to the match mode regex handling
 rules.
 T}@T{
 T}
+_
 T{
 rewrite\-url
 T}@T{
@@ -1123,6 +1176,7 @@ If a new URL is returned, or the URL object is modified in any way,
 Chawan will transparently redirect the user to this new URL.
 T}@T{
 T}
+_
 T{
 cookie
 T}@T{
@@ -1134,6 +1188,7 @@ Whether loading (with \[lq]save\[rq], also saving) cookies should be
 allowed for this URL.
 T}@T{
 T}
+_
 T{
 share\-cookie\-jar
 T}@T{
@@ -1145,6 +1200,7 @@ Cookie jar to use for this domain.
 Useful for e.g.\ sharing cookies with subdomains.
 T}@T{
 T}
+_
 T{
 referer\-from
 T}@T{
@@ -1159,6 +1215,7 @@ and referer\-from is true, b.com is sent \[lq]a.com\[rq] as the Referer
 header.
 T}@T{
 T}
+_
 T{
 scripting
 T}@T{
@@ -1170,6 +1227,7 @@ Enable/disable JavaScript execution on this site.
 See \f[CR]buffer.scripting\f[R] for details.
 T}@T{
 T}
+_
 T{
 styling
 T}@T{
@@ -1180,6 +1238,7 @@ T}@T{
 Enable/disable author styles (CSS) on this site.
 T}@T{
 T}
+_
 T{
 images
 T}@T{
@@ -1190,6 +1249,7 @@ T}@T{
 Enable/disable image display on this site.
 T}@T{
 T}
+_
 T{
 document\-charset
 T}@T{
@@ -1200,6 +1260,7 @@ T}@T{
 Specify the default encoding for this site.
 T}@T{
 T}
+_
 T{
 stylesheet
 T}@T{
@@ -1214,6 +1275,7 @@ stylesheet.
 Please use \f[CR]user\-style\f[R] instead.
 T}@T{
 T}
+_
 T{
 proxy
 T}@T{
@@ -1224,6 +1286,7 @@ T}@T{
 Specify a proxy for network requests fetching contents of this buffer.
 T}@T{
 T}
+_
 T{
 default\-headers
 T}@T{
@@ -1235,6 +1298,7 @@ Specify a list of default headers for HTTP(S) network requests to this
 buffer.
 T}@T{
 T}
+_
 T{
 insecure\-ssl\-no\-verify
 T}@T{
@@ -1249,6 +1313,7 @@ Please do not use this unless you are absolutely sure you know what you
 are doing.
 T}@T{
 T}
+_
 T{
 autofocus
 T}@T{
@@ -1261,6 +1326,7 @@ focused on automatically after the buffer is loaded.
 If scripting is enabled, this also allows scripts to focus on elements.
 T}@T{
 T}
+_
 T{
 meta\-refresh
 T}@T{
@@ -1274,6 +1340,7 @@ respected.
 accepts all of them, \[lq]ask\[rq] brings up a pop\-up menu.
 T}@T{
 T}
+_
 T{
 history
 T}@T{
@@ -1285,6 +1352,7 @@ Whether or not browsing history should be saved to the disk for this
 URL.
 T}@T{
 T}
+_
 T{
 mark\-links
 T}@T{
@@ -1295,6 +1363,7 @@ T}@T{
 Add numeric markers before links.
 T}@T{
 T}
+_
 T{
 user\-style
 T}@T{
@@ -1378,6 +1447,7 @@ T}@T{
 Exit the browser.
 T}@T{
 T}
+_
 T{
 C\-z
 T}@T{
@@ -1389,6 +1459,7 @@ So if you are downloading something, that will be delayed until you
 restart the process.
 T}@T{
 T}
+_
 T{
 C\-l
 T}@T{
@@ -1397,6 +1468,7 @@ T}@T{
 Open the current address in the URL bar.
 T}@T{
 T}
+_
 T{
 C\-k
 T}@T{
@@ -1406,6 +1478,7 @@ Open the URL bar with an arbitrary search engine.
 At the moment, this is Google Search, but this may change in the future.
 T}@T{
 T}
+_
 T{
 M\-u
 T}@T{
@@ -1414,6 +1487,7 @@ T}@T{
 Duplicate the current buffer by loading its source to a new buffer.
 T}@T{
 T}
+_
 T{
 U
 T}@T{
@@ -1423,6 +1497,7 @@ Open a new buffer with the current buffer\[cq]s URL, replacing the
 current buffer.
 T}@T{
 T}
+_
 T{
 C\-g
 T}@T{
@@ -1431,6 +1506,7 @@ T}@T{
 Display information about the current line on the status line.
 T}@T{
 T}
+_
 T{
 \[rs]
 T}@T{
@@ -1440,6 +1516,7 @@ If viewing an HTML buffer, open a new buffer with its source.
 Otherwise, open the current buffer\[cq]s contents as HTML.
 T}@T{
 T}
+_
 T{
 D
 T}@T{
@@ -1449,6 +1526,7 @@ Discard the current buffer, and move back to the previous/next buffer
 depending on what the previously viewed buffer was.
 T}@T{
 T}
+_
 T{
 d,, d.
 T}@T{
@@ -1459,6 +1537,7 @@ Discard the current buffer, and move back to the previous/next buffer,
 or open the link under the cursor.
 T}@T{
 T}
+_
 T{
 M\-d
 T}@T{
@@ -1467,6 +1546,7 @@ T}@T{
 Discard all child buffers of the current buffer.
 T}@T{
 T}
+_
 T{
 \&., ,, M\-,, M\-., M\-/
 T}@T{
@@ -1484,6 +1564,7 @@ current buffer was opened from, even if e.g.\ the user returns and opens
 another page \[lq]in between\[rq].
 T}@T{
 T}
+_
 T{
 M\-c
 T}@T{
@@ -1494,6 +1575,7 @@ Note that this interacts with the pager, not the website being
 displayed.
 T}@T{
 T}
+_
 T{
 None
 T}@T{
@@ -1502,6 +1584,7 @@ T}@T{
 Search for a string in the current buffer, forwards or backwards.
 T}@T{
 T}
+_
 T{
 /, ?
 T}@T{
@@ -1511,6 +1594,7 @@ Incremental\-search for a string, highlighting the first result,
 forwards or backwards.
 T}@T{
 T}
+_
 T{
 n, N
 T}@T{
@@ -1519,6 +1603,7 @@ T}@T{
 Jump to the nth (or if unspecified, first) next/previous search result.
 T}@T{
 T}
+_
 T{
 c
 T}@T{
@@ -1527,6 +1612,7 @@ T}@T{
 Display a message of the current buffer\[cq]s URL on the status line.
 T}@T{
 T}
+_
 T{
 u
 T}@T{
@@ -1538,6 +1624,7 @@ Multiple calls allow cycling through the two.
 (i.e.\ by default, press u once \-> title, press again \-> URL)
 T}@T{
 T}
+_
 T{
 su
 T}@T{
@@ -1547,6 +1634,7 @@ Show the last alert inside the line editor.
 You can also view previous ones using C\-p or C\-n.
 T}@T{
 T}
+_
 T{
 M\-y
 T}@T{
@@ -1555,6 +1643,7 @@ T}@T{
 Copy the current buffer\[cq]s URL to the system clipboard.
 T}@T{
 T}
+_
 T{
 yu
 T}@T{
@@ -1563,6 +1652,7 @@ T}@T{
 Copy the link under the cursor to the system clipboard.
 T}@T{
 T}
+_
 T{
 yI
 T}@T{
@@ -1571,6 +1661,7 @@ T}@T{
 Copy the URL of the image under the cursor to the system clipboard.
 T}@T{
 T}
+_
 T{
 M\-p
 T}@T{
@@ -1579,6 +1670,7 @@ T}@T{
 Go to the URL currently on the clipboard.
 T}@T{
 T}
+_
 T{
 M\-b
 T}@T{
@@ -1587,6 +1679,7 @@ T}@T{
 Open the bookmark file.
 T}@T{
 T}
+_
 T{
 M\-a
 T}@T{
@@ -1624,6 +1717,7 @@ Move the cursor upwards/downwards by n lines, or if n is unspecified, by
 1.
 T}@T{
 T}
+_
 T{
 h, l
 T}@T{
@@ -1633,6 +1727,7 @@ Move the cursor to the left/right by n cells, or if n is unspecified, by
 1.
 T}@T{
 T}
+_
 T{
 0
 T}@T{
@@ -1641,6 +1736,7 @@ T}@T{
 Move the cursor to the first cell of the line.
 T}@T{
 T}
+_
 T{
 \[ha]
 T}@T{
@@ -1649,6 +1745,7 @@ T}@T{
 Move the cursor to the first non\-blank character of the line.
 T}@T{
 T}
+_
 T{
 $
 T}@T{
@@ -1657,6 +1754,7 @@ T}@T{
 Move the cursor to the last cell of the line.
 T}@T{
 T}
+_
 T{
 w, W
 T}@T{
@@ -1667,6 +1765,7 @@ T}@T{
 Move the cursor to the beginning of the next word.
 T}@T{
 T}
+_
 T{
 None
 T}@T{
@@ -1677,6 +1776,7 @@ T}@T{
 Move the cursor to the end of the previous word.
 T}@T{
 T}
+_
 T{
 e, E
 T}@T{
@@ -1688,6 +1788,7 @@ Move the cursor to the end of the current word, or if already there, to
 the end of the next word.
 T}@T{
 T}
+_
 T{
 b, B
 T}@T{
@@ -1699,6 +1800,7 @@ Move the cursor to the beginning of the current word, or if already
 there, to the end of the previous word.
 T}@T{
 T}
+_
 T{
 [, ]
 T}@T{
@@ -1709,6 +1811,7 @@ Move the cursor to the end/beginning of the previous/next clickable
 element (e.g.\ link, input field, etc).
 T}@T{
 T}
+_
 T{
 {, }
 T}@T{
@@ -1718,6 +1821,7 @@ T}@T{
 Move the cursor to the end/beginning of the nth previous/next paragraph.
 T}@T{
 T}
+_
 T{
 None
 T}@T{
@@ -1727,6 +1831,7 @@ Move the cursor to the nth link of the document, counting backwards from
 the document\[cq]s last line.
 T}@T{
 T}
+_
 T{
 None
 T}@T{
@@ -1735,6 +1840,7 @@ T}@T{
 Move the cursor to the nth link of the document.
 T}@T{
 T}
+_
 T{
 C\-b, C\-f, zH, zL
 T}@T{
@@ -1745,6 +1851,7 @@ Scroll up/down/left/right by n pages, or if n is unspecified, by one
 page.
 T}@T{
 T}
+_
 T{
 C\-u, C\-d
 T}@T{
@@ -1755,6 +1862,7 @@ Scroll up/down/left/right by n half pages, or if n is unspecified, by
 one page.
 T}@T{
 T}
+_
 T{
 K/C\-y, J/C\-e, zh, zl
 T}@T{
@@ -1765,6 +1873,7 @@ Scroll up/down/left/right by n lines, or if n is unspecified, by one
 line.
 T}@T{
 T}
+_
 T{
 Enter/Return
 T}@T{
@@ -1773,6 +1882,7 @@ T}@T{
 Click the HTML element currently under the cursor.
 T}@T{
 T}
+_
 T{
 I
 T}@T{
@@ -1781,6 +1891,7 @@ T}@T{
 View the image currently under the cursor in an external viewer.
 T}@T{
 T}
+_
 T{
 R
 T}@T{
@@ -1790,6 +1901,7 @@ Reshape the current buffer (=render the current page anew.)
 Useful if the layout is not updating even though it should have.
 T}@T{
 T}
+_
 T{
 r
 T}@T{
@@ -1799,6 +1911,7 @@ Redraw screen contents.
 Useful if something messed up the display.
 T}@T{
 T}
+_
 T{
 None (see gotoLineOrStart/End instead)
 T}@T{
@@ -1808,6 +1921,7 @@ T}@T{
 Move to the beginning/end in the buffer.
 T}@T{
 T}
+_
 T{
 H
 T}@T{
@@ -1817,6 +1931,7 @@ Move to the first line on the screen.
 (Equivalent to H in vi.)
 T}@T{
 T}
+_
 T{
 M
 T}@T{
@@ -1826,6 +1941,7 @@ Move to the line in the middle of the screen.
 (Equivalent to M in vi.)
 T}@T{
 T}
+_
 T{
 L
 T}@T{
@@ -1835,6 +1951,7 @@ Move to the last line on the screen.
 (Equivalent to L in vi.)
 T}@T{
 T}
+_
 T{
 zt, z Return, zz, z., zb, z\-
 T}@T{
@@ -1855,6 +1972,7 @@ The \-\f[CR]Begin\f[R] variants also move the cursor to the line\[cq]s
 first non\-blank character, as the variants originating from vi do.
 T}@T{
 T}
+_
 T{
 z+
 T}@T{
@@ -1865,6 +1983,7 @@ page.
 Otherwise, go to the previous screen\[cq]s last line and raise the page.
 T}@T{
 T}
+_
 T{
 z\[ha]
 T}@T{
@@ -1875,6 +1994,7 @@ page.
 Otherwise, go to the previous screen\[cq]s last line and raise the page.
 T}@T{
 T}
+_
 T{
 g0, gc, g$
 T}@T{
@@ -1885,6 +2005,7 @@ T}@T{
 Move to the first/middle/last column on the screen.
 T}@T{
 T}
+_
 T{
 None
 T}@T{
@@ -1894,6 +2015,7 @@ Center screen around the current column.
 (w3m \f[CR]Z\f[R].)
 T}@T{
 T}
+_
 T{
 gg, G
 T}@T{
@@ -1904,6 +2026,7 @@ If n is specified, jump to line n.\ Otherwise, jump to the start/end of
 the page.
 T}@T{
 T}
+_
 T{
 T}@T{
 , None
@@ -1914,6 +2037,7 @@ T}@T{
 If n is specified, jump to column n of the current line.
 Otherwise, jump to the first/last column.
 T}
+_
 T{
 m
 T}@T{
@@ -1923,6 +2047,7 @@ Wait for a character \f[CR]x\f[R] and then set a mark with the ID
 \f[CR]x\f[R].
 T}@T{
 T}
+_
 T{
 \[ga], \[cq]
 T}@T{
@@ -1934,6 +2059,7 @@ Wait for a character \f[CR]x\f[R] and then jump to the mark with the ID
 the Y position.
 T}@T{
 T}
+_
 T{
 :
 T}@T{
@@ -1942,6 +2068,7 @@ T}@T{
 Convert URL\-like strings to anchors on the current page.
 T}@T{
 T}
+_
 T{
 s Return
 T}@T{
@@ -1950,6 +2077,7 @@ T}@T{
 Save resource from the URL pointed to by the cursor to the disk.
 T}@T{
 T}
+_
 T{
 sS
 T}@T{
@@ -1958,6 +2086,7 @@ T}@T{
 Save the source of the current buffer to the disk.
 T}@T{
 T}
+_
 T{
 sI
 T}@T{
@@ -1989,6 +2118,7 @@ T}@T{
 Submit the line.
 T}@T{
 T}
+_
 T{
 C\-c
 T}@T{
@@ -1997,6 +2127,7 @@ T}@T{
 Cancel the current operation.
 T}@T{
 T}
+_
 T{
 C\-h, C\-d
 T}@T{
@@ -2005,6 +2136,7 @@ T}@T{
 Delete character before (backspace)/after (delete) the cursor.
 T}@T{
 T}
+_
 T{
 C\-u, C\-k
 T}@T{
@@ -2013,6 +2145,7 @@ T}@T{
 Delete text before (clear)/after (kill) the cursor.
 T}@T{
 T}
+_
 T{
 C\-w, M\-d
 T}@T{
@@ -2021,6 +2154,7 @@ T}@T{
 Delete word before (clear)/after (kill) the cursor.
 T}@T{
 T}
+_
 T{
 C\-b, C\-f
 T}@T{
@@ -2029,6 +2163,7 @@ T}@T{
 Move cursor backward/forward by one character.
 T}@T{
 T}
+_
 T{
 M\-b, M\-f
 T}@T{
@@ -2037,6 +2172,7 @@ T}@T{
 Move cursor to the previous/next word by one character
 T}@T{
 T}
+_
 T{
 C\-a, C\-e
 T}@T{
@@ -2045,6 +2181,7 @@ T}@T{
 Move cursor to the beginning/end of the line.
 T}@T{
 T}
+_
 T{
 C\-v
 T}@T{
@@ -2053,6 +2190,7 @@ T}@T{
 Ignore keybindings for next character.
 T}@T{
 T}
+_
 T{
 C\-p, C\-n
 T}@T{
diff --git a/doc/cha-protocols.7 b/doc/cha-protocols.7
index 048c1d4a..6efa1d29 100644
--- a/doc/cha-protocols.7
+++ b/doc/cha-protocols.7
@@ -3,11 +3,11 @@
 .TH "cha\-protocols" "7" "" "" "Protocol support in Chawan"
 .SH Protocols
 Chawan supports downloading resources from various protocols: HTTP, FTP,
-Gopher, Gemini, and Finger.
+SFTP, Gopher, Gemini, Spartan, and Finger.
 Details on these protocols, and information on how users can add support
 to their preferred protocols is outlined in this document.
 .PP
-In general, you can find network adapters in the
+You can find network adapters in the source distribution\[cq]s
 \f[CR]adapter/protocol\f[R] directory.
 For protocol\-specific file formats (like gemtext or gopher directories)
 you will also find an appropriate HTML converter in
@@ -19,10 +19,13 @@ use passed userinfo data, and returns all headers and response body it
 receives without exception.
 .PP
 Deflate decompression with gzip and zlib headers is supported.
-(Content\-Type: gzip, deflate.)
+(Accept\-Encoding: gzip, deflate.)
 This is based on a modified version of the public domain tinfl.h
 decompressor by Rich Geldreich.
 .PP
+Brotli decompression (Accept\-Encoding: br) is supported using the
+decoder provided by the reference implementation.
+.PP
 The \f[CR]bonus\f[R] directory contains two alternative HTTP clients:
 .IP \[bu] 2
 curlhttp; this is the old HTTP client based on libcurl.
diff --git a/doc/cha-terminal.7 b/doc/cha-terminal.7
new file mode 100644
index 00000000..16c7da16
--- /dev/null
+++ b/doc/cha-terminal.7
@@ -0,0 +1,76 @@
+.\" Automatically generated by Pandoc 3.6.4
+.\"
+.TH "cha\-terminal" "7" "" "" "Chawan terminal compatibility"
+.SH Chawan terminal compatibility
+Chawan does not use termcap, terminfo, or ncurses; it relies solely on
+built\-in terminal handling routines, mostly inspired by notcurses.
+.SS XTerm compatibility
+In general, Chawan assumes an XTerm\-compatible environment where XTerm
+means the current XTerm version as developed and maintained by Thomas E.
+Dickey.
+This means that Chawan is compatible with any given terminal if:
+.IP \[bu] 2
+the terminal is actually compatible with XTerm, OR
+.IP \[bu] 2
+the terminal isn\[cq]t compatible with XTerm, but reports its
+capabilities via terminal queries correctly, OR
+.IP \[bu] 2
+the terminal isn\[cq]t compatible with XTerm, but its \f[CR]TERM\f[R]
+value is hardcoded in Chawan.
+.PP
+Terminals pretending to be XTerm (\f[CR]TERM=xterm\f[R]) which are not
+actually XTerm might malfunction.
+.PP
+(In practice, I have tested dozens of terminal emulators and haven\[cq]t
+encountered any major issues; in all likelihood, yours will work too.
+Still, if it doesn\[cq]t, please \c
+.UR https://tickets.sr.ht/~bptato/chawan.
+open a ticket
+.UE \c
+.SS Queries
+Queries are preferred to hardcoded terminal descriptions because they
+are forward\-compatible.
+On startup, Chawan queries:
+.IP \[bu] 2
+Whether the terminal has true color, with XTGETTCAP rgb.
+.IP \[bu] 2
+The default background, foreground, and 16 ANSI(\-ish) colors with
+\f[CR]OSC 1 0 ; ? ST\f[R], \f[CR]OSC 1 1 ; ? ST\f[R], and
+\f[CR]OSC 4 ; {0..15} ; ? ST\f[R].
+.IP \[bu] 2
+Whether the terminal can use the Kitty image protocol, by sending an
+incorrectly encoded image and listening for an error.
+.IP \[bu] 2
+The number of Sixel color registers (\f[CR]CSI ? 1 ; 1 ; 0 $\f[R]).
+.IP \[bu] 2
+The maximum Sixel image dimensions (\f[CR]CSI ? 2 ; 1 ; 0 $\f[R]).
+.IP \[bu] 2
+Text area, cell, and window size using \f[CR]CSI 1 4 t\f[R],
+\f[CR]CSI 1 6 t\f[R], \f[CR]CSI 1 8 t\f[R].
+(Cell size, \f[CR]1 6\f[R], beats the other two as it is more reliable.)
+.IP \[bu] 2
+Primary device attributes.
+.PP
+Primary device attributes (henceforth DA1) are queried last, and most
+terminals respond to this, so Chawan should never hang on startup.
+If it \f[I]isn\[cq]t\f[R] implemented (as on the FreeBSD console), the
+user can hit any key to break out of the state machine and set
+\f[CR]display.query\-da1 = false\f[R] as instructed by the browser.
+On known terminals with this issue which set \f[CR]TERM\f[R] correctly,
+DA1 is omitted.
+.PP
+Some terminals bleed the APC sequence used to recognize kitty image
+support.
+If the terminal also supports the alternate screen (ti/smcup), the
+sequence may end up inside the shell prompt.
+On known terminals with this issue which set \f[CR]TERM\f[R] correctly,
+the kitty query is omitted.
+.SS Ancient terminals
+Pre\-ECMA\-48 terminals are generally not expected to work.
+.PP
+There is some degree of ADM\-3A support, tested in Kragen Javier
+Sitaker\[cq]s \f[CR]admu\f[R] emulator.
+However, a real ADM\-3A would likely be confused by non\-ASCII
+characters.
+.PP
+Patches for other terminals (hardware or software alike) are welcome.
diff --git a/doc/cha.1 b/doc/cha.1
index 472ef2ae..707e9659 100644
--- a/doc/cha.1
+++ b/doc/cha.1
@@ -142,4 +142,4 @@ Configuration options are described in \fBcha-config\fR(5).
 .br
 \fBcha-localcgi\fR(5), \fBcha-urimethodmap\fR(5), \fBcha-protocols\fR(7),
 .br
-\fBcha-image\fR(7), \fBcha-css\fR(7), \fBcha-troubleshooting\fR(7)
+\fBcha-image\fR(7), \fBcha-css\fR(7), \fBcha-troubleshooting\fR(7), \fBcha-terminal\fR(7)
diff --git a/doc/config.md b/doc/config.md
index 61a38ac1..5012910c 100644
--- a/doc/config.md
+++ b/doc/config.md
@@ -369,7 +369,7 @@ the line number.</td>
 <tr>
 <td>mime-types</td>
 <td>array of paths</td>
-<td>{see mime.types docs</td>
+<td>{see mime.types docs}</td>
 <td>Search path for <!-- MANOFF -->[mime.types](mime.types.md) files.<!-- MANON -->
 <!-- MANON mime.types files. (See **cha-mime.types**(5) for details.) MANOFF -->
 </td>
diff --git a/doc/protocols.md b/doc/protocols.md
index c195b0a9..3cfdaf98 100644
--- a/doc/protocols.md
+++ b/doc/protocols.md
@@ -5,13 +5,14 @@ MANOFF -->
 # Protocols
 
 Chawan supports downloading resources from various protocols: HTTP, FTP,
-Gopher, Gemini, and Finger. Details on these protocols, and information
-on how users can add support to their preferred protocols is outlined in
-this document.
-
-In general, you can find network adapters in the `adapter/protocol` directory.
-For protocol-specific file formats (like gemtext or gopher directories) you will
-also find an appropriate HTML converter in `adapter/format`.
+SFTP, Gopher, Gemini, Spartan, and Finger.  Details on these protocols,
+and information on how users can add support to their preferred
+protocols is outlined in this document.
+
+You can find network adapters in the source distribution's
+`adapter/protocol` directory.  For protocol-specific file formats (like
+gemtext or gopher directories) you will also find an appropriate HTML
+converter in `adapter/format`.
 
 <!-- MANOFF -->
 **Table of contents**
diff --git a/doc/terminals.md b/doc/terminal.md
index faaa8534..1ad28611 100644
--- a/doc/terminals.md
+++ b/doc/terminal.md
@@ -1,4 +1,8 @@
-# Terminals and Chawan
+<!-- MANON
+% cha-terminal(7) | Chawan terminal compatibility
+MANOFF -->
+
+# Chawan terminal compatibility
 
 Chawan does not use termcap, terminfo, or ncurses; it relies solely
 on built-in terminal handling routines, mostly inspired by notcurses.
@@ -19,6 +23,11 @@ if:
 Terminals pretending to be XTerm (`TERM=xterm`) which are not actually
 XTerm might malfunction.
 
+(In practice, I have tested dozens of terminal emulators and haven't
+encountered any major issues; in all likelihood, yours will work too.
+Still, if it doesn't, please
+[open a ticket](https://tickets.sr.ht/~bptato/chawan.)
+
 ## Queries
 
 Queries are preferred to hardcoded terminal descriptions because they