AZJIO

PureBasic Linux Scintilla Notepad

Nov 11th, 2018
884
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. EnableExplicit
  2. InitScintilla()
  3.  
  4. ; #MENU_EXTEND_SELECTION=10
  5. Define txt$, txtLen, marginWidth, Gadget
  6. Declare Color(*regex, regexLength, n)
  7. Declare Color2(*regex, regexLength, n)
  8. Declare MakeUTF8Text(text.s)
  9. Declare MakeScintillaText(text.s, *sciLength.Integer=0)
  10. Declare OpenFileR(*sciLength.Integer=0)
  11. Declare SciNotification(Gadget, *scinotify.SCNotification)
  12. Declare ReadFileR(Path$)
  13.  
  14. ; Procedure ExtendScintillaSelection()
  15. ;    Protected mainSel, selStart, selEnd
  16. ;    mainSel=ScintillaSendMessage(0, #SCI_GETMAINSELECTION)
  17. ;    selStart=ScintillaSendMessage(0, #SCI_GETSELECTIONNSTART, mainSel)
  18. ;    selEnd=ScintillaSendMessage(0, #SCI_GETSELECTIONNEND, mainSel)
  19. ;    
  20. ; EndProcedure
  21.  
  22. txt$="Вставка теста "+#CR$+
  23. "вы можете  использовать это код как пример работы со Scintilla"+#CR$+
  24. "ссылка http://purebasic.info/phpBB3ex/index.php"+#CR$+
  25. "Это поиск, маркеры, стилизация, и т.д. 2222 "+#CR$
  26. txtLen=StringByteLength(txt$, #PB_UTF8)
  27.  
  28. OpenWindow(100, 0, 0, 900, 600, "Редактор Scintilla", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
  29.  
  30. ; Создание гаджета размером на всё окно
  31. ScintillaGadget(0, 0, 0, WindowWidth(100), WindowHeight(100), @SciNotification())
  32. ; Устанавливает режим текста
  33. ScintillaSendMessage(0, #SCI_SETWRAPMODE, #SC_WRAP_NONE) ; без переносов строк
  34. ScintillaSendMessage(0, #SCI_SETCODEPAGE, #SC_CP_UTF8)   ; в кодировке UTF-8
  35.                                                          ; ScintillaSendMessage(0, #SCI_SETVIRTUALSPACEOPTIONS, #SCVS_RECTANGULARSELECTION | #SCVS_USERACCESSIBLE) ; позволить установить курсор и выделение за пределами конца строки
  36.                                                          ; Устанавливает текущую подсветку строки
  37. ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLE, 1)     ; подсвечивает текущую строку
  38. ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLEALWAYS, 1) ; подсвечивает всегда, даже при потере фокуса
  39.                                                            ; ScintillaSendMessage(0, #SCI_SETCARETLINEBACKALPHA, 255) ; прозрачность подсветки текущей строки (0-255), 255 прозрачна на 100%
  40. ScintillaSendMessage(0, #SCI_SETCARETLINEBACK, RGB(0, 0, 0)) ; цвет подсвеченной строки
  41.                                                              ; Устанавливает стиль текста
  42. ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text("Arial")) ; выделение прямоугольником лучше работает с моноширинным шрифтом Courier New
  43. ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(63, 63, 63))       ; цвет фона
  44. ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(153, 153, 153))    ; цвет текста
  45. ScintillaSendMessage(0, #SCI_STYLECLEARALL)
  46. ; Устанавливает размер отступа и стиль колонки номеров строк
  47. ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_LINENUMBER, MakeUTF8Text("Arial")) ; шрифт номеров строк
  48. ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(33, 33, 33))       ; цвет фона поля номеров строк
  49. ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(153, 153, 153))    ; цвет текста поля номеров строк
  50. marginWidth=ScintillaSendMessage(0, #SCI_TEXTWIDTH, #STYLE_LINENUMBER, MakeUTF8Text("_999")) ; ширина поля номеров строк
  51. ScintillaSendMessage(0, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
  52. ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 0, marginWidth) ; Устанавливает ширину поля номеров строк
  53. marginWidth=0
  54. ScintillaSendMessage(0, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS) ; Устанавливает отступ для поля свёртывания с запасом сгиба
  55. ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 2, marginWidth)     ; Устанавливает ширину поля свёртывания
  56. ScintillaSendMessage(0, #SCI_SETMARGINSENSITIVEN, 2, #True)       ; Устанавливает чуствительность поля к клику
  57.                                                                   ; Устанавливает стиль текстовго курсора и выделения
  58. ScintillaSendMessage(0, #SCI_SETCARETSTICKY, 1)                   ; делает всегда видимым (?)
  59. ScintillaSendMessage(0, #SCI_SETCARETWIDTH, 1)                    ; толщина текстовго курсора
  60. ScintillaSendMessage(0, #SCI_SETCARETFORE, RGB(255, 255, 255))    ; цвет текстовго курсора
  61. ScintillaSendMessage(0, #SCI_SETSELALPHA, 100)                    ; прозрачность выделения
  62. ScintillaSendMessage(0, #SCI_SETSELBACK, 1, RGB(255, 255, 255))   ; цвет фона выделения
  63. ScintillaSendMessage(0, #SCI_SETSELFORE, 1, RGB(160, 160, 160))   ; цвет текста выделения
  64.                                                                   ; Устанавливает дополнительные стили при использовании множественного курсора и выделения
  65. ScintillaSendMessage(0, #SCI_SETADDITIONALCARETFORE, RGB(255, 160, 160)) ; цвет дополнительного текстовго курсора
  66. ScintillaSendMessage(0, #SCI_SETADDITIONALCARETSBLINK, 1)                ; мигание дополнительного текстовго курсора
  67. ScintillaSendMessage(0, #SCI_SETADDITIONALSELALPHA, 100)                 ; прозрачность дополнительного выделения
  68. ScintillaSendMessage(0, #SCI_SETADDITIONALSELBACK, RGB(255, 255, 100))   ; цвет фона дополнительного выделения
  69. ScintillaSendMessage(0, #SCI_SETADDITIONALSELFORE, RGB(255, 255, 130))   ; цвет текста дополнительного выделения
  70.                                                                          ; Разрешает множественный курсор
  71. ScintillaSendMessage(0, #SCI_SETRECTANGULARSELECTIONMODIFIER, #SCMOD_ALT); выделить, удерживая нажатой клавишу Alt
  72. ScintillaSendMessage(0, #SCI_SETMULTIPLESELECTION, 1)                    ; позволяет выделить несколько раз удерживая нажатой клавишу CTRL или CMD
  73. ScintillaSendMessage(0, #SCI_SETMULTIPASTE, #SC_MULTIPASTE_EACH)         ; множественная вставка текста
  74. ScintillaSendMessage(0, #SCI_SETADDITIONALSELECTIONTYPING, 1)            ; позволяет ввод текста, перемешение курсора и т.д. сразу в нескольких местах
  75.  
  76. ; ScintillaSendMessage(0, #SCI_USEPOPUP, 1)
  77. ; ScintillaSendMessage(0, #SCI_SETVSCROLLBAR, 1)             ; вертикальная полоса прокрутки всегда
  78.  
  79. ; Разрешить горячую клаваишу CTRL + D для дополнительного авто выделения
  80. ; AddKeyboardShortcut(100, #PB_Shortcut_Control | #PB_Shortcut_D, #MENU_EXTEND_SELECTION)
  81. ; BindEvent(#PB_Event_Menu, ExtendScintillaSelection())
  82.  
  83.  
  84. ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeUTF8Text(txt$)) ; Установить текст гаджета
  85. ScintillaSendMessage(0, #SCI_GOTOPOS, txtLen)                ; Курсор в конец текста
  86. SetActiveGadget(0)                                           ; Установить гаджет активным, фокус ввода
  87.  
  88. ; Эти константы будут использоватся для подсветки синтаксиса.
  89. Enumeration 0
  90.     #LexerState_Space
  91.     #LexerState_Number
  92.     #LexerState_Keyword
  93.     #LexerState_String
  94.     #LexerState_Preprocessor
  95.     #LexerState_Operator
  96.     #LexerState_Comment
  97.     #LexerState_FoldKeyword
  98. EndEnumeration
  99. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Comment, RGB(113, 174, 113)) ; Цвет комментариев
  100. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Number, $ABCEE3)             ; Цвет чисел, BGR
  101. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Keyword, $FF9F00)            ; Цвет ключевых слов, BGR
  102. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Preprocessor, $DE97D9)       ; Цвет препроцессор, BGR
  103. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Operator, $8080FF)           ; Цвет препроцессор, BGR
  104. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_FoldKeyword, RGB(0, 136, 0)) ; Цвет ключевых слов со сворачиванием.
  105. ScintillaSendMessage(0, #SCI_STYLESETBOLD, #LexerState_Number, 1)                   ; Выделять чисел жирным шрифтом
  106. ScintillaSendMessage(0, #SCI_STYLESETITALIC, #LexerState_Comment, 1)                ; Выделять комментарии наклонным шрифтом
  107.                                                                                     ; MessageRequester(Str(#STYLE_LINENUMBER) , Str(#STYLE_DEFAULT)) ; тут проверяем константы других стилей, почем они не мешают
  108.  
  109. ; Для RGB из Веб
  110. ; Global num.i = Val("$71AE71")
  111. ; Global num_text.s = Str(Red(num)) + ", " + Str(Green(num)) + ", " + Str(Blue(num))
  112. ; Debug num_text ; Отображает цвет в формате функции RGB
  113.  
  114. ; Пробуем применить стиль (проблема с позиционированием и длинной)
  115. ScintillaSendMessage(0, #SCI_STARTSTYLING, 50, 0) ; позиция начала (с 50-го)
  116. ScintillaSendMessage(0, #SCI_SETSTYLING, 14, #LexerState_Comment) ; ширина и номер стиля
  117.  
  118. If CreateMenu(0, WindowID(100))  ; Здесь начинается создание меню....
  119.     MenuTitle("Меню")
  120.     MenuItem(1, "Открыть файл")
  121.     MenuItem(2, "Вставить текущую дату")
  122.     MenuItem(3, "Вставить из буфера обмена")
  123.     MenuBar() ; разделитель
  124.     MenuItem(4, "Выход")
  125.     MenuItem(5, "Найти числа (индикаторы)")
  126.     MenuItem(6, "Найти числа (стиль)")
  127.     MenuItem(7, "Очистить стиль")
  128. EndIf
  129.  
  130. Global Event, em, Text$, TextLength, regex$
  131. Repeat
  132.     Event = WaitWindowEvent()
  133.     Select Event
  134.         Case #PB_Event_SizeWindow
  135.             ResizeGadget(0, #PB_Ignore, #PB_Ignore, WindowWidth(100), WindowHeight(100))
  136.         Case #PB_Event_Menu
  137.             em = EventMenu()
  138.             Select em
  139.                 Case 1
  140.                     OpenFileR()
  141.                 Case 2
  142.                     Text$ =  FormatDate("%dd.%mm.%yyyy", Date()) ; Возвращает текущую дату
  143.                                                                  ;ScintillaSendMessage(0, #SCI_APPENDTEXT, Len(Text$), MakeUTF8Text(Text$)) ; не работает с UTF-8
  144.                                                                  ;                  ScintillaSendMessage(0, #SCI_INSERTTEXT, txtLen, MakeUTF8Text(Text$)) ; проблема измерять длину текста в Scintilla каждый раз
  145.                     ScintillaSendMessage(0, #SCI_APPENDTEXT, TextLength, MakeScintillaText(Text$, @TextLength))
  146.                 Case 3
  147.                     ;                   Text$ = "вставленный текст" ; перед вставкой приводится к формату UTF-8
  148.                     Text$ = GetClipboardText()
  149.                     ScintillaSendMessage(0, #SCI_APPENDTEXT, TextLength, MakeScintillaText(Text$, @TextLength))
  150.                 Case 4
  151.                     Break
  152.                 Case 5
  153.                     regex$ = "\d+"
  154.                     Color(MakeScintillaText(regex$, @TextLength), Len(regex$), 7)
  155.                 Case 6
  156.                     regex$ = "\d+"
  157.                     Color2(MakeScintillaText(regex$, @TextLength), Len(regex$), 7)
  158.                 Case 7
  159.                     ScintillaSendMessage(0, #SCI_CLEARDOCUMENTSTYLE)
  160.             EndSelect
  161.         Case #PB_Event_CloseWindow
  162.             Break
  163.     EndSelect
  164. ForEver
  165.  
  166. FreeMenu(0)
  167. CloseWindow(100)
  168. End
  169.  
  170. ; Уведомления
  171. ProcedureDLL SciNotification(Gadget, *scinotify.SCNotification)
  172.     Protected Path$, pos
  173. ;   Select Gadget
  174. ;       Case 0 ; уведомление гаджету 0 (Scintilla)
  175.     With *scinotify
  176.         Select \nmhdr\code
  177.             Case #SCN_URIDROPPED ; о броске файлов в окно
  178. ;               Debug PeekS(*scinotify.SCNotification\text, -1, #PB_Ascii)
  179.                 Path$ = PeekS(*scinotify.SCNotification\text, -1, #PB_UTF8 | #PB_ByteLength)
  180. ;               Path$ = PeekS(*scinotify.SCNotification\text, -1, #PB_Ascii)
  181.                 pos = FindString(Path$, Chr(10)) ; обрезка, оставляя 1 файл
  182.                 If pos
  183.                     Path$ = LSet(Path$ , pos-2)
  184.                 EndIf
  185.                 Path$ = RemoveString(Path$ , "file://", #PB_String_CaseSensitive, 1, 1) ; удалить 1 раз
  186.                 Debug Path$
  187.                 ReadFileR(Path$)
  188.         EndSelect
  189.     EndWith
  190. ;   EndSelect
  191. EndProcedure
  192.  
  193.  
  194. ; Преобразование текста в текст для вставки в Scintilla
  195. Procedure MakeUTF8Text(text.s)
  196.     Static buffer.s
  197.     buffer=Space(StringByteLength(text, #PB_UTF8))
  198.     PokeS(@buffer, text, -1, #PB_UTF8)
  199.     ProcedureReturn @buffer
  200. EndProcedure
  201.  
  202. Procedure MakeScintillaText(text.s, *sciLength.Integer=0)
  203.     Static sciLength : sciLength=StringByteLength(text, #PB_UTF8) ; #TextEncoding
  204.     Static sciText.s : sciText = Space(sciLength)
  205.     If *sciLength : *sciLength\i=sciLength : EndIf ;<--- Возвращает длину буфера scintilla  (требуется для определенной команды scintilla)
  206.     PokeS(@sciText, text, -1, #PB_UTF8)            ; #TextEncoding
  207.     ProcedureReturn @sciText
  208. EndProcedure
  209.  
  210. Procedure OpenFileR(*sciLength.Integer=0)
  211.     ;   Запрос пути к файлу
  212.     Protected Path$ = OpenFileRequester("Выберите файл","","Текст|*.txt;*.bat;*.pb|Все файлы (*.*)|*.*",0)
  213.     If Path$ ; так как sciLength = 0 это критерий отмены для следующей функции
  214.         ReadFileR(Path$)
  215.     EndIf
  216. EndProcedure
  217.  
  218. Procedure ReadFileR1(Path$) ; свой вариант заменил вариантом из справки, см ниже
  219.     Protected sizefile, *MemoryBuffer
  220.     sizefile = FileSize(Path$) ; определяем размер данных в байтах
  221.     If sizefile => 0 ; файл существует
  222.         *MemoryBuffer = AllocateMemory(sizefile) ; выделение памяти под размер файла
  223.         ReadFile(0 , Path$, #PB_UTF8)
  224.         ReadData(0, *MemoryBuffer, sizefile) ; чтение файла в память
  225.         CloseFile(0)                         ; закрытие файла
  226.         ScintillaSendMessage(0, #SCI_SETTEXT, 0, *MemoryBuffer)
  227.         ;       ScintillaSendMessage(0, #SCN_UPDATEUI, #SC_UPDATE_V_SCROLL) ; не то, надо обновить прокрутку
  228.         FreeMemory(*MemoryBuffer)
  229.     EndIf
  230. EndProcedure
  231.  
  232. Procedure ReadFileR(Path$)
  233.     Protected length, *MemoryID
  234.     If ReadFile(0, Path$)
  235.         length = Lof(0)                            ; получаем длину открытого файла
  236.         *MemoryID = AllocateMemory(length)        ; выделяем необходимую память
  237.         If *MemoryID
  238.             ReadData(0, *MemoryID, length)  ; считаем все данные в блок памяти
  239.         EndIf
  240.         CloseFile(0)
  241.         ScintillaSendMessage(0, #SCI_SETTEXT, 0, *MemoryID)
  242.         FreeMemory(*MemoryID)
  243.     EndIf
  244. EndProcedure
  245.  
  246. ; Подсвечивание через индикаторы
  247. Procedure Color(*regex, regexLength, n)
  248.     Protected txtLen, StartPos, EndPos, firstMatchPos
  249.    
  250.     ; Устанавливает режим поиска (REGEX + POSIX фигурные скобки)
  251.     ScintillaSendMessage(0, #SCI_SETSEARCHFLAGS, #SCFIND_REGEXP | #SCFIND_POSIX)
  252.    
  253.     ; Устанавливает целевой диапазон поиска
  254.     txtLen = ScintillaSendMessage(0, #SCI_GETTEXTLENGTH) ; получает длину текста
  255.     ScintillaSendMessage(0, #SCI_INDICSETSTYLE, n, 6)    ; #INDIC_TEXTFORE = 17 создаёт индикатор под номером 7 (занятые по уиолчанию 0, 1, 2)
  256.     ScintillaSendMessage(0, #SCI_INDICSETFORE, n, $71AE71) ; назначает цвет индикатора под номером 7 - зелёный
  257.    
  258.     EndPos = 0
  259.     Repeat
  260.         ScintillaSendMessage(0, #SCI_SETTARGETSTART, EndPos)       ; от начала (задаём область поиска) используя позицию конца предыдущего поиска
  261.         ScintillaSendMessage(0, #SCI_SETTARGETEND, txtLen)         ; до конца по длине текста
  262.         firstMatchPos=ScintillaSendMessage(0, #SCI_SEARCHINTARGET, regexLength, *regex) ; возвращает позицию первого найденного. В параметрах длина искомого и указатель
  263.         If firstMatchPos>-1                                                             ; если больше -1, то есть найдено, то
  264.             StartPos=ScintillaSendMessage(0, #SCI_GETTARGETSTART)                       ; получает позицию начала найденного
  265.             EndPos=ScintillaSendMessage(0, #SCI_GETTARGETEND)                           ; получает позицию конца найденного
  266.             ScintillaSendMessage(0, #SCI_SETINDICATORCURRENT, n)                        ; делает индикатор под номером 7 текущим
  267.             ScintillaSendMessage(0, #SCI_INDICATORFILLRANGE, StartPos, EndPos - StartPos)  ; выделяет текст используя текущий индикатор
  268.         Else
  269.             Break
  270.         EndIf
  271.     ForEver
  272. EndProcedure
  273.  
  274. ; Подсвечивание через стиль
  275. Procedure Color2(*regex, regexLength, n)
  276.     Protected txtLen, StartPos, EndPos, firstMatchPos
  277.    
  278.     ; Устанавливает режим поиска (REGEX + POSIX фигурные скобки)
  279.     ScintillaSendMessage(0, #SCI_SETSEARCHFLAGS, #SCFIND_REGEXP | #SCFIND_POSIX)
  280.    
  281.     ; Устанавливает целевой диапазон поиска
  282.     txtLen = ScintillaSendMessage(0, #SCI_GETTEXTLENGTH) ; получает длину текста
  283.    
  284.     EndPos = 0
  285.     Repeat
  286.         ScintillaSendMessage(0, #SCI_SETTARGETSTART, EndPos)       ; от начала (задаём область поиска) используя позицию конца предыдущего поиска
  287.         ScintillaSendMessage(0, #SCI_SETTARGETEND, txtLen)         ; до конца по длине текста
  288.         firstMatchPos=ScintillaSendMessage(0, #SCI_SEARCHINTARGET, regexLength, *regex) ; возвращает позицию первого найденного. В параметрах длина искомого и указатель
  289.         If firstMatchPos>-1                                                             ; если больше -1, то есть найдено, то
  290.             StartPos=ScintillaSendMessage(0, #SCI_GETTARGETSTART)                       ; получает позицию начала найденного
  291.             EndPos=ScintillaSendMessage(0, #SCI_GETTARGETEND)                           ; получает позицию конца найденного
  292.             ScintillaSendMessage(0, #SCI_STARTSTYLING, StartPos, 0)                     ; позиция начала (с 50-го)
  293.             ScintillaSendMessage(0, #SCI_SETSTYLING, EndPos - StartPos, #LexerState_Number) ; ширина и номер стиля
  294.         Else
  295.             Break
  296.         EndIf
  297.     ForEver
  298. EndProcedure
RAW Paste Data