about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-06-03 20:29:10 +0200
committerbptato <nincsnevem662@gmail.com>2024-06-03 20:29:10 +0200
commit3e12a95ab34e120fb958ba0eeebaada5def7cd11 (patch)
treeff46a2d73d32c2a2a72df82801483dc7fd0134a2 /src
parent5acbab703ba074e20dbc0ce729d9f57f467901e0 (diff)
downloadchawan-3e12a95ab34e120fb958ba0eeebaada5def7cd11.tar.gz
js: improve jsregex interface
It's easier to just use nested seqs here.

(This also fixes reverse-search highlighting the last capture group
instead of the whole match.)
Diffstat (limited to 'src')
-rw-r--r--src/js/jsregex.nim29
-rw-r--r--src/server/buffer.nim26
2 files changed, 25 insertions, 30 deletions
diff --git a/src/js/jsregex.nim b/src/js/jsregex.nim
index f24633d1..9fb09872 100644
--- a/src/js/jsregex.nim
+++ b/src/js/jsregex.nim
@@ -10,23 +10,19 @@ export LREFlags
 type
   Regex* = object
     bytecode: seq[uint8]
-    buf: string
+    when defined(debug):
+      buf: string
 
-  RegexCapture* = tuple # start, end, index
+  RegexCapture* = tuple # start, end
     s, e: int
-    i: int32
 
   RegexResult* = object
     success*: bool
-    captures*: seq[RegexCapture]
+    captures*: seq[seq[RegexCapture]]
 
-  RegexReplace* = object
-    regex: Regex
-    rule: string
-    global: bool
-
-func `$`*(regex: Regex): string =
-  regex.buf
+when defined(debug):
+  func `$`*(regex: Regex): string =
+    regex.buf
 
 # this is hardcoded into quickjs, so we must override it here.
 proc lre_realloc(opaque, p: pointer; size: csize_t): pointer {.exportc.} =
@@ -43,10 +39,9 @@ proc compileRegex*(buf: string; flags: LREFlags = {}): Result[Regex, string] =
   var bcseq = newSeqUninitialized[uint8](plen)
   copyMem(addr bcseq[0], bytecode, plen)
   dealloc(bytecode)
-  let regex = Regex(
-    buf: buf,
-    bytecode: bcseq
-  )
+  var regex = Regex(bytecode: bcseq)
+  when defined(debug):
+    regex.buf = buf
   return ok(regex)
 
 func countBackslashes(buf: string; i: int): int =
@@ -133,13 +128,15 @@ proc exec*(regex: Regex; str: string; start = 0; length = -1; nocaps = false):
     result.success = true
     if captureCount == 0 or nocaps:
       break
+    var caps: seq[RegexCapture] = @[]
     let cstrAddress = cast[int](cstr)
     let ps = start
     start = capture[1] - cstrAddress
     for i in 0 ..< captureCount:
       let s = capture[i * 2] - cstrAddress
       let e = capture[i * 2 + 1] - cstrAddress
-      result.captures.add((s, e, i))
+      caps.add((s, e))
+    result.captures.add(caps)
     if LRE_FLAG_GLOBAL notin flags:
       break
     if start >= str.len:
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index 6b214b4e..9a141135 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -594,8 +594,8 @@ proc findPrevMatch*(buffer: Buffer; regex: Regex; cursorx, cursory: int;
   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]
+  if res.captures.len > 0:
+    let cap = res.captures[^1][0]
     let x = buffer.lines[y].str.width(0, cap.s)
     let str = buffer.lines[y].str.substr(cap.s, cap.e - 1)
     inc numfound
@@ -609,8 +609,8 @@ proc findPrevMatch*(buffer: Buffer; regex: Regex; cursorx, cursory: int;
       else:
         break
     let res = regex.exec(buffer.lines[y].str)
-    if res.success and res.captures.len > 0:
-      let cap = res.captures[^1]
+    if res.captures.len > 0:
+      let cap = res.captures[^1][0]
       let x = buffer.lines[y].str.width(0, cap.s)
       let str = buffer.lines[y].str.substr(cap.s, cap.e - 1)
       inc numfound
@@ -628,7 +628,7 @@ proc findNextMatch*(buffer: Buffer; regex: Regex; cursorx, cursory: int;
   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 cap = res.captures[0][0]
     let x = buffer.lines[y].str.width(0, cap.s)
     let str = buffer.lines[y].str.substr(cap.s, cap.e - 1)
     inc numfound
@@ -643,7 +643,7 @@ proc findNextMatch*(buffer: Buffer; regex: Regex; cursorx, cursory: int;
         break
     let res = regex.exec(buffer.lines[y].str)
     if res.success and res.captures.len > 0:
-      let cap = res.captures[0]
+      let cap = res.captures[0][0]
       let x = buffer.lines[y].str.width(0, cap.s)
       let str = buffer.lines[y].str.substr(cap.s, cap.e - 1)
       inc numfound
@@ -1779,10 +1779,8 @@ proc markURL*(buffer: Buffer; schemes: seq[string]) {.proxy.} =
           var data = ""
           var j = 0
           for cap in res.captures.mitems:
-            if cap.i != 0:
-              continue
-            let capLen = cap.e - cap.s
-            while j < cap.s:
+            let capLen = cap[0].e - cap[0].s
+            while j < cap[0].s:
               case (let c = text.data[j]; c)
               of '<':
                 data &= "&lt;"
@@ -1802,13 +1800,13 @@ proc markURL*(buffer: Buffer; schemes: seq[string]) {.proxy.} =
               else:
                 data &= c
               inc j
-            cap.s += offset
-            cap.e += offset
+            cap[0].s += offset
+            cap[0].e += offset
             let s = text.data[j ..< j + capLen]
             let news = "<a href=\"" & s & "\">" & s.htmlEscape() & "</a>"
             data &= news
-            j += cap.e - cap.s
-            offset += news.len - (cap.e - cap.s)
+            j += cap[0].e - cap[0].s
+            offset += news.len - (cap[0].e - cap[0].s)
           while j < text.data.len:
             case (let c = text.data[j]; c)
             of '<': data &= "&lt;"