Show all occurrences of a word in the IDE

Working on new editor enhancements?
Mesa
Enthusiast
Enthusiast
Posts: 345
Joined: Fri Feb 24, 2012 10:19 am

Show all occurrences of a word in the IDE

Post by Mesa »

On this German thread https://www.purebasic.fr/german/viewtopic.php?t=28292, we can add this very practical option using a keyboard shortcut.

However, it doesn't show constants so I added a little snippet of code that does this.

Code: Select all

;   Description: Find all references of a variable
;            OS: Windows
; English-Forum: 
;  French-Forum: 
;  German-Forum: http://www.purebasic.fr/german/viewtopic.php?f=8&t=28292
;-----------------------------------------------------------------------------

; MIT License
; 
; Copyright (c) 2015 Kiffi
; 
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
; 
; The above copyright notice and this permission notice shall be included in all
; copies or substantial portions of the Software.
; 
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
; SOFTWARE.

; FindAllReferences



CompilerIf #PB_Compiler_OS<>#PB_OS_Windows
	CompilerError "Windows Only!"
CompilerEndIf

EnableExplicit

Enumeration ; Windows
	#frmMain
EndEnumeration
Enumeration ; Gadgets
	#frmMain_References
EndEnumeration
Enumeration ; Menu-/Toolbaritems
	#frmMain_Shortcut_Escape_Event
EndEnumeration

Global PbIdeHandle = Val(GetEnvironmentVariable("PB_TOOL_MainWindow"))
If PbIdeHandle = 0 : End : EndIf

Global ScintillaHandle = Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
If ScintillaHandle = 0 : End : EndIf

Procedure.s RemoveLeadingWhitespaceFromString(InString.s)
	
	While Left(InString, 1) = Chr(32) Or Left(InString, 1) = Chr(9)
		InString = LTrim(InString, Chr(32))
		InString = LTrim(InString, Chr(9))
	Wend
	
	ProcedureReturn InString
	
EndProcedure

