Skip to content

Commit ef14642

Browse files
committed
feature: add hotkey Alt+Down/⌥+Down to goto parent of selected commit (#2104)
Signed-off-by: leo <longshuang@msn.cn>
1 parent c624fbf commit ef14642

File tree

10 files changed

+240
-5
lines changed

10 files changed

+240
-5
lines changed

src/Resources/Locales/en_US.axaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@
467467
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Remote:</x:String>
468468
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Track files named '{0}'</x:String>
469469
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Track all *{0} files</x:String>
470+
<x:String x:Key="Text.GotoParentSelector" xml:space="preserve">Select Parent</x:String>
470471
<x:String x:Key="Text.Histories" xml:space="preserve">HISTORY</x:String>
471472
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">AUTHOR</x:String>
472473
<x:String x:Key="Text.Histories.Header.AuthorTime" xml:space="preserve">AUTHOR TIME</x:String>
@@ -496,6 +497,7 @@
496497
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">Stage all changes and commit</x:String>
497498
<x:String x:Key="Text.Hotkeys.Repo.Fetch" xml:space="preserve">Fetch, starts directly</x:String>
498499
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">Dashboard mode (Default)</x:String>
500+
<x:String x:Key="Text.Hotkeys.Repo.GoToParent" xml:space="preserve">Goto parent of selected commit</x:String>
499501
<x:String x:Key="Text.Hotkeys.Repo.OpenCommandPalette" xml:space="preserve">Open command palette</x:String>
500502
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">Commit search mode</x:String>
501503
<x:String x:Key="Text.Hotkeys.Repo.Pull" xml:space="preserve">Pull, starts directly</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@
471471
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">远程 :</x:String>
472472
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">跟踪名为'{0}'的文件</x:String>
473473
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">跟踪所有 *{0} 文件</x:String>
474+
<x:String x:Key="Text.GotoParentSelector" xml:space="preserve">选择前往的父提交</x:String>
474475
<x:String x:Key="Text.Histories" xml:space="preserve">历史记录</x:String>
475476
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">作者</x:String>
476477
<x:String x:Key="Text.Histories.Header.AuthorTime" xml:space="preserve">修改时间</x:String>
@@ -500,6 +501,7 @@
500501
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">自动暂存全部变更并提交</x:String>
501502
<x:String x:Key="Text.Hotkeys.Repo.Fetch" xml:space="preserve">拉取 (fetch) 远程变更</x:String>
502503
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">切换左边栏为分支/标签等显示模式(默认)</x:String>
504+
<x:String x:Key="Text.Hotkeys.Repo.GoToParent" xml:space="preserve">前往选中提交的父提交</x:String>
503505
<x:String x:Key="Text.Hotkeys.Repo.OpenCommandPalette" xml:space="preserve">打开快捷命令面板</x:String>
504506
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">切换左边栏为提交搜索模式</x:String>
505507
<x:String x:Key="Text.Hotkeys.Repo.Pull" xml:space="preserve">拉回 (pull) 远程变更</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@
471471
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">遠端存放庫:</x:String>
472472
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">追蹤名稱為「{0}」的檔案</x:String>
473473
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">追蹤所有 *{0} 檔案</x:String>
474+
<x:String x:Key="Text.GotoParentSelector" xml:space="preserve">選取要前往的父提交</x:String>
474475
<x:String x:Key="Text.Histories" xml:space="preserve">歷史記錄</x:String>
475476
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">作者</x:String>
476477
<x:String x:Key="Text.Histories.Header.AuthorTime" xml:space="preserve">修改時間</x:String>
@@ -500,6 +501,7 @@
500501
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">自動暫存全部變更並提交</x:String>
501502
<x:String x:Key="Text.Hotkeys.Repo.Fetch" xml:space="preserve">提取 (fetch) 遠端的變更</x:String>
502503
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">切換左邊欄為分支/標籤等顯示模式 (預設)</x:String>
504+
<x:String x:Key="Text.Hotkeys.Repo.GoToParent" xml:space="preserve">前往所選提交的父提交</x:String>
503505
<x:String x:Key="Text.Hotkeys.Repo.OpenCommandPalette" xml:space="preserve">開啟命令面板</x:String>
504506
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">切換左邊欄為歷史搜尋模式</x:String>
505507
<x:String x:Key="Text.Hotkeys.Repo.Pull" xml:space="preserve">拉取 (pull) 遠端的變更</x:String>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
3+
namespace SourceGit.ViewModels
4+
{
5+
public class GotoParentSelector
6+
{
7+
public List<Models.Commit> Parents
8+
{
9+
get;
10+
}
11+
12+
public GotoParentSelector(Histories owner, List<Models.Commit> parents)
13+
{
14+
Parents = parents;
15+
_owner = owner;
16+
}
17+
18+
public void Sure(Models.Commit commit)
19+
{
20+
_owner.NavigateTo(commit.SHA);
21+
}
22+
23+
private Histories _owner;
24+
}
25+
}

src/ViewModels/Histories.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,13 @@ public void Select(IList commits)
254254
}
255255
}
256256

