@fugood/llama.node 0.3.12 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/bin/darwin/arm64/llama-node.node +0 -0
  2. package/bin/darwin/x64/llama-node.node +0 -0
  3. package/bin/linux/arm64/llama-node.node +0 -0
  4. package/bin/linux/x64/llama-node.node +0 -0
  5. package/bin/linux-cuda/arm64/llama-node.node +0 -0
  6. package/bin/linux-cuda/x64/llama-node.node +0 -0
  7. package/bin/linux-vulkan/arm64/llama-node.node +0 -0
  8. package/bin/linux-vulkan/x64/llama-node.node +0 -0
  9. package/bin/win32/arm64/llama-node.node +0 -0
  10. package/bin/win32/arm64/node.lib +0 -0
  11. package/bin/win32/x64/llama-node.node +0 -0
  12. package/bin/win32/x64/node.lib +0 -0
  13. package/bin/win32-vulkan/arm64/llama-node.node +0 -0
  14. package/bin/win32-vulkan/arm64/node.lib +0 -0
  15. package/bin/win32-vulkan/x64/llama-node.node +0 -0
  16. package/bin/win32-vulkan/x64/node.lib +0 -0
  17. package/lib/binding.ts +2 -1
  18. package/package.json +1 -1
  19. package/src/LlamaCompletionWorker.cpp +14 -0
  20. package/src/LlamaContext.cpp +110 -79
  21. package/src/LlamaContext.h +1 -1
  22. package/src/common.hpp +1 -2
  23. package/src/llama.cpp/.github/workflows/build.yml +95 -13
  24. package/src/llama.cpp/.github/workflows/docker.yml +2 -0
  25. package/src/llama.cpp/.github/workflows/labeler.yml +1 -1
  26. package/src/llama.cpp/.github/workflows/server.yml +2 -0
  27. package/src/llama.cpp/common/CMakeLists.txt +23 -6
  28. package/src/llama.cpp/common/arg.cpp +292 -14
  29. package/src/llama.cpp/common/chat.cpp +1128 -315
  30. package/src/llama.cpp/common/chat.h +135 -0
  31. package/src/llama.cpp/common/common.cpp +27 -171
  32. package/src/llama.cpp/common/common.h +41 -73
  33. package/src/llama.cpp/common/json-schema-to-grammar.cpp +4 -5
  34. package/src/llama.cpp/common/json-schema-to-grammar.h +0 -1
  35. package/src/llama.cpp/common/llguidance.cpp +3 -3
  36. package/src/llama.cpp/common/log.cpp +1 -0
  37. package/src/llama.cpp/common/log.h +2 -1
  38. package/src/llama.cpp/common/{chat-template.hpp → minja/chat-template.hpp} +21 -7
  39. package/src/llama.cpp/common/{minja.hpp → minja/minja.hpp} +61 -14
  40. package/src/llama.cpp/common/ngram-cache.cpp +1 -0
  41. package/src/llama.cpp/common/sampling.cpp +93 -49
  42. package/src/llama.cpp/common/speculative.cpp +6 -5
  43. package/src/llama.cpp/common/speculative.h +1 -1
  44. package/src/llama.cpp/docs/build.md +47 -9
  45. package/src/llama.cpp/examples/cvector-generator/cvector-generator.cpp +3 -1
  46. package/src/llama.cpp/examples/embedding/embedding.cpp +1 -0
  47. package/src/llama.cpp/examples/export-lora/export-lora.cpp +4 -2
  48. package/src/llama.cpp/examples/imatrix/imatrix.cpp +4 -4
  49. package/src/llama.cpp/examples/llama-bench/llama-bench.cpp +6 -5
  50. package/src/llama.cpp/examples/llama.android/llama/src/main/cpp/CMakeLists.txt +1 -1
  51. package/src/llama.cpp/examples/llama.android/llama/src/main/cpp/llama-android.cpp +1 -1
  52. package/src/llama.cpp/examples/llava/CMakeLists.txt +7 -0
  53. package/src/llama.cpp/examples/llava/clip.cpp +373 -107
  54. package/src/llama.cpp/examples/llava/clip.h +19 -3
  55. package/src/llama.cpp/examples/llava/gemma3-cli.cpp +341 -0
  56. package/src/llama.cpp/examples/llava/llava.cpp +4 -2
  57. package/src/llama.cpp/examples/llava/minicpmv-cli.cpp +30 -11
  58. package/src/llama.cpp/examples/lookahead/lookahead.cpp +1 -0
  59. package/src/llama.cpp/examples/main/main.cpp +73 -28
  60. package/src/llama.cpp/examples/parallel/parallel.cpp +1 -0
  61. package/src/llama.cpp/examples/passkey/passkey.cpp +1 -0
  62. package/src/llama.cpp/examples/perplexity/perplexity.cpp +1 -0
  63. package/src/llama.cpp/examples/quantize/quantize.cpp +1 -0
  64. package/src/llama.cpp/examples/run/linenoise.cpp/linenoise.cpp +882 -237
  65. package/src/llama.cpp/examples/run/linenoise.cpp/linenoise.h +35 -26
  66. package/src/llama.cpp/examples/run/run.cpp +115 -79
  67. package/src/llama.cpp/examples/server/CMakeLists.txt +1 -1
  68. package/src/llama.cpp/examples/server/httplib.h +381 -292
  69. package/src/llama.cpp/examples/server/server.cpp +134 -128
  70. package/src/llama.cpp/examples/server/utils.hpp +95 -106
  71. package/src/llama.cpp/examples/sycl/run-llama2.sh +2 -2
  72. package/src/llama.cpp/examples/tts/tts.cpp +251 -142
  73. package/src/llama.cpp/ggml/CMakeLists.txt +13 -1
  74. package/src/llama.cpp/ggml/include/ggml-alloc.h +1 -1
  75. package/src/llama.cpp/ggml/include/ggml-backend.h +3 -3
  76. package/src/llama.cpp/ggml/include/ggml-cpu.h +4 -1
  77. package/src/llama.cpp/ggml/include/ggml-metal.h +1 -1
  78. package/src/llama.cpp/ggml/include/ggml-vulkan.h +0 -2
  79. package/src/llama.cpp/ggml/include/ggml.h +6 -2
  80. package/src/llama.cpp/ggml/src/CMakeLists.txt +10 -7
  81. package/src/llama.cpp/ggml/src/ggml-alloc.c +24 -15
  82. package/src/llama.cpp/ggml/src/ggml-backend-impl.h +1 -1
  83. package/src/llama.cpp/ggml/src/ggml-backend-reg.cpp +58 -54
  84. package/src/llama.cpp/ggml/src/ggml-backend.cpp +10 -8
  85. package/src/llama.cpp/ggml/src/ggml-cann/ggml-cann.cpp +3 -2
  86. package/src/llama.cpp/ggml/src/ggml-cann/kernels/dup.cpp +3 -5
  87. package/src/llama.cpp/ggml/src/ggml-common.h +0 -2
  88. package/src/llama.cpp/ggml/src/ggml-cpu/CMakeLists.txt +132 -17
  89. package/src/llama.cpp/ggml/src/ggml-cpu/amx/amx.cpp +2 -1
  90. package/src/llama.cpp/ggml/src/ggml-cpu/cpu-feats-x86.cpp +4 -0
  91. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu-aarch64.cpp +2 -1
  92. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu-impl.h +156 -11
  93. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu-quants.c +2235 -641
  94. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu.c +1572 -198
  95. package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu.cpp +24 -5
  96. package/src/llama.cpp/ggml/src/ggml-cpu/kleidiai/kernels.cpp +259 -0
  97. package/src/llama.cpp/ggml/src/ggml-cpu/kleidiai/kernels.h +61 -0
  98. package/src/llama.cpp/ggml/src/ggml-cpu/kleidiai/kleidiai.cpp +288 -0
  99. package/src/llama.cpp/ggml/src/ggml-cpu/kleidiai/kleidiai.h +17 -0
  100. package/src/llama.cpp/ggml/src/ggml-cpu/llamafile/sgemm.cpp +9 -8
  101. package/src/llama.cpp/ggml/src/ggml-cuda/CMakeLists.txt +16 -3
  102. package/src/llama.cpp/ggml/src/ggml-hip/CMakeLists.txt +14 -0
  103. package/src/llama.cpp/ggml/src/ggml-impl.h +1 -1
  104. package/src/llama.cpp/ggml/src/ggml-metal/CMakeLists.txt +4 -5
  105. package/src/llama.cpp/ggml/src/ggml-metal/ggml-metal-impl.h +235 -0
  106. package/src/llama.cpp/ggml/src/ggml-musa/CMakeLists.txt +6 -2
  107. package/src/llama.cpp/ggml/src/ggml-opencl/CMakeLists.txt +1 -0
  108. package/src/llama.cpp/ggml/src/ggml-opencl/ggml-opencl.cpp +246 -120
  109. package/src/llama.cpp/ggml/src/ggml-quants.c +114 -114
  110. package/src/llama.cpp/ggml/src/ggml-rpc/ggml-rpc.cpp +2 -1
  111. package/src/llama.cpp/ggml/src/ggml-sycl/CMakeLists.txt +2 -0
  112. package/src/llama.cpp/ggml/src/ggml-sycl/backend.hpp +1 -0
  113. package/src/llama.cpp/ggml/src/ggml-sycl/common.cpp +17 -0
  114. package/src/llama.cpp/ggml/src/ggml-sycl/common.hpp +51 -10
  115. package/src/llama.cpp/ggml/src/ggml-sycl/convert.cpp +33 -4
  116. package/src/llama.cpp/ggml/src/ggml-sycl/convert.hpp +2 -2
  117. package/src/llama.cpp/ggml/src/ggml-sycl/cpy.cpp +701 -0
  118. package/src/llama.cpp/ggml/src/ggml-sycl/cpy.hpp +11 -0
  119. package/src/llama.cpp/ggml/src/ggml-sycl/dequantize.hpp +55 -0
  120. package/src/llama.cpp/ggml/src/ggml-sycl/dmmv.cpp +136 -4
  121. package/src/llama.cpp/ggml/src/ggml-sycl/getrows.cpp +308 -0
  122. package/src/llama.cpp/ggml/src/ggml-sycl/getrows.hpp +23 -0
  123. package/src/llama.cpp/ggml/src/ggml-sycl/ggml-sycl.cpp +174 -728
  124. package/src/llama.cpp/ggml/src/ggml-sycl/mmvq.cpp +75 -77
  125. package/src/llama.cpp/ggml/src/ggml-sycl/softmax.cpp +3 -0
  126. package/src/llama.cpp/ggml/src/ggml-sycl/sycl_hw.cpp +13 -0
  127. package/src/llama.cpp/ggml/src/ggml-sycl/sycl_hw.hpp +23 -0
  128. package/src/llama.cpp/ggml/src/ggml-vulkan/ggml-vulkan.cpp +949 -602
  129. package/src/llama.cpp/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +37 -3
  130. package/src/llama.cpp/ggml/src/ggml.c +9 -4
  131. package/src/llama.cpp/include/llama.h +32 -14
  132. package/src/llama.cpp/models/ggml-vocab-gpt-4o.gguf.inp +112 -0
  133. package/src/llama.cpp/models/ggml-vocab-gpt-4o.gguf.out +46 -0
  134. package/src/llama.cpp/requirements/requirements-all.txt +1 -0
  135. package/src/llama.cpp/requirements/requirements-tool_bench.txt +12 -0
  136. package/src/llama.cpp/requirements.txt +1 -0
  137. package/src/llama.cpp/src/llama-arch.cpp +21 -0
  138. package/src/llama.cpp/src/llama-arch.h +1 -0
  139. package/src/llama.cpp/src/llama-chat.cpp +1 -0
  140. package/src/llama.cpp/src/llama-grammar.cpp +183 -183
  141. package/src/llama.cpp/src/llama-grammar.h +13 -4
  142. package/src/llama.cpp/src/llama-impl.h +6 -6
  143. package/src/llama.cpp/src/llama-kv-cache.h +2 -1
  144. package/src/llama.cpp/src/llama-mmap.cpp +11 -1
  145. package/src/llama.cpp/src/llama-mmap.h +1 -0
  146. package/src/llama.cpp/src/llama-model.cpp +70 -6
  147. package/src/llama.cpp/src/llama-sampling.cpp +174 -67
  148. package/src/llama.cpp/src/llama-vocab.cpp +12 -0
  149. package/src/llama.cpp/src/llama.cpp +154 -5
  150. package/src/llama.cpp/src/unicode.cpp +9 -2
  151. package/src/llama.cpp/tests/test-backend-ops.cpp +171 -115
  152. package/src/llama.cpp/tests/test-chat-template.cpp +32 -22
  153. package/src/llama.cpp/tests/test-chat.cpp +691 -325
  154. package/src/llama.cpp/tests/test-gguf.cpp +4 -4
  155. package/src/llama.cpp/tests/test-json-schema-to-grammar.cpp +63 -63
  156. package/src/llama.cpp/tests/test-quantize-fns.cpp +1 -9
  157. package/src/llama.cpp/tests/test-sampling.cpp +15 -0
  158. package/src/llama.cpp/Sources/llama/llama.h +0 -4
  159. package/src/llama.cpp/common/chat.hpp +0 -52
