about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-09-26 16:52:57 +0200
committerbptato <nincsnevem662@gmail.com>2023-09-26 16:54:46 +0200
commit2b47c6f5ac8d41a8025c10d02da4d6090e616a68 (patch)
treee97afd43206d14b058813d159dc1f53c59b8f20b /src
parentee17e946c53e6ca807dea2df04f8f2b9eedd754f (diff)
downloadchawan-2b47c6f5ac8d41a8025c10d02da4d6090e616a68.tar.gz
Add precnum support to more functions
Diffstat (limited to 'src')
-rw-r--r--src/local/container.nim59
-rw-r--r--src/local/pager.nim16
-rw-r--r--src/server/buffer.nim24
3 files changed, 59 insertions, 40 deletions
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