257+
public async Task<Models.Commit> GetCommitAsync(string sha)
258+
{
259+
return await new Commands.QuerySingleCommit(_repo.FullPath, sha)
260+
.GetResultAsync()
261+
.ConfigureAwait(false);
262+
}
263+
257264
public async Task<bool> CheckoutBranchByDecoratorAsync(Models.Decorator decorator)
258265
{
259266
if (decorator == null)

src/Views/GotoParentSelector.axaml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<v:ChromelessWindow xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:m="using:SourceGit.Models"
6+
xmlns:v="using:SourceGit.Views"
7+
xmlns:vm="using:SourceGit.ViewModels"
8+
xmlns:c="using:SourceGit.Converters"
9+
mc:Ignorable="d" d:DesignWidth="520" d:DesignHeight="230"
10+
x:Class="SourceGit.Views.GotoParentSelector"
11+
x:DataType="vm:GotoParentSelector"
12+
x:Name="ThisControl"
13+
Icon="/App.ico"
14+
Title="{DynamicResource Text.GotoParentSelector}"
15+
Width="600" SizeToContent="Height"
16+
CanResize="False"
17+
WindowStartupLocation="CenterOwner">
18+
<Grid RowDefinitions="Auto,Auto">
19+
<!-- TitleBar -->
20+
<Grid Grid.Row="0" Height="28" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}">
21+
<Border Background="{DynamicResource Brush.TitleBar}"
22+
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
23+
PointerPressed="BeginMoveWindow"/>
24+
25+
<Path Width="14" Height="14"
26+
Margin="10,0,0,0"
27+
HorizontalAlignment="Left"
28+
Data="{StaticResource Icons.GotoParent}"
29+
IsVisible="{OnPlatform True, macOS=False}"/>
30+
31+
<TextBlock Classes="bold"
32+
Text="{DynamicResource Text.GotoParentSelector}"
33+
HorizontalAlignment="Center" VerticalAlignment="Center"
34+
IsHitTestVisible="False"/>
35+
36+
<v:CaptionButtons HorizontalAlignment="Right"
37+
IsCloseButtonOnly="True"
38+
IsVisible="{OnPlatform True, macOS=False}"/>
39+
</Grid>
40+
41+
<ListBox Grid.Row="1"
42+
Focusable="True"
43+
Margin="8" Padding="4"
44+
ItemsSource="{Binding Parents}"
45+
SelectionMode="AlwaysSelected"
46+
BorderThickness="0"
47+
Background="Transparent"
48+
Grid.IsSharedSizeScope="True"
49+
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
50+
ScrollViewer.VerticalScrollBarVisibility="Disabled"
51+
Loaded="OnListLoaded"
52+
KeyDown="OnListKeyDown">
53+
<ListBox.Styles>
54+
<Style Selector="ListBoxItem">
55+
<Setter Property="Margin" Value="0"/>
56+
<Setter Property="Padding" Value="0"/>
57+
<Setter Property="Height" Value="28"/>
58+
<Setter Property="CornerRadius" Value="4"/>
59+
</Style>
60+
</ListBox.Styles>
61+
62+
<ListBox.ItemsPanel>
63+
<ItemsPanelTemplate>
64+
<StackPanel Orientation="Vertical" Spacing="2"/>
65+
</ItemsPanelTemplate>
66+
</ListBox.ItemsPanel>
67+
68+
<ListBox.ItemTemplate>
69+
<DataTemplate DataType="m:Commit">
70+
<Grid Background="Transparent" Tapped="OnListItemTapped">
71+
<Grid.ColumnDefinitions>
72+
<ColumnDefinition Width="24"/>
73+
<ColumnDefinition Width="*"/>
74+
<ColumnDefinition Width="Auto" SharedSizeGroup="CommitSHAColumn"/>
75+
<ColumnDefinition Width="Auto" SharedSizeGroup="CommitTimeColumn"/>
76+
</Grid.ColumnDefinitions>
77+
78+
<v:Avatar Grid.Column="0"
79+
Width="16" Height="16"
80+
HorizontalAlignment="Center" VerticalAlignment="Center"
81+
IsHitTestVisible="False"
82+
User="{Binding Author}"/>
83+
84+
<Border Grid.Column="1" Margin="2,0,0,0" ClipToBounds="True">
85+
<TextBlock Text="{Binding Subject}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"/>
86+
</Border>
87+
88+
<TextBlock Grid.Column="2"
89+
Margin="4,0,0,0"
90+
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
91+
Foreground="DarkOrange"
92+
VerticalAlignment="Center"/>
93+
94+
<TextBlock Grid.Column="3"
95+
Margin="4,0"
96+
Text="{Binding CommitterTimeShortStr}"
97+
HorizontalAlignment="Right" VerticalAlignment="Center"/>
98+
</Grid>
99+
</DataTemplate>
100+
</ListBox.ItemTemplate>
101+
</ListBox>
102+
</Grid>
103+
</v:ChromelessWindow>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Avalonia.Controls;
2+
using Avalonia.Input;
3+
using Avalonia.Interactivity;
4+
5+
namespace SourceGit.Views
6+
{
7+
public partial class GotoParentSelector : ChromelessWindow
8+
{
9+
public GotoParentSelector()
10+
{
11+
CloseOnESC = true;
12+
InitializeComponent();
13+
}
14+
15+
private void OnListLoaded(object sender, RoutedEventArgs e)
16+
{
17+
(sender as ListBox)?.Focus();
18+
}
19+
20+
private void OnListKeyDown(object sender, KeyEventArgs e)
21+
{
22+
if (e is not { Key: Key.Enter, KeyModifiers: KeyModifiers.None })
23+
return;
24+
25+
if (DataContext is not ViewModels.GotoParentSelector vm)
26+
return;
27+
28+
if (sender is not ListBox { SelectedItem: Models.Commit commit })
29+
return;
30+
31+
vm.Sure(commit);
32+
Close();
33+
e.Handled = true;
34+
}
35+
36+
private void OnListItemTapped(object sender, TappedEventArgs e)
37+
{
38+
if (sender is not Control { DataContext: Models.Commit commit })
39+
return;
40+
41+
if (DataContext is ViewModels.GotoParentSelector vm)
42+
vm.Sure(commit);
43+
44+
Close();
45+
e.Handled = true;
46+
}
47+
}
48+
}
49+

