From 7f838f1f88ddd1cbac25694c92383b3332281273 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 8 Jul 2025 20:05:37 +0800 Subject: [PATCH] feature: add hotkeys to open file with default editor Signed-off-by: leo --- src/ViewModels/CommitDetail.cs | 1 + src/ViewModels/WorkingCopy.cs | 13 +++++++++++-- src/Views/RevisionFiles.axaml | 9 ++++++++- src/Views/WorkingCopy.axaml.cs | 34 +++++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 8c9fdc9e..d3f338be 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -528,6 +528,7 @@ namespace SourceGit.ViewModels var openWith = new MenuItem(); openWith.Header = App.Text("OpenWith"); openWith.Icon = App.CreateMenuIcon("Icons.OpenWith"); + openWith.Tag = OperatingSystem.IsMacOS() ? "⌘+O" : "Ctrl+O"; openWith.IsEnabled = file.Type == Models.ObjectType.Blob; openWith.Click += async (_, ev) => { diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 901b19a0..d8ec3326 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -328,6 +328,13 @@ namespace SourceGit.ViewModels }); } + public void OpenWithDefaultEditor(Models.Change c) + { + var absPath = Native.OS.GetAbsPath(_repo.FullPath, c.Path); + if (File.Exists(absPath)) + Native.OS.OpenWithDefaultEditor(absPath); + } + public void StashAll(bool autoStart) { if (!_repo.CanCreatePopup()) @@ -609,10 +616,11 @@ namespace SourceGit.ViewModels var openWith = new MenuItem(); openWith.Header = App.Text("OpenWith"); openWith.Icon = App.CreateMenuIcon("Icons.OpenWith"); + openWith.Tag = OperatingSystem.IsMacOS() ? "⌘+O" : "Ctrl+O"; openWith.IsEnabled = File.Exists(path); openWith.Click += (_, e) => { - Native.OS.OpenWithDefaultEditor(path); + OpenWithDefaultEditor(change); e.Handled = true; }; menu.Items.Add(openWith); @@ -1293,10 +1301,11 @@ namespace SourceGit.ViewModels var openWith = new MenuItem(); openWith.Header = App.Text("OpenWith"); openWith.Icon = App.CreateMenuIcon("Icons.OpenWith"); + openWith.Tag = OperatingSystem.IsMacOS() ? "⌘+O" : "Ctrl+O"; openWith.IsEnabled = File.Exists(path); openWith.Click += (_, e) => { - Native.OS.OpenWithDefaultEditor(path); + OpenWithDefaultEditor(change); e.Handled = true; }; diff --git a/src/Views/RevisionFiles.axaml b/src/Views/RevisionFiles.axaml index 961a05b5..b9842da3 100644 --- a/src/Views/RevisionFiles.axaml +++ b/src/Views/RevisionFiles.axaml @@ -149,7 +149,14 @@ Background="Transparent" Click="OnOpenFileWithDefaultEditor" IsVisible="{Binding CanOpenRevisionFileWithDefaultEditor, Mode=OneWay}" - ToolTip.Tip="{DynamicResource Text.OpenWith}"> + HotKey="{OnPlatform Ctrl+O, macOS=⌘+O}"> + + + + + + + diff --git a/src/Views/WorkingCopy.axaml.cs b/src/Views/WorkingCopy.axaml.cs index 4b25590c..409da98d 100644 --- a/src/Views/WorkingCopy.axaml.cs +++ b/src/Views/WorkingCopy.axaml.cs @@ -1,3 +1,4 @@ +using System; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; @@ -96,12 +97,17 @@ namespace SourceGit.Views vm.StageSelected(next); UnstagedChangesView.TakeFocus(); e.Handled = true; - return; } - - if (e.Key is Key.Delete or Key.Back && vm.SelectedUnstaged is { Count: > 0 } selected) + else if (e.Key is Key.Delete or Key.Back && vm.SelectedUnstaged is { Count: > 0 }) { - vm.Discard(selected); + vm.Discard(vm.SelectedUnstaged); + e.Handled = true; + } + else if (e.Key is Key.O && + e.KeyModifiers == (OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control) && + vm.SelectedUnstaged is { Count: 1 }) + { + vm.OpenWithDefaultEditor(vm.SelectedUnstaged[0]); e.Handled = true; } } @@ -109,12 +115,22 @@ namespace SourceGit.Views private void OnStagedKeyDown(object _, KeyEventArgs e) { - if (DataContext is ViewModels.WorkingCopy vm && e.Key is Key.Space or Key.Enter) + if (DataContext is ViewModels.WorkingCopy vm) { - var next = StagedChangesView.GetNextChangeWithoutSelection(); - vm.UnstageSelected(next); - StagedChangesView.TakeFocus(); - e.Handled = true; + if (e.Key is Key.Space or Key.Enter) + { + var next = StagedChangesView.GetNextChangeWithoutSelection(); + vm.UnstageSelected(next); + StagedChangesView.TakeFocus(); + e.Handled = true; + } + else if (e.Key is Key.O && + e.KeyModifiers == (OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control) && + vm.SelectedStaged is { Count: 1 }) + { + vm.OpenWithDefaultEditor(vm.SelectedStaged[0]); + e.Handled = true; + } } }