Теория разработки текстового редактора с подсветкой синтаксиса

Projects yet to be implemented in working code
  • Leency wrote:Дабы не велосипедить, я вначале хочу обсудить как правильно его реализовать.
    А вариант переноса или идей компонента Scintilla не рассматривался?
  • Учитывая, что Scintilla разрабатывают уже 16 лет, портирование - наиболее логичный вариант.

    Leency
    Я ещё когда с TinyPad возился, чуть фейспалмом лоб не пробил... А массив указателей на строки сделать не вариант? Зачем в массив структур включать сами строки? Почто текст мучить? Может даже лучше связный список структур с указателями на строки.
  • Leency, во-первых в твоих программах вывод текста в буфер сделан неправильно. Ты создаешь огромный буфер и рисуешь туда текст, затем, выводишь в окно программы ту часть буфера, которая требуется. Это совершенно неприличный расход памяти (и её может не хватить). Надо, чтобы буфер соответствовал размеру окна программы. При обновлении окна программы, содержимое буфера стирается и текст рисуется заново, естественно, только те строки, которые попадают в окно.

    Текст можно представить как список строк, где строка представляет собой структуру, главное поле которой -- символьный массив (или его адрес) (потребуются еще и другие поля: длина, флаг изменения, флаг сохранения...). Хранить номер строки не надо: при вставке, удалении строк нумерация нарушится и каждый раз ее поправлять -- это лишний геморрой. Если строк в тексте не миллионы, то номер строки можно узнать путем простого пересчета структур в списке до текущей строки.

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

    Разработка текстового редактора -- дело сложное. У меня есть некоторый опыт, хотя на идеал я не притендую.

    К сожалению, когда я это делал, опыта у меня не хватало и о кроссплатформенности я не заботился. Программа жестко привязана к WINAPI.
    Spoiler:
    1.png
    1.png (16.9 KiB)
    Viewed 8152 times
  • Kopa
    В идеале было бы круто, но я такое не потяну.

    Leency
    string_data и предполагался быть указателем.
    > Может даже лучше связный список структур с указателями на строки.
    Интересно, очень даже может быть.
    Из хаоса в космос
  • akron1
    Спасибо за развернутое объяснение.
    Leency, во-первых в твоих программах вывод текста в буфер сделан неправильно. Ты создаешь огромный буфер и рисуешь туда текст, затем, выводишь в окно программы ту часть буфера, которая требуется. Это совершенно неприличный расход памяти (и её может не хватить). Надо, чтобы буфер соответствовал размеру окна программы. При обновлении окна программы, содержимое буфера стирается и текст рисуется заново, естественно, только те строки, которые попадают в окно.
    В WebView такое сделать сейчас нельзя, т.к. процесс парсинга и рисования однопроходный. Для того, чтобы реализовать буфер окна нужен DOM.
    В Calypte такое можно попробовать следать уже сейчас.
    Для TxtView чтобы такое сделать нужно две вещи:
    1. перевести каждый символ KF шрифта в растр (как делаешь ты в BF view)
    2. написать функцию, которая будет накладывать партинку на картинку
    Подсветку синтаксиса я делал так:
    Каждая строка перед выводом в буфер парсится и, по мере нахождения в строке той или иной лексемы, лексема выводится в графический буфер заданным цветом. Никакие списки лексем не создаются, потому что строки изменяемы и списки лексем тоже придется менять. Парсить надо только те строки, которые попадают в окно программы. На экране помещается всего несколько десятков строк, и поэтому такой способ, если сделать правильно, будет эффективен.
    Здесь еще надо обратить внимание на многострочные комментарии. Начало комментария может быть выше видимой части текста. Поэтому, перед началом работы с текстом, надо найти все комментарии и пометить строки, в которых комментарий начинается, заканчивается или продолжается. И после изменения любой строки, проверить её на наличие в ней начала или конца комментария, чтобы поддерживать информацию о расположении комментариев актуальной.
    Интересно. Вообще дело в том, что не только комментарии могут быть многострочными, но и строки "". Если реализовыватть только подсветку Си - вроде просто.
    Но если универстально, чтобы использовались файлы подсветки разных систаксисов не думаю что твой вариант "надо найти все комментарии и пометить строки, в которых комментарий начинается, заканчивается или продолжается". Например в HTML таких мест будет очень много.
    Разработка текстового редактора -- дело сложное. У меня есть некоторый опыт, хотя на идеал я не притендую.
    У меня нет и я даже не имею ИТ образования. Многие студенты как курсовую делают редакторы. Смотрю исходники других проектов, анализирую. Возможно, стоит нанять человека на разработку или портирование редактора...
    Из хаоса в космос
  • Некоторые рассматривали возможность портирования Scintilla. Интересует их мнение на этот счёт. Детально ещё не смотрел, возможно ли обойтись без GTK+?
    to infinity and beyond
  • punk_joker wrote:возможно ли обойтись без GTK+
    Siemargl писал, что можно FLTK.
  • Да, только я никак не возьмусь за ФЛТК - все же большой объем непонятного кода
  • Siemargl, если можно как-то разбить задачу на части, то может кто-нибудь ещё примет участие и тогда это будет быстрее.
  • Leency wrote:2. поиск лексем для применения стилей
    Там вон какой-то лексер http://websvn.kolibrios.org/filedetails ... %2Flexer.h
  • Если актуально...

    Открытый документ лучше всего хранить в виде: кол-во строк + указатель на список указателей строк документа, текущая позиция курсора ввода, цвет фона подложки и так далее. Почему указатель - чтобы задачу можно было разбить на более простые и разделить между людьми (+ если кому-то надо список, то просто даём ему указатель), а в случае чего (например переделка gui) будет просто отделить обёртку от основной структуры.

    Предлагаю на каждую строку отдельно хранить: символы строки, битовую (или байтовую) маску изменения цвета, список цветов, байт характеристик строки (номер цвета фона строки и знаки: брейкпоинт, ошибка, строка изменена и не сохранена, изменения сохранены и так далее).
    Список цветов хранить в виде буфера нужного размера с расчётом по 4 байта на один цвет. В большинстве случаев при добавлении символа маску придётся пересчитать для всей строки заново, а может и для всей видимой области. В других же случаях можно будет сдвигать её вправо на 1 разряд и заполнять+изменять её и соседние биты.
    Битовая маска должна обозначать 1 - символ, с которого начинается новый цвет (увеличиваем +4 смещение на цвет в буфере списка цветов), 0 - цвет не изменяется (используем тот же).
    Рисовать всё следует в буфере и потом выводить на экран/в окно. Для старта можно воспользоваться моим koView.
    Следует создать и описать API такого компонента: получения/установка цвета, символа и так далее.

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

    Есть другой вариант: можно идти от формата лексера, преобразовывать его формат и красить. Но тут можно споткнуться с устройством самого текстового редактора (задача редактора не просто вывести подсвеченный текст, а изменять его).

    Могу помочь сделать описанную выше структуру строк и средний компонент, который будет рисовать заданный цветной текст. Нужен тот, кто напишет оболочку программы (загрузка и сохранение файла, вкладки, меню, копировать/вставить, растянуть окно и прочее). От кого-то потом потребуется написать лексер, который будет обновлять маску какими цветами красить.
    Общая схема
    0.png (112.86 KiB)
    Общая схема Viewed 7751 times
  • Who is online

    Users browsing this forum: No registered users and 3 guests