But recherché: créer un bookmark d'un fichier ( peut être utilisé pour n'importe quel type de fichier texte)
Méthode (pour un fichier source PureBasic)
- Ouvrir un fichier source PureBasic
- Chercher tous les mots-clés « Procedure » et certains types de commentaires « ;- » « ;{ ». (Les lignes de tirets seuls « ;------ » sont exclues)
- Créer une liste (liste + gadget)
- Quand on clique sur un des éléments de la liste, mettre la ligne en référence en haut de l'éditeur ainsi que le curseur et la ligne surlignée.
Principe de fonctionnement:
- Si un nom de fichier est passé en paramètre, il est utilisé, sinon le programme ouvre une fenêtre de demande.
- Le système recherche toutes les occurrences à l'aide d'une expression régulière
- À chaque expression trouvée il mémorise l'offset (position depuis le début du fichier) et la chaîne (ligne 101). [Edit] et compte le nombre de CRLF dspuis le début et l'ajoute à la structure
̶D̶a̶n̶s̶ ̶u̶n̶e̶ ̶d̶e̶u̶x̶i̶è̶m̶e̶ ̶b̶o̶u̶c̶l̶e̶ ̶(̶l̶i̶g̶n̶e̶ ̶1̶1̶0̶)̶,̶ ̶p̶o̶u̶r̶ ̶t̶o̶u̶s̶ ̶l̶e̶s̶ ̶é̶l̶é̶m̶e̶n̶t̶s̶ ̶d̶e̶ ̶l̶a̶ ̶l̶i̶s̶t̶e̶,̶ ̶i̶l̶ ̶c̶o̶m̶p̶t̶e̶ ̶l̶e̶ ̶n̶o̶m̶b̶r̶e̶ ̶d̶e̶ ̶C̶R̶L̶F̶ ̶d̶e̶p̶u̶i̶s̶ ̶l̶e̶ ̶d̶é̶b̶u̶t̶ ̶e̶t̶ ̶m̶é̶m̶o̶r̶i̶s̶e̶ ̶c̶e̶ ̶n̶u̶m̶é̶r̶o̶ ̶d̶a̶n̶s̶ ̶l̶e̶ ̶t̶r̶o̶i̶s̶i̶è̶m̶e̶ ̶c̶h̶a̶m̶p̶s̶ ̶d̶e̶ ̶l̶a̶ ̶s̶t̶r̶u̶c̶t̶u̶r̶e̶.̶
̶O̶n̶ ̶p̶e̶u̶t̶ ̶m̶e̶t̶t̶r̶e̶ ̶l̶e̶s̶ ̶d̶e̶u̶x̶ ̶é̶t̶a̶p̶e̶s̶ ̶c̶i̶-̶d̶e̶s̶s̶u̶s̶ ̶e̶n̶ ̶u̶n̶e̶ ̶s̶e̶u̶l̶e̶.̶ ̶J̶e̶ ̶n̶'̶y̶ ̶a̶ ̶a̶v̶a̶i̶t̶ ̶p̶a̶s̶ ̶p̶e̶n̶s̶é̶ ̶à̶ ̶l̶'̶é̶p̶o̶q̶u̶e̶.̶.̶.̶ - Il supprime le mot clé « procedure » et l'éventuel type « .x » (ligne 116)
- Quand l'utilisateur clique sur un des éléments de la liste, il n'y a plus qu'à faire défiler l'écran sur ligne mémorisée (ligne 164).
Code : Tout sélectionner
; Bookmark_Maker_2.pb
; Marc56 - 19/06/19
;
; Crée une liste des procédures contenues dans un cource PB
; Ajoute certaines lignes de commentaires « ;- » et « ;{ »
; Fait défiler l'éditeur sur le ligne pointée dans la liste
EnableExplicit
Enumeration
#Win
#Editor
#Bookmark
#Btn_Load_File
#Btn_Refresh
EndEnumeration
Global File_Name$ = ProgramParameter(0)
Global Full_Txt$
Global RegEx$ = "\bprocedure(?:.\w)?\s+[\w.\(\)\s*,]+|;[-{][^-].+"
Structure Type_Bookmark
Offset.i ; Position de la chaine "Procedure ..." dans le texte complet
Title$ ; Texte de la procédure (pour l'instant juste le nom)
NbL.i ; Numéro de la ligne
EndStructure
Global NewList Bookmark.Type_Bookmark()
SetGadgetFont(#PB_Default, FontID(LoadFont(#PB_Any, "Consolas", 8)))
Procedure Init()
OpenWindow(#Win, 0, 0, 1000, 800, "Auto-Bookmarker", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If Not InitScintilla() : MessageRequester("Erreur", "Ne peut initialiser Scintilla") : End : EndIf
ScintillaGadget(#Editor, 10, 10, 780, 780, 0)
ListViewGadget(#Bookmark, 800, 40, 190, 750)
ButtonGadget(#Btn_Load_File, 800, 10, 90, 25, "Ouvrir...")
ButtonGadget(#Btn_Refresh, 900, 10, 90, 25, "Réindexer")
ScintillaSendMessage(#Editor, #SCI_STYLESETFONT, #STYLE_DEFAULT, Ascii("Consolas"))
ScintillaSendMessage(#Editor, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 10)
; Couleur texte
ScintillaSendMessage(#Editor, #SCI_STYLESETBACK, #STYLE_DEFAULT, $F0FFFF)
ScintillaSendMessage(#Editor, #SCI_STYLESETFORE, #STYLE_DEFAULT, $8B0000)
ScintillaSendMessage(#Editor, #SCI_STYLECLEARALL)
; Marge de numéros de ligne
ScintillaSendMessage(#Editor, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER) ;
ScintillaSendMessage(#Editor, #SCI_SETMARGINWIDTHN, 0, 50)
ScintillaSendMessage(#Editor, #SCI_STYLESETBACK, #STYLE_LINENUMBER, $DBDBDB)
ScintillaSendMessage(#Editor, #SCI_STYLESETFORE, #STYLE_LINENUMBER, $908070)
; Ligne en cours
ScintillaSendMessage(#Editor, #SCI_SETCARETLINEBACK, $00FFFF)
ScintillaSendMessage(#Editor, #SCI_SETCARETLINEVISIBLE, #True)
If Not CreateRegularExpression(0, RegEx$, #PB_RegularExpression_NoCase)
Debug RegularExpressionError()
End
EndIf
EndProcedure
Procedure Load_File()
If Not ReadFile(0, File_Name$)
Debug "Erreur ouverture fichier: " + File_Name$
End
EndIf
Protected FileType = ReadStringFormat(0)
Protected Size = FileSize(File_Name$)
Protected *Buffer = AllocateMemory(Size)
If *Buffer
ReadData(0, *Buffer, Size)
CloseFile(0)
Full_Txt$ = PeekS(*Buffer, Size, FileType)
FreeMemory(*Buffer)
Else
Debug "Erreur allocation mémoire"
EndIf
ScintillaSendMessage(#Editor, #SCI_SETTEXT, 0, UTF8(Full_Txt$))
EndProcedure
Procedure Make_Bookmark()
ClearList(Bookmark())
ClearGadgetItems(#Bookmark)
Full_Txt$ = GetGadgetText(#Editor)
Protected Tmp_Remove$
If ExamineRegularExpression(0, Full_Txt$)
Protected i
While NextRegularExpressionMatch(0)
i + 1
AddElement(Bookmark())
With Bookmark()
\Offset = RegularExpressionMatchPosition(0)
\Title$ = RegularExpressionMatchString(0)
\NbL = CountString(Left(Full_Txt$, \Offset), #CRLF$) + 1
If Mid(\Title$, 10, 1) = "."
Tmp_Remove$ = Left(\Title$, 11) ; Effacer le type (ex: procedure.q)
Else
Tmp_Remove$ = "procedure" ; Effacer le mot "procedure"
EndIf
AddGadgetItem(#Bookmark, -1,
RemoveString(\Title$, Tmp_Remove$, #PB_String_NoCase) +
" (" + Str(\NbL) + ")")
EndWith
Wend
EndIf
SetWindowTitle(#Win, File_Name$)
EndProcedure
Procedure Ask_File()
File_Name$ = OpenFileRequester("Fichier à ouvrir", "", "Source PureBasic|*.pb", 0)
If FileSize(File_Name$) > 0
Full_Txt$ = ""
ClearList(Bookmark())
ClearGadgetItems(#Bookmark)
Load_File()
Make_Bookmark()
EndIf
EndProcedure
;- Début du programme
Init()
; Si aucun fichier passé en paramètre ou "droppé" sur l'icône, alors OpenFileRequester()
If ProgramParameter(0) = "" : Ask_File() : EndIf
Load_File()
Make_Bookmark()
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
Select EventGadget()
Case #Btn_Load_File
Ask_File()
Case #Btn_Refresh
Make_Bookmark()
Case #Bookmark ; (Clic sur une ligne du bookmark)
SelectElement(Bookmark(), GetGadgetState(#Bookmark))
With Bookmark()
If \NbL - 1 > 0
ScintillaSendMessage(#Editor, #SCI_SETFIRSTVISIBLELINE, \NbL - 1)
ScintillaSendMessage(#Editor, #SCI_GOTOLINE, \NbL - 1)
SetActiveGadget(#Editor)
EndIf
EndWith
EndSelect
EndSelect
ForEver
End
J'avais envisagé de compter les lignes par un déplacement relatif à la place d'un déplacement absolu, mais finalement ça va tellement vite que cela n'est pas nécessaire.
[Edit] version 2 : deux fonctions en une seule