set file colour in sln explorer based on git status
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
<PackageVersion Include="ClrDebug" Version="0.3.4" />
|
<PackageVersion Include="ClrDebug" Version="0.3.4" />
|
||||||
<PackageVersion Include="FileWatcherEx" Version="2.7.0" />
|
<PackageVersion Include="FileWatcherEx" Version="2.7.0" />
|
||||||
<PackageVersion Include="Krafs.Publicizer" Version="2.3.0" />
|
<PackageVersion Include="Krafs.Publicizer" Version="2.3.0" />
|
||||||
|
<PackageVersion Include="LibGit2Sharp" Version="0.31.0" />
|
||||||
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="10.0.0-rc.2.25502.107" />
|
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="10.0.0-rc.2.25502.107" />
|
||||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebView" Version="10.0.0-rc.2.25502.107" />
|
<PackageVersion Include="Microsoft.AspNetCore.Components.WebView" Version="10.0.0-rc.2.25502.107" />
|
||||||
<PackageVersion Include="Microsoft.Build" Version="18.1.0-preview-25521-106" />
|
<PackageVersion Include="Microsoft.Build" Version="18.1.0-preview-25521-106" />
|
||||||
@@ -59,4 +60,4 @@
|
|||||||
<PackageVersion Include="Microsoft.CodeAnalysis.ExternalAccess.Razor.Features" Version="5.3.0-1.25521.106" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.ExternalAccess.Razor.Features" Version="5.3.0-1.25521.106" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.Remote.ServiceHub" Version="5.3.0-1.25521.106" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.Remote.ServiceHub" Version="5.3.0-1.25521.106" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -17,6 +17,7 @@ public class SharpIdeFile : ISharpIdeNode, IChildSharpIdeNode, IFileOrFolder
|
|||||||
public bool IsCshtmlFile => Path.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase);
|
public bool IsCshtmlFile => Path.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase);
|
||||||
public bool IsCsharpFile => Path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase);
|
public bool IsCsharpFile => Path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase);
|
||||||
public bool IsRoslynWorkspaceFile => IsCsharpFile || IsRazorFile || IsCshtmlFile;
|
public bool IsRoslynWorkspaceFile => IsCsharpFile || IsRazorFile || IsCshtmlFile;
|
||||||
|
public GitStatus GitStatus { get; set; } = GitStatus.Unaltered;
|
||||||
public required ReactiveProperty<bool> IsDirty { get; init; }
|
public required ReactiveProperty<bool> IsDirty { get; init; }
|
||||||
public required bool SuppressDiskChangeEvents { get; set; } // probably has concurrency issues
|
public required bool SuppressDiskChangeEvents { get; set; } // probably has concurrency issues
|
||||||
public required DateTimeOffset? LastIdeWriteTime { get; set; }
|
public required DateTimeOffset? LastIdeWriteTime { get; set; }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using LibGit2Sharp;
|
||||||
|
|
||||||
namespace SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
namespace SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||||
|
|
||||||
@@ -11,7 +12,34 @@ public static class VsPersistenceMapper
|
|||||||
var intermediateModel = await IntermediateMapper.GetIntermediateModel(solutionFilePath, cancellationToken);
|
var intermediateModel = await IntermediateMapper.GetIntermediateModel(solutionFilePath, cancellationToken);
|
||||||
|
|
||||||
var solutionModel = new SharpIdeSolutionModel(solutionFilePath, intermediateModel);
|
var solutionModel = new SharpIdeSolutionModel(solutionFilePath, intermediateModel);
|
||||||
|
using var repo = new Repository(solutionModel.DirectoryPath);
|
||||||
|
var status = repo.RetrieveStatus(new StatusOptions());
|
||||||
|
|
||||||
|
foreach (var entry in status.Where(s => s.State is not FileStatus.Ignored))
|
||||||
|
{
|
||||||
|
// Assumes solution file is at git repo root
|
||||||
|
var filePath = new FileInfo(Path.Combine(solutionModel.DirectoryPath, entry.FilePath)).FullName; // used to normalise path separators
|
||||||
|
var fileInSolution = solutionModel.AllFiles.SingleOrDefault(f => f.Path.Equals(filePath, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (fileInSolution is null) continue;
|
||||||
|
|
||||||
|
var mappedGitStatus = entry.State switch
|
||||||
|
{
|
||||||
|
FileStatus.NewInIndex | FileStatus.ModifiedInWorkdir => GitStatus.Added, // I've seen these appear together
|
||||||
|
FileStatus.NewInIndex or FileStatus.NewInWorkdir => GitStatus.Added,
|
||||||
|
FileStatus.ModifiedInIndex or FileStatus.ModifiedInWorkdir => GitStatus.Modified,
|
||||||
|
_ => GitStatus.Unaltered // TODO: handle other kinds?
|
||||||
|
};
|
||||||
|
|
||||||
|
fileInSolution.GitStatus = mappedGitStatus;
|
||||||
|
}
|
||||||
|
|
||||||
return solutionModel;
|
return solutionModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum GitStatus
|
||||||
|
{
|
||||||
|
Unaltered,
|
||||||
|
Modified,
|
||||||
|
Added
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CliWrap" />
|
<PackageReference Include="CliWrap" />
|
||||||
<PackageReference Include="FileWatcherEx" />
|
<PackageReference Include="FileWatcherEx" />
|
||||||
|
<PackageReference Include="LibGit2Sharp" />
|
||||||
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" PrivateAssets="all" />
|
||||||
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" />
|
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Shared.VSCodeDebugProtocol" />
|
<PackageReference Include="Microsoft.VisualStudio.Shared.VSCodeDebugProtocol" />
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ public partial class SolutionExplorerPanel : MarginContainer
|
|||||||
public Texture2D SlnIcon { get; set; } = null!;
|
public Texture2D SlnIcon { get; set; } = null!;
|
||||||
|
|
||||||
private readonly Color _gitNewFileColour = new Color("50964c");
|
private readonly Color _gitNewFileColour = new Color("50964c");
|
||||||
private readonly Color _gitEditedFileColour = new Color("5988b3");
|
private readonly Color _gitEditedFileColour = new Color("6496ba");
|
||||||
|
private readonly Color _gitUnalteredFileColour = new Color("d4d4d4");
|
||||||
|
|
||||||
public SharpIdeSolutionModel SolutionModel { get; set; } = null!;
|
public SharpIdeSolutionModel SolutionModel { get; set; } = null!;
|
||||||
private Tree _tree = null!;
|
private Tree _tree = null!;
|
||||||
@@ -286,7 +287,8 @@ public partial class SolutionExplorerPanel : MarginContainer
|
|||||||
{
|
{
|
||||||
var fileItem = tree.CreateItem(parent);
|
var fileItem = tree.CreateItem(parent);
|
||||||
fileItem.SetText(0, sharpIdeFile.Name);
|
fileItem.SetText(0, sharpIdeFile.Name);
|
||||||
fileItem.SetIcon(0, CsharpFileIcon);
|
fileItem.SetIcon(0, CsharpFileIcon);
|
||||||
|
fileItem.SetCustomColor(0, GetColorForGitStatus(sharpIdeFile.GitStatus));
|
||||||
fileItem.SetMetadata(0, new RefCountedContainer<SharpIdeFile>(sharpIdeFile));
|
fileItem.SetMetadata(0, new RefCountedContainer<SharpIdeFile>(sharpIdeFile));
|
||||||
|
|
||||||
Observable.EveryValueChanged(sharpIdeFile, folder => folder.Name)
|
Observable.EveryValueChanged(sharpIdeFile, folder => folder.Name)
|
||||||
@@ -302,4 +304,12 @@ public partial class SolutionExplorerPanel : MarginContainer
|
|||||||
{
|
{
|
||||||
await this.InvokeAsync(() => item?.Free());
|
await this.InvokeAsync(() => item?.Free());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Color GetColorForGitStatus(GitStatus status) => status switch
|
||||||
|
{
|
||||||
|
GitStatus.Added => _gitNewFileColour,
|
||||||
|
GitStatus.Modified => _gitEditedFileColour,
|
||||||
|
GitStatus.Unaltered => _gitUnalteredFileColour,
|
||||||
|
_ => _gitUnalteredFileColour
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user