Tab, and indenting code

Share your advanced PureBasic knowledge/code with the community.
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Tab, and indenting code

Post by dobro »

the example code used here to load a file PB
then see the result in the debugger

do not forget that here are True tabs Tabs (Chr (9)) so it may seem impressive
in the debugger, but in a Scintilla editor or another, we can easily adjust the size of the Tabs

this procedure is rather made to work with an editor (a real, not the debugger) :)

improvement of indentations Select Cases, and alignment with the IF Else
I would also account decrements being on the same line
eg If xxxx: endif // For the ixxxx: next etc ...

I tested on well-twisted codes, it works fine

Code: Select all

Declare.S  tabulation(txt.S)
Global NewMap decrement.S()

decrement.S("endenumeration")="endenumeration"
decrement.S("endstructure")="endstructure"
decrement.S( "endprocedure")="endprocedure"
decrement.S( "enddatasection")="enddatasection"
decrement.S( "endselect")="endselect"
decrement.S( "stopdrawing")="stopdrawing"
decrement.S( "endinterface")="endinterface"
decrement.S( "endstructure")="endstructure"
decrement.S( "endimport")= "endimport"
decrement.S( "endmacro")= "endmacro"
decrement.S( "endwith")="endwith"
decrement.S( "endstructureunion")="endstructureunion"
decrement.S("stop3d")="stop3d"
decrement.S("compilerendif")="compilerendif"
decrement.S("compilerendselect")="compilerendselect"
decrement.S("endmodule")="endmodule"
decrement.S("enddeclaremodule")="enddeclaremodule"
decrement.S("closefile")="closefile"
decrement.S("next")="next"
decrement.S("until")="until"
decrement.S("forever")="forever"
decrement.S("wend")="wend"
decrement.S( "endif")="endif"
; *******************************************
; attention l'ordre des termes a son importance
Global NewMap increment.S()
increment.S( "enumeration")="enumeration"
increment.S( "datasection")="datasection"
increment.S( "startdrawing")=  "startdrawing"
increment.S( "structure")= "structure"
increment.S( "proceduredll")= "proceduredll"
increment.S( "procedurecdll")= "procedurecdll"
increment.S( "procedurec")="procedurec"
increment.S( "procedure")= "procedure"
increment.S( "importc")= "importc"
increment.S( "import")= "import"
increment.S( "macro")="macro"
increment.S( "interface")= "interface"
increment.S( "structureunion")= "structureunion"
increment.S("start3d")="start3d"
increment.S("compilerif")="compilerif"
increment.S("compilerselect")="compilerselect"
increment.S("module")="module"
increment.S("declaremodule")="declaremodule"
increment.S( "with")= "with"
increment.S( "select")= "select"
increment.S("openfile")="openfile"
increment.S("readfile")="readfile"
increment.S("createfile")="createfile"
increment.S( "foreach")="foreach"
increment.S( "for")="for"
increment.S( "repeat")="repeat"
increment.S( "while")="while"
increment.S( "if")="if"
increment.S("case")="case"
local.S=GetCurrentDirectory()
file.S=OpenFileRequester("ouvrir code",local.S,"*.pb",1)
Global NewList code.S()
if OpenFile(0,file.S)
      While Eof(0) = 0           ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
         line.S=ReadString(0)
         a$=LTrim(line.S,Chr(9))
         a$=LTrim(a$)
         AddElement(code.S())
         code.S()=a$
      Wend
   CloseFile(0)
Endif
Global Compteur_tab=0
ForEach code.S()
   txt.S=code.S()
   Debug tabulation(txt.S)
Next

