Add _SupTrim Helper

This commit is contained in:
2025-08-24 18:11:13 +02:00
parent 62b3ba4d52
commit c0148b8790

315
main.pb
View File

@@ -507,6 +507,40 @@ EndProcedure
; ---- Helpers --------------------------------------------------------------- ; ---- Helpers ---------------------------------------------------------------
Procedure.s _SupTrim(text.s)
If text = "" : ProcedureReturn "" : EndIf
Protected i.i = 1
Protected j.i = Len(text)
Protected c.l
; Trim gauche : avancer tant que <= 32
While i <= j
c = Asc(Mid(text, i, 1))
If c <= 32
i + 1
Else
Break
EndIf
Wend
; Trim droite : reculer tant que <= 32
While j >= i
c = Asc(Mid(text, j, 1))
If c <= 32
j - 1
Else
Break
EndIf
Wend
If j < i
ProcedureReturn ""
Else
ProcedureReturn Mid(text, i, j - i + 1)
EndIf
EndProcedure
Procedure.s _JoinPath(base$, sub$) Procedure.s _JoinPath(base$, sub$)
Protected out$ = Trim(base$) Protected out$ = Trim(base$)
If out$ = "" : ProcedureReturn sub$ : EndIf If out$ = "" : ProcedureReturn sub$ : EndIf
@@ -552,6 +586,60 @@ Procedure Max(nb1, nb2)
ProcedureReturn Result ProcedureReturn Result
EndProcedure EndProcedure
; ------------------------------------------------------------------
; Récupération récursive de TOUS les fichiers du workdir
; Remplit main\listFilesGit() avec un statut " " (clean/unmodified)
; ------------------------------------------------------------------
; --- Helper interne : scanne un dossier et alimente la liste
Procedure _ScanAndFillAllFiles(dir$, root$)
Protected did.i = ExamineDirectory(#PB_Any, dir$, "*")
If did = 0 : ProcedureReturn : EndIf
While NextDirectoryEntry(did)
Protected name$ = DirectoryEntryName(did)
If name$ = "." Or name$ = ".." : Continue : EndIf
Protected full$ = dir$ + name$
Debug full$
If DirectoryEntryType(did) = #PB_DirectoryEntry_Directory
; Ignorer le dépôt interne
If LCase(name$) <> ".git"
If Right(full$, 1) <> #PS$ : full$ + #PS$ : EndIf
_ScanAndFillAllFiles(full$, root$)
EndIf
Else
; Fichier : on ajoute une ligne dans main\listFilesGit()
Protected rel$ = Mid(full$, Len(root$) + 1)
rel$ = ReplaceString(rel$, "\", "/") ; chemins normalisés
AddElement(main\listFilesGit())
main\listFilesGit()\name = rel$
main\listFilesGit()\status = " " ; 2 espaces = clean
main\listFilesGit()\indexStatus = " "
main\listFilesGit()\workingTreeStatus = " "
main\listFilesGit()\statusDescription = "Unmodified"
EndIf
Wend
FinishDirectory(did)
EndProcedure
; --- API publique : appelle ceci pour remplir la liste
Procedure.i FillAllFilesRecursively()
root$ = GetCurrentDirectory()
; Normalise avec un séparateur de fin
If Right(root$, 1) <> "\" And Right(root$, 1) <> "/" : root$ + "/" : EndIf
; On n'efface pas ici pour laisser le choix à l'appelant
_ScanAndFillAllFiles(root$, root$)
ProcedureReturn ListSize(main\listFilesGit())
EndProcedure
Procedure.i EnsureGitAvailable() Procedure.i EnsureGitAvailable()
Debug "EnsureGitAvailable()" Debug "EnsureGitAvailable()"
@@ -702,6 +790,8 @@ EndProcedure
Procedure.s GetStatusDescription(status.s) Procedure.s GetStatusDescription(status.s)
Select status Select status
Case " "
ProcedureReturn "Unmodified" ;Non modifié
Case "M " Case "M "
ProcedureReturn "Modified in index";Modifié dans index seulement ProcedureReturn "Modified in index";Modifié dans index seulement
Case " M" Case " M"
@@ -750,8 +840,8 @@ Procedure.s GetStatusDescription(status.s)
EndProcedure EndProcedure
Procedure GetGitStatus() Procedure GetGitStatus()
; Vider la liste existante ; Ne PAS vider la liste ici : on veut pouvoir mettre à jour des entrées existantes
ClearList(main\listFilesGit()) ; ClearList(main\listFilesGit()) ; <-- laissé intentionnellement commenté
; Configuration pour git status --porcelain --ignored ; Configuration pour git status --porcelain --ignored
main\Gitcall\args = "status --porcelain --ignored" main\Gitcall\args = "status --porcelain --ignored"
@@ -806,27 +896,44 @@ Procedure GetGitStatus()
For i = 0 To ArraySize(lines()) For i = 0 To ArraySize(lines())
line$ = lines(i) line$ = lines(i)
If line$ <> "" If line$ <> ""
; Le format est : XY filename ; Le format est : XY␠<filename>
; X = index status, Y = working tree status ; X = index status, Y = working tree status
If Len(line$) >= 3 If Len(line$) >= 3
AddElement(main\listFilesGit()) status$ = Left(line$, 2)
index$ = Left(line$, 1)
worktree$ = Mid(line$, 2, 1)
name$ = Mid(line$, 4) ; chemin tel que renvoyé par Git
name$ = ReplaceString(name$, "\", "/") ; normalisation (par sécurité)
; ----- MODIF: chercher si l'entrée existe déjà -----
found.b = #False
ForEach main\listFilesGit()
If main\listFilesGit()\name = name$
found = #True
; Mise à jour uniquement
main\listFilesGit()\status = status$
main\listFilesGit()\indexStatus = index$
main\listFilesGit()\workingTreeStatus = worktree$
main\listFilesGit()\statusDescription = GetStatusDescription(status$)
Break
EndIf
Next
; Extraire le status (2 premiers caractères) ; Si non trouvée, on l'ajoute
main\listFilesGit()\status = Left(line$, 2) If Not found
main\listFilesGit()\indexStatus = Left(line$, 1) AddElement(main\listFilesGit())
main\listFilesGit()\workingTreeStatus = Mid(line$, 2, 1) main\listFilesGit()\name = name$
main\listFilesGit()\status = status$
; Extraire le nom du fichier (à partir du 4ème caractère) main\listFilesGit()\indexStatus = index$
main\listFilesGit()\name = Mid(line$, 4) main\listFilesGit()\workingTreeStatus = worktree$
main\listFilesGit()\statusDescription = GetStatusDescription(status$)
; Obtenir la description du status EndIf
main\listFilesGit()\statusDescription = GetStatusDescription(main\listFilesGit()\status) ; ----- FIN MODIF -----
EndIf EndIf
EndIf EndIf
Next Next
Debug "Récupération des status Git réussie. " + Str(ListSize(main\listFilesGit())) + " fichiers trouvés." Debug "Récupération des status Git réussie. " + Str(ListSize(main\listFilesGit())) + " fichiers (maj/ajout)."
ProcedureReturn #True ProcedureReturn #True
Else Else
@@ -835,6 +942,7 @@ Procedure GetGitStatus()
EndIf EndIf
EndProcedure EndProcedure
; Récupère le nombre immédiatement avant un mot-clé dans une ligne ; Récupère le nombre immédiatement avant un mot-clé dans une ligne
Procedure.i ExtractNumberBefore(word.s, line.s) Procedure.i ExtractNumberBefore(word.s, line.s)
Protected pos = FindString(line, word, 1) Protected pos = FindString(line, word, 1)
@@ -1151,6 +1259,10 @@ EndProcedure
;-Suite ;-Suite
Procedure AddRemoteRepo(Url.s,name.s="origin") Procedure AddRemoteRepo(Url.s,name.s="origin")
Url=_SupTrim(Url)
name=_SupTrim(name)
Debug "Url="+Url
Debug "name="+name
;Check if this remote already exists ;Check if this remote already exists
main\Gitcall\args = "remote get-url "+name main\Gitcall\args = "remote get-url "+name
If RunExe(@main\Gitcall) = 0 If RunExe(@main\Gitcall) = 0
@@ -1172,7 +1284,7 @@ EndProcedure
Procedure GetRemoteUrl(name.s="origin") Procedure GetRemoteUrl(name.s="origin")
main\Gitcall\args = "remote get-url "+name main\Gitcall\args = "remote get-url "+name
If RunExe(@main\Gitcall) = 0 If RunExe(@main\Gitcall) = 0
SetGadgetText(#GdtFieldRemote,main\GitCall\output) SetGadgetText(#GdtFieldRemote,_SupTrim(main\GitCall\output))
Else Else
SetGadgetText(#GdtFieldRemote,"") SetGadgetText(#GdtFieldRemote,"")
EndIf EndIf
@@ -1208,6 +1320,111 @@ Procedure DoPull()
EndIf EndIf
EndProcedure EndProcedure
Procedure.s ExtractRepoNameFromUrl(url.s)
; helper for Doclone
; Extraire le nom du dépôt depuis l'URL
Protected repoName.s, parts.i, i.i
; Supprimer .git à la fin si présent
If Right(url, 4) = ".git"
url = Left(url, Len(url) - 4)
EndIf
; Remplacer les \ par des / pour uniformiser
url = ReplaceString(url, "\", "/")
; Compter le nombre de parties séparées par /
parts = CountString(url, "/")
; Extraire la dernière partie
If parts > 0
repoName = StringField(url, parts + 1, "/")
Else
repoName = url
EndIf
ProcedureReturn repoName
EndProcedure
Procedure.s GetParentPath(path.s)
Protected parentPath.s
; Supprimer le séparateur final si présent
If Right(Path, 1) = "\" Or Right(Path, 1) = "/"
Path = Left(Path, Len(Path) - 1)
EndIf
; Utiliser GetPathPart() qui retourne le chemin sans le fichier/dossier final
parentPath = GetPathPart(path)
ProcedureReturn parentPath
EndProcedure
Procedure DoClone()
Protected remoteUrl.s, repoName.s, targetFolder.s, currentDir.s, choice.i
remoteUrl = Trim(GetGadgetText(#GdtFieldRemote))
If remoteUrl = ""
MessageRequester("Git Clone", "Échec: " + #LF$ + "You Must have a remote URL", #PB_MessageRequester_Error)
ProcedureReturn #False
EndIf
; Extraire le nom du dépôt depuis l'URL
Debug "remoteUrl="+remoteUrl
repoName = ExtractRepoNameFromUrl(remoteUrl)
Debug "repoName="+repoName
; Obtenir le chemin complet du répertoire courant
currentDir = GetCurrentDirectory()
; Demander à l'utilisateur où cloner
choice = MessageRequester("Git Clone - Destination",
"Où voulez-vous cloner le dépôt ?" + #LF$ + #LF$ +
"OUI: Créer un répertoire '" + repoName + "' dans le répertoire courant" + #LF$ +
" → " + currentDir + repoName + "/" + #LF$ + #LF$ +
"NON: Cloner directement dans le répertoire courant" + #LF$ +
" → " + currentDir + #LF$ + #LF$ +
"ANNULER: Annuler l'opération",
#PB_MessageRequester_YesNoCancel)
Select choice
Case #PB_MessageRequester_Yes
; Créer un nouveau répertoire avec le nom du dépôt
targetFolder = repoName
main\Gitcall\args = "clone " + remoteUrl + " " + targetFolder
Case #PB_MessageRequester_No
; Cloner directement dans le répertoire courant (doit être vide)
SetCurrentDirectory(GetParentPath(GetGadgetText(#GgtFieldRepo)))
targetFolder = "."
main\Gitcall\args = "clone " + remoteUrl + " " + targetFolder
Case #PB_MessageRequester_Cancel
; Annuler l'opération
ProcedureReturn #False
EndSelect
; Exécuter la commande git clone
If RunExe(@main\Gitcall) = 0
If targetFolder = "."
MessageRequester("Git Clone", "Succès:" + #LF$ +
"Dépôt cloné dans le répertoire courant" + #LF$ + #LF$ +
main\Gitcall\output, #PB_MessageRequester_Info)
Else
MessageRequester("Git Clone", "Succès:" + #LF$ +
"Dépôt cloné dans le répertoire: " + targetFolder + "/" + #LF$ + #LF$ +
main\Gitcall\output, #PB_MessageRequester_Info)
EndIf
AddRemoteRepo(remoteUrl)
SetCurrentDirectory(GetGadgetText(#GgtFieldRepo))
CreateThread(@RefreshFileList(),0)
ProcedureReturn #True
Else
MessageRequester("Git Clone", "Échec: " + #LF$ + main\Gitcall\errors, #PB_MessageRequester_Error)
ProcedureReturn #False
EndIf
EndProcedure
Procedure DoStatus() Procedure DoStatus()
Protected *status.GitStatus=@main\GitStatus Protected *status.GitStatus=@main\GitStatus
@@ -1397,7 +1614,7 @@ EndProcedure
Procedure.s GetBranchesList() Procedure.s GetBranchesList()
ClearGadgetItems(#GdtSlctBranch) ClearGadgetItems(#GdtSlctBranch)
main\Gitcall\args = "branch" main\Gitcall\args = "branch -a"
If RunExe(@main\Gitcall) <> 0 If RunExe(@main\Gitcall) <> 0
ProcedureReturn "" ProcedureReturn ""
EndIf EndIf
@@ -1586,7 +1803,7 @@ Procedure RefreshFileList(null.i)
ClearGadgetItems(#GdtListStatus) ClearGadgetItems(#GdtListStatus)
ClearList(main\listFilesGit()) ClearList(main\listFilesGit())
;-Init File List ;-Init File List
DoLsFilesByType("C") FillAllFilesRecursively()
;DoLsFilesByType("D") ;DoLsFilesByType("D")
;DoLsFilesByType("O") ;DoLsFilesByType("O")
;DoLsFilesByType("I") ;DoLsFilesByType("I")
@@ -1604,6 +1821,8 @@ Procedure RefreshFileList(null.i)
Next Next
DisableGadget(#GdtListStatus,#False) DisableGadget(#GdtListStatus,#False)
DisableGadget(#GdtBtnRefresh,#False) DisableGadget(#GdtBtnRefresh,#False)
GetBranchesList()
GetRemoteUrl()
EndProcedure EndProcedure
Procedure UpdateHelp(txt.s) Procedure UpdateHelp(txt.s)
@@ -1706,6 +1925,13 @@ Procedure InitGadget()
EndProcedure EndProcedure
Macro RightGadget(GDT)
GadgetX(GDT)+GadgetWidth(GDT)
EndMacro
Macro DownGadget(GDT)
GadgetY(GDT)+GadgetHeight(GDT)
EndMacro
Procedure OpenGUI() Procedure OpenGUI()
Protected argCount.l=CountProgramParameters(), w.l,a$ Protected argCount.l=CountProgramParameters(), w.l,a$
@@ -1731,11 +1957,9 @@ Procedure OpenGUI()
EndIf EndIf
; --- Dimensions générales --- ; --- Dimensions générales ---
#WinW = 950 #WinW = 950
#WinH = 930 ; plus haut pour la zone daide #WinH = 720 ; plus haut pour la zone daide
#PanelX = 15
#PanelY = 15
#PanelW = 920 #PanelW = 920
#PanelH = 700 #PanelH = 500
#InPad = 15 ; marge interne au Panel #InPad = 15 ; marge interne au Panel
#FrmGap = 10 ; espace vertical entre frames #FrmGap = 10 ; espace vertical entre frames
#RowH = 26 #RowH = 26
@@ -1743,15 +1967,16 @@ Procedure OpenGUI()
If OpenWindow(#WinMain, 0, 0, #WinW, #WinH, "Git helpmate", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) If OpenWindow(#WinMain, 0, 0, #WinW, #WinH, "Git helpmate", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
PanelGadget(#gdtPnl, #PanelX, #PanelY, #PanelW, #PanelH) PanelGadget(#GdtPnl, #InPad,#InPad, #PanelW, #PanelH)
; ============================================================ ; ============================================================
; Onglet 1 : Dépôt ; Onglet 1 : Dépôt
; ============================================================ ; ============================================================
AddGadgetItem(#gdtPnl, -1, T("#gdtPnl-Repo","Dépôt")) AddGadgetItem(#gdtPnl, -1, T("#gdtPnl-Repo","Dépôt"))
Protected PanelH.l=WindowHeight(#WinMain)- 2*#InPad
Protected PanelW.l=900
; ---- Cadre "Dépôt local" ---- ; ---- Cadre "Dépôt local" ----
FrameGadget(#GdtFrmLocal, #InPad, #InPad, #PanelW - 2*#InPad, 100, T("GdtFrmLocal","Dépôt local")) FrameGadget(#GdtFrmLocal, #InPad, #InPad, PanelW - 2*#InPad, 100, T("GdtFrmLocal","Dépôt local"))
TextGadget(#GdtLblRepo, #InPad + 10, #InPad + 30, 60, 22, T("GdtLblRepo","Dépôt :")) TextGadget(#GdtLblRepo, #InPad + 10, #InPad + 30, 60, 22, T("GdtLblRepo","Dépôt :"))
StringGadget(#GgtFieldRepo, #InPad + 75, #InPad + 28, #PanelW - 2*#InPad - 75 - 105, #RowH, repoDir$) StringGadget(#GgtFieldRepo, #InPad + 75, #InPad + 28, #PanelW - 2*#InPad - 75 - 105, #RowH, repoDir$)
ButtonGadget(#GdtBtnBrowseRepo, #PanelW - #InPad - 95, #InPad + 28, 95, #RowH, T("GdtBtnBrowseRepo","Parcourir…")) ButtonGadget(#GdtBtnBrowseRepo, #PanelW - #InPad - 95, #InPad + 28, 95, #RowH, T("GdtBtnBrowseRepo","Parcourir…"))
@@ -1856,13 +2081,26 @@ Procedure OpenGUI()
; --- Fin des onglets --- ; --- Fin des onglets ---
CloseGadgetList() CloseGadgetList()
; ============================================================ ; ============================================================
; Zone daide (plus haute grâce à #PanelH réduit) ; Aide à droite du Panel (sans splitter)
; ============================================================ ; ============================================================
Define helpY = #PanelY + #PanelH + 10 ; On garde #PanelW / #PanelH tels quels
;FrameGadget(#GdtFrmHelp, #PanelX, helpY, #PanelW, #WinH - helpY - #PanelX, T("GdtFrmHelp","Aide"))
WebViewGadget(#GdtHelp, #PanelX + 10, helpY + 25, #PanelW - 20, #WinH - helpY - #PanelX - 35)
Define helpGap = 10 ; espace entre panel et aide
Define helpX = #InPad + #PanelW + helpGap ; à droite du panel
Define helpY = #InPad
Define helpW = WindowWidth(#WinMain)-GadgetWidth(#gdtPnl)- #InPad*4 ; reste de largeur jusqu'à la marge droite
Define helpH = #PanelH ; même hauteur que le panel
; (Optionnel) borne minimale si besoin
If helpW < 100 : helpW = 100 : EndIf
; Soit en direct :
WebViewGadget(#GdtHelp, helpX, helpY, helpW, helpH)
; — ou, si tu veux un cadre :
; FrameGadget(#GdtFrmHelp, helpX, helpY, helpW, helpH, T("GdtFrmHelp","Aide"))
; WebViewGadget(#GdtHelp, helpX + 10, helpY + 25, helpW - 20, helpH - 35)
SetGadgetText(#GgtFieldRepo,main\GitCall\workdir) SetGadgetText(#GgtFieldRepo,main\GitCall\workdir)
@@ -1901,19 +2139,26 @@ Procedure OpenGUI()
Case #GdtBtnRefresh Case #GdtBtnRefresh
CreateThread(@RefreshFileList(),0) CreateThread(@RefreshFileList(),0)
Case #GgtFieldRepo Case #GgtFieldRepo
If EventType()=#PB_EventType_Change If EventType()=#PB_EventType_LostFocus
main\GitCall\workdir=GetGadgetText(#GgtFieldRepo) main\GitCall\workdir=GetGadgetText(#GgtFieldRepo)
CreateThread(@RefreshFileList(),0)
EndIf EndIf
Case #GdtBtnBrowseRepo Case #GdtBtnBrowseRepo
Protected path.s=PathRequester("Select Folder",main\GitCall\workdir,WindowID(#WinMain)) Protected path.s=PathRequester("Select Folder",main\GitCall\workdir,WindowID(#WinMain))
If path<>"" And FileSize(path)=-2 If path<>"" And FileSize(path)=-2
main\GitCall\workdir=path main\GitCall\workdir=path
SetCurrentDirectory(main\GitCall\workdir)
SetGadgetText(#GgtFieldRepo,main\GitCall\workdir)
CreateThread(@RefreshFileList(),0)
EndIf EndIf
Case #GdtFieldRemote Case #GdtFieldRemote
;If EventType()=#PB_EventType_LostFocus ;If EventType()=#PB_EventType_LostFocus
; AddRemoteRepo(GetGadgetText(#GdtFieldRemote),"origin") ; AddRemoteRepo(GetGadgetText(#GdtFieldRemote),"origin")
; EndIf ; EndIf
Case #GdtBtnClone
DoClone()
Case #GdtBtnPush Case #GdtBtnPush
DoPush() DoPush()
Case #GdtBtnPull Case #GdtBtnPull
@@ -1957,9 +2202,9 @@ OpenGUI()
; IDE Options = PureBasic 6.21 (Windows - x64) ; IDE Options = PureBasic 6.21 (Windows - x64)
; CursorPosition = 1947 ; CursorPosition = 541
; FirstLine = 1906 ; FirstLine = 509
; Folding = -------- ; Folding = ----------
; Optimizer ; Optimizer
; EnableThread ; EnableThread
; EnableXP ; EnableXP