Scintilla find/replace
- Crusiatus Black
- Enthusiast

- Posts: 389
- Joined: Mon May 12, 2008 1:25 pm
- Location: The Netherlands
- Contact:
Scintilla find/replace
Hey all,
Me again, asking for help and info once again.
I'm trying to find info regarding implementing find/replace features in Scintilla, but I can't find
any stuff that explains to me how I can implement this in PureBasic. I would like to code a
dialog similar to the one in the PureBasic IDE, coding the window is easy, but the step of
actually finding / selecting and replacing content in scintilla is unclear to me.
Does anyone have some pointers where precisely I should look, and perhaps some example
code?
Thanks!
Me again, asking for help and info once again.
I'm trying to find info regarding implementing find/replace features in Scintilla, but I can't find
any stuff that explains to me how I can implement this in PureBasic. I would like to code a
dialog similar to the one in the PureBasic IDE, coding the window is easy, but the step of
actually finding / selecting and replacing content in scintilla is unclear to me.
Does anyone have some pointers where precisely I should look, and perhaps some example
code?
Thanks!
Re: Scintilla find/replace
http://www.scintilla.org/
has everything you need. The Documentation page describes all of the commands, and the source code for the SciTe editor is also available there.
You might also consider checking out GoScintilla on this forum; SRod has done a great job of making a library that converts many lines into a short command.
Edit: there are two Search methods with Scintilla; one repositions the screen, and the other does not. Use the appropriate one for your task.
has everything you need. The Documentation page describes all of the commands, and the source code for the SciTe editor is also available there.
You might also consider checking out GoScintilla on this forum; SRod has done a great job of making a library that converts many lines into a short command.
Edit: there are two Search methods with Scintilla; one repositions the screen, and the other does not. Use the appropriate one for your task.
Re: Scintilla find/replace
Minimalist code include 2 procedures.Crusiatus Black wrote:Does anyone have some pointers where precisely I should look, and perhaps some examplecode? Thanks!
ScintillaStringFind(StringFind.s) and ScintillaStringReplace(StringFind.s, StringReplace.s)
Short Key
Ctrl + F : Open Search Replace Dialog
F3 : When Open Search Replace Dialog is close, to continue the search.
Code: Select all
; Scintilla : Search Replace Exemple
EnableExplicit
Enumeration
#Mainform
#Editor
#StringFindForm
#StringFind
#StringFindCheck
#StringReplace
#Btn_StringFindNext
#Btn_StringFindReplace
#Btn_StringFindEnd
#Kbd_CtrlF ;Shortcut Find / replace
#Kbd_F3 ;Shortcut Next string
#Kbd_Return
EndEnumeration
Define.l Event, WEvent, MEvent, GEvent, TEvent
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered
;Find replace
Global StringFind.s, StringReplace.s
;Indentation
Global SciPos.l, SciLine.l, SciCol.l, SciIndent.l
; Find String
Procedure ScintillaStringFind(StringFind.s)
Protected Current.l, start.l, Anchor.l
If StringFind <> ""
Current = ScintillaSendMessage(#Editor, #SCI_GETCURRENTPOS)
ScintillaSendMessage(#Editor, #SCI_SETANCHOR, Current)
ScintillaSendMessage(#Editor, #SCI_SEARCHANCHOR)
Start = ScintillaSendMessage(#Editor, #SCI_SEARCHNEXT, 0, @StringFind)
If Start<> -1
anchor = ScintillaSendMessage(#Editor, #SCI_GETANCHOR)
ScintillaSendMessage(#Editor, #SCI_SETSEL, start, anchor)
Else
MessageRequester("Find string", "No more matching")
EndIf
EndIf
EndProcedure
; Find Replace string
Procedure ScintillaStringReplace(StringFind.s, StringReplace.s)
Protected StringSel.s
;Storing the selected word
ScintillaSendMessage(#Editor, #SCI_COPY)
StringSel=GetClipboardText()
If LCase(StringSel)=LCase(StringFind)
SetClipboardText(StringReplace)
ScintillaSendMessage(#Editor, #SCI_PASTE)
;Find the next occurrence
ScintillaStringFind(StringFind)
EndIf
EndProcedure
; Show find/replace string dialog
Procedure Open_StringFindForm()
If OpenWindow(#StringFindForm,0,0,455,195,"Find/Replace",#PB_Window_Tool|#PB_Window_WindowCentered,WindowID(#Mainform))
TextGadget(#PB_Any,30,21,85,20,"Find")
ComboBoxGadget(#StringFind,130,18,310,23,#PB_ComboBox_Editable)
CheckBoxGadget(#StringFindCheck,15,60,105,20,"Replace by")
ComboBoxGadget(#StringReplace,130,59,310,23,#PB_ComboBox_Editable)
ButtonGadget(#Btn_StringFindNext,20,150,125,20,"Next String")
ButtonGadget(#Btn_StringFindReplace,160,150,80,20,"Find (Replace)")
ButtonGadget(#Btn_StringFindEnd,360,150,80,20,"Close")
DisableGadget(#StringReplace, #True)
DisableGadget(#Btn_StringFindReplace, #True)
SetActiveGadget(#StringFind)
AddKeyboardShortcut(#StringFindForm, #PB_Shortcut_Return, #Kbd_Return) ;Find String
EndIf
EndProcedure
; Scintilla Callback
;
; CallBack To receive the events of Scintilla gadget
; scinotify * pointer to a structure containing the information on the event:
; See the bottom of this page http://www.scintilla.org/ScintillaDoc.html
;
; -Knowing the current cursor position and correctly position
; after having press the Enter key
Procedure ScintillaCallBack(Gadget, *scinotify.SCNotification)
; Enter key is used
If *scinotify\ch=13
;New line: Cursor on the indentation of the previous line.
ScintillaSendMessage(Gadget, #SCI_SETLINEINDENTATION, SciLIne+1, SciIndent)
If SciIndent=0
SciPos=SciPos+2
EndIf
ScintillaSendMessage(Gadget, #SCI_GOTOPOS, SciPos+SciIndent)
EndIf
;Position in the chain scintilla
SciPos = ScintillaSendMessage(Gadget, #SCI_GETANCHOR)
;Line from position
SciLine = ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, SciPos)
;Column from position
SciCol = ScintillaSendMessage(Gadget, #SCI_GETCOLUMN, SciPos)
;Determination de l'indentation
SciIndent = ScintillaSendMessage(Gadget, #SCI_GETLINEINDENTATION, SciLine)
EndProcedure
;Init scintilla properties (minimalist)
Procedure ScintillaSetProperties(Gadget)
ScintillaSendMessage(Gadget, #SCI_SETLEXER, 0); No lexer
ScintillaSendMessage(Gadget, #SCI_STYLESETFONT, #STYLE_DEFAULT,@"Arial") ;Police
ScintillaSendMessage(Gadget, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 12) ;Size
ScintillaSendMessage(Gadget, #SCI_STYLECLEARALL)
ScintillaSendMessage(Gadget, #SCI_SETCARETLINEBACK, RGB(245, 245, 220));Line Active BackColor
ScintillaSendMessage(Gadget, #SCI_SETCARETLINEVISIBLE, #True) ;Cursor Yes
ScintillaSendMessage(gadget, #SCI_SETCARETWIDTH, 3) ;Cursor Size
ScintillaSendMessage(Gadget, #SCI_SETUSETABS, #False) ;User tabs replace by space
ScintillaSendMessage(Gadget, #SCI_SETINDENT, 8) ; Number spaces
EndProcedure
;Mainform
Procedure Open_MainForm()
OpenWindow(#Mainform, 0, 0, 800, 600, "New Form", WindowStyle)
ScintillaGadget(#Editor, 10, 10, 780, 580, @ScintillaCallBack())
ScintillaSetProperties(#Editor)
;Init Shortcut
RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab)
AddKeyboardShortcut(#Mainform, #PB_Shortcut_F|#PB_Shortcut_Control, #Kbd_CtrlF)
AddKeyboardShortcut(#Mainform, #PB_Shortcut_F3, #Kbd_F3)
SetActiveGadget(#Editor)
EndProcedure
Procedure Start()
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
InitScintilla()
CompilerEndIf
Open_MainForm()
EndProcedure
start()
Repeat
Event = WaitWindowEvent(10)
WEvent = EventWindow()
MEvent = EventMenu()
GEvent = EventGadget()
TEvent = EventType()
Select Event
Case #PB_Event_Menu
Select MEvent
Case #Kbd_CtrlF
Open_StringFindForm()
Case #Kbd_F3
ScintillaStringFind(StringFind)
Case #Kbd_Return
Select WEvent
Case #StringFindForm
ScintillaStringFind(StringFind)
EndSelect
EndSelect
Case #PB_Event_Gadget
Select GEvent
Case #StringFindCheck
If GetGadgetState(#StringFindCheck)=#PB_Checkbox_Checked
DisableGadget(#StringReplace, #False)
DisableGadget(#Btn_StringFindReplace, #False)
Else
DisableGadget(#StringReplace, #True)
DisableGadget(#Btn_StringFindReplace, #True)
EndIf
Case #StringFind
StringFind=GetGadgetText(#StringFind)
Case #StringReplace
StringReplace=GetGadgetText(#StringReplace)
Case #Btn_StringFindEnd
CloseWindow(#StringFindForm)
Case #Btn_StringFindNext
ScintillaStringFind(GetGadgetText(#StringFind))
Case #Btn_StringFindReplace
ScintillaStringReplace(StringFind, StringReplace)
EndSelect
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Last edited by falsam on Mon Sep 24, 2012 9:19 am, edited 3 times in total.
➽ 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
Re: Scintilla find/replace
I get an IMA error...
Probably something conflicting -- but it's frustrating... Thanks for the demo -- I keep meaning to implement scintilla in a project, but never seem to get around to it...
Code: Select all
;Scintilla Callback
Procedure ScintillaCallBack()
EndProcedure ; << [ERROR] Invalid memory access. (write error at address 0)- Crusiatus Black
- Enthusiast

- Posts: 389
- Joined: Mon May 12, 2008 1:25 pm
- Location: The Netherlands
- Contact:
Re: Scintilla find/replace
Works perfectly for me, it's a nice start that shows me how I can do this.
Thank you very much for the example!
Jassing, the code as provided causes the exception? At the EndProcedure keyword?
Have you tried restarting the compiler and re-executing the code?
Thank you very much for the example!
Jassing, the code as provided causes the exception? At the EndProcedure keyword?
Have you tried restarting the compiler and re-executing the code?
Re: Scintilla find/replace
I get the same error.jassing wrote:I get an IMA error...
Code: Select all
;Scintilla Callback Procedure ScintillaCallBack() EndProcedure ; << [ERROR] Invalid memory access. (write error at address 0)
- Crusiatus Black
- Enthusiast

- Posts: 389
- Joined: Mon May 12, 2008 1:25 pm
- Location: The Netherlands
- Contact:
Re: Scintilla find/replace
PureBasic version, OS version and x86/x64?
I would like to reproduce that error.
Re: Scintilla find/replace
Help says the callback has 2 params:
Code: Select all
ProcedureDLL ScintillaCallBack(Gadget, *scinotify.SCNotification)
;
; The ProcedureDLL declaration is important for the callback to work correctly on MacOSX,
; on all other OS it has no effect.
;
EndProcedureRe: Scintilla find/replace
Win XP x86Crusiatus Black wrote:PureBasic version, OS version and x86/x64?I would like to reproduce that error.
Re: Scintilla find/replace
@falsam: I got your example working after making the parameter change suggested by Danillo. It is a great example.
The replace function has one quirk though. It works fine unless there is no text selected before the first replacement is attempted.
To reproduce it:
The replace function has one quirk though. It works fine unless there is no text selected before the first replacement is attempted.
To reproduce it:
- type three lines
* Click somewhere in the first line without creating a selection
* Call up the find dialog (it can also be called up before this)
* Enter a 'find' word for something in the second or third line of the document
* Enter a 'replace by' word
* Click 'Find (Replace)'.
Re: Scintilla find/replace
Sorry for this huge mistake in the callback. I've updated the code.
➽ 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
Re: Scintilla find/replace
Update the code :
I added a bonus: Calculation of the indentation for the next line.
I added a bonus: Calculation of the indentation for the next line.
➽ 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
- Crusiatus Black
- Enthusiast

- Posts: 389
- Joined: Mon May 12, 2008 1:25 pm
- Location: The Netherlands
- Contact:
Re: Scintilla find/replace
Thanks! 
Re: Scintilla find/replace
Code: Select all
Procedure ScintillaStringFind(StringFind.s)
Protected Current.l, start.l, Anchor.l
If StringFind <> ""
Current = ScintillaSendMessage(#Editor, #SCI_GETCURRENTPOS)
ScintillaSendMessage(#Editor, #SCI_SETANCHOR, Current)
ScintillaSendMessage(#Editor, #SCI_SEARCHANCHOR)
Start = ScintillaSendMessage(#Editor, #SCI_SEARCHNEXT, 0, @StringFind)
If Start<> -1
anchor = ScintillaSendMessage(#Editor, #SCI_GETANCHOR)
ScintillaSendMessage(#Editor, #SCI_SETSEL, start, anchor)
Else
MessageRequester("Find string", "No more matching")
EndIf
EndIf
EndProcedure
example: the word "repeated" in french "répété"
ps : excellent Falsam
dommage ça ne marche plus avec les Accents ...
Last edited by dobro on Fri Aug 23, 2013 12:55 am, edited 1 time in total.
Re: Scintilla find/replace
That is due to the lack of a UTF8 conversion...see SRod's GoScintilla for a sample.dobro wrote:does not work, if the search term contains an emphasis
example: the word "repeated" in french "répété"