src/Views/Histories.axaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
</v:HistoriesLayout.ColumnDefinitions>
2525

2626
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
27+
<!-- DataGrid hardcodes all the arrow keys, so we need a fake button to intercept this shortcut key -->
28+
<Button Width="0" Height="0"
29+
Click="OnGotoParent"
30+
HotKey="Alt+Down"
31+
IsVisible="False"/>
32+
2733
<DataGrid x:Name="CommitListContainer"
2834
Classes="static_scrollbar"
2935
ScrollViewer.AllowAutoHide="False"

src/Views/Histories.axaml.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,42 @@ private void OnCommitListLoaded(object sender, RoutedEventArgs e)
159159
dataGrid.ScrollIntoView(dataGrid.SelectedItem, null);
160160
}
161161

162+
private async void OnGotoParent(object sender, RoutedEventArgs e)
163+
{
164+
if (DataContext is not ViewModels.Histories vm)
165+
return;
166+
167+
if (!CommitListContainer.IsKeyboardFocusWithin)
168+
return;
169+
170+
if (CommitListContainer.SelectedItems is not { Count: 1 } selected)
171+
return;
172+
173+
if (selected[0] is not Models.Commit { Parents.Count: > 0 } commit)
174+
return;
175+
176+
e.Handled = true;
177+
178+
if (commit.Parents.Count == 1)
179+
{
180+
vm.NavigateTo(commit.Parents[0]);
181+
return;
182+
}
183+
184+
var parents = new List<Models.Commit>();
185+
foreach (var sha in commit.Parents)
186+
{
187+
var c = await vm.GetCommitAsync(sha);
188+
if (c != null)
189+
parents.Add(c);
190+
}
191+
192+
if (parents.Count == 1)
193+
vm.NavigateTo(parents[0].SHA);
194+
else if (parents.Count > 1)
195+
await App.ShowDialog(new ViewModels.GotoParentSelector(vm, parents));
196+
}
197+
162198
private void OnCommitListLayoutUpdated(object _1, EventArgs _2)
163199
{
164200
if (!IsLoaded)
@@ -513,7 +549,7 @@ private ContextMenu CreateContextMenuForMultipleCommits(ViewModels.Repository re
513549
var messages = new List<string>();
514550
foreach (var c in selected)
515551
{
516-
var message = await vm.GetCommitFullMessageAsync(c);
552+
var message = await vm!.GetCommitFullMessageAsync(c);
517553
messages.Add(message);
518554
}
519555

src/Views/Hotkeys.axaml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Increase}}"
8484
Margin="0,8"/>
8585

