diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/cha-api.5 | 6 | ||||
-rw-r--r-- | doc/cha-config.5 | 540 | ||||
-rw-r--r-- | doc/cha-image.5 | 115 | ||||
-rw-r--r-- | doc/config.md | 58 |
4 files changed, 496 insertions, 223 deletions
diff --git a/doc/cha-api.5 b/doc/cha-api.5 index 45b37d61..fd5dee6b 100644 --- a/doc/cha-api.5 +++ b/doc/cha-api.5 @@ -263,6 +263,12 @@ Multiple calls allow cycling through the two. 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{ Ask the user for confirmation. diff --git a/doc/cha-config.5 b/doc/cha-config.5 index dd086807..c9b797aa 100644 --- a/doc/cha-config.5 +++ b/doc/cha-config.5 @@ -555,6 +555,17 @@ images. T}@T{ T} T{ +sixel\-colors +T}@T{ +\[lq]auto\[rq] / 2..65535 +T}@T{ +Only applies when \f[CR]display.image\-mode=\[dq]sixel\[dq]\f[R]. +Setting a number overrides the number of sixel color registers reported +by the terminal, while \[lq]auto\[rq] leaves color detection to Chawan. +Defaults to \[lq]auto\[rq]. +T}@T{ +T} +T{ alt\-screen T}@T{ \[lq]auto\[rq] / boolean @@ -1022,14 +1033,16 @@ Examples: \[aq]C\-M\-j\[aq] = \[aq]cmd.pager.load\[aq] \f[I]# go to the first line of the page when g is pressed twice without a preceding\f[R] \f[I]# number, or to the line when a preceding number is given.\f[R] -\[aq]gg\[aq] = \[aq]cmd.pager.gotoLineOrStart\[aq] +\[aq]gg\[aq] = \[aq]cmd.buffer.gotoLineOrStart\[aq] .EE -.SS Browser actions +.SS Pager actions .PP .TS tab(@); -lw(21.5n) lw(43.1n) lw(5.4n). +lw(32.1n) lw(11.7n) lw(23.3n) lw(2.9n). T{ +Default key +T}@T{ Name T}@T{ Function @@ -1037,12 +1050,16 @@ T}@T{ T} _ T{ +q +T}@T{ \f[CR]cmd.pager.quit\f[R] T}@T{ Exit the browser. T}@T{ T} T{ +C\-z +T}@T{ \f[CR]cmd.pager.suspend\f[R] T}@T{ Temporarily suspend the browser Note: this also suspends e.g.\ buffer @@ -1051,8 +1068,199 @@ So if you are downloading something, that will be delayed until you restart the process. T}@T{ T} +T{ +C\-l +T}@T{ +\f[CR]cmd.pager.load\f[R] +T}@T{ +Open the current address in the URL bar. +T}@T{ +T} +T{ +C\-k +T}@T{ +\f[CR]cmd.pager.webSearch\f[R] +T}@T{ +Open the URL bar with an arbitrary search engine. +At the moment, this is DuckDuckGo Lite, but this may change in the +future. +T}@T{ +T} +T{ +M\-u +T}@T{ +\f[CR]cmd.pager.dupeBuffer\f[R] +T}@T{ +Duplicate the current buffer by loading its source to a new buffer. +T}@T{ +T} +T{ +U +T}@T{ +\f[CR]cmd.pager.reloadBuffer\f[R] +T}@T{ +Open a new buffer with the current buffer\[cq]s URL, replacing the +current buffer. +T}@T{ +T} +T{ +C\-g +T}@T{ +\f[CR]cmd.pager.lineInfo\f[R] +T}@T{ +Display information about the current line on the status line. +T}@T{ +T} +T{ +\[rs] +T}@T{ +\f[CR]cmd.pager.toggleSource\f[R] +T}@T{ +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{ +\f[CR]cmd.pager.discardBuffer\f[R] +T}@T{ +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{ +\f[CR]cmd.pager.discardBufferPrev\f[R], +\f[CR]cmd.pager.discardBufferNext\f[R] +T}@T{ +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{ +\f[CR]cmd.pager.discardTree\f[R] +T}@T{ +Discard all child buffers of the current buffer. +T}@T{ +T} +T{ +\&., ,, M\-,, M\-., M\-/ +T}@T{ +\f[CR]cmd.pager.nextBuffer\f[R], \f[CR]cmd.pager.prevBuffer\f[R], +\f[CR]cmd.pager.prevSiblingBuffer\f[R], +\f[CR]cmd.pager.nextSiblingBufer\f[R], \f[CR]cmd.pager.parentBuffer\f[R] +T}@T{ +Traverse the buffer tree. +\f[CR]nextBuffer\f[R] and \f[CR]prevBuffer\f[R] are the most intuitive, +traversing the tree as if it were a linked list. +\f[CR]prevSiblingBuffer\f[R] and \f[CR]nextSiblingBuffer\f[R] cycle +through the buffers opened from the same buffer. +Finally, \f[CR]parentBuffer\f[R] always returns to the buffer the +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{ +\f[CR]cmd.pager.enterCommand\f[R] +T}@T{ +Directly enter a JavaScript command. +Note that this interacts with the pager, not the website being +displayed. +T}@T{ +T} +T{ +None +T}@T{ +\f[CR]cmd.pager.searchForward\f[R], \f[CR]cmd.pager.searchBackward\f[R] +T}@T{ +Search for a string in the current buffer, forwards or backwards. +T}@T{ +T} +T{ +/, ? +T}@T{ +\f[CR]cmd.pager.isearchForward\f[R], \f[CR]cmd.pager.searchBackward\f[R] +T}@T{ +Incremental\-search for a string, highlighting the first result, +forwards or backwards. +T}@T{ +T} +T{ +n, N +T}@T{ +\f[CR]cmd.pager.searchNext\f[R], \f[CR]cmd.pager.searchPrev\f[R] +T}@T{ +Jump to the nth (or if unspecified, first) next/previous search result. +T}@T{ +T} +T{ +c +T}@T{ +\f[CR]cmd.pager.peek\f[R] +T}@T{ +Display a message of the current buffer\[cq]s URL on the status line. +T}@T{ +T} +T{ +u +T}@T{ +\f[CR]cmd.pager.peekCursor\f[R] +T}@T{ +Display a message of the URL or title under the cursor on the status +line. +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{ +\f[CR]cmd.pager.showFullAlert\f[R] +T}@T{ +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{ +\f[CR]cmd.pager.copyURL\f[R] +T}@T{ +Copy the current buffer\[cq]s URL to the system clipboard. +T}@T{ +T} +T{ +yu +T}@T{ +\f[CR]cmd.pager.copyCursorLink\f[R] +T}@T{ +Copy the link under the cursor to the system clipboard. +T}@T{ +T} +T{ +yI +T}@T{ +\f[CR]cmd.pager.copyCursorImage\f[R] +T}@T{ +Copy the URL of the image under the cursor to the system clipboard. +T}@T{ +T} +T{ +M\-p +T}@T{ +\f[CR]cmd.pager.gotoClipboardURL\f[R] +T}@T{ +Go to the URL currently on the clipboard. +T}@T{ +T} .TE -.SS Pager actions +.SS Buffer actions Note: \f[CR]n\f[R] in the following text refers to a number preceding the action. e.g. @@ -1061,8 +1269,10 @@ If no preceding number is input, then it is left unspecified. .PP .TS tab(@); -lw(21.5n) lw(43.1n) lw(5.4n). +lw(32.1n) lw(11.7n) lw(23.3n) lw(2.9n). T{ +Default key +T}@T{ Name T}@T{ Function @@ -1070,244 +1280,223 @@ T}@T{ T} _ T{ -\f[CR]cmd.pager.cursorUp\f[R], \f[CR]cmd.pager.cursorDown\f[R] +j, k +T}@T{ +\f[CR]cmd.buffer.cursorUp\f[R], \f[CR]cmd.buffer.cursorDown\f[R] T}@T{ Move the cursor upwards/downwards by n lines, or if n is unspecified, by 1. T}@T{ T} T{ -\f[CR]cmd.pager.cursorLeft\f[R], \f[CR]cmd.pager.cursorRight\f[R] +h, l +T}@T{ +\f[CR]cmd.buffer.cursorLeft\f[R], \f[CR]cmd.buffer.cursorRight\f[R] T}@T{ Move the cursor to the left/right by n cells, or if n is unspecified, by 1. T}@T{ T} T{ -\f[CR]cmd.pager.cursorLineBegin\f[R] +0 +T}@T{ +\f[CR]cmd.buffer.cursorLineBegin\f[R] T}@T{ Move the cursor to the first cell of the line. T}@T{ T} T{ -\f[CR]cmd.pager.cursorLineTextStart\f[R] +\[ha] +T}@T{ +\f[CR]cmd.buffer.cursorLineTextStart\f[R] T}@T{ Move the cursor to the first non\-blank character of the line. T}@T{ T} T{ -\f[CR]cmd.pager.cursorLineEnd\f[R] +$ +T}@T{ +\f[CR]cmd.buffer.cursorLineEnd\f[R] T}@T{ Move the cursor to the last cell of the line. T}@T{ T} T{ -\f[CR]cmd.pager.cursorNextWord\f[R], -\f[CR]cmd.pager.cursorNextViWord\f[R], -\f[CR]cmd.pager.cursorNextBigWord\f[R] +w, W +T}@T{ +\f[CR]cmd.buffer.cursorNextWord\f[R], +\f[CR]cmd.buffer.cursorNextViWord\f[R], +\f[CR]cmd.buffer.cursorNextBigWord\f[R] T}@T{ Move the cursor to the beginning of the next word. T}@T{ T} T{ -\f[CR]cmd.pager.cursorPrevWord\f[R], -\f[CR]cmd.pager.cursorPrevViWord\f[R], -\f[CR]cmd.pager.cursorPrevBigWord\f[R] +None +T}@T{ +\f[CR]cmd.buffer.cursorPrevWord\f[R], +\f[CR]cmd.buffer.cursorPrevViWord\f[R], +\f[CR]cmd.buffer.cursorPrevBigWord\f[R] T}@T{ Move the cursor to the end of the previous word. T}@T{ T} T{ -\f[CR]cmd.pager.cursorWordEnd\f[R], -\f[CR]cmd.pager.cursorViWordEnd\f[R], -\f[CR]cmd.pager.cursorBigWordEnd\f[R] +e, E +T}@T{ +\f[CR]cmd.buffer.cursorWordEnd\f[R], +\f[CR]cmd.buffer.cursorViWordEnd\f[R], +\f[CR]cmd.buffer.cursorBigWordEnd\f[R] T}@T{ 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]cmd.pager.cursorWordBegin\f[R], -\f[CR]cmd.pager.cursorViWordBegin\f[R], -\f[CR]cmd.pager.cursorBigWordBegin\f[R] +b, B +T}@T{ +\f[CR]cmd.buffer.cursorWordBegin\f[R], +\f[CR]cmd.buffer.cursorViWordBegin\f[R], +\f[CR]cmd.buffer.cursorBigWordBegin\f[R] T}@T{ 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]cmd.pager.cursorPrevLink\f[R], \f[CR]cmd.pager.cursorNextLink\f[R] +[, ] +T}@T{ +\f[CR]cmd.buffer.cursorPrevLink\f[R], +\f[CR]cmd.buffer.cursorNextLink\f[R] T}@T{ Move the cursor to the end/beginning of the previous/next clickable element (e.g.\ link, input field, etc). T}@T{ T} T{ -\f[CR]cmd.pager.cursorPrevParagraph\f[R], -\f[CR]cmd.pager.cursorNextParagraph\f[R] +{, } +T}@T{ +\f[CR]cmd.buffer.cursorPrevParagraph\f[R], +\f[CR]cmd.buffer.cursorNextParagraph\f[R] T}@T{ Move the cursor to the end/beginning of the nth previous/next paragraph. T}@T{ T} T{ -\f[CR]cmd.pager.cursorRevNthLink\f[R] +None +T}@T{ +\f[CR]cmd.buffer.cursorRevNthLink\f[R] T}@T{ 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]cmd.pager.cursorNthLink\f[R] +None +T}@T{ +\f[CR]cmd.buffer.cursorNthLink\f[R] T}@T{ Move the cursor to the nth link of the document. T}@T{ T} T{ -\f[CR]cmd.pager.pageUp\f[R], \f[CR]cmd.pager.pageDown\f[R], -\f[CR]cmd.pager.pageLeft\f[R], \f[CR]cmd.pager.pageRight\f[R] +C\-b, C\-f, zH, zL +T}@T{ +\f[CR]cmd.buffer.pageUp\f[R], \f[CR]cmd.buffer.pageDown\f[R], +\f[CR]cmd.buffer.pageLeft\f[R], \f[CR]cmd.buffer.pageRight\f[R] T}@T{ Scroll up/down/left/right by n pages, or if n is unspecified, by one page. T}@T{ T} T{ -\f[CR]cmd.pager.halfPageUp\f[R], \f[CR]cmd.pager.halfPageDown\f[R], -\f[CR]cmd.pager.halfPageLeft\f[R], \f[CR]pager.halfPageUp\f[R] +C\-u, C\-d +T}@T{ +\f[CR]cmd.buffer.halfPageUp\f[R], \f[CR]cmd.buffer.halfPageDown\f[R], +\f[CR]cmd.buffer.halfPageLeft\f[R], \f[CR]cmd.buffer.halfPageUp\f[R] T}@T{ Scroll up/down/left/right by n half pages, or if n is unspecified, by one page. T}@T{ T} T{ -\f[CR]cmd.pager.scrollUp\f[R], \f[CR]cmd.pager.scrollDown\f[R], -\f[CR]cmd.pager.scrollLeft\f[R], \f[CR]cmd.pager.scrollRight\f[R] +K/C\-y, J/C\-e, zh, zl +T}@T{ +\f[CR]cmd.buffer.scrollUp\f[R], \f[CR]cmd.buffer.scrollDown\f[R], +\f[CR]cmd.buffer.scrollLeft\f[R], \f[CR]cmd.buffer.scrollRight\f[R] T}@T{ Scroll up/down/left/right by n lines, or if n is unspecified, by one line. T}@T{ T} T{ -\f[CR]cmd.pager.click\f[R] -T}@T{ -Click the HTML element currently under the cursor. -T}@T{ -T} -T{ -\f[CR]cmd.pager.load\f[R] +Enter/Return T}@T{ -Open the current address in the URL bar. +\f[CR]cmd.buffer.click\f[R] T}@T{ -T} -T{ -\f[CR]cmd.pager.webSearch\f[R] -T}@T{ -Open the URL bar with an arbitrary search engine. -At the moment, this is DuckDuckGo Lite. -(Note: Chawan developers aren\[cq]t affiliated with DuckDuckGo the -company or their product in any way.) -T}@T{ -T} -T{ -\f[CR]cmd.pager.nextBuffer\f[R], \f[CR]cmd.pager.prevBuffer\f[R], -\f[CR]cmd.pager.prevSiblingBuffer\f[R], -\f[CR]cmd.pager.nextSiblingBufer\f[R], \f[CR]cmd.pager.parentBuffer\f[R] -T}@T{ -Traverse the buffer tree. -\f[CR]nextBuffer\f[R] and \f[CR]prevBuffer\f[R] are the most intuitive, -traversing the tree as if it were a linked list. -\f[CR]prevSiblingBuffer\f[R] and \f[CR]nextSiblingBuffer\f[R] cycle -through the buffers opened from the same buffer. -Finally, \f[CR]parentBuffer\f[R] always returns to the buffer the -current buffer was opened from, even if e.g.\ the user returns and opens -another page \[lq]in between\[rq]. -T}@T{ -T} -T{ -\f[CR]cmd.pager.dupeBuffer\f[R] -T}@T{ -Duplicate the current buffer by loading its source to a new buffer. -T}@T{ -T} -T{ -\f[CR]cmd.pager.discardBuffer\f[R] -T}@T{ -Discard the current buffer, and move back to the previous/next buffer -depending on what the previously viewed buffer was. -T}@T{ -T} -T{ -\f[CR]cmd.pager.discardBufferPrev\f[R], -\f[CR]cmd.pager.discardBufferNext\f[R] -T}@T{ -Discard the current buffer, and move back to the previous/next buffer, -or open the link under the cursor. -T}@T{ -T} -T{ -\f[CR]cmd.pager.discardTree\f[R] -T}@T{ -Discard all child buffers of the current buffer. +Click the HTML element currently under the cursor. T}@T{ T} T{ -\f[CR]cmd.pager.reload\f[R] -T}@T{ -Open a new buffer with the current buffer\[cq]s URL, replacing the -current buffer. +R T}@T{ -T} -T{ -\f[CR]cmd.pager.reshape\f[R] +\f[CR]cmd.buffer.reshape\f[R] T}@T{ 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{ -\f[CR]cmd.pager.redraw\f[R] +r +T}@T{ +\f[CR]cmd.buffer.redraw\f[R] T}@T{ Redraw screen contents. Useful if something messed up the display. T}@T{ T} T{ -\f[CR]cmd.pager.toggleSource\f[R] -T}@T{ -If viewing an HTML buffer, open a new buffer with its source. -Otherwise, open the current buffer\[cq]s contents as HTML. +None (see gotoLineOrStart/End instead) T}@T{ -T} -T{ -\f[CR]cmd.pager.cursorFirstLine\f[R], -\f[CR]cmd.pager.cursorLastLine\f[R] +\f[CR]cmd.buffer.cursorFirstLine\f[R], +\f[CR]cmd.buffer.cursorLastLine\f[R] T}@T{ Move to the beginning/end in the buffer. T}@T{ T} T{ -\f[CR]cmd.pager.cursorTop\f[R] +H +T}@T{ +\f[CR]cmd.buffer.cursorTop\f[R] T}@T{ Move to the first line on the screen. (Equivalent to H in vi.) T}@T{ T} T{ -\f[CR]cmd.pager.cursorMiddle\f[R] +M +T}@T{ +\f[CR]cmd.buffer.cursorMiddle\f[R] T}@T{ Move to the line in the middle of the screen. (Equivalent to M in vi.) T}@T{ T} T{ -\f[CR]cmd.pager.cursorBottom\f[R] +L +T}@T{ +\f[CR]cmd.buffer.cursorBottom\f[R] T}@T{ Move to the last line on the screen. (Equivalent to L in vi.) T}@T{ T} T{ -\f[CR]cmd.pager.raisePage\f[R], \f[CR]cmd.pager.raisePageBegin\f[R], -\f[CR]cmd.pager.centerLine\f[R], \f[CR]cmd.pager.centerLineBegin\f[R], -\f[CR]cmd.pager.lowerPage\f[R], \f[CR]cmd.pager.lowerPageBegin\f[R] +zt, z Return, zz, z., zb, z\- +T}@T{ +\f[CR]cmd.buffer.raisePage\f[R], \f[CR]cmd.buffer.raisePageBegin\f[R], +\f[CR]cmd.buffer.centerLine\f[R], \f[CR]cmd.buffer.centerLineBegin\f[R], +\f[CR]cmd.buffer.lowerPage\f[R], \f[CR]cmd.buffer.lowerPageBegin\f[R] T}@T{ If n is specified, move cursor to line n.\ Then, * \f[CR]raisePage\f[R] scrolls down so that the cursor is on the top line of the screen. @@ -1323,94 +1512,67 @@ first non\-blank character, as the variants originating from vi do. T}@T{ T} T{ -\f[CR]cmd.pager.nextPageBegin\f[R] +z+ +T}@T{ +\f[CR]cmd.buffer.nextPageBegin\f[R] T}@T{ If n is specified, move to the screen before the nth line and raise the page. 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]cmd.pager.previousPageBegin\f[R] +z\[ha] +T}@T{ +\f[CR]cmd.buffer.previousPageBegin\f[R] T}@T{ If n is specified, move to the screen before the nth line and raise the page. 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]cmd.pager.cursorLeftEdge\f[R], -\f[CR]cmd.pager.cursorMiddleColumn\f[R], -\f[CR]cmd.pager.cursorRightEdge\f[R] +g0, gc, g$ +T}@T{ +\f[CR]cmd.buffer.cursorLeftEdge\f[R], +\f[CR]cmd.buffer.cursorMiddleColumn\f[R], +\f[CR]cmd.buffer.cursorRightEdge\f[R] T}@T{ Move to the first/middle/last column on the screen. T}@T{ T} T{ -\f[CR]cmd.pager.centerColumn\f[R] +None +T}@T{ +\f[CR]cmd.buffer.centerColumn\f[R] T}@T{ Center screen around the current column. (w3m \f[CR]Z\f[R].) T}@T{ T} T{ -\f[CR]cmd.pager.lineInfo\f[R] -T}@T{ -Display information about the current line on the status line. -T}@T{ -T} -T{ -\f[CR]cmd.pager.searchForward\f[R], \f[CR]cmd.pager.searchBackward\f[R] -T}@T{ -Search for a string in the current buffer, forwards or backwards. -T}@T{ -T} -T{ -\f[CR]cmd.pager.isearchForward\f[R], \f[CR]cmd.pager.searchBackward\f[R] +gg, G T}@T{ -Incremental\-search for a string, highlighting the first result, -forwards or backwards. -T}@T{ -T} -T{ -\f[CR]cmd.pager.gotoLineOrStart\f[R], \f[CR]cmd.pager.gotoLineOrEnd\f[R] +\f[CR]cmd.buffer.gotoLineOrStart\f[R], +\f[CR]cmd.buffer.gotoLineOrEnd\f[R] T}@T{ If n is specified, jump to line n.\ Otherwise, jump to the start/end of the page. T}@T{ T} T{ -\f[CR]cmd.pager.searchNext\f[R], \f[CR]cmd.pager.searchPrev\f[R] +m T}@T{ -Jump to the nth (or if unspecified, first) next/previous search result. -T}@T{ -T} -T{ -\f[CR]cmd.pager.peek\f[R] -T}@T{ -Display a message of the current buffer\[cq]s URL on the status line. -T}@T{ -T} -T{ -\f[CR]cmd.pager.peekCursor\f[R] -T}@T{ -Display a message of the URL or title under the cursor on the status -line. -Multiple calls allow cycling through the two. -(i.e.\ by default, press u once \-> title, press again \-> URL) -T}@T{ -T} -T{ -\f[CR]cmd.pager.setMark\f[R] +\f[CR]cmd.buffer.mark\f[R] T}@T{ 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{ -\f[CR]cmd.pager.gotoMark\f[R], \f[CR]cmd.pager.gotoMarkY\f[R] +\[ga], \[cq] +T}@T{ +\f[CR]cmd.buffer.gotoMark\f[R], \f[CR]cmd.buffer.gotoMarkY\f[R] T}@T{ Wait for a character \f[CR]x\f[R] and then jump to the mark with the ID \f[CR]x\f[R] (if it exists on the page). @@ -1419,39 +1581,27 @@ the Y position. T}@T{ T} T{ -\f[CR]cmd.pager.markURL\f[R] +: T}@T{ -Convert URL\-like strings to anchors on the current page. +\f[CR]cmd.buffer.markURL\f[R] T}@T{ -T} -T{ -\f[CR]cmd.pager.saveLink\f[R] -T}@T{ -Save resource from the URL pointed to by the cursor to the disk. +Convert URL\-like strings to anchors on the current page. T}@T{ T} T{ -\f[CR]cmd.pager.saveSource\f[R] -T}@T{ -Save the source of the current buffer to the disk. +s Return T}@T{ -T} -T{ -\f[CR]cmd.pager.copyURL\f[R] +\f[CR]cmd.buffer.saveLink\f[R] T}@T{ -Copy the current buffer\[cq]s URL to the system clipboard. +Save resource from the URL pointed to by the cursor to the disk. T}@T{ T} T{ -\f[CR]cmd.pager.copyCursorLink\f[R] +sS T}@T{ -Copy the link under the cursor to the system clipboard. -T}@T{ -T} -T{ -\f[CR]cmd.pager.copyCursorImage\f[R] +\f[CR]cmd.buffer.saveSource\f[R] T}@T{ -Copy the URL of the image under the cursor to the system clipboard. +Save the source of the current buffer to the disk. T}@T{ T} .TE @@ -1459,8 +1609,10 @@ T} .PP .TS tab(@); -lw(21.5n) lw(43.1n) lw(5.4n). +lw(32.1n) lw(11.7n) lw(23.3n) lw(2.9n). T{ +Default key +T}@T{ Name T}@T{ Function @@ -1468,60 +1620,80 @@ T}@T{ T} _ T{ +Return +T}@T{ \f[CR]cmd.line.submit\f[R] T}@T{ Submit the line. T}@T{ T} T{ +C\-c +T}@T{ \f[CR]cmd.line.cancel\f[R] T}@T{ Cancel the current operation. T}@T{ T} T{ +C\-h, C\-d +T}@T{ \f[CR]cmd.line.backspace\f[R], \f[CR]cmd.line.delete\f[R] T}@T{ Delete character before (backspace)/after (delete) the cursor. T}@T{ T} T{ +C\-u, C\-k +T}@T{ \f[CR]cmd.line.clear\f[R], \f[CR]cmd.line.kill\f[R] T}@T{ Delete text before (clear)/after (kill) the cursor. T}@T{ T} T{ +C\-w, M\-d +T}@T{ \f[CR]cmd.line.clearWord\f[R], \f[CR]cmd.line.killWord\f[R] T}@T{ Delete word before (clear)/after (kill) the cursor. T}@T{ T} T{ +C\-b, C\-f +T}@T{ \f[CR]cmd.line.backward\f[R], \f[CR]cmd.line.forward\f[R] T}@T{ Move cursor backward/forward by one character. T}@T{ T} T{ +M\-b, M\-f +T}@T{ \f[CR]cmd.line.prevWord\f[R], \f[CR]cmd.line.nextWord\f[R] T}@T{ Move cursor to the previous/next word by one character T}@T{ T} T{ +C\-a, C\-e +T}@T{ \f[CR]cmd.line.begin\f[R], \f[CR]cmd.line.end\f[R] T}@T{ Move cursor to the beginning/end of the line. T}@T{ T} T{ +C\-v +T}@T{ \f[CR]cmd.line.escape\f[R] T}@T{ Ignore keybindings for next character. T}@T{ T} T{ +C\-p, C\-n +T}@T{ \f[CR]cmd.line.prevHist\f[R], \f[CR]cmd.line.nextHist\f[R] T}@T{ Jump to the previous/next history entry diff --git a/doc/cha-image.5 b/doc/cha-image.5 index 764079c1..4a97f055 100644 --- a/doc/cha-image.5 +++ b/doc/cha-image.5 @@ -4,9 +4,6 @@ .SH Inline images On terminals that support images, Chawan can display various bit\-mapped image formats. -.PP -Warning: both this document and the implementation is very much WIP. -Anything described in this document may change in the near future. .SS Enabling images There are actually two switches for images in the config: .IP \[bu] 2 @@ -21,14 +18,13 @@ In most cases, all you need to do is to set \[lq]buffer.images\[rq] to true; with the default image\-mode, Chawan will find the best image display method supported by your terminal. .PP -However, there are terminals (such as yaft) that support an image output -method but do not advertise it (and are therefore left undetected). -For such terminals, you also have to set \[lq]display.image\-mode\[rq] -appropriately. +If your terminal does not tell Chawan that it can display sixels, you +may also have to set \[lq]display.image\-mode\[rq] appropriately. +See below for further discussion of sixel configuration. .SS Output formats Supported output formats are: .IP \[bu] 2 -The DEC SIXEL format +The DEC Sixel format .IP \[bu] 2 The Kitty terminal graphics protocol .PP @@ -42,6 +38,50 @@ the above two anyways.) .PP Support for hacks such as w3mimgdisplay, ueberzug, etc. is not planned. +.SS Sixel +Sixel is the most widely supported image format. +See \c +.UR https://arewesixelyet.com +.UE \c +\ to find a terminal that supports it. +.PP +Known quirks and implementation details: +.IP \[bu] 2 +XTerm needs extensive configuration for ideal sixel support. +In particular, you will want to set the decTerminalID, +numColorRegisters, and maxGraphicSize attributes. +See \f[CR]man xterm\f[R] for details. +.IP \[bu] 2 +We assume private color registers are supported. +On terminals where they aren\[cq]t (e.g.\ SyncTERM or hardware +terminals), colors will get messed up with multiple images on screen. +.IP \[bu] 2 +We send XTSMGRAPHICS for retrieving the number of color registers; on +failure, we fall back to 256. +You can override color register count using the +\f[CR]display.sixel\-colors\f[R] configuration value. +.IP \[bu] 2 +For the most efficient sixel display, you will want a cell height that +is a multiple of 6. +Otherwise, the images will have to be re\-coded several times on scroll. +.IP \[bu] 2 +Normally, Sixel encoding runs in two passes. +On slow computers, you can try setting +\f[CR]display.sixel\-colors = 2\f[R], which will skip the first pass +(but will also display everything in monochrome). +.IP \[bu] 2 +Transparency \f[I]is\f[R] supported, but looks weird because we +approximate an 8\-bit alpha channel with Sixel\[cq]s 1\-bit alpha +channel. +.SS Kitty +On terminals that support it, Kitty\[cq]s protocol is preferred over +Sixel. +Its main benefit is that images do not have to be sent again every time +they move on the screen (i.e.\ on scroll), but the initial transfer +should also be faster (because PNG\[cq]s compression tends to outperform +Sixel\[cq]s RLE). +.PP +Unlike Sixel, the Kitty protocol fully supports transparency. .SS Input formats Currently, the supported input formats are: .IP \[bu] 2 @@ -57,14 +97,15 @@ something like stbi is OK to vendor.) All image codec implementations are specified by the URL scheme \[lq]img\-codec+name:\[rq], where \[lq]name\[rq] is the MIME subtype. e.g.\ for image/png, it is \[lq]img\-codec+png:\[rq]. +(This indeed means that only \[lq]image\[rq] MIME types can be used.) +.PP Like all schemes, these are defined (and overridable) in the urimethodmap file, and are implemented as local CGI programs. These programs take an encoded image on stdin, and dump the decoded RGBA data to stdout \- when encoding, vice versa. .PP -This means that it is possible (although rarely practical) for users to -define image decoders for their preferred formats, or even override the -built\-in ones. +This means that it is possible for users to define image decoders for +their preferred formats, or even override the built\-in ones. (If you actually end up doing this for some reason, please shoot me a mail so I can add it to the bonus directory.) .PP @@ -82,8 +123,6 @@ binary stream of an encoded image on its standard input and print the equivalent binary stream of big\-endian 8\-bit (per component) RGBA values to stdout. .PP -If specified, it also has to resize said image first. -.PP Input headers: .IP \[bu] 2 Cha\-Image\-Info\-Only: 1 @@ -91,33 +130,15 @@ Cha\-Image\-Info\-Only: 1 This tells the image decoder to only send image metadata (i.e.\ size). Technically, the decoder is free to actually decode the image too, but the browser will ignore any output after headers. -.IP \[bu] 2 -Cha\-Image\-Target\-Dimensions: {width}x{height} -.PP -Mutually exclusive with Cha\-Image\-Info\-Only; this instructs the -decoder to also resize the output image. -The dimension format is such that for e.g.\ 123x456, 123 is width and -456 is height. -.PP -(Readers of good taste might consider this header to be a questionable -design decision, but remember that both the decoder and encoder -effectively require copying the output image (thru stdio). -Combined with the current file loader implementation, this means that -in\-browser image resizing would require at least two unnecessary -copies. -.PP -A future design might solve this problem better through shared memory.) .PP Output headers: .IP \[bu] 2 Cha\-Image\-Dimensions: {width}x{height} .PP -The final size of the decoded image. -If the image was resized through Cha\-Image\-Target\-Dimensions, then -this header\[cq]s value will match the value specified there. +The size of the decoded image. .PP -Again, the dimension format is such that e.g.\ for 123x456, 123 is width -and 456 is height. +The dimension format is such that e.g.\ for 123x456, 123 is width and +456 is height. .SS encoding When the path equals \[lq]encode\[rq], a codec CGI script must take a binary stream of big\-endian 8\-bit (per component) RGBA values on its @@ -146,3 +167,29 @@ It is up to the encoder to interpret this number. Output headers: .PP Currently, no output headers are defined for encoders. +.SS Skipping copies with mmap +The naive implementation of the above system would have to copy the +output at least twice when an image is resized. +To skip these copies, stdin and/or stdout is (currently) a file in the +tmp directory for: +.IP \[bu] 2 +decode stdin, when the image is already downloaded +.IP \[bu] 2 +decode stdout, always +.IP \[bu] 2 +encode stdin, always +.PP +This makes it possible to mmap(2) stdin/stdout instead of streaming +through them with read(2) and write(2). +When doing this, mind the following: +.IP \[bu] 2 +When reading, you must check your initial position in the file with +lseek(2). +.IP \[bu] 2 +When writing, your headers are part of the output. +At the very least, you must place a newline at the file\[cq]s beginning. +.IP \[bu] 2 +This \f[I]is\f[R] an implementation detail, and might change at any time +in the future (e.g.\ if we add a \[lq]no cache files\[rq] mode). +Always check for S_ISREG to ensure that you are actually dealing with a +file. diff --git a/doc/config.md b/doc/config.md index 13afec04..cde29243 100644 --- a/doc/config.md +++ b/doc/config.md @@ -1064,50 +1064,59 @@ unspecified. <table> <tr> +<th>Default key</th> <th>Name</th> <th>Function</th> </tr> <tr> +<td><kbd>j</kbd>, <kbd>k</kbd></td> <td>`cmd.buffer.cursorUp`, `cmd.buffer.cursorDown`</td> <td>Move the cursor upwards/downwards by n lines, or if n is unspecified, by 1.</td> </tr> <tr> +<td><kbd>h</kbd>, <kbd>l</kbd></td> <td>`cmd.buffer.cursorLeft`, `cmd.buffer.cursorRight`</td> <td>Move the cursor to the left/right by n cells, or if n is unspecified, by 1.</td> </tr> <tr> +<td><kbd>0</kbd></td> <td>`cmd.buffer.cursorLineBegin`</td> <td>Move the cursor to the first cell of the line.</td> </tr> <tr> +<td><kbd>^</kbd></td> <td>`cmd.buffer.cursorLineTextStart`</td> <td>Move the cursor to the first non-blank character of the line.</td> </tr> <tr> +<td><kbd>$</kbd></td> <td>`cmd.buffer.cursorLineEnd`</td> <td>Move the cursor to the last cell of the line.</td> </tr> <tr> +<td><kbd>w</kbd>, <kbd>W</kbd></td> <td>`cmd.buffer.cursorNextWord`, `cmd.buffer.cursorNextViWord`, `cmd.buffer.cursorNextBigWord`</td> <td>Move the cursor to the beginning of the next [word](#word-types).</td> </tr> <tr> +<td>None</td> <td>`cmd.buffer.cursorPrevWord`, `cmd.buffer.cursorPrevViWord`, `cmd.buffer.cursorPrevBigWord`</td> <td>Move the cursor to the end of the previous [word](#word-types).</td> </tr> <tr> +<td><kbd>e</kbd>, <kbd>E</kbd></td> <td>`cmd.buffer.cursorWordEnd`, `cmd.buffer.cursorViWordEnd`, `cmd.buffer.cursorBigWordEnd`</td> <td>Move the cursor to the end of the current [word](#word-types), or if already @@ -1115,6 +1124,7 @@ there, to the end of the next word.</td> </tr> <tr> +<td><kbd>b</kbd>, <kbd>B</kbd></td> <td>`cmd.buffer.cursorWordBegin`, `cmd.buffer.cursorViWordBegin`, `cmd.buffer.cursorBigWordBegin`</td> <td>Move the cursor to the beginning of the current [word](#word-types), or if @@ -1122,29 +1132,34 @@ already there, to the end of the previous word.</td> </tr> <tr> +<td><kbd>[</kbd>, <kbd>]</kbd></td> <td>`cmd.buffer.cursorPrevLink`, `cmd.buffer.cursorNextLink`</td> <td>Move the cursor to the end/beginning of the previous/next clickable element (e.g. link, input field, etc).</td> </tr> <tr> +<td><kbd>{</kbd>, <kbd>}</kbd></td> <td>`cmd.buffer.cursorPrevParagraph`, `cmd.buffer.cursorNextParagraph`</td> <td>Move the cursor to the end/beginning of the nth previous/next paragraph.</td> </tr> <tr> +<td>None</td> <td>`cmd.buffer.cursorRevNthLink`</td> <td>Move the cursor to the nth link of the document, counting backwards from the document's last line.</td> </tr> <tr> +<td>None</td> <td>`cmd.buffer.cursorNthLink`</td> <td>Move the cursor to the nth link of the document.</td> </tr> <tr> +<td><kbd>C-b</kbd>, <kbd>C-f</kbd>, <kbd>zH</kbd>, <kbd>zL</kbd></td> <td>`cmd.buffer.pageUp`, `cmd.buffer.pageDown`, `cmd.buffer.pageLeft`, `cmd.buffer.pageRight`</td> <td>Scroll up/down/left/right by n pages, or if n is unspecified, by one @@ -1152,6 +1167,7 @@ page.</td> </tr> <tr> +<td><kbd>C-u</kbd>, <kbd>C-d</kbd></td> <td>`cmd.buffer.halfPageUp`, `cmd.buffer.halfPageDown`, `cmd.buffer.halfPageLeft`, `cmd.buffer.halfPageUp`</td> <td>Scroll up/down/left/right by n half pages, or if n is unspecified, by one @@ -1159,6 +1175,8 @@ page.</td> </tr> <tr> +<td><kbd>K</kbd>/<kbd>C-y</kbd>, <kbd>J</kbd>/<kbd>C-e</kbd>, +<kbd>zh</kbd>, <kbd>zl</kbd></td> <td>`cmd.buffer.scrollUp`, `cmd.buffer.scrollDown`, `cmd.buffer.scrollLeft`, `cmd.buffer.scrollRight`</td> <td>Scroll up/down/left/right by n lines, or if n is unspecified, by one @@ -1166,41 +1184,52 @@ line.</td> </tr> <tr> +<td><kbd>Enter</kbd>/<kbd>Return</kbd></td> <td>`cmd.buffer.click`</td> <td>Click the HTML element currently under the cursor.</td> </tr> <tr> +<td><kbd>R</kbd></td> <td>`cmd.buffer.reshape`</td> -<td>Reshape the current buffer (=render the current page anew.)</td> +<td>Reshape the current buffer (=render the current page anew.) Useful +if the layout is not updating even though it should have.</td> </tr> <tr> +<td><kbd>r</kbd></td> <td>`cmd.buffer.redraw`</td> <td>Redraw screen contents. Useful if something messed up the display.</td> </tr> <tr> +<td>None (see gotoLineOrStart/End instead)</td> <td>`cmd.buffer.cursorFirstLine`, `cmd.buffer.cursorLastLine`</td> <td>Move to the beginning/end in the buffer.</td> </tr> <tr> +<td><kbd>H</kbd></td> <td>`cmd.buffer.cursorTop`</td> <td>Move to the first line on the screen. (Equivalent to H in vi.)</td> </tr> <tr> +<td><kbd>M</kbd></td> <td>`cmd.buffer.cursorMiddle`</td> <td>Move to the line in the middle of the screen. (Equivalent to M in vi.)</td> </tr> <tr> +<td><kbd>L</kbd></td> <td>`cmd.buffer.cursorBottom`</td> <td>Move to the last line on the screen. (Equivalent to L in vi.)</td> </tr> <tr> +<td><kbd>zt</kbd>, <kbd>z Return</kbd>, +<kbd>zz</kbd>, <kbd>z.</kbd>, +<kbd>zb</kbd>, <kbd>z-</kbd></td> <td>`cmd.buffer.raisePage`, `cmd.buffer.raisePageBegin`, `cmd.buffer.centerLine`, `cmd.buffer.centerLineBegin`, `cmd.buffer.lowerPage`, `cmd.buffer.lowerPageBegin`</td> @@ -1219,42 +1248,47 @@ character, as the variants originating from vi do. </tr> <tr> +<td><kbd>z+</kbd></td> <td>`cmd.buffer.nextPageBegin`</td> <td>If n is specified, move to the screen before the nth line and raise the page. -Otherwise, go to the previous screen's last line and raise the page. (`z+` -in vi.)</td> +Otherwise, go to the previous screen's last line and raise the page.</td> </tr> <tr> +<td><kbd>z^</kbd></td> <td>`cmd.buffer.previousPageBegin`</td> <td>If n is specified, move to the screen before the nth line and raise the -page. Otherwise, go to the previous screen's last line and raise the page. -(`z+` in vi.)</td> +page. Otherwise, go to the previous screen's last line and raise the page.</td> </tr> <tr> +<td><kbd>g0</kbd>, <kbd>gc</kbd>, <kbd>g$</kbd></td> <td>`cmd.buffer.cursorLeftEdge`, `cmd.buffer.cursorMiddleColumn`, `cmd.buffer.cursorRightEdge`</td> <td>Move to the first/middle/last column on the screen.</td> </tr> <tr> +<td>None</td> <td>`cmd.buffer.centerColumn`</td> <td>Center screen around the current column. (w3m `Z`.)</td> </tr> <tr> +<td><kbd>gg</kbd>, <kbd>G</kbd></td> <td>`cmd.buffer.gotoLineOrStart`, `cmd.buffer.gotoLineOrEnd`</td> <td>If n is specified, jump to line n. Otherwise, jump to the start/end of the page.</td> </tr> <tr> +<td><kbd>m</kbd></td> <td>`cmd.buffer.mark`</td> <td>Wait for a character `x` and then set a mark with the ID `x`.</td> </tr> <tr> +<td><kbd>`</kbd>, <kbd>'</kbd></td> <td>`cmd.buffer.gotoMark`, `cmd.buffer.gotoMarkY`</td> <td>Wait for a character `x` and then jump to the mark with the ID `x` (if it exists on the page).<br> @@ -1263,16 +1297,19 @@ position.</td> </tr> <tr> +<td><kbd>:</kbd></td> <td>`cmd.buffer.markURL`</td> <td>Convert URL-like strings to anchors on the current page.</td> </tr> <tr> +<td><kbd>s Return</kbd></td> <td>`cmd.buffer.saveLink`</td> <td>Save resource from the URL pointed to by the cursor to the disk.</td> </tr> <tr> +<td><kbd>sS</kbd></td> <td>`cmd.buffer.saveSource`</td> <td>Save the source of the current buffer to the disk.</td> </tr> @@ -1285,56 +1322,67 @@ position.</td> <table> <tr> +<th>Default key</th> <th>Name</th> <th>Function</th> </tr> <tr> +<td><kbd>Return</kbd></td> <td>`cmd.line.submit`</td> <td>Submit the line.</td> </tr> <tr> +<td><kbd>C-c</kbd></td> <td>`cmd.line.cancel`</td> <td>Cancel the current operation.</td> </tr> <tr> +<td><kbd>C-h</kbd>, <kbd>C-d</kbd></td> <td>`cmd.line.backspace`, `cmd.line.delete`</td> <td>Delete character before (backspace)/after (delete) the cursor.</td> </tr> <tr> +<td><kbd>C-u</kbd>, <kbd>C-k</kbd></td> <td>`cmd.line.clear`, `cmd.line.kill`</td> <td>Delete text before (clear)/after (kill) the cursor.</td> </tr> <tr> +<td><kbd>C-w</kbd>, <kbd>M-d</kbd></td> <td>`cmd.line.clearWord`, `cmd.line.killWord`</td> <td>Delete word before (clear)/after (kill) the cursor.</td> </tr> <tr> +<td><kbd>C-b</kbd>, <kbd>C-f</kbd></td> <td>`cmd.line.backward`, `cmd.line.forward`</td> <td>Move cursor backward/forward by one character.</td> </tr> <tr> +<td><kbd>M-b</kbd>, <kbd>M-f</kbd></td> <td>`cmd.line.prevWord`, `cmd.line.nextWord`</td> <td>Move cursor to the previous/next word by one character</td> </tr> <tr> +<td><kbd>C-a</kbd>, <kbd>C-e</kbd></td> <td>`cmd.line.begin`, `cmd.line.end`</td> <td>Move cursor to the beginning/end of the line.</td> </tr> <tr> +<td><kbd>C-v</kbd></td> <td>`cmd.line.escape`</td> <td>Ignore keybindings for next character.</td> </tr> <tr> +<td><kbd>C-p</kbd>, <kbd>C-n</kbd></td> <td>`cmd.line.prevHist`, `cmd.line.nextHist`</td> <td>Jump to the previous/next history entry</td> </tr> |