PB IDE Smart Highlight (showing selected text) implementatio

Just starting out? Need help? Post your questions and find answers here.
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

PB IDE Smart Highlight (showing selected text) implementatio

Post by Tenaja »

Highlighting selected text is an often-requested feature. It is very handy in editing large projects.

I have implemented this in my own editor. If someone can pitch in with info on PB's IDE plugin system, I can convert it. I just don't have time to pour over random examples and mediocre documentation to figure out the IDE interface.

How do I use Static variables for a plugin?
How do I start a plugin at startup
How do I send a Fn key to the plugin?
How do I pop up and handle a window with an Fn key, in a "snoozing" plugin that has static variables?
{edit} How do I "see" Scintilla messages? I need to call my routine when a Sci gadget fires a SCN_UPDATEUI message.

Thanks...
Last edited by Tenaja on Wed May 16, 2012 8:30 pm, edited 1 time in total.
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

I don't know if this is what you want. It highlights the current word under cursor if you press a hotkey.

Compile in ASCII mode. Add it as a tool with argument "%TEMPFILE" and
assign a hotkey. Press the hotkey to highlight the word under the cursor.

IT IS JUST A TEST, NOT AN USEFUL TOOL.

Code: Select all

CompilerIf #PB_Compiler_Unicode
    CompilerError "Compile without Unicode mode"
CompilerEndIf

Scintilla = Val( GetEnvironmentVariable("PB_TOOL_Scintilla") )

color = $FFFF