@@ -75,7 +75,7 @@
75
75
  *
76
76
  * DSR (Device Status Report)
77
77
  * Sequence: ESC [ 6 n
78
- * Effect: reports the current cusor position as ESC [ n ; m R
78
+ * Effect: reports the current cursor position as ESC [ n ; m R
79
79
  * where n is the row and m is the column
80
80
  *
81
81
  * When multi line mode is enabled, we also use an additional escape
@@ -107,6 +107,7 @@
107
107
 
108
108
  # include <ctype.h>
109
109
  # include <errno.h>
110
+ # include <poll.h>
110
111
  # include <stdio.h>
111
112
  # include <string.h>
112
113
  # include <sys/file.h>
@@ -205,9 +206,9 @@ class File {
205
206
  int fd = -1;
206
207
  };
207
208
 
208
- __attribute__((format(printf, 1, 2)))
209
- /* Debugging function. */
210
209
  #if 0
210
+ /* Debugging function. */
211
+ __attribute__((format(printf, 1, 2)))
211
212
  static void lndebug(const char *fmt, ...) {
212
213
  static File file;
213
214
  if (file.file == nullptr) {
@@ -222,11 +223,469 @@ static void lndebug(const char *fmt, ...) {
222
223
  fflush(file.file);
223
224
  }
224
225
  }
225
- #else
226
- static void lndebug(const char *, ...) {
227
- }
228
226
  #endif
229
227
 
228
+ /* ========================== Encoding functions ============================= */
229
+
230
+ /* Get length of previous UTF8 codepoint */
231
+ static size_t prevUtf8CodePointLen(const char * buf, int pos) {
232
+ int end = pos--;
233
+ while (pos >= 0 && ((unsigned char) buf[pos] & 0xC0) == 0x80) {
234
+ pos--;
235
+ }
236
+ return end - pos;
237
+ }
238
+
239
+ /* Convert UTF8 to Unicode code point */
240
+ static size_t utf8BytesToCodePoint(const char * buf, size_t len, int * cp) {
241
+ if (len) {
242
+ unsigned char byte = buf[0];
243
+ if ((byte & 0x80) == 0) {
244
+ *cp = byte;
245
+ return 1;
246
+ } else if ((byte & 0xE0) == 0xC0) {
247
+ if (len >= 2) {
248
+ *cp = (((unsigned long) (buf[0] & 0x1F)) << 6) | ((unsigned long) (buf[1] & 0x3F));
249
+ return 2;
250
+ }
251
+ } else if ((byte & 0xF0) == 0xE0) {
252
+ if (len >= 3) {
253
+ *cp = (((unsigned long) (buf[0] & 0x0F)) << 12) | (((unsigned long) (buf[1] & 0x3F)) << 6) |
254
+ ((unsigned long) (buf[2] & 0x3F));
255
+ return 3;
256
+ }
257
+ } else if ((byte & 0xF8) == 0xF0) {
258
+ if (len >= 4) {
259
+ *cp = (((unsigned long) (buf[0] & 0x07)) << 18) | (((unsigned long) (buf[1] & 0x3F)) << 12) |
260
+ (((unsigned long) (buf[2] & 0x3F)) << 6) | ((unsigned long) (buf[3] & 0x3F));
261
+ return 4;
262
+ }
263
+ }
264
+ }
265
+ return 0;
266
+ }
267
+
268
+ /* Check if the code is a wide character */
269
+ static const unsigned long wideCharTable[][2] = {
270
+ /* BEGIN: WIDE CHAR TABLE */
271
+ { 0x1100, 0x115F },
272
+ { 0x231A, 0x231B },
273
+ { 0x2329, 0x232A },
274
+ { 0x23E9, 0x23EC },
275
+ { 0x23F0, 0x23F0 },
276
+ { 0x23F3, 0x23F3 },
277
+ { 0x25FD, 0x25FE },
278
+ { 0x2614, 0x2615 },
279
+ { 0x2630, 0x2637 },
280
+ { 0x2648, 0x2653 },
281
+ { 0x267F, 0x267F },
282
+ { 0x268A, 0x268F },
283
+ { 0x2693, 0x2693 },
284
+ { 0x26A1, 0x26A1 },
285
+ { 0x26AA, 0x26AB },
286
+ { 0x26BD, 0x26BE },
287
+ { 0x26C4, 0x26C5 },
288
+ { 0x26CE, 0x26CE },
289
+ { 0x26D4, 0x26D4 },
290
+ { 0x26EA, 0x26EA },
291
+ { 0x26F2, 0x26F3 },
292
+ { 0x26F5, 0x26F5 },
293
+ { 0x26FA, 0x26FA },
294
+ { 0x26FD, 0x26FD },
295
+ { 0x2705, 0x2705 },
296
+ { 0x270A, 0x270B },
297
+ { 0x2728, 0x2728 },
298
+ { 0x274C, 0x274C },
299
+ { 0x274E, 0x274E },
300
+ { 0x2753, 0x2755 },
301
+ { 0x2757, 0x2757 },
302
+ { 0x2795, 0x2797 },
303
+ { 0x27B0, 0x27B0 },
304
+ { 0x27BF, 0x27BF },
305
+ { 0x2B1B, 0x2B1C },
306
+ { 0x2B50, 0x2B50 },
307
+ { 0x2B55, 0x2B55 },
308
+ { 0x2E80, 0x2E99 },
309
+ { 0x2E9B, 0x2EF3 },
310
+ { 0x2F00, 0x2FD5 },
311
+ { 0x2FF0, 0x303E },
312
+ { 0x3041, 0x3096 },
313
+ { 0x3099, 0x30FF },
314
+ { 0x3105, 0x312F },
315
+ { 0x3131, 0x318E },
316
+ { 0x3190, 0x31E5 },
317
+ { 0x31EF, 0x321E },
318
+ { 0x3220, 0x3247 },
319
+ { 0x3250, 0xA48C },
320
+ { 0xA490, 0xA4C6 },
321
+ { 0xA960, 0xA97C },
322
+ { 0xAC00, 0xD7A3 },
323
+ { 0xF900, 0xFAFF },
324
+ { 0xFE10, 0xFE19 },
325
+ { 0xFE30, 0xFE52 },
326
+ { 0xFE54, 0xFE66 },
327
+ { 0xFE68, 0xFE6B },
328
+ { 0xFF01, 0xFF60 },
329
+ { 0xFFE0, 0xFFE6 },
330
+ { 0x16FE0, 0x16FE4 },
331
+ { 0x16FF0, 0x16FF1 },
332
+ { 0x17000, 0x187F7 },
333
+ { 0x18800, 0x18CD5 },
334
+ { 0x18CFF, 0x18D08 },
335
+ { 0x1AFF0, 0x1AFF3 },
336
+ { 0x1AFF5, 0x1AFFB },
337
+ { 0x1AFFD, 0x1AFFE },
338
+ { 0x1B000, 0x1B122 },
339
+ { 0x1B132, 0x1B132 },
340
+ { 0x1B150, 0x1B152 },
341
+ { 0x1B155, 0x1B155 },
342
+ { 0x1B164, 0x1B167 },
343
+ { 0x1B170, 0x1B2FB },
344
+ { 0x1D300, 0x1D356 },
345
+ { 0x1D360, 0x1D376 },
346
+ { 0x1F004, 0x1F004 },
347
+ { 0x1F0CF, 0x1F0CF },
348
+ { 0x1F18E, 0x1F18E },
349
+ { 0x1F191, 0x1F19A },
350
+ { 0x1F200, 0x1F202 },
351
+ { 0x1F210, 0x1F23B },
352
+ { 0x1F240, 0x1F248 },
353
+ { 0x1F250, 0x1F251 },
354
+ { 0x1F260, 0x1F265 },
355
+ { 0x1F300, 0x1F320 },
356
+ { 0x1F32D, 0x1F335 },
357
+ { 0x1F337, 0x1F37C },
358
+ { 0x1F37E, 0x1F393 },
359
+ { 0x1F3A0, 0x1F3CA },
360
+ { 0x1F3CF, 0x1F3D3 },
361
+ { 0x1F3E0, 0x1F3F0 },
362
+ { 0x1F3F4, 0x1F3F4 },
363
+ { 0x1F3F8, 0x1F43E },
364
+ { 0x1F440, 0x1F440 },
365
+ { 0x1F442, 0x1F4FC },
366
+ { 0x1F4FF, 0x1F53D },
367
+ { 0x1F54B, 0x1F54E },
368
+ { 0x1F550, 0x1F567 },
369
+ { 0x1F57A, 0x1F57A },
370
+ { 0x1F595, 0x1F596 },
371
+ { 0x1F5A4, 0x1F5A4 },
372
+ { 0x1F5FB, 0x1F64F },
373
+ { 0x1F680, 0x1F6C5 },
374
+ { 0x1F6CC, 0x1F6CC },
375
+ { 0x1F6D0, 0x1F6D2 },
376
+ { 0x1F6D5, 0x1F6D7 },
377
+ { 0x1F6DC, 0x1F6DF },
378
+ { 0x1F6EB, 0x1F6EC },
379
+ { 0x1F6F4, 0x1F6FC },
380
+ { 0x1F7E0, 0x1F7EB },
381
+ { 0x1F7F0, 0x1F7F0 },
382
+ { 0x1F90C, 0x1F93A },
383
+ { 0x1F93C, 0x1F945 },
384
+ { 0x1F947, 0x1F9FF },
385
+ { 0x1FA70, 0x1FA7C },
386
+ { 0x1FA80, 0x1FA89 },
387
+ { 0x1FA8F, 0x1FAC6 },
388
+ { 0x1FACE, 0x1FADC },
389
+ { 0x1FADF, 0x1FAE9 },
390
+ { 0x1FAF0, 0x1FAF8 },
391
+ { 0x20000, 0x2FFFD },
392
+ { 0x30000, 0x3FFFD }
393
+ /* END: WIDE CHAR TABLE */
394
+ };
395
+
396
+ static const size_t wideCharTableSize = sizeof(wideCharTable) / sizeof(wideCharTable[0]);
397
+
398
+ static bool isWideChar(unsigned long cp) {
399
+ for (size_t i = 0; i < wideCharTableSize; i++) {
400
+ auto first_code = wideCharTable[i][0];
401
+ auto last_code = wideCharTable[i][1];
402
+ if (first_code > cp) {
403
+ return false;
404
+ }
405
+ if (first_code <= cp && cp <= last_code) {
406
+ return true;
407
+ }
408
+ }
409
+ return false;
410
+ }
411
+
412
+ /* Check if the code is a combining character */
413
+ static const unsigned long combiningCharTable[] = {
414
+ /* BEGIN: COMBINING CHAR TABLE */
415
+ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, 0x030A, 0x030B, 0x030C,
416
+ 0x030D, 0x030E, 0x030F, 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, 0x0318, 0x0319,
417
+ 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F, 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326,
418
+ 0x0327, 0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F, 0x0330, 0x0331, 0x0332, 0x0333,
419
+ 0x0334, 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F, 0x0340,
420
+ 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D,
421
+ 0x034E, 0x034F, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035A,
422
+ 0x035B, 0x035C, 0x035D, 0x035E, 0x035F, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
423
+ 0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
424
+ 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597, 0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D,
425
+ 0x059E, 0x059F, 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7, 0x05A8, 0x05A9, 0x05AA,
426
+ 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF, 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
427
+ 0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BF, 0x05C1, 0x05C2, 0x05C4, 0x05C5, 0x05C7, 0x0610,
428
+ 0x0611, 0x0612, 0x0613, 0x0614, 0x0615, 0x0616, 0x0617, 0x0618, 0x0619, 0x061A, 0x064B, 0x064C, 0x064D,
429
+ 0x064E, 0x064F, 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0656, 0x0657, 0x0658, 0x0659, 0x065A,
430
+ 0x065B, 0x065C, 0x065D, 0x065E, 0x065F, 0x0670, 0x06D6, 0x06D7, 0x06D8, 0x06D9, 0x06DA, 0x06DB, 0x06DC,
431
+ 0x06DF, 0x06E0, 0x06E1, 0x06E2, 0x06E3, 0x06E4, 0x06E7, 0x06E8, 0x06EA, 0x06EB, 0x06EC, 0x06ED, 0x0711,
432
+ 0x0730, 0x0731, 0x0732, 0x0733, 0x0734, 0x0735, 0x0736, 0x0737, 0x0738, 0x0739, 0x073A, 0x073B, 0x073C,
433
+ 0x073D, 0x073E, 0x073F, 0x0740, 0x0741, 0x0742, 0x0743, 0x0744, 0x0745, 0x0746, 0x0747, 0x0748, 0x0749,
434
+ 0x074A, 0x07A6, 0x07A7, 0x07A8, 0x07A9, 0x07AA, 0x07AB, 0x07AC, 0x07AD, 0x07AE, 0x07AF, 0x07B0, 0x07EB,
435
+ 0x07EC, 0x07ED, 0x07EE, 0x07EF, 0x07F0, 0x07F1, 0x07F2, 0x07F3, 0x07FD, 0x0816, 0x0817, 0x0818, 0x0819,
436
+ 0x081B, 0x081C, 0x081D, 0x081E, 0x081F, 0x0820, 0x0821, 0x0822, 0x0823, 0x0825, 0x0826, 0x0827, 0x0829,
437
+ 0x082A, 0x082B, 0x082C, 0x082D, 0x0859, 0x085A, 0x085B, 0x0897, 0x0898, 0x0899, 0x089A, 0x089B, 0x089C,
438
+ 0x089D, 0x089E, 0x089F, 0x08CA, 0x08CB, 0x08CC, 0x08CD, 0x08CE, 0x08CF, 0x08D0, 0x08D1, 0x08D2, 0x08D3,
439
+ 0x08D4, 0x08D5, 0x08D6, 0x08D7, 0x08D8, 0x08D9, 0x08DA, 0x08DB, 0x08DC, 0x08DD, 0x08DE, 0x08DF, 0x08E0,
440
+ 0x08E1, 0x08E3, 0x08E4, 0x08E5, 0x08E6, 0x08E7, 0x08E8, 0x08E9, 0x08EA, 0x08EB, 0x08EC, 0x08ED, 0x08EE,
441
+ 0x08EF, 0x08F0, 0x08F1, 0x08F2, 0x08F3, 0x08F4, 0x08F5, 0x08F6, 0x08F7, 0x08F8, 0x08F9, 0x08FA, 0x08FB,
442
+ 0x08FC, 0x08FD, 0x08FE, 0x08FF, 0x0900, 0x0901, 0x0902, 0x093A, 0x093C, 0x0941, 0x0942, 0x0943, 0x0944,
443
+ 0x0945, 0x0946, 0x0947, 0x0948, 0x094D, 0x0951, 0x0952, 0x0953, 0x0954, 0x0955, 0x0956, 0x0957, 0x0962,
444
+ 0x0963, 0x0981, 0x09BC, 0x09C1, 0x09C2, 0x09C3, 0x09C4, 0x09CD, 0x09E2, 0x09E3, 0x09FE, 0x0A01, 0x0A02,
445
+ 0x0A3C, 0x0A41, 0x0A42, 0x0A47, 0x0A48, 0x0A4B, 0x0A4C, 0x0A4D, 0x0A51, 0x0A70, 0x0A71, 0x0A75, 0x0A81,
446
+ 0x0A82, 0x0ABC, 0x0AC1, 0x0AC2, 0x0AC3, 0x0AC4, 0x0AC5, 0x0AC7, 0x0AC8, 0x0ACD, 0x0AE2, 0x0AE3, 0x0AFA,
447
+ 0x0AFB, 0x0AFC, 0x0AFD, 0x0AFE, 0x0AFF, 0x0B01, 0x0B3C, 0x0B3F, 0x0B41, 0x0B42, 0x0B43, 0x0B44, 0x0B4D,
448
+ 0x0B55, 0x0B56, 0x0B62, 0x0B63, 0x0B82, 0x0BC0, 0x0BCD, 0x0C00, 0x0C04, 0x0C3C, 0x0C3E, 0x0C3F, 0x0C40,
449
+ 0x0C46, 0x0C47, 0x0C48, 0x0C4A, 0x0C4B, 0x0C4C, 0x0C4D, 0x0C55, 0x0C56, 0x0C62, 0x0C63, 0x0C81, 0x0CBC,
450
+ 0x0CBF, 0x0CC6, 0x0CCC, 0x0CCD, 0x0CE2, 0x0CE3, 0x0D00, 0x0D01, 0x0D3B, 0x0D3C, 0x0D41, 0x0D42, 0x0D43,
451
+ 0x0D44, 0x0D4D, 0x0D62, 0x0D63, 0x0D81, 0x0DCA, 0x0DD2, 0x0DD3, 0x0DD4, 0x0DD6, 0x0E31, 0x0E34, 0x0E35,
452
+ 0x0E36, 0x0E37, 0x0E38, 0x0E39, 0x0E3A, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E,
453
+ 0x0EB1, 0x0EB4, 0x0EB5, 0x0EB6, 0x0EB7, 0x0EB8, 0x0EB9, 0x0EBA, 0x0EBB, 0x0EBC, 0x0EC8, 0x0EC9, 0x0ECA,
454
+ 0x0ECB, 0x0ECC, 0x0ECD, 0x0ECE, 0x0F18, 0x0F19, 0x0F35, 0x0F37, 0x0F39, 0x0F71, 0x0F72, 0x0F73, 0x0F74,
455
+ 0x0F75, 0x0F76, 0x0F77, 0x0F78, 0x0F79, 0x0F7A, 0x0F7B, 0x0F7C, 0x0F7D, 0x0F7E, 0x0F80, 0x0F81, 0x0F82,
456
+ 0x0F83, 0x0F84, 0x0F86, 0x0F87, 0x0F8D, 0x0F8E, 0x0F8F, 0x0F90, 0x0F91, 0x0F92, 0x0F93, 0x0F94, 0x0F95,
457
+ 0x0F96, 0x0F97, 0x0F99, 0x0F9A, 0x0F9B, 0x0F9C, 0x0F9D, 0x0F9E, 0x0F9F, 0x0FA0, 0x0FA1, 0x0FA2, 0x0FA3,
458
+ 0x0FA4, 0x0FA5, 0x0FA6, 0x0FA7, 0x0FA8, 0x0FA9, 0x0FAA, 0x0FAB, 0x0FAC, 0x0FAD, 0x0FAE, 0x0FAF, 0x0FB0,
459
+ 0x0FB1, 0x0FB2, 0x0FB3, 0x0FB4, 0x0FB5, 0x0FB6, 0x0FB7, 0x0FB8, 0x0FB9, 0x0FBA, 0x0FBB, 0x0FBC, 0x0FC6,
460
+ 0x102D, 0x102E, 0x102F, 0x1030, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037, 0x1039, 0x103A, 0x103D,
461
+ 0x103E, 0x1058, 0x1059, 0x105E, 0x105F, 0x1060, 0x1071, 0x1072, 0x1073, 0x1074, 0x1082, 0x1085, 0x1086,
462
+ 0x108D, 0x109D, 0x135D, 0x135E, 0x135F, 0x1712, 0x1713, 0x1714, 0x1732, 0x1733, 0x1752, 0x1753, 0x1772,
463
+ 0x1773, 0x17B4, 0x17B5, 0x17B7, 0x17B8, 0x17B9, 0x17BA, 0x17BB, 0x17BC, 0x17BD, 0x17C6, 0x17C9, 0x17CA,
464
+ 0x17CB, 0x17CC, 0x17CD, 0x17CE, 0x17CF, 0x17D0, 0x17D1, 0x17D2, 0x17D3, 0x17DD, 0x180B, 0x180C, 0x180D,
465
+ 0x180F, 0x1885, 0x1886, 0x18A9, 0x1920, 0x1921, 0x1922, 0x1927, 0x1928, 0x1932, 0x1939, 0x193A, 0x193B,
466
+ 0x1A17, 0x1A18, 0x1A1B, 0x1A56, 0x1A58, 0x1A59, 0x1A5A, 0x1A5B, 0x1A5C, 0x1A5D, 0x1A5E, 0x1A60, 0x1A62,
467
+ 0x1A65, 0x1A66, 0x1A67, 0x1A68, 0x1A69, 0x1A6A, 0x1A6B, 0x1A6C, 0x1A73, 0x1A74, 0x1A75, 0x1A76, 0x1A77,
468
+ 0x1A78, 0x1A79, 0x1A7A, 0x1A7B, 0x1A7C, 0x1A7F, 0x1AB0, 0x1AB1, 0x1AB2, 0x1AB3, 0x1AB4, 0x1AB5, 0x1AB6,
469
+ 0x1AB7, 0x1AB8, 0x1AB9, 0x1ABA, 0x1ABB, 0x1ABC, 0x1ABD, 0x1ABF, 0x1AC0, 0x1AC1, 0x1AC2, 0x1AC3, 0x1AC4,
470
+ 0x1AC5, 0x1AC6, 0x1AC7, 0x1AC8, 0x1AC9, 0x1ACA, 0x1ACB, 0x1ACC, 0x1ACD, 0x1ACE, 0x1B00, 0x1B01, 0x1B02,
471
+ 0x1B03, 0x1B34, 0x1B36, 0x1B37, 0x1B38, 0x1B39, 0x1B3A, 0x1B3C, 0x1B42, 0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E,
472
+ 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73, 0x1B80, 0x1B81, 0x1BA2, 0x1BA3, 0x1BA4, 0x1BA5, 0x1BA8, 0x1BA9,
473
+ 0x1BAB, 0x1BAC, 0x1BAD, 0x1BE6, 0x1BE8, 0x1BE9, 0x1BED, 0x1BEF, 0x1BF0, 0x1BF1, 0x1C2C, 0x1C2D, 0x1C2E,
474
+ 0x1C2F, 0x1C30, 0x1C31, 0x1C32, 0x1C33, 0x1C36, 0x1C37, 0x1CD0, 0x1CD1, 0x1CD2, 0x1CD4, 0x1CD5, 0x1CD6,
475
+ 0x1CD7, 0x1CD8, 0x1CD9, 0x1CDA, 0x1CDB, 0x1CDC, 0x1CDD, 0x1CDE, 0x1CDF, 0x1CE0, 0x1CE2, 0x1CE3, 0x1CE4,
476
+ 0x1CE5, 0x1CE6, 0x1CE7, 0x1CE8, 0x1CED, 0x1CF4, 0x1CF8, 0x1CF9, 0x1DC0, 0x1DC1, 0x1DC2, 0x1DC3, 0x1DC4,
477
+ 0x1DC5, 0x1DC6, 0x1DC7, 0x1DC8, 0x1DC9, 0x1DCA, 0x1DCB, 0x1DCC, 0x1DCD, 0x1DCE, 0x1DCF, 0x1DD0, 0x1DD1,
478
+ 0x1DD2, 0x1DD3, 0x1DD4, 0x1DD5, 0x1DD6, 0x1DD7, 0x1DD8, 0x1DD9, 0x1DDA, 0x1DDB, 0x1DDC, 0x1DDD, 0x1DDE,
479
+ 0x1DDF, 0x1DE0, 0x1DE1, 0x1DE2, 0x1DE3, 0x1DE4, 0x1DE5, 0x1DE6, 0x1DE7, 0x1DE8, 0x1DE9, 0x1DEA, 0x1DEB,
480
+ 0x1DEC, 0x1DED, 0x1DEE, 0x1DEF, 0x1DF0, 0x1DF1, 0x1DF2, 0x1DF3, 0x1DF4, 0x1DF5, 0x1DF6, 0x1DF7, 0x1DF8,
481
+ 0x1DF9, 0x1DFA, 0x1DFB, 0x1DFC, 0x1DFD, 0x1DFE, 0x1DFF, 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5,
482
+ 0x20D6, 0x20D7, 0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20E1, 0x20E5, 0x20E6, 0x20E7, 0x20E8, 0x20E9,
483
+ 0x20EA, 0x20EB, 0x20EC, 0x20ED, 0x20EE, 0x20EF, 0x20F0, 0x2CEF, 0x2CF0, 0x2CF1, 0x2D7F, 0x2DE0, 0x2DE1,
484
+ 0x2DE2, 0x2DE3, 0x2DE4, 0x2DE5, 0x2DE6, 0x2DE7, 0x2DE8, 0x2DE9, 0x2DEA, 0x2DEB, 0x2DEC, 0x2DED, 0x2DEE,
485
+ 0x2DEF, 0x2DF0, 0x2DF1, 0x2DF2, 0x2DF3, 0x2DF4, 0x2DF5, 0x2DF6, 0x2DF7, 0x2DF8, 0x2DF9, 0x2DFA, 0x2DFB,
486
+ 0x2DFC, 0x2DFD, 0x2DFE, 0x2DFF, 0x302A, 0x302B, 0x302C, 0x302D, 0x3099, 0x309A, 0xA66F, 0xA674, 0xA675,
487
+ 0xA676, 0xA677, 0xA678, 0xA679, 0xA67A, 0xA67B, 0xA67C, 0xA67D, 0xA69E, 0xA69F, 0xA6F0, 0xA6F1, 0xA802,
488
+ 0xA806, 0xA80B, 0xA825, 0xA826, 0xA82C, 0xA8C4, 0xA8C5, 0xA8E0, 0xA8E1, 0xA8E2, 0xA8E3, 0xA8E4, 0xA8E5,
489
+ 0xA8E6, 0xA8E7, 0xA8E8, 0xA8E9, 0xA8EA, 0xA8EB, 0xA8EC, 0xA8ED, 0xA8EE, 0xA8EF, 0xA8F0, 0xA8F1, 0xA8FF,
490
+ 0xA926, 0xA927, 0xA928, 0xA929, 0xA92A, 0xA92B, 0xA92C, 0xA92D, 0xA947, 0xA948, 0xA949, 0xA94A, 0xA94B,
491
+ 0xA94C, 0xA94D, 0xA94E, 0xA94F, 0xA950, 0xA951, 0xA980, 0xA981, 0xA982, 0xA9B3, 0xA9B6, 0xA9B7, 0xA9B8,
492
+ 0xA9B9, 0xA9BC, 0xA9BD, 0xA9E5, 0xAA29, 0xAA2A, 0xAA2B, 0xAA2C, 0xAA2D, 0xAA2E, 0xAA31, 0xAA32, 0xAA35,
493
+ 0xAA36, 0xAA43, 0xAA4C, 0xAA7C, 0xAAB0, 0xAAB2, 0xAAB3, 0xAAB4, 0xAAB7, 0xAAB8, 0xAABE, 0xAABF, 0xAAC1,
494
+ 0xAAEC, 0xAAED, 0xAAF6, 0xABE5, 0xABE8, 0xABED, 0xFB1E, 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05,
495
+ 0xFE06, 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F, 0xFE20, 0xFE21, 0xFE22,
496
+ 0xFE23, 0xFE24, 0xFE25, 0xFE26, 0xFE27, 0xFE28, 0xFE29, 0xFE2A, 0xFE2B, 0xFE2C, 0xFE2D, 0xFE2E, 0xFE2F,
497
+ 0x101FD, 0x102E0, 0x10376, 0x10377, 0x10378, 0x10379, 0x1037A, 0x10A01, 0x10A02, 0x10A03, 0x10A05, 0x10A06, 0x10A0C,
498
+ 0x10A0D, 0x10A0E, 0x10A0F, 0x10A38, 0x10A39, 0x10A3A, 0x10A3F, 0x10AE5, 0x10AE6, 0x10D24, 0x10D25, 0x10D26, 0x10D27,
499
+ 0x10D69, 0x10D6A, 0x10D6B, 0x10D6C, 0x10D6D, 0x10EAB, 0x10EAC, 0x10EFC, 0x10EFD, 0x10EFE, 0x10EFF, 0x10F46, 0x10F47,
500
+ 0x10F48, 0x10F49, 0x10F4A, 0x10F4B, 0x10F4C, 0x10F4D, 0x10F4E, 0x10F4F, 0x10F50, 0x10F82, 0x10F83, 0x10F84, 0x10F85,
501
+ 0x11001, 0x11038, 0x11039, 0x1103A, 0x1103B, 0x1103C, 0x1103D, 0x1103E, 0x1103F, 0x11040, 0x11041, 0x11042, 0x11043,
502
+ 0x11044, 0x11045, 0x11046, 0x11070, 0x11073, 0x11074, 0x1107F, 0x11080, 0x11081, 0x110B3, 0x110B4, 0x110B5, 0x110B6,
503
+ 0x110B9, 0x110BA, 0x110C2, 0x11100, 0x11101, 0x11102, 0x11127, 0x11128, 0x11129, 0x1112A, 0x1112B, 0x1112D, 0x1112E,
504
+ 0x1112F, 0x11130, 0x11131, 0x11132, 0x11133, 0x11134, 0x11173, 0x11180, 0x11181, 0x111B6, 0x111B7, 0x111B8, 0x111B9,
505
+ 0x111BA, 0x111BB, 0x111BC, 0x111BD, 0x111BE, 0x111C9, 0x111CA, 0x111CB, 0x111CC, 0x111CF, 0x1122F, 0x11230, 0x11231,
506
+ 0x11234, 0x11236, 0x11237, 0x1123E, 0x11241, 0x112DF, 0x112E3, 0x112E4, 0x112E5, 0x112E6, 0x112E7, 0x112E8, 0x112E9,
507
+ 0x112EA, 0x11300, 0x11301, 0x1133B, 0x1133C, 0x11340, 0x11366, 0x11367, 0x11368, 0x11369, 0x1136A, 0x1136B, 0x1136C,
508
+ 0x11370, 0x11371, 0x11372, 0x11373, 0x11374, 0x113BB, 0x113BC, 0x113BD, 0x113BE, 0x113BF, 0x113C0, 0x113CE, 0x113D0,
509
+ 0x113D2, 0x113E1, 0x113E2, 0x11438, 0x11439, 0x1143A, 0x1143B, 0x1143C, 0x1143D, 0x1143E, 0x1143F, 0x11442, 0x11443,
510
+ 0x11444, 0x11446, 0x1145E, 0x114B3, 0x114B4, 0x114B5, 0x114B6, 0x114B7, 0x114B8, 0x114BA, 0x114BF, 0x114C0, 0x114C2,
511
+ 0x114C3, 0x115B2, 0x115B3, 0x115B4, 0x115B5, 0x115BC, 0x115BD, 0x115BF, 0x115C0, 0x115DC, 0x115DD, 0x11633, 0x11634,
512
+ 0x11635, 0x11636, 0x11637, 0x11638, 0x11639, 0x1163A, 0x1163D, 0x1163F, 0x11640, 0x116AB, 0x116AD, 0x116B0, 0x116B1,
513
+ 0x116B2, 0x116B3, 0x116B4, 0x116B5, 0x116B7, 0x1171D, 0x1171F, 0x11722, 0x11723, 0x11724, 0x11725, 0x11727, 0x11728,
514
+ 0x11729, 0x1172A, 0x1172B, 0x1182F, 0x11830, 0x11831, 0x11832, 0x11833, 0x11834, 0x11835, 0x11836, 0x11837, 0x11839,
515
+ 0x1183A, 0x1193B, 0x1193C, 0x1193E, 0x11943, 0x119D4, 0x119D5, 0x119D6, 0x119D7, 0x119DA, 0x119DB, 0x119E0, 0x11A01,
516
+ 0x11A02, 0x11A03, 0x11A04, 0x11A05, 0x11A06, 0x11A07, 0x11A08, 0x11A09, 0x11A0A, 0x11A33, 0x11A34, 0x11A35, 0x11A36,
517
+ 0x11A37, 0x11A38, 0x11A3B, 0x11A3C, 0x11A3D, 0x11A3E, 0x11A47, 0x11A51, 0x11A52, 0x11A53, 0x11A54, 0x11A55, 0x11A56,
518
+ 0x11A59, 0x11A5A, 0x11A5B, 0x11A8A, 0x11A8B, 0x11A8C, 0x11A8D, 0x11A8E, 0x11A8F, 0x11A90, 0x11A91, 0x11A92, 0x11A93,
519
+ 0x11A94, 0x11A95, 0x11A96, 0x11A98, 0x11A99, 0x11C30, 0x11C31, 0x11C32, 0x11C33, 0x11C34, 0x11C35, 0x11C36, 0x11C38,
520
+ 0x11C39, 0x11C3A, 0x11C3B, 0x11C3C, 0x11C3D, 0x11C3F, 0x11C92, 0x11C93, 0x11C94, 0x11C95, 0x11C96, 0x11C97, 0x11C98,
521
+ 0x11C99, 0x11C9A, 0x11C9B, 0x11C9C, 0x11C9D, 0x11C9E, 0x11C9F, 0x11CA0, 0x11CA1, 0x11CA2, 0x11CA3, 0x11CA4, 0x11CA5,
522
+ 0x11CA6, 0x11CA7, 0x11CAA, 0x11CAB, 0x11CAC, 0x11CAD, 0x11CAE, 0x11CAF, 0x11CB0, 0x11CB2, 0x11CB3, 0x11CB5, 0x11CB6,
523
+ 0x11D31, 0x11D32, 0x11D33, 0x11D34, 0x11D35, 0x11D36, 0x11D3A, 0x11D3C, 0x11D3D, 0x11D3F, 0x11D40, 0x11D41, 0x11D42,
524
+ 0x11D43, 0x11D44, 0x11D45, 0x11D47, 0x11D90, 0x11D91, 0x11D95, 0x11D97, 0x11EF3, 0x11EF4, 0x11F00, 0x11F01, 0x11F36,
525
+ 0x11F37, 0x11F38, 0x11F39, 0x11F3A, 0x11F40, 0x11F42, 0x11F5A, 0x13440, 0x13447, 0x13448, 0x13449, 0x1344A, 0x1344B,
526
+ 0x1344C, 0x1344D, 0x1344E, 0x1344F, 0x13450, 0x13451, 0x13452, 0x13453, 0x13454, 0x13455, 0x1611E, 0x1611F, 0x16120,
527
+ 0x16121, 0x16122, 0x16123, 0x16124, 0x16125, 0x16126, 0x16127, 0x16128, 0x16129, 0x1612D, 0x1612E, 0x1612F, 0x16AF0,
528
+ 0x16AF1, 0x16AF2, 0x16AF3, 0x16AF4, 0x16B30, 0x16B31, 0x16B32, 0x16B33, 0x16B34, 0x16B35, 0x16B36, 0x16F4F, 0x16F8F,
529
+ 0x16F90, 0x16F91, 0x16F92, 0x16FE4, 0x1BC9D, 0x1BC9E, 0x1CF00, 0x1CF01, 0x1CF02, 0x1CF03, 0x1CF04, 0x1CF05, 0x1CF06,
530
+ 0x1CF07, 0x1CF08, 0x1CF09, 0x1CF0A, 0x1CF0B, 0x1CF0C, 0x1CF0D, 0x1CF0E, 0x1CF0F, 0x1CF10, 0x1CF11, 0x1CF12, 0x1CF13,
531
+ 0x1CF14, 0x1CF15, 0x1CF16, 0x1CF17, 0x1CF18, 0x1CF19, 0x1CF1A, 0x1CF1B, 0x1CF1C, 0x1CF1D, 0x1CF1E, 0x1CF1F, 0x1CF20,
532
+ 0x1CF21, 0x1CF22, 0x1CF23, 0x1CF24, 0x1CF25, 0x1CF26, 0x1CF27, 0x1CF28, 0x1CF29, 0x1CF2A, 0x1CF2B, 0x1CF2C, 0x1CF2D,
533
+ 0x1CF30, 0x1CF31, 0x1CF32, 0x1CF33, 0x1CF34, 0x1CF35, 0x1CF36, 0x1CF37, 0x1CF38, 0x1CF39, 0x1CF3A, 0x1CF3B, 0x1CF3C,
534
+ 0x1CF3D, 0x1CF3E, 0x1CF3F, 0x1CF40, 0x1CF41, 0x1CF42, 0x1CF43, 0x1CF44, 0x1CF45, 0x1CF46, 0x1D167, 0x1D168, 0x1D169,
535
+ 0x1D17B, 0x1D17C, 0x1D17D, 0x1D17E, 0x1D17F, 0x1D180, 0x1D181, 0x1D182, 0x1D185, 0x1D186, 0x1D187, 0x1D188, 0x1D189,
536
+ 0x1D18A, 0x1D18B, 0x1D1AA, 0x1D1AB, 0x1D1AC, 0x1D1AD, 0x1D242, 0x1D243, 0x1D244, 0x1DA00, 0x1DA01, 0x1DA02, 0x1DA03,
537
+ 0x1DA04, 0x1DA05, 0x1DA06, 0x1DA07, 0x1DA08, 0x1DA09, 0x1DA0A, 0x1DA0B, 0x1DA0C, 0x1DA0D, 0x1DA0E, 0x1DA0F, 0x1DA10,
538
+ 0x1DA11, 0x1DA12, 0x1DA13, 0x1DA14, 0x1DA15, 0x1DA16, 0x1DA17, 0x1DA18, 0x1DA19, 0x1DA1A, 0x1DA1B, 0x1DA1C, 0x1DA1D,
539
+ 0x1DA1E, 0x1DA1F, 0x1DA20, 0x1DA21, 0x1DA22, 0x1DA23, 0x1DA24, 0x1DA25, 0x1DA26, 0x1DA27, 0x1DA28, 0x1DA29, 0x1DA2A,
540
+ 0x1DA2B, 0x1DA2C, 0x1DA2D, 0x1DA2E, 0x1DA2F, 0x1DA30, 0x1DA31, 0x1DA32, 0x1DA33, 0x1DA34, 0x1DA35, 0x1DA36, 0x1DA3B,
541
+ 0x1DA3C, 0x1DA3D, 0x1DA3E, 0x1DA3F, 0x1DA40, 0x1DA41, 0x1DA42, 0x1DA43, 0x1DA44, 0x1DA45, 0x1DA46, 0x1DA47, 0x1DA48,
542
+ 0x1DA49, 0x1DA4A, 0x1DA4B, 0x1DA4C, 0x1DA4D, 0x1DA4E, 0x1DA4F, 0x1DA50, 0x1DA51, 0x1DA52, 0x1DA53, 0x1DA54, 0x1DA55,
543
+ 0x1DA56, 0x1DA57, 0x1DA58, 0x1DA59, 0x1DA5A, 0x1DA5B, 0x1DA5C, 0x1DA5D, 0x1DA5E, 0x1DA5F, 0x1DA60, 0x1DA61, 0x1DA62,
544
+ 0x1DA63, 0x1DA64, 0x1DA65, 0x1DA66, 0x1DA67, 0x1DA68, 0x1DA69, 0x1DA6A, 0x1DA6B, 0x1DA6C, 0x1DA75, 0x1DA84, 0x1DA9B,
545
+ 0x1DA9C, 0x1DA9D, 0x1DA9E, 0x1DA9F, 0x1DAA1, 0x1DAA2, 0x1DAA3, 0x1DAA4, 0x1DAA5, 0x1DAA6, 0x1DAA7, 0x1DAA8, 0x1DAA9,
546
+ 0x1DAAA, 0x1DAAB, 0x1DAAC, 0x1DAAD, 0x1DAAE, 0x1DAAF, 0x1E000, 0x1E001, 0x1E002, 0x1E003, 0x1E004, 0x1E005, 0x1E006,
547
+ 0x1E008, 0x1E009, 0x1E00A, 0x1E00B, 0x1E00C, 0x1E00D, 0x1E00E, 0x1E00F, 0x1E010, 0x1E011, 0x1E012, 0x1E013, 0x1E014,
548
+ 0x1E015, 0x1E016, 0x1E017, 0x1E018, 0x1E01B, 0x1E01C, 0x1E01D, 0x1E01E, 0x1E01F, 0x1E020, 0x1E021, 0x1E023, 0x1E024,
549
+ 0x1E026, 0x1E027, 0x1E028, 0x1E029, 0x1E02A, 0x1E08F, 0x1E130, 0x1E131, 0x1E132, 0x1E133, 0x1E134, 0x1E135, 0x1E136,
550
+ 0x1E2AE, 0x1E2EC, 0x1E2ED, 0x1E2EE, 0x1E2EF, 0x1E4EC, 0x1E4ED, 0x1E4EE, 0x1E4EF, 0x1E5EE, 0x1E5EF, 0x1E8D0, 0x1E8D1,
551
+ 0x1E8D2, 0x1E8D3, 0x1E8D4, 0x1E8D5, 0x1E8D6, 0x1E944, 0x1E945, 0x1E946, 0x1E947, 0x1E948, 0x1E949, 0x1E94A, 0xE0100,
552
+ 0xE0101, 0xE0102, 0xE0103, 0xE0104, 0xE0105, 0xE0106, 0xE0107, 0xE0108, 0xE0109, 0xE010A, 0xE010B, 0xE010C, 0xE010D,
553
+ 0xE010E, 0xE010F, 0xE0110, 0xE0111, 0xE0112, 0xE0113, 0xE0114, 0xE0115, 0xE0116, 0xE0117, 0xE0118, 0xE0119, 0xE011A,
554
+ 0xE011B, 0xE011C, 0xE011D, 0xE011E, 0xE011F, 0xE0120, 0xE0121, 0xE0122, 0xE0123, 0xE0124, 0xE0125, 0xE0126, 0xE0127,
555
+ 0xE0128, 0xE0129, 0xE012A, 0xE012B, 0xE012C, 0xE012D, 0xE012E, 0xE012F, 0xE0130, 0xE0131, 0xE0132, 0xE0133, 0xE0134,
556
+ 0xE0135, 0xE0136, 0xE0137, 0xE0138, 0xE0139, 0xE013A, 0xE013B, 0xE013C, 0xE013D, 0xE013E, 0xE013F, 0xE0140, 0xE0141,
557
+ 0xE0142, 0xE0143, 0xE0144, 0xE0145, 0xE0146, 0xE0147, 0xE0148, 0xE0149, 0xE014A, 0xE014B, 0xE014C, 0xE014D, 0xE014E,
558
+ 0xE014F, 0xE0150, 0xE0151, 0xE0152, 0xE0153, 0xE0154, 0xE0155, 0xE0156, 0xE0157, 0xE0158, 0xE0159, 0xE015A, 0xE015B,
559
+ 0xE015C, 0xE015D, 0xE015E, 0xE015F, 0xE0160, 0xE0161, 0xE0162, 0xE0163, 0xE0164, 0xE0165, 0xE0166, 0xE0167, 0xE0168,
560
+ 0xE0169, 0xE016A, 0xE016B, 0xE016C, 0xE016D, 0xE016E, 0xE016F, 0xE0170, 0xE0171, 0xE0172, 0xE0173, 0xE0174, 0xE0175,
561
+ 0xE0176, 0xE0177, 0xE0178, 0xE0179, 0xE017A, 0xE017B, 0xE017C, 0xE017D, 0xE017E, 0xE017F, 0xE0180, 0xE0181, 0xE0182,
562
+ 0xE0183, 0xE0184, 0xE0185, 0xE0186, 0xE0187, 0xE0188, 0xE0189, 0xE018A, 0xE018B, 0xE018C, 0xE018D, 0xE018E, 0xE018F,
563
+ 0xE0190, 0xE0191, 0xE0192, 0xE0193, 0xE0194, 0xE0195, 0xE0196, 0xE0197, 0xE0198, 0xE0199, 0xE019A, 0xE019B, 0xE019C,
564
+ 0xE019D, 0xE019E, 0xE019F, 0xE01A0, 0xE01A1, 0xE01A2, 0xE01A3, 0xE01A4, 0xE01A5, 0xE01A6, 0xE01A7, 0xE01A8, 0xE01A9,
565
+ 0xE01AA, 0xE01AB, 0xE01AC, 0xE01AD, 0xE01AE, 0xE01AF, 0xE01B0, 0xE01B1, 0xE01B2, 0xE01B3, 0xE01B4, 0xE01B5, 0xE01B6,
566
+ 0xE01B7, 0xE01B8, 0xE01B9, 0xE01BA, 0xE01BB, 0xE01BC, 0xE01BD, 0xE01BE, 0xE01BF, 0xE01C0, 0xE01C1, 0xE01C2, 0xE01C3,
567
+ 0xE01C4, 0xE01C5, 0xE01C6, 0xE01C7, 0xE01C8, 0xE01C9, 0xE01CA, 0xE01CB, 0xE01CC, 0xE01CD, 0xE01CE, 0xE01CF, 0xE01D0,
568
+ 0xE01D1, 0xE01D2, 0xE01D3, 0xE01D4, 0xE01D5, 0xE01D6, 0xE01D7, 0xE01D8, 0xE01D9, 0xE01DA, 0xE01DB, 0xE01DC, 0xE01DD,
569
+ 0xE01DE, 0xE01DF, 0xE01E0, 0xE01E1, 0xE01E2, 0xE01E3, 0xE01E4, 0xE01E5, 0xE01E6, 0xE01E7, 0xE01E8, 0xE01E9, 0xE01EA,
570
+ 0xE01EB, 0xE01EC, 0xE01ED, 0xE01EE, 0xE01EF
571
+ /* END: COMBINING CHAR TABLE */
572
+ };
573
+
574
+ static const unsigned long combiningCharTableSize = sizeof(combiningCharTable) / sizeof(combiningCharTable[0]);
575
+
576
+ static bool isCombiningChar(unsigned long cp) {
577
+ for (size_t i = 0; i < combiningCharTableSize; i++) {
578
+ auto code = combiningCharTable[i];
579
+ if (code > cp) {
580
+ return false;
581
+ }
582
+ if (code == cp) {
583
+ return true;
584
+ }
585
+ }
586
+ return false;
587
+ }
588
+
589
+ /* Get length of previous grapheme */
590
+ static size_t defaultPrevCharLen(const char * buf, size_t /*buf_len*/, size_t pos, size_t * col_len) {
591
+ size_t end = pos;
592
+ while (pos > 0) {
593
+ size_t len = prevUtf8CodePointLen(buf, pos);
594
+ pos -= len;
595
+ int cp;
596
+ utf8BytesToCodePoint(buf + pos, len, &cp);
597
+ if (!isCombiningChar(cp)) {
598
+ if (col_len != NULL) {
599
+ *col_len = isWideChar(cp) ? 2 : 1;
600
+ }
601
+ return end - pos;
602
+ }
603
+ }
604
+ /* NOTREACHED */
605
+ return 0;
606
+ }
607
+
608
+ /* Get length of next grapheme */
609
+ static size_t defaultNextCharLen(const char * buf, size_t buf_len, size_t pos, size_t * col_len) {
610
+ size_t beg = pos;
611
+ int cp;
612
+ size_t len = utf8BytesToCodePoint(buf + pos, buf_len - pos, &cp);
613
+ if (isCombiningChar(cp)) {
614
+ /* NOTREACHED */
615
+ return 0;
616
+ }
617
+ if (col_len != NULL) {
618
+ *col_len = isWideChar(cp) ? 2 : 1;
619
+ }
620
+ pos += len;
621
+ while (pos < buf_len) {
622
+ int cp;
623
+ len = utf8BytesToCodePoint(buf + pos, buf_len - pos, &cp);
624
+ if (!isCombiningChar(cp)) {
625
+ return pos - beg;
626
+ }
627
+ pos += len;
628
+ }
629
+ return pos - beg;
630
+ }
631
+
632
+ /* Read a Unicode from file. */
633
+ static size_t defaultReadCode(int fd, char * buf, size_t buf_len, int * cp) {
634
+ if (buf_len < 1) {
635
+ return -1;
636
+ }
637
+ size_t nread = read(fd, &buf[0], 1);
638
+ if (nread <= 0) {
639
+ return nread;
640
+ }
641
+
642
+ unsigned char byte = buf[0];
643
+ if ((byte & 0x80) == 0) {
644
+ ;
645
+ } else if ((byte & 0xE0) == 0xC0) {
646
+ if (buf_len < 2) {
647
+ return -1;
648
+ }
649
+ nread = read(fd, &buf[1], 1);
650
+ if (nread <= 0) {
651
+ return nread;
652
+ }
653
+ } else if ((byte & 0xF0) == 0xE0) {
654
+ if (buf_len < 3) {
655
+ return -1;
656
+ }
657
+ nread = read(fd, &buf[1], 2);
658
+ if (nread <= 0) {
659
+ return nread;
660
+ }
661
+ } else if ((byte & 0xF8) == 0xF0) {
662
+ if (buf_len < 3) {
663
+ return -1;
664
+ }
665
+ nread = read(fd, &buf[1], 3);
666
+ if (nread <= 0) {
667
+ return nread;
668
+ }
669
+ } else {
670
+ return -1;
671
+ }
672
+
673
+ return utf8BytesToCodePoint(buf, buf_len, cp);
674
+ }
675
+
676
+ /* Set default encoding functions */
677
+ static linenoisePrevCharLen * prevCharLen = defaultPrevCharLen;
678
+ static linenoiseNextCharLen * nextCharLen = defaultNextCharLen;
679
+ static linenoiseReadCode * readCode = defaultReadCode;
680
+
681
+ /* Set used defined encoding functions */
682
+ void linenoiseSetEncodingFunctions(linenoisePrevCharLen * prevCharLenFunc, linenoiseNextCharLen * nextCharLenFunc,
683
+ linenoiseReadCode * readCodeFunc) {
684
+ prevCharLen = prevCharLenFunc;
685
+ nextCharLen = nextCharLenFunc;
686
+ readCode = readCodeFunc;
687
+ }
688
+
230
689
  /* ======================= Low level terminal handling ====================== */
231
690
 
232
691
  /* Enable "mask mode". When it is enabled, instead of the input that
@@ -408,6 +867,73 @@ static void refreshLineWithCompletion(struct linenoiseState *ls, linenoiseComple
408
867
  }
409
868
  }
410
869
 
870
+ enum ESC_TYPE { ESC_NULL = 0, ESC_DELETE, ESC_UP, ESC_DOWN, ESC_RIGHT, ESC_LEFT, ESC_HOME, ESC_END };
871
+
872
+ static ESC_TYPE readEscapeSequence(struct linenoiseState * l) {
873
+ /* Check if the file input has additional data. */
874
+ struct pollfd pfd;
875
+ pfd.fd = l->ifd;
876
+ pfd.events = POLLIN;
877
+
878
+ auto ret = poll(&pfd, 1, 1); // 1 millisecond timeout
879
+ if (ret <= 0) { // -1: error, 0: timeout
880
+ return ESC_NULL;
881
+ }
882
+
883
+ /* Read the next two bytes representing the escape sequence.
884
+ * Use two calls to handle slow terminals returning the two
885
+ * chars at different times. */
886
+ char seq[3];
887
+ if (read(l->ifd, seq, 1) == -1) {
888
+ return ESC_NULL;
889
+ }
890
+ if (read(l->ifd, seq + 1, 1) == -1) {
891
+ return ESC_NULL;
892
+ }
893
+
894
+ /* ESC [ sequences. */
895
+ if (seq[0] == '[') {
896
+ if (seq[1] >= '0' && seq[1] <= '9') {
897
+ /* Extended escape, read additional byte. */
898
+ if (read(l->ifd, seq + 2, 1) == -1) {
899
+ return ESC_NULL;
900
+ }
901
+ if (seq[2] == '~') {
902
+ switch (seq[1]) {
903
+ case '3':
904
+ return ESC_DELETE;
905
+ }
906
+ }
907
+ } else {
908
+ switch (seq[1]) {
909
+ case 'A':
910
+ return ESC_UP;
911
+ case 'B':
912
+ return ESC_DOWN;
913
+ case 'C':
914
+ return ESC_RIGHT;
915
+ case 'D':
916
+ return ESC_LEFT;
917
+ case 'H':
918
+ return ESC_HOME;
919
+ case 'F':
920
+ return ESC_END;
921
+ }
922
+ }
923
+ }
924
+
925
+ /* ESC O sequences. */
926
+ else if (seq[0] == 'O') {
927
+ switch (seq[1]) {
928
+ case 'H':
929
+ return ESC_HOME;
930
+ case 'F':
931
+ return ESC_END;
932
+ }
933
+ }
934
+ return ESC_NULL;
935
+ }
936
+
411
937
  /* This is an helper function for linenoiseEdit*() and is called when the
412
938
  * user types the <tab> key in order to complete the string currently in the
413
939
  * input.
@@ -418,11 +944,11 @@ static void refreshLineWithCompletion(struct linenoiseState *ls, linenoiseComple
418
944
  * If the function returns non-zero, the caller should handle the
419
945
  * returned value as a byte read from the standard input, and process
420
946
  * it as usually: this basically means that the function may return a byte
421
- * read from the termianl but not processed. Otherwise, if zero is returned,
947
+ * read from the terminal but not processed. Otherwise, if zero is returned,
422
948
  * the input was consumed by the completeLine() function to navigate the
423
949
  * possible completions, and the caller should read for the next characters
424
950
  * from stdin. */
425
- static int completeLine(struct linenoiseState *ls, int keypressed) {
951
+ static int completeLine(struct linenoiseState * ls, int keypressed, ESC_TYPE esc_type) {
426
952
  linenoiseCompletions lc;
427
953
  int nwritten;
428
954
  char c = keypressed;
@@ -432,31 +958,31 @@ static int completeLine(struct linenoiseState *ls, int keypressed) {
432
958
  linenoiseBeep();
433
959
  ls->in_completion = 0;
434
960
  } else {
435
- switch(c) {
436
- case 9: /* tab */
437
- if (ls->in_completion == 0) {
438
- ls->in_completion = 1;
439
- ls->completion_idx = 0;
440
- } else {
441
- ls->completion_idx = (ls->completion_idx + 1) % (lc.len + 1);
442
- if (ls->completion_idx == lc.len) linenoiseBeep();
443
- }
444
- c = 0;
445
- break;
446
- case 27: /* escape */
447
- /* Re-show original buffer */
448
- if (ls->completion_idx < lc.len) refreshLine(ls);
449
- ls->in_completion = 0;
450
- c = 0;
451
- break;
452
- default:
453
- /* Update buffer and return */
454
- if (ls->completion_idx < lc.len) {
455
- nwritten = snprintf(ls->buf, ls->buflen, "%s", lc.cvec[ls->completion_idx]);
456
- ls->len = ls->pos = nwritten;
961
+ if (c == TAB) {
962
+ if (ls->in_completion == 0) {
963
+ ls->in_completion = 1;
964
+ ls->completion_idx = 0;
965
+ } else {
966
+ ls->completion_idx = (ls->completion_idx + 1) % (lc.len + 1);
967
+ if (ls->completion_idx == lc.len) {
968
+ linenoiseBeep();
457
969
  }
458
- ls->in_completion = 0;
459
- break;
970
+ }
971
+ c = 0;
972
+ } else if (c == ESC && esc_type == ESC_NULL) {
973
+ /* Re-show original buffer */
974
+ if (ls->completion_idx < lc.len) {
975
+ refreshLine(ls);
976
+ }
977
+ ls->in_completion = 0;
978
+ c = 0;
979
+ } else {
980
+ /* Update buffer and return */
981
+ if (ls->completion_idx < lc.len) {
982
+ nwritten = snprintf(ls->buf, ls->buflen, "%s", lc.cvec[ls->completion_idx]);
983
+ ls->len = ls->pos = nwritten;
984
+ }
985
+ ls->in_completion = 0;
460
986
  }
461
987
 
462
988
  /* Show completion or original buffer */
@@ -508,16 +1034,30 @@ void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
508
1034
  lc->cvec[lc->len++] = copy.release();
509
1035
  }
510
1036
 
1037
+ /* Get column length from begining of buffer to current byte position */
1038
+ static size_t columnPos(const char * buf, size_t buf_len, size_t pos) {
1039
+ size_t ret = 0;
1040
+ size_t off = 0;
1041
+ while (off < pos) {
1042
+ size_t col_len;
1043
+ size_t len = nextCharLen(buf, buf_len, off, &col_len);
1044
+ off += len;
1045
+ ret += col_len;
1046
+ }
1047
+ return ret;
1048
+ }
1049
+
511
1050
  /* Helper of refreshSingleLine() and refreshMultiLine() to show hints
512
1051
  * to the right of the prompt. */
513
- static void refreshShowHints(std::string & ab, struct linenoiseState * l, int plen) {
1052
+ static void refreshShowHints(std::string & ab, struct linenoiseState * l, int pcollen) {
514
1053
  char seq[64];
515
- if (hintsCallback && plen+l->len < l->cols) {
1054
+ size_t collen = pcollen + columnPos(l->buf, l->len, l->len);
1055
+ if (hintsCallback && collen < l->cols) {
516
1056
  int color = -1, bold = 0;
517
1057
  const char *hint = hintsCallback(l->buf,&color,&bold);
518
1058
  if (hint) {
519
1059
  int hintlen = strlen(hint);
520
- int hintmaxlen = l->cols-(plen+l->len);
1060
+ int hintmaxlen = l->cols - collen;
521
1061
  if (hintlen > hintmaxlen) hintlen = hintmaxlen;
522
1062
  if (bold == 1 && color == -1) color = 37;
523
1063
  if (color != -1 || bold != 0)
@@ -535,6 +1075,50 @@ static void refreshShowHints(std::string & ab, struct linenoiseState * l, int pl
535
1075
  }
536
1076
  }
537
1077
 
1078
+ /* Check if text is an ANSI escape sequence */
1079
+ static int isAnsiEscape(const char * buf, size_t buf_len, size_t * len) {
1080
+ if (buf_len > 2 && !memcmp("\033[", buf, 2)) {
1081
+ size_t off = 2;
1082
+ while (off < buf_len) {
1083
+ switch (buf[off++]) {
1084
+ case 'A':
1085
+ case 'B':
1086
+ case 'C':
1087
+ case 'D':
1088
+ case 'E':
1089
+ case 'F':
1090
+ case 'G':
1091
+ case 'H':
1092
+ case 'J':
1093
+ case 'K':
1094
+ case 'S':
1095
+ case 'T':
1096
+ case 'f':
1097
+ case 'm':
1098
+ *len = off;
1099
+ return 1;
1100
+ }
1101
+ }
1102
+ }
1103
+ return 0;
1104
+ }
1105
+
1106
+ /* Get column length of prompt text */
1107
+ static size_t promptTextColumnLen(const char * prompt, size_t plen) {
1108
+ char buf[LINENOISE_MAX_LINE];
1109
+ size_t buf_len = 0;
1110
+ size_t off = 0;
1111
+ while (off < plen) {
1112
+ size_t len;
1113
+ if (isAnsiEscape(prompt + off, plen - off, &len)) {
1114
+ off += len;
1115
+ continue;
1116
+ }
1117
+ buf[buf_len++] = prompt[off++];
1118
+ }
1119
+ return columnPos(buf, buf_len, buf_len);
1120
+ }
1121
+
538
1122
  /* Single line low level line refresh.
539
1123
  *
540
1124
  * Rewrite the currently edited line accordingly to the buffer content,
@@ -544,19 +1128,21 @@ static void refreshShowHints(std::string & ab, struct linenoiseState * l, int pl
544
1128
  * prompt, just write it, or both. */
545
1129
  static void refreshSingleLine(struct linenoiseState *l, int flags) {
546
1130
  char seq[64];
547
- size_t plen = strlen(l->prompt);
1131
+ size_t pcollen = promptTextColumnLen(l->prompt, strlen(l->prompt));
548
1132
  int fd = l->ofd;
549
1133
  char *buf = l->buf;
550
1134
  size_t len = l->len;
551
1135
  size_t pos = l->pos;
552
1136
  std::string ab;
553
- while((plen+pos) >= l->cols) {
554
- buf++;
555
- len--;
556
- pos--;
1137
+
1138
+ while ((pcollen + columnPos(buf, len, pos)) >= l->cols) {
1139
+ int chlen = nextCharLen(buf, len, 0, NULL);
1140
+ buf += chlen;
1141
+ len -= chlen;
1142
+ pos -= chlen;
557
1143
  }
558
- while (plen+len > l->cols) {
559
- len--;
1144
+ while (pcollen + columnPos(buf, len, len) > l->cols) {
1145
+ len -= prevCharLen(buf, len, len, NULL);
560
1146
  }
561
1147
 
562
1148
  /* Cursor to left edge */
@@ -574,7 +1160,7 @@ static void refreshSingleLine(struct linenoiseState *l, int flags) {
574
1160
  ab.append(buf, len);
575
1161
  }
576
1162
  /* Show hits if any. */
577
- refreshShowHints(ab, l, plen);
1163
+ refreshShowHints(ab, l, pcollen);
578
1164
  }
579
1165
 
580
1166
  /* Erase to right */
@@ -582,13 +1168,43 @@ static void refreshSingleLine(struct linenoiseState *l, int flags) {
582
1168
  ab.append(seq);
583
1169
  if (flags & REFRESH_WRITE) {
584
1170
  /* Move cursor to original position. */
585
- snprintf(seq,sizeof(seq),"\r\x1b[%dC", (int)(pos+plen));
1171
+ snprintf(seq, sizeof(seq), "\r\x1b[%dC", (int) (columnPos(buf, len, pos) + pcollen));
586
1172
  ab.append(seq);
587
1173
  }
588
1174
 
589
1175
  (void) !write(fd, ab.c_str(), ab.size()); /* Can't recover from write error. */
590
1176
  }
591
1177
 
1178
+ /* Get column length from begining of buffer to current byte position for multiline mode*/
1179
+ static size_t columnPosForMultiLine(const char * buf, size_t buf_len, size_t pos, size_t cols, size_t ini_pos) {
1180
+ size_t ret = 0;
1181
+ size_t colwid = ini_pos;
1182
+
1183
+ size_t off = 0;
1184
+ while (off < buf_len) {
1185
+ size_t col_len;
1186
+ size_t len = nextCharLen(buf, buf_len, off, &col_len);
1187
+
1188
+ int dif = (int) (colwid + col_len) - (int) cols;
1189
+ if (dif > 0) {
1190
+ ret += dif;
1191
+ colwid = col_len;
1192
+ } else if (dif == 0) {
1193
+ colwid = 0;
1194
+ } else {
1195
+ colwid += col_len;
1196
+ }
1197
+
1198
+ if (off >= pos) {
1199
+ break;
1200
+ }
1201
+ off += len;
1202
+ ret += col_len;
1203
+ }
1204
+
1205
+ return ret;
1206
+ }
1207
+
592
1208
  /* Multi line low level line refresh.
593
1209
  *
594
1210
  * Rewrite the currently edited line accordingly to the buffer content,
@@ -598,11 +1214,13 @@ static void refreshSingleLine(struct linenoiseState *l, int flags) {
598
1214
  * prompt, just write it, or both. */
599
1215
  static void refreshMultiLine(struct linenoiseState *l, int flags) {
600
1216
  char seq[64];
601
- int plen = strlen(l->prompt);
602
- int rows = (plen+l->len+l->cols-1)/l->cols; /* rows used by current buf. */
603
- int rpos = (plen+l->oldpos+l->cols)/l->cols; /* cursor relative row. */
1217
+ size_t pcollen = promptTextColumnLen(l->prompt, strlen(l->prompt));
1218
+ int colpos = columnPosForMultiLine(l->buf, l->len, l->len, l->cols, pcollen);
1219
+ int colpos2; /* cursor column position. */
1220
+ int rows = (pcollen + colpos + l->cols - 1) / l->cols; /* rows used by current buf. */
1221
+ int rpos = (pcollen + l->oldcolpos + l->cols) / l->cols; /* cursor relative row. */
604
1222
  int rpos2; /* rpos after refresh. */
605
- int col; /* colum position, zero-based. */
1223
+ int col; /* column position, zero-based. */
606
1224
  int old_rows = l->oldrows;
607
1225
  int fd = l->ofd, j;
608
1226
  std::string ab;
@@ -611,15 +1229,13 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
611
1229
  /* First step: clear all the lines used before. To do so start by
612
1230
  * going to the last row. */
613
1231
  if (flags & REFRESH_CLEAN) {
614
- if (old_rows-rpos > 0) {
615
- lndebug("go down %d", old_rows-rpos);
1232
+ if (old_rows - rpos > 0) {
616
1233
  snprintf(seq,64,"\x1b[%dB", old_rows-rpos);
617
1234
  ab.append(seq);
618
1235
  }
619
1236
 
620
1237
  /* Now for every row clear it, go up. */
621
- for (j = 0; j < old_rows-1; j++) {
622
- lndebug("clear+up");
1238
+ for (j = 0; j < old_rows - 1; j++) {
623
1239
  snprintf(seq,64,"\r\x1b[0K\x1b[1A");
624
1240
  ab.append(seq);
625
1241
  }
@@ -627,11 +1243,13 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
627
1243
 
628
1244
  if (flags & REFRESH_ALL) {
629
1245
  /* Clean the top line. */
630
- lndebug("clear");
631
1246
  snprintf(seq,64,"\r\x1b[0K");
632
1247
  ab.append(seq);
633
1248
  }
634
1249
 
1250
+ /* Get column length to cursor position */
1251
+ colpos2 = columnPosForMultiLine(l->buf, l->len, l->pos, l->cols, pcollen);
1252
+
635
1253
  if (flags & REFRESH_WRITE) {
636
1254
  /* Write the prompt and the current buffer content */
637
1255
  ab.append(l->prompt);
@@ -644,15 +1262,11 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
644
1262
  }
645
1263
 
646
1264
  /* Show hits if any. */
647
- refreshShowHints(ab, l, plen);
1265
+ refreshShowHints(ab, l, pcollen);
648
1266
 
649
1267
  /* If we are at the very end of the screen with our prompt, we need to
650
1268
  * emit a newline and move the prompt to the first column. */
651
- if (l->pos &&
652
- l->pos == l->len &&
653
- (l->pos+plen) % l->cols == 0)
654
- {
655
- lndebug("<newline>");
1269
+ if (l->pos && l->pos == l->len && (colpos2 + pcollen) % l->cols == 0) {
656
1270
  ab.append("\n");
657
1271
  snprintf(seq,64,"\r");
658
1272
  ab.append(seq);
@@ -661,19 +1275,16 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
661
1275
  }
662
1276
 
663
1277
  /* Move cursor to right position. */
664
- rpos2 = (plen+l->pos+l->cols)/l->cols; /* Current cursor relative row */
665
- lndebug("rpos2 %d", rpos2);
1278
+ rpos2 = (pcollen + colpos2 + l->cols) / l->cols; /* Current cursor relative row */
666
1279
 
667
- /* Go up till we reach the expected positon. */
668
- if (rows-rpos2 > 0) {
669
- lndebug("go-up %d", rows-rpos2);
1280
+ /* Go up till we reach the expected position. */
1281
+ if (rows - rpos2 > 0) {
670
1282
  snprintf(seq,64,"\x1b[%dA", rows-rpos2);
671
1283
  ab.append(seq);
672
1284
  }
673
1285
 
674
1286
  /* Set column. */
675
- col = (plen+(int)l->pos) % (int)l->cols;
676
- lndebug("set col %d", 1+col);
1287
+ col = (pcollen + colpos2) % l->cols;
677
1288
  if (col)
678
1289
  snprintf(seq,64,"\r\x1b[%dC", col);
679
1290
  else
@@ -681,8 +1292,8 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
681
1292
  ab.append(seq);
682
1293
  }
683
1294
 
684
- lndebug("\n");
685
- l->oldpos = l->pos;
1295
+ l->oldcolpos = colpos2;
1296
+
686
1297
  (void) !write(fd, ab.c_str(), ab.size()); /* Can't recover from write error. */
687
1298
  }
688
1299
 
@@ -720,26 +1331,36 @@ void linenoiseShow(struct linenoiseState *l) {
720
1331
  /* Insert the character 'c' at cursor current position.
721
1332
  *
722
1333
  * On error writing to the terminal -1 is returned, otherwise 0. */
723
- static int linenoiseEditInsert(struct linenoiseState * l, char c) {
724
- if (l->len < l->buflen) {
1334
+ static int linenoiseEditInsert(struct linenoiseState * l, const char * cbuf, int clen) {
1335
+ if (l->len + clen <= l->buflen) {
725
1336
  if (l->len == l->pos) {
726
- l->buf[l->pos] = c;
727
- l->pos++;
728
- l->len++;
1337
+ memcpy(&l->buf[l->pos], cbuf, clen);
1338
+ l->pos += clen;
1339
+ l->len += clen;
1340
+ ;
729
1341
  l->buf[l->len] = '\0';
730
- if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) {
1342
+ if ((!mlmode && promptTextColumnLen(l->prompt, l->plen) + columnPos(l->buf, l->len, l->len) < l->cols &&
1343
+ !hintsCallback)) {
731
1344
  /* Avoid a full update of the line in the
732
1345
  * trivial case. */
733
- char d = (maskmode==1) ? '*' : c;
734
- if (write(l->ofd,&d,1) == -1) return -1;
1346
+ if (maskmode == 1) {
1347
+ static const char d = '*';
1348
+ if (write(l->ofd, &d, 1) == -1) {
1349
+ return -1;
1350
+ }
1351
+ } else {
1352
+ if (write(l->ofd, cbuf, clen) == -1) {
1353
+ return -1;
1354
+ }
1355
+ }
735
1356
  } else {
736
1357
  refreshLine(l);
737
1358
  }
738
1359
  } else {
739
- memmove(l->buf+l->pos+1,l->buf+l->pos,l->len-l->pos);
740
- l->buf[l->pos] = c;
741
- l->len++;
742
- l->pos++;
1360
+ memmove(l->buf + l->pos + clen, l->buf + l->pos, l->len - l->pos);
1361
+ memcpy(&l->buf[l->pos], cbuf, clen);
1362
+ l->pos += clen;
1363
+ l->len += clen;
743
1364
  l->buf[l->len] = '\0';
744
1365
  refreshLine(l);
745
1366
  }
@@ -750,7 +1371,7 @@ static int linenoiseEditInsert(struct linenoiseState * l, char c) {
750
1371
  /* Move cursor on the left. */
751
1372
  static void linenoiseEditMoveLeft(struct linenoiseState * l) {
752
1373
  if (l->pos > 0) {
753
- l->pos--;
1374
+ l->pos -= prevCharLen(l->buf, l->len, l->pos, NULL);
754
1375
  refreshLine(l);
755
1376
  }
756
1377
  }
@@ -758,7 +1379,7 @@ static void linenoiseEditMoveLeft(struct linenoiseState * l) {
758
1379
  /* Move cursor on the right. */
759
1380
  static void linenoiseEditMoveRight(struct linenoiseState * l) {
760
1381
  if (l->pos != l->len) {
761
- l->pos++;
1382
+ l->pos += nextCharLen(l->buf, l->len, l->pos, NULL);
762
1383
  refreshLine(l);
763
1384
  }
764
1385
  }
@@ -810,8 +1431,9 @@ static void linenoiseEditHistoryNext(struct linenoiseState * l, int dir) {
810
1431
  * position. Basically this is what happens with the "Delete" keyboard key. */
811
1432
  static void linenoiseEditDelete(struct linenoiseState * l) {
812
1433
  if (l->len > 0 && l->pos < l->len) {
813
- memmove(l->buf+l->pos,l->buf+l->pos+1,l->len-l->pos-1);
814
- l->len--;
1434
+ int chlen = nextCharLen(l->buf, l->len, l->pos, NULL);
1435
+ memmove(l->buf + l->pos, l->buf + l->pos + chlen, l->len - l->pos - chlen);
1436
+ l->len -= chlen;
815
1437
  l->buf[l->len] = '\0';
816
1438
  refreshLine(l);
817
1439
  }
@@ -820,15 +1442,16 @@ static void linenoiseEditDelete(struct linenoiseState * l) {
820
1442
  /* Backspace implementation. */
821
1443
  static void linenoiseEditBackspace(struct linenoiseState * l) {
822
1444
  if (l->pos > 0 && l->len > 0) {
823
- memmove(l->buf+l->pos-1,l->buf+l->pos,l->len-l->pos);
824
- l->pos--;
825
- l->len--;
1445
+ int chlen = prevCharLen(l->buf, l->len, l->pos, NULL);
1446
+ memmove(l->buf + l->pos - chlen, l->buf + l->pos, l->len - l->pos);
1447
+ l->pos -= chlen;
1448
+ l->len -= chlen;
826
1449
  l->buf[l->len] = '\0';
827
1450
  refreshLine(l);
828
1451
  }
829
1452
  }
830
1453
 
831
- /* Delete the previosu word, maintaining the cursor at the start of the
1454
+ /* Delete the previous word, maintaining the cursor at the start of the
832
1455
  * current word. */
833
1456
  static void linenoiseEditDeletePrevWord(struct linenoiseState * l) {
834
1457
  size_t old_pos = l->pos;
@@ -855,7 +1478,7 @@ static void linenoiseEditDeletePrevWord(struct linenoiseState * l) {
855
1478
  * each time there is some data arriving in the standard input.
856
1479
  *
857
1480
  * The user can also call linenoiseEditHide() and linenoiseEditShow() if it
858
- * is required to show some input arriving asyncronously, without mixing
1481
+ * is required to show some input arriving asynchronously, without mixing
859
1482
  * it with the currently edited line.
860
1483
  *
861
1484
  * When linenoiseEditFeed() returns non-NULL, the user finished with the
@@ -878,7 +1501,7 @@ int linenoiseEditStart(struct linenoiseState *l, int stdin_fd, int stdout_fd, ch
878
1501
  l->buflen = buflen;
879
1502
  l->prompt = prompt;
880
1503
  l->plen = strlen(prompt);
881
- l->oldpos = l->pos = 0;
1504
+ l->oldcolpos = l->pos = 0;
882
1505
  l->len = 0;
883
1506
 
884
1507
  /* Enter raw mode. */
@@ -890,7 +1513,7 @@ int linenoiseEditStart(struct linenoiseState *l, int stdin_fd, int stdout_fd, ch
890
1513
 
891
1514
  /* Buffer starts empty. */
892
1515
  l->buf[0] = '\0';
893
- l->buflen--; /* Make sure there is always space for the nulterm */
1516
+ l->buflen--; /* Make sure there is always space for the nullterm */
894
1517
 
895
1518
  /* If stdin is not a tty, stop here with the initialization. We
896
1519
  * will actually just read a line from standard input in blocking
@@ -907,6 +1530,159 @@ int linenoiseEditStart(struct linenoiseState *l, int stdin_fd, int stdout_fd, ch
907
1530
 
908
1531
  const char* linenoiseEditMore = "If you see this, you are misusing the API: when linenoiseEditFeed() is called, if it returns linenoiseEditMore the user is yet editing the line. See the README file for more information.";
909
1532
 
1533
+ static const char * handleEnterKey(struct linenoiseState * l) {
1534
+ --history_len;
1535
+ free(history[history_len]);
1536
+ if (mlmode) {
1537
+ linenoiseEditMoveEnd(l);
1538
+ }
1539
+ if (hintsCallback) {
1540
+ /* Force a refresh without hints to leave the previous
1541
+ * line as the user typed it after a newline. */
1542
+ linenoiseHintsCallback * hc = hintsCallback;
1543
+ hintsCallback = NULL;
1544
+ refreshLine(l);
1545
+ hintsCallback = hc;
1546
+ }
1547
+
1548
+ return strdup(l->buf);
1549
+ }
1550
+
1551
+ static const char * handleCtrlCKey() {
1552
+ errno = EAGAIN;
1553
+ return NULL;
1554
+ }
1555
+
1556
+ static const char * handleCtrlDKey(struct linenoiseState * l) {
1557
+ if (l->len > 0) {
1558
+ linenoiseEditDelete(l);
1559
+ return linenoiseEditMore;
1560
+ }
1561
+
1562
+ --history_len;
1563
+ free(history[history_len]);
1564
+ errno = ENOENT;
1565
+ return NULL;
1566
+ }
1567
+
1568
+ static void handleCtrlTKey(struct linenoiseState * l) {
1569
+ if (l->pos > 0 && l->pos < l->len) {
1570
+ auto prev_chlen = prevCharLen(l->buf, l->len, l->pos, NULL);
1571
+ auto curr_chlen = nextCharLen(l->buf, l->len, l->pos, NULL);
1572
+
1573
+ std::string prev_char(prev_chlen, 0);
1574
+ memcpy(prev_char.data(), l->buf + l->pos - prev_chlen, prev_chlen);
1575
+ memmove(l->buf + l->pos - prev_chlen, l->buf + l->pos, curr_chlen);
1576
+ memmove(l->buf + l->pos - prev_chlen + curr_chlen, prev_char.data(), prev_chlen);
1577
+
1578
+ l->pos = l->pos - prev_chlen + curr_chlen;
1579
+ if (l->pos + prev_chlen != l->len) {
1580
+ l->pos += prev_chlen;
1581
+ }
1582
+
1583
+ refreshLine(l);
1584
+ }
1585
+ }
1586
+
1587
+ static void handleEscapeSequence(struct linenoiseState * l, int esc_type) {
1588
+ switch (esc_type) {
1589
+ case ESC_NULL:
1590
+ break;
1591
+ case ESC_DELETE:
1592
+ linenoiseEditDelete(l);
1593
+ break;
1594
+ case ESC_UP:
1595
+ linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV);
1596
+ break;
1597
+ case ESC_DOWN:
1598
+ linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT);
1599
+ break;
1600
+ case ESC_RIGHT:
1601
+ linenoiseEditMoveRight(l);
1602
+ break;
1603
+ case ESC_LEFT:
1604
+ linenoiseEditMoveLeft(l);
1605
+ break;
1606
+ case ESC_HOME:
1607
+ linenoiseEditMoveHome(l);
1608
+ break;
1609
+ case ESC_END:
1610
+ linenoiseEditMoveEnd(l);
1611
+ break;
1612
+ }
1613
+ }
1614
+
1615
+ static void handleCtrlUKey(struct linenoiseState * l) {
1616
+ l->buf[0] = '\0';
1617
+ l->pos = l->len = 0;
1618
+ refreshLine(l);
1619
+ }
1620
+
1621
+ static void handleCtrlKKey(struct linenoiseState * l) {
1622
+ l->buf[l->pos] = '\0';
1623
+ l->len = l->pos;
1624
+ refreshLine(l);
1625
+ }
1626
+
1627
+ static const char * processInputCharacter(struct linenoiseState * l, int c, char * cbuf, int nread, int esc_type) {
1628
+ switch (c) {
1629
+ case ENTER:
1630
+ return handleEnterKey(l);
1631
+ case CTRL_C:
1632
+ return handleCtrlCKey();
1633
+ case BACKSPACE:
1634
+ case CTRL_H:
1635
+ linenoiseEditBackspace(l);
1636
+ break;
1637
+ case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the
1638
+ line is empty, act as end-of-file. */
1639
+ return handleCtrlDKey(l);
1640
+ case CTRL_T:
1641
+ handleCtrlTKey(l);
1642
+ break;
1643
+ case CTRL_B:
1644
+ linenoiseEditMoveLeft(l);
1645
+ break;
1646
+ case CTRL_F:
1647
+ linenoiseEditMoveRight(l);
1648
+ break;
1649
+ case CTRL_P:
1650
+ linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV);
1651
+ break;
1652
+ case CTRL_N:
1653
+ linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT);
1654
+ break;
1655
+ case ESC:
1656
+ handleEscapeSequence(l, esc_type);
1657
+ break;
1658
+ default:
1659
+ if (linenoiseEditInsert(l, cbuf, nread)) {
1660
+ return NULL;
1661
+ }
1662
+ break;
1663
+ case CTRL_U: /* Ctrl+u, delete the whole line. */
1664
+ handleCtrlUKey(l);
1665
+ break;
1666
+ case CTRL_K: /* Ctrl+k, delete from current to end of line. */
1667
+ handleCtrlKKey(l);
1668
+ break;
1669
+ case CTRL_A: /* Ctrl+a, go to the start of the line */
1670
+ linenoiseEditMoveHome(l);
1671
+ break;
1672
+ case CTRL_E: /* ctrl+e, go to the end of the line */
1673
+ linenoiseEditMoveEnd(l);
1674
+ break;
1675
+ case CTRL_L: /* ctrl+l, clear screen */
1676
+ linenoiseClearScreen();
1677
+ refreshLine(l);
1678
+ break;
1679
+ case CTRL_W: /* ctrl+w, delete previous word */
1680
+ linenoiseEditDeletePrevWord(l);
1681
+ break;
1682
+ }
1683
+ return linenoiseEditMore;
1684
+ }
1685
+
910
1686
  /* This function is part of the multiplexed API of linenoise, see the top
911
1687
  * comment on linenoiseEditStart() for more information. Call this function
912
1688
  * each time there is some data to read from the standard input file
@@ -925,163 +1701,33 @@ const char* linenoiseEditMore = "If you see this, you are misusing the API: when
925
1701
  *
926
1702
  * Some other errno: I/O error.
927
1703
  */
928
- const char *linenoiseEditFeed(struct linenoiseState *l) {
929
- /* Not a TTY, pass control to line reading without character
930
- * count limits. */
1704
+ const char * linenoiseEditFeed(struct linenoiseState * l) {
1705
+ /* Not a TTY, pass control to line reading without character count
1706
+ * limits. */
931
1707
  if (!isatty(l->ifd)) return linenoiseNoTTY();
932
1708
 
933
- char c;
1709
+ int c;
934
1710
  int nread;
935
- char seq[3];
1711
+ char cbuf[32];
936
1712
 
937
- nread = read(l->ifd,&c,1);
1713
+ nread = readCode(l->ifd, cbuf, sizeof(cbuf), &c);
938
1714
  if (nread <= 0) return NULL;
939
1715
 
1716
+ auto esc_type = ESC_NULL;
1717
+ if (c == ESC) {
1718
+ esc_type = readEscapeSequence(l);
1719
+ }
1720
+
940
1721
  /* Only autocomplete when the callback is set. It returns < 0 when
941
1722
  * there was an error reading from fd. Otherwise it will return the
942
1723
  * character that should be handled next. */
943
1724
  if ((l->in_completion || c == 9) && completionCallback != NULL) {
944
- c = completeLine(l,c);
1725
+ c = completeLine(l, c, esc_type);
945
1726
  /* Read next character when 0 */
946
1727
  if (c == 0) return linenoiseEditMore;
947
1728
  }
948
1729
 
949
- switch(c) {
950
- case ENTER: /* enter */
951
- history_len--;
952
- free(history[history_len]);
953
- if (mlmode) linenoiseEditMoveEnd(l);
954
- if (hintsCallback) {
955
- /* Force a refresh without hints to leave the previous
956
- * line as the user typed it after a newline. */
957
- linenoiseHintsCallback *hc = hintsCallback;
958
- hintsCallback = NULL;
959
- refreshLine(l);
960
- hintsCallback = hc;
961
- }
962
- return strdup(l->buf);
963
- case CTRL_C: /* ctrl-c */
964
- errno = EAGAIN;
965
- return NULL;
966
- case BACKSPACE: /* backspace */
967
- case 8: /* ctrl-h */
968
- linenoiseEditBackspace(l);
969
- break;
970
- case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the
971
- line is empty, act as end-of-file. */
972
- if (l->len > 0) {
973
- linenoiseEditDelete(l);
974
- } else {
975
- history_len--;
976
- free(history[history_len]);
977
- errno = ENOENT;
978
- return NULL;
979
- }
980
- break;
981
- case CTRL_T: /* ctrl-t, swaps current character with previous. */
982
- if (l->pos > 0 && l->pos < l->len) {
983
- int aux = l->buf[l->pos-1];
984
- l->buf[l->pos-1] = l->buf[l->pos];
985
- l->buf[l->pos] = aux;
986
- if (l->pos != l->len-1) l->pos++;
987
- refreshLine(l);
988
- }
989
- break;
990
- case CTRL_B: /* ctrl-b */
991
- linenoiseEditMoveLeft(l);
992
- break;
993
- case CTRL_F: /* ctrl-f */
994
- linenoiseEditMoveRight(l);
995
- break;
996
- case CTRL_P: /* ctrl-p */
997
- linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV);
998
- break;
999
- case CTRL_N: /* ctrl-n */
1000
- linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT);
1001
- break;
1002
- case ESC: /* escape sequence */
1003
- /* Read the next two bytes representing the escape sequence.
1004
- * Use two calls to handle slow terminals returning the two
1005
- * chars at different times. */
1006
- if (read(l->ifd,seq,1) == -1) break;
1007
- if (read(l->ifd,seq+1,1) == -1) break;
1008
-
1009
- /* ESC [ sequences. */
1010
- if (seq[0] == '[') {
1011
- if (seq[1] >= '0' && seq[1] <= '9') {
1012
- /* Extended escape, read additional byte. */
1013
- if (read(l->ifd,seq+2,1) == -1) break;
1014
- if (seq[2] == '~') {
1015
- switch(seq[1]) {
1016
- case '3': /* Delete key. */
1017
- linenoiseEditDelete(l);
1018
- break;
1019
- }
1020
- }
1021
- } else {
1022
- switch(seq[1]) {
1023
- case 'A': /* Up */
1024
- linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV);
1025
- break;
1026
- case 'B': /* Down */
1027
- linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT);
1028
- break;
1029
- case 'C': /* Right */
1030
- linenoiseEditMoveRight(l);
1031
- break;
1032
- case 'D': /* Left */
1033
- linenoiseEditMoveLeft(l);
1034
- break;
1035
- case 'H': /* Home */
1036
- linenoiseEditMoveHome(l);
1037
- break;
1038
- case 'F': /* End*/
1039
- linenoiseEditMoveEnd(l);
1040
- break;
1041
- }
1042
- }
1043
- }
1044
-
1045
- /* ESC O sequences. */
1046
- else if (seq[0] == 'O') {
1047
- switch(seq[1]) {
1048
- case 'H': /* Home */
1049
- linenoiseEditMoveHome(l);
1050
- break;
1051
- case 'F': /* End*/
1052
- linenoiseEditMoveEnd(l);
1053
- break;
1054
- }
1055
- }
1056
- break;
1057
- default:
1058
- if (linenoiseEditInsert(l,c)) return NULL;
1059
- break;
1060
- case CTRL_U: /* Ctrl+u, delete the whole line. */
1061
- l->buf[0] = '\0';
1062
- l->pos = l->len = 0;
1063
- refreshLine(l);
1064
- break;
1065
- case CTRL_K: /* Ctrl+k, delete from current to end of line. */
1066
- l->buf[l->pos] = '\0';
1067
- l->len = l->pos;
1068
- refreshLine(l);
1069
- break;
1070
- case CTRL_A: /* Ctrl+a, go to the start of the line */
1071
- linenoiseEditMoveHome(l);
1072
- break;
1073
- case CTRL_E: /* ctrl+e, go to the end of the line */
1074
- linenoiseEditMoveEnd(l);
1075
- break;
1076
- case CTRL_L: /* ctrl+l, clear screen */
1077
- linenoiseClearScreen();
1078
- refreshLine(l);
1079
- break;
1080
- case CTRL_W: /* ctrl+w, delete previous word */
1081
- linenoiseEditDeletePrevWord(l);
1082
- break;
1083
- }
1084
- return linenoiseEditMore;
1730
+ return processInputCharacter(l, c, cbuf, nread, esc_type);
1085
1731
  }
1086
1732
 
1087
1733
  /* This is part of the multiplexed linenoise API. See linenoiseEditStart()
@@ -1095,7 +1741,7 @@ void linenoiseEditStop(struct linenoiseState *l) {
1095
1741
  }
1096
1742
 
1097
1743
  /* This just implements a blocking loop for the multiplexed API.
1098
- * In many applications that are not event-drivern, we can just call
1744
+ * In many applications that are not event-driven, we can just call
1099
1745
  * the blocking linenoise API, wait for the user to complete the editing
1100
1746
  * and return the buffer. */
1101
1747
  static const char *linenoiseBlockingEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt)
@@ -1135,8 +1781,7 @@ void linenoisePrintKeyCodes(void) {
1135
1781
  quit[sizeof(quit)-1] = c; /* Insert current char on the right. */
1136
1782
  if (memcmp(quit,"quit",sizeof(quit)) == 0) break;
1137
1783
 
1138
- printf("'%c' %02x (%d) (type quit to exit)\n",
1139
- isprint(c) ? c : '?', (int)c, (int)c);
1784
+ printf("'%c' %02x (%d) (type quit to exit)\n", isprint((int) c) ? c : '?', (int) c, (int) c);
1140
1785
  printf("\r"); /* Go left edge manually, we are in raw mode. */
1141
1786
  fflush(stdout);
1142
1787
  }