Fils List Corrected and sorted

This commit is contained in:
2025-08-29 22:11:55 +02:00
parent 1464995bc8
commit 339f4f5f40
2 changed files with 285 additions and 15 deletions

294
main2.pb
View File

@@ -945,6 +945,95 @@ Procedure.i DoCommit()
ProcedureReturn #True
EndProcedure
Procedure.i GetRemoteStatusInfo()
; Récupère les informations de status du remote
Protected localBranch.s = GetGadgetText(#GID_CbLocalBranch)
Protected remoteBranch.s = GetGadgetText(#GID_CbRemoteBranch)
; Variables initialisées
Protected ahead.l = 0
Protected behind.l = 0
Protected isUpToDate.b = #False
Protected status.s = "--"
Protected needsAction.s = "--"
Protected color.i = RGB(60, 60, 60) ; Gris par défaut
; Vérifier que les branches sont définies
If Len(Trim(localBranch)) = 0 Or Len(Trim(remoteBranch)) = 0
status = "Branches non sélectionnées"
needsAction = "Sélectionner les branches"
ProcedureReturn #False
EndIf
; Comparer local vs remote
If Git("rev-list --left-right --count " + localBranch + "..." + remoteBranch) = 0
Protected counts.s = Trim(main\GitCall\output)
; Vérifier que la sortie contient bien des données
If Len(counts) > 0
; Parser les résultats (séparés par des espaces ou tabs)
Protected parts.s = ReplaceString(counts, #TAB$, " ") ; Normaliser les séparateurs
parts = ReplaceString(parts, " ", " ") ; Supprimer les espaces multiples
ahead = Val(StringField(parts, 1, " "))
behind = Val(StringField(parts, 2, " "))
; Construire le status et les actions
If ahead = 0 And behind = 0
isUpToDate = #True
status = "À jour"
needsAction = ""
color = RGB(0, 128, 0) ; Vert pour "à jour"
ElseIf ahead > 0 And behind = 0
status = Str(ahead) + " commit(s) en avance"
needsAction = "Push recommandé"
color = RGB(0, 100, 200) ; Bleu pour "en avance"
ElseIf ahead = 0 And behind > 0
status = Str(behind) + " commit(s) en retard"
needsAction = "Pull nécessaire"
color = RGB(255, 140, 0) ; Orange pour "en retard"
Else
status = Str(ahead) + " en avance, " + Str(behind) + " en retard"
needsAction = "Branches divergentes - Merge/Rebase requis"
color = RGB(255, 69, 0) ; Rouge-orange pour divergence
EndIf
Else
status = "Réponse vide de Git"
needsAction = "Vérifier la configuration Git"
EndIf
Else
; Erreur dans la commande Git
status = "Erreur comparaison"
needsAction = "Vérifier les noms de branches"
color = RGB(255, 0, 0) ; Rouge pour erreur
; Debug pour diagnostiquer l'erreur
Debug "Erreur Git: " + main\GitCall\output
Debug "Commande: rev-list --left-right --count " + localBranch + "..." + remoteBranch
EndIf
; Mettre à jour l'interface
SetGadgetText(#GID_TxtRemoteStatus, status)
; Définir la couleur si le gadget le supporte
; (Décommentez si votre version de PureBasic/OS le supporte)
; SetGadgetColor(#GID_LblRemoteStatus, #PB_Gadget_FrontColor, color)
; Action recommandée
If needsAction <> ""
SetGadgetText(#GID_TxtAction, needsAction)
Else
SetGadgetText(#GID_TxtAction, "Aucune action nécessaire")
EndIf
ProcedureReturn #True
EndProcedure
Procedure.s GetStatusDescription(status.s)
Select status
Case " "
@@ -996,8 +1085,50 @@ Procedure.s GetStatusDescription(status.s)
EndSelect
EndProcedure
Procedure.i GetStatusImportance(status.s)
Protected x.s = Left(status, 1)
Protected y.s = Mid(status, 2, 1)
Protected score.i = 0
; Conflits d'abord
Select status
Case "DD","AU","UD","UA","DU","AA","UU"
ProcedureReturn 1000
EndSelect
If x = "U" Or y = "U" : ProcedureReturn 1000 : EndIf
; Cas simples
If status = "??" : ProcedureReturn 300 : EndIf ; Non suivis
If status = "!!" : ProcedureReturn 50 : EndIf ; Ignorés
If status = " " : ProcedureReturn 0 : EndIf ; Propres
; Index > Worktree
If x <> " " : score + 700 : EndIf
If y <> " " And y <> "?" And y <> "!" : score + 600 : EndIf
; Raffinement (X puis Y)
Select x
Case "D" : score + 80
Case "R" : score + 70
Case "A" : score + 60
Case "M" : score + 50
Case "C" : score + 40
Case "T" : score + 30
EndSelect
Select y
Case "D" : score + 40
Case "R" : score + 35
Case "A" : score + 30
Case "M" : score + 25
Case "C" : score + 20
Case "T" : score + 15
EndSelect
ProcedureReturn score
EndProcedure
Procedure GetGitStatusPocelaine()
If Git("status --porcelain -z --ignored") = 0
If Git("status --porcelain --ignored") = 0
ProcedureReturn #True
EndIf
ProcedureReturn #False
@@ -1005,22 +1136,22 @@ EndProcedure
; Parse la sortie de: git status --porcelain -z
Procedure ParseStatusPorcelaine(output$)
Protected delim$ = Chr(0)
Protected delim$ = Chr(10)
Protected total.l = CountString(output$, delim$) + 1
Protected i.l = 1, tok$, sp.l
Protected xy$, path1$, path2$, name$, found.b
; Ne PAS vider main\Files(): on met à jour si existe déjà
For i=1 To total
tok$ = StringField(output$, i, delim$) : i + 1
tok$ = StringField(output$, i, delim$)
If tok$ = "" : Continue : EndIf
; tok$ ressemble à: "XY[...score...]␠<path1>"
sp = FindString(tok$, " ", 3)
Debug "sp="+Str(sp)
If sp = 0 Or Len(tok$) < 3 : Continue : EndIf
If Mid(tok$,3,1)<>" "
Continue
EndIf
xy$ = Left(tok$, 2) ; ex: " M", "R ", " C", "??", "UU", etc.
path1$ = Mid(tok$, sp+1,Len(tok$)-(sp+1)) ; 1er chemin
path1$ = Mid(tok$, 4,Len(tok$)-(3)) ; 1er chemin
;TODO check this
; Renomme/copie ? (si X ou Y est R/C, le prochain champ NUL = nouveau chemin)
@@ -1060,6 +1191,130 @@ Procedure ParseStatusPorcelaine(output$)
ProcedureReturn #True
EndProcedure
; Parse la sortie de: git status --porcelain -z
Procedure ParseStatusPorcelaine_new(output$)
Protected delim$ = Chr(0)
Protected pos.l = 1, nextPos.l
Protected xy$, path1$, path2$, name$, found.b
Protected line$, spacePos.l
Debug "Début parsing status -z, taille output: " + Str(Len(output$))
; Ne PAS vider main\Files(): on met à jour si existe déjà
While pos <= Len(output$)
; Trouver la prochaine entrée (délimitée par Chr(0))
nextPos = FindString(output$, delim$, pos)
If nextPos = 0
nextPos = Len(output$) + 1 ; Dernière entrée
EndIf
line$ = Mid(output$, pos, nextPos - pos)
; Passer à la prochaine entrée
pos = nextPos + 1
; Ignorer les lignes vides
If Len(line$) < 3
Continue
EndIf
Debug "Ligne analysée: [" + ReplaceString(line$, Chr(9), "<TAB>") + "]"
; Format: XY<espace><chemin> où XY = 2 caractères de status
xy$ = Left(line$, 2)
; Le 3ème caractère doit être un espace
If Mid(line$, 3, 1) <> " "
Debug "Format invalide - pas d'espace en position 3: " + line$
Continue
EndIf
; Extraire le chemin (à partir du 4ème caractère)
path1$ = Mid(line$, 4)
; Initialiser path2$ pour les cas rename/copy
path2$ = ""
; Vérifier si c'est un rename ou copy (R ou C dans le status)
; Format pour rename: "R100 ancien_nom<NUL>nouveau_nom<NUL>"
If Left(xy$, 1) = "R" Or Left(xy$, 1) = "C" Or Right(xy$, 1) = "R" Or Right(xy$, 1) = "C"
; Pour les renames/copies, il peut y avoir un score (ex: R100)
; Le chemin source se termine par NUL, suivi du chemin destination
Protected nullPos.l = FindString(path1$, delim$, 1)
If nullPos > 0
; Séparer les deux chemins
Protected tempPath$ = path1$
path1$ = Left(tempPath$, nullPos - 1)
; Le chemin de destination est après le NUL
If pos <= Len(output$)
nextPos = FindString(output$, delim$, pos)
If nextPos = 0
nextPos = Len(output$) + 1
EndIf
path2$ = Mid(output$, pos, nextPos - pos)
pos = nextPos + 1
EndIf
Debug "Rename/Copy détecté: " + path1$ + " -> " + path2$
EndIf
; Pour les renames, utiliser le nouveau nom
If path2$ <> ""
name$ = path2$
Else
name$ = path1$
EndIf
Else
name$ = path1$
EndIf
; Nettoyer le nom (enlever les guillemets si présents)
If Left(name$, 1) = Chr(34) And Right(name$, 1) = Chr(34) ; guillemets doubles
name$ = Mid(name$, 2, Len(name$) - 2)
EndIf
; Normaliser les séparateurs
name$ = ReplaceString(name$, "\", "/")
; Décoder les caractères échappés (\n, \t, \\, etc.)
name$ = ReplaceString(name$, "\\", "\")
name$ = ReplaceString(name$, "\n", Chr(10))
name$ = ReplaceString(name$, "\t", Chr(9))
Debug "Fichier traité: [" + name$ + "] Status: [" + xy$ + "]"
; Vérifier que le nom n'est pas vide
If Len(Trim(name$)) = 0
Debug "Nom de fichier vide, ignoré"
Continue
EndIf
; MAJ si déjà présent, sinon ajout
found = #False
ForEach main\Files()
If main\Files()\name = name$
found = #True
main\Files()\status = xy$
main\Files()\statusDescription = GetStatusDescription(xy$)
Debug "Fichier mis à jour: " + name$
Break
EndIf
Next
If Not found
AddElement(main\Files())
main\Files()\name = name$
main\Files()\status = xy$
main\Files()\statusDescription = GetStatusDescription(xy$)
Debug "Nouveau fichier ajouté: " + name$
EndIf
Wend
Debug "Récupération des status Git (-z) réussie. " + Str(ListSize(main\Files())) + " fichiers (maj/ajout)."
ProcedureReturn #True
EndProcedure
Procedure IsGitRepository()
If Git("status") <> 0
ProcedureReturn #False
@@ -1233,12 +1488,24 @@ Procedure RefreshFiles()
main\hasRemoteUrl=#True
GetGitRemoteBranch()
RefreshRemoteBranchesList(#GID_CbRemoteBranch)
Debug "###################################"
GetRemoteStatusInfo()
Else
SetGadgetText(#GID_EdRemote,"")
main\hasRemoteUrl=#False
ClearGadgetItems(#GID_CbRemoteBranch)
EndIf
EndIf
;Get Status
ForEach main\Files()
main\Files()\importance = GetStatusImportance(main\Files()\status)
Next
;Sort by Importance
SortStructuredList(main\Files(), #PB_Sort_Descending, OffsetOf(FilesStruct\importance), #PB_Integer)
;Display list
Protected n.l=n-1
ForEach main\Files()
n=n+1
@@ -1369,7 +1636,10 @@ Procedure Main()
; TODO: ignore
Case #GID_BtnCommit
DoCommit()
If DoCommit()=#True
SetGadgetText(#GID_EdMessage,"")
RefreshFiles()
EndIf
Case #GID_BtnSaveGitIgnore
; TODO: save .gitignore
@@ -1387,8 +1657,8 @@ EndProcedure
Main()
; IDE Options = PureBasic 6.21 (Windows - x64)
; CursorPosition = 924
; FirstLine = 904
; Folding = ------
; CursorPosition = 224
; FirstLine = 211
; Folding = ----4--
; EnableXP
; DPIAware