Linenoise: Добавить многобайтовую поддержку

Созданный на 23 янв. 2012  ·  21Комментарии  ·  Источник: antirez/linenoise

Текущий код не поддерживает многобайтовые строки, например строки, содержащие символы Юникода за пределами диапазона ASCII. Сдвиги столбцов для refreshLine вычисляются с помощью strlen (), которая возвращает 2 вместо 1 для двухбайтового символа, такого как «Ş» на турецком языке.

Библиотека должна использовать mbstowcs () или другие функции для получения количества символов вместо количества байтов для обработки столбца (стрелки вверх, вниз, стирание символа и т. Д.).

Кроме того, поскольку эти функции зависят от LC_CTYPE, вы или приложения, использующие леншум, должны вызвать setlocale (LC_ALL, ""), чтобы установить языковой стандарт приложения на системный языковой стандарт.

Спасибо.

Самый полезный комментарий

Моя вилка (https://github.com/yhirose/linenoise/tree/utf8-support) теперь поддерживает Unicode 11.0 и включает все недавние изменения, внесенные в antirez / lnenoise .

Все 21 Комментарий

Взгляните на мою вилку https://github.com/msteveb/linenoise , которая поддерживает utf-8.

Вам действительно нужны все эти функции? Я не совсем знаком с этим материалом, но я легко исправил некоторые странные проблемы, используя mbstowcs () вместо strlen (), где длина строки считается эквивалентной количеству символов в строке. Но я не мог найти способ исправить удаление широких символов с помощью backspace ..

Подход здесь заключается в том, чтобы не полагаться на системную поддержку utf-8. Например, у меня есть системы, в которых работает uClibc без поддержки локали, которые могут успешно запускать консоль utf-8 через последовательный порт. Конечно, вы можете использовать другой подход.

У меня похожая проблема; Я попробовал линейный шум для реализации оболочки. Если мне нужны цветные подсказки, в расчет длины включаются escape-коды.

Более простой и легкий способ исправить:

1) разрешите самостоятельно указать длину подсказки.
2) используйте команды терминала для извлечения позиции курсора после вывода приглашения (не уверен, возможно ли это)

Я нахожу это из кода оболочки mongo. Меня всегда раздражает все больше и больше инструментов CLI (mongo, redis-cli, node)), которые я использую, курсор которых сильно перемещается, когда есть многобайтовые символы. Я не знаю, используют ли другие льняной шум или что-то еще, но я бы хотел, чтобы это было исправлено :-)

Я сделал модифицированный бельевой шум, который позволяет вам определять ширину самостоятельно, так что это дополнительная работа для приложения, но, по крайней мере, возможная; Пользуюсь уже около 3 месяцев без проблем. Возможно, я превращу это в пул-реквест.

В ветке 'utf-8 support' на моей вилке были исправлены следующие проблемы с UTF-8, которые появились в последней версии lenneoise 1.0:

  • Многобайтовые символы: ö (U+00F6)
  • Многокодовые символы: ö (U+006F U+0308)
  • Широкие символы: 日本語 ('японский')
  • Текст подсказки, включающий указанные выше символы и экранированный цветной текст ANSI.

Сначала я попробовал https://github.com/msteveb/linenoise. Но он не основан на последнем льняном шуме, который поддерживает фантастический многострочный режим. Также он не поддерживает широкие символы CJK и символы с несколькими кодами ...

Здравствуйте, я думаю о том, чтобы пойти по следующему пути с этой проблемой:

  1. Используйте @yhirose в качестве справочника, чтобы проверить, где функции простой строки C должны быть заменены функциями с поддержкой многобайтовых символов.
  2. Экспортируйте API, который позволяет пользователю Linenoise устанавливать альтернативные функции для расчета длины строки. По умолчанию задайте для функции простые функции C.
  3. Включите код @yhirose в виде отдельного файла, который вы можете добавить в свое приложение, вызывая новые функции Linenoise, чтобы установить функции длины, чтобы иметь многобайтовую поддержку.

Таким образом, мы получаем, что простота льняного шума остается почти нетронутой, но при желании можно поддерживать многобайтовые символы как с помощью функций C++ , других пользовательских функций, отличных от стандартных, или тех, которые включены в сам льняной шум, если ваш проект находится на C, и вы не хотите снова и снова переписывать то, что уже написал @yhirose .

Имеет смысл для вас? Спасибо.

@antirez , Спасибо за внимание пользователям многобайтового кода! Идея, которую вы представили, имеет для меня смысл. Я даже счастлив, потому что, если бы сама библиотека Linenoise могла предоставить расширяемость, мы могли бы легко добавить другую поддержку многобайтового кодирования.