If Scintilla
    SendMessageTimeout_(Scintilla,#SCI_INDICSETSTYLE,1,6,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETFORE,1,color,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_SETINDICATORCURRENT,1,0,#SMTO_ABORTIFHUNG,2000,@result)
    
    word$ = GetEnvironmentVariable("PB_TOOL_Word")
    If word$
    
        wordlen = Len(word$)
    
        text$=""
        If ReadFile(0,ProgramParameter(0))
            Repeat
                text$ + ReadString(0) + Chr(10) + Chr(13)
            Until Eof(0)
            CloseFile(0)
        EndIf
            
        pos = 0
        
        Repeat
            pos = FindString(text$,word$,pos+1)

            If pos >0
                SendMessageTimeout_(Scintilla,#SCI_STARTSTYLING  ,pos-4,%1000000,#SMTO_ABORTIFHUNG,2000,@result)
                SendMessageTimeout_(Scintilla,#SCI_SETSTYLING    ,wordlen,%1000000,#SMTO_ABORTIFHUNG,2000,@result)
                SendMessageTimeout_(Scintilla,#SCI_COLOURISE     ,pos-4,wordlen,#SMTO_ABORTIFHUNG,2000,@result)
            EndIf
        Until pos = 0
    EndIf

EndIf
Image
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Tenaja »

That might be better than nothing, but it is certainly a huge compromise from the Smart Highlighting found in editors like Notepad++.

My editor also does it automatically, every time something is highlighted, and the feature is not disabled. Of course, it can be turned on/off (hence the need for another pref box). In my editor, I call the routine when I get a SCN_UPDATEUI message. (See additional need listed in first post.)
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

@Tenaja:
The IDE coders could add this stuff much easier, but unfortunately they are not interested.
The IDE does not have an plugin system. It is just external tools that do not run in the same
process and I think that's very limiting.
The external tools are made for preprocessors that change the source code, but they are
not plugins for changing the IDE. A good plugin system or scripting language would allow
to call internal IDE commands, create toolwindows etc.

Do you know how to set and clear styles with this Scintilla thing? Maybe you can change the
following code, so the current word is highlighted and all other words are not highlighted.
It does not clear the highlighting atm. If you highlight another word, the old words are still highlighted.
Calling '#SCI_INDICATORCLEARRANGE,0,length' does not clear the highlighting here, don't know why.

I have no experience with this Scintilla stuff and I don't like it anyway.

Code: Select all

CompilerIf #PB_Compiler_Unicode = 0
    CompilerError "Compile with Unicode mode enabled"
CompilerEndIf

Scintilla = Val( GetEnvironmentVariable("PB_TOOL_Scintilla") )

color = $FFFF

If Scintilla
    SendMessageTimeout_(Scintilla,#SCI_INDICSETSTYLE,1,5,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETFORE,1,color,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_SETINDICATORCURRENT,1,0,#SMTO_ABORTIFHUNG,2000,@result)
    
    word$ = GetEnvironmentVariable("PB_TOOL_Word")
    If word$
    
        wordlen = Len(word$)
    
        text$=""
        If ReadFile(0,ProgramParameter(0))
            format = ReadStringFormat(0)
            Repeat
                text$ + ReadString(0,format) + Chr(10) + Chr(13)
            Until Eof(0)
            CloseFile(0)
        EndIf

        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        ;SendMessageTimeout_(Scintilla,#SCI_SETINDICATORVALUE,0,0,#SMTO_ABORTIFHUNG,2000,@result)
        ;SendMessageTimeout_(Scintilla,#SCI_INDICATORFILLRANGE,0,length-1,#SMTO_ABORTIFHUNG,2000,@result)
        SendMessageTimeout_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length,#SMTO_ABORTIFHUNG,2000,@result)
        ;SendMessageTimeout_(Scintilla,#SCI_STARTSTYLING  ,0,%1000000,#SMTO_ABORTIFHUNG,2000,@result)
        ;SendMessageTimeout_(Scintilla,#SCI_SETSTYLING    ,length-1,%1000000,#SMTO_ABORTIFHUNG,2000,@result)
        ;SendMessageTimeout_(Scintilla,#SCI_COLOURISE     ,0,length-1,#SMTO_ABORTIFHUNG,2000,@result)

        SendMessageTimeout_(Scintilla,#SCI_INDICSETSTYLE,1,6,#SMTO_ABORTIFHUNG,2000,@result)
            
        pos = 0
        
        Repeat
            pos = FindString(text$,word$,pos+1)

            If pos >0
                SendMessageTimeout_(Scintilla,#SCI_STARTSTYLING  ,pos-1,1<<6,#SMTO_ABORTIFHUNG,2000,@result)
                SendMessageTimeout_(Scintilla,#SCI_SETSTYLING    ,wordlen,1<<6,#SMTO_ABORTIFHUNG,2000,@result)
                SendMessageTimeout_(Scintilla,#SCI_COLOURISE     ,pos-1,wordlen,#SMTO_ABORTIFHUNG,2000,@result)
            EndIf
        Until pos = 0
    EndIf

EndIf
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Tenaja »

Danilo,
I use Indicators to do the highlight:
ScintillaSendMessage(ID, #SCI_INDICATORFILLRANGE, StartPos, SelectedTextLen)
It requires a loop finding the text within the range you want (either full screen, or full doc).
With a 10k line file, there is no discernible delay with doing the whole file at once.
With a long file, there is about a one second delay for every 100k lines when doing the whole file at once--so if you want a slower machine happy or longer files acceptable, you shouldn't do it all at once. (Measurements done on my 4-year old laptop with Intel dual core L7700.)


Then to clear, it is one command (no loop) that clears all indicators:
ScintillaSendMessage(ID, #SCI_INDICATORCLEARRANGE, 0, ScintillaSendMessage(ID, #SCI_GETLENGTH))

I do just the visible screen, for indicating, and it has no discernible delay with styling even scrolling from the bottom up to the top with a 200,000+ line file. Even with the debugger running, there is no discernible delay with removing the indicators in that same 200,000 line file.

Clearly you could put this in a hotkey to activate. It is a shame we don't have true plugin capability. You can use this to make the plugin if you want. Make the second one to clear using the one-line command.

Code: Select all

	Protected.i ID		;ID is the active ScintillaGadget ID.
	Protected.s selectedtext	;, LineOfText

	Protected CurrentPos, SelTextLen, flag, endatpos
	Protected ttf.TextToFind

	ScintillaSendMessage(id, #SCI_INDICSETSTYLE, 0, 8)    ; makes a colored background instead of a box or underscore.
	ScintillaSendMessage(id, #SCI_INDICSETFORE, 0,StyleColorChart(Theme, #StyleColorSmartHighlight))	; $0000FF)	; should be light red.

	; these flags are optional
	flag = 0
	If SmartHighlightSettingWords = 1
		flag = #SCFIND_WHOLEWORD
	EndIf
	If SmartHighlightSettingCase = 1
		flag = flag | #SCFIND_MATCHCASE
	EndIf

	; or just hard code it:
	flag = 0
	
	; Get text data:
	selectedtext = GOSCI_GetSelectedText(ActiveSci)
	SelTextLen = Len(selectedtext)
	; Set up non-scrolling search:
	ttf\lpstrText = selectedtext 
	ttf\chrg\cpMin=ScintillaSendMessage(ID, #SCI_GETLINEENDPOSITION, 0)
	ttf\chrg\cpMax=ScintillaSendMessage(ID, #SCI_GETLENGTH)
	endatpos = ScintillaSendMessage(ID, #SCI_GETLENGTH)
	
; 	Do initial search to get started:
	CurrentPos = ScintillaSendMessage(ID, #SCI_FINDTEXT, flag, @ttf)
	While CurrentPos >= 0 ; does initial test, too.
		ScintillaSendMessage(ID, #SCI_INDICATORFILLRANGE, CurrentPos, SelTextLen)
		CurrentPos = ScintillaSendMessage(ID, #SCI_FINDTEXT, flag, @ttf)
		ttf\chrg\cpMin = CurrentPos + SelTextLen 
	Wend
	
Edited to replace my SendSci macro with ScintillaSendMessage, and to add the background highlighting rather than the box.
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Tenaja »

I added the edits to highlight rather than underscore or box.
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

@Tenaja:
The problem is that we are not in the IDE process, we are outside.

SCI_SEARCHINTARGET and #SCI_FINDTEXT need the search string in the arguments, and our
search string is in our process. The IDE Scintilla cannot read our search string because it is
not in the IDE process.
So it is very limited what we can do from outside.

Also, #SCI_INDICATORCLEARRANGE and #SCI_INDICATORFILLRANGE did not work here.
It works now when I use PostMessage_() instead SendMessageTimeout_().

Maybe PureBasic uses an old version of Scintilla, but the style #INDIC_STRAIGHTBOX does not work here.
That's the reason I used the box style, but underlining works too, if you like that more.

I think this is the best I can do for now, from outside. Fred or freak could implement this better directly within 2 hours maximum:

Code: Select all

CompilerIf #PB_Compiler_Unicode = 0
    CompilerError "Compile with Unicode mode enabled"
CompilerEndIf


#INDIC_STRAIGHTBOX = 8
#INDIC_DASH        = 9
#INDIC_DOTS        = 10
#INDIC_SQUIGGLELOW = 11
#INDIC_DOTBOX      = 12

#SCI_INDICSETALPHA          = 2523
#SCI_INDICSETOUTLINEALPHA   = 2558


;-----------------------------------
; SETUP

; #INDIC_PLAIN       ; Underlined With a single, straight line.
; #INDIC_SQUIGGLE    ; A squiggly underline. Requires 3 pixels of descender space.
; #INDIC_TT          ; A line of small T shapes.
; #INDIC_DIAGONAL    ; Diagonal hatching.
; #INDIC_STRIKE      ; Strike out.
; #INDIC_HIDDEN      ; An indicator With no visual effect.
; #INDIC_BOX         ; A rectangle around the text.
;
; - the following styles don't work with Scintilla used by PB 4.60
; - maybe useful for future versions
;
; #INDIC_ROUNDBOX    ; A rectangle with rounded corners around the text using translucent drawing
;                    ; with the interior usually more transparent than the border.
;                    ; You can use SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA to control the alpha transparency values.
;                    ; The default alpha values are 30 for fill colour and 50 for outline colour.
; #INDIC_STRAIGHTBOX ; A rectangle around the text using translucent drawing With the interior
;                    ; usually more transparent than the border.
;                    ; You can use SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA to control the alpha transparency values.
;                    ; The default alpha values are 30 for fill colour and 50 for outline colour.
; #INDIC_DASH        ; A dashed underline.
; #INDIC_DOTS        ; A dotted underline.
; #INDIC_SQUIGGLELOW ; Similar To INDIC_SQUIGGLE but only using 2 vertical pixels so will fit under small fonts.
; #INDIC_DOTBOX      ; A dotted rectangle around the text using translucent drawing.
;                    ; Translucency alternates between the alpha and outline alpha settings with the top-left pixel
;                    ; using the alpha setting.
;                    ; SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA control the alpha transparency values.
;                    ; The default values are 30 For alpha And 50 For outline alpha.
;                    ; To avoid excessive memory allocation the maximum width of a dotted box is 4000 pixels.
;                    ; Not available For OS X Carbon.

style = #INDIC_BOX

color = RGB($FF,$FF,$00)

InnerAlpha  = 255
BorderAlpha = 255

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



Scintilla = Val( GetEnvironmentVariable("PB_TOOL_Scintilla") )


If Scintilla
    word$    = GetEnvironmentVariable("PB_TOOL_Word")

    SendMessageTimeout_(Scintilla,#SCI_SETINDICATORCURRENT  ,9, 0          ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETSTYLE        ,9, style      ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETFORE         ,9, color      ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETALPHA        ,9, InnerAlpha ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETOUTLINEALPHA ,9, BorderAlpha,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETUNDER        ,9, #False     ,#SMTO_ABORTIFHUNG,2000,@result)
    
    If word$
    
        wordlen = Len(word$)
    
        text$=""
        If ReadFile(0,ProgramParameter(0))
            format = ReadStringFormat(0)
            Repeat
                text$ + ReadString(0,format) + Chr(10) + Chr(13)
            Until Eof(0)
            CloseFile(0)
        EndIf

        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        PostMessage_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length)

        pos = 0

        Repeat
            pos = FindString(text$,word$,pos)
            If pos > 0
                PostMessage_(Scintilla,#SCI_INDICATORFILLRANGE,pos-1,wordlen)
                pos + wordlen
            EndIf
        Until pos = 0
    Else
        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        PostMessage_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length)
    EndIf

EndIf
I am happy with the result. It highlights all occurrences of the current word under cursor when pressing
a hotkey and the highlighting stays now until you highlight another word or nothing.
You can set a color for the highlighting and choose out of 6 different styles (box, underline, squiggle, ..).

Hey, it works and it is better than nothing! ;)
Last edited by Danilo on Thu May 17, 2012 8:00 pm, edited 1 time in total.
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

This is much faster with big sources and it should always be correct. The last code wasn't always correct.

I added the option: #IGNORE_CASE -> set it to #True to ignore case on search.

Code: Select all

CompilerIf #PB_Compiler_Unicode = 0
    CompilerError "Compile with Unicode mode enabled"
CompilerEndIf


#INDIC_STRAIGHTBOX = 8
#INDIC_DASH        = 9
#INDIC_DOTS        = 10
#INDIC_SQUIGGLELOW = 11
#INDIC_DOTBOX      = 12

#SCI_INDICSETALPHA          = 2523
#SCI_INDICSETOUTLINEALPHA   = 2558


;-----------------------------------
; SETUP

; #INDIC_PLAIN       ; Underlined With a single, straight line.
; #INDIC_SQUIGGLE    ; A squiggly underline. Requires 3 pixels of descender space.
; #INDIC_TT          ; A line of small T shapes.
; #INDIC_DIAGONAL    ; Diagonal hatching.
; #INDIC_STRIKE      ; Strike out.
; #INDIC_HIDDEN      ; An indicator With no visual effect.
; #INDIC_BOX         ; A rectangle around the text.
;
; - the following styles don't work with Scintilla used by PB 4.60
; - maybe useful for future versions
;
; #INDIC_ROUNDBOX    ; A rectangle with rounded corners around the text using translucent drawing
;                    ; with the interior usually more transparent than the border.
;                    ; You can use SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA to control the alpha transparency values.
;                    ; The default alpha values are 30 for fill colour and 50 for outline colour.
; #INDIC_STRAIGHTBOX ; A rectangle around the text using translucent drawing With the interior
;                    ; usually more transparent than the border.
;                    ; You can use SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA to control the alpha transparency values.
;                    ; The default alpha values are 30 for fill colour and 50 for outline colour.
; #INDIC_DASH        ; A dashed underline.
; #INDIC_DOTS        ; A dotted underline.
; #INDIC_SQUIGGLELOW ; Similar To INDIC_SQUIGGLE but only using 2 vertical pixels so will fit under small fonts.
; #INDIC_DOTBOX      ; A dotted rectangle around the text using translucent drawing.
;                    ; Translucency alternates between the alpha and outline alpha settings with the top-left pixel
;                    ; using the alpha setting.
;                    ; SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA control the alpha transparency values.
;                    ; The default values are 30 For alpha And 50 For outline alpha.
;                    ; To avoid excessive memory allocation the maximum width of a dotted box is 4000 pixels.
;                    ; Not available For OS X Carbon.

style = #INDIC_BOX

color = RGB($FF,$FF,$00)

InnerAlpha  = 255
BorderAlpha = 255

#IGNORE_CASE = #True

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

NewList positions.i()

Scintilla = Val( GetEnvironmentVariable("PB_TOOL_Scintilla") )


If Scintilla
    word$    = GetEnvironmentVariable("PB_TOOL_Word")

    SendMessageTimeout_(Scintilla,#SCI_SETINDICATORCURRENT  ,9, 0          ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETSTYLE        ,9, style      ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETFORE         ,9, color      ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETALPHA        ,9, InnerAlpha ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETOUTLINEALPHA ,9, BorderAlpha,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETUNDER        ,9, #False      ,#SMTO_ABORTIFHUNG,2000,@result)
    
    If word$
    
        wordlen = Len(word$)

        CompilerIf #IGNORE_CASE
            word$ = LCase(word$)
        CompilerEndIf
    
        text$=""
        If ReadFile(0,ProgramParameter(0))
            format = ReadStringFormat(0)
            line = 0
            Repeat
                text$ = ReadString(0,format)
                CompilerIf #IGNORE_CASE
                    text$ = LCase(text$)
                CompilerEndIf

                pos = 1
                Repeat
                    pos = FindString(text$,word$,pos)
                    If pos
                        If AddElement(positions())
                            SendMessageTimeout_(Scintilla,#SCI_POSITIONFROMLINE,line,0,#SMTO_ABORTIFHUNG,2000,@offset)
                            positions() = offset + pos - 1
                        EndIf
                        pos + wordlen
                    EndIf
                Until pos = 0
                line + 1
            Until Eof(0)
            CloseFile(0)
        EndIf

        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        PostMessage_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length)


        ForEach positions()
            PostMessage_(Scintilla,#SCI_INDICATORFILLRANGE,positions(),wordlen)
        Next
    Else
        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        PostMessage_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length)
    EndIf

EndIf
Last edited by Danilo on Thu May 17, 2012 7:51 pm, edited 2 times in total.
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Tenaja »

Danilo wrote:@Tenaja:
The problem is that we are not in the IDE process, we are outside.
Yes, hence my list of questions in the first post...

Did you try this, instead?
selectedtext = GOSCI_GetSelectedText(ActiveSci)
(which is this, from srod's GOSCI...)

Code: Select all

Procedure.s GOSCI_GetSelectedText(id)
  Protected text$, numBytes, utf8Buffer
  If IsGadget(id) And GadgetType(id) = #PB_GadgetType_Scintilla
    numBytes = ScintillaSendMessage(id, #SCI_GETSELTEXT)
    If numBytes
      utf8Buffer = AllocateMemory(numBytes)
      If utf8Buffer
        ScintillaSendMessage(id, #SCI_GETSELTEXT, 0, utf8Buffer)
        text$ = PeekS(utf8Buffer, -1, #PB_UTF8)
        FreeMemory(utf8Buffer)
      EndIf
    EndIf
  EndIf
  ProcedureReturn text$
EndProcedure
If it doesn't work, you should be able to replace the ScintillaSendMessage command calls with SendMessageTimeout_() commands, I would think...
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

Tenaja wrote:Did you try this, instead?
Yes, just tried it. It does not work, Scintilla from the IDE can not write to our external process,
and utf8buffer is a memory in our process.
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

Danilo wrote:Maybe PureBasic uses an old version of Scintilla, but the style #INDIC_STRAIGHTBOX does not work here.
That's the reason I used the box style, but underlining works too, if you like that more.
- Quit the PureBasic IDE
- rename PB/Compilers/Scintilla.dll to Scintilla_old.dll
- copy SciLexer.DLL (download) to PB/Compilers and rename it to Scintilla.dll

Styles #INDIC_STRAIGHTBOX, #INDIC_ROUNDBOX etc. are available.

Example:

Code: Select all

style = #INDIC_STRAIGHTBOX

color = RGB($00,$FF,$FF)

InnerAlpha  =  50
BorderAlpha = 200
Image
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Tenaja »

Danilo wrote:
Tenaja wrote:Did you try this, instead?
Yes, just tried it. It does not work, Scintilla from the IDE can not write to our external process,
and utf8buffer is a memory in our process.
In this case, itf8buffer is declared as a local integer, and used as a pointer from a call to allocatememory(). That is used as a temporary storage for the text until it can be moved into a pb-friendly string variable.
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

New version with selected text:
- If there is selected text (single line only), the selection is highlighted
- Nothing selected, the word under cursor gets highlighted
- Nothing selected and no word under cursor -> highlighting is cleared

Image

Image

Code: Select all

CompilerIf #PB_Compiler_Unicode = 0
    CompilerError "Compile with Unicode mode enabled"
CompilerEndIf


#INDIC_STRAIGHTBOX = 8
#INDIC_DASH        = 9
#INDIC_DOTS        = 10
#INDIC_SQUIGGLELOW = 11
#INDIC_DOTBOX      = 12

#SCI_INDICSETALPHA          = 2523
#SCI_INDICSETOUTLINEALPHA   = 2558


;-----------------------------------
; SETUP

; #INDIC_PLAIN       ; Underlined With a single, straight line.
; #INDIC_SQUIGGLE    ; A squiggly underline. Requires 3 pixels of descender space.
; #INDIC_TT          ; A line of small T shapes.
; #INDIC_DIAGONAL    ; Diagonal hatching.
; #INDIC_STRIKE      ; Strike out.
; #INDIC_HIDDEN      ; An indicator With no visual effect.
; #INDIC_BOX         ; A rectangle around the text.
;
; - the following styles don't work with Scintilla used by PB 4.60
; - maybe useful for future versions
;
; #INDIC_ROUNDBOX    ; A rectangle with rounded corners around the text using translucent drawing
;                    ; with the interior usually more transparent than the border.
;                    ; You can use SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA to control the alpha transparency values.
;                    ; The default alpha values are 30 for fill colour and 50 for outline colour.
; #INDIC_STRAIGHTBOX ; A rectangle around the text using translucent drawing With the interior
;                    ; usually more transparent than the border.
;                    ; You can use SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA to control the alpha transparency values.
;                    ; The default alpha values are 30 for fill colour and 50 for outline colour.
; #INDIC_DASH        ; A dashed underline.
; #INDIC_DOTS        ; A dotted underline.
; #INDIC_SQUIGGLELOW ; Similar To INDIC_SQUIGGLE but only using 2 vertical pixels so will fit under small fonts.
; #INDIC_DOTBOX      ; A dotted rectangle around the text using translucent drawing.
;                    ; Translucency alternates between the alpha and outline alpha settings with the top-left pixel
;                    ; using the alpha setting.
;                    ; SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA control the alpha transparency values.
;                    ; The default values are 30 For alpha And 50 For outline alpha.
;                    ; To avoid excessive memory allocation the maximum width of a dotted box is 4000 pixels.
;                    ; Not available For OS X Carbon.

style = #INDIC_BOX

color = RGB($00,$FF,$FF)

InnerAlpha  =  50
BorderAlpha = 200

#IGNORE_CASE = #True

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

NewList positions.i()
NewList source.s()

Scintilla = Val( GetEnvironmentVariable("PB_TOOL_Scintilla") )


If Scintilla
    word$    = GetEnvironmentVariable("PB_TOOL_Word")

    SendMessageTimeout_(Scintilla,#SCI_GETSELECTIONSTART,0,0,#SMTO_ABORTIFHUNG,2000,@selectionStart)
    SendMessageTimeout_(Scintilla,#SCI_GETSELECTIONEND  ,0,0,#SMTO_ABORTIFHUNG,2000,@selectionEnd)

    If selectionStart <> selectionEnd
        ;
        ; get informations about the current selection
        ;
        SendMessageTimeout_(Scintilla,#SCI_LINEFROMPOSITION,selectionStart,0,#SMTO_ABORTIFHUNG,2000,@selectionLine)
        SendMessageTimeout_(Scintilla,#SCI_POSITIONFROMLINE,selectionLine ,0,#SMTO_ABORTIFHUNG,2000,@selectionLineStart)
        selectionEnd   - selectionStart
        selectionStart - selectionLineStart
        word$ = "..."
    Else
        ;
        ; no selection
        ;
        selectionLine = -1
    EndIf

    SendMessageTimeout_(Scintilla,#SCI_SETINDICATORCURRENT  ,9, 0          ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETSTYLE        ,9, style      ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETFORE         ,9, color      ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETALPHA        ,9, InnerAlpha ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETOUTLINEALPHA ,9, BorderAlpha,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETUNDER        ,9, #False     ,#SMTO_ABORTIFHUNG,2000,@result)
    
    If word$
    
        line = 0
        If ReadFile(0,ProgramParameter(0))
            format = ReadStringFormat(0)
            Repeat
                If AddElement( source() )
                    source() = ReadString(0,format)
                    If line = selectionLine
                        word$ = Mid( source(), selectionStart+1, selectionEnd )
                    EndIf
                EndIf
                line + 1
            Until Eof(0)
            CloseFile(0)
        EndIf

        wordlen = Len(word$)

        CompilerIf #IGNORE_CASE
            word$ = LCase(word$)
        CompilerEndIf

        line = 0
        ForEach source()
            text$ = source()

            CompilerIf #IGNORE_CASE
                text$ = LCase(text$)
            CompilerEndIf

            pos = 1
            Repeat
                pos = FindString(text$,word$,pos)
                If pos
                    If AddElement(positions())
                        SendMessageTimeout_(Scintilla,#SCI_POSITIONFROMLINE,line,0,#SMTO_ABORTIFHUNG,2000,@offset)
                        positions() = offset + pos - 1
                    EndIf
                    pos + wordlen
                EndIf
            Until pos = 0
            line + 1
        Next

        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        PostMessage_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length)


        ForEach positions()
            PostMessage_(Scintilla,#SCI_INDICATORFILLRANGE,positions(),wordlen)
        Next
    Else
        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        PostMessage_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length)
    EndIf

EndIf
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

This version works in memory only, without using %TEMPFILE, but it requires the new Scintilla.dll (renamed SciLexer.dll)
because it uses #SCI_GETCHARACTERPOINTER.

Code: Select all

CompilerIf #PB_Compiler_Unicode = 0
    CompilerError "Compile with Unicode mode enabled"
CompilerEndIf


#INDIC_STRAIGHTBOX = 8
#INDIC_DASH        = 9
#INDIC_DOTS        = 10
#INDIC_SQUIGGLELOW = 11
#INDIC_DOTBOX      = 12

#SCI_INDICSETALPHA          = 2523
#SCI_INDICSETOUTLINEALPHA   = 2558


;-----------------------------------
; SETUP

; #INDIC_PLAIN       ; Underlined With a single, straight line.
; #INDIC_SQUIGGLE    ; A squiggly underline. Requires 3 pixels of descender space.
; #INDIC_TT          ; A line of small T shapes.
; #INDIC_DIAGONAL    ; Diagonal hatching.
; #INDIC_STRIKE      ; Strike out.
; #INDIC_HIDDEN      ; An indicator With no visual effect.
; #INDIC_BOX         ; A rectangle around the text.
;
; - the following styles don't work with Scintilla used by PB 4.60
; - maybe useful for future versions
;
; #INDIC_ROUNDBOX    ; A rectangle with rounded corners around the text using translucent drawing
;                    ; with the interior usually more transparent than the border.
;                    ; You can use SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA to control the alpha transparency values.
;                    ; The default alpha values are 30 for fill colour and 50 for outline colour.
; #INDIC_STRAIGHTBOX ; A rectangle around the text using translucent drawing With the interior
;                    ; usually more transparent than the border.
;                    ; You can use SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA to control the alpha transparency values.
;                    ; The default alpha values are 30 for fill colour and 50 for outline colour.
; #INDIC_DASH        ; A dashed underline.
; #INDIC_DOTS        ; A dotted underline.
; #INDIC_SQUIGGLELOW ; Similar To INDIC_SQUIGGLE but only using 2 vertical pixels so will fit under small fonts.
; #INDIC_DOTBOX      ; A dotted rectangle around the text using translucent drawing.
;                    ; Translucency alternates between the alpha and outline alpha settings with the top-left pixel
;                    ; using the alpha setting.
;                    ; SCI_INDICSETALPHA And SCI_INDICSETOUTLINEALPHA control the alpha transparency values.
;                    ; The default values are 30 For alpha And 50 For outline alpha.
;                    ; To avoid excessive memory allocation the maximum width of a dotted box is 4000 pixels.
;                    ; Not available For OS X Carbon.

style = #INDIC_STRAIGHTBOX

color = RGB($00,$FF,$FF)

InnerAlpha  =  50
BorderAlpha = 200

#IGNORE_CASE = #True

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

NewList positions.i()
NewList source.s()

Global Scintilla = Val( GetEnvironmentVariable("PB_TOOL_Scintilla") )
Global numBytes, utf8Buffer

If Scintilla

    SendMessageTimeout_(Scintilla,#SCI_GETSELECTIONSTART,0,0,#SMTO_ABORTIFHUNG,2000,@selectionStart)
    SendMessageTimeout_(Scintilla,#SCI_GETSELECTIONEND  ,0,0,#SMTO_ABORTIFHUNG,2000,@selectionEnd)
    
    If selectionStart <> selectionEnd
        word$=""
        For i = selectionStart To selectionEnd-1
            SendMessageTimeout_(Scintilla,#SCI_GETCHARAT,i,0,#SMTO_ABORTIFHUNG,2000,@result)
            word$ + Chr(result)
        Next i
    Else
        word$    = GetEnvironmentVariable("PB_TOOL_Word")
    EndIf

    SendMessageTimeout_(Scintilla,#SCI_SETINDICATORCURRENT  ,9, 0          ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETSTYLE        ,9, style      ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETFORE         ,9, color      ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETALPHA        ,9, InnerAlpha ,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETOUTLINEALPHA ,9, BorderAlpha,#SMTO_ABORTIFHUNG,2000,@result)
    SendMessageTimeout_(Scintilla,#SCI_INDICSETUNDER        ,9, #False     ,#SMTO_ABORTIFHUNG,2000,@result)

    If word$
        wordlen = Len(word$)

        CompilerIf #IGNORE_CASE
            word$ = LCase(word$)
        CompilerEndIf

        #SCI_GETCHARACTERPOINTER = 2520
    
        SendMessageTimeout_(Scintilla,#SCI_SETREADONLY,1,0,#SMTO_ABORTIFHUNG,2000,@result)
        SendMessageTimeout_(Scintilla,#SCI_GETCHARACTERPOINTER,0,0,#SMTO_ABORTIFHUNG,2000,@result)
        If result
            SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH,0,0,#SMTO_ABORTIFHUNG,2000,@length)
            memory = AllocateMemory(length+2)

            If Not memory
                SendMessageTimeout_(Scintilla,#SCI_SETREADONLY,0,0,#SMTO_ABORTIFHUNG,2000,@result)
                End
            EndIf

            GetWindowThreadProcessId_(Scintilla, @processId)
            hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, processId)
            ReadProcessMemory_(hProcess,result,memory,length,0)

            *p.Ascii = memory
            length = memory + length

            While *p < length And *p\a
                If *p\a = 10                     ; remove chr(10) + chr(13)
                   *p+1
                   If *p\a = 13 : *p+1 : EndIf
                ElseIf *p\a = 13                 ; remove chr(13) + chr(10)
                   *p+1
                   If *p\a = 10 : *p+1 : EndIf
                   line+1
                Else                             ; read line
                   offset = *p - memory
                   text$ = ""
                   While *p\a And *p\a <> 10 And *p\a <> 13
                       text$ + Chr(*p\a)
                       *p+1
                   Wend
                   If text$
                        CompilerIf #IGNORE_CASE
                            text$ = LCase(text$)
                        CompilerEndIf
                        pos = 1
                        Repeat
                            pos = FindString(text$,word$,pos)
                            If pos
                                If AddElement(positions())
                                    positions() = offset + pos - 1
                                EndIf
                                pos + wordlen
                            EndIf
                        Until pos = 0
                        line + 1
                   EndIf
                EndIf
            Wend
        EndIf

        SendMessageTimeout_(Scintilla,#SCI_SETREADONLY,0,0,#SMTO_ABORTIFHUNG,2000,@result)

        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        PostMessage_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length)


        ForEach positions()
            PostMessage_(Scintilla,#SCI_INDICATORFILLRANGE,positions(),wordlen)
        Next
    Else
        SendMessageTimeout_(Scintilla,#SCI_GETTEXTLENGTH ,0,0,#SMTO_ABORTIFHUNG,2000,@length)
        PostMessage_(Scintilla,#SCI_INDICATORCLEARRANGE,0,length)
    EndIf

EndIf
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PB IDE Smart Highlight (showing selected text) implement

Post by Danilo »

Scintilla.dll and SciLexer.dll binaries for 32bit and 64bit, compiled with latest Intel C++
and Microsoft VC++ 2010: Scintilla310.zip (3.40MB)

Just replace the PureBasic\Compilers\Scintilla.dll with a Scintilla.dll from the file above,
just choose the right version (32/64bit).

The last in-memory highlighting code works with this Scintilla.dll versions.
Post Reply