diff options
author | bptato <nincsnevem662@gmail.com> | 2024-06-03 20:42:16 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-06-03 21:15:44 +0200 |
commit | 3aa8f1e0694d1606c3f3795f8b83e8a82caacd3e (patch) | |
tree | 9708d4599360116a96e4aa7f983eea387e8437c6 /src/utils | |
parent | 3e12a95ab34e120fb958ba0eeebaada5def7cd11 (diff) | |
download | chawan-3aa8f1e0694d1606c3f3795f8b83e8a82caacd3e.tar.gz |
Move JS wrapper into Monoucha
Operation "modularize Chawan somewhat" part 3
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/luwrap.nim | 5 | ||||
-rw-r--r-- | src/utils/regexutils.nim | 64 |
2 files changed, 67 insertions, 2 deletions
diff --git a/src/utils/luwrap.nim b/src/utils/luwrap.nim index 853d3015..7ccb2c51 100644 --- a/src/utils/luwrap.nim +++ b/src/utils/luwrap.nim @@ -2,7 +2,7 @@ import std/algorithm import std/strutils import std/unicode -import bindings/libunicode +import monoucha/libunicode import utils/charcategory proc passRealloc(opaque, p: pointer; size: csize_t): pointer {.cdecl.} = @@ -50,7 +50,8 @@ proc capitalizeLU*(s: string): string = result = newStringOfCap(s.len) var wordStart = true for r in s.runes: - if lre_is_space(uint32(r)) == 1: + if uint32(r) < 256 and char(r) in AsciiWhitespace or + lre_is_space_non_ascii(uint32(r)) == 1: wordStart = true result &= $r elif wordStart: diff --git a/src/utils/regexutils.nim b/src/utils/regexutils.nim new file mode 100644 index 00000000..ab7308f6 --- /dev/null +++ b/src/utils/regexutils.nim @@ -0,0 +1,64 @@ +import types/opt + +import monoucha/jsregex +import monoucha/libregexp + +func countBackslashes(buf: string; i: int): int = + var j = 0 + for i in countdown(i, 0): + if buf[i] != '\\': + break + inc j + return j + +# ^abcd -> ^abcd +# efgh$ -> efgh$ +# ^ijkl$ -> ^ijkl$ +# mnop -> ^mnop$ +proc compileMatchRegex*(buf: string): Result[Regex, string] = + if buf.len == 0: + return compileRegex(buf) + if buf[0] == '^': + return compileRegex(buf) + if buf[^1] == '$': + # Check whether the final dollar sign is escaped. + if buf.len == 1 or buf[^2] != '\\': + return compileRegex(buf) + let j = buf.countBackslashes(buf.high - 2) + if j mod 2 == 1: # odd, because we do not count the last backslash + return compileRegex(buf) + # escaped. proceed as if no dollar sign was at the end + if buf[^1] == '\\': + # Check if the regex contains an invalid trailing backslash. + let j = buf.countBackslashes(buf.high - 1) + if j mod 2 != 1: # odd, because we do not count the last backslash + return err("unexpected end") + var buf2 = "^" + buf2 &= buf + buf2 &= "$" + return compileRegex(buf2) + +proc compileSearchRegex*(str: string; defaultFlags: LREFlags): + Result[Regex, string] = + # Emulate vim's \c/\C: override defaultFlags if one is found, then remove it + # from str. + # Also, replace \< and \> with \b as (a bit sloppy) vi emulation. + var flags = defaultFlags + var s = newStringOfCap(str.len) + var quot = false + for c in str: + if quot: + quot = false + case c + of 'c': flags.incl(LRE_FLAG_IGNORECASE) + of 'C': flags.excl(LRE_FLAG_IGNORECASE) + of '<', '>': s &= "\\b" + else: s &= '\\' & c + elif c == '\\': + quot = true + else: + s &= c + if quot: + s &= '\\' + flags.incl(LRE_FLAG_GLOBAL) # for easy backwards matching + return compileRegex(s, flags) |