El código actual no admite cadenas multibyte, por ejemplo, cadenas que tienen caracteres Unicode más allá del rango ASCII. Los cambios de columna para refreshLine se calculan usando strlen () que devuelve 2 en lugar de 1 para un carácter de 2 bytes como 'Ş' en turco.
La biblioteca debe usar mbstowcs () u otras funciones para obtener el número de caracteres en lugar del número de bytes para el procesamiento de columnas (flechas arriba, abajo, borrar un carácter, etc.).
Y también como esas funciones dependen de LC_CTYPE, tanto usted como las aplicaciones que usan linenoise deben llamar a setlocale (LC_ALL, "") para establecer la configuración regional de la aplicación en la configuración regional del sistema.
Gracias.
Eche un vistazo a mi bifurcación, https://github.com/msteveb/linenoise , que tiene soporte para utf-8
¿Realmente necesitas todas esas funciones? No estoy muy familiarizado con las cosas, pero solucioné fácilmente algunos de los problemas extraños usando mbstowcs () en lugar de strlen () donde se supone que la longitud de la cadena es equivalente a la cantidad de caracteres en la cadena. Pero no pude encontrar la manera de solucionar la eliminación de caracteres anchos con retroceso.
El enfoque aquí es evitar cualquier dependencia del soporte del sistema para utf-8. Por ejemplo, tengo sistemas que ejecutan uClibc sin soporte de configuración regional que aún pueden ejecutar felizmente una consola utf-8 a través de un puerto serie. Por supuesto, puede adoptar un enfoque diferente.
Tengo un problema similar; Probé line-noise para una implementación de shell. Si quiero mensajes de colores, los códigos de escape terminan incluyéndose en el cálculo de la longitud.
Una solución más simple y fácil es hacer lo siguiente:
1) permita que usted mismo especifique la longitud del mensaje.
2) use comandos de terminal para extraer la posición del cursor después de mostrar el mensaje (no estoy seguro de si esto es posible)
Encuentro esto en el código de mongo shell. Siempre me molestan más y más herramientas CLI (mongo, redis-cli, node)) que uso cuyo cursor se mueve de manera extraña cuando hay caracteres multibyte. No sé si los demás están usando linenoise o algo más, pero me gustaría ver que esto se solucione :-)
Hice una linenoise modificada que le permite especificar el ancho usted mismo, por lo que es un trabajo adicional para la aplicación, pero al menos es posible; Lo he estado usando durante aproximadamente 3 meses sin problemas. Lo convertiré en una solicitud de extracción, tal vez.
La rama 'utf-8 support' en mi bifurcación solucionó los siguientes problemas de UTF-8 que aparecen en la última versión 1.0 de linenoise:
ö (U+00F6)
ö (U+006F U+0308)
日本語
('japonés')Primero probé https://github.com/msteveb/linenoise. Pero no se basa en la última linenoise que admite el fantástico modo multilínea. Además, no admite caracteres anchos CJK y caracteres de código múltiple ...
Hola, estoy pensando en seguir la siguiente ruta con este problema:
De esta manera obtenemos que la simplicidad de linenoise permanece casi intacta, pero opcionalmente es posible admitir caracteres de varios bytes con funciones C++
, funciones proporcionadas por otros usuarios diferentes de las estándar, o las incluidas en linenoise si su El proyecto está en C y no quieres volver a escribir lo que @yhirose ya escribió una y otra vez.
¿Tiene sentido para ti? Gracias.
@antirez , ¡Gracias por prestar atención a los usuarios de códigos
Como puede ver en mi bifurcación, el concepto más importante para habilitar el soporte de 'múltiples bytes' es hacer una clara distinción entre ' posición / ancho de byte ' en el búfer de texto y ' posición / ancho de columna ' en la pantalla. A continuación, se muestran algunos ejemplos en UTF-8:
あ
(U + 3042): E3 81 82
(3 bytes): Ancho (2 columnas de ancho)ö
(U + 00F6): C3 B6
(2 bytes): Estrecho (1 ancho de columna)ö
(U + 006F U + 0308): 6F CC 88
(3 bytes): Estrecho (1 ancho de columna)Una vez que nos damos cuenta de la diferencia, es bastante fácil manejar correctamente el código multibyte. Puede captar la idea de los cambios en la primera confirmación . También apliqué el mismo principio al texto de solicitud en la segunda confirmación .
El único lugar donde debemos tener cuidado es el código de manejo del modo multilínea. Por ejemplo, cuando el último carácter es ancho y solo queda 1 columna en la fila actual, ese carácter ancho no se ajusta al espacio restante. Por lo tanto, el carácter ancho debe mostrarse al comienzo de la siguiente línea. Este código lo maneja.
Una cosa más que hice fue omitir todos los caracteres de la secuencia de escape ANSI al calcular la posición / ancho de la columna en
Estoy muy emocionado de ver la nueva API en un futuro próximo. Por favor, avíseme si tiene alguna pregunta sobre este asunto. Estoy seguro de que harás un trabajo fantástico !!
Después de investigar más sobre las dependencias entre el código linenoise y el código de codificación UTF-8 de acuerdo con su objetivo de diseño, me di cuenta de que solo se necesitan tres funciones al agregar otro soporte de codificación.
Basado en la investigación, he actualizado mi rama. Aquí está la diferencia entre el cabezal linenoise y la rama utf8-support . Como puede ver allí, me deshice de todo el código específico UTF-8 por completo de linenoise.c
y los puse en encodings/utf8.h
y encodings/utf8.c
. También agregué una API de experimento llamada linenoiseSetEncodingFunctions
en linenoise.h, para que los usuarios pudieran configurar su propio conjunto de funciones de codificación. Confirmé que todas las funcionalidades aún funcionan.
Aquí hay un fragmento de mi API experimental actual:
typedef size_t (linenoisePrevCharLen)(const char *buf, size_t buf_len, size_t pos, size_t *col_len);
typedef size_t (linenoiseNextCharLen)(const char *buf, size_t buf_len, size_t pos, size_t *col_len);
typedef size_t (linenoiseReadCode)(int fd, char *buf, size_t buf_len, int* c);
void linenoiseSetEncodingFunctions(
linenoisePrevCharLen *prevCharLenFunc,
linenoiseNextCharLen *nextCharLenFunc,
linenoiseReadCode *readCodeFunc);
linenoisePrevCharLen
y linenoiseNextCharLen
devuelven la longitud del byte como valor devuelto y establecen la longitud de la columna en el parámetro col_len
. linenoiseReadCode
lee bytes en buf
, convierte los bytes y establece un código de carácter significativo para la codificación en el parámetro c
.
Si los usuarios no llaman a linenoiseSetEncodingFunctions
, terminará llamando a implementaciones _default_. Simplemente manejan _un byte_ como un carácter.
Espero que la publicación sea útil cuando diseñe la nueva API de codificación. ¡¡Lo estoy deseando!!
@yhirose, ¡ es un trabajo fantástico! :-) Voy a comprobar el código y fusionarlo. Gracias por esto.
¿Aún no te has fusionado?
@antirez ¿ algún progreso en la fusión?
He modificado mi bifurcación (https://github.com/yhirose/linenoise/tree/utf8-support) para ponerme al día con los cambios recientes realizados en la linenoise original, como la función 'sugerencias'.
Muchas gracias @yhirose. ¡Has mejorado el buen código! y mi
trabajo más fácil!
@sonophoto
El lunes, 27 de junio de 2016 18:56:45 -0700, yhirose escribió:
I have modified my fork
(https://github.com/yhirose/linenoise/tree/utf8-support) para ponerse al día
con los cambios recientes realizados en la linenoise original, como 'sugerencias'
característica.
-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub o silencie el hilo.
*
Mi bifurcación (https://github.com/yhirose/linenoise/tree/utf8-support) ahora es compatible con Unicode 9.0.
@antirez ¿Tendrá tiempo libre en un futuro cercano para fusionar el soporte multibyte de https://github.com/hoelzro/lua-linenoise para usar la bifurcación de @yhirose hasta entonces? ✌️
Mi bifurcación (https://github.com/yhirose/linenoise/tree/utf8-support) ahora es compatible con Unicode 11.0 e incluye todos los cambios recientes realizados en antirez / linenoise .
Mi bifurcación (https://github.com/yhirose/linenoise/tree/utf8-support) ahora es compatible con Unicode 12.1.
Mi bifurcación (https://github.com/yhirose/linenoise/tree/utf8-support) ahora es compatible con Unicode 13.0.
Comentario más útil
Mi bifurcación (https://github.com/yhirose/linenoise/tree/utf8-support) ahora es compatible con Unicode 11.0 e incluye todos los cambios recientes realizados en antirez / linenoise .