feature: add Use context menu entry to apply selected text as commit message

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo
2026-03-26 16:19:50 +08:00
parent 3b6342dc6a
commit bc0f86b4ba
7 changed files with 28 additions and 18 deletions

View File

@@ -20,6 +20,7 @@
<x:String x:Key="Text.AIAssistant" xml:space="preserve">AI Assistant</x:String>
<x:String x:Key="Text.AIAssistant.Regen" xml:space="preserve">RE-GENERATE</x:String>
<x:String x:Key="Text.AIAssistant.Tip" xml:space="preserve">Use AI to generate commit message</x:String>
<x:String x:Key="Text.AIAssistant.Use" xml:space="preserve">Use</x:String>
<x:String x:Key="Text.App.Hide" xml:space="preserve">Hide SourceGit</x:String>
<x:String x:Key="Text.App.ShowAll" xml:space="preserve">Show All</x:String>
<x:String x:Key="Text.Apply" xml:space="preserve">Patch</x:String>

View File

@@ -24,6 +24,7 @@
<x:String x:Key="Text.AIAssistant" xml:space="preserve">AI助手</x:String>
<x:String x:Key="Text.AIAssistant.Regen" xml:space="preserve">重新生成</x:String>
<x:String x:Key="Text.AIAssistant.Tip" xml:space="preserve">使用AI助手生成提交信息</x:String>
<x:String x:Key="Text.AIAssistant.Use" xml:space="preserve">应用所选</x:String>
<x:String x:Key="Text.App.Hide" xml:space="preserve">隐藏 SourceGit</x:String>
<x:String x:Key="Text.App.ShowAll" xml:space="preserve">显示所有窗口</x:String>
<x:String x:Key="Text.Apply" xml:space="preserve">应用补丁(apply)</x:String>

View File

@@ -24,6 +24,7 @@
<x:String x:Key="Text.AIAssistant" xml:space="preserve">AI 助理</x:String>
<x:String x:Key="Text.AIAssistant.Regen" xml:space="preserve">重新產生</x:String>
<x:String x:Key="Text.AIAssistant.Tip" xml:space="preserve">使用 AI 產生提交訊息</x:String>
<x:String x:Key="Text.AIAssistant.Use" xml:space="preserve">套用選取</x:String>
<x:String x:Key="Text.App.Hide" xml:space="preserve">隱藏 SourceGit</x:String>
<x:String x:Key="Text.App.ShowAll" xml:space="preserve">顯示所有</x:String>
<x:String x:Key="Text.Apply" xml:space="preserve">套用修補檔 (apply patch)</x:String>

View File

@@ -22,7 +22,7 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _text, value);
}
public AIAssistant(string repo, AI.Service service, List<Models.Change> changes)
public AIAssistant(Repository repo, AI.Service service, List<Models.Change> changes)
{
_repo = repo;
_service = service;
@@ -49,7 +49,7 @@ namespace SourceGit.ViewModels
try
{
await agent.GenerateCommitMessageAsync(_repo, _changeList, message =>
await agent.GenerateCommitMessageAsync(_repo.FullPath, _changeList, message =>
{
builder.AppendLine(message);
Dispatcher.UIThread.Post(() => Text = builder.ToString());
@@ -72,6 +72,11 @@ namespace SourceGit.ViewModels
IsGenerating = false;
}
public void Use(string text)
{
_repo.SetCommitMessage(text);
}
public void Cancel()
{
_cancel?.Cancel();
@@ -98,7 +103,7 @@ namespace SourceGit.ViewModels
builder.Append(c.Path).AppendLine();
}
private readonly string _repo = null;
private readonly Repository _repo = null;
private readonly AI.Service _service = null;
private readonly string _changeList = null;
private CancellationTokenSource _cancel = null;

View File

@@ -93,29 +93,31 @@ namespace SourceGit.Views
private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e)
{
if (DataContext is not ViewModels.AIAssistant vm)
return;
var selected = SelectedText;
if (string.IsNullOrEmpty(selected))
return;
var apply = new MenuItem() { Header = App.Text("AIAssistant.Use") };
apply.Icon = App.CreateMenuIcon("Icons.Check");
apply.Click += (_, ev) =>
{
vm.Use(selected);
ev.Handled = true;
};
var copy = new MenuItem() { Header = App.Text("Copy") };
copy.Icon = App.CreateMenuIcon("Icons.Copy");
copy.Click += async (_, ev) =>
{
await App.CopyTextAsync(selected);
ev.Handled = true;
};
if (this.FindResource("Icons.Copy") is Geometry geo)
{
copy.Icon = new Avalonia.Controls.Shapes.Path()
{
Width = 10,
Height = 10,
Stretch = Stretch.Uniform,
Data = geo,
};
}
var menu = new ContextMenu();
menu.Items.Add(apply);
menu.Items.Add(copy);
menu.Open(TextArea.TextView);

View File

@@ -588,7 +588,7 @@ namespace SourceGit.Views
if (services.Count == 1)
{
await App.ShowDialog(new ViewModels.AIAssistant(repo.FullPath, services[0], vm.Staged));
await App.ShowDialog(new ViewModels.AIAssistant(repo, services[0], vm.Staged));
e.Handled = true;
return;
}
@@ -601,7 +601,7 @@ namespace SourceGit.Views
item.Header = service.Name;
item.Click += async (_, ev) =>
{
await App.ShowDialog(new ViewModels.AIAssistant(repo.FullPath, dup, vm.Staged));
await App.ShowDialog(new ViewModels.AIAssistant(repo, dup, vm.Staged));
ev.Handled = true;
};

View File

@@ -929,7 +929,7 @@ namespace SourceGit.Views
{
ai.Click += async (_, e) =>
{
await App.ShowDialog(new ViewModels.AIAssistant(repo.FullPath, services[0], selectedStaged));
await App.ShowDialog(new ViewModels.AIAssistant(repo, services[0], selectedStaged));
e.Handled = true;
};
}
@@ -943,7 +943,7 @@ namespace SourceGit.Views
item.Header = service.Name;
item.Click += async (_, e) =>
{
await App.ShowDialog(new ViewModels.AIAssistant(repo.FullPath, dup, selectedStaged));
await App.ShowDialog(new ViewModels.AIAssistant(repo, dup, selectedStaged));
e.Handled = true;
};