|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 124
|
||||||
Работа с текстовым редактором Scintilla16.11.2022, 21:30. Показов 9444. Ответов 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 | |
|
Помощь с текстовым редактором Ввод и вывод массива с текстовым редактором Обработка больших файлов текстовым редактором Сценарий PowerShell для работы с текстовым редактором Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Из невошедшего на форум (диалог с ИИ-гугла)
zorxor 29.07.2026
А вот, что интересно, сказал мне ИИ-гугла:
Этот текст — эмоциональный пост пользователя под ником zorxor на интернет-форуме (вероятно, посвященном мистике, непознанному или альтернативной науке). . . .
|
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет
Новости компьютерного мира и их обсуждение (4)
Салют, шампанское, овации!
:drink:
|
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр.
Дословно, отклонённая. . .
|
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы
Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
|
|
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
|
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2.
Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
|
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
|
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
|