Procedure.s GetScintillaText()
	
	Protected ReturnValue.s
	
	Protected length
	Protected buffer
	Protected processId
	Protected hProcess
	Protected result
	
	length = SendMessage_(ScintillaHandle, #SCI_GETLENGTH, 0, 0)
	If length
		length + 2
		buffer = AllocateMemory(length)
		If buffer   
			SendMessageTimeout_(ScintillaHandle, #SCI_GETCHARACTERPOINTER, 0, 0, #SMTO_ABORTIFHUNG, 2000, @result)
			If result
				GetWindowThreadProcessId_(ScintillaHandle, @processId)
				hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, processId)
				If hProcess
					ReadProcessMemory_(hProcess, result, buffer, length, 0)   
					ReturnValue = PeekS(buffer, -1, #PB_UTF8)
				EndIf
			EndIf
		EndIf
		FreeMemory(buffer)
	EndIf
	
	ProcedureReturn ReturnValue
	
EndProcedure

Procedure frmMain_SizeWindow_Event()
	ResizeGadget(#frmMain_References, #PB_Ignore, #PB_Ignore, WindowWidth(#frmMain) - 20, WindowHeight(#frmMain) - 20)
EndProcedure

Procedure frmMain_References_Event()
	
	Protected SelectedLine
	
	SelectedLine = Val(GetGadgetItemText(#frmMain_References, GetGadgetState(#frmMain_References), 0))
	
	If SelectedLine > 0
		SendMessage_(ScintillaHandle, #SCI_GOTOLINE, SelectedLine - 1, 0)
		SendMessage_(ScintillaHandle, #SCI_ENSUREVISIBLE, SelectedLine - 1, 0)
		SetForegroundWindow_(PbIdeHandle)
		SetActiveWindow_(PbIdeHandle)
	EndIf
	
EndProcedure

Define SelectedWord.s = GetEnvironmentVariable("PB_TOOL_Word")
If SelectedWord = "" : End : EndIf

Define ScintillaText.s = GetScintillaText()
If ScintillaText = "" : End : EndIf

Define Line.s
Define CountLines, LineCounter
Define CountTokens, TokenCounter
Define WWE
Define RegexLines, PbRegexTokens

Structure sFoundReference
	LineNo.i
	Reference.s
	
EndStructure

NewList FoundReference.sFoundReference()

Dim Tokens.s(0)


;http://www.purebasic.fr/english/viewtopic.php?f=12&t=37823
RegexLines = CreateRegularExpression(#PB_Any , ".*\r\n")
PbRegexTokens = CreateRegularExpression(#PB_Any, #DOUBLEQUOTE$ + "[^" + #DOUBLEQUOTE$ + "]*" + #DOUBLEQUOTE$ + "|[\*]?[a-zA-Z_]+[\w]*[\x24]?|#[a-zA-Z_]+[\w]*[\x24]?|[\[\]\(\)\{\}]|[-+]?[0-9]*\.?[0-9]+|;.*|\.|\+|-|[&@!\\\/\*,\|]|::|:|\|<>|>>|<<|=>{1}|>={1}|<={1}|=<{1}|={1}|<{1}|>{1}|\x24+[0-9a-fA-F]+|\%[0-1]*|%|'")

CountLines = CountString(ScintillaText, #CRLF$)

Dim Lines.s(0)

CountLines = ExtractRegularExpression(RegexLines, ScintillaText, Lines())

SelectedWord = LCase(SelectedWord)

For LineCounter = 0 To CountLines - 1
	
	Line = Lines(LineCounter)   
	
	CountTokens = ExtractRegularExpression(PbRegexTokens, Line, Tokens())
	
	For TokenCounter = 0 To CountTokens - 1   
		If SelectedWord = LCase(Tokens(TokenCounter))
			AddElement(FoundReference())
			FoundReference()\LineNo = LineCounter + 1
			Line = Trim(Line)
			Line = Mid(Line, 1, Len(Line)-2)
			FoundReference()\Reference = Line
		EndIf
		
	Next
	
Next

If ListSize(FoundReference()) = 0
	
	SelectedWord = "#" + SelectedWord
	
	For LineCounter = 0 To CountLines - 1
		
		Line = Lines(LineCounter)   
		
		CountTokens = ExtractRegularExpression(PbRegexTokens, Line, Tokens())
		
		For TokenCounter = 0 To CountTokens - 1   
			If SelectedWord = LCase(Tokens(TokenCounter))
				AddElement(FoundReference())
				FoundReference()\LineNo = LineCounter + 1
				Line = Trim(Line)
				Line = Mid(Line, 1, Len(Line)-2)
				FoundReference()\Reference = Line
			EndIf
			
		Next
		
	Next	
	
	If ListSize(FoundReference()) = 0 : End : EndIf
EndIf

OpenWindow(#frmMain,
           #PB_Ignore,
           #PB_Ignore,
           600,
           300,
           "Display all: '" + SelectedWord + "'",
           #PB_Window_SystemMenu |
           #PB_Window_SizeGadget |
           #PB_Window_ScreenCentered)

StickyWindow(#frmMain, #True)

ListIconGadget(#frmMain_References,
               10,
               10,
               WindowWidth(#frmMain) - 20,
               WindowHeight(#frmMain) - 20,
               "Line",
               50,
               #PB_ListIcon_FullRowSelect |   
               #PB_ListIcon_GridLines |
               #PB_ListIcon_AlwaysShowSelection)

AddGadgetColumn(#frmMain_References, 1, "Ref", 400)


ForEach FoundReference()
	AddGadgetItem(#frmMain_References, -1, Str(FoundReference()\LineNo) + #LF$ + FoundReference()\Reference)   
Next

Define i

SendMessage_(GadgetID(#frmMain_References), #LVM_SETCOLUMNWIDTH, 0, #LVSCW_AUTOSIZE_USEHEADER)
SendMessage_(GadgetID(#frmMain_References), #LVM_SETCOLUMNWIDTH, 1, #LVSCW_AUTOSIZE)
SendMessage_(GadgetID(#frmMain_References), #LVM_SETCOLUMNWIDTH, 2, #LVSCW_AUTOSIZE)

AddKeyboardShortcut(#frmMain, #PB_Shortcut_Escape, #frmMain_Shortcut_Escape_Event)
BindEvent(#PB_Event_SizeWindow, @frmMain_SizeWindow_Event(), #frmMain)
BindGadgetEvent(#frmMain_References, @frmMain_References_Event())
SetActiveGadget(#frmMain_References)


Repeat
	
	WWE = WaitWindowEvent()
	
	If (WWE = #PB_Event_Menu And EventMenu() = #frmMain_Shortcut_Escape_Event) Or (WWE = #PB_Event_CloseWindow)
		Break
	EndIf
	
ForEver
My final version with the use of a scintilla gadget and your own PB settings
[Edit] fix title window.
Image

Code: Select all

EnableExplicit

;=============================================================
; ----------------------------------------------------------------------------
; File : FindAllReferences[Win].pb
; ----------------------------------------------------------------------------
;
;   Description: Find all references of a variable
;            OS: Windows
; English-Forum:
;  French-Forum:
;  German-Forum: http://www.purebasic.fr/german/viewtopic.php?f=8&t=28292
; ----------------------------------------------------------------------------

; MIT License
;
; Copyright (c) 2015 Kiffi
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in all
; copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
; SOFTWARE.
;
; ----------------------------------------------------------------------------
; Change Log :
;   2023-02-12 : New Additions from Mesa, AZJIO, Axolotl, Dadlick, ChrisR, Allen
;		2023-03-08 : New scintilla version by Mesa
;
; English-Forum: https://www.purebasic.fr/english/viewtopic.php?t=80739
;
; History
;   - Mesa added search for constants and renewed interest in the tool
;   - AZJIO embedded highlight using ColorListIconGadget.pb by srod
;   - Axolotl qualitatively rewrote the functionality, making many changes
;   - Axolotl added the ability to test without compiling
;   - AZJIO added regular expressions
;   - ChrisR added a black theme
;   - Dadlick started his own tool fork
;   - AZJIO added a jump test to a string without compiling
;   - AZJIO added a black theme for Header and button
;   - Mesa created a scintilla version
;
; ----------------------------------------------------------------------------

; FindAllReferences

CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
	CompilerError "Windows Only!"
CompilerEndIf

EnableExplicit

;- Enumeration

Enumeration Windows
	#Mainform
EndEnumeration

Enumeration Gadgets
	#cmbRex
	#btnRex
	#Scintilla
EndEnumeration

Enumeration  Menus
	#Mainform_Shortcut_Escape_Event
	#Shortcut_Ctrl_Shift_C
	#Shortcut_Enter
EndEnumeration

Enumeration Scintilla_Syntax
	#Scintilla_Text
	#Scintilla_Keyword
	#Scintilla_Comment
	#Scintilla_Constant
	#Scintilla_String
	#Scintilla_Function
	#Scintilla_Asm
	#Scintilla_Operator
	#Scintilla_Structure
	#Scintilla_Number
	#Scintilla_Pointer
	#Scintilla_Separator
	#Scintilla_Label
	#Scintilla_Module
	
	#Scintilla_MyLexer
EndEnumeration

Enumeration File
	#Scintilla_Highlight_DLL
EndEnumeration


;- Structure

Structure sFoundReference
	LineNo.i
	Reference.s
	Selregexp.s
EndStructure

Structure xywhm
	;ini file
	x.i
	y.i
	w.i
	h.i
	m.i
EndStructure


;- Global
Global ini$ = LSet(ProgramFilename(), Len(ProgramFilename()) - 3) + "ini"
Global centered
Global xywh.xywhm
Global xywh2.xywhm
Global xywh\w = 600
Global xywh\h = 300
Global CursorLine
Global flgRead
Global YouAreHere.s

Global PbIdeHandle, ScintillaHandle

Global SelectedWord.s, PB_ScintillaText.s
Global CountSelectedWords
Global NewList FoundReference.sFoundReference()
Global Dim Lines.s(0)

Global BackColor = $B4DDE8
Global ForeColor = $151515
Global BackColorHeader = $C4CDC8
; Global ForeColorHeader = $151515
Global BorderColor = $888888
Global HightLightBrush = CreateSolidBrush_(GetSysColor_(#COLOR_HIGHLIGHT))
Global BackColorBrush = CreateSolidBrush_(BackColor)
Global BackColorBrushHeader = CreateSolidBrush_(BackColorHeader)

; ---------------------------------------------------------------------------------------------------------------------

; ---== Procedures ==--------------------------------------------------------------------------------------------------

;- Procedure
; AZJIO
Procedure.s LTrimChar(String$, TrimChar$ = #CRLF$ + #TAB$ + #FF$ + #VT$ + " ")
	
	Protected *memChar, *c.Character, *jc.Character
	
	If Not Asc(String$)
		ProcedureReturn ""
	EndIf
	
	*c.Character = @String$
	*memChar = @TrimChar$
	
	While *c\c
		*jc.Character = *memChar
		
		While *jc\c
			If *c\c = *jc\c
				*c\c = 0
				Break
			EndIf
			*jc + SizeOf(Character)
		Wend
		
		If *c\c
			String$ = PeekS(*c)
			Break
		EndIf
		*c + SizeOf(Character)
	Wend
	
	ProcedureReturn String$
	
EndProcedure

Procedure.s RemoveLeadingWhitespaceFromString(InString.s)
	
	While Left(InString, 1) = Chr(32) Or Left(InString, 1) = Chr(9)
		InString = LTrim(InString, Chr(32))
		InString = LTrim(InString, Chr(9))
	Wend
	
	ProcedureReturn InString
	
EndProcedure


Procedure.s Get_PB_ScintillaText()
	Protected ReturnValue.s
	Protected length
	Protected buffer
	Protected processId
	Protected hProcess
	Protected result
	
	length = SendMessage_(ScintillaHandle, #SCI_GETLENGTH, 0, 0)
	If length
		length + 2
		buffer = AllocateMemory(length)
		If buffer
			SendMessageTimeout_(ScintillaHandle, #SCI_GETCHARACTERPOINTER, 0, 0, #SMTO_ABORTIFHUNG, 2000, @result)
			If result
				GetWindowThreadProcessId_(ScintillaHandle, @processId)
				hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, processId)
				If hProcess
					ReadProcessMemory_(hProcess, result, buffer, length, 0)
					ReturnValue = PeekS(buffer, -1, #PB_UTF8)
					CloseHandle_(hProcess)  ; <-- Axolotl, added acc. to MSDN
				EndIf
			EndIf
		EndIf
		FreeMemory(buffer)
	EndIf
	ProcedureReturn ReturnValue
EndProcedure

; ---------------------------------------------------------------------------------------------------------------------

; For test only
Global classText.s = Space(256)
; Finding a PureBasic Window
Procedure.l EnumChildren0(hwnd.l)
	If hwnd
		GetClassName_(hwnd, @classText, 256)
		If classText = "WindowClass_2"
			GetWindowText_(hwnd, @classText, 256)
			If Left(classText, 9) = "PureBasic"
				PbIdeHandle = hwnd
				ProcedureReturn 0
			EndIf
		EndIf
		ProcedureReturn 1
	EndIf
	ProcedureReturn 0
EndProcedure

; Finding the PB Scintilla
Procedure.l EnumChildren1(hwnd.l)
	If hwnd
		GetClassName_(hwnd, @classText, 256)
		If classText = "Scintilla"
			ScintillaHandle = hwnd
			ProcedureReturn 0
		EndIf
		ProcedureReturn 1
	EndIf
	ProcedureReturn 0
EndProcedure

Procedure Initialization()
	
	PbIdeHandle = Val(GetEnvironmentVariable("PB_TOOL_MainWindow"))
	CompilerIf Not #PB_Compiler_Debugger
		If PbIdeHandle = 0 : End : EndIf
	CompilerEndIf
	
	ScintillaHandle = Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
	CompilerIf Not #PB_Compiler_Debugger
		If ScintillaHandle = 0 : End : EndIf
	CompilerEndIf
	
	
	; For test only
	CompilerIf #PB_Compiler_Debugger
		EnumChildWindows_(0, @enumChildren0(), 0)
		EnumChildWindows_(PbIdeHandle, @enumChildren1(), 0)
	CompilerEndIf
	; End: For test only
	
	
	SelectedWord.s = GetEnvironmentVariable("PB_TOOL_Word")
	CompilerIf Not #PB_Compiler_Debugger
		If SelectedWord = "" : End : EndIf
	CompilerEndIf
	
	PB_ScintillaText.s = Get_PB_ScintillaText()
	CompilerIf Not #PB_Compiler_Debugger
		If PB_ScintillaText = "" : End : EndIf
	CompilerEndIf
	
	CursorLine = Int(Val(StringField(GetEnvironmentVariable("PB_TOOL_Cursor"), 1, "x")))
	
	
	; For test only
	CompilerIf #PB_Compiler_Debugger
		
		If SelectedWord = ""
			;     SelectedWord = "Line"    ; try one of these
			;     SelectedWord = "#Line"   ; -"-  #Line could be in a comment also
			SelectedWord = "PB_ScintillaText"   ; -"-
		EndIf
		
		If PB_ScintillaText = ""
			#File = 0
			If ReadFile(#File, #PB_Compiler_File)
				PB_ScintillaText = ReadString(#File, #PB_UTF8 | #PB_File_IgnoreEOL)
				CloseFile(#File)
			EndIf
			; 			RunProgram("explorer.exe", "/Select," + #PB_Compiler_File, "")
			
			; 			PB_ScintillaText = "" + #CRLF$ +
			; 			                "#Line = #LF ;  #Line could be in a comment also " + #CRLF$ +
			; 			                "Procedure Test(*Line)  ; pointer *Line " + #CRLF$ +
			; 			                "" + #CRLF$ +
			; 			                "If SelectedWord = LCase(Tokens(TokenCounter))" + #CRLF$ +
			; 			                "	 AddElement(FoundReference())" + #CRLF$ +
			; 			                "	 FoundReference()\LineNo = LineCounter + 1" + #CRLF$ +
			; 			                "	 Line = Trim(Line)" + #CRLF$ +
			; 			                "	 Line = Mid(Line, 1, Len(Line)-2)" + #CRLF$ +
			; 			                "	 FoundReference()\Reference = Line" + #CRLF$ +
			; 			                "EndIf" + #CRLF$ +
			; 			                "" ; End of Text
		EndIf
	CompilerEndIf
	; End: For test only
	
	ProcedureReturn 0  ; default (ZERO is returned by default, even if there is no ProcedureReturn)
EndProcedure

; ---------------------------------------------------------------------------------------------------------------------

; ChrisR
Procedure CopyClipboard()
	
	Protected text$,Title$
	
	PushListPosition(FoundReference())
	ForEach FoundReference()
		If text$ : text$ + #CRLF$ : EndIf
		If Right(FoundReference()\Reference, 2) = #CRLF$
			text$ + Left(FoundReference()\Reference, Len(FoundReference()\Reference) - 2)
		Else
			text$ + FoundReference()\Reference
		EndIf
	Next
	PopListPosition(FoundReference())
	If text$
		SetClipboardText(text$)
		Title$ = GetWindowTitle(#Mainform)
		SetWindowTitle(#Mainform, " >>> (References copied to the clipboard) <<<")
		Delay(500)
		SetWindowTitle(#Mainform, Title$)
	EndIf
EndProcedure

;highlighting via indicator 
Procedure ScintillaIndicColor(*regex, regexLength, n, p=6)
	
	Protected txtLen, StartPos, EndPos, firstMatchPos
	
	; Sets search mode (REGEX + POSIX braces)
	ScintillaSendMessage(#Scintilla, #SCI_SETSEARCHFLAGS, #SCFIND_REGEXP | #SCFIND_POSIX)
	
	; Sets target search range
	txtLen = ScintillaSendMessage(#Scintilla, #SCI_GETTEXTLENGTH) ; gets the text length
	ScintillaSendMessage(#Scintilla, #SCI_INDICSETSTYLE, n, p)		; #INDIC_TEXTFORE = 17 creates an indicator with number 7 (occupied by default 0, 1, 2)
	ScintillaSendMessage(#Scintilla, #SCI_INDICSETFORE, n, $3A3AE7) ; assign colour of indicator number 7 - green
	
	EndPos = 0
	Repeat
		ScintillaSendMessage(#Scintilla, #SCI_SETTARGETSTART, EndPos) ; from the beginning (set the search area) using the position of the previous search end
		ScintillaSendMessage(#Scintilla, #SCI_SETTARGETEND, txtLen)		; to the end by the text length
		firstMatchPos=ScintillaSendMessage(#Scintilla, #SCI_SEARCHINTARGET, regexLength, *regex) ; returns the position of the first found. The parameters are length and pointer
		If firstMatchPos>-1																																			 ; if greater than -1, that is found
			StartPos=ScintillaSendMessage(#Scintilla, #SCI_GETTARGETSTART)												 ; it gets position of the first found
			EndPos=ScintillaSendMessage(#Scintilla, #SCI_GETTARGETEND)														 ; gets position of the end of found
			ScintillaSendMessage(#Scintilla, #SCI_SETINDICATORCURRENT, n)													 ; makes the indicator number 7 current
			ScintillaSendMessage(#Scintilla, #SCI_INDICATORFILLRANGE, StartPos, EndPos - StartPos) ; it selects text using the current indicator
		Else
			Break
		EndIf
	ForEver
EndProcedure

;highlighting via style
Procedure ScintillaIndicColor2(*regex, regexLength, n=0)
	Protected txtLen, StartPos, EndPos, firstMatchPos
	
	; Sets search mode (REGEX + POSIX curly brackets)
	ScintillaSendMessage(#Scintilla, #SCI_SETSEARCHFLAGS, #SCFIND_REGEXP | #SCFIND_POSIX)
	
	; Sets target search range
	txtLen = ScintillaSendMessage(#Scintilla, #SCI_GETTEXTLENGTH) ; gets the text length
	
	EndPos = 0
	Repeat
		ScintillaSendMessage(#Scintilla, #SCI_SETTARGETSTART, EndPos) ; from the beginning (set the search area) using the position of the previous search end
		ScintillaSendMessage(#Scintilla, #SCI_SETTARGETEND, txtLen)		; to the end by the text length
		firstMatchPos=ScintillaSendMessage(#Scintilla, #SCI_SEARCHINTARGET, regexLength, *regex) ; returns the position of the first found. The parameters are length and pointer
		If firstMatchPos>-1																																			 ; if greater than -1, that is found
			StartPos=ScintillaSendMessage(#Scintilla, #SCI_GETTARGETSTART)												 ; it gets position of the first found
			EndPos=ScintillaSendMessage(#Scintilla, #SCI_GETTARGETEND)														 ; gets position of the end of found
			ScintillaSendMessage(#Scintilla, #SCI_STARTSTYLING, StartPos, 0)											 ; the start position (from the 50th)
			ScintillaSendMessage(#Scintilla, #SCI_SETSTYLING, EndPos - StartPos, #Scintilla_MyLexer)				 ; width and style number
		Else
			Break
		EndIf
	ForEver
EndProcedure

Procedure.s  GetScintillaCurLineText(ScintillaID, NextGadgetID=-1)
	Protected numUtf8Bytes, bufferPtr,  caretPos
	
	Protected *utf8Buffer
	
	numUtf8Bytes = ScintillaSendMessage(ScintillaID,#SCI_GETCURLINE, 0, 0);includes the null
	
	If numUtf8Bytes
		bufferPtr = AllocateMemory(numUtf8Bytes)
		If bufferPtr
			
			*utf8Buffer = bufferPtr
			caretPos = ScintillaSendMessage(ScintillaID, #SCI_GETCURLINE, numUtf8Bytes, *utf8Buffer)
		EndIf
	EndIf
	
	;Trick to get the scintilla gadget clickable again
	SetActiveGadget(NextGadgetID)
	
	ProcedureReturn PeekS(*utf8Buffer,numUtf8Bytes,#PB_UTF8)
	
EndProcedure

;Dadlick
Procedure.s FindProcedureName(CursorLine)
	
	Protected LineCounter,  Line.s
	
	For LineCounter = CursorLine - 1 To 1 Step - 1   
		Line = RemoveLeadingWhitespaceFromString(StringField(PB_ScintillaText, LineCounter, #CRLF$))
		
		If Left(LCase(Line), Len("endprocedure")) = "endprocedure"
			Break
		EndIf
		
		If Left(LCase(Line), Len("endmacro")) = "endmacro"
			Break
		EndIf
		
		If Left(LCase(Line), Len("procedure")) = "procedure"
			If Left(LCase(Line), Len("procedurereturn")) <> "procedurereturn"
				ProcedureReturn    Line
				Break
			EndIf
		EndIf 
		
		If Left(LCase(Line), Len("macro")) = "macro"
			If Left(LCase(Line), Len("endmacro")) <> "endmacro"
				ProcedureReturn    Line
				Break
			EndIf
		EndIf 

	Next LineCounter
	
	ProcedureReturn ""
	
EndProcedure

; AZJIO
Procedure GoRegExp()
	; LINK : https://www.purebasic.fr/english/viewtopic.php?p=595832#p595832
	Protected rex, LSize, Pos = 0, i, tmp$, regex$
	Protected Dim Tokens.s(0)
	Protected *Texte
	
	ScintillaSendMessage(#Scintilla, #SCI_CLEARALL)
	ClearList(FoundReference())
	
	tmp$ = GetGadgetText(#cmbRex)
	regex$ = tmp$
	If Not Asc(tmp$)
		ProcedureReturn
	EndIf

	rex = CreateRegularExpression(#PB_Any, tmp$)
	
	If rex
		If ExamineRegularExpression(rex, PB_ScintillaText)
			While NextRegularExpressionMatch(rex)
				If Not FindString(RegularExpressionMatchString(rex), #LF$)
					AddElement(FoundReference())
					FoundReference()\Selregexp = RegularExpressionMatchString(rex)
					FoundReference()\LineNo = RegularExpressionMatchPosition(rex)
				EndIf
			Wend
		EndIf
	Else
		MessageRequester("Regular expression error", RegularExpressionError())
		ProcedureReturn
	EndIf
	
	LSize = ListSize(FoundReference())
	If LSize > 0
		; 		If LSize > 5000 And MessageRequester("Continue?", "Found" + Str(LSize) + " rows, Continue?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_No
		; 			ProcedureReturn
		; 		EndIf
		
		Pos = 0
		i = 0
		ForEach FoundReference()
			While Pos < FoundReference()\LineNo
				Pos = FindString(PB_ScintillaText, #LF$, Pos + 1)
				If Pos
					i + 1
				Else
					Break
				EndIf
			Wend
			If i < 1 Or i > ArraySize(Lines())
				Continue
			EndIf
			
			FoundReference()\LineNo = i
			FoundReference()\Reference = Lines(i - 1)
			FoundReference()\Reference = LTrimChar(FoundReference()\Reference, " " + #TAB$)
			
			; >> first attempt to mark the selected word in the string
			Protected  Texte$=Str(FoundReference()\LineNo) + #TAB$ + "["+FindProcedureName(FoundReference()\LineNo)+"]> " + FoundReference()\Reference
			*Texte=UTF8(Texte$)
			ScintillaSendMessage(#Scintilla, #SCI_APPENDTEXT, Len(Texte$), *Texte) 
		Next
		FreeMemory(*Texte)
		
		
		ForEach FoundReference()
			tmp$=FoundReference()\Selregexp
			If Right(tmp$, 1)="$"
				tmp$=Left(tmp$, Len(tmp$)-1)+"+\$"
			EndIf
			;The integrated regex in the scintilla gadget need some escapments
			tmp$ = ReplaceString(tmp$, "*", "\*")
			tmp$ = ReplaceString(tmp$, "(", "\(")
			tmp$ = ReplaceString(tmp$, ")", "\)")
			tmp$ = ReplaceString(tmp$, "\", "\\")
			tmp$ = ReplaceString(tmp$, "\\", "\")
			; ScintillaIndicColor2(UTF8(tmp$), Len(tmp$))
			ScintillaIndicColor(UTF8(tmp$), Len(tmp$),7,7)	
		Next
		
		SelectedWord = StringField(regex$, 1, ")")
		SelectedWord = Right(SelectedWord,Len(SelectedWord)-3)
		SelectedWord=Trim(SelectedWord)
		
		SetWindowTitle(#Mainform,"'" + SelectedWord + "'> "+ CountSelectedWords +" times in " + Str(ListSize(FoundReference())) + " lines" + YouAreHere)
		
	EndIf
	
EndProcedure

Procedure LookForWordUnderCursor()
	; LINK : http://www.purebasic.fr/english/viewtopic.php?f=12&t=37823
	Protected RegexLines, PbRegexTokens
	Protected CountLines, LineCounter, CountTokens, TokenCounter
	Protected Line.s, selWord.s, stx.s
	Protected Dim Tokens.s(0)
	
	RegexLines = CreateRegularExpression(#PB_Any , ".*\r\n")
	PbRegexTokens = CreateRegularExpression(#PB_Any, #DOUBLEQUOTE$ + "[^" + #DOUBLEQUOTE$ + "]*" + #DOUBLEQUOTE$ + "|[\*]?[a-zA-Z_]+[\w]*[\x24]?|#[a-zA-Z_]+[\w]*[\x24]?|[\[\]\(\)\{\}]|[-+]?[0-9]*\.?[0-9]+|;.*|\.|\+|-|[&@!\\\/\*,\|]|::|:|\|<>|>>|<<|=>{1}|>={1}|<={1}|=<{1}|={1}|<{1}|>{1}|\x24+[0-9a-fA-F]+|\%[0-1]*|%|'")
	
	CountLines = CountString(PB_ScintillaText, #CRLF$)
	
	CountLines = ExtractRegularExpression(RegexLines, PB_ScintillaText, Lines())
	
	selWord = LCase(SelectedWord)  ; keep the original writing
	CountSelectedWords = 0				 ; init for new search
	
	For LineCounter = 0 To CountLines - 1
		Line = Lines(LineCounter)
		
		;Debug "tokenize Line '" + Line + "'"
		
		CountTokens = ExtractRegularExpression(PbRegexTokens, Line, Tokens()) ; tokenize the line
		
		For TokenCounter = 0 To CountTokens - 1
			;Debug "  check Token '" + Tokens(TokenCounter) + "'"
			
			If selWord = LCase(Tokens(TokenCounter))
				AddElement(FoundReference())
				FoundReference()\LineNo = LineCounter + 1
				
				Line = Trim(Line)
				Line = Mid(Line, 1, Len(Line) - 2)  ; remove the #CRLF$
				
				CountSelectedWords + CountString(LCase(Line), selWord)   ; <-- count SelectedWord in the codeline
				
				FoundReference()\Reference = Line
				Break  ; only one line (evenn if there are more than one SelectedWord )
			EndIf
		Next TokenCounter
	Next LineCounter
	
	; because of #Constant or *Pointer
	If ListSize(FoundReference()) = 0
		For LineCounter = 0 To CountLines - 1
			Line = Lines(LineCounter)
			CountTokens = ExtractRegularExpression(PbRegexTokens, Line, Tokens())
			For TokenCounter = 0 To CountTokens - 1
				stx = LCase(Tokens(TokenCounter))
				If stx = "#" + selWord Or stx = "*" + selWord
					AddElement(FoundReference())
					FoundReference()\LineNo = LineCounter + 1
					
					Line = Trim(Line)
					Line = Mid(Line, 1, Len(Line) - 2)
					
					CountSelectedWords + CountString(LCase(Line), stx)  ; <-- count SelectedWord in the codeline
					
					FoundReference()\Reference = Line
					Break
				EndIf
			Next
		Next
		
		CompilerIf Not #PB_Compiler_Debugger
			If ListSize(FoundReference()) = 0 : End : EndIf
		CompilerEndIf
	EndIf
	
EndProcedure

Procedure  GetNumberLine(String$,TrimChar$ = #TAB$)
	
	Protected *c.Character, *jc.Character,i
	
	If Not Asc(String$)
		ProcedureReturn 0
	EndIf
	
	*c.Character = @String$
	
	While *c\c
		*jc.Character = @TrimChar$
		
		While *jc\c
			i+1
			If *c\c = *jc\c
				Break 2
			EndIf
			*jc + SizeOf(Character)
		Wend
		
		*c + SizeOf(Character)
	Wend
	
	If i
		String$=Left(String$,i-1)
		ProcedureReturn Val(String$)
	Else
		ProcedureReturn 0
	EndIf
	
EndProcedure

Procedure JumpToLine(SelectedLine)
	
	Protected Count

	SendMessage_(ScintillaHandle, #SCI_GOTOLINE, SelectedLine - 1, 0)
	Count = SendMessage_(ScintillaHandle, #SCI_LINESONSCREEN, 0, 0) / 2
	SendMessage_(ScintillaHandle, #SCI_SETFIRSTVISIBLELINE, SelectedLine - Count - 1, 0)
	SetForegroundWindow_(PbIdeHandle)
	SetActiveWindow_(PbIdeHandle)
	
EndProcedure


; ---------------------------------------------------------------------------------------------------------------------

;Only to have a combobox nicer
Procedure Callback_Win(hwnd, msg, wParam, lParam)
	Protected Result,  *DrawItem.DRAWITEMSTRUCT, Buffer.s
Protected  text$
	Protected nNotifyCode
	
	Result = #PB_ProcessPureBasicEvents
	
	Select msg
		Case #WM_COMMAND
			If lParam = GadgetID(#cmbRex)
				nNotifyCode = wParam >> 16 ; HiWord
				If nNotifyCode = #CBN_SELENDCANCEL
					flgRead = 0
				EndIf
				If nNotifyCode = #CBN_DROPDOWN
					flgRead = 1
				EndIf
			EndIf
			
		Case #WM_NCDESTROY
			DeleteObject_(HightLightBrush)
			DeleteObject_(BackColorBrush)
			DeleteObject_(BackColorBrushHeader)
			
			
		Case #WM_CTLCOLOREDIT
			Buffer = Space(64)
			If GetClassName_(GetParent_(lParam), @Buffer, 64)
				If Buffer = "ComboBox"
					SetTextColor_(wParam, #Black)
					SetBkMode_(wParam, #TRANSPARENT)
					ProcedureReturn BackColorBrush
				EndIf
			EndIf
			
		Case #WM_DRAWITEM
			*DrawItem.DRAWITEMSTRUCT = lParam
			If *DrawItem\CtlType = #ODT_COMBOBOX
				If IsGadget(wParam)
					If *DrawItem\itemID <> -1
						If *DrawItem\itemstate & #ODS_SELECTED
							FillRect_(*DrawItem\hDC, *DrawItem\rcitem, HightLightBrush)
						Else
							FillRect_(*DrawItem\hDC, *DrawItem\rcitem, BackColorBrush)
						EndIf
						SetBkMode_(*DrawItem\hDC, #TRANSPARENT)
						SetTextColor_(*DrawItem\hDC, ForeColor)
						Text$ = GetGadgetItemText(*DrawItem\CtlID, *DrawItem\itemID)
						*DrawItem\rcItem\left + DesktopScaledX(4)
						DrawText_(*DrawItem\hDC, Text$, Len(Text$), *DrawItem\rcItem, #DT_LEFT | #DT_SINGLELINE | #DT_VCENTER)
					EndIf
				EndIf
			EndIf
	EndSelect
	ProcedureReturn Result
EndProcedure


; ---------------------------------------------------------------------------------------------------------------------
;Not used    ChrisR
Procedure SetWindowTheme()
	Protected Theme.s, cmbRexID, ChildGadget, Buffer.s
	If OSVersion() >= #PB_OS_Windows_10
		Theme = "DarkMode_Explorer"
	Else
		Theme = "Explorer"
	EndIf
	
	SetWindowTheme_(GadgetID(#Scintilla), @Theme, 0)
	
	cmbRexID = GadgetID(#cmbRex)
	Buffer = Space(64)
	If GetClassName_(cmbRexID, @Buffer, 64)
		If Buffer = "ComboBox"
			If OSVersion() >= #PB_OS_Windows_10 And Theme = "DarkMode_Explorer"
				SetWindowTheme_(cmbRexID, "DarkMode_CFD", "Combobox")
			Else
				SetWindowTheme_(cmbRexID, @Theme, 0)
			EndIf
		EndIf
	EndIf
	ChildGadget = GetWindow_(cmbRexID, #GW_CHILD)
	If ChildGadget
		Buffer = Space(64)
		If GetClassName_(ChildGadget, @Buffer, 64)
			If Buffer = "ComboBox"
				If OSVersion() >= #PB_OS_Windows_10 And Theme = "DarkMode_Explorer"
					SetWindowTheme_(ChildGadget, "DarkMode_CFD", "Combobox")
				Else
					SetWindowTheme_(ChildGadget, @Theme, 0)
				EndIf
			EndIf
		EndIf
	EndIf
EndProcedure

;For test only
Macro TEST
	Debug "ok"
EndMacro
Macro TEST2(ok)
	Debug  ok
EndMacro

; ---------------------------------------------------------------------------------------------------------------------

;-.............Scintilla...........
;=============================================================

;Global
Global SciPositionStart, *Buffer

;-Declare
Declare CallbackHighlight(*Position, Length, IdColor)
Declare ScintillaCallBack(Gadget.i, *scinotify.SCNotification)


;- Callback Procedures
Procedure CallbackHighlight(*Position, Length, IdColor)
	
	Shared SciPositionStart, *Buffer
	
	ScintillaSendMessage(#Scintilla, #SCI_STARTSTYLING, (*Position - *Buffer) + SciPositionStart, $1F)
	ScintillaSendMessage(#Scintilla, #SCI_SETSTYLING, Length, IdColor)
EndProcedure

Procedure ScintillaCallBack(Gadget.i, *scinotify.SCNotification)
	
	Protected SciLineNumber
	Protected txtr.TEXTRANGE
	Protected SciPositionEnd
	Shared SciPositionStart, *Buffer
	
	Select *scinotify\nmhdr\code      
			
		Case #SCN_STYLENEEDED
			SciLineNumber = ScintillaSendMessage(Gadget, #SCI_LINEFROMPOSITION, ScintillaSendMessage(Gadget, #SCI_GETENDSTYLED))
			SciPositionStart = ScintillaSendMessage(Gadget, #SCI_POSITIONFROMLINE, SciLineNumber)
			SciPositionEnd     = *scinotify\Position
			
			txtr\chrg\cpMin = SciPositionStart
			txtr\chrg\cpMax = SciPositionEnd
			txtr\lpstrText  = AllocateMemory(SciPositionEnd - SciPositionStart + 1)
			
			*Buffer          = txtr\lpstrText
			
			ScintillaSendMessage(Gadget, #SCI_GETTEXTRANGE, 0, txtr)
			
			CallFunction(#Scintilla_Highlight_DLL, "SyntaxHighlight", *Buffer, SciPositionEnd - SciPositionStart, @CallbackHighlight(), #True)
			
			FreeMemory(*Buffer)
			
	EndSelect
	
EndProcedure
;-..............Start..............
;=============================================================

; ---== MainWindow Procedures ==---------------------------------------------------------------------------------------


If Not OpenLibrary(#Scintilla_Highlight_DLL, #PB_Compiler_Home+"SDK/Syntax Highlighting/SyntaxHighlighting.dll") 
	MessageRequester("Error", "SyntaxHilighting.dll not found")
	End
EndIf

If Not InitScintilla()
	MessageRequester("Error", "error Scintilla")
	End
EndIf

Procedure MainWindowsResize_Event()
	
	xywh\w = WindowWidth(#Mainform)
	xywh\h = WindowHeight(#Mainform)
	ResizeGadget(#cmbRex, #PB_Ignore, #PB_Ignore, xywh\w - 34, 24)
	ResizeGadget(#btnRex, xywh\w - 28, #PB_Ignore, #PB_Ignore, #PB_Ignore)
	ResizeGadget(#Scintilla, #PB_Ignore, #PB_Ignore, xywh\w - 6, xywh\h - 33)
	
EndProcedure



; MainForm_Open()
Procedure Main()
	
	Protected tmp
	Protected  Font.s
	
	Initialization() 
	LookForWordUnderCursor()
	
; 	YouAreHere = FindProcedureName(CursorLine)
	If PB_ScintillaText <> ""  
		YouAreHere = FindProcedureName(CursorLine)
		If YouAreHere <> ""
			YouAreHere = "|Current: " + YouAreHere
		EndIf
	EndIf
	
	; ini
	If OpenPreferences(ini$) 
		If PreferenceGroup("set")
			xywh\x = ReadPreferenceInteger("x", xywh\x)
			xywh\y = ReadPreferenceInteger("y", xywh\y)
			xywh\w = ReadPreferenceInteger("w", xywh\w)
			xywh\h = ReadPreferenceInteger("h", xywh\h)
		EndIf
		ClosePreferences()
	EndIf
	If xywh\x = 0 And xywh\y = 0
		centered = #PB_Window_ScreenCentered
	EndIf
	CopyStructure(@xywh, @xywh2, xywhm)
	
	
	;- GUI
	If OpenWindow(#Mainform, xywh\x, xywh\y, xywh\w, xywh\h,
	              "'" + SelectedWord + "'> "+ CountSelectedWords +" times in " + Str(ListSize(FoundReference())) + " lines" + YouAreHere,
	              #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | centered)
		SetWindowColor(#Mainform, BackColor)
		StickyWindow(#Mainform, #True)
		SetWindowCallback(@Callback_Win())

		ComboBoxGadget(#cmbRex, 3, 3, WindowWidth(#Mainform) - 34, 24, #PB_ComboBox_Editable | #CBS_HASSTRINGS | #CBS_OWNERDRAWFIXED)
		
		;-regex
		AddGadgetItem(#cmbRex, -1, "(?# Debug, All )\bDebug\b")
		AddGadgetItem(#cmbRex, -1, "(?# Debug, real )(?m)^\h*\KDebug\b")
		AddGadgetItem(#cmbRex, -1, "(?# WinAPI )(?mi)[a-z][\da-z]*_(?=\h*\()")
		AddGadgetItem(#cmbRex, -1, "(?# Link )https?://[\w.:]+/?(?:[\w/?&=.~;\+!*_#%-]+)")
		AddGadgetItem(#cmbRex, -1, "(?# Procedure )(?mi)^\h*(?:Procedure[CDL$]{0,5}?(?:\h*\.[abcdfilqsuw])?\h+\K)[A-Za-z_]\w*\h*(?=\()")
		AddGadgetItem(#cmbRex, -1, "(?# Macro, All )(?mi)^\h*Macro\h+\K[A-Za-z_]\w*\h*")
		AddGadgetItem(#cmbRex, -1, "(?# Macro )(?mi)^\h*Macro\h+\K[A-Za-z_]\w*\h*(?=\()")
		AddGadgetItem(#cmbRex, -1, "(?# Var$ )(?<![#@\w])\w+\$")
		AddGadgetItem(#cmbRex, -1, "(?# @*Point, whole )[@*]{1,2}\w+\b\$?(?![\\.(])")
		AddGadgetItem(#cmbRex, -1, "(?# @*Point, var)[@*]{1,2}\w+(?!\()")
		AddGadgetItem(#cmbRex, -1, "(?# @Point, Procedure)@\w+\(\)")
		AddGadgetItem(#cmbRex, -1, "(?# Hex num )(?i)\$[\da-f]+")
		AddGadgetItem(#cmbRex, -1, "(?# Comments )(?m)^\h*\K;.*?(?=\r?$)")
		#q$ = Chr(34)
		AddGadgetItem(#cmbRex, -1, "(?# Comments, All )(?m)^(?:[^" + #q$ + ";]*" + #q$ + "[^" + #q$ + "]*?" + #q$ + ")*[^" + #q$ + ";]*(;.*?)(?=\r?$)")
		AddGadgetItem(#cmbRex, -1, "(?# Structures, Declare )(?i)(?<![=\w" + #q$ + "\\./-])[a-z]\w*\.[a-z]\w+(?![\w" + #q$ + "\\./-])")
		AddGadgetItem(#cmbRex, -1, "(?# Structures, item )(?<![\w.:" + #q$ + "\\])\*?\w+(?:(?:\(\))?\\[\d_a-zA-Z]+)+(?![\w" + #q$ + "\\])")
		AddGadgetItem(#cmbRex, -1, "(?# Structures, Content )(?m)^\h*Structure\h*\K\w+")
		; AddGadgetItem(#cmbRex, -1, ~"(?# Comments )(?m)^(?:[^\";]*\"[^\"]*?\")*[^\";]*(;.*?)(?=\r?$)")
		; AddGadgetItem(#cmbRex, -1, ~"(?# Structures, Declare )(?i)(?<![=\\w\"\\./-])[a-z]\\w*\\.[a-z]\\w+(?![\\w\"\\\\./-])")
		; AddGadgetItem(#cmbRex, -1, ~"(?# Structures, item )(?<![\\w.:\"\\\\])\\*?\\w+(?:(?:\\(\\))?\\\\[\\d_a-zA-Z]+)+(?![\\w\"\\\\])")
		AddGadgetItem(#cmbRex, -1, "(?# Types )\b\w+\.[sfdqbliwcapu]\b")
		AddGadgetItem(#cmbRex, -1, "(?# Constants, Declare )(?m)^\h*\K#\w+\$?(?=\h*(?:=|\r?$))")
		AddGadgetItem(#cmbRex, -1, "(?# Constants, All )#\w+\b\$?")
		AddGadgetItem(#cmbRex, -1, "(?# CONSTANTS, DECLARE )(?m)^\h*\K#[A-Z\d_]+(?=\h*(?:=|\r?$))")
		AddGadgetItem(#cmbRex, -1, "(?# CONSTANTS, ALL )#[A-Z\d_]+\b")
		AddGadgetItem(#cmbRex, -1, "(?# CONSTANTS, X_X )#[A-Z\d]+_[A-Z\d]+\b")
		AddGadgetItem(#cmbRex, -1, "(?# Constants, #PB_ )#PB_\w+\b\$?")
		AddGadgetItem(#cmbRex, -1, "(?# Constants, Str )#\w+\$")
		AddGadgetItem(#cmbRex, -1, "(?# If )(?mi)^\h*\KIf(?=\h)")
		AddGadgetItem(#cmbRex, -1, "(?# Loop )(?mi)^\h*\K(For(Each)?|Repeat|While)(?=\h)")
		AddGadgetItem(#cmbRex, -1, "(?# Select )(?mi)^\h*\KSelect(?=\h)")
		AddGadgetItem(#cmbRex, -1, "(?# Include )(?mi)^\h*\KX?Include[a-z]{4,6}\b(?=\h)")
		
		#img = 0
		
		tmp = 24;= GadgetHeight(#cmbRex)
		If CreateImage(#img, tmp, tmp, 32, RGB(255, 255, 255))
			StartDrawing(ImageOutput(#img))
			Box(0, 0, tmp, tmp, BorderColor)
			Box(1, 1, tmp - 2, tmp - 2, BackColorHeader)
			DrawText((tmp - TextWidth(">")) / 2, (tmp - TextHeight(">")) / 2, ">", ForeColor, BackColorHeader)
			StopDrawing()
		EndIf
		ImageGadget(#btnRex, WindowWidth(#Mainform) - 28, 3, tmp, tmp, ImageID(0))
		
		If CursorLine < 1 Or CursorLine > ArraySize(Lines())
			CursorLine = 1
		EndIf
		
		ScintillaGadget(#Scintilla, 3, 30, WindowWidth(#Mainform) - 6, WindowHeight(#Mainform) - 33, @ScintillaCallBack())
		
		ScintillaSendMessage(#Scintilla, #SCI_SETLEXER, #SCLEX_CONTAINER)
		
		;Your own PB preferences
		OpenPreferences(GetEnvironmentVariable("APPDATA") + "\PureBasic\PureBasic.prefs")
		PreferenceGroup("Editor")
		
		Font = ReadPreferenceString("EditorFontName", "Courier New")
		
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE,#STYLE_DEFAULT, $000000)
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETBACK, #STYLE_DEFAULT, ReadPreferenceLong("BackgroundColor", $FFFFFF))
		
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFONT, #STYLE_DEFAULT, @Font)
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETSIZE, #STYLE_DEFAULT, ReadPreferenceLong("EditorFontSize", 10))
		ScintillaSendMessage(#Scintilla, #SCI_STYLECLEARALL)
		
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Text, ReadPreferenceLong("NormalTextColor", 0))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Keyword, ReadPreferenceLong("BasicKeywordColor", $9D030D))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETBOLD, #Scintilla_Keyword, #True)
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Comment, ReadPreferenceLong("CommentColor", $6F884A))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETITALIC, #Scintilla_Comment, #True)
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Constant, ReadPreferenceLong("ConstantColor", $0B46AE))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_String, ReadPreferenceLong("StringColor", $413C33))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Function, ReadPreferenceLong("PureKeywordColor", $EF303D))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Asm, ReadPreferenceLong("ASMKeywordColor", $400080))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Operator,  ReadPreferenceLong("OperatorColor", $0000FF))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Structure, ReadPreferenceLong("StructureColor", $0548B4))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Number, ReadPreferenceLong("NumberColor", $0000FF))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Pointer,  ReadPreferenceLong("PointerColor", $0507B4))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Separator,  ReadPreferenceLong("SeparatorColor", $000000))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Label,  ReadPreferenceLong("LabelColor", $804000))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_Module,  ReadPreferenceLong("ModuleColor", $9D030D))
		
		;Line nimber    
		ScintillaSendMessage(#Scintilla, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
		ScintillaSendMessage(#Scintilla, #SCI_SETMARGINWIDTHN, 0, 50)
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETBACK, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberBackColor", GetSysColor_(15)))
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberColor", 0))
		ScintillaSendMessage(#Scintilla, #SCI_SETMARGINWIDTHN, 1, 5)
		
		;Current line
		ScintillaSendMessage(#Scintilla, #SCI_SETCARETLINEVISIBLE, #True)
		ScintillaSendMessage(#Scintilla, #SCI_SETCARETLINEBACK, ReadPreferenceLong("CurrentLineColor", 0))
		
		;Replace TABs by Spaces 
		ScintillaSendMessage(#Scintilla, #SCI_SETUSETABS, #False)
		
		;TAB = 4 spaces
		ScintillaSendMessage(#Scintilla, #SCI_SETINDENT, 4)
		
		;Indentation
		ScintillaSendMessage(#Scintilla, #SCI_SETINDENTATIONGUIDES, #SC_IV_LOOKFORWARD)
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #STYLE_INDENTGUIDE, RGB(154, 205, 50))
		
		;lexer
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETFORE, #Scintilla_MyLexer,  $0000FF)
		ScintillaSendMessage(#Scintilla, #SCI_STYLESETBOLD, #Scintilla_MyLexer, #True)
		
		RemoveKeyboardShortcut(#Mainform, #PB_Shortcut_Tab)
		
		ClosePreferences()
		
		
		ForEach FoundReference()
			FoundReference()\Reference = LTrimChar(FoundReference()\Reference, " " + #TAB$)
			
			; >> first attempt to mark the selected word in the string
			Protected  Texte$=Str(FoundReference()\LineNo) + #TAB$ +  "["+FindProcedureName(FoundReference()\LineNo)+"]> " + FoundReference()\Reference+ #LF$;
			Protected *Texte=UTF8(Texte$)
			ScintillaSendMessage(#Scintilla, #SCI_APPENDTEXT, Len(Texte$), *Texte)    
		Next
		FreeMemory(*Texte)
		
		Define regex$ = SelectedWord
		; ScintillaIndicColor2(UTF8(regex$), Len(regex$))
		ScintillaIndicColor(UTF8(regex$), Len(regex$),7,7)
		
		AddKeyboardShortcut(#Mainform, #PB_Shortcut_Escape, #Mainform_Shortcut_Escape_Event)
		BindEvent(#PB_Event_SizeWindow, @MainWindowsResize_Event(), #Mainform)
		
		SetActiveGadget(-1)
		
		;Copy to clipboard
		AddKeyboardShortcut(#Mainform, #PB_Shortcut_Control | #PB_Shortcut_Shift | #PB_Shortcut_C, #Shortcut_Ctrl_Shift_C)
		;ComboBox enter
		AddKeyboardShortcut(#Mainform, #PB_Shortcut_Return, #Shortcut_Enter)
		
		
		
		;- Loop
		Repeat
			
			Select WaitWindowEvent()
					
				Case #PB_Event_MoveWindow
					xywh\x = WindowX(#Mainform)
					xywh\y = WindowY(#Mainform)
					
				Case #PB_Event_CloseWindow
					If Not CompareMemory(@xywh, @xywh2, SizeOf(xywhm))
						If OpenPreferences(ini$) Or CreatePreferences(ini$)
							PreferenceGroup("set")
							WritePreferenceInteger("x", xywh\x)
							WritePreferenceInteger("y", xywh\y)
							WritePreferenceInteger("w", xywh\w)
							WritePreferenceInteger("h", xywh\h)
							ClosePreferences()
						EndIf
					EndIf
					Break
					
				Case #PB_Event_Menu
					Select EventMenu()
						Case #Shortcut_Enter
							If GetActiveGadget() = #cmbRex
								flgRead = 0
								GoRegExp()
							EndIf
						Case #Shortcut_Ctrl_Shift_C
							CopyClipboard()
						Case #Mainform_Shortcut_Escape_Event
							Break
					EndSelect
					
				Case #PB_Event_Gadget
					Select EventGadget()
						Case #cmbRex
							If EventType() = #PB_EventType_Change And flgRead = 1
								flgRead = 0
								GoRegExp()
							EndIf
						Case #btnRex
							GoRegExp()
						Case #Scintilla
							JumpToLine(GetNumberLine(GetScintillaCurLineText(#Scintilla, #cmbRex)))	
					EndSelect
			EndSelect
		ForEver
		
	EndIf
	ProcedureReturn 0  ; not necessary, but looks good/better
EndProcedure
End main()
Create an executable and add it into the Tools menu.

M.
Last edited by Mesa on Wed Mar 08, 2023 6:11 pm, edited 3 times in total.
Allen
User
User
Posts: 92
Joined: Wed Nov 10, 2021 2:05 am

Re: Show all occurrences of a word in the IDE

Post by Allen »

Hi, Mesa,

Thank you for your code, it is very useful.

Allen
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Show all occurrences of a word in the IDE

Post by AZJIO »

I would also like to highlight the selected text.
viewtopic.php?f=13&t=31092&p=235655&hil ... ES#p235655
Allen
User
User
Posts: 92
Joined: Wed Nov 10, 2021 2:05 am

Re: Show all occurrences of a word in the IDE

Post by Allen »

Hi,

I named the exe file as "ShowVar.exe" and add it under tool menu. After testing it for a while I found some problems.

In below code:

Code: Select all

Define.q EncodeInputF

Procedure.s ReadNextLine()
  Protected.s Tmp$
  Repeat 
    Tmp$=ReadString(1,EncodeInputF)
    If Asc(Tmp$)<>Asc(";") And Tmp$<>""
      ProcedureReturn Tmp$
    EndIf  
  Until Eof(1)
  ProcedureReturn ""
EndProcedure
1) If I highlighted the "EncodeInputF" in line 6, and run the ShowVar, line 1 and line 6 are displayed correctly. If I highlighted the "EncodeInputF" in line 1 and run SHowVar, nothing is displayed.
2) If I highlighted "Tmp$" and run ShowVar, nothing is displayed, if I only highlighted "Tmp", all lines with Tmp$ will be shown.

I am runming PB6.01 beta 2 CBE in win 10.

Allen
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Show all occurrences of a word in the IDE

Post by AZJIO »

Try not to select the text, but just place the cursor on the word and everything will work out
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Show all occurrences of a word in the IDE

Post by AZJIO »

ColorListIconGadget.pb

Code: Select all

#coloredChars_Delimeter = "{***\"

Enumeration
	#frmMain_References
EndEnumeration

;... Create brushes for painting item background
Structure MYBRUSHES
	brushDefault.l
	brushSelected.l
EndStructure

Global brush.MYBRUSHES

brush\brushSelected = CreateSolidBrush_(GetSysColor_(#COLOR_HIGHLIGHT))
brush\brushDefault = GetStockObject_(#WHITE_BRUSH)

Procedure GetCharWidth(gad, c$)
	ProcedureReturn SendMessage_(gad, #LVM_GETSTRINGWIDTH, 0, @c$)
EndProcedure

;Here we add some text to the underlying cell text to store the color info.
Procedure SetColor(gad, row, column, startp, endp, color)
	Protected text$
	If column
		text$ = GetGadgetItemText(gad, row, column)
		;Now add the new text.
		text$+#coloredChars_Delimeter+Str(startp)+"\"+Str(endp)+"\"+Str(color)
		SetGadgetItemText(gad,row,text$,column)
	EndIf
EndProcedure

Procedure myWindowCallback(hwnd, msg, wParam, lParam)
	Protected Result, *nmhdr.NMHDR, *lvCD.NMLVCUSTOMDRAW, subItemRect.RECT
	Protected thisRow, thisCol, subItemText$, text$, pos, i, color, j, c, c$, nextColor, thisColor
	Result = #PB_ProcessPureBasicEvents
	Dim LVColor(0)
	Select msg
		Case #WM_NOTIFY
			*nmhdr.NMHDR = lParam
			*lvCD.NMLVCUSTOMDRAW = lParam
			If *lvCD\nmcd\hdr\hwndFrom=GadgetID(#frmMain_References) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
				Select *lvCD\nmcd\dwDrawStage
					Case #CDDS_PREPAINT
						Result = #CDRF_NOTIFYITEMDRAW
					Case #CDDS_ITEMPREPAINT
						Result = #CDRF_NOTIFYSUBITEMDRAW;
					Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
						thisRow = *lvCD\nmcd\dwItemSpec
						thisCol = *lvCD\iSubItem
						If thisCol
							;... Define rect for text
							subItemRect.RECT\left = #LVIR_LABEL
							subItemRect.RECT\top = *lvCD\iSubItem
							;... Get the subitem rect
							SendMessage_(GadgetID(#frmMain_References), #LVM_GETSUBITEMRECT, thisRow, @subItemRect)
							text$ = GetGadgetItemText(#frmMain_References, thisRow, thisCol)
							pos = FindString(text$, #coloredChars_Delimeter,1)
							If pos
								subItemText$ = Left(text$, pos-1)
								text$ = Right(text$, Len(text$)-pos+1)
							Else
								subItemText$ = text$
								text$=""
							EndIf
							Dim LVColor(Len(subItemText$))
							pos=2
							For i = 1 To CountString(text$, #coloredChars_Delimeter)
								color = Val(StringField(StringField(text$,pos+2,"\"),1,"{"))
								For j = Val(StringField(text$,pos,"\")) To Val(StringField(text$,pos+1,"\"))
									LVColor(j) = color
								Next
								pos+3
							Next
							If GetGadgetState(#frmMain_References) = thisRow
								;... If item is selected
								FillRect_(*lvCD\nmcd\hdc, subItemRect, brush\brushSelected)
							Else
								;... If item is not selected
								FillRect_(*lvCD\nmcd\hdc, subItemRect, brush\brushDefault)
							EndIf
							InflateRect_(subItemRect,-2,0)

							;... Here we will paste together the colored characters
							;... to form a string. This should speed up the drawing
							For c = 1 To Len(subItemText$)
								c$ = Mid(subItemText$, c, 1)
								If thisRow <> GetGadgetState(#frmMain_References)
									For i = c + 1 To Len(subItemText$)
										thisColor = LVColor(c)
										nextColor = LVColor(i)
										If thisColor = nextColor
											c$ + Mid(subItemText$, i, 1)
											c + 1
										Else
											Break
										EndIf
									Next i
									SetTextColor_(*lvCD\nmcd\hdc, thisColor)
								Else
									SetTextColor_(*lvCD\nmcd\hdc, GetSysColor_(#COLOR_HIGHLIGHTTEXT))
								EndIf
								DrawText_(*lvCD\nmcd\hdc, c$, Len(c$), subItemRect, #DT_END_ELLIPSIS|#DT_VCENTER|#DT_SINGLELINE)
								subItemRect\left + GetCharWidth(*nmhdr\hwndFrom, c$)
							Next c
							Result = #CDRF_SKIPDEFAULT
						Else
							Result = #CDRF_DODEFAULT
						EndIf
				EndSelect
			EndIf
	EndSelect
	ProcedureReturn Result
EndProcedure

Procedure.s LTrimChar(String$, TrimChar$ = #CRLF$ + #TAB$ + #FF$ + #VT$ + " ")
	Protected *memChar, *c.Character, *jc.Character
	
	If Not Asc(String$)
		ProcedureReturn ""
	EndIf
	
	*c.Character = @String$
	*memChar = @TrimChar$
	
	While *c\c
		*jc.Character = *memChar
		
		While *jc\c
			If *c\c = *jc\c
				*c\c = 0
				Break
			EndIf
			*jc + SizeOf(Character)
		Wend
		
		If *c\c
			String$ = PeekS(*c)
			Break
		EndIf
		*c + SizeOf(Character)
	Wend
	
	ProcedureReturn String$
EndProcedure
FindAllReferences2.pb

Code: Select all

;   Description: Find all references of a variable
;            OS: Windows
; English-Forum:
;  French-Forum:
;  German-Forum: http://www.purebasic.fr/german/viewtopic.php?f=8&t=28292
;-----------------------------------------------------------------------------

; MIT License
;
; Copyright (c) 2015 Kiffi
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in all
; copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
; SOFTWARE.

; FindAllReferences



CompilerIf #PB_Compiler_OS<>#PB_OS_Windows
	CompilerError "Windows Only!"
CompilerEndIf

EnableExplicit

Enumeration ; Windows
	#frmMain
EndEnumeration
Enumeration ; Gadgets
	#frmMain_References
EndEnumeration
Enumeration ; Menu-/Toolbaritems
	#frmMain_Shortcut_Escape_Event
EndEnumeration

Global PbIdeHandle = Val(GetEnvironmentVariable("PB_TOOL_MainWindow"))
If PbIdeHandle = 0 : End : EndIf

Global ScintillaHandle = Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
If ScintillaHandle = 0 : End : EndIf

Procedure.s RemoveLeadingWhitespaceFromString(InString.s)

	While Left(InString, 1) = Chr(32) Or Left(InString, 1) = Chr(9)
		InString = LTrim(InString, Chr(32))
		InString = LTrim(InString, Chr(9))
	Wend

	ProcedureReturn InString

EndProcedure

Procedure.s GetScintillaText()

	Protected ReturnValue.s

	Protected length
	Protected buffer
	Protected processId
	Protected hProcess
	Protected result

	length = SendMessage_(ScintillaHandle, #SCI_GETLENGTH, 0, 0)
	If length
		length + 2
		buffer = AllocateMemory(length)
		If buffer
			SendMessageTimeout_(ScintillaHandle, #SCI_GETCHARACTERPOINTER, 0, 0, #SMTO_ABORTIFHUNG, 2000, @result)
			If result
				GetWindowThreadProcessId_(ScintillaHandle, @processId)
				hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, processId)
				If hProcess
					ReadProcessMemory_(hProcess, result, buffer, length, 0)
					ReturnValue = PeekS(buffer, -1, #PB_UTF8)
				EndIf
			EndIf
		EndIf
		FreeMemory(buffer)
	EndIf

	ProcedureReturn ReturnValue

EndProcedure

Procedure frmMain_SizeWindow_Event()
	ResizeGadget(#frmMain_References, #PB_Ignore, #PB_Ignore, WindowWidth(#frmMain) - 20, WindowHeight(#frmMain) - 20)
EndProcedure

Procedure frmMain_References_Event()

	Protected SelectedLine

	SelectedLine = Val(GetGadgetItemText(#frmMain_References, GetGadgetState(#frmMain_References), 0))

	If SelectedLine > 0
		SendMessage_(ScintillaHandle, #SCI_GOTOLINE, SelectedLine - 1, 0)
		SendMessage_(ScintillaHandle, #SCI_ENSUREVISIBLE, SelectedLine - 1, 0)
		SetForegroundWindow_(PbIdeHandle)
		SetActiveWindow_(PbIdeHandle)
	EndIf

EndProcedure

Define SelectedWord.s = GetEnvironmentVariable("PB_TOOL_Word")
If SelectedWord = "" : End : EndIf

; MessageRequester("", SelectedWord)

Define ScintillaText.s = GetScintillaText()
If ScintillaText = "" : End : EndIf

Define Line.s
Define CountLines, LineCounter
Define CountTokens, TokenCounter
Define WWE
Define RegexLines, PbRegexTokens

Structure sFoundReference
	LineNo.i
	Reference.s

EndStructure

NewList FoundReference.sFoundReference()

Dim Tokens.s(0)


;http://www.purebasic.fr/english/viewtopic.php?f=12&t=37823
RegexLines = CreateRegularExpression(#PB_Any , ".*\r\n")
PbRegexTokens = CreateRegularExpression(#PB_Any, #DOUBLEQUOTE$ + "[^" + #DOUBLEQUOTE$ + "]*" + #DOUBLEQUOTE$ + "|[\*]?[a-zA-Z_]+[\w]*[\x24]?|#[a-zA-Z_]+[\w]*[\x24]?|[\[\]\(\)\{\}]|[-+]?[0-9]*\.?[0-9]+|;.*|\.|\+|-|[&@!\\\/\*,\|]|::|:|\|<>|>>|<<|=>{1}|>={1}|<={1}|=<{1}|={1}|<{1}|>{1}|\x24+[0-9a-fA-F]+|\%[0-1]*|%|'")

CountLines = CountString(ScintillaText, #CRLF$)

Dim Lines.s(0)

CountLines = ExtractRegularExpression(RegexLines, ScintillaText, Lines())

SelectedWord = LCase(SelectedWord)

For LineCounter = 0 To CountLines - 1

	Line = Lines(LineCounter)

	CountTokens = ExtractRegularExpression(PbRegexTokens, Line, Tokens())

	For TokenCounter = 0 To CountTokens - 1
		If SelectedWord = LCase(Tokens(TokenCounter))
			AddElement(FoundReference())
			FoundReference()\LineNo = LineCounter + 1
			Line = Trim(Line)
			Line = Mid(Line, 1, Len(Line)-2)
			FoundReference()\Reference = Line
			Break
		EndIf

	Next

Next

Define SelectedWord2.s
Define SelectedWord1.s
If ListSize(FoundReference()) = 0

	SelectedWord1 = "#" + SelectedWord

	For LineCounter = 0 To CountLines - 1

		Line = Lines(LineCounter)

		CountTokens = ExtractRegularExpression(PbRegexTokens, Line, Tokens())

		For TokenCounter = 0 To CountTokens - 1
			If SelectedWord1 = LCase(Tokens(TokenCounter))
				AddElement(FoundReference())
				FoundReference()\LineNo = LineCounter + 1
				Line = Trim(Line)
				Line = Mid(Line, 1, Len(Line)-2)
				FoundReference()\Reference = Line
				Break
			EndIf

		Next

	Next

	If ListSize(FoundReference())
		SelectedWord = SelectedWord1
	EndIf
EndIf


If ListSize(FoundReference()) = 0

	SelectedWord2 = "*" + SelectedWord

	For LineCounter = 0 To CountLines - 1

		Line = Lines(LineCounter)

		CountTokens = ExtractRegularExpression(PbRegexTokens, Line, Tokens())

		For TokenCounter = 0 To CountTokens - 1
			If SelectedWord2 = LCase(Tokens(TokenCounter))
				AddElement(FoundReference())
				FoundReference()\LineNo = LineCounter + 1
				Line = Trim(Line)
				Line = Mid(Line, 1, Len(Line)-2)
				FoundReference()\Reference = Line
				Break
			EndIf

		Next

	Next


	If ListSize(FoundReference())
		SelectedWord = SelectedWord2
	Else
		End
	EndIf
EndIf



XIncludeFile "ColorListIconGadget.pb"

Global hGUI
Global ColumnWidth

Procedure Redraw()
	Protected rc.RECT
		With rc
			rc\left = 10
			rc\right = ColumnWidth + 10
			rc\top = 10
			rc\bottom = 300 - 10
		EndWith
		RedrawWindow_(hGUI, rc, 0, #RDW_ERASE|#RDW_INVALIDATE|#RDW_ERASENOW)
EndProcedure

;- GUI
hGUI = OpenWindow(#frmMain,
           #PB_Ignore,
           #PB_Ignore,
           600,
           300,
           "Показать все: '" + SelectedWord + "', " + Str(ListSize(FoundReference())),
           #PB_Window_SystemMenu |
           #PB_Window_SizeGadget |
           #PB_Window_ScreenCentered)

SetWindowCallback(@myWindowCallback())

StickyWindow(#frmMain, #True)

ListIconGadget(#frmMain_References,
               10,
               10,
               WindowWidth(#frmMain) - 20,
               WindowHeight(#frmMain) - 20,
               "-№-",
               50,
               #PB_ListIcon_FullRowSelect |
               #PB_ListIcon_GridLines |
               #PB_ListIcon_AlwaysShowSelection)

AddGadgetColumn(#frmMain_References, 1, "Строка", 400)


ForEach FoundReference()
	FoundReference()\Reference = LTrimChar(FoundReference()\Reference, " " + #TAB$)
	AddGadgetItem(#frmMain_References, -1, Str(FoundReference()\LineNo) + #LF$ + FoundReference()\Reference)
Next

Define i

SendMessage_(GadgetID(#frmMain_References), #LVM_SETCOLUMNWIDTH, 0, #LVSCW_AUTOSIZE_USEHEADER)
SendMessage_(GadgetID(#frmMain_References), #LVM_SETCOLUMNWIDTH, 1, #LVSCW_AUTOSIZE)
SendMessage_(GadgetID(#frmMain_References), #LVM_SETCOLUMNWIDTH, 2, #LVSCW_AUTOSIZE)

AddKeyboardShortcut(#frmMain, #PB_Shortcut_Escape, #frmMain_Shortcut_Escape_Event)
BindEvent(#PB_Event_SizeWindow, @frmMain_SizeWindow_Event(), #frmMain)
BindGadgetEvent(#frmMain_References, @frmMain_References_Event())
SetActiveGadget(#frmMain_References)

ColumnWidth = GetGadgetItemAttribute(#frmMain_References, 0 , #PB_ListIcon_ColumnWidth, 0)


Define pos, le, i;, RegexClr

le = Len(SelectedWord)
i = 0

; RegexClr = CreateRegularExpression(#PB_Any , "\b\Q" + SelectedWord + "\E\b") ; проблема если в имени есть метасимволы: $ и т.д.
pos = 1
ForEach FoundReference()
	Repeat
		pos = FindString(FoundReference()\Reference, SelectedWord, pos, #PB_String_NoCase)
		If pos
			SetColor(#frmMain_References, i, 1, pos, pos + le - 1, #Red)
			pos + le
		Else
			Break
		EndIf
	ForEver

	
; 	If ExamineRegularExpression(RegexClr, FoundReference()\Reference)
; 		If NextRegularExpressionMatch(RegexClr)
; 			pos = RegularExpressionMatchPosition(RegexClr)
; 			If pos
; 				SetColor(#frmMain_References, i, 1, pos, pos + le - 1, #Red)
; 			EndIf
; 		EndIf
; 	EndIf
	i + 1
Next
Redraw()

Repeat

	WWE = WaitWindowEvent()

	If (WWE = #PB_Event_Menu And EventMenu() = #frmMain_Shortcut_Escape_Event) Or (WWE = #PB_Event_CloseWindow)
		Break
	EndIf

ForEver

DeleteObject_(brush\brushSelected)
Added the number of found lines to the title. At me 700 lines are quickly enough displayed. I wanted to add that if a lot is found, then turn off the backlight, but this works quickly.

You need to add a position to the structure so as not to search, especially since there can be 2 matches in one line, and highlighting is looking for the first one.
You need to save the position and size of the window.
Last edited by AZJIO on Sat Feb 11, 2023 10:20 pm, edited 3 times in total.
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Show all occurrences of a word in the IDE

Post by BarryG »

What does this tip do? Because if I double-click any text in the IDE, all occurrences of that text get highlighted already. No need for a tool to do it.
Allen
User
User
Posts: 92
Joined: Wed Nov 10, 2021 2:05 am

Re: Show all occurrences of a word in the IDE

Post by Allen »

by AZJIO » Sat Feb 11, 2023 12:34 am

Try not to select the text, but just place the cursor on the word and everything will work out
@AZJIO, thanks. You are right. It worked a bit different from IDE.
by BarryG » Sat Feb 11, 2023 7:43 am

What does this tip do? Because if I double-click any text in the IDE, all occurrences of that text get highlighted already. No need for a tool to do it.
@BarryG, this tool will provide a summary so you need not scroll up and down to see all the occurrences in a large program. This way, you can very quickly identify any declared but unused varibles. You can also easily jump to the line by clicking on the summary window.

Allen
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Show all occurrences of a word in the IDE

Post by AZJIO »

BarryG wrote: Sat Feb 11, 2023 12:43 am What does this tip do? Because if I double-click any text in the IDE, all occurrences of that text get highlighted already. No need for a tool to do it.
Quickly jump to the desired line, such as a function call line, or to the contents of a function, or to a variable declaration. Clicking on a line moves to that line. It's best to assign this window to a hotkey, I use Ctrl+Shift+D.
TassyJim
Enthusiast
Enthusiast
Posts: 151
Joined: Sun Jun 16, 2013 6:27 am
Location: Tasmania (Australia)

Re: Show all occurrences of a word in the IDE

Post by TassyJim »

BarryG wrote: Sat Feb 11, 2023 12:43 am What does this tip do? Because if I double-click any text in the IDE, all occurrences of that text get highlighted already. No need for a tool to do it.
Like "Find in Files" when you only have one file in the searched folder.
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Show all occurrences of a word in the IDE

Post by BarryG »

Thanks, guys. I set it up as tool, and I understand now. Nice!

Suggestion: Don't add a line to the list if it's already there. I had a variable used 4 times in one line, and the same line was added 4 times to the list.
Allen
User
User
Posts: 92
Joined: Wed Nov 10, 2021 2:05 am

Re: Show all occurrences of a word in the IDE

Post by Allen »

Hi,

Is the program currently not support pointers?

Code: Select all

Define *Ptr.unicode
Define.s Text="abcd"

*Ptr=@Text
Debug *Ptr\u
I place currsor on *Ptr and nothing is shown.

Allen
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Show all occurrences of a word in the IDE

Post by AZJIO »

BarryG wrote: Sat Feb 11, 2023 12:27 pm don't add a line to the list if it already exists
Added "Break" to the loop, now one line is added if there are several tokens in it
Allen wrote: Sat Feb 11, 2023 2:12 pm I place currsor on *Ptr and nothing is shown.
It is necessary to do in the same way as with constants an additional loop to search for pointers. Or make a proper regex. Or use original analyzer "PureBasic\SDK\Syntax Highlighting\SyntaxHighlighting.dll"

Added pointers (*Ptr etc.). But if there is the same variable in the code, then it will be highlighted, since %WORD% does not capture the characters # and *
Allen
User
User
Posts: 92
Joined: Wed Nov 10, 2021 2:05 am

Re: Show all occurrences of a word in the IDE

Post by Allen »

AZJIO,

Thank you for the hints, I modify the code as advised ( add another loop to check pointers) and now it also worked on pointers.

Allen
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Show all occurrences of a word in the IDE

Post by AZJIO »

Everything has already been done in the previous post
Post Reply