Темная сторона QScintilla

в 7:06, , рубрики: qscintilla, qt, Qt Software, метки: ,

Недавно на Хабре начали появляться статьи (1, 2) про замечательный компонент QScintilla.
Я один из разработчиков проекта Monkey Studio, и, последние полтора года, mksv3. Мы пользуемся QScintilla уже 5 лет. Периодически делаем для него баг репорты и патчи. Мы решили от него отказаться. И нам мучительно больно за потраченные на него годы.
Пишу этот пост, чтобы у других не случилось так же.

Я делюсь своим опытом. Мы разрабатываем свободный универсальный кроссплатформенный текстовый редактор. То, что критично для нас, может быть не важно для вас. И наоборот. Анализируйте.
И так, наш опыт. Что плохо в QScintilla…

Бинарные лексеры

Лексер в терминологии Scintilla — класс, разбирающий, подсвечивающий, выравнивающий и т.д. определенный язык программирования.
Для большинства компонентов, позволяющих редактировать код, можно создавать текстовые файлы с описанием синтаксиса нового языка. Например, для katepart. Для QScintilla лексер — это только C++ код. Соответственно:

  • Поддерживается мало языков и типов файлов (по сравнению с emacs, vim, kate). Не много желающих писать свой лексер.
  • Для большинства редакторов пользователь может скачать текстовый файлик из интернета и получить подсветку нового языка без перекомпиляции редактора. (Вот, например, поддержка go для vim). Вот только для QScintilla таких файликов вы не найдете.
Настройки лексеров

QScintilla позволяет настраивать лексер. Вы можете выбрать, какие структуры будут сворачиваться (code folding), а какие нет в C++, и будет ли лексер подсвечивать неконсистентное выравнивание кода в Python. Но, у каждого лексера свой набор параметров. И код и для для настройки лексера приходится писать уникальный.
Если программисту захочется узнать, является ли строка файла Y символ X комментарием (например, чтобы проверять правописание в комментариях, но не в коде) — снова придется писать уникальную проверку для каждого из лексеров.
Еще больше проблема обостряется тем, что набор лексеров и их настроек меняется с каждым релизом. О том, что настройки изменились вам будут периодически напоминать баг репортами «У меня не собирается проект на QScintilla версии x.x.x». И вам очень пригодится конструкция
#if QSCINTILLA_VERSION >= ...

Цветовые схемы

Люди разные, вкусы у них тоже разные. Кому-то нравится темный текст на светлом фоне, кому-то светлый текст на темном фоне. QScintilla позволяет настроить шрифт и фон для каждого из синтаксических элементов (числа, строки, ключевые слова...)
Вот, например, диалог настройки из Monkey Studio (кликните картинку для полного размера):
Темная сторона QScintilla
Но, настроить можно только конкретный лексер. На скриншоте — страничка настройки C++. Если пользователю захочется создать свою цветовую схему, придется настраивать по очереди каждый из используемых языков.
Если программист захочет создать цветовую схему для пользователей, вариант тот-же — придется настроить каждый из нескольких десятков языков, и не забывать обновлять тему с появлением новых.
Очень трудоемко. Kate и некоторые другие редакторы позволяют настраивать все языки одновременно. Так проще.

Плохой рендеринг

QScintilla не использует QTextEdit + QSyntaxHighlighter, а рисует все самостоятельно на QAbstractScrollArea. Велосипед местами получился кривой.

  • Ширина monospace шрифта на некоторых платформах зависит от того, является ли он жирным.
  • Шрифты на некоторых платформах не сглаживаются и смотрятся убого.
  • Если строка длинная и не вмещается в ширину экрана, иногда она рисуется не правильно. Редактирование происходит не там, где отображается курсор. Приходится переоткрывать файл, чтобы его возможно было редактировать. Пока снова не начнется...
Собственный синтаксис регулярных выражений

QScintilla поддерживает поиск в тексте. Он работает, даже можно использовать регулярные выражения. Но вот синтаксис регулярных выражений местами отличается от общепринятого (такого, как, например, у QRegExp). И пользователям эти мелкие отличия не понравятся. Для прототипа — сгодится, для стабильного проекта — нет.
Мы сделали поиск на QScintilla, потом пришлось его выбросить и написать собственный.

Нет открытого репозитория

Из каких-то соображений Phil Thomson не открывает репозиторий QScintilla в публичный доступ, а только выкладывает архивы.
Из-за этого:

  • Неудобно проверять, что изменилось в версии X по сравнению с версией Y.
  • Очень сложно делать патчи для старых версий QScintilla на основе исправлений в новой.
    Необходимость возникает, например, если нужно сделать патч для версии, которая используется в Debian stable. Политика дистрибутива не позволяет просто обновить пакет.
Заключение

Надеюсь никто не подумал, что я не люблю QScintilla, или считаю его плохим компонентом. У него очень много полезной функциональности, он поддерживает большое количество языков, в большинстве случаев автор очень оперативно и адекватно реагирует на патчи и баг репорты. Для большинства проектов на Qt, которым нужен редактор кода, QScintilla — оптимальное решение. Тем более, что альтернатив не много. И очень здорово, что namespace пишет про QScintilla полезные статьи.
Просто про положительные стороны уже написано. А я рассказал про найденные нами недостатки, которые не очевидны на начальных стадиях проекта. Надеюсь, это поможет составить полную картину и объективно оценить компонент.

Список недостатков — наш опыт. Вожможно мы что-то не поняли и делаем не правильно. Комментируйте. Давайте искать истину.

Если решите использовать QScintilla, полезные примеры можно найти в Eric, JuffEd и моих проектах, ссылки на которые есть в начале.

Авторам новых IDE

И еще, если вы дочитали до конца, с некоторой долей вероятности вы планируете или уже начали сделать свой собственный текстовый редактор или IDE. И, может быть, на этом этапе вас еще не поздно остановить.
За пять лет я видел не менее десятка проектов, которые умерли через пару лет после старта. Запал автора иссякает, а функционал оказывается не намного больше того, что было в первые пару месяцев. Печально.
Иногда новые проекты начинать стоит. Но, только если есть действительно серьезные причины. Сначала просмотрите существующие и четко сформулируйте для себя, почему нельзя влиться в их комманду и продолжить работу вместе. Лучше один хороший проект, чем 10 плохих. Ссылки на несколько стоящих проектов на Qt, и в т.ч. на QScintilla есть здесь.

Удачи!

Автор: hlamer


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js