Форум программистов, компьютерный форум, киберфорум
Pure Basic
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/26: Рейтинг темы: голосов - 26, средняя оценка - 4.73
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
1

Работа с текстовым редактором Scintilla

16.11.2022, 21:30. Показов 5241. Ответов 99
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток ! Тружусь над небольшой программкой, в которой у меня будет редактор кода на основе "Scintilla". Столкнулся с такой задачкой: нужно, чтобы при нахождении ключевого слова, происходила его замена. По типу как в пурике - если пользователь написал ключевое слово в нижнем регистре, редактор его заменил на то, как эти ключевые слова хранятся в программе. К примеру, пользователь прописал "for" -> редактор сменил на "For". При этом, пурик, как известно, подсветку производит непосредственно как только обнаруживает ключевое слово, а замену делает при наборе следующего символа. При этом, символ должен быть либо пробел, либо скобка, либо переход на новую строку и т.п.
Выкладываю свой самый сокращенный вариант для примера. В нём зарезервировано только одно ключевое слово "For", ну этого достаточно для теста. Тут я пытаюсь добиться желаемого, но как-то некорректно это происходит. В строчках 89, 90 как раз пытаюсь прописать эту замену, но почему-то она не работает как нужно.
Подскажите, пожалуйста, в чём ошибка ? Как только не пытался экспериментировать, никак не могу добиться желаемого. Документацию по Scintilla уже раз 40 пересматривал, изучал, но там тоже не так просто разобраться. Она таким тяжелым языком написана, а более понятной и доступной нигде не найти.
В общем, вот мой пример поиска решения, дальше которого я никак не могу продвинуться. Помогите, пожалуйста, если есть кто-то компетентный.

PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
InitScintilla("Scintilla.dll")
 
; Константы для подсветки синтаксиса
Enumeration 0
  #LexerState_Space
  #LexerState_Keyword
  #LexerState_FoldKeyword
EndEnumeration
 
Global ChangeWord$ = "For" ; слово для замены
 
