mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
feature: add powershell support for Windows
This commit is contained in:
parent
8f70778ec2
commit
4ac705f8ca
13 changed files with 88 additions and 46 deletions
10
README.md
10
README.md
|
@ -53,20 +53,20 @@ For **Linux** users:
|
|||
* Maybe you need to set environment variable `AVALONIA_SCREEN_SCALE_FACTORS`. See https://github.com/AvaloniaUI/Avalonia/wiki/Configuring-X11-per-monitor-DPI.
|
||||
* Modify `SourceGit.desktop.template` (replace SOURCEGIT_LOCAL_FOLDER with real path) and move it into `~/.local/share/applications`.
|
||||
|
||||
## External Editors
|
||||
## External Tools
|
||||
|
||||
This app supports open repository in external editors listed in the table below.
|
||||
This app supports open repository in external tools listed in the table below.
|
||||
|
||||
| Editor | Windows | macOS | Linux | Environment Variable |
|
||||
| Tool | Windows | macOS | Linux | Environment Variable |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Visual Studio Code | YES | YES | YES | VSCODE_PATH |
|
||||
| Visual Studio Code - Insiders | YES | YES | YES | VSCODE_INSIDERS_PATH |
|
||||
| JetBrains Fleet | YES | YES | YES | FLEET_PATH |
|
||||
| Sublime Text | YES | YES | YES | SUBLIME_TEXT_PATH |
|
||||
|
||||
You can set the given environment variable for special editor if it can NOT be found by this app automatically.
|
||||
You can set the given environment variable for special tool if it can NOT be found by this app automatically.
|
||||
|
||||
## Screen Shots
|
||||
## Screenshots
|
||||
|
||||
* Dark Theme
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.IO;
|
|||
|
||||
namespace SourceGit.Models
|
||||
{
|
||||
public class ExternalEditor
|
||||
public class ExternalTool
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Icon { get; set; } = string.Empty;
|
||||
|
@ -24,13 +24,13 @@ namespace SourceGit.Models
|
|||
}
|
||||
}
|
||||
|
||||
public class ExternalEditorFinder
|
||||
public class ExternalToolsFinder
|
||||
{
|
||||
public List<ExternalEditor> Editors
|
||||
public List<ExternalTool> Founded
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
} = new List<ExternalEditor>();
|
||||
} = new List<ExternalTool>();
|
||||
|
||||
public void VSCode(Func<string> platform_finder)
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ namespace SourceGit.Models
|
|||
TryAdd("Sublime Text", "sublime_text.png", "\"{0}\"", "SUBLIME_TEXT_PATH", platform_finder);
|
||||
}
|
||||
|
||||
private void TryAdd(string name, string icon, string args, string env, Func<string> finder)
|
||||
public void TryAdd(string name, string icon, string args, string env, Func<string> finder)
|
||||
{
|
||||
var path = Environment.GetEnvironmentVariable(env);
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||||
|
@ -62,7 +62,7 @@ namespace SourceGit.Models
|
|||
return;
|
||||
}
|
||||
|
||||
Editors.Add(new ExternalEditor
|
||||
Founded.Add(new ExternalTool
|
||||
{
|
||||
Name = name,
|
||||
Icon = icon,
|
|
@ -31,14 +31,14 @@ namespace SourceGit.Native
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
public List<Models.ExternalEditor> FindExternalEditors()
|
||||
public List<Models.ExternalTool> FindExternalTools()
|
||||
{
|
||||
var finder = new Models.ExternalEditorFinder();
|
||||
var finder = new Models.ExternalToolsFinder();
|
||||
finder.VSCode(() => "/usr/share/code/code");
|
||||
finder.VSCodeInsiders(() => "/usr/share/code-insiders/code-insiders");
|
||||
finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox/apps/fleet/bin/Fleet");
|
||||
finder.SublimeText(() => File.Exists("/usr/bin/subl") ? "/usr/bin/subl" : "/usr/local/bin/subl");
|
||||
return finder.Editors;
|
||||
return finder.Founded;
|
||||
}
|
||||
|
||||
public void OpenBrowser(string url)
|
||||
|
|
|
@ -28,14 +28,14 @@ namespace SourceGit.Native
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
public List<Models.ExternalEditor> FindExternalEditors()
|
||||
public List<Models.ExternalTool> FindExternalTools()
|
||||
{
|
||||
var finder = new Models.ExternalEditorFinder();
|
||||
var finder = new Models.ExternalToolsFinder();
|
||||
finder.VSCode(() => "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code");
|
||||
finder.VSCodeInsiders(() => "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code");
|
||||
finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Applications/Fleet.app/Contents/MacOS/Fleet");
|
||||
finder.SublimeText(() => "/Applications/Sublime Text.app/Contents/SharedSupport/bin");
|
||||
return finder.Editors;
|
||||
return finder.Founded;
|
||||
}
|
||||
|
||||
public void OpenBrowser(string url)
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace SourceGit.Native
|
|||
void SetupApp(AppBuilder builder);
|
||||
|
||||
string FindGitExecutable();
|
||||
List<Models.ExternalEditor> FindExternalEditors();
|
||||
List<Models.ExternalTool> FindExternalTools();
|
||||
|
||||
void OpenTerminal(string workdir);
|
||||
void OpenInFileManager(string path, bool select);
|
||||
|
@ -21,7 +21,8 @@ namespace SourceGit.Native
|
|||
}
|
||||
|
||||
public static string GitExecutable { get; set; } = string.Empty;
|
||||
public static List<Models.ExternalEditor> ExternalEditors { get; set; } = new List<Models.ExternalEditor>();
|
||||
public static bool UsePowershellOnWindows { get; set; } = false;
|
||||
public static List<Models.ExternalTool> ExternalTools { get; set; } = new List<Models.ExternalTool>();
|
||||
|
||||
static OS()
|
||||
{
|
||||
|
@ -42,7 +43,7 @@ namespace SourceGit.Native
|
|||
throw new Exception("Platform unsupported!!!");
|
||||
}
|
||||
|
||||
ExternalEditors = _backend.FindExternalEditors();
|
||||
ExternalTools = _backend.FindExternalTools();
|
||||
}
|
||||
|
||||
public static void SetupApp(AppBuilder builder)
|
||||
|
|
|
@ -54,6 +54,16 @@ namespace SourceGit.Native
|
|||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = false)]
|
||||
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, int cild, IntPtr apidl, int dwFlags);
|
||||
|
||||
public Windows()
|
||||
{
|
||||
var localMachine = Microsoft.Win32.RegistryKey.OpenBaseKey(
|
||||
Microsoft.Win32.RegistryHive.LocalMachine,
|
||||
Microsoft.Win32.RegistryView.Registry64);
|
||||
|
||||
var pwsh = localMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\pwsh.exe");
|
||||
_powershellPath = pwsh != null ? pwsh.GetValue(null) as string : "powershell";
|
||||
}
|
||||
|
||||
public void SetupApp(AppBuilder builder)
|
||||
{
|
||||
builder.With(new FontManagerOptions()
|
||||
|
@ -114,14 +124,14 @@ namespace SourceGit.Native
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<Models.ExternalEditor> FindExternalEditors()
|
||||
public List<Models.ExternalTool> FindExternalTools()
|
||||
{
|
||||
var finder = new Models.ExternalEditorFinder();
|
||||
var finder = new Models.ExternalToolsFinder();
|
||||
finder.VSCode(FindVSCode);
|
||||
finder.VSCodeInsiders(FindVSCodeInsiders);
|
||||
finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe");
|
||||
finder.SublimeText(FindSublimeText);
|
||||
return finder.Editors;
|
||||
return finder.Founded;
|
||||
}
|
||||
|
||||
public void OpenBrowser(string url)
|
||||
|
@ -132,6 +142,16 @@ namespace SourceGit.Native
|
|||
}
|
||||
|
||||
public void OpenTerminal(string workdir)
|
||||
{
|
||||
var startInfo = new ProcessStartInfo() { UseShellExecute = true };
|
||||
if (!string.IsNullOrEmpty(workdir) && Path.Exists(workdir))
|
||||
startInfo.WorkingDirectory = workdir;
|
||||
|
||||
if (OS.UsePowershellOnWindows)
|
||||
{
|
||||
startInfo.FileName = _powershellPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
var binDir = Path.GetDirectoryName(OS.GitExecutable);
|
||||
var bash = Path.Combine(binDir, "bash.exe");
|
||||
|
@ -141,11 +161,9 @@ namespace SourceGit.Native
|
|||
return;
|
||||
}
|
||||
|
||||
var startInfo = new ProcessStartInfo();
|
||||
startInfo.UseShellExecute = true;
|
||||
startInfo.FileName = bash;
|
||||
if (!string.IsNullOrEmpty(workdir) && Path.Exists(workdir))
|
||||
startInfo.WorkingDirectory = workdir;
|
||||
}
|
||||
|
||||
Process.Start(startInfo);
|
||||
}
|
||||
|
||||
|
@ -281,5 +299,7 @@ namespace SourceGit.Native
|
|||
ILFree(pidl);
|
||||
}
|
||||
}
|
||||
|
||||
private string _powershellPath = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@
|
|||
<x:String x:Key="Text.Preference.Git.Path" xml:space="preserve">Install Path</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.User" xml:space="preserve">User Name</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.User.Placeholder" xml:space="preserve">Global git user name</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.UsePowershellOnWindows" xml:space="preserve">Use Powershell instead of Git bash</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.Version" xml:space="preserve">Git version</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG" xml:space="preserve">GPG SIGNING</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.Enabled" xml:space="preserve">Commit GPG signing</x:String>
|
||||
|
|
|
@ -268,6 +268,7 @@
|
|||
<x:String x:Key="Text.Preference.Git.Path" xml:space="preserve">安装路径</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.User" xml:space="preserve">用户名</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.User.Placeholder" xml:space="preserve">默认GIT用户名</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.UsePowershellOnWindows" xml:space="preserve">使用PowerShell替代Git Bash</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.Version" xml:space="preserve">Git 版本</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG" xml:space="preserve">GPG签名</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.Enabled" xml:space="preserve">启用提交签名</x:String>
|
||||
|
|
|
@ -219,6 +219,19 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public bool UsePowershellOnWindows
|
||||
{
|
||||
get => Native.OS.UsePowershellOnWindows;
|
||||
set
|
||||
{
|
||||
if (Native.OS.UsePowershellOnWindows != value)
|
||||
{
|
||||
Native.OS.UsePowershellOnWindows = value;
|
||||
OnPropertyChanged(nameof(UsePowershellOnWindows));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int ExternalMergeToolType
|
||||
{
|
||||
get => _externalMergeToolType;
|
||||
|
|
|
@ -287,10 +287,10 @@ namespace SourceGit.ViewModels
|
|||
Native.OS.OpenTerminal(_fullpath);
|
||||
}
|
||||
|
||||
public ContextMenu CreateContextMenuForExternalEditors()
|
||||
public ContextMenu CreateContextMenuForExternalTools()
|
||||
{
|
||||
var editors = Native.OS.ExternalEditors;
|
||||
if (editors.Count == 0)
|
||||
var tools = Native.OS.ExternalTools;
|
||||
if (tools.Count == 0)
|
||||
{
|
||||
App.RaiseException(_fullpath, "No available external editors found!");
|
||||
return null;
|
||||
|
@ -300,16 +300,16 @@ namespace SourceGit.ViewModels
|
|||
menu.Placement = PlacementMode.BottomEdgeAlignedLeft;
|
||||
RenderOptions.SetBitmapInterpolationMode(menu, BitmapInterpolationMode.HighQuality);
|
||||
|
||||
foreach (var editor in editors)
|
||||
foreach (var tool in tools)
|
||||
{
|
||||
var dupEditor = editor;
|
||||
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/ExternalToolIcons/{dupEditor.Icon}", UriKind.RelativeOrAbsolute));
|
||||
var dupTool = tool;
|
||||
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/ExternalToolIcons/{dupTool.Icon}", UriKind.RelativeOrAbsolute));
|
||||
var item = new MenuItem();
|
||||
item.Header = App.Text("Repository.OpenIn", dupEditor.Name);
|
||||
item.Header = App.Text("Repository.OpenIn", dupTool.Name);
|
||||
item.Icon = new Image { Width = 16, Height = 16, Source = new Bitmap(icon) };
|
||||
item.Click += (o, e) =>
|
||||
{
|
||||
dupEditor.Open(_fullpath);
|
||||
dupTool.Open(_fullpath);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@
|
|||
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.Git}"/>
|
||||
</TabItem.Header>
|
||||
|
||||
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
|
||||
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,Auto,32" ColumnDefinitions="Auto,*">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="{DynamicResource Text.Preference.Git.Path}"
|
||||
HorizontalAlignment="Right"
|
||||
|
@ -310,6 +310,12 @@
|
|||
</ComboBox>
|
||||
|
||||
<CheckBox Grid.Row="6" Grid.Column="1"
|
||||
Height="32"
|
||||
Content="{DynamicResource Text.Preference.Git.UsePowershellOnWindows}"
|
||||
IsChecked="{Binding UsePowershellOnWindows, Mode=TwoWay}"
|
||||
IsVisible="{OnPlatform False, Windows=True}"/>
|
||||
|
||||
<CheckBox Grid.Row="7" Grid.Column="1"
|
||||
Content="{DynamicResource Text.Preference.Git.AutoFetch}"
|
||||
IsChecked="{Binding GitAutoFetch, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<Path Width="13" Height="13" Data="{StaticResource Icons.Terminal}"/>
|
||||
</Button>
|
||||
|
||||
<Button Classes="icon_button" Width="32" Click="OnOpenWithExternalEditor" ToolTip.Tip="{DynamicResource Text.Repository.OpenWithExternalTools}">
|
||||
<Button Classes="icon_button" Width="32" Click="OnOpenWithExternalTools" ToolTip.Tip="{DynamicResource Text.Repository.OpenWithExternalTools}">
|
||||
<Path Width="13" Height="13" Data="{StaticResource Icons.OpenWith}"/>
|
||||
</Button>
|
||||
|
||||
|
|
|
@ -61,11 +61,11 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnOpenWithExternalEditor(object sender, RoutedEventArgs e)
|
||||
private void OnOpenWithExternalTools(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button && DataContext is ViewModels.Repository repo)
|
||||
{
|
||||
var menu = repo.CreateContextMenuForExternalEditors();
|
||||
var menu = repo.CreateContextMenuForExternalTools();
|
||||
if (menu != null)
|
||||
{
|
||||
menu.Open(button);
|
||||
|
|
Loading…
Reference in a new issue