about summary refs log tree commit diff stats
path: root/src/utils/twtstr.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-12-19 12:26:25 +0100
committerbptato <nincsnevem662@gmail.com>2021-12-19 12:26:57 +0100
commit9a3cd69ea8b99b04cb64800b75f4d2aa3e81fc84 (patch)
tree0a5d2dd69a4435ea64cabc4eb638e0e0ad09d586 /src/utils/twtstr.nim
parent3360c8b7d3ca98712e7440d5f8d73705afc03dc9 (diff)
downloadchawan-9a3cd69ea8b99b04cb64800b75f4d2aa3e81fc84.tar.gz
More configuration options
Diffstat (limited to 'src/utils/twtstr.nim')
-rw-r--r--src/utils/twtstr.nim131
1 files changed, 69 insertions, 62 deletions
diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim
index 2ec9967c..52abade7 100644
--- a/src/utils/twtstr.nim
+++ b/src/utils/twtstr.nim
@@ -533,60 +533,6 @@ func is_dwidth(r: Rune): bool =
       (ucs >= 0x20000 and ucs <= 0x2fffd) or
       (ucs >= 0x30000 and ucs <= 0x3fffd)))
 
-func makewidthtable(): array[0..0x10FFFF, byte] =
-  for r in low(char)..high(char):
-    if r.isControlChar():
-      result[int(r)] = 2 #TODO this should be 0
-    else:
-      result[int(r)] = 1
-
-  var i = 0
-  var next_combining = combining[i]
-  for ucs in 256..0x10FFFF:
-    if ucs >= next_combining[0]:
-      if ucs <= next_combining[1]:
-        result[ucs] = 0
-        continue
-      elif i + 1 < combining.len:
-        inc i
-        next_combining = combining[i]
-
-    if Rune(ucs).is_dwidth():
-      result[ucs] = 2
-    else:
-      result[ucs] = 1
-
-# compute lookup table on startup
-# TODO: we could have an option to store it in the executable but honestly I
-# don't see the need to
-let width_table = makewidthtable()
-
-{.push boundChecks:off.}
-func width*(r: Rune): int =
-  {.cast(noSideEffect).}:
-    return int(width_table[int(r)])
-
-func width*(s: string): int =
-  for r in s.runes():
-    result += width(r)
-
-func width*(s: seq[Rune]): int =
-  for r in s:
-    result += width(r)
-
-func width*(s: seq[Rune], min, max: int): int =
-  var i = min
-  var mi = min(max, s.len)
-  while i < mi:
-    result += width(s[i])
-    inc i
-
-func width*(s: seq[Rune], min: int): int =
-  var i = min
-  while i < s.len:
-    result += width(s[i])
-    inc i
-
 # sorted list of non-overlapping intervals of East Asian Ambiguous characters,
 # generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c"
 
@@ -674,18 +620,79 @@ func bisearch(ucs: Rune, table: openarray[(int, int)]): bool =
       return true
   return false
 
-
-func mk_wcwidth_cjk(r: Rune): int =
+func is_dwidth_cjk(r: Rune): bool =
   # binary search in table of non-spacing characters
   if bisearch(r, ambiguous):
-    return 2;
+    return true
 
-  return r.width();
+  return r.is_dwidth()
 
-func mk_wcswidth_cjk(s: string): int =
-  for r in s.runes:
-    result += mk_wcwidth_cjk(r)
-  return result
+# compute lookup table on startup
+var width_table*: array[0..0x10FFFF, byte]
+
+func makewidthtable*(cjk: bool): array[0..0x10FFFF, byte] =
+  for r in low(char)..high(char):
+    if r.isControlChar():
+      result[int(r)] = 2 #TODO this should be 0
+    else:
+      result[int(r)] = 1
+
+  var i = 0
+  var next_combining = combining[i]
+  if cjk:
+    for ucs in 256..0x10FFFF:
+      if ucs >= next_combining[0]:
+        if ucs <= next_combining[1]:
+          result[ucs] = 0
+          continue
+        elif i + 1 < combining.len:
+          inc i
+          next_combining = combining[i]
+
+      if Rune(ucs).is_dwidth_cjk():
+        result[ucs] = 2
+      else:
+        result[ucs] = 1
+  else:
+    for ucs in 256..0x10FFFF:
+      if ucs >= next_combining[0]:
+        if ucs <= next_combining[1]:
+          result[ucs] = 0
+          continue
+        elif i + 1 < combining.len:
+          inc i
+          next_combining = combining[i]
+
+      if Rune(ucs).is_dwidth():
+        result[ucs] = 2
+      else:
+        result[ucs] = 1
+
+{.push boundChecks:off.}
+func width*(r: Rune): int =
+  {.cast(noSideEffect).}:
+    return int(width_table[int(r)])
+
+func width*(s: string): int =
+  for r in s.runes():
+    result += width(r)
+
+func width*(s: seq[Rune]): int =
+  for r in s:
+    result += width(r)
+
+func width*(s: seq[Rune], min, max: int): int =
+  var i = min
+  var mi = min(max, s.len)
+  while i < mi:
+    result += width(s[i])
+    inc i
+
+func width*(s: seq[Rune], min: int): int =
+  var i = min
+  while i < s.len:
+    result += width(s[i])
+    inc i
 
 const CanHaveDakuten = "かきくけこさしすせそたちつてとはひふへほカキクケコサシスセソタチツテトハヒフヘホ".toRunes()