1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
||||||
1 | ||||||
Работа с текстовым редактором Scintilla16.11.2022, 21:30. Показов 5241. Ответов 99
Метки нет (Все метки)
Доброго времени суток ! Тружусь над небольшой программкой, в которой у меня будет редактор кода на основе "Scintilla". Столкнулся с такой задачкой: нужно, чтобы при нахождении ключевого слова, происходила его замена. По типу как в пурике - если пользователь написал ключевое слово в нижнем регистре, редактор его заменил на то, как эти ключевые слова хранятся в программе. К примеру, пользователь прописал "for" -> редактор сменил на "For". При этом, пурик, как известно, подсветку производит непосредственно как только обнаруживает ключевое слово, а замену делает при наборе следующего символа. При этом, символ должен быть либо пробел, либо скобка, либо переход на новую строку и т.п.
Выкладываю свой самый сокращенный вариант для примера. В нём зарезервировано только одно ключевое слово "For", ну этого достаточно для теста. Тут я пытаюсь добиться желаемого, но как-то некорректно это происходит. В строчках 89, 90 как раз пытаюсь прописать эту замену, но почему-то она не работает как нужно. Подскажите, пожалуйста, в чём ошибка ? Как только не пытался экспериментировать, никак не могу добиться желаемого. Документацию по Scintilla уже раз 40 пересматривал, изучал, но там тоже не так просто разобраться. Она таким тяжелым языком написана, а более понятной и доступной нигде не найти. В общем, вот мой пример поиска решения, дальше которого я никак не могу продвинуться. Помогите, пожалуйста, если есть кто-то компетентный.
0
|
16.11.2022, 21:30 | |
Ответы с готовыми решениями:
99
Работа с текстовым редактором Работа с текстовым редактором Помогите с текстовым редактором! С текстовым редактором C++ Builder Помощь с текстовым редактором |
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
|
03.12.2022, 13:49 [ТС] | 81 |
Сейчас уже не смогу проверить. Это было около полугода назад. Они не могли быть разными, если я копирую весь код, открываю новую вкладку, вставляю скопированное, и тут же запускаю. Однако, ваши с AZJIO, советы принял во внимание себе на заметку.
Хотя, в данном случае, тоже есть некоторые непонятные мне пока моменты. Запускаю код редактора, над которым работаю, на своём ПК прямо из среды PureBasic, и этот же код запускаю на ноутбуке. Операционные системы одинаковые на обеих машинах. В коде реализовал множественное подсвечивание выделенного слова как в PureBasic - когда выделяешь, к примеру имя переменной, и во всём коде она подсвечивается. Выбрал для этого индикатор INDIC_STRAIGHTBOX. На ПК он ни в какую не хочет отображаться. Вместо него подсветка производится индикатором INDIC_PLAIN. Меняю тип индикатора на NDIC_BOX - он отображается нормально - все слова выделяются рамкой. Снова пытаюсь сменить индикатор на INDIC_STRAIGHTBOX, а он вновь отображает NDIC_BOX. Хотя, этот же самый код на ноутбуке вполне себе корректно отображает запрашиваемый INDIC_STRAIGHTBOX. Тоже причина пока мне не ясна.
0
|
03.12.2022, 14:36 | 82 | |||||
Там выше написано: "Если вы используете SCI_SETILEXER..."
То есть насколько я понял некоторому движку передаётся диапазон для подсветки и он там делает эту подсветку самостоятельно, ища ключевые слова, операторы и т.д. Там даже сказано что SCI_GETENDSTYLED перемещается по мере подсветки. В моём случае если я делаю подсветку самостоятельно, откуда движку знать где начало, где конец? Если считать SCI_GETENDSTYLED концом, а SCI_SETSTYLING заставляет передвигать конец, но ведь я вызываю внутри цикл подсветки многократно вызывая SCI_SETSTYLING. *scinotify.SCNotification\Position является началом подсвечивания, но показывает конец документа, а SCI_GETENDSTYLED должен выдать конец подсвечивания, а выдаёт начало документа. Как он узнаёт что текст подсвечен или не подсвечен? Теоретически он должен подсвечивать строку, в которой произошло изменение. Я попробовал обозначить *scinotify.SCNotification\Position как конец, а SCI_GETENDSTYLED как начало, то заработало. Но опять же у меня при вводе символа подсвечивается от курсора до конца видимой части документа. Пока я не понимаю как это работает, при выборе кодировки не подсвечивается, открытый документ не подсвечивается, при попытке ввода символа подсвечивает от начала до конца видимого. Буду дальше экспериментировать. antro735, в общем я добавил в конец блока уведомления SCN_STYLENEEDED две строки
1
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
|
03.12.2022, 15:54 [ТС] | 84 |
Отлично, AZJIO, это реально работает !
Остался ещё такой момент: если скопировать некий код, опять же, в 4 - 5 тыс. строк, и пытаться его вставить в редактор, то он слишком долго думает перед тем, как его отобразить. В моём случае, он зависает секунд аж на 10 - 12. Есть какие-то варианты избавиться от этого явления ?
0
|
03.12.2022, 16:17 | 85 | |||||
locm, я написал сумбурно. Теперь по полочкам: есть вариант "костыли": я могу как у меня сделано в Grub2-generator (Sci).pb подсветить строку при вводе символа или подсветить вставленный текст при вставке, казалось бы 2 режима полностью покрывают мои хотелки. Но в этом случае я теряю флаг SCI_SETIDLESTYLING + SC_IDLESTYLING_ALL то есть подсветить видимое и фоном подсвечивать за пределами видимого, если файлы большие. Значит желательно разобраться.
Теперь правильный вариант: начало и конец поменяны местами, иначе у меня проц работает на полную катушку а редактор бездействует, то есть начало 999 а конец 0, естественно это не работает. Меняю местами (метод тыка). При этом при открытии подсвечивается видимое, а фоном ничего не подсвечивается, да и начало и конец в отладчике выдают видимое, соответственно невидимое непонятно как подсветится, может ещё какой флаг нужен для запуска подсветки невидимого в фоне. Второе - ввод символа подсвечивает 2 строки в той где курсор и ниже. Это неплохо, а вот с открытием пока проблема, в фоне не подсвечивается, документ не подсвечен. Ну и непонятно как принудительно выслать SCN_STYLENEEDED например при смене стиля очистить стили и назначить другой, чтобы сохранилось фоновая подсветка невидимых участков.
antro735, забыл сказать главное преимущество рег.выров перед внутренним оптимизированным движком. Преимущество в том что пользователь задаёт свою раскраску, он может придумать собственный синтаксис или временно заставить некоторый документ подсвечиваться по заданным правилам. То есть мы пользователю даём инструмент в руки. В Notepad++ сейчас нет подсветки с помощью регулярных выражений, а в AkelPad есть. Я на форуме Notepad++ уже просил добавить рег.выры в "Собственный синтаксис", люди сами решат, тормозит ли у них файл или нет., не каждый ведь открывает файл размером 1-10 Мб. так что разобравшись вполне можно написать плаг, который подсветит в Notepad++ используя рег.выр. Я уже делал плаг на индикаторах и он работал разово, то есть можно выбрать в списке PureBasic и начать кнопку подсветить и он использует десяток рег.выров для подсветки. А теперь интересно было бы сделать это автоматически. По крайней мере я уже пробовал плаг, который при открытии файла перебивал подсветку Notepad++, но сделать это автоматический по расширению файлов не получилось просто запутался и не понял где не работает.
0
|
06.12.2022, 11:30 | 86 |
Из текущей ситуации пока вижу один выход:
1. При открытии файла подсветить весь файл во втором потоке, причём исключая видимый диапазон по полученным позициям (в LInux нет второго потока). 2. По мере редактирования у нас подсветка работает. 3. Вставка может быть тоже всего документа или больше чем видимый диапазон. Вот тут тоже надо посмотреть какие позиции будут получены и в принципе подсветить аналогично открытию файла - в пункте 1. 4. Подсмотреть исходники Notepad++ или PureBasic.
0
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
||||||
06.12.2022, 14:43 [ТС] | 87 | |||||
Я пытался брать диапазон строк видимой области, и по ходу скроллинга подсвечивать эту видимую область. Добавил для этого где у нас идёт блок Select *scinotify\nmhdr\code ещё уведомления от Case #SCN_PAINTED . Там можно при скроллинге получать порядковый номер самой верхней строки и количество строк в видимой области, и этот видимый диапазон подсвечивать
А где можно посмотреть исходный код PureBasic ? Хотя, я ещё плохо в чужих кодах ориентируюсь. А если он ещё и на каком-нибудь С++, боюсь, совсем не разберусь.
0
|
06.12.2022, 16:20 | 88 | |||||
antro735, я сделал так
по крайней мере тормозит только при открытии файла, а после уже ввод текста не происходит с тормозами
У меня вроде получилось, но из-за Linux вся идея ручного умного подсвечивания умирает из-за отсутствия потока. mk-soft предлагал вариант потока, надо посмотреть, как бы он не оказался псевдопотоком, который не будет работать как ожидается. Только с потоком можно подсветить весь файл не мешая пользователю сразу заниматься редактированием файла. Кстати, появлялась мысль - запоминать подсвеченное. Сейчас у меня режим подсветка поверх, но можно сделать флаг, который переключает подсветку на "подсвечивать только неподсвеченное". То есть надо иметь массив позиций подсвеченного и подсвечивать в промежутках, вставляя в список очередной уже подсвеченный диапазон. Возможно даже так будет работать быстрее, потому что каждый шаг исключает часть текста, но кто знает, из-за множества кусков это может отрабатывать медленно, надо вводить умный анализ чтобы пробелы прилегающие к подсвеченному элементу добавлять в его диапазон тем самым уменьшать раздробленность по пробелам. Да и как быть если при изменении текста позиции сдвигаются.
0
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
|
06.12.2022, 17:46 [ТС] | 89 |
AZJIO, в PureBasic ещё отсутствует функция SCI_SETIDLESTYLING. В документации она описана так:
SCI_SETIDLESTYLING(int idleStyling) SCI_GETIDLESTYLING → int По умолчанию, SC_IDLESTYLING_NONE (0), стиль синтаксиса выполняется для всего видимого в данный момент текста перед его отображением. В очень больших файлах это может замедлить прокрутку. С помощью SC_IDLESTYLING_TOVISIBLE (1) перед отображением выполняется небольшое количество стилей, а затем дополнительное стилирование выполняется в фоновом режиме в качестве задачи бездействия. Это может привести к тому, что текст изначально выглядит некрасивым, а затем, спустя некоторое время, он окрашен. Текст после видимой в настоящее время части может быть оформлен в фоновом режиме с помощью SC_IDLESTYLING_AFTERVISIBLE (2). Чтобы создать стиль перед и после видимого текста в фоновом режиме, используйте SC_IDLESTYLING_ALL (3). Вот, только жаль, что в PureBasic она отсутствует. Добавлено через 10 минут AZJIO, интересно, а можно ли сначала выполнить стилизацию в оперативной памяти, и выложить уже стилированный текст в редактор ? Наверняка, это было бы намного быстрее, но возможно ли это реализовать ? Добавлено через 5 минут Хотя... оно ведь так и происходит. Пока идёт стилизация, он и не отображает текст.
0
|
06.12.2022, 18:32 | 90 | |||||
https://github.com/fantaisie-software/purebasic/
Если нужно весь файл подсветить, можно текст обработать в отдельном потоке и сохранить в списке позиции начала и конца подсветки и ее стиль. После передать список в основной поток и в нем подсветить. Объявить не составляет труда https://github.com/vinsworldco... cintilla.h
0
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
|
06.12.2022, 18:58 [ТС] | 91 |
Да, видимо, у меня не та версия Scintilla, потому что это: #SCI_SETIDLESTYLING = 2692 я уже пытался делать.
Ты имеешь ввиду создать NewList и в него отдельным потоком сохранить позиции начала и конца каждого стиля, а потом соответственно этим позициям стилизовать в редакторе ?
0
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
|
06.12.2022, 20:03 [ТС] | 93 |
Надо завтра попробовать, сейчас у меня уже поздно.
0
|
07.12.2022, 08:57 | 94 |
antro735, использую XIncludeFile "Const.pb" из моего блокнота, там все константы. Ты мне даёшь документацию SCI_SETIDLESTYLING (посмотри на предыдущей странице), я неделю назад тебе про неё говорил, что не работает и не могу понять почему.
locm, если только сделать второй гаджет невидимый, в нём обработать текст получив позиции и применить их к текущему. Потому что к тексту в памяти нужен доступ по байтам, а не по позициям. Функции строковые возвращают позиции по символам. Но если вводить текст в Scintilla и получать позиции, то когда вводишь русские буквы позиция через 2 байта, а когда английский, то через 1 байт. Поэтому я и не использую рег.выр PureBasic (более продвинутый) для поиска так как если текст вперемешку русский и англ., то позиции неверны. Я вчера решил проверить вставку текста большого взамен текущего кода и он был правильно подсвечен. Возник вопрос, а может я неправильно открываю файл и вставляю текст, ведь открытие файла в принципе та же операция вставки в пустой документ. Вставка также тормозит доступ к документу, SCI_SETIDLESTYLING в этом случае не работает. antro735, перекачай мой "My_Notepad_Sci", я решил некоторые наработки вставить.
0
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
|
07.12.2022, 19:44 [ТС] | 95 |
0
|
08.12.2022, 10:39 | 96 |
antro735, посмотрел исходники IDE и даже скомпилировал IDE со своими изменениями. В общем в файле purebasic-devel\PureBasicIDE\ScintillaHighlighting.pb в строке 3039 есть событие #SCN_STYLENEEDED ну и далее код. Проблема, что он использует свой движок подсветки, где подсветка выполняется за один проход. Ну и мы не знаем поддерживается ли дополнительный движок рег.выр. SCFIND_CXX11REGEX. Буду изучать, мне кажется это лучший исходный код для изучения, так как это рабочая версия используемая сообществом из разных стран, а не пример.
0
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
|
08.12.2022, 11:50 [ТС] | 97 |
AZJIO, скачал себе тоже этот архив, нашёл ScintillaHighlighting.pb
Я так понимаю, это реализация подсветки в самом редакторе PureBasic. Интересно. Тоже попытаюсь там что-нибудь понять, если смогу разобраться, конечно.
0
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
||||||
15.12.2023, 07:49 [ТС] | 98 | |||||
У меня почему-то scintilla не хочет реагировать на клавишу 'Tab'. Сейчас автозавершение происходит по нажатию клавиши 'Enter', но это немного неудобно в некоторых моментах. Хотел привязать автозавершение к 'Tab', но эта клавиша вообще никак себя не проявляет. Даже при событии ввода символа #SCN_CHARADDED при попытке отобразить код события через Debug *scinotify/ch никакой код не выводится. Попытался привязать к 'Tab' автозавершение с помощью
0
|
15.12.2023, 13:31 | 99 |
В этом примере автозавершение выполняется при нажатии tab и enter.
0
|
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
|
|
15.12.2023, 14:04 [ТС] | 100 |
locm, Да, я помню про этот пример. Сам же его выкладывал. Но я не смог в нём разобраться. Немного сложновато для меня ещё такие чужие коды читать. Попробую, конечно, порыться как там это реализовано, если смогу разобраться...
Добавлено через 3 минуты locm, Там, кстати, тоже есть баги. Если в последней строке вписать 'While', а потом по символу начать удалять, то на последних двух оставшихся символах выскакивает ошибка. Добавлено через 13 минут locm, Скорее всего, там с 22 по 46 строку компилируется не та библиотека Scintilla.dll, с которой работает мой редактор, потому что в коде нигде нет привязки клавиши 'Tab' к автозавершению. Оно уже есть в его библиотеке.
0
|
15.12.2023, 14:04 | |
15.12.2023, 14:04 | |
Помогаю со студенческими работами здесь
100
Ввод и вывод массива с текстовым редактором Обработка больших файлов текстовым редактором Сценарий PowerShell для работы с текстовым редактором Проблемы с кирилицей при просмотре файлов модулей текстовым редактором В файл a.txt записать текстовым редактором значения элементов целочисловой матрицы Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |