Creating an IDE
- captain_skank
- Enthusiast
- Posts: 641
- Joined: Fri Oct 06, 2006 3:57 pm
- Location: England
Creating an IDE
Hi all,
I've been pratting around with creating my own form designer that fits my own specific needs.
I'm quite happy with what i've come up with but want to extend it to be able to include code.
But i have no idea on the best way to acheive this as i'd like to include the funtionality of the default pb ide such as completion, syntax colouring etc.
Is there a simple way to do this E.G importing from the PB IDE or has this all got be coded from scratch using the scinitilla gadget ??
cheers
I've been pratting around with creating my own form designer that fits my own specific needs.
I'm quite happy with what i've come up with but want to extend it to be able to include code.
But i have no idea on the best way to acheive this as i'd like to include the funtionality of the default pb ide such as completion, syntax colouring etc.
Is there a simple way to do this E.G importing from the PB IDE or has this all got be coded from scratch using the scinitilla gadget ??
cheers
Re: Creating an IDE
I think it would be better, especially since there are examples for thisusing scintilla gadget ?? yay
It was very interesting to seeЯ очень доволен тем, что я придумал

- captain_skank
- Enthusiast
- Posts: 641
- Joined: Fri Oct 06, 2006 3:57 pm
- Location: England
Re: Creating an IDE
Does the existing PB ide utilise scintilla ?? and is there a way of exporting the parser ??
Cos doin this from scratch just seems like reinventing the wheel
Cos doin this from scratch just seems like reinventing the wheel