Как вы можете видеть в моей вилке, наиболее важной концепцией для включения поддержки «многобайтовой информации» является четкое различие между « положением / шириной байта » в текстовом буфере и « положением / шириной столбца » на экране. Вот несколько примеров в UTF-8:

  • (U + 3042): E3 81 82 (3 байта): широкий (ширина 2 столбца)
  • ö (U + 00F6): C3 B6 (2 байта): узкий (ширина 1 столбца)
  • (U + 006F U + 0308): 6F CC 88 (3 байта): узкий (ширина 1 столбца)

Как только мы узнаем разницу, будет довольно легко правильно обрабатывать многобайтовый код. Вы можете уловить идею из изменений в 1-м коммите . Я применил тот же принцип для подсказки текста во 2-м коммите .

Единственное место, где нам нужно быть осторожными, - это код обработки многострочного режима. Например, когда последний широкий символ является широким, а в текущей строке остается только 1 столбец, этот широкий символ не помещается в оставшееся пространство. Таким образом, широкий символ должен отображаться в начале следующей строки. Этот код обрабатывает это.

Еще одна вещь, которую я сделал, - это пропустить все символы escape-последовательности ANSI при вычислении позиции / ширины столбца в третьей фиксации . Это изменение позволяет нам использовать цвет в тексте подсказки.

Я очень рад увидеть новый API в ближайшем будущем. Пожалуйста, дайте мне знать, если у вас возникнут вопросы по этому поводу. Я уверен, что вы проделаете фантастическую работу !!

Изучив больше зависимостей между кодом льняного шума и кодом кодировки UTF-8 в соответствии с вашей целью проектирования, я понял, что при добавлении другой поддержки кодирования необходимы только три функции.

По результатам исследования обновил свою ветку. Вот разница между льняной головкой и ответвлением utf8-support . Как вы могли видеть, я полностью избавился от всего кода, специфичного для UTF-8, из linenoise.c и поместил их в encodings/utf8.h и encodings/utf8.c . Кроме того, я добавил один экспериментальный API под названием linenoiseSetEncodingFunctions в бельеoise.h, чтобы пользователи могли устанавливать свой собственный набор функций кодирования. Я подтвердил, что все функции по-прежнему работают.

Вот фрагмент моего текущего экспериментального API:

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 и linenoiseNextCharLen возвращают длину байта в качестве возвращаемого значения и устанавливают длину столбца в параметр col_len . linenoiseReadCode считывает байты в buf , конвертирует байты и устанавливает значимый код символа для кодировки в параметр c .

Если пользователи не вызовут linenoiseSetEncodingFunctions , это приведет к вызову реализаций _default_. Они просто обрабатывают один байт как символ.

Надеюсь, этот пост будет полезен при разработке нового API кодирования. Я очень этого жду !!

@yhirose , это фантастическая работа !!! :-) Я собираюсь проверить код и объединить его. Спасибо тебе за это.

Еще не слились?

@antirez есть ли прогресс в его объединении?

Я изменил свою вилку (https://github.com/yhirose/linenoise/tree/utf8-support), чтобы не отставать от недавних изменений, внесенных в исходный льняной шум, таких как функция «подсказок».

Большое спасибо @yhirose. Вы сделали хороший код лучше! и мой
работа проще!

@sonophoto

В понедельник, 27 июня 2016 г., 18:56:45 -0700 yhirose написал:

   I have modified my fork 

(https://github.com/yhirose/linenoise/tree/utf8-support), чтобы наверстать упущенное
с недавними изменениями, внесенными в оригинальный бельевой шум, такими как «подсказки»
характерная черта.
-
Вы получаете это, потому что подписаны на эту беседу.
Ответьте на это письмо напрямую, просмотрите его на GitHub или отключите обсуждение.

*

Моя вилка (https://github.com/yhirose/linenoise/tree/utf8-support) теперь поддерживает Unicode 9.0.

@antirez Будет ли у вас в ближайшем будущем свободное время, чтобы объединить многобайтовую поддержку @yhirose ? Или мы должны переключить https://github.com/hoelzro/lua-linenoise на использование форка @yhirose до тех пор? ✌️

Моя вилка (https://github.com/yhirose/linenoise/tree/utf8-support) теперь поддерживает Unicode 11.0 и включает все недавние изменения, внесенные в antirez / lnenoise .

Моя вилка (https://github.com/yhirose/linenoise/tree/utf8-support) теперь поддерживает Unicode 12.1.

Моя вилка (https://github.com/yhirose/linenoise/tree/utf8-support) теперь поддерживает Unicode 13.0.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

krux02 picture krux02  ·  8Комментарии

denisvm picture denisvm  ·  9Комментарии

JelteF picture JelteF  ·  8Комментарии

fatcerberus picture fatcerberus  ·  5Комментарии

ghost picture ghost  ·  4Комментарии