Procedure MyLexerInit()
  ; Шрифт
  ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, @"Lucida Console")
  ; Размер шрифта
  ScintillaSendMessage(0, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 10)
  ScintillaSendMessage(0, #SCI_STYLECLEARALL)
  
  ; Цвет активной строки
  ScintillaSendMessage(0, #SCI_SETCARETLINEBACK, RGB(254, 252, 202))
  ; Разрешаем отмачать активную строку
  ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLE, #True)
  
  ; Цвета подсветки синтаксиса
  ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Keyword, 0)  ; Обычный текст
  ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_FoldKeyword, $FF) ; Ключевые слова
  
  ; Поля 
  ScintillaSendMessage(0, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER) ; Поле автонумирации
  ScintillaSendMessage(0, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS)  ; Поле свертки и маркеров
  ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 0, 20)               ; Ширина поля автонумирации
  ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 2, 20)               ; Ширина поля свертки и маркеров
  ScintillaSendMessage(0, #SCI_SETMARGINSENSITIVEN, 2, #True)
EndProcedure
 
Procedure SCI_EVENT(Gadget, *scinotify.SCNotification) ; Обработка событий от редактора
  code=             *scinotify.SCNotification\nmhdr\code
  pos=              *scinotify.SCNotification\Position
  ch=               *scinotify.SCNotification\ch
  modificationType= *scinotify.SCNotification\modifiers
  text=             *scinotify.SCNotification\text
  Length=           *scinotify.SCNotification\length
  linesAdded=       *scinotify.SCNotification\linesAdded
  message=          *scinotify.SCNotification\message
  wParam=           *scinotify.SCNotification\wParam
  lParam=           *scinotify.SCNotification\lParam
  line=             *scinotify.SCNotification\line
  foldLevelNow=     *scinotify.SCNotification\foldLevelNow
  foldLevelPrev=    *scinotify.SCNotification\foldLevelPrev
  margin=           *scinotify.SCNotification\margin
  listType=         *scinotify.SCNotification\listType
  x=                *scinotify.SCNotification\x
  y=                *scinotify.SCNotification\y
  
  
  Select code
    Case #SCN_STYLENEEDED
      EndPos = pos
      EndStyledPos = ScintillaSendMessage(0, #SCI_GETENDSTYLED)
      linenumber = ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, EndStyledPos)
      
      ; Текуцая позиция курсора
      CurrentPos.l = ScintillaSendMessage(0, #SCI_POSITIONFROMLINE, linenumber)
      ; Подготовка к стилистической правке
      ScintillaSendMessage(0, #SCI_STARTSTYLING, CurrentPos)
      State = #LexerState_Space
      KeywordStartPos = CurrentPos
      keyword.s = ""
      
      While CurrentPos <= EndPos
        OldState = State
        
        Char.l = ScintillaSendMessage(0, #SCI_GETCHARAT, CurrentPos) ; Получаем символ из текущей позиции 
        If Char = 10 Or Char = 13 Or Char = 9 Or Char = ' '
          State = #LexerState_Space
        Else
          State = #LexerState_Keyword
          keyword + Chr(Char)
        EndIf
        
        If OldState <> State Or CurrentPos = EndPos
          If OldState = #LexerState_Keyword
            lkeyword.s = LCase(keyword)
            If lkeyword = "for"
              LenKeyword = Len(lkeyword)
              *Kwd = AllocateMemory(LenKeyword)
              PokeS(*Kwd, ChangeWord$, LenKeyword, #PB_UTF8)
              
              ScintillaSendMessage(0, #SCI_DELETERANGE, pos - LenKeyword, LenKeyword)
              ScintillaSendMessage(0, #SCI_INSERTTEXT, -1, *Kwd)
              ScintillaSendMessage(0, #SCI_GOTOPOS, pos)
              FreeMemory(*Kwd)
              
              OldState = #LexerState_FoldKeyword
            EndIf
            keyword = ""
          EndIf
          ScintillaSendMessage(0, #SCI_SETSTYLING, CurrentPos - KeywordStartPos, OldState) ; Подсветка синтаксиса
          KeywordStartPos = CurrentPos
        EndIf
        CurrentPos + 1
      Wend
      
  EndSelect
EndProcedure
 
If OpenWindow(0, 450, 200, 402, 402, "Scintilla Example", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
  ScintillaGadget(0, 2, 2, 398, 398, @SCI_EVENT())
  MyLexerInit()
  
  Repeat
    Event = WaitWindowEvent()
    
  Until Event = #PB_Event_CloseWindow
EndIf
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.11.2022, 21:30
Ответы с готовыми решениями:

Работа с текстовым редактором
Доброе время суток!!! Помогите! пишу текстовый редактор, на основе ActionManager использовал...

Работа с текстовым редактором
Помогите пожалуйста доделать задание. Не понимаю как дальше сделать. Только начал изучать win form

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

С текстовым редактором C++ Builder
Всем привет, нужна ваша помощь. Делаю текстовый редактор, окно сохранить, открыть файл уже готовы....

Помощь с текстовым редактором
ребят нужна помощь!) нужно в текстовом редакторе сделать правописание жи-ши , т.е. пишим ЖЫ или Шы...

99
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
03.12.2022, 13:49  [ТС] 81
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от locm Посмотреть сообщение
Точно одинаковые?
Сейчас уже не смогу проверить. Это было около полугода назад. Они не могли быть разными, если я копирую весь код, открываю новую вкладку, вставляю скопированное, и тут же запускаю. Однако, ваши с AZJIO, советы принял во внимание себе на заметку.
Хотя, в данном случае, тоже есть некоторые непонятные мне пока моменты. Запускаю код редактора, над которым работаю, на своём ПК прямо из среды PureBasic, и этот же код запускаю на ноутбуке. Операционные системы одинаковые на обеих машинах. В коде реализовал множественное подсвечивание выделенного слова как в PureBasic - когда выделяешь, к примеру имя переменной, и во всём коде она подсвечивается. Выбрал для этого индикатор INDIC_STRAIGHTBOX. На ПК он ни в какую не хочет отображаться. Вместо него подсветка производится индикатором INDIC_PLAIN. Меняю тип индикатора на NDIC_BOX - он отображается нормально - все слова выделяются рамкой. Снова пытаюсь сменить индикатор на INDIC_STRAIGHTBOX, а он вновь отображает NDIC_BOX. Хотя, этот же самый код на ноутбуке вполне себе корректно отображает запрашиваемый INDIC_STRAIGHTBOX. Тоже причина пока мне не ясна.
0
43 / 40 / 3
Регистрация: 06.11.2010
Сообщений: 141
Записей в блоге: 1
03.12.2022, 14:36 82
Цитата Сообщение от locm Посмотреть сообщение
Перевод на русский
Вы должны стилизовать текст от строки, содержащей позицию, возвращенную SCI_GETENDSTYLED, до позиции, переданной в SCNotification.position.
Там выше написано: "Если вы используете SCI_SETILEXER..."
То есть насколько я понял некоторому движку передаётся диапазон для подсветки и он там делает эту подсветку самостоятельно, ища ключевые слова, операторы и т.д. Там даже сказано что SCI_GETENDSTYLED перемещается по мере подсветки. В моём случае если я делаю подсветку самостоятельно, откуда движку знать где начало, где конец? Если считать SCI_GETENDSTYLED концом, а SCI_SETSTYLING заставляет передвигать конец, но ведь я вызываю внутри цикл подсветки многократно вызывая SCI_SETSTYLING. *scinotify.SCNotification\Position является началом подсвечивания, но показывает конец документа, а SCI_GETENDSTYLED должен выдать конец подсвечивания, а выдаёт начало документа. Как он узнаёт что текст подсвечен или не подсвечен? Теоретически он должен подсвечивать строку, в которой произошло изменение. Я попробовал обозначить *scinotify.SCNotification\Position как конец, а SCI_GETENDSTYLED как начало, то заработало. Но опять же у меня при вводе символа подсвечивается от курсора до конца видимой части документа.
Пока я не понимаю как это работает, при выборе кодировки не подсвечивается, открытый документ не подсвечивается, при попытке ввода символа подсвечивает от начала до конца видимого. Буду дальше экспериментировать.

antro735, в общем я добавил в конец блока уведомления SCN_STYLENEEDED две строки
PureBasic
1
2
ScintillaSendMessage(#SciGadget, #SCI_STARTSTYLING, 999999, 0)
ScintillaSendMessage(#SciGadget, #SCI_SETSTYLING, 0, 0)
здесь 999999 это начальная точка подсвечивания, а длина 0. Именно 999999 должно быть за пределами документа, возможно увеличить, так как это всего 1 Мб, если стартовая внутри документа, а длина 0 то продолжает досить уведомление, а если число 999999 за пределами документа, то всё норм SCI_SETSTYLING даёт флаг что событие выполнилось и досить перестаёт, вообще не досит. Проверил 4000 строк, да это работает медленно, но благодаря переделке сейчас будет подсвечивать только видимую часть документа, остальное надо фоном, тогда я смогу вводить буквы без тормозов, не дожидаясь пока подсветит весь документ.
1
4394 / 2244 / 252
Регистрация: 28.10.2011
Сообщений: 8,575
Записей в блоге: 6
03.12.2022, 14:46 83
Цитата Сообщение от AZJIO Посмотреть сообщение
В моём случае если я делаю подсветку самостоятельно, откуда движку знать где начало, где конец?
Редактор сообщает какие области текста изменились (или ранее не подсвечивались) и требуют подсветки.
0
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
03.12.2022, 15:54  [ТС] 84
Цитата Сообщение от AZJIO Посмотреть сообщение
в общем я добавил в конец блока уведомления SCN_STYLENEEDED две строки
Отлично, AZJIO, это реально работает !

Остался ещё такой момент: если скопировать некий код, опять же, в 4 - 5 тыс. строк, и пытаться его вставить в редактор, то он слишком долго думает перед тем, как его отобразить. В моём случае, он зависает секунд аж на 10 - 12. Есть какие-то варианты избавиться от этого явления ?
0
43 / 40 / 3
Регистрация: 06.11.2010
Сообщений: 141
Записей в блоге: 1
03.12.2022, 16:17 85
locm, я написал сумбурно. Теперь по полочкам: есть вариант "костыли": я могу как у меня сделано в Grub2-generator (Sci).pb подсветить строку при вводе символа или подсветить вставленный текст при вставке, казалось бы 2 режима полностью покрывают мои хотелки. Но в этом случае я теряю флаг SCI_SETIDLESTYLING + SC_IDLESTYLING_ALL то есть подсветить видимое и фоном подсвечивать за пределами видимого, если файлы большие. Значит желательно разобраться.
Теперь правильный вариант: начало и конец поменяны местами, иначе у меня проц работает на полную катушку а редактор бездействует, то есть начало 999 а конец 0, естественно это не работает. Меняю местами (метод тыка). При этом при открытии подсвечивается видимое, а фоном ничего не подсвечивается, да и начало и конец в отладчике выдают видимое, соответственно невидимое непонятно как подсветится, может ещё какой флаг нужен для запуска подсветки невидимого в фоне. Второе - ввод символа подсвечивает 2 строки в той где курсор и ниже. Это неплохо, а вот с открытием пока проблема, в фоне не подсвечивается, документ не подсвечен. Ну и непонятно как принудительно выслать SCN_STYLENEEDED например при смене стиля очистить стили и назначить другой, чтобы сохранилось фоновая подсветка невидимых участков.

PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Procedure SciNotification(Gadget, *scinotify.SCNotification)
    Protected regex$, *mem, posEnd, posStart, pos, line, pos2
    With *scinotify
        Select \nmhdr\code
            Case #SCN_STYLENEEDED
;               начало и конец поменяны местами
                posStart = ScintillaSendMessage(#SciGadget, #SCI_GETENDSTYLED)
                posEnd = *scinotify.SCNotification\Position
;               чтобы взять от начала строки
                line = ScintillaSendMessage(#SciGadget, #SCI_LINEFROMPOSITION, posStart) 
                posStart = ScintillaSendMessage(#SciGadget, #SCI_POSITIONFROMLINE, line)
;               вывод начала и конца чтобы контролировать позиции
                Debug Str(posStart) + "  -  " + Str(posEnd)
                
;               меняем флаг, так как он мог быть изменён флагами поиска в редакторе
                ScintillaSendMessage(#SciGadget, #SCI_SETSEARCHFLAGS, #SCFIND_REGEXP | #SCFIND_POSIX)
                
                ForEach regex()
;                   цикл списка регекспов для подсветки
                    Color(regex()\mem, regex()\len, regex()\id, posStart, posEnd)
                Next
                
;               выполняем SCI_SETSTYLING, чтобы закрыть работу уведомлений
                ScintillaSendMessage(#SciGadget, #SCI_STARTSTYLING, 99999999, 0)        
                ScintillaSendMessage(#SciGadget, #SCI_SETSTYLING, 0, 0)     
        EndSelect
    EndWith
EndProcedure
Добавлено через 15 минут
antro735, забыл сказать главное преимущество рег.выров перед внутренним оптимизированным движком. Преимущество в том что пользователь задаёт свою раскраску, он может придумать собственный синтаксис или временно заставить некоторый документ подсвечиваться по заданным правилам. То есть мы пользователю даём инструмент в руки. В Notepad++ сейчас нет подсветки с помощью регулярных выражений, а в AkelPad есть. Я на форуме Notepad++ уже просил добавить рег.выры в "Собственный синтаксис", люди сами решат, тормозит ли у них файл или нет., не каждый ведь открывает файл размером 1-10 Мб. так что разобравшись вполне можно написать плаг, который подсветит в Notepad++ используя рег.выр. Я уже делал плаг на индикаторах и он работал разово, то есть можно выбрать в списке PureBasic и начать кнопку подсветить и он использует десяток рег.выров для подсветки. А теперь интересно было бы сделать это автоматически. По крайней мере я уже пробовал плаг, который при открытии файла перебивал подсветку Notepad++, но сделать это автоматический по расширению файлов не получилось просто запутался и не понял где не работает.
0
43 / 40 / 3
Регистрация: 06.11.2010
Сообщений: 141
Записей в блоге: 1
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
1
2
ScintillaSendMessage(#Scintilla_Gadget, #SCI_GETFIRSTVISIBLELINE) ; номер первой строки видимой области
ScintillaSendMessage(#Scintilla_Gadget, #SCI_LINESONSCREEN) ; количество строк видимой области
Пытаюсь реализовать, но пока у меня не получается это сделать.
Цитата Сообщение от AZJIO Посмотреть сообщение
4. Подсмотреть исходники Notepad++ или PureBasic.
А где можно посмотреть исходный код PureBasic ? Хотя, я ещё плохо в чужих кодах ориентируюсь. А если он ещё и на каком-нибудь С++, боюсь, совсем не разберусь.
0
43 / 40 / 3
Регистрация: 06.11.2010
Сообщений: 141
Записей в блоге: 1
06.12.2022, 16:20 88
antro735, я сделал так
по крайней мере тормозит только при открытии файла, а после уже ввод текста не происходит с тормозами
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
If IsOpenFile ; флаг =1 при открытии документа
;   тут заранее запрос диапазонов до и после видимого
    Protected before1, before2, After1, After2
    before1 = 0
    before2 = posStart
    After1 = posEnd
    After2 = ScintillaSendMessage(#SciGadget, #SCI_GETTEXTLENGTH) 
EndIf
 
; тут подсвечивается только видимый фрагмент кода или две строки где происходит правка
ForEach regex()
    Color(regex()\mem, regex()\len, regex()\id, posStart, posEnd)
Next
 
If IsOpenFile
;   тут если документ короткий умещается в видимом, то ничего не делаем,
;   а если есть невидимые участки, то обрабатываем их
    If before1 <> before2
        ForEach regex()
            Color(regex()\mem, regex()\len, regex()\id, before1, before2)
        Next
    EndIf
    If After1 <> After2
        ForEach regex()
            Color(regex()\mem, regex()\len, regex()\id, After1, After2)
        Next
    EndIf
    IsOpenFile = 0 ; сбрасываем флаг в 0, так как подсветили
EndIf
На счёт прокрутки... Ну где остановка? То есть начал крутить текст по 3 строки, он у тебя пропустит к примеру 40 строк плавно прокрутки или всё что ты крутишь он будет в режиме реального времени подсвечивать? Тогда нужно ещё добавлять массив подсвеченных диапазонов, чтобы не подсвечивать повторно уже подсвеченное. У тебя должен быть некий флаг, чтобы отменить подсветку всего пока пользователь крутит текст и в этот момент кешировать все диапазоны, которые пользователь увидел и подсветил, чтобы потом "фоном" подсветить остатки.
У меня вроде получилось, но из-за 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
4394 / 2244 / 252
Регистрация: 28.10.2011
Сообщений: 8,575
Записей в блоге: 6
06.12.2022, 18:32 90
Цитата Сообщение от antro735 Посмотреть сообщение
А где можно посмотреть исходный код PureBasic?
https://github.com/fantaisie-software/purebasic/

Цитата Сообщение от AZJIO Посмотреть сообщение
У меня вроде получилось, но из-за Linux вся идея ручного умного подсвечивания умирает из-за отсутствия потока.
Если нужно весь файл подсветить, можно текст обработать в отдельном потоке и сохранить в списке позиции начала и конца подсветки и ее стиль. После передать список в основной поток и в нем подсветить.

Цитата Сообщение от antro735 Посмотреть сообщение
Вот, только жаль, что в PureBasic она отсутствует.
Объявить не составляет труда https://github.com/vinsworldco... cintilla.h
PureBasic
1
#SCI_SETIDLESTYLING = 2692
В используемой версии Scintilla должна быть поддержка SCI_SETIDLESTYLING, иначе работать не будет.
0
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
06.12.2022, 18:58  [ТС] 91
Цитата Сообщение от locm Посмотреть сообщение
В используемой версии Scintilla должна быть поддержка SCI_SETIDLESTYLING, иначе работать не будет.
Да, видимо, у меня не та версия Scintilla, потому что это: #SCI_SETIDLESTYLING = 2692 я уже пытался делать.
Цитата Сообщение от locm Посмотреть сообщение
сохранить в списке позиции начала и конца подсветки и ее стиль
Ты имеешь ввиду создать NewList и в него отдельным потоком сохранить позиции начала и конца каждого стиля, а потом соответственно этим позициям стилизовать в редакторе ?
0
4394 / 2244 / 252
Регистрация: 28.10.2011
Сообщений: 8,575
Записей в блоге: 6
06.12.2022, 19:54 92
Цитата Сообщение от antro735 Посмотреть сообщение
создать NewList и в него отдельным потоком сохранить позиции начала и конца каждого стиля
Да.
0
1 / 1 / 0
Регистрация: 28.07.2018
Сообщений: 115
06.12.2022, 20:03  [ТС] 93
Надо завтра попробовать, сейчас у меня уже поздно.
0
43 / 40 / 3
Регистрация: 06.11.2010
Сообщений: 141
Записей в блоге: 1
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
Цитата Сообщение от AZJIO Посмотреть сообщение
я неделю назад тебе про неё говорил, что не работает и не могу понять почему
Да, извиняюсь. Я тогда ещё не совсем понял о чём шла речь.
0
43 / 40 / 3
Регистрация: 06.11.2010
Сообщений: 141
Записей в блоге: 1
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' автозавершение с помощью
PureBasic
1
ScintillaSendMessage(#Scintilla_Gadget, #SCI_ASSIGNCMDKEY, #SCK_TAB, #SCI_AUTOCCOMPLETE)
никакого эффекта не дало. Даже не знаю уже что я упускаю... Или же это в библиотеке Scintilla 'Tab' упущена. Сталкивался кто-нибудь с таким ?
0
4394 / 2244 / 252
Регистрация: 28.10.2011
Сообщений: 8,575
Записей в блоге: 6
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.12.2023, 14:04
Помогаю со студенческими работами здесь

Ввод и вывод массива с текстовым редактором
Ребят помогите срочно нужно сделать так чтобы считывался массив с in.txt и отправлялся полученный...

Обработка больших файлов текстовым редактором
У меня задание написать текстовый редактор, в целом всё ясно, за исключение пункта: &quot;возможность...

Сценарий PowerShell для работы с текстовым редактором
Доброго времени суток!!! Очень нуждаюсь в вашей помощи! Начали изучать в университете новый...

Проблемы с кирилицей при просмотре файлов модулей текстовым редактором
Пользуюсь AcelPad. В Embarcadero XE-4 никаких проблем с этим не было, ни в Delphi, ни в Buildere....

В файл a.txt записать текстовым редактором значения элементов целочисловой матрицы
В файл a.txt записать текстовым редактором значения элементов целочисловой матрицы А размером 4х4,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru