diff options
-rw-r--r-- | doc/config.md | 24 | ||||
-rw-r--r-- | res/config.toml | 22 | ||||
-rw-r--r-- | src/local/container.nim | 59 | ||||
-rw-r--r-- | src/local/pager.nim | 16 | ||||
-rw-r--r-- | src/server/buffer.nim | 24 |
5 files changed, 82 insertions, 63 deletions
diff --git a/doc/config.md b/doc/config.md index 8796ccfe..ad1807c5 100644 --- a/doc/config.md +++ b/doc/config.md @@ -703,23 +703,23 @@ Note: this does not suspend buffer processes.</td> </tr> <tr> -<td>`pager.scrollDown()`</td> -<td>Scroll forwards by one line.</td> +<td>`pager.scrollDown(n = 1)`</td> +<td>Scroll forwards by n lines.</td> </tr> <tr> -<td>`pager.scrollUp()`</td> -<td>Scroll backwards by one line.</td> +<td>`pager.scrollUp(n = 1)`</td> +<td>Scroll backwards by n lines.</td> </tr> <tr> -<td>`pager.scrollLeft()`</td> -<td>Scroll to the left by one column.</td> +<td>`pager.scrollLeft(n = 1)`</td> +<td>Scroll to the left by n columns.</td> </tr> <tr> -<td>`pager.scrollRight()`</td> -<td>Scroll to the right by one column.</td> +<td>`pager.scrollRight(n = 1)`</td> +<td>Scroll to the right by n columns.</td> </tr> <tr> @@ -857,13 +857,13 @@ shown.</td> </tr> <tr> -<td>`pager.searchNext()`</td> -<td>Jump to the next search result.</td> +<td>`pager.searchNext(n = 1)`</td> +<td>Jump to the nth next search result.</td> </tr> <tr> -<td>`pager.searchPrev()`</td> -<td>Jump to the previous search result.</td> +<td>`pager.searchPrev(n = 1)`</td> +<td>Jump to the nth previous search result.</td> </tr> <tr> diff --git a/res/config.toml b/res/config.toml index 89b42cbe..fbda89b6 100644 --- a/res/config.toml +++ b/res/config.toml @@ -77,9 +77,9 @@ b = 'pager.cursorPrevWord()' w = 'pager.cursorNextWord()' '[' = 'pager.cursorPrevLink()' ']' = 'pager.cursorNextLink()' -H = 'pager.cursorTop()' -M = 'pager.cursorMiddle()' -L = 'pager.cursorBottom()' +H = 'n => pager.cursorTop(n ?? 1)' +M = '() => pager.cursorMiddle()' +L = 'n => pager.cursorBottom(n ?? 1)' ';' = 'pager.cursorLeftEdge()' '+' = 'pager.cursorMiddleColumn()' '@' = 'pager.cursorRightEdge()' @@ -91,12 +91,12 @@ C-b = 'pager.pageUp()' 'M-[5~' = 'pager.pageUp()' '>' = 'pager.pageRight()' '<' = 'pager.pageLeft()' -C-e = 'pager.scrollDown()' -C-y = 'pager.scrollUp()' -J = 'pager.scrollDown()' -K = 'pager.scrollUp()' -'('= 'pager.scrollLeft()' -')' = 'pager.scrollRight()' +C-e = 'n => pager.scrollDown(n ?? 1)' +C-y = 'n => pager.scrollUp(n ?? 1)' +J = 'n => pager.scrollDown(n ?? 1)' +K = 'n => pager.scrollUp(n ?? 1)' +'('= 'n => pager.scrollLeft(n ?? 1)' +')' = 'n => pager.scrollRight(n ?? 1)' C-m = 'pager.click()' C-j = 'pager.click()' M-u = 'pager.dupeBuffer()' @@ -123,8 +123,8 @@ M-d = 'pager.discardTree()' M-c = 'pager.command()' '/' = 'pager.isearchForward()' '?' = 'pager.isearchBackward()' -n = 'pager.searchNext()' -N = 'pager.searchPrev()' +n = 'n => pager.searchNext(n ?? 1)' +N = 'n => pager.searchPrev(n ?? 1)' c = 'pager.peek()' u = 'pager.peekCursor()' C-w = ''' diff --git a/src/local/container.nim b/src/local/container.nim index 37a78faf..465d7b87 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -610,14 +610,16 @@ proc cursorLastLine*(container: Container) {.jsfunc.} = else: container.setCursorY(container.numLines - 1) -proc cursorTop(container: Container) {.jsfunc.} = - container.setCursorY(container.fromy) +proc cursorTop(container: Container, i = 1) {.jsfunc.} = + let i = clamp(i - 1, 0, container.height - 1) + container.setCursorY(container.fromy + i) proc cursorMiddle(container: Container) {.jsfunc.} = container.setCursorY(container.fromy + (container.height - 2) div 2) -proc cursorBottom(container: Container) {.jsfunc.} = - container.setCursorY(container.fromy + container.height - 1) +proc cursorBottom(container: Container, i = 1) {.jsfunc.} = + let i = clamp(i, 0, container.height) + container.setCursorY(container.fromy + container.height - i) proc cursorLeftEdge(container: Container) {.jsfunc.} = container.setCursorX(container.fromx) @@ -628,29 +630,30 @@ proc cursorMiddleColumn(container: Container) {.jsfunc.} = proc cursorRightEdge(container: Container) {.jsfunc.} = container.setCursorX(container.fromx + container.width - 1) -proc scrollDown(container: Container) {.jsfunc.} = +proc scrollDown(container: Container, n = 1) {.jsfunc.} = if container.fromy + container.height < container.numLines: - container.setFromY(container.fromy + 1) + container.setFromY(container.fromy + n) if container.fromy > container.cursory: - container.cursorDown() + container.cursorDown(container.fromy - container.cursory) else: - container.cursorDown() + container.cursorDown(n) -proc scrollUp(container: Container) {.jsfunc.} = +proc scrollUp(container: Container, n = 1) {.jsfunc.} = if container.fromy > 0: - container.setFromY(container.fromy - 1) + container.setFromY(container.fromy - n) if container.fromy + container.height <= container.cursory: - container.cursorUp() + container.cursorUp(container.cursory - container.fromy - + container.height + 1) else: - container.cursorUp() + container.cursorUp(n) -proc scrollRight(container: Container) {.jsfunc.} = - if container.fromx + container.width < container.maxScreenWidth(): - container.setFromX(container.fromx + 1) +proc scrollRight(container: Container, n = 1) {.jsfunc.} = + if container.fromx + container.width + n <= container.maxScreenWidth(): + container.setFromX(container.fromx + n) -proc scrollLeft(container: Container) {.jsfunc.} = - if container.fromx > 0: - container.setFromX(container.fromx - 1) +proc scrollLeft(container: Container, n = 1) {.jsfunc.} = + if container.fromx - n >= 0: + container.setFromX(container.fromx - n) proc alert(container: Container, msg: string) = container.triggerEvent(ContainerEvent(t: ALERT, msg: msg)) @@ -742,25 +745,29 @@ proc onMatch(container: Container, res: BufferMatch, refresh: bool) = container.needslines = true container.hlon = false -proc cursorNextMatch*(container: Container, regex: Regex, wrap, refresh: bool): - EmptyPromise {.discardable.} = +proc cursorNextMatch*(container: Container, regex: Regex, wrap, refresh: bool, + n: int): EmptyPromise {.discardable.} = if container.select.open: - container.select.cursorNextMatch(regex, wrap) + #TODO + for _ in 0 ..< n: + container.select.cursorNextMatch(regex, wrap) return newResolvedPromise() else: return container.iface - .findNextMatch(regex, container.cursorx, container.cursory, wrap) + .findNextMatch(regex, container.cursorx, container.cursory, wrap, n) .then(proc(res: BufferMatch) = container.onMatch(res, refresh)) -proc cursorPrevMatch*(container: Container, regex: Regex, wrap, refresh: bool): - EmptyPromise {.discardable.} = +proc cursorPrevMatch*(container: Container, regex: Regex, wrap, refresh: bool, + n: int): EmptyPromise {.discardable.} = if container.select.open: - container.select.cursorPrevMatch(regex, wrap) + #TODO + for _ in 0 ..< n: + container.select.cursorPrevMatch(regex, wrap) return newResolvedPromise() else: return container.iface - .findPrevMatch(regex, container.cursorx, container.cursory, wrap) + .findPrevMatch(regex, container.cursorx, container.cursory, wrap, n) .then(proc(res: BufferMatch) = container.onMatch(res, refresh)) diff --git a/src/local/pager.nim b/src/local/pager.nim index 79511f86..eb3f0ca0 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -141,21 +141,21 @@ proc getter(ctx: JSContext, pager: Pager, s: string): Option[JSValue] return some(fun) return some(val) -proc searchNext(pager: Pager) {.jsfunc.} = +proc searchNext(pager: Pager, n = 1) {.jsfunc.} = if pager.regex.isSome: let wrap = pager.config.search.wrap if not pager.reverseSearch: - pager.container.cursorNextMatch(pager.regex.get, wrap, true) + pager.container.cursorNextMatch(pager.regex.get, wrap, true, n) else: - pager.container.cursorPrevMatch(pager.regex.get, wrap, true) + pager.container.cursorPrevMatch(pager.regex.get, wrap, true, n) -proc searchPrev(pager: Pager) {.jsfunc.} = +proc searchPrev(pager: Pager, n = 1) {.jsfunc.} = if pager.regex.isSome: let wrap = pager.config.search.wrap if not pager.reverseSearch: - pager.container.cursorPrevMatch(pager.regex.get, wrap, true) + pager.container.cursorPrevMatch(pager.regex.get, wrap, true, n) else: - pager.container.cursorNextMatch(pager.regex.get, wrap, true) + pager.container.cursorNextMatch(pager.regex.get, wrap, true, n) proc getLineHist(pager: Pager, mode: LineMode): LineHistory = if pager.linehist[mode] == nil: @@ -778,9 +778,9 @@ proc updateReadLineISearch(pager: Pager, linemode: LineMode) = pager.container.hlon = true let wrap = pager.config.search.wrap return if linemode == ISEARCH_F: - pager.container.cursorNextMatch(pager.iregex.get, wrap, false) + pager.container.cursorNextMatch(pager.iregex.get, wrap, false, 1) else: - pager.container.cursorPrevMatch(pager.iregex.get, wrap, false) + pager.container.cursorPrevMatch(pager.iregex.get, wrap, false, 1) of FINISH: pager.regex = pager.checkRegex(pager.iregex) pager.reverseSearch = linemode == ISEARCH_B diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 4ab09c20..d6c00ef9 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -463,16 +463,20 @@ proc findNextLink*(buffer: Buffer, cursorx, cursory: int): tuple[x, y: int] {.pr inc i return (-1, -1) -proc findPrevMatch*(buffer: Buffer, regex: Regex, cursorx, cursory: int, wrap: bool): BufferMatch {.proxy.} = +proc findPrevMatch*(buffer: Buffer, regex: Regex, cursorx, cursory: int, + wrap: bool, n: int): BufferMatch {.proxy.} = if cursory >= buffer.lines.len: return var y = cursory let b = buffer.cursorBytes(y, cursorx) let res = regex.exec(buffer.lines[y].str, 0, b) + var numfound = 0 if res.success and res.captures.len > 0: let cap = res.captures[^1] let x = buffer.lines[y].str.width(0, cap.s) let str = buffer.lines[y].str.substr(cap.s, cap.e - 1) - return BufferMatch(success: true, x: x, y: y, str: str) + inc numfound + if numfound >= n: + return BufferMatch(success: true, x: x, y: y, str: str) dec y while true: if y < 0: @@ -485,21 +489,27 @@ proc findPrevMatch*(buffer: Buffer, regex: Regex, cursorx, cursory: int, wrap: b let cap = res.captures[^1] let x = buffer.lines[y].str.width(0, cap.s) let str = buffer.lines[y].str.substr(cap.s, cap.e - 1) - return BufferMatch(success: true, x: x, y: y, str: str) + inc numfound + if numfound >= n: + return BufferMatch(success: true, x: x, y: y, str: str) if y == cursory: break dec y -proc findNextMatch*(buffer: Buffer, regex: Regex, cursorx, cursory: int, wrap: bool): BufferMatch {.proxy.} = +proc findNextMatch*(buffer: Buffer, regex: Regex, cursorx, cursory: int, + wrap: bool, n: int): BufferMatch {.proxy.} = if cursory >= buffer.lines.len: return var y = cursory let b = buffer.cursorBytes(y, cursorx + 1) let res = regex.exec(buffer.lines[y].str, b, buffer.lines[y].str.len) + var numfound = 0 if res.success and res.captures.len > 0: let cap = res.captures[0] let x = buffer.lines[y].str.width(0, cap.s) let str = buffer.lines[y].str.substr(cap.s, cap.e - 1) - return BufferMatch(success: true, x: x, y: y, str: str) + inc numfound + if numfound >= n: + return BufferMatch(success: true, x: x, y: y, str: str) inc y while true: if y > buffer.lines.high: @@ -512,7 +522,9 @@ proc findNextMatch*(buffer: Buffer, regex: Regex, cursorx, cursory: int, wrap: b let cap = res.captures[0] let x = buffer.lines[y].str.width(0, cap.s) let str = buffer.lines[y].str.substr(cap.s, cap.e - 1) - return BufferMatch(success: true, x: x, y: y, str: str) + inc numfound + if numfound >= n: + return BufferMatch(success: true, x: x, y: y, str: str) if y == cursory: break inc y |