|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||||||
Работа с текстовым редактором Scintilla16.11.2022, 21:30. Показов 9035. Ответов 99
Метки нет (Все метки)
Доброго времени суток ! Тружусь над небольшой программкой, в которой у меня будет редактор кода на основе "Scintilla". Столкнулся с такой задачкой: нужно, чтобы при нахождении ключевого слова, происходила его замена. По типу как в пурике - если пользователь написал ключевое слово в нижнем регистре, редактор его заменил на то, как эти ключевые слова хранятся в программе. К примеру, пользователь прописал "for" -> редактор сменил на "For". При этом, пурик, как известно, подсветку производит непосредственно как только обнаруживает ключевое слово, а замену делает при наборе следующего символа. При этом, символ должен быть либо пробел, либо скобка, либо переход на новую строку и т.п.
Выкладываю свой самый сокращенный вариант для примера. В нём зарезервировано только одно ключевое слово "For", ну этого достаточно для теста. Тут я пытаюсь добиться желаемого, но как-то некорректно это происходит. В строчках 89, 90 как раз пытаюсь прописать эту замену, но почему-то она не работает как нужно. Подскажите, пожалуйста, в чём ошибка ? Как только не пытался экспериментировать, никак не могу добиться желаемого. Документацию по Scintilla уже раз 40 пересматривал, изучал, но там тоже не так просто разобраться. Она таким тяжелым языком написана, а более понятной и доступной нигде не найти. В общем, вот мой пример поиска решения, дальше которого я никак не могу продвинуться. Помогите, пожалуйста, если есть кто-то компетентный.
0
|
||||||
| 16.11.2022, 21:30 | |
|
Ответы с готовыми решениями:
99
Работа с текстовым редактором Работа с текстовым редактором Помогите с текстовым редактором! |
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||||||
| 25.11.2022, 15:26 [ТС] | ||||||
|
locm, потому что, совпадение с ключевым словом на этапе набора самого слова, ещё не значит, что это оно и есть, это пока ещё только первоначальное сходство. Дальше может пойти символ слова и это уже не будет ключевым словом, а замена уже произведена. Так вот, чтоб такого не происходило, нужно, чтобы лексер, следующий за пока ещё только намечающимся ключевым словом, был отличным от лексера простого слова. Только тогда мы со 100%-ной уверенностью можем сказать, что тут действительно имелось ввиду ключевое слово, и делать замену.
Добавлено через 14 минут Кстати, в отправленном Вами последнем куске части кода, мне тоже непонятен один момент. Ведь код перебирает строку посимвольно и сравнивает текущий символ с предыдущим. Если State текущего символа отличается от предыдущего (OldState), только тогда выполняется какое-то изменение в подсветке. Условие:
0
|
||||||
|
|
|||||||
| 25.11.2022, 15:37 | |||||||
|
Тогда нужно проверять чтобы после ключевого слова был еще какой-то символ (пробел или другой, который не встречается в ключевых словах).
Может этот код чем-то поможет https://github.com/fantaisie-s... ighting.pb
0
|
|||||||
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||||||||||||||||||||
| 25.11.2022, 19:27 [ТС] | ||||||||||||||||||||
|
...
Добавлено через 4 минуты Благодарю, locm, к сожалению, у меня почему-то не запускается этот код. Жалуется с первой же строки на необъявленные константы.
Добавлено через 12 минут Однако, если, к примеру, тот же самый пробел предварительно уже имеется после ключевого слова, то реакция нормальная, а если его ещё нет, и мы его только что ввели, то ракция совсем другая. Но ведь по сути, он появился, и обработка строки производится с уже имеющимся пробелом. Почему же ракция совсем другая ? Хотя, в редакторе пурика это срабатывает нормально. Вот, мне и непонятно, то ли Scintilla по-разному обрабатывает строку, то ли я чего-то не понимаю. решение однозначно какое-то должно быть - пурик наглядный пример, но моих остатков мозгов что-то не хватает разобраться в столь странном поведении сцинтиллы. Добавлено через 7 минут
Добавлено через 17 минут
Делал вот так:
Добавлено через 2 часа 9 минут Да, locm, есть у него в коллекции по ссылке на гитхабе, который Вы высылали мне, процедура замены слова. Нашёл её, сделал перевод. Кстати, он там в комментариях тоже пишет об этой проблеме. Мне только в ней немного непонятно, на что указывают указатели *HighlightBuffer , *StringStart.Ascii, *Color . Я в указателях ещё не очень силён. Не могли бы пояснить, что это за указатели, и как их правильно определить ? Вот эта процедура с переведёнными комментариями:
0
|
||||||||||||||||||||
|
|
||||||||
| 25.11.2022, 20:11 | ||||||||
|
Можно проверять чтобы курсор был не в конце ключевого слова.
1
|
||||||||
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||||||
| 25.11.2022, 20:57 [ТС] | ||||||
|
Обалдеть ! Так быстро найти решение !!! Я больше недели бьюсь над реализацией этого эффекта, а тут буквально молниеносно (сравниваю со своим временным промежутком поиска решения) такое гениальное элегантное решение !!! Интересно, сколько понадобится времени усердной работы над составлениями алгоритмов и кодинга, чтобы хотя бы приблизиться к такому уровню !?
Немного добавил в условие, чтоб он окончательно делал то, чего я добивался:
0
|
||||||
|
|
|||||||
| 25.11.2022, 21:06 | |||||||
Сообщение было отмечено antro735 как решение
РешениеСохранив переменную EndKeyword можно добиться более или менее нормальной работы.
0
|
|||||||
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
|
| 25.11.2022, 21:24 [ТС] | |
|
Дошло. Да, при следующем вызове процедуры значения уже другие. Кстати, добавленное мной условие немного не то делает, но я над этим сейчас подумаю, чтоб добиться всё-таки чего я хочу окончательно.
Благодарю, locm !!! Замечательное решение и объяснение !!!!
0
|
|
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
|
| 26.11.2022, 04:13 [ТС] | |
|
AZJIO, у меня без багов работает. Сейчас, вот, подумаю как проработать, чтоб если пробел или символ с другим лексером уже присутствует после ключевого слова, значит, можно сразу же как только слово появилось, вместе с подсветкой тут же делать и замену. В принципе, я такой вариант сделал, но тут оказалось, что если ниже есть пусть даже пустая строка, символы перехода на следующую строку и возврата каретки сразу же создают условие для замены ключевого слова. Нужно, чтобы последний символ до которого работает подсветка строки был как раз перед этими двумя неотображаемыми символами. Ну, тут, думаю, справлюсь с этим.
А почему у тебя некорректно происходит замена, интересно... У меня отрабатывает без нареканий.
0
|
|
| 28.11.2022, 04:35 | |
|
locm, пробовал ранее #SCI_GETENDSTYLED, у меня всегда возвращает 0. И мне было не понятно "GET END STYLED", а где же "GET START STYLED"? Это работает от начала текста? С позиции 0? Если от начала строки, то как будет обрабатываться вставка многострочного текста.
Пока тестировал используя Debug для #SCI_GETENDSTYLED, обнаружил, что у меня события #SCN_STYLENEEDED высылаются каждую секунду вне зависимости ввожу я текст или нет. Проверил ваш код выше и этого не было, событие 1 раз после ввода символа, как положено. Естественно я начал искать проблему в своём коде и самое интересное я комментирую все функции оставляя только #SCN_STYLENEEDED и Debug и это не исправляет ситуацию, закомментировал все функции установки параметров после ScintillaGadget(), не помогает. В общем совершенно ничего не помогает, попробовал все варианты, которые я мог представить. Также проверил свою прогу "Grub2-generator", #SCN_STYLENEEDED там тоже высылает каждую секунду событие, но там вместо #SCN_STYLENEEDED я использовал #SCN_CHARADDED и #SC_MOD_INSERTTEXT, то есть движок не досит гаджет. Есть идеи?
0
|
|
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
|
| 28.11.2022, 05:09 [ТС] | |
|
Если я правильно понимаю, после того как происходит событие SCN_STYLENEEDED, то есть, какое-то изменение текста в редакторе, побуждающее стилировать строку, запускается команда подготовки к стилированию SCI_STARTSTYLING. Если перерисовка, которую выполняет SCI_SETSTYLING не произошла, запрос SCN_STYLENEEDED так и будет постоянно отправляться пока не будет произведена перерисовка. Возможно, я ошибаюсь, но по-моему это здесь так работает.
0
|
|
| 28.11.2022, 07:08 | |
|
Проверил, если ввёл код, который требует раскраски, то есть срабатывает SCI_SETSTYLING, то прекращается повторные уведомления SCN_STYLENEEDED, если же ввёл иной текст, который не требует раскраски, то уведомление SCN_STYLENEEDED приходит каждую секунду. Может я чего не понимаю, но если не сработал SCI_SETSTYLING то есть нечего подкрашивать и я не ввожу текст, то как я понимаю SCN_STYLENEEDED должен прекратиться. На данный момент так как SCI_GETENDSTYLED у меня возвращает 0 то использование его ни к чему не приводит, диапазон от нуля до нуля ничего не подкрасит в тексте, поэтому я подкрашиваю весь текст. Естественно не хочется чтобы файл размером 200 кб каждую секунду пытался подкрашиваться 16-надцатью регулярными выражениями.
0
|
|
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||||||
| 28.11.2022, 07:31 [ТС] | ||||||
|
Тогда, вероятно, нужно создавать условие для строки:
0
|
||||||
| 28.11.2022, 08:02 | |
|
antro735,
SCI_STARTSTYLING задаёт начальную позицию для подкрашивания. А SCI_SETSTYLING задаёт длину слова и подкрашивает. Второй параметр SCI_STARTSTYLING не используется - unused) SCI_STARTSTYLING(position start, int unused)
0
|
|
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||||||
| 28.11.2022, 08:34 [ТС] | ||||||
|
Ну, да, в документации написано, что в SCI_STARTSTYLING(position start, int unused) второй параметр устарел и сейчас не используется. Однако, в любом случае, какую-то стартовую позицию он будет задавать, и будет ждать, когда произойдёт перерисовка. То есть, он отправляет запрос на подготовку к стилической правке и ждать эту самую правку, пока она будет выполнена. Чтоб избежать правки, нужно, чтоб эта строка не отправляла запрос. Значит, нужны условия, когда запрос будет отправлен, а когда нет.
То есть, если текущий символ, к примеру, "$", то полностью исключить исполнение SCN_STYLENEEDED Добавлено через 10 минут Другими словами, что-то вроде вот этого:
0
|
||||||
| 28.11.2022, 08:44 | |
|
Ты же говорил SCN_STYLENEEDED требует SCI_SETSTYLING, а теперь говоришь что мешает SCI_STARTSTYLING.
SCI_SEARCHINTARGET возвращает -1 если не найден искомый элемент для подсветки. Если не найден, то никакие функции SCI_STARTSTYLING/SCI_SETSTYLING не выполняются. Сейчас попробовал ProcedureReturn #True / #False так как в уведомлениях листвью и "перетащить и бросить" есть способы отмены операций выпрыгивая с помощью возврата #True или #False, не помогло. Заметил, открыл большой файл grub.cfg и функционал не досил уведомлениями. Если открываю пустой и ввожу Enter (перенос строки) и посыпались уведомления. Здесь же пример выше аналогично пустой элемент, Enter и ничего не происходит (Debug вставлен) По поводу примера, я же говорил, после SCN_STYLENEEDED я всё закомментировал, нет никаких условий и команд, только отлов событий SCN_STYLENEEDED, а ну Debug только для проверки сколько уведомлений приходит.
0
|
|
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||
| 28.11.2022, 08:58 [ТС] | ||
|
Я сейчас начал прорабатывать индикаторную подсветку для множественного выделения текста, чтоб как в пурике - выделил слово, и по всему коду везде где есть это слово, оно во всём коде подсвечивается. Тут тоже покубатурить придётся, вернее, не придётся, а уже это происходит )))
0
|
||
| 28.11.2022, 09:22 | |
|
antro735, ну это же выдумки, в документации нет того что ты пишешь. Тебе кажется что так работает, но это не обязательно так. Ты можешь только доказывать реальным поведением движка используя примеры. Зачем SCI_STARTSTYLING что-то там активировать? Попробуй думать как разработчики. Им нужно подсветить слово. Значит должно быть слово или позиции откуда докуда подсвечивать. Используя SCI_SEARCHINTARGET я получаю позицию слова для подсветки, позицию конца я могу вычислить прибавив к позиции длину слова. Итак позиции есть, смотрим что нам предоставляет движок Scintilla, а предоставляет он возможность задать начало подсветки SCI_STARTSTYLING, а SCI_SETSTYLING задаёт длину подсветки и подсвечивает. Внимание вопрос, зачем к этим функциям привязывать ещё какие-то действия? Тебе надо подсветить, ты подсветил, с чего SCI_STARTSTYLING должен там что-то запустить то после чего гаджет Scintilla поломается? И так все функции, если SCI_POSITIONFROMLINE возвращает позицию начала, то это просто возвращает число, а не запускает какой-то движок после которого если что-то там не выполнишь то Scintilla упадёт, совсем нет, вот так просто это работает.
0
|
|
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||||||
| 28.11.2022, 09:30 [ТС] | ||||||
|
Задуманный эксперимент не представляется возможным, там ведь распознание символов происходит уже после того как отправляется команда SCI_STARTSTYLING. И окончание стилизации происходит по условию
Вот что написано в документации: SCI_GETENDSTYLED → position Scintilla хранит запись последнего символа, который, вероятно, будет создан правильно. Это перемещается вперед, когда символы после этого стилизованы и перемещаются назад, если перед текстом документа внесены изменения. Перед рисованием текста эта позиция проверяется, если требуется какой-либо стиль и, если это так, сообщение уведомления SCN_STYLENEEDED отправляется в контейнер. Контейнер может отправить SCI_GETENDSTYLED для разработки, где ему нужно начать стилизацию. Scintilla всегда будет запрашивать стиль целых строк. Но тут такой мутный перевод, что толком понять его как-то не очень легко. Вообще, SCI_GETENDSTYLED - даже по названию - до какой позиции производится стилизация, а из документации складывается впечатление, что SCI_GETENDSTYLED зто начало стилизации.
0
|
||||||
| 28.11.2022, 09:56 | |
|
там есть внутренние лексеры, ты же не знаешь точно о каком лексере говорится. Фактически любое изменение (ввод символа, удаление символа/текста, вставка текста из буфера, замена одно другим) требует пересмотра, отсюда и необходимость подсвечивания. Но я то ранее начал речь о том что ничего не происходит, какого либо изменения и происходит прилёт уведомлений. На счёт всё должно быть в стилях, по сути стиль не привязывается к тексту ни как, у буквы есть поле, как структура, как будто буква многоэтажный дом, на первом этаже буква, на втором этаже цвет буквы, на третьем ещё что-нибудь. Движок Scintilla подкрашивает каждую букву исходя из данных находящихся на втором этаже, в общем данные привязанные к этой букве. В отличии от индикаторов стиль в моём блокноте подкрашивается в несколько проходов регулярными выражениями и может последний рег.выр. перекрасить то что было покрашено первым рег.выром. Индикаторы действуют по-другому, если покрасил букву регвыром, то второй регвыр не может перекрасить её, вернее поиск для покраски просто игнорирует покрашеные, точнее он ищет первую непокрашенную букву, потом находит после нею покрашенную и это диапазон для возможной покраски, потом ищет с помощью регулярного выражения внутри непокрашенного диапазона и если находит то красит его и это диапазон тоже становится неприступным. Чтобы сделать опять доступным надо очистить индикаторы. То есть создание рег.выр немного по-иному, сначала подкрашиваются те, которые точно являются гарантированными элементами кода, а уж потом между них ищутся например операторы, со стилем наоборот сначала операторы, потом другие элементы, иначе операторы подсветят внутри других элементов.
Покраска целых строк, потому что если ту удались символ внутри слова, то ты не можешь его подкрасить от начала слова до курсора, так как оно будет составлять часть ключевого слова. А перенос строк является разделителем, поэтому перекрашивая строку будет правильно подкрашиваться.
0
|
|
| 28.11.2022, 09:56 | |
|
Помогаю со студенческими работами здесь
40
Помощь с текстовым редактором Ввод и вывод массива с текстовым редактором Обработка больших файлов текстовым редактором Сценарий PowerShell для работы с текстовым редактором Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер.
Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
|
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта
Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
|
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром.
возможно получится прикрутить интерпретатор питон для кастомизации игровой логики.
что есть на текущий момент:. . .
|
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2.
Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
|
|
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
|
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2.
Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
|
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2.
Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом.
В. . .
|
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2.
Задача: отобразить спецтехнику, которая на данный момент находится в ремонте.
Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
|