Skip to content

Commit fa5698c

Browse files
Add UTF8 support
This is the second half of the PR that I'm merging in from upstream. It adds UTF8 13.0 support by including an extra library to get the char width of those characters (the visual width that is). During testing things seem to work quite well. I'm impressed. Author: https://github.com/yhirose PR: antirez/linenoise#187
1 parent 92a0118 commit fa5698c

File tree

7 files changed

+593
-26
lines changed

7 files changed

+593
-26
lines changed

Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ default: extension lint test
77
example: extension
88
crystal run example/example.cr
99

10-
extension: src/lib/linenoise.o
10+
extension: src/lib/linenoise.o src/lib/utf8.o
1111

1212
src/lib/linenoise.o: ext/linenoise.c ext/linenoise.h
1313
$(CC) -o $@ $< $(CFLAGS)
1414

15+
src/lib/utf8.o: ext/utf8.c ext/utf8.h
16+
$(CC) -o $@ $< $(CFLAGS)
17+
1518
check: extension
1619
crystal build --no-codegen -o example_program example/example.cr
1720

@@ -35,3 +38,4 @@ test: specs expect
3538

3639
clean:
3740
rm -f src/lib/linenoise.o
41+
rm -f src/lib/utf8.o

ext/linenoise.c

+29-17
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
#include <sys/types.h>
120120
#include <sys/ioctl.h>
121121
#include "linenoise.h"
122+
#include "utf8.h"
122123

123124
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
124125
#define LINENOISE_MAX_LINE 4096
@@ -140,7 +141,7 @@ static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
140141
static int history_len = 0;
141142
static char **history = NULL;
142143

143-
enum KEY_ACTION{
144+
enum KEY_ACTION {
144145
KEY_NULL = 0, /* NULL */
145146
CTRL_A = 1, /* Ctrl+a */
146147
CTRL_B = 2, /* Ctrl-b */
@@ -189,41 +190,52 @@ FILE *lndebug_fp = NULL;
189190
#endif
190191

191192
/* ========================== Encoding functions ============================= */
193+
194+
typedef size_t (linenoisePrevCharLen)(const char *buf, size_t buf_len, size_t pos, size_t *col_len);
195+
typedef size_t (linenoiseNextCharLen)(const char *buf, size_t buf_len, size_t pos, size_t *col_len);
196+
typedef size_t (linenoiseReadCode)(int fd, char *buf, size_t buf_len, int* c);
197+
198+
/* Set default encoding functions */
199+
static linenoisePrevCharLen *prevCharLen = linenoiseUtf8PrevCharLen;
200+
static linenoiseNextCharLen *nextCharLen = linenoiseUtf8NextCharLen;
201+
static linenoiseReadCode *readCode = linenoiseUtf8ReadCode;
202+
192203
/* Get byte length and column length of the previous character */
193-
static size_t defaultPrevCharLen(const char *buf, size_t buf_len, size_t pos, size_t *col_len) {
204+
static size_t asciiPrevCharLen(const char *buf, size_t buf_len, size_t pos, size_t *col_len) {
194205
UNUSED(buf); UNUSED(buf_len); UNUSED(pos);
195206
if (col_len != NULL) *col_len = 1;
196207
return 1;
197208
}
198209

199210
/* Get byte length and column length of the next character */
200-
static size_t defaultNextCharLen(const char *buf, size_t buf_len, size_t pos, size_t *col_len) {
211+
static size_t asciiNextCharLen(const char *buf, size_t buf_len, size_t pos, size_t *col_len) {
201212
UNUSED(buf); UNUSED(buf_len); UNUSED(pos);
202213
if (col_len != NULL) *col_len = 1;
203214
return 1;
204215
}
205216

206217
/* Read bytes of the next character */
207-
static size_t defaultReadCode(int fd, char *buf, size_t buf_len, int* c) {
218+
static size_t asciiReadCode(int fd, char *buf, size_t buf_len, int* c) {
208219
if (buf_len < 1) return -1;
209220
int nread = read(fd,&buf[0],1);
210221
if (nread == 1) *c = buf[0];
211222
return nread;
212223
}
213224

214-
/* Set default encoding functions */
215-
static linenoisePrevCharLen *prevCharLen = defaultPrevCharLen;
216-
static linenoiseNextCharLen *nextCharLen = defaultNextCharLen;
217-
static linenoiseReadCode *readCode = defaultReadCode;
218-
219-
/* Set used defined encoding functions */
220-
void linenoiseSetEncodingFunctions(
221-
linenoisePrevCharLen *prevCharLenFunc,
222-
linenoiseNextCharLen *nextCharLenFunc,
223-
linenoiseReadCode *readCodeFunc) {
224-
prevCharLen = prevCharLenFunc;
225-
nextCharLen = nextCharLenFunc;
226-
readCode = readCodeFunc;
225+
/* Set string encoding functions */
226+
void linenoiseSetEncoding(enum STRING_ENCODING encoding) {
227+
switch(encoding) {
228+
case ASCII:
229+
prevCharLen = asciiPrevCharLen;
230+
nextCharLen = asciiNextCharLen;
231+
readCode = asciiReadCode;
232+
break;
233+
case UTF8:
234+
prevCharLen = linenoiseUtf8PrevCharLen;
235+
nextCharLen = linenoiseUtf8NextCharLen;
236+
readCode = linenoiseUtf8ReadCode;
237+
break;
238+
}
227239
}
228240

229241
/* Get column length from begining of buffer to current byte position */

ext/linenoise.h

+6-7
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,13 @@ void linenoisePrintKeyCodes(void);
106106
void linenoiseMaskModeEnable(void);
107107
void linenoiseMaskModeDisable(void);
108108

109-
typedef size_t (linenoisePrevCharLen)(const char *buf, size_t buf_len, size_t pos, size_t *col_len);
110-
typedef size_t (linenoiseNextCharLen)(const char *buf, size_t buf_len, size_t pos, size_t *col_len);
111-
typedef size_t (linenoiseReadCode)(int fd, char *buf, size_t buf_len, int* c);
109+
/* String encoding. */
110+
enum STRING_ENCODING {
111+
ASCII,
112+
UTF8 // default
113+
};
112114

113-
void linenoiseSetEncodingFunctions(
114-
linenoisePrevCharLen *prevCharLenFunc,
115-
linenoiseNextCharLen *nextCharLenFunc,
116-
linenoiseReadCode *readCodeFunc);
115+
void linenoiseSetEncoding(enum STRING_ENCODING);
117116

118117
#ifdef __cplusplus
119118
}

0 commit comments

Comments
 (0)