86-
<Grid RowDefinitions="20,20,20,20,20,20,20,20,20,20,20,20,20" ColumnDefinitions="150,*">
86+
<Grid RowDefinitions="20,20,20,20,20,20,20,20,20,20,20,20,20,20" ColumnDefinitions="150,*">
8787
<TextBlock Grid.Row="0" Grid.Column="0" Classes="bold" Text="{OnPlatform Ctrl+Shift+H, macOS=⌘+⇧+H}"/>
8888
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.GoHome}" />
8989

@@ -119,9 +119,12 @@
119119

120120
<TextBlock Grid.Row="11" Grid.Column="0" Classes="bold" Text="{OnPlatform Ctrl+Shift+P, macOS=⌘+⇧+P}"/>
121121
<TextBlock Grid.Row="11" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.OpenCommandPalette}" />
122-
123-
<TextBlock Grid.Row="12" Grid.Column="0" Classes="bold" Text="F5"/>
124-
<TextBlock Grid.Row="12" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Refresh}" />
122+
123+
<TextBlock Grid.Row="12" Grid.Column="0" Classes="bold" Text="{OnPlatform Alt+Down, macOS=⌥+Down}"/>
124+
<TextBlock Grid.Row="12" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.GoToParent}" />
125+
126+
<TextBlock Grid.Row="13" Grid.Column="0" Classes="bold" Text="F5"/>
127+
<TextBlock Grid.Row="13" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Refresh}" />
125128
</Grid>
126129

127130
<TextBlock Text="{DynamicResource Text.Hotkeys.TextEditor}"

0 commit comments

Comments
 (0)