diff options
author | bptato <nincsnevem662@gmail.com> | 2023-09-08 20:07:58 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-09-08 20:23:42 +0200 |
commit | 39e9d80a49124067edb38c4711c58d5cb790c91e (patch) | |
tree | e4c676814f13078ad77ffaa5101f852870d05809 /src | |
parent | 099550625e55ad59a6ed6bef54ad0d86470cdd91 (diff) | |
download | chawan-39e9d80a49124067edb38c4711c58d5cb790c91e.tar.gz |
Add vi-style numeric prefixes, make gotoLine 1-based
* it is now possible to jump to the nth line by typing {n}G * gotoLine is now 1-based, so to go to the first line you would use pager.gotoLine(1) * it is now allowed to return a function from a keybinding (which will be subsequently executed as a regular keybinding)
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer/container.nim | 11 | ||||
-rw-r--r-- | src/config/config.nim | 4 | ||||
-rw-r--r-- | src/display/client.nim | 51 |
3 files changed, 52 insertions, 14 deletions
diff --git a/src/buffer/container.nim b/src/buffer/container.nim index 0e31b672..2a000bbf 100644 --- a/src/buffer/container.nim +++ b/src/buffer/container.nim @@ -1,7 +1,6 @@ import deques import options import streams -import strutils import unicode when defined(posix): @@ -627,13 +626,13 @@ proc gotoLine*[T: string|int](container: Container, s: T) = elif s[0] == '$': container.cursorLastLine() else: - try: - let i = parseInt(s) - container.setCursorY(i) - except ValueError: + let i = parseUInt32(s) + if i.isSome and i.get > 0: + container.setCursorY(int(i.get - 1)) + else: container.alert("First line is #1") # :) else: - container.setCursorY(s) + container.setCursorY(s - 1) proc pushCursorPos*(container: Container) = if container.select.open: diff --git a/src/config/config.nim b/src/config/config.nim index 1719d18b..6d75c411 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -88,6 +88,9 @@ type mailcap* {.jsgetset.}: seq[string] mime_types* {.jsgetset.}: seq[string] + InputConfig = object + vi_numeric_prefix* {.jsgetset.}: bool + NetworkConfig = object max_redirect* {.jsgetset.}: int32 prepend_https* {.jsgetset.}: bool @@ -118,6 +121,7 @@ type encoding* {.jsget.}: EncodingConfig external* {.jsget.}: ExternalConfig network* {.jsget.}: NetworkConfig + input* {.jsget.}: InputConfig display* {.jsget.}: DisplayConfig #TODO getset siteconf: seq[StaticSiteConfig] diff --git a/src/display/client.nim b/src/display/client.nim index d5140de8..72a42124 100644 --- a/src/display/client.nim +++ b/src/display/client.nim @@ -42,10 +42,12 @@ import js/intl import js/javascript import js/module import js/timeout +import js/tojs import types/blob import types/cookie import types/url import utils/opt +import utils/twtstr import xhr/formdata import xhr/xmlhttprequest @@ -63,13 +65,15 @@ type fdmap: Table[int, Container] feednext: bool forkserver: ForkServer + notnum: bool # has a non-numeric character been input already? jsctx: JSContext jsrt: JSRuntime line {.jsget.}: LineEdit loader: FileLoader mainproc: Pid pager {.jsget.}: Pager - s: string + precnum: int32 # current number prefix (when vi-numeric-prefix is true) + s: string # current input buffer selector: Selector[Container] ssock: ServerSocket store {.jsget, jsset.}: Document @@ -190,6 +194,42 @@ proc handlePagerEvents(client: Client) = if container != nil: client.pager.handleEvents(container) +proc evalAction(client: Client, action: string, arg0: int32) = + let ret = client.evalJS(action, "<command>") + let ctx = client.jsctx + if JS_IsFunction(ctx, ret): + if arg0 != 0: # no precnum + let arg0 = toJS(ctx, arg0) + JS_FreeValue(ctx, JS_Call(ctx, ret, JS_UNDEFINED, 1, addr arg0)) + JS_FreeValue(ctx, arg0) + else: + JS_FreeValue(ctx, JS_Call(ctx, ret, JS_UNDEFINED, 0, nil)) + JS_FreeValue(ctx, ret) + +# The maximum number we are willing to accept. +# This should be fine for 32-bit signed ints (which precnum currently is). +# We can always increase it further (e.g. by switching to uint32, uint64...) if +# it proves to be too low. +const MaxPrecNum = 100000000 + +proc handleCommandInput(client: Client, c: char) = + if client.config.input.vi_numeric_prefix and not client.notnum: + if client.precnum != 0 and c == '0' or c in '1' .. '9': + if client.precnum < MaxPrecNum: # better ignore than eval... + client.precnum *= 10 + client.precnum += cast[int32](decValue(c)) + return + else: + client.notnum = true + client.s &= c + let action = getNormalAction(client.config, client.s) + client.evalAction(action, client.precnum) + if not client.feedNext: + client.precnum = 0 + client.notnum = false + client.handlePagerEvents() + client.pager.refreshStatusMsg() + proc input(client: Client) = restoreStdin(client.console.tty.getFileHandle()) while true: @@ -217,18 +257,13 @@ proc input(client: Client) = else: client.feedNext = true elif not client.feednext: - client.evalJSFree(action, "<command>") + client.evalAction(action, 0) if client.pager.lineedit.isNone: client.line = nil if not client.feedNext: client.pager.updateReadLine() else: - client.s &= c - let action = getNormalAction(client.config, client.s) - client.evalJSFree(action, "<command>") - if not client.feedNext: - client.handlePagerEvents() - client.pager.refreshStatusMsg() + client.handleCommandInput(c) if not client.feednext: client.s = "" break |