Re: Creating an IDE
Yes.captain_skank wrote:Does the existing PB ide utilise scintilla ??
No.and is there a way of exporting the parser ??
Cos doin this from scratch just seems like reinventing the wheel
However, if you use GoScintilla (a very powerful lexer by srod), you get most of PB's lexer capabilities by loading variables with keywords plus a few lines of setup calls.
Re: Creating an IDE
Just an idea - if I had the same purpose and wanted to achieve the result as fast as possible - just used some mainstream programming language + human usable IDE(e.g. Delphi or VS) + some commercial components, e.g. http://www.econtrol.ru/formdsn.html
Re: Creating an IDE
The IDE's syntax parser (the one that does the coloring) is available as a dll in the purebasic package in the SDK folder. This make it easy to add coloring to a project. A basic example is provided below. Features like auto completion will be more work as you need to scan the source code yourself to extract tokens such as variables and functions for the completion list.
Scintilla documentation: http://www.scintilla.org/ScintillaDoc.html
Scintilla documentation: http://www.scintilla.org/ScintillaDoc.html
Code: Select all
; Color values returned in the Dll callback
;
Enumeration
#SYNTAX_Text
#SYNTAX_Keyword
#SYNTAX_Comment
#SYNTAX_Constant
#SYNTAX_String
#SYNTAX_Function
#SYNTAX_Asm
#SYNTAX_Operator
#SYNTAX_Structure
#SYNTAX_Number
#SYNTAX_Pointer
#SYNTAX_Separator
#SYNTAX_Label
#SYNTAX_Module
EndEnumeration
; Define protype for the dll function
;
Prototype SyntaxHighlight(*Buffer, Length, *Callback, Asm)
Global SyntaxHighlight.SyntaxHighlight
; Callback for the syntax parser
;
Procedure ColorCallback(*Position, Length, Color)
ScintillaSendMessage(0, #SCI_SETSTYLING, Length, Color)
EndProcedure
; Callback for scintilla events
;
Procedure ScintillaCallback(Gadget, *scinotify.SCNotification)
Protected LastStyled, Range.TextRange
; This event indicates that new coloring is needed. The #SCI_GETENDSTYLED message and *scinotify\position indicate the range to color
If *scinotify\nmhdr\code = #SCN_STYLENEEDED
; calculate the range to color
; always start coloring at the line start
LastStyled = ScintillaSendMessage(Gadget, #SCI_GETENDSTYLED)
Range\chrg\cpMin = ScintillaSendMessage(Gadget, #SCI_POSITIONFROMLINE, ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, LastStyled))
Range\chrg\cpMax = *scinotify\position
Range\lpstrText = AllocateMemory(Range\chrg\cpMax - Range\chrg\cpMin + 1)
If Range\lpstrText
; retrieve the text range
ScintillaSendMessage(Gadget, #SCI_GETTEXTRANGE, 0, @Range)
; start coloring
ScintillaSendMessage(Gadget, #SCI_STARTSTYLING, Range\chrg\cpMin, $FF)
; call the parser function in the dll
; the callback above will apply the colors to the returned tokens
SyntaxHighlight(Range\lpstrText, Range\chrg\cpMax - Range\chrg\cpMin, @ColorCallback(), #False)
FreeMemory(Range\lpstrText)
EndIf
EndIf
EndProcedure
If InitScintilla() And OpenLibrary(0, #PB_Compiler_Home + "SDK\Syntax Highlighting\SyntaxHilighting.dll")
; get the syntax parser function
SyntaxHighlight = GetFunction(0, "SyntaxHighlight")
; create window and gadget
OpenWindow(0, 0, 0, 640, 480, "Tiny Editor", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
ScintillaGadget(0, 0, 0, 640, 480, @ScintillaCallback())
; Important: tell the gadget to send the #SCN_STYLENEEDED notification to the callback if coloring is needed
ScintillaSendMessage(0, #SCI_SETLEXER, #SCLEX_CONTAINER)
; Enable line numbers
ScintillaSendMessage(0, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
; Set common style info
Define *FontName = AllocateMemory(StringByteLength("Courier New", #PB_Ascii) + 1)
If *FontName
PokeS(*FontName, "Courier New", -1, #PB_Ascii)
ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, *FontName)
FreeMemory(*FontName)
EndIf
ScintillaSendMessage(0, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 12)
ScintillaSendMessage(0, #SCI_STYLESETBACK, #SCI_STYLESETFORE, 0)
ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_DEFAULT, $DFFFFF)
ScintillaSendMessage(0, #SCI_STYLECLEARALL)
; Set individual colors
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Text, 0)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Keyword, $666600)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Comment, $AAAA00)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Constant, $724B92)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_String, $FF8000)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Function, $666600)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Asm, $DFFFFF)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Operator, 0)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Structure, 0)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Number, 0)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Pointer, 0)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Separator, 0)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Label, 0)
ScintillaSendMessage(0, #SCI_STYLESETFORE, #SYNTAX_Module, 0)
ScintillaSendMessage(0, #SCI_STYLESETBOLD, #SYNTAX_Keyword, #True)
; Minimalistic event loop
Define Event
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_SizeWindow
ResizeGadget(0, 0, 0, WindowWidth(0), WindowHeight(0))
EndIf
Until Event = #PB_Event_CloseWindow
Else
MessageRequester("Error", "Cannot load scintilla or parser dll")
EndIf
quidquid Latine dictum sit altum videtur
-
- Enthusiast
- Posts: 176
- Joined: Sun Jun 28, 2009 7:07 pm
- Location: RUS
Re: Creating an IDE
Hi
Please show an example of how to highlight the syntax?
For example:
for, goto - green
next, add - red
I do not understand how to use this code.
Thank you!
Best regards.
Please show an example of how to highlight the syntax?
For example:
for, goto - green
next, add - red
I do not understand how to use this code.
Thank you!
Best regards.
Re: Creating an IDE
A piece of code without the sdk Syntax Highlightingregistrymechanic22 wrote:Please show an example of how to highlight the syntax?
For example: for, goto - green next, add - red
Code: Select all
EnableExplicit
Enumeration Highlight
#Style_KeyWord_Green
#Style_KeyWord_Red
#Style_NonKeyWord
EndEnumeration
Enumeration Form
#Mainform
EndEnumeration
Enumeration Gadget
#Editor
EndEnumeration
;-Déclaration variable et procédures
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget
;Your KeyWords
Global KeyWordGreen.s = "For|Goto"
Global KeyWordRed.s = "Next|Add"
Global KeyWordSep.s = "|"
;Summary
Declare Start()
Declare ScintillaCallBack(Gadget, *scinotify.SCNotification)
Declare ScintillaProperties(Gadget)
Declare KeyWord(Key.s)
Declare Highlight(Gadget.l, EndPos.l)
Declare ScintillaGetLineEndPosition(Gadget, Line)
Declare ScintillaLineFromPosition(gadget, Pos)
Declare MainFormClose()
Start()
Procedure Start()
OpenWindow(#MainForm, 0, 0, 1024, 768, "ScintillaGadget : Custom Highlight", WindowStyle)
If InitScintilla()
ScintillaGadget(#Editor, 10, 40, 1004, 668, @ScintillaCallBack())
ScintillaProperties(#Editor)
SetActiveGadget(#Editor)
EndIf
RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab) ;Tab key enable
BindEvent(#PB_Event_CloseWindow, @MainFormClose(), #MainForm)
Repeat : WaitWindowEvent(10) : ForEver
EndProcedure
;Scintilla Properties
Procedure ScintillaProperties(Gadget)
;Character between each word in the KeyWord list
ScintillaSendMessage(Gadget, #SCI_AUTOCSETSEPARATOR, Asc(KeyWordSep))
;Style KeyWord Green
ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_KeyWord_Green, RGB(50, 205, 50))
;Style KeyWord Red
ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_KeyWord_Red, RGB(255, 0, 0))
;Style NonKeyWord
ScintillaSendMessage(Gadget, #SCI_STYLESETFORE, #Style_NonKeyWord, RGB(0, 0, 0))
EndProcedure
;Scintilla CallBack
Procedure ScintillaCallBack(Gadget, *scinotify.SCNotification)
Select *scinotify\nmhdr\code
Case #SCN_STYLENEEDED
Highlight(Gadget, *scinotify\position)
EndSelect
EndProcedure
Procedure KeyWord(Key.s)
Protected n
If Key=""
ProcedureReturn -1
EndIf
;KeyWordGreen
For n=1 To CountString(KeyWordGreen, KeyWordSep) + 1
If LCase(StringField(KeyWordGreen, n, KeyWordSep)) = LCase(Key)
ProcedureReturn #Style_KeyWord_Green
EndIf
Next
;KeyWordRed
For n=1 To CountString(KeyWordRed, KeyWordSep) + 1
If LCase(StringField(KeyWordRed, n, KeyWordSep)) = LCase(Key)
ProcedureReturn #Style_KeyWord_Red
EndIf
Next
ProcedureReturn #Style_NonKeyWord
EndProcedure
Procedure Highlight(Gadget.l, EndPos.l)
Protected Char.i, KeyWord.s, StyleID.i
Protected CurrentPos.i = 0, EndLinePos.i
EndPos = ScintillaGetLineEndPosition(Gadget, ScintillaLineFromPosition(Gadget, EndPos))
ScintillaSendMessage(Gadget, #SCI_STARTSTYLING, CurrentPos, $1F | #INDICS_MASK)
While CurrentPos <= EndPos
Char = ScintillaSendMessage(Gadget, #SCI_GETCHARAT, CurrentPos)
Select Char
Case 'a' To 'z', 'A' To 'Z'
EndLinePos = ScintillaGetLineEndPosition(Gadget, ScintillaLineFromPosition(Gadget, CurrentPos))
KeyWord = Chr(Char)
While CurrentPos < EndLinePos
CurrentPos + 1
Char = ScintillaSendMessage(Gadget, #SCI_GETCHARAT, CurrentPos)
If Not ((Char >= 'a' And Char <= 'z') Or (Char >= 'A' And Char <= 'Z') Or Char = '_'Or (Char >= '0' And Char <= '9'))
CurrentPos-1
Break
EndIf
KeyWord + Chr(Char)
Wend
;-KeyWord or not KeyWord ?
Select KeyWord(KeyWord)
Case #Style_KeyWord_Green
StyleID = #Style_KeyWord_Green
Case #Style_KeyWord_Red
StyleID = #Style_KeyWord_Red
Default
StyleID = #Style_NonKeyWord
EndSelect
ScintillaSendMessage(Gadget, #SCI_SETSTYLING, Len(KeyWord), StyleID)
Default
ScintillaSendMessage(Gadget, #SCI_SETSTYLING, 1, #Style_NonKeyWord)
EndSelect
CurrentPos+1
Wend
EndProcedure
Procedure ScintillaGetLineEndPosition(Gadget, Line)
ProcedureReturn ScintillaSendMessage(Gadget, #SCI_GETLINEENDPOSITION, Line)
EndProcedure
Procedure ScintillaLineFromPosition(gadget, Pos)
ProcedureReturn ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, Pos)
EndProcedure
Procedure MainFormClose()
End
EndProcedure
➽ Windows 11 64-bit - PB 6.21 x64 - AMD Ryzen 7 - NVIDIA GeForce GTX 1650 Ti
Sorry for my bad english and the Dunning–Kruger effect
-
- Enthusiast
- Posts: 176
- Joined: Sun Jun 28, 2009 7:07 pm
- Location: RUS
Re: Creating an IDE
Wonderful and simple example!falsam wrote:....
Thank you so much!
Best regards.
Re: Creating an IDE
i agree thats a really nice example!
it also compiles to just 40kb x86 Windows exe - i didn't realise how lightweight Scintilla is!?!?

Re: Creating an IDE
You have to include the Scintilla DLL with your program, which adds ~400 kB.Keya wrote:it also compiles to just 40kb x86 Windows exe - i didn't realise how lightweight Scintilla is!?!?
(On Mac/Linux Scintilla is automatically included in your executable)
Re: Creating an IDE
ahh i see. I had a look at the .exe dependencies and couldnt see scintilla.dll linked, so i guess InitScintilla() loads it dynamically. 40kb standalone for a full-featured editor gadget probably was asking a bit much 