Procedure.S tabulation(txt.S)
   ; procedure de tabulation by Dobro (plus court tu meurts !! )
   
   extrait.S=LCase(StringField(txt.S,1,":")) ; recup avant multipligne
   ;  extrait.S=StringField(extrait.S,1,";"); recupe avant commentaire : ceci ne tabule pas les comentaires ... c'est un choix
   extrait.S=StringField(extrait.S,1," "); recupe premier mot
   extrait.S=StringField(extrait.S,1,"("); pour les fonctions
   extrait.S=StringField(extrait.S,1,"."); pour les fonctions (typée)
   extrait.S=LCase(Trim(extrait.S))
   ; If extrait.S="" :Goto su :EndIf ; saute les lignes vides
   tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour l'increment se fait dans un deuxieme appel
   ; -- Else
   If extrait.S="else" Or extrait.S="elseif" Or extrait.S="case"
      mem_Compteur_tab=Compteur_tab
      Compteur_tab=Compteur_tab-1
      tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour un decrement, c'est tout de suite
      Compteur_tab=mem_Compteur_tab
      Goto su
   EndIf
   
   ;++++ increment
   If extrait.S= increment.S(extrait.S)  And extrait.S<>""
      ; regarde si un decrement se trouve sur la meme ligne qu'un increment , dans ce cas on tabule en arriere puis on remet la valeur de tabulation
      extrait2.S=StringField(txt.S,1,";")
      ForEach decrement.S()
         pooo=FindString(extrait2.S,decrement.S(),Len(extrait.S),#PB_String_NoCase)
         If pooo>0                     
            If Asc(Mid( extrait2.S,pooo+Len(decrement.S()),1))<33               
               Goto su
            Else
               Break
            EndIf
         EndIf
      Next
      
      ; regarde si un increment se trouve sur la meme ligne qu'un increment dans ce cas on ajoute une tabulation
      extrait2.S=StringField(txt.S,1,"(") :extrait2.S=StringField(extrait2.S,1,"."):extrait2.S=StringField(extrait2.S,1,":")
      ForEach increment.S()
         ;If FindString(extrait2.S,increment.S(),Len(extrait.S),#PB_String_NoCase)>0
         pooo=FindString(extrait2.S,increment.S(),Len(extrait.S),#PB_String_NoCase) ; on a trouvé un semblant d'increment
         If pooo>0                        
            If Asc(Mid( extrait2.S,pooo+Len(increment.S()),1))<33   ; on regarde le caractere suivant, si inf a 33 c'est vrais c'est un increment
               Compteur_tab=Compteur_tab+1
               Break
            EndIf
            EndIf   
         Next
         ;
         Compteur_tab=Compteur_tab+1
         Goto su
      EndIf
      ;----- decrement
      If extrait.S= decrement.S(extrait.S) And  extrait.S<>""
         Compteur_tab=Compteur_tab-1
         tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour un decrement, c'est tout de suite
         Goto su
      EndIf
      su:
      If Compteur_tab<=0:Compteur_tab=0
         tab.S=""
      EndIf
      txt.S=tab.S+txt.S;+"("+str(compteur_tab)+")"
      ProcedureReturn txt.S   
   EndProcedure
Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Re: Tab, and indenting code

Post by dobro »

Here is the code with an editor Gadget:
This code was tabbed with himself :)

Code: Select all

;{- Enumerations / DataSections
Declare  openwindow_win()
Declare.s tabulation(txt.s)
Global NewMap decrement.S()
decrement.S("endenumeration")="endenumeration"
decrement.S("endstructure")="endstructure"
decrement.S( "endprocedure")="endprocedure"
decrement.S( "enddatasection")="enddatasection"
decrement.S( "endselect")="endselect"
decrement.S( "stopdrawing")="stopdrawing"
decrement.S( "endinterface")="endinterface"
decrement.S( "endstructure")="endstructure"
decrement.S( "endimport")= "endimport"
decrement.S( "endmacro")= "endmacro"
decrement.S( "endwith")="endwith"
decrement.S( "endstructureunion")="endstructureunion"
decrement.S("stop3d")="stop3d"
decrement.S("compilerendif")="compilerendif"
decrement.S("compilerendselect")="compilerendselect"
decrement.S("endmodule")="endmodule"
decrement.S("enddeclaremodule")="enddeclaremodule"
decrement.S("closefile")="closefile"
decrement.S("next")="next"
decrement.S("until")="until"
decrement.S("forever")="forever"
decrement.S("wend")="wend"
decrement.S( "endif")="endif"
; *******************************************
; attention l'ordre des termes a son importance
Global NewMap increment.S()
increment.S( "enumeration")="enumeration"
increment.S( "datasection")="datasection"
increment.S( "startdrawing")=  "startdrawing"
increment.S( "structure")= "structure"
increment.S( "proceduredll")= "proceduredll"
increment.S( "procedurecdll")= "procedurecdll"
increment.S( "procedurec")="procedurec"
increment.S( "procedure")= "procedure"
increment.S( "importc")= "importc"
increment.S( "import")= "import"
increment.S( "macro")="macro"
increment.S( "interface")= "interface"
increment.S( "structureunion")= "structureunion"
increment.S("start3d")="start3d"
increment.S("compilerif")="compilerif"
increment.S("compilerselect")="compilerselect"
increment.S("module")="module"
increment.S("declaremodule")="declaremodule"
increment.S( "with")= "with"
increment.S( "select")= "select"
increment.S("openfile")="openfile"
increment.S("readfile")="readfile"
increment.S("createfile")="createfile"
increment.S( "foreach")="foreach"
increment.S( "for")="for"
increment.S( "repeat")="repeat"
increment.S( "while")="while"
increment.S( "if")="if"
increment.S("case")="case"

;{ Windows
Enumeration
   #Win
EndEnumeration
;}
;{ Gadgets
Enumeration
   #Button_Load
   #Text_titre
   #Editor
EndEnumeration
;}
;{ Fonts
Enumeration
   #Font_Text_titre
EndEnumeration
;}
Define.l Event
;}
Procedure OpenWindow_Win()
   If OpenWindow(#Win, 405, 47, 720, 597, "Exemple indentation", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
      ButtonGadget(#Button_Load, 20, 20, 90, 35, "Load *.Pb")
      TextGadget(#Text_titre, 205, 15, 255, 40, "Exemple Tabulation")
      EditorGadget(#Editor, 25, 80, 680, 500)
      ; Gadget Fonts
      SetGadgetFont(#Text_titre, LoadFont(#Font_Text_titre, "Microsoft Sans Serif", 20, #PB_Font_HighQuality))
      
   EndIf
EndProcedure

OpenWindow_Win()

;{- Event loop
Repeat
   Event = WaitWindowEvent(12)
   Select Event
      ; ///////////////////
   Case #PB_Event_Gadget
      Select EventGadget()
      Case #Button_Load
         local.S=GetCurrentDirectory()
         file.S=OpenFileRequester("ouvrir code",local.S,"*.pb",1)
         Global NewList code.S()
         OpenFile(0,file.S)
            While Eof(0) = 0           ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
               line.S=ReadString(0)
               a$=LTrim(line.S,Chr(9))
               a$=LTrim(a$)
               AddElement(code.S())
               code.S()=a$
            Wend
         CloseFile(0)
         ; Tabulation au chargement
         Global Compteur_tab=0
         ForEach code.S()
            txt.S=code.S()
            AddGadgetItem(#editor, -1, tabulation(txt.S) ) ; ajoute chaque ligne tabulées
         Next
      Case #Text_titre
      Case #Editor
      EndSelect
      ; ////////////////////////
   Case #PB_Event_CloseWindow
      Select EventWindow()
      Case #Win
         CloseWindow(#Win)
         Break
      EndSelect
   EndSelect
Forever

;-Zone Procedures
Procedure.S tabulation(txt.S)
   ; procedure de tabulation by Dobro (plus court tu meurts !! )
   
   extrait.S=LCase(StringField(txt.S,1,":")) ; recup avant multipligne
   ;  extrait.S=StringField(extrait.S,1,";"); recupe avant commentaire : ceci ne tabule pas les comentaires ... c'est un choix
   extrait.S=StringField(extrait.S,1," "); recupe premier mot
   extrait.S=StringField(extrait.S,1,"("); pour les fonctions
   extrait.S=StringField(extrait.S,1,"."); pour les fonctions (typée)
   extrait.S=LCase(Trim(extrait.S))
   ; If extrait.S="" :Goto su :EndIf ; saute les lignes vides
   tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour l'increment se fait dans un deuxieme appel
   ; -- Else
   If extrait.S="else" Or extrait.S="elseif" Or extrait.S="case"
      mem_Compteur_tab=Compteur_tab
      Compteur_tab=Compteur_tab-1
      tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour un decrement, c'est tout de suite
      Compteur_tab=mem_Compteur_tab
      Goto su
   EndIf
   
   ;++++ increment
   If extrait.S= increment.S(extrait.S)  And extrait.S<>""
      ; regarde si un decrement se trouve sur la meme ligne qu'un increment , dans ce cas on tabule en arriere puis on remet la valeur de tabulation
      extrait2.S=StringField(txt.S,1,";")
      ForEach decrement.S()
         pooo=FindString(extrait2.S,decrement.S(),Len(extrait.S),#PB_String_NoCase)
         If pooo>0                     
            If Asc(Mid( extrait2.S,pooo+Len(decrement.S()),1))<33               
               Goto su
            Else
               Break
            EndIf
         EndIf
      Next
      
      ; regarde si un increment se trouve sur la meme ligne qu'un increment dans ce cas on ajoute une tabulation
      extrait2.S=StringField(txt.S,1,"(") :extrait2.S=StringField(extrait2.S,1,"."):extrait2.S=StringField(extrait2.S,1,":")
      ForEach increment.S()
         ;If FindString(extrait2.S,increment.S(),Len(extrait.S),#PB_String_NoCase)>0
         pooo=FindString(extrait2.S,increment.S(),Len(extrait.S),#PB_String_NoCase) ; on a trouvé un semblant d'increment
         If pooo>0
            If Asc(Mid( extrait2.S,pooo+Len(increment.S()),1))<33; on regarde le caractere suivant, si inf a 33 c'est vrais c'est un increment
               Compteur_tab=Compteur_tab+1
               Break
            EndIf
         EndIf
      Next
      ;
      Compteur_tab=Compteur_tab+1
      Goto su
   EndIf
   ;----- decrement
   If extrait.S= decrement.S(extrait.S) And  extrait.S<>""
      Compteur_tab=Compteur_tab-1
      tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour un decrement, c'est tout de suite
      Goto su
   EndIf
   su:
   If Compteur_tab<=0:Compteur_tab=0
      tab.S=""
   EndIf
   txt.S=tab.S+txt.S;+"("+str(compteur_tab)+")"
   ProcedureReturn txt.S
EndProcedure

;
;}


;Epb

Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Re: Tab, and indenting code

Post by dobro »

and a Scintilla editor + coloration Purebasic Code in stride

to get an idea, know that all these codes have been formatted with this Procedure :)

you will have to paste a no indenting code into it , and Press Ctrl+Tab ;)

Code: Select all

;***********************************************
;Titre  :*exemple scintilla_tabulation_modify by Dobro
;Auteur  : Dobro

;Date  :27/03/2016
;Heure  :16:38:51
;Version Purebasic :  PureBasic 5.42 LTS (Windows - x86)
;Version de l'editeur :EPB V2.62
; Libairies necessaire : Aucune  (tout est inclu dans les procedures a l'interieur du code
;***********************************************

; infos :
;tabulation avec Ctrl+Tab
; c'est juste un editeur , faut integrer la compilation en ligne de commande , je ne l'ai volontairement pas ajouté


; la procedure d'appel de tout l'ensemble c'est la procedure : CreatePBSourceView()
; toutes les autres procedures sont appelées par CreatePBSourceView() ;o) 
; pour ne pas réinventer la roue, j'ai inclu quelques fonctions de la librairie Gosci 
; dont une faite par mes soins (j'utilise une version personelle de cette librairie pour EPB )

; dans l'absolu, il suffit d'ajouter:
; un module de parametrage des couleurs
; un module de sauvegarde/chargement du code
; un module de compilation

; pour avoir un editeur "Maison" :o) 
; je n'ai pas fait de gestion de completion, voir les exemples de Falsam



Define.S HighLightDLLPath = #PB_Compiler_Home + "SDK\Syntax Highlighting\SyntaxHilighting.dll" ; ne pas toucher

If OpenLibrary(0, HighLightDLLPath) = #False : Debug "HL-DLL nicht gefunden" :End:EndIf
If InitScintilla("scintilla.dll") = #False : Debug "Scintilla-DLL nicht gefunden" :	End :EndIf

Prototype SyntaxHighlight(*Buffer, len.L, callback.L, asm.L)
Global SyntaxHighlight.SyntaxHighlight = GetFunction(0, "SyntaxHighlight")

Enumeration ; Win
	#win
EndEnumeration
Enumeration ; Gadgets
	#SciID
	#SciID2
	#Splitter
	#ctrl_Tab
EndEnumeration

Enumeration ; Syntax
	#SYNTAX_Text
	#SYNTAX_Keyword
	#SYNTAX_Comment
	#SYNTAX_Constant
	#SYNTAX_String
	#SYNTAX_Function
	#SYNTAX_Asm
	#SYNTAX_Operator
	#SYNTAX_Structure
	#SYNTAX_Number
	#SYNTAX_Pointer
	#SYNTAX_Separator
	#SYNTAX_Label
EndEnumeration


Define.L start_pos, Buffer, editor

Declare  GOSCI_Setcurs(id, color,taille)
Declare  GOSCI_Get_number_line(id)
Declare  GOSCI_Clear(id)
Declare  GOSCI_SetText(id, text$, clearUndoStack=#False)
Declare  GOSCI_SetLineText(id, lineIndex, text$)
Declare.S GOSCI_GetLineText(id, lineIndex)
Declare.S GOSCI_GetText(id)
Declare  GOSCI_SetTabs(id, width, blnUseSoftTabs = #False)
Declare.S tab(txt.S)
Declare  tabulation(editor)
Declare.S getspecialfolder(csidl.L)
Declare  shcallback(pos, len, id)
Declare  scintillacallback(editorgadget.L, *scinotity.SCNotification)
Declare  createpbsourceview()


;{
; attention l'ordre des termes a son importance 
Global NewMap decrement.S()


decrement.S("endenumeration")="endenumeration"
decrement.S("endstructure")="endstructure"
decrement.S( "endprocedure")="endprocedure"
decrement.S( "enddatasection")="enddatasection"
decrement.S( "endselect")="endselect"
decrement.S( "stopdrawing")="stopdrawing"
decrement.S( "endinterface")="endinterface"
decrement.S( "endstructure")="endstructure"
decrement.S( "endimport")= "endimport"
decrement.S( "endmacro")= "endmacro"
decrement.S( "endwith")="endwith"
decrement.S( "endstructureunion")="endstructureunion"
decrement.S("stop3d")="stop3d"
decrement.S("compilerendif")="compilerendif"
decrement.S("compilerendselect")="compilerendselect"
decrement.S("endmodule")="endmodule"
decrement.S("enddeclaremodule")="enddeclaremodule"
decrement.S("closefile")="closefile"
decrement.S("next")="next"
decrement.S("until")="until"
decrement.S("forever")="forever"
decrement.S("wend")="wend"
decrement.S( "endif")="endif"

; *******************************************
; attention l'ordre des termes a son importance 
Global NewMap increment.S()
increment.S( "enumeration")="enumeration"
increment.S( "datasection")="datasection"
increment.S( "startdrawing")=  "startdrawing"
increment.S( "structure")= "structure"
increment.S( "proceduredll")= "proceduredll"
increment.S( "procedurecdll")= "procedurecdll"
increment.S( "procedurec")="procedurec"
increment.S( "procedure")= "procedure"
increment.S( "importc")= "importc"
increment.S( "import")= "import"
increment.S( "macro")="macro"
increment.S( "interface")= "interface"
increment.S( "structureunion")= "structureunion"
increment.S("start3d")="start3d"
increment.S("compilerif")="compilerif"
increment.S("compilerselect")="compilerselect"
increment.S("module")="module"
increment.S("declaremodule")="declaremodule"
increment.S( "with")= "with"
increment.S( "select")= "select"
increment.S("openfile")="openfile"
increment.S("readfile")="readfile"
increment.S("createfile")="createfile"
increment.S( "foreach")="foreach"
increment.S( "for")="for"
increment.S( "repeat")="repeat"
increment.S( "while")="while"
increment.S( "if")="if"
increment.S("case")="case"

;


;}

;- boucle principale

If createpbsourceview()
	HideWindow(#win, #False)
	Repeat
		Select WaitWindowEvent()
		Case #PB_Event_Menu
			Select EventMenu()
			Case #ctrl_Tab
				Global Compteur_tab=0
				tabulation(#SciID2)
			EndSelect
		Case #PB_Event_CloseWindow : Break
		Case #PB_Event_SizeWindow
			ResizeGadget(#Splitter, #PB_Ignore, #PB_Ignore, WindowWidth(#win), WindowHeight(#win))
		EndSelect
	ForEver 
EndIf


;-Zone Procedure

ProcedureDLL GOSCI_Setcurs(id, color,taille)
	; by dobro Taille et couleur du curseur
	ScintillaSendMessage(id, #SCI_SETCARETFORE, color)
	ScintillaSendMessage(id,#SCI_SETCARETWIDTH,taille,0); Largeur du curseur
EndProcedure
ProcedureDLL GOSCI_Get_number_line(id)
	; retourne le nombre de lignes dans l'editeur id
	; return a number line of Editor
	ProcedureReturn ScintillaSendMessage(id, #SCI_GETLINECOUNT)
EndProcedure
ProcedureDLL GOSCI_Clear(id)
	If IsGadget(id) And GadgetType(id) = #PB_GadgetType_Scintilla
		If ScintillaSendMessage(id, #SCI_GETREADONLY) = 0
			ScintillaSendMessage(id, #SCI_CLEARALL)
		EndIf
	EndIf
EndProcedure
ProcedureDLL GOSCI_SetText(id, text$, clearUndoStack=#False)
	Protected utf8Buffer
	If IsGadget(id) And GadgetType(id) = #PB_GadgetType_Scintilla
		;Need to convert to utf-8 first.
		utf8Buffer = AllocateMemory(StringByteLength(text$, #PB_UTF8)+1)
		If utf8Buffer 
			PokeS(utf8Buffer, text$, -1, #PB_UTF8)
			ScintillaSendMessage(id, #SCI_SETTEXT, 0, utf8Buffer)
			FreeMemory(utf8Buffer)
			If clearUndoStack
				ScintillaSendMessage(id, #SCI_EMPTYUNDOBUFFER)
			EndIf
			;;       GOSCI_RestyleLinesXXX(id, 0, -1)  ; source de lenteur !!
		EndIf
	EndIf
EndProcedure
ProcedureDLL GOSCI_SetLineText(id, lineIndex, text$)
	Protected numLines, lineLength, startPos, EndPos, Char.a, utf8Buffer
	If IsGadget(id) And GadgetType(id) = #PB_GadgetType_Scintilla
		numLines = ScintillaSendMessage(id, #SCI_GETLINECOUNT)
		If lineIndex >=0 And lineIndex < numLines
			;Remove all EOL characters.
			text$ = RemoveString(text$, #LF$)
			text$ = RemoveString(text$, #CR$)
			;Find the beginning and the end of the text to replace.
			lineLength = ScintillaSendMessage(id, #SCI_LINELENGTH, lineIndex)
			startPos = ScintillaSendMessage(id, #SCI_POSITIONFROMLINE, lineIndex)
			EndPos = startPos + lineLength
			;We ignore any EOL characters.
			EndPos - 1
			Char = ScintillaSendMessage(id, #SCI_GETCHARAT, EndPos)
			While (Char = 10 Or Char = 13) And EndPos >= startPos
				EndPos-1
				Char = ScintillaSendMessage(id, #SCI_GETCHARAT, EndPos)
			Wend
			EndPos + 1
			;Need to convert text to utf-8 first.
			utf8Buffer = AllocateMemory(StringByteLength(text$, #PB_UTF8)+1)
			If utf8Buffer 
				PokeS(utf8Buffer, text$, -1, #PB_UTF8)
				ScintillaSendMessage(id, #SCI_SETTARGETSTART, startPos)
				ScintillaSendMessage(id, #SCI_SETTARGETEND, EndPos)
				ScintillaSendMessage(id, #SCI_REPLACETARGET, -1, utf8Buffer)
				FreeMemory(utf8Buffer)
				; GOSCI_RestyleLinesXXX(id, lineIndex, lineIndex)  
			EndIf
		EndIf
	EndIf
EndProcedure
ProcedureDLL.S GOSCI_GetLineText(id, lineIndex)
	Protected text$, numLines, lineLength, utf8Buffer, *ptrAscii.ASCII
	If IsGadget(id) And GadgetType(id) = #PB_GadgetType_Scintilla
		numLines = ScintillaSendMessage(id, #SCI_GETLINECOUNT)
		If lineIndex >=0 And lineIndex < numLines
			lineLength = ScintillaSendMessage(id, #SCI_LINELENGTH, lineIndex)
			If lineLength
				utf8Buffer = AllocateMemory(lineLength+1)
				If utf8Buffer
					ScintillaSendMessage(id, #SCI_GETLINE, lineIndex, utf8Buffer)
					;Remove any terminating EOL characters.
					*ptrAscii = utf8Buffer + lineLength - 1
					While (*ptrAscii\a = 10 Or *ptrAscii\a = 13) And lineLength
						lineLength - 1
						*ptrAscii - 1
					Wend
					text$ = PeekS(utf8Buffer, lineLength, #PB_UTF8)
					FreeMemory(utf8Buffer)
				EndIf
			EndIf
		EndIf
	EndIf
	ProcedureReturn text$
EndProcedure
ProcedureDLL.S GOSCI_GetText(id)
	Protected text$, utf8Buffer, numBytes
	If IsGadget(id) And GadgetType(id) = #PB_GadgetType_Scintilla
		numBytes = ScintillaSendMessage(id, #SCI_GETLENGTH)
		If numBytes
			utf8Buffer = AllocateMemory(numBytes+1)
			If utf8Buffer 
				ScintillaSendMessage(id, #SCI_GETTEXT, numBytes + 1, utf8Buffer)
				text$ = PeekS(utf8Buffer, -1, #PB_UTF8)
				FreeMemory(utf8Buffer)
			EndIf
		EndIf
	EndIf
	ProcedureReturn text$
EndProcedure
ProcedureDLL GOSCI_SetTabs(id, width, blnUseSoftTabs = #False)
	If IsGadget(id) And GadgetType(id) = #PB_GadgetType_Scintilla
		ScintillaSendMessage(id, #SCI_SETTABWIDTH, width)
		ScintillaSendMessage(id, #SCI_SETUSETABS, 1-blnUseSoftTabs)
	EndIf
EndProcedure


Procedure.S tab(txt.S)
	; procedure de tabulation by Dobro (plus court tu meurts !! )
	
	extrait.S=LCase(StringField(txt.S,1,":")) ; recup avant multipligne
	;  extrait.S=StringField(extrait.S,1,";"); recupe avant commentaire : ceci ne tabule pas les comentaires ... c'est un choix
	extrait.S=StringField(extrait.S,1," "); recupe premier mot
	extrait.S=StringField(extrait.S,1,"("); pour les fonctions
	extrait.S=StringField(extrait.S,1,"."); pour les fonctions (typée)
	extrait.S=LCase(Trim(extrait.S))
	
	; If extrait.S="" :Goto su :EndIf ; saute les lignes vides
	tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour l'increment se fait dans un deuxieme appel
	; -- Else
	If extrait.S="else" Or extrait.S="elseif" Or extrait.S="case"
		mem_Compteur_tab=Compteur_tab
		Compteur_tab=Compteur_tab-1
		tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour un decrement, c'est tout de suite
		Compteur_tab=mem_Compteur_tab
		Goto su
	EndIf
	
	
	;++++ increment
	If extrait.S= increment.S(extrait.S)  And extrait.S<>""
		; regarde si un decrement se trouve sur la meme ligne qu'un increment , dans ce cas on tabule en arriere puis on remet la valeur de tabulation
		extrait2.S=StringField(txt.S,1,";")
		ForEach decrement.S()
			pooo=FindString(extrait2.S,decrement.S(),Len(extrait.S),#PB_String_NoCase)
			If pooo>0							
				If Asc(Mid( extrait2.S,pooo+Len(decrement.S()),1))<33					
					Goto su
				Else
					Break
				EndIf
			EndIf
		Next
		
		
		
		; regarde si un increment se trouve sur la meme ligne qu'un increment dans ce cas on ajoute une tabulation
		extrait2.S=StringField(txt.S,1,"(") :extrait2.S=StringField(extrait2.S,1,"."):extrait2.S=StringField(extrait2.S,1,":")
		ForEach increment.S()
			;If FindString(extrait2.S,increment.S(),Len(extrait.S),#PB_String_NoCase)>0
			pooo=FindString(extrait2.S,increment.S(),Len(extrait.S),#PB_String_NoCase) ; on a trouvé un semblant d'increment
			If pooo>0								
				If Asc(Mid( extrait2.S,pooo+Len(increment.S()),1))<33	; on regarde le caractere suivant, si inf a 33 c'est vrais c'est un increment
					Compteur_tab=Compteur_tab+1
					Break
				EndIf
				EndIf	
				
			Next
			;
			Compteur_tab=Compteur_tab+1
			Goto su
		EndIf
		
		;----- decrement
		If extrait.S= decrement.S(extrait.S) And  extrait.S<>""
			Compteur_tab=Compteur_tab-1
			tab.S=LSet(tab.S,Compteur_tab,Chr(9)) ; pour un decrement, c'est tout de suite
			Goto su
		EndIf
		su:
		If Compteur_tab<=0:Compteur_tab=0
			tab.S=""
		EndIf
		txt.S=tab.S+txt.S;+"("+str(compteur_tab)+")"
		ProcedureReturn txt.S	
	EndProcedure
	
	
	Procedure tabulation(editor)
		;By Dobro
		; base pour tabulation avec Contrl+Tab
		;nombre_ligne=CountGadgetItems(editor)
		nombre_ligne=GOSCI_Get_number_line(editor)
		
		For lin=0 To nombre_ligne 
			ligne$=GetGadgetItemText(editor, lin); recup la ligne en cours
			ligne$=Trim(GOSCI_GetLineText(editor,lin) ,Chr(9)); recup la ligne
			ligne$=tab(ligne$) ; tabule la ligne
			GOSCI_SetLineText(editor,lin,ligne$) ; pose la ligne
		Next lin
	EndProcedure
	
	
	Procedure.S getspecialfolder(csidl.L)
		Protected *itemid.ITEMIDLIST
		Protected location.S = Space(#MAX_PATH)
		
		If SHGetSpecialFolderLocation_ (0, csidl, @*itemid) = #NOERROR
			If SHGetPathFromIDList_(*itemid, @location)
				If Right(location, 1) <> "\" : location + "\" : EndIf
				ProcedureReturn location
			EndIf
		EndIf
	EndProcedure
	
	Procedure shcallback(pos, len, id)
		Shared start_pos,Buffer, editor
		
		ScintillaSendMessage(editor, #SCI_STARTSTYLING, (pos - Buffer) + start_pos, $1F)
		ScintillaSendMessage(editor, #SCI_SETSTYLING, len, id)
		
		
		
	EndProcedure
	
	Procedure scintillacallback(editorgadget.L, *scinotity.SCNotification)
		Protected line_number.L
		Protected txtr.TEXTRANGE
		Protected end_pos.L
		Shared start_pos, Buffer, editor
		
		editor = editorgadget
		If *scinotity\nmhdr\code = #SCN_STYLENEEDED
			
			
			
			line_number = ScintillaSendMessage(editorgadget, #SCI_LINEFROMPOSITION, ScintillaSendMessage(editorgadget, #SCI_GETENDSTYLED))
			start_pos = ScintillaSendMessage(editorgadget, #SCI_POSITIONFROMLINE, line_number)
			end_pos     = *scinotity\Position
			
			txtr\chrg\cpMin = start_pos
			txtr\chrg\cpMax = end_pos
			txtr\lpstrText  = AllocateMemory(end_pos - start_pos + 1)
			Buffer          = txtr\lpstrText
			
			ScintillaSendMessage(editorgadget, #SCI_GETTEXTRANGE, 0, txtr)
			
			SyntaxHighlight(Buffer, end_pos - start_pos, @shcallback(), #False)
			
			FreeMemory(Buffer)
		EndIf
	EndProcedure
	
	Procedure createpbsourceview()
		; la dedans la creation de l'editeur et tout le binz pour colorer le bouzin en fonction du profil Purebasic
		; la seule chose a parametrer eventuellement, c'est la couleur et la taille du curseur  et la couleur de la numértation voir en fin de cette procedure
		Protected wFlags.L = #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_Invisible | #PB_Window_SystemMenu | #PB_Window_SizeGadget
		Protected temp.S
		If OpenWindow(#win, #PB_Ignore, 0, 800, 600, "Scintilla Editor", wFlags)
			SmartWindowRefresh(#win, #True)
			RemoveKeyboardShortcut(#win, #PB_Shortcut_Tab) ;Required for the tab key to function correctly when the Scintilla control has the focus.
			AddKeyboardShortcut(#win, #PB_Shortcut_Control | #PB_Shortcut_Tab, #ctrl_Tab)
			
			ScintillaGadget(#SciID, 0, 0, 0, 0, @scintillacallback())
			
			
			ScintillaGadget(#SciID2, 0, 0, 0, 0, 0)
			
			
			ScintillaSendMessage(#SciID2, #SCI_SETDOCPOINTER, 0, ScintillaSendMessage(#SciID, #SCI_GETDOCPOINTER))
			
			SplitterGadget(#Splitter, 0, 0, 0, 0, #SciID, #SciID2)
			SetGadgetState(#Splitter, 0)
			
			ScintillaSendMessage(#SciID, #SCI_SETLEXER, #SCLEX_CONTAINER)
			ScintillaSendMessage(#SciID2, #SCI_SETLEXER, #SCLEX_CONTAINER)
			
			OpenPreferences(getspecialfolder(#CSIDL_APPDATA) + "PureBasic\PureBasic.prefs")
			PreferenceGroup("Editor")
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE,#STYLE_DEFAULT, $000000)
			ScintillaSendMessage(#SciID, #SCI_STYLESETBACK, #STYLE_DEFAULT, ReadPreferenceLong("BackgroundColor", $FFFFFF))
			temp = ReadPreferenceString("EditorFontName", "Courier New")
			ScintillaSendMessage(#SciID, #SCI_STYLESETFONT, #STYLE_DEFAULT, @temp)
			ScintillaSendMessage(#SciID, #SCI_STYLESETSIZE, #STYLE_DEFAULT, ReadPreferenceLong("EditorFontSize", 10))
			ScintillaSendMessage(#SciID, #SCI_STYLECLEARALL)
			
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Text, ReadPreferenceLong("NormalTextColor", 0))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Keyword, ReadPreferenceLong("BasicKeywordColor", $9D030D))
			ScintillaSendMessage(#SciID, #SCI_STYLESETBOLD, #SYNTAX_Keyword, #True)
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Comment, ReadPreferenceLong("CommentColor", $6F884A))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Constant, ReadPreferenceLong("ConstantColor", $0B46AE))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_String, ReadPreferenceLong("StringColor", $413C33))
			ScintillaSendMessage(#SciID, #SCI_STYLESETITALIC, #SYNTAX_String, #True)
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Function, ReadPreferenceLong("PureKeywordColor", $EF303D))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Asm, ReadPreferenceLong("ASMKeywordColor", $400080))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Operator,  ReadPreferenceLong("OperatorColor", $0000FF))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Structure, ReadPreferenceLong("StructureColor", $0548B4))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Number, ReadPreferenceLong("NumberColor", $0000FF))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Pointer,  ReadPreferenceLong("PointerColor", $0507B4))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Separator,  ReadPreferenceLong("SeparatorColor", $000000))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #SYNTAX_Label,  ReadPreferenceLong("LabelColor", $804000))
			ScintillaSendMessage(#SciID, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
			ScintillaSendMessage(#SciID, #SCI_SETMARGINWIDTHN, 0, 40)
			ScintillaSendMessage(#SciID, #SCI_STYLESETBACK, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberBackColor", GetSysColor_(15)))
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #STYLE_LINENUMBER, ReadPreferenceLong("LineNumberColor", 0))
			ScintillaSendMessage(#SciID, #SCI_SETMARGINWIDTHN, 1, 5)
			ClosePreferences()
			
			; defini la taille et la couleur du curseur
			color_curseur=RGB(255,255,0):taille=5
			GOSCI_Setcurs(#SciID, color_curseur,taille) 
			; defini la couleur de la numerotation
			color_numerotation=RGB(255,255,0)
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #STYLE_LINENUMBER, color_numerotation) 
			; defini le fond des numero de lignes
			color_fond_numerotation=RGB(80,0,80)
			ScintillaSendMessage(#SciID, #SCI_STYLESETBACK, #STYLE_LINENUMBER, color_fond_numerotation) 
			
			GOSCI_SetTabs(#SciID,3, #False) ; defini la largeur d'une tabulation (ici 4)
			
			; definition des guides de tabulation(j'ai pas trouvé comment changer la couleur )
			ScintillaSendMessage(#SciID,#SCI_SETHIGHLIGHTGUIDE, 1)
			ScintillaSendMessage(#SciID, #SCI_SETINDENTATIONGUIDES, #SC_IV_LOOKFORWARD)
			ScintillaSendMessage(#SciID, #SCI_STYLESETFORE, #STYLE_INDENTGUIDE, RGB(255,255,0))
			
			; definition couleur de la ligne en cours
			ScintillaSendMessage(#SciID, #SCI_SETCARETLINEBACK, RGB(30,30,30))
			ScintillaSendMessage(#SciID, #SCI_SETCARETLINEVISIBLE, #True)
			
			;definition couleur de la selection
			ScintillaSendMessage(#SciID, #SCI_SETSELBACK, #True, RGB(125,125,0))  
			ScintillaSendMessage(#SciID, #SCI_SETSELFORE, #True, $0)  
			
			ProcedureReturn 1
		EndIf
		ProcedureReturn 0
	EndProcedure
	
	;Epb

; Epb

Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Re: Tab, and indenting code

Post by Nico »

Work very well but

mais j'ai dû remplacer la couleur de la sélection de la ligne en cours:
; definition couleur de la ligne en cours
ScintillaSendMessage(#SciID, #SCI_SETCARETLINEBACK, RGB(30,30,30)) par RGB(230,230,230)

sinon au niveau de l'écriture, j'avais noir sur fond noir, je ne voyais pas ce que j'écrivais.

Excellent code. :)
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Re: Tab, and indenting code

Post by dobro »

Thanks Nico ;)
Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Tab, and indenting code

Post by davido »

@dobro,
Very nice, thank you for sharing.

Also a nice demonstration on use of the Scintilla Gadget. :D
DE AA EB
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Re: Tab, and indenting code

Post by dobro »

Thanks Davido :)
Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
Post Reply