about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/config.md6
-rw-r--r--res/config.toml2
-rw-r--r--src/config/config.nim2
-rw-r--r--src/local/pager.nim5
-rw-r--r--src/utils/regexutils.nim23
-rw-r--r--todo1
6 files changed, 25 insertions, 14 deletions
diff --git a/doc/config.md b/doc/config.md
index b55cf74b..9b9bcae1 100644
--- a/doc/config.md
+++ b/doc/config.md
@@ -191,9 +191,11 @@ Following is a list of search options:
 
 <tr>
 <td>ignore-case</td>
-<td>boolean</td>
+<td>"auto" / boolean</td>
 <td>When set to true, document-wide searches are case-insensitive by
-default.<br>
+default. When set to "auto", searches are only case-sensitive when the search
+term includes a capital letter.<br>
+Defaults to "auto".<br>
 Note: this can also be overridden inline in the search bar (vim-style),
 with the escape sequences `\c` (ignore case) and `\C` (strict case). See
 [search mode](#search-mode) for details.)</td>
diff --git a/res/config.toml b/res/config.toml
index d93eb067..6e05b816 100644
--- a/res/config.toml
+++ b/res/config.toml
@@ -240,7 +240,7 @@ cookie = false
 
 [search]
 wrap = true
-ignore-case = true
+ignore-case = "auto"
 
 [encoding]
 document-charset = ["utf-8", "sjis", "euc-jp", "latin2"]
diff --git a/src/config/config.nim b/src/config/config.nim
index 1ab77f01..3d4a0217 100644
--- a/src/config/config.nim
+++ b/src/config/config.nim
@@ -81,7 +81,7 @@ type
 
   SearchConfig = object
     wrap* {.jsgetset.}: bool
-    ignore_case* {.jsgetset.}: bool
+    ignore_case* {.jsgetset.}: Option[bool]
 
   EncodingConfig = object
     display_charset* {.jsgetset.}: Option[Charset]
diff --git a/src/local/pager.nim b/src/local/pager.nim
index dfa7d014..de990767 100644
--- a/src/local/pager.nim
+++ b/src/local/pager.nim
@@ -1327,10 +1327,7 @@ proc checkRegex(pager: Pager; regex: Result[Regex, string]): Opt[Regex] =
   return ok(regex.get)
 
 proc compileSearchRegex(pager: Pager; s: string): Result[Regex, string] =
-  var flags = {LRE_FLAG_UNICODE}
-  if pager.config.search.ignore_case:
-    flags.incl(LRE_FLAG_IGNORECASE)
-  return compileSearchRegex(s, flags)
+  return compileSearchRegex(s, pager.config.search.ignore_case)
 
 proc updateReadLineISearch(pager: Pager; linemode: LineMode) =
   let lineedit = pager.lineedit
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)
diff --git a/todo b/todo
index 0ebbcfc4..9c2d3de7 100644
--- a/todo
+++ b/todo
@@ -32,7 +32,6 @@ buffer:
 	  container is reading...
 - important: improve sandboxing
 	* sandbox more built-in CGI protocol handlers
-	* fix newFormData with seccomp
 - configurable/better url filtering in loader
 - when the log buffer crashes, print its contents to stderr
 	* easiest way seems to be to just dump its cache file