about summary refs log tree commit diff stats
path: root/src/utils/regexutils.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-07-16 18:09:51 +0200
committerbptato <nincsnevem662@gmail.com>2024-07-16 18:09:51 +0200
commit88a43edc6a915890a1864e912669e258b45a0889 (patch)
tree21a7b4748941f66b0e7dcc0dfc51f5348ffa3b4b /src/utils/regexutils.nim
parent6a06e111ebfbb8bbf69f4539863ae2d5d62794f9 (diff)
downloadchawan-88a43edc6a915890a1864e912669e258b45a0889.tar.gz
config: support smart case
and enable it by default.
Diffstat (limited to 'src/utils/regexutils.nim')
-rw-r--r--src/utils/regexutils.nim23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/utils/regexutils.nim b/src/utils/regexutils.nim
index ab7308f6..7c09625f 100644
--- a/src/utils/regexutils.nim
+++ b/src/utils/regexutils.nim
@@ -1,7 +1,9 @@
-import types/opt
+import std/options
 
 import monoucha/jsregex
 import monoucha/libregexp
+import types/opt
+import utils/charcategory
 
 func countBackslashes(buf: string; i: int): int =
   var j = 0
@@ -38,20 +40,29 @@ proc compileMatchRegex*(buf: string): Result[Regex, string] =
   buf2 &= "$"
   return compileRegex(buf2)
 
-proc compileSearchRegex*(str: string; defaultFlags: LREFlags):
+proc compileSearchRegex*(str: string; ignoreCase: Option[bool]):
     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 flags = {LRE_FLAG_UNICODE}
+  if ignoreCase.isSome and ignoreCase.get:
+    flags.incl(LRE_FLAG_IGNORECASE)
   var s = newStringOfCap(str.len)
   var quot = false
+  var hasUpper = false
+  var hasC = false
   for c in str:
+    hasUpper = hasUpper or c in AsciiUpperAlpha
     if quot:
       quot = false
       case c
-      of 'c': flags.incl(LRE_FLAG_IGNORECASE)
-      of 'C': flags.excl(LRE_FLAG_IGNORECASE)
+      of 'c':
+        flags.incl(LRE_FLAG_IGNORECASE)
+        hasC = true
+      of 'C':
+        flags.excl(LRE_FLAG_IGNORECASE)
+        hasC = true
       of '<', '>': s &= "\\b"
       else: s &= '\\' & c
     elif c == '\\':
@@ -60,5 +71,7 @@ proc compileSearchRegex*(str: string; defaultFlags: LREFlags):
       s &= c
   if quot:
     s &= '\\'
+  if not hasC and not hasUpper and ignoreCase.isNone:
+    flags.incl(LRE_FLAG_IGNORECASE) # smart case
   flags.incl(LRE_FLAG_GLOBAL) # for easy backwards matching
   return compileRegex(s, flags)