@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.
- package/bin/darwin/arm64/llama-node.node +0 -0
- package/bin/darwin/x64/llama-node.node +0 -0
- package/bin/linux/arm64/llama-node.node +0 -0
- package/bin/linux/x64/llama-node.node +0 -0
- package/bin/linux-cuda/arm64/llama-node.node +0 -0
- package/bin/linux-cuda/x64/llama-node.node +0 -0
- package/bin/linux-vulkan/arm64/llama-node.node +0 -0
- package/bin/linux-vulkan/x64/llama-node.node +0 -0
- package/bin/win32/arm64/llama-node.node +0 -0
- package/bin/win32/arm64/node.lib +0 -0
- package/bin/win32/x64/llama-node.node +0 -0
- package/bin/win32/x64/node.lib +0 -0
- package/bin/win32-vulkan/arm64/llama-node.node +0 -0
- package/bin/win32-vulkan/arm64/node.lib +0 -0
- package/bin/win32-vulkan/x64/llama-node.node +0 -0
- package/bin/win32-vulkan/x64/node.lib +0 -0
- package/lib/binding.ts +2 -1
- package/package.json +1 -1
- package/src/LlamaCompletionWorker.cpp +14 -0
- package/src/LlamaContext.cpp +110 -79
- package/src/LlamaContext.h +1 -1
- package/src/common.hpp +1 -2
- package/src/llama.cpp/.github/workflows/build.yml +95 -13
- package/src/llama.cpp/.github/workflows/docker.yml +2 -0
- package/src/llama.cpp/.github/workflows/labeler.yml +1 -1
- package/src/llama.cpp/.github/workflows/server.yml +2 -0
- package/src/llama.cpp/common/CMakeLists.txt +23 -6
- package/src/llama.cpp/common/arg.cpp +292 -14
- package/src/llama.cpp/common/chat.cpp +1128 -315
- package/src/llama.cpp/common/chat.h +135 -0
- package/src/llama.cpp/common/common.cpp +27 -171
- package/src/llama.cpp/common/common.h +41 -73
- package/src/llama.cpp/common/json-schema-to-grammar.cpp +4 -5
- package/src/llama.cpp/common/json-schema-to-grammar.h +0 -1
- package/src/llama.cpp/common/llguidance.cpp +3 -3
- package/src/llama.cpp/common/log.cpp +1 -0
- package/src/llama.cpp/common/log.h +2 -1
- package/src/llama.cpp/common/{chat-template.hpp → minja/chat-template.hpp} +21 -7
- package/src/llama.cpp/common/{minja.hpp → minja/minja.hpp} +61 -14
- package/src/llama.cpp/common/ngram-cache.cpp +1 -0
- package/src/llama.cpp/common/sampling.cpp +93 -49
- package/src/llama.cpp/common/speculative.cpp +6 -5
- package/src/llama.cpp/common/speculative.h +1 -1
- package/src/llama.cpp/docs/build.md +47 -9
- package/src/llama.cpp/examples/cvector-generator/cvector-generator.cpp +3 -1
- package/src/llama.cpp/examples/embedding/embedding.cpp +1 -0
- package/src/llama.cpp/examples/export-lora/export-lora.cpp +4 -2
- package/src/llama.cpp/examples/imatrix/imatrix.cpp +4 -4
- package/src/llama.cpp/examples/llama-bench/llama-bench.cpp +6 -5
- package/src/llama.cpp/examples/llama.android/llama/src/main/cpp/CMakeLists.txt +1 -1
- package/src/llama.cpp/examples/llama.android/llama/src/main/cpp/llama-android.cpp +1 -1
- package/src/llama.cpp/examples/llava/CMakeLists.txt +7 -0
- package/src/llama.cpp/examples/llava/clip.cpp +373 -107
- package/src/llama.cpp/examples/llava/clip.h +19 -3
- package/src/llama.cpp/examples/llava/gemma3-cli.cpp +341 -0
- package/src/llama.cpp/examples/llava/llava.cpp +4 -2
- package/src/llama.cpp/examples/llava/minicpmv-cli.cpp +30 -11
- package/src/llama.cpp/examples/lookahead/lookahead.cpp +1 -0
- package/src/llama.cpp/examples/main/main.cpp +73 -28
- package/src/llama.cpp/examples/parallel/parallel.cpp +1 -0
- package/src/llama.cpp/examples/passkey/passkey.cpp +1 -0
- package/src/llama.cpp/examples/perplexity/perplexity.cpp +1 -0
- package/src/llama.cpp/examples/quantize/quantize.cpp +1 -0
- package/src/llama.cpp/examples/run/linenoise.cpp/linenoise.cpp +882 -237
- package/src/llama.cpp/examples/run/linenoise.cpp/linenoise.h +35 -26
- package/src/llama.cpp/examples/run/run.cpp +115 -79
- package/src/llama.cpp/examples/server/CMakeLists.txt +1 -1
- package/src/llama.cpp/examples/server/httplib.h +381 -292
- package/src/llama.cpp/examples/server/server.cpp +134 -128
- package/src/llama.cpp/examples/server/utils.hpp +95 -106
- package/src/llama.cpp/examples/sycl/run-llama2.sh +2 -2
- package/src/llama.cpp/examples/tts/tts.cpp +251 -142
- package/src/llama.cpp/ggml/CMakeLists.txt +13 -1
- package/src/llama.cpp/ggml/include/ggml-alloc.h +1 -1
- package/src/llama.cpp/ggml/include/ggml-backend.h +3 -3
- package/src/llama.cpp/ggml/include/ggml-cpu.h +4 -1
- package/src/llama.cpp/ggml/include/ggml-metal.h +1 -1
- package/src/llama.cpp/ggml/include/ggml-vulkan.h +0 -2
- package/src/llama.cpp/ggml/include/ggml.h +6 -2
- package/src/llama.cpp/ggml/src/CMakeLists.txt +10 -7
- package/src/llama.cpp/ggml/src/ggml-alloc.c +24 -15
- package/src/llama.cpp/ggml/src/ggml-backend-impl.h +1 -1
- package/src/llama.cpp/ggml/src/ggml-backend-reg.cpp +58 -54
- package/src/llama.cpp/ggml/src/ggml-backend.cpp +10 -8
- package/src/llama.cpp/ggml/src/ggml-cann/ggml-cann.cpp +3 -2
- package/src/llama.cpp/ggml/src/ggml-cann/kernels/dup.cpp +3 -5
- package/src/llama.cpp/ggml/src/ggml-common.h +0 -2
- package/src/llama.cpp/ggml/src/ggml-cpu/CMakeLists.txt +132 -17
- package/src/llama.cpp/ggml/src/ggml-cpu/amx/amx.cpp +2 -1
- package/src/llama.cpp/ggml/src/ggml-cpu/cpu-feats-x86.cpp +4 -0
- package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu-aarch64.cpp +2 -1
- package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu-impl.h +156 -11
- package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu-quants.c +2235 -641
- package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu.c +1572 -198
- package/src/llama.cpp/ggml/src/ggml-cpu/ggml-cpu.cpp +24 -5
- package/src/llama.cpp/ggml/src/ggml-cpu/kleidiai/kernels.cpp +259 -0
- package/src/llama.cpp/ggml/src/ggml-cpu/kleidiai/kernels.h +61 -0
- package/src/llama.cpp/ggml/src/ggml-cpu/kleidiai/kleidiai.cpp +288 -0
- package/src/llama.cpp/ggml/src/ggml-cpu/kleidiai/kleidiai.h +17 -0
- package/src/llama.cpp/ggml/src/ggml-cpu/llamafile/sgemm.cpp +9 -8
- package/src/llama.cpp/ggml/src/ggml-cuda/CMakeLists.txt +16 -3
- package/src/llama.cpp/ggml/src/ggml-hip/CMakeLists.txt +14 -0
- package/src/llama.cpp/ggml/src/ggml-impl.h +1 -1
- package/src/llama.cpp/ggml/src/ggml-metal/CMakeLists.txt +4 -5
- package/src/llama.cpp/ggml/src/ggml-metal/ggml-metal-impl.h +235 -0
- package/src/llama.cpp/ggml/src/ggml-musa/CMakeLists.txt +6 -2
- package/src/llama.cpp/ggml/src/ggml-opencl/CMakeLists.txt +1 -0
- package/src/llama.cpp/ggml/src/ggml-opencl/ggml-opencl.cpp +246 -120
- package/src/llama.cpp/ggml/src/ggml-quants.c +114 -114
- package/src/llama.cpp/ggml/src/ggml-rpc/ggml-rpc.cpp +2 -1
- package/src/llama.cpp/ggml/src/ggml-sycl/CMakeLists.txt +2 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/backend.hpp +1 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/common.cpp +17 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/common.hpp +51 -10
- package/src/llama.cpp/ggml/src/ggml-sycl/convert.cpp +33 -4
- package/src/llama.cpp/ggml/src/ggml-sycl/convert.hpp +2 -2
- package/src/llama.cpp/ggml/src/ggml-sycl/cpy.cpp +701 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/cpy.hpp +11 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/dequantize.hpp +55 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/dmmv.cpp +136 -4
- package/src/llama.cpp/ggml/src/ggml-sycl/getrows.cpp +308 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/getrows.hpp +23 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/ggml-sycl.cpp +174 -728
- package/src/llama.cpp/ggml/src/ggml-sycl/mmvq.cpp +75 -77
- package/src/llama.cpp/ggml/src/ggml-sycl/softmax.cpp +3 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/sycl_hw.cpp +13 -0
- package/src/llama.cpp/ggml/src/ggml-sycl/sycl_hw.hpp +23 -0
- package/src/llama.cpp/ggml/src/ggml-vulkan/ggml-vulkan.cpp +949 -602
- package/src/llama.cpp/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +37 -3
- package/src/llama.cpp/ggml/src/ggml.c +9 -4
- package/src/llama.cpp/include/llama.h +32 -14
- package/src/llama.cpp/models/ggml-vocab-gpt-4o.gguf.inp +112 -0
- package/src/llama.cpp/models/ggml-vocab-gpt-4o.gguf.out +46 -0
- package/src/llama.cpp/requirements/requirements-all.txt +1 -0
- package/src/llama.cpp/requirements/requirements-tool_bench.txt +12 -0
- package/src/llama.cpp/requirements.txt +1 -0
- package/src/llama.cpp/src/llama-arch.cpp +21 -0
- package/src/llama.cpp/src/llama-arch.h +1 -0
- package/src/llama.cpp/src/llama-chat.cpp +1 -0
- package/src/llama.cpp/src/llama-grammar.cpp +183 -183
- package/src/llama.cpp/src/llama-grammar.h +13 -4
- package/src/llama.cpp/src/llama-impl.h +6 -6
- package/src/llama.cpp/src/llama-kv-cache.h +2 -1
- package/src/llama.cpp/src/llama-mmap.cpp +11 -1
- package/src/llama.cpp/src/llama-mmap.h +1 -0
- package/src/llama.cpp/src/llama-model.cpp +70 -6
- package/src/llama.cpp/src/llama-sampling.cpp +174 -67
- package/src/llama.cpp/src/llama-vocab.cpp +12 -0
- package/src/llama.cpp/src/llama.cpp +154 -5
- package/src/llama.cpp/src/unicode.cpp +9 -2
- package/src/llama.cpp/tests/test-backend-ops.cpp +171 -115
- package/src/llama.cpp/tests/test-chat-template.cpp +32 -22
- package/src/llama.cpp/tests/test-chat.cpp +691 -325
- package/src/llama.cpp/tests/test-gguf.cpp +4 -4
- package/src/llama.cpp/tests/test-json-schema-to-grammar.cpp +63 -63
- package/src/llama.cpp/tests/test-quantize-fns.cpp +1 -9
- package/src/llama.cpp/tests/test-sampling.cpp +15 -0
- package/src/llama.cpp/Sources/llama/llama.h +0 -4
- 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
|
|
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
|
|
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
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
-
|
|
459
|
-
|
|
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
|
|
1052
|
+
static void refreshShowHints(std::string & ab, struct linenoiseState * l, int pcollen) {
|
|
514
1053
|
char seq[64];
|
|
515
|
-
|
|
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-
|
|
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
|
|
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
|
-
|
|
554
|
-
|
|
555
|
-
len
|
|
556
|
-
|
|
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 (
|
|
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,
|
|
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+
|
|
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
|
-
|
|
602
|
-
int
|
|
603
|
-
int
|
|
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
|
|
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,
|
|
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 = (
|
|
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
|
|
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 = (
|
|
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
|
-
|
|
685
|
-
|
|
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
|
|
724
|
-
if (l->len
|
|
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]
|
|
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 &&
|
|
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
|
-
|
|
734
|
-
|
|
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+
|
|
740
|
-
l->buf[l->pos]
|
|
741
|
-
l->
|
|
742
|
-
l->
|
|
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
|
-
|
|
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
|
-
|
|
824
|
-
l->pos
|
|
825
|
-
l->
|
|
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
|
|
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
|
|
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->
|
|
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
|
|
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
|
-
*
|
|
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
|
-
|
|
1709
|
+
int c;
|
|
934
1710
|
int nread;
|
|
935
|
-
char
|
|
1711
|
+
char cbuf[32];
|
|
936
1712
|
|
|
937
|
-
nread =
|
|
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
|
-
|
|
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-
|
|
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
|
}
|