From efa6e46471bd7a700c3fb3c71a54e06b1034342f Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 17 Jun 2025 12:20:02 +0800 Subject: [PATCH] feature: add a button to open current revision file with default editor Signed-off-by: leo --- src/ViewModels/CommitDetail.cs | 32 +++++++++++++++++++++++++++----- src/Views/RevisionFiles.axaml | 14 ++++++++++++-- src/Views/RevisionFiles.axaml.cs | 9 +++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index fbecf30e..65719293 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -133,6 +133,12 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _revisionFileSearchSuggestion, value); } + public bool CanOpenRevisionFileWithDefaultEditor + { + get => _canOpenRevisionFileWithDefaultEditor; + private set => SetProperty(ref _canOpenRevisionFileWithDefaultEditor, value); + } + public CommitDetail(Repository repo) { _repo = repo; @@ -197,6 +203,7 @@ namespace SourceGit.ViewModels { ViewRevisionFilePath = string.Empty; ViewRevisionFileContent = null; + CanOpenRevisionFileWithDefaultEditor = false; return; } @@ -205,6 +212,7 @@ namespace SourceGit.ViewModels switch (file.Type) { case Models.ObjectType.Blob: + CanOpenRevisionFileWithDefaultEditor = true; Task.Run(() => { var isBinary = new Commands.IsBinary(_repo.FullPath, _commit.SHA, file.Path).Result(); @@ -252,6 +260,7 @@ namespace SourceGit.ViewModels }); break; case Models.ObjectType.Commit: + CanOpenRevisionFileWithDefaultEditor = false; Task.Run(() => { var submoduleRoot = Path.Combine(_repo.FullPath, file.Path).Replace('\\', '/').Trim('/'); @@ -267,11 +276,26 @@ namespace SourceGit.ViewModels }); break; default: + CanOpenRevisionFileWithDefaultEditor = false; ViewRevisionFileContent = null; break; } } + public Task OpenRevisionFileWithDefaultEditor(string file) + { + return Task.Run(() => + { + var fullPath = Native.OS.GetAbsPath(_repo.FullPath, file); + var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? ""; + var fileExt = Path.GetExtension(fullPath) ?? ""; + var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_commit.SHA.Substring(0, 10)}{fileExt}"); + + Commands.SaveRevisionFile.Run(_repo.FullPath, _commit.SHA, file, tmpFile); + Native.OS.OpenWithDefaultEditor(tmpFile); + }); + } + public ContextMenu CreateChangeContextMenu(Models.Change change) { var diffWithMerger = new MenuItem(); @@ -421,13 +445,10 @@ namespace SourceGit.ViewModels var openWith = new MenuItem(); openWith.Header = App.Text("OpenWith"); openWith.Icon = App.CreateMenuIcon("Icons.OpenWith"); + openWith.IsEnabled = file.Type == Models.ObjectType.Blob; openWith.Click += async (_, ev) => { - var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? ""; - var fileExt = Path.GetExtension(fullPath) ?? ""; - var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_commit.SHA.Substring(0, 10)}{fileExt}"); - await Task.Run(() => Commands.SaveRevisionFile.Run(_repo.FullPath, _commit.SHA, file.Path, tmpFile)); - Native.OS.OpenWithDefaultEditor(tmpFile); + await OpenRevisionFileWithDefaultEditor(file.Path); ev.Handled = true; }; @@ -887,5 +908,6 @@ namespace SourceGit.ViewModels private List _revisionFiles = null; private string _revisionFileSearchFilter = string.Empty; private List _revisionFileSearchSuggestion = null; + private bool _canOpenRevisionFileWithDefaultEditor = false; } } diff --git a/src/Views/RevisionFiles.axaml b/src/Views/RevisionFiles.axaml index 5b512060..961a05b5 100644 --- a/src/Views/RevisionFiles.axaml +++ b/src/Views/RevisionFiles.axaml @@ -119,7 +119,7 @@ Height="26" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" IsVisible="{Binding ViewRevisionFilePath, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> - + - + + + diff --git a/src/Views/RevisionFiles.axaml.cs b/src/Views/RevisionFiles.axaml.cs index 3208fbb8..4894d1d4 100644 --- a/src/Views/RevisionFiles.axaml.cs +++ b/src/Views/RevisionFiles.axaml.cs @@ -1,5 +1,6 @@ using Avalonia.Controls; using Avalonia.Input; +using Avalonia.Interactivity; namespace SourceGit.Views { @@ -80,5 +81,13 @@ namespace SourceGit.Views e.Handled = true; } + + private async void OnOpenFileWithDefaultEditor(object sender, RoutedEventArgs e) + { + if (DataContext is ViewModels.CommitDetail { CanOpenRevisionFileWithDefaultEditor: true } vm) + await vm.OpenRevisionFileWithDefaultEditor(vm.ViewRevisionFilePath); + + e.Handled = true; + } } }