diff options
author | bptato <nincsnevem662@gmail.com> | 2023-10-01 02:42:57 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-10-01 02:42:57 +0200 |
commit | 6c10c1b14b5fec2c0c3ba2d2bd22d3d23265377e (patch) | |
tree | 11227039c18a09e31840bb4fd3e436ae70b16226 | |
parent | 03fc72abc4f99b3ee46591d8247a27c642e0b51a (diff) | |
download | chawan-6c10c1b14b5fec2c0c3ba2d2bd22d3d23265377e.tar.gz |
Improve vi/m compat in scrolling
-rw-r--r-- | doc/config.md | 41 | ||||
-rw-r--r-- | res/chawan.html | 4 | ||||
-rw-r--r-- | res/config.toml | 12 | ||||
-rw-r--r-- | src/local/container.nim | 85 |
4 files changed, 120 insertions, 22 deletions
diff --git a/doc/config.md b/doc/config.md index 996f0c16..1140f8d9 100644 --- a/doc/config.md +++ b/doc/config.md @@ -840,8 +840,45 @@ open the current buffer's contents as HTML.</td> </tr> <tr> -<td>`pager.centerLine()`</td> -<td>Center screen around the current line.</td> +<td>`pager.lowerPage(n = pager.cursory)`</td> +<td>Move cursor to line n, then scroll up so that the cursor is on the +top line on the screen. (`zt` in vim.)</td> +</tr> + +<tr> +<td>`pager.lowerPageBegin(n = pager.cursory)`</td> +<td>Move cursor to the first non-blank character of line n, then scroll up +so that the cursor is on the top line on the screen. (`z<CR>` in vi.)</td> +</tr> + +<tr> +<td>`pager.centerLine(n = pager.cursory)`</td> +<td>Center screen around line n. (`zz` in vim.)</td> +</tr> + +<tr> +<td>`pager.centerLineBegin(n = pager.cursory)`</td> +<td>Center screen around line n, and move the cursor to the line's first +non-blank character. (`z.` in vi.)</td> +</tr> + +<tr> +<td>`pager.raisePage(n = pager.cursory)`</td> +<td>Move cursor to line n, then scroll down so that the cursor is on the +top line on the screen. (zb in vim.)</td> +</tr> + +<tr> +<td>`pager.lowerPageBegin(n = pager.cursory)`</td> +<td>Move cursor to the first non-blank character of line n, then scroll up +so that the cursor is on the last line on the screen. (`z^` in vi.)</td> +</tr> + +<tr> +<td>`pager.nextPageBegin(n = pager.cursory)`</td> +<td>If n was given, 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> </tr> <tr> diff --git a/res/chawan.html b/res/chawan.html index 81f9bbea..b73a4347 100644 --- a/res/chawan.html +++ b/res/chawan.html @@ -46,7 +46,9 @@ the meta key may be called Alt or Escape.) <li><b>C-z</b>: suspend the browser <li><b>M-C-c</b>: cancel loading <li><b>H</b>, <b>M</b>, <b>L</b>: move cursor to the Highest/Middle/Lowest rows -<li><b>z</b>: center on current column +<li><b>zz, z.</b>: center on current line (and move to beginning) +<li><b>zt, z-</b>: center on current line (and move to beginning) +<li><b>zb, zC-m</b>: center on current line (and move to beginning) <li><b>w</b>, <b>b</b>: move cursor to next/previous word <li><b>v</b>: toggle page source view <li><b>0</b>: cursor to first cell on line diff --git a/res/config.toml b/res/config.toml index c69d8b66..fed898e9 100644 --- a/res/config.toml +++ b/res/config.toml @@ -113,10 +113,18 @@ U = 'pager.reload()' r = 'pager.redraw()' R = 'pager.reshape()' M-C-c = 'pager.cancel()' -g = 'pager.cursorFirstLine()' +gg = 'pager.cursorFirstLine()' G = 'n => n ? pager.gotoLine(n) : pager.cursorLastLine()' M-g = 'pager.gotoLine()' -z = 'pager.centerLine()' +'z.' = 'n => pager.centerLineBegin(n)' +'zC-m' = 'n => pager.raisePageBegin(n)' +'zC-j' = 'n => pager.raisePageBegin(n)' +'z-' = 'n => pager.lowerPageBegin(n)' +zz = 'n => pager.centerLine(n)' +'zt' = 'n => pager.raisePage(n)' +'zb' = 'n => pager.lowerPage(n)' +'z+' = 'n => pager.nextPageBegin(n)' +'z^' = 'n => pager.previousPageBegin(n)' C-g = 'pager.lineInfo()' v = 'pager.toggleSource()' D = 'pager.discardBuffer()' diff --git a/src/local/container.nim b/src/local/container.nim index 6a11e02a..9667d84b 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -460,16 +460,76 @@ proc setCursorY(container: Container, y: int, refresh = true) {.jsfunc.} = if refresh: container.sendCursorPosition() -proc centerLine(container: Container) {.jsfunc.} = +proc setCursorXY(container: Container, x, y: int, refresh = true) {.jsfunc.} = + container.setCursorY(y, refresh) + container.setCursorX(x, refresh) + +proc cursorLineTextStart(container: Container) {.jsfunc.} = + if container.numLines == 0: return + var x = 0 + for r in container.currentLine.runes: + if not r.isWhitespace(): + break + x += r.twidth(x) + container.setCursorX(x) + +# zb +proc lowerPage(container: Container, n = 0) {.jsfunc.} = + if n != 0: + container.setCursorY(n - 1) + container.setFromY(container.cursory - container.height + 1) + +# z- +proc lowerPageBegin(container: Container, n = 0) {.jsfunc.} = + container.lowerPage(n) + container.cursorLineTextStart() + +# zz +proc centerLine(container: Container, n = 0) {.jsfunc.} = + if n != 0: + container.setCursorY(n - 1) container.setFromY(container.cursory - container.height div 2) +# z. +proc centerLineBegin(container: Container, n = 0) {.jsfunc.} = + container.centerLine(n) + container.cursorLineTextStart() + +# zt +proc raisePage(container: Container, n = 0) {.jsfunc.} = + if n != 0: + container.setCursorY(n - 1) + container.setFromY(container.cursory) + +# z^M +proc raisePageBegin(container: Container, n = 0) {.jsfunc.} = + container.raisePage(n) + container.cursorLineTextStart() + +# z+ +proc nextPageBegin(container: Container, n = 0) {.jsfunc.} = + if n == 0: + container.setCursorY(container.fromy + container.height) + else: + container.setCursorY(n - 1) + container.cursorLineTextStart() + container.raisePage() + +# z^ +proc previousPageBegin(container: Container, n = 0) {.jsfunc.} = + if n == 0: + container.setCursorY(container.fromy - 1) + else: + container.setCursorY(n - container.height) # +- 1 cancels out + container.cursorLineTextStart() + container.lowerPage() + proc centerColumn(container: Container) {.jsfunc.} = container.setFromX(container.cursorx - container.width div 2) -proc setCursorXY(container: Container, x, y: int, refresh = true) {.jsfunc.} = +proc setCursorXYCenter(container: Container, x, y: int, refresh = true) {.jsfunc.} = let fy = container.fromy - container.setCursorY(y, refresh) - container.setCursorX(x, refresh) + container.setCursorXY(x, y, refresh) if fy != container.fromy: container.centerLine() @@ -500,15 +560,6 @@ proc cursorRight(container: Container, n = 1) {.jsfunc.} = proc cursorLineBegin(container: Container) {.jsfunc.} = container.setCursorX(0) -proc cursorLineTextStart(container: Container) {.jsfunc.} = - if container.numLines == 0: return - var x = 0 - for r in container.currentLine.runes: - if not r.isWhitespace(): - break - x += r.twidth(x) - container.setCursorX(x) - proc cursorLineEnd(container: Container) {.jsfunc.} = container.setCursorX(container.currentLineWidth() - 1) @@ -716,14 +767,14 @@ proc cursorNextLink*(container: Container) {.jsfunc.} = .findNextLink(container.cursorx, container.cursory) .then(proc(res: tuple[x, y: int]) = if res.x > -1 and res.y != -1: - container.setCursorXY(res.x, res.y)) + container.setCursorXYCenter(res.x, res.y)) proc cursorPrevLink*(container: Container) {.jsfunc.} = container.iface .findPrevLink(container.cursorx, container.cursory) .then(proc(res: tuple[x, y: int]) = if res.x > -1 and res.y != -1: - container.setCursorXY(res.x, res.y)) + container.setCursorXYCenter(res.x, res.y)) proc clearSearchHighlights*(container: Container) = for i in countdown(container.highlights.high, 0): @@ -732,7 +783,7 @@ proc clearSearchHighlights*(container: Container) = proc onMatch(container: Container, res: BufferMatch, refresh: bool) = if res.success: - container.setCursorXY(res.x, res.y, refresh) + container.setCursorXYCenter(res.x, res.y, refresh) if container.hlon: container.clearSearchHighlights() let ex = res.x + res.str.twidth(res.x) - 1 @@ -812,7 +863,7 @@ proc onload*(container: Container, res: LoadResult) = ).then(proc(res: Opt[tuple[x, y: int]]) = if res.isSome: let res = res.get - container.setCursorXY(res.x, res.y)) + container.setCursorXYCenter(res.x, res.y)) proc load(container: Container) = container.setLoadInfo("Connecting to " & container.location.host & "...") |