From 0eaa7d35ff7b14b998ce3de91118617381748a5b Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 8 Jul 2025 20:25:21 +0800 Subject: [PATCH] feature: add hotkeys to save revision file Signed-off-by: leo --- src/ViewModels/CommitDetail.cs | 53 ++++++++++++++----------- src/Views/RevisionFileTreeView.axaml.cs | 11 +++++ 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index d3f338be..56084f30 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -254,6 +254,33 @@ namespace SourceGit.ViewModels new Commands.DiffTool(_repo.FullPath, toolType, toolPath, opt).Open(); } + public async Task SaveRevisionFile(Models.Object file) + { + var storageProvider = App.GetStorageProvider(); + if (storageProvider == null) + return; + + var options = new FolderPickerOpenOptions() { AllowMultiple = false }; + try + { + var selected = await storageProvider.OpenFolderPickerAsync(options); + if (selected.Count == 1) + { + var folder = selected[0]; + var folderPath = folder is { Path: { IsAbsoluteUri: true } path } ? path.LocalPath : folder.Path.ToString(); + var saveTo = Path.Combine(folderPath, Path.GetFileName(file.Path)!); + + await Commands.SaveRevisionFile + .RunAsync(_repo.FullPath, _commit.SHA, file.Path, saveTo) + .ConfigureAwait(false); + } + } + catch (Exception e) + { + App.RaiseException(_repo.FullPath, $"Failed to save file: {e.Message}"); + } + } + public ContextMenu CreateChangeContextMenuByFolder(ChangeTreeNode node, List changes) { var fullPath = Native.OS.GetAbsPath(_repo.FullPath, node.FullPath); @@ -540,32 +567,10 @@ namespace SourceGit.ViewModels saveAs.Header = App.Text("SaveAs"); saveAs.Icon = App.CreateMenuIcon("Icons.Save"); saveAs.IsEnabled = file.Type == Models.ObjectType.Blob; + saveAs.Tag = OperatingSystem.IsMacOS() ? "⌘+S" : "Ctrl+S"; saveAs.Click += async (_, ev) => { - var storageProvider = App.GetStorageProvider(); - if (storageProvider == null) - return; - - var options = new FolderPickerOpenOptions() { AllowMultiple = false }; - try - { - var selected = await storageProvider.OpenFolderPickerAsync(options); - if (selected.Count == 1) - { - var folder = selected[0]; - var folderPath = folder is { Path: { IsAbsoluteUri: true } path } ? path.LocalPath : folder.Path.ToString(); - var saveTo = Path.Combine(folderPath, Path.GetFileName(file.Path)!); - - await Commands.SaveRevisionFile - .RunAsync(_repo.FullPath, _commit.SHA, file.Path, saveTo) - .ConfigureAwait(false); - } - } - catch (Exception e) - { - App.RaiseException(_repo.FullPath, $"Failed to save file: {e.Message}"); - } - + await SaveRevisionFile(file); ev.Handled = true; }; diff --git a/src/Views/RevisionFileTreeView.axaml.cs b/src/Views/RevisionFileTreeView.axaml.cs index c71be771..cd126a25 100644 --- a/src/Views/RevisionFileTreeView.axaml.cs +++ b/src/Views/RevisionFileTreeView.axaml.cs @@ -132,6 +132,17 @@ namespace SourceGit.Views e.Handled = true; } } + else if (node.Backend is { Type: Models.ObjectType.Blob } file && + e.Key == Key.S && + e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control)) + { + var detailView = this.FindAncestorOfType(); + if (detailView is { DataContext: ViewModels.CommitDetail detail }) + { + await detail.SaveRevisionFile(file); + e.Handled = true; + } + } } if (!e.Handled)