|
@@ -751,7 +751,11 @@ namespace Terminal.Gui {
|
|
|
if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
|
|
|
clipboard = new MacOSXClipboard ();
|
|
|
} else {
|
|
|
- clipboard = new CursesClipboard ();
|
|
|
+ if (Is_WSL_Platform ()) {
|
|
|
+ clipboard = new WSLClipboard ();
|
|
|
+ } else {
|
|
|
+ clipboard = new CursesClipboard ();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
Curses.raw ();
|
|
@@ -844,6 +848,15 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public static bool Is_WSL_Platform ()
|
|
|
+ {
|
|
|
+ var result = BashRunner.Run ("uname -a");
|
|
|
+ if (result.Contains ("microsoft") && result.Contains ("WSL")) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
static int MapColor (Color color)
|
|
|
{
|
|
|
switch (color) {
|
|
@@ -1056,67 +1069,102 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- class CursesClipboard : IClipboard {
|
|
|
- public string GetClipboardData ()
|
|
|
+ class CursesClipboard : ClipboardBase {
|
|
|
+ public override bool IsSupported => CheckSupport ();
|
|
|
+
|
|
|
+ bool CheckSupport ()
|
|
|
{
|
|
|
- var tempFileName = System.IO.Path.GetTempFileName ();
|
|
|
try {
|
|
|
- // BashRunner.Run ($"xsel -o --clipboard > {tempFileName}");
|
|
|
- BashRunner.Run ($"xclip -o > {tempFileName}");
|
|
|
- return System.IO.File.ReadAllText (tempFileName);
|
|
|
- } finally {
|
|
|
- System.IO.File.Delete (tempFileName);
|
|
|
+ var result = BashRunner.Run ("which xclip");
|
|
|
+ return BashRunner.FileExists (result);
|
|
|
+ } catch (Exception) {
|
|
|
+ // Permissions issue.
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void SetClipboardData (string text)
|
|
|
+ protected override string GetClipboardDataImpl ()
|
|
|
{
|
|
|
var tempFileName = System.IO.Path.GetTempFileName ();
|
|
|
- System.IO.File.WriteAllText (tempFileName, text);
|
|
|
try {
|
|
|
- // BashRunner.Run ($"cat {tempFileName} | xsel -i --clipboard");
|
|
|
- BashRunner.Run ($"cat {tempFileName} | xclip -selection clipboard");
|
|
|
+ // BashRunner.Run ($"xsel -o --clipboard > {tempFileName}");
|
|
|
+ BashRunner.Run ($"xclip -selection clipboard -o > {tempFileName}");
|
|
|
+ return System.IO.File.ReadAllText (tempFileName);
|
|
|
} finally {
|
|
|
System.IO.File.Delete (tempFileName);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ protected override void SetClipboardDataImpl (string text)
|
|
|
+ {
|
|
|
+ // var tempFileName = System.IO.Path.GetTempFileName ();
|
|
|
+ // System.IO.File.WriteAllText (tempFileName, text);
|
|
|
+ // try {
|
|
|
+ // // BashRunner.Run ($"cat {tempFileName} | xsel -i --clipboard");
|
|
|
+ // BashRunner.Run ($"cat {tempFileName} | xclip -selection clipboard");
|
|
|
+ // } finally {
|
|
|
+ // System.IO.File.Delete (tempFileName);
|
|
|
+ // }
|
|
|
+
|
|
|
+ BashRunner.Run ("xclip -selection clipboard -i", false, text);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static class BashRunner {
|
|
|
- public static string Run (string commandLine)
|
|
|
+ public static string Run (string commandLine, bool output = true, string inputText = "")
|
|
|
{
|
|
|
- var errorBuilder = new System.Text.StringBuilder ();
|
|
|
- var outputBuilder = new System.Text.StringBuilder ();
|
|
|
var arguments = $"-c \"{commandLine}\"";
|
|
|
- using (var process = new System.Diagnostics.Process {
|
|
|
- StartInfo = new System.Diagnostics.ProcessStartInfo {
|
|
|
- FileName = "bash",
|
|
|
- Arguments = arguments,
|
|
|
- RedirectStandardOutput = true,
|
|
|
- RedirectStandardError = true,
|
|
|
- UseShellExecute = false,
|
|
|
- CreateNoWindow = false,
|
|
|
- }
|
|
|
- }) {
|
|
|
- process.Start ();
|
|
|
- process.OutputDataReceived += (sender, args) => { outputBuilder.AppendLine (args.Data); };
|
|
|
- process.BeginOutputReadLine ();
|
|
|
- process.ErrorDataReceived += (sender, args) => { errorBuilder.AppendLine (args.Data); };
|
|
|
- process.BeginErrorReadLine ();
|
|
|
- if (!process.DoubleWaitForExit ()) {
|
|
|
- var timeoutError = $@"Process timed out. Command line: bash {arguments}.
|
|
|
+
|
|
|
+ if (output) {
|
|
|
+ var errorBuilder = new System.Text.StringBuilder ();
|
|
|
+ var outputBuilder = new System.Text.StringBuilder ();
|
|
|
+
|
|
|
+ using (var process = new System.Diagnostics.Process {
|
|
|
+ StartInfo = new System.Diagnostics.ProcessStartInfo {
|
|
|
+ FileName = "bash",
|
|
|
+ Arguments = arguments,
|
|
|
+ RedirectStandardOutput = true,
|
|
|
+ RedirectStandardError = true,
|
|
|
+ UseShellExecute = false,
|
|
|
+ CreateNoWindow = false,
|
|
|
+ }
|
|
|
+ }) {
|
|
|
+ process.Start ();
|
|
|
+ process.OutputDataReceived += (sender, args) => { outputBuilder.AppendLine (args.Data); };
|
|
|
+ process.BeginOutputReadLine ();
|
|
|
+ process.ErrorDataReceived += (sender, args) => { errorBuilder.AppendLine (args.Data); };
|
|
|
+ process.BeginErrorReadLine ();
|
|
|
+ if (!process.DoubleWaitForExit ()) {
|
|
|
+ var timeoutError = $@"Process timed out. Command line: bash {arguments}.
|
|
|
+ Output: {outputBuilder}
|
|
|
+ Error: {errorBuilder}";
|
|
|
+ throw new Exception (timeoutError);
|
|
|
+ }
|
|
|
+ if (process.ExitCode == 0) {
|
|
|
+ return outputBuilder.ToString ();
|
|
|
+ }
|
|
|
+
|
|
|
+ var error = $@"Could not execute process. Command line: bash {arguments}.
|
|
|
Output: {outputBuilder}
|
|
|
Error: {errorBuilder}";
|
|
|
- throw new Exception (timeoutError);
|
|
|
+ throw new Exception (error);
|
|
|
}
|
|
|
- if (process.ExitCode == 0) {
|
|
|
- return outputBuilder.ToString ();
|
|
|
+ } else {
|
|
|
+ using (var process = new System.Diagnostics.Process {
|
|
|
+ StartInfo = new System.Diagnostics.ProcessStartInfo {
|
|
|
+ FileName = "bash",
|
|
|
+ Arguments = arguments,
|
|
|
+ RedirectStandardInput = true,
|
|
|
+ UseShellExecute = false,
|
|
|
+ CreateNoWindow = false
|
|
|
+ }
|
|
|
+ }) {
|
|
|
+ process.Start ();
|
|
|
+ process.StandardInput.Write (inputText);
|
|
|
+ process.StandardInput.Close ();
|
|
|
+ process.WaitForExit ();
|
|
|
+ return inputText;
|
|
|
}
|
|
|
-
|
|
|
- var error = $@"Could not execute process. Command line: bash {arguments}.
|
|
|
- Output: {outputBuilder}
|
|
|
- Error: {errorBuilder}";
|
|
|
- throw new Exception (error);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1128,9 +1176,14 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ public static bool FileExists (string value)
|
|
|
+ {
|
|
|
+ return !string.IsNullOrEmpty (value) && !value.Contains ("not found");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- class MacOSXClipboard : IClipboard {
|
|
|
+ class MacOSXClipboard : ClipboardBase {
|
|
|
IntPtr nsString = objc_getClass ("NSString");
|
|
|
IntPtr nsPasteboard = objc_getClass ("NSPasteboard");
|
|
|
IntPtr utfTextType;
|
|
@@ -1144,6 +1197,18 @@ namespace Terminal.Gui {
|
|
|
IntPtr generalPasteboardRegister = sel_registerName ("generalPasteboard");
|
|
|
IntPtr clearContentsRegister = sel_registerName ("clearContents");
|
|
|
|
|
|
+ public override bool IsSupported => CheckSupport ();
|
|
|
+
|
|
|
+ bool CheckSupport ()
|
|
|
+ {
|
|
|
+ var result = BashRunner.Run ("which pbcopy");
|
|
|
+ if (!BashRunner.FileExists (result)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ result = BashRunner.Run ("which pbpaste");
|
|
|
+ return BashRunner.FileExists (result);
|
|
|
+ }
|
|
|
+
|
|
|
public MacOSXClipboard ()
|
|
|
{
|
|
|
utfTextType = objc_msgSend (objc_msgSend (nsString, allocRegister), initWithUtf8Register, "public.utf8-plain-text");
|
|
@@ -1151,14 +1216,14 @@ namespace Terminal.Gui {
|
|
|
generalPasteboard = objc_msgSend (nsPasteboard, generalPasteboardRegister);
|
|
|
}
|
|
|
|
|
|
- public string GetClipboardData ()
|
|
|
+ protected override string GetClipboardDataImpl ()
|
|
|
{
|
|
|
var ptr = objc_msgSend (generalPasteboard, stringForTypeRegister, nsStringPboardType);
|
|
|
var charArray = objc_msgSend (ptr, utf8Register);
|
|
|
return Marshal.PtrToStringAnsi (charArray);
|
|
|
}
|
|
|
|
|
|
- public void SetClipboardData (string text)
|
|
|
+ protected override void SetClipboardDataImpl (string text)
|
|
|
{
|
|
|
IntPtr str = default;
|
|
|
try {
|
|
@@ -1190,4 +1255,63 @@ namespace Terminal.Gui {
|
|
|
[DllImport ("/System/Library/Frameworks/AppKit.framework/AppKit")]
|
|
|
static extern IntPtr sel_registerName (string selectorName);
|
|
|
}
|
|
|
+
|
|
|
+ class WSLClipboard : ClipboardBase {
|
|
|
+ public override bool IsSupported => CheckSupport ();
|
|
|
+
|
|
|
+ bool CheckSupport ()
|
|
|
+ {
|
|
|
+ var result = BashRunner.Run ("which powershell.exe");
|
|
|
+ return BashRunner.FileExists (result);
|
|
|
+
|
|
|
+ //var result = BashRunner.Run ("which powershell.exe");
|
|
|
+ //if (!BashRunner.FileExists (result)) {
|
|
|
+ // return false;
|
|
|
+ //}
|
|
|
+ //result = BashRunner.Run ("which clip.exe");
|
|
|
+ //return BashRunner.FileExists (result);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override string GetClipboardDataImpl ()
|
|
|
+ {
|
|
|
+ using (var powershell = new System.Diagnostics.Process {
|
|
|
+ StartInfo = new System.Diagnostics.ProcessStartInfo {
|
|
|
+ RedirectStandardOutput = true,
|
|
|
+ FileName = "powershell.exe",
|
|
|
+ Arguments = "-noprofile -command \"Get-Clipboard\""
|
|
|
+ }
|
|
|
+ }) {
|
|
|
+ powershell.Start ();
|
|
|
+ var result = powershell.StandardOutput.ReadToEnd ();
|
|
|
+ powershell.StandardOutput.Close ();
|
|
|
+ powershell.WaitForExit ();
|
|
|
+ return result.TrimEnd ();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void SetClipboardDataImpl (string text)
|
|
|
+ {
|
|
|
+ using (var powershell = new System.Diagnostics.Process {
|
|
|
+ StartInfo = new System.Diagnostics.ProcessStartInfo {
|
|
|
+ FileName = "powershell.exe",
|
|
|
+ Arguments = $"-noprofile -command \"Set-Clipboard -Value \\\"{text}\\\"\""
|
|
|
+ }
|
|
|
+ }) {
|
|
|
+ powershell.Start ();
|
|
|
+ powershell.WaitForExit ();
|
|
|
+ }
|
|
|
+
|
|
|
+ //using (var clipExe = new System.Diagnostics.Process {
|
|
|
+ // StartInfo = new System.Diagnostics.ProcessStartInfo {
|
|
|
+ // FileName = "clip.exe",
|
|
|
+ // RedirectStandardInput = true
|
|
|
+ // }
|
|
|
+ //}) {
|
|
|
+ // clipExe.Start ();
|
|
|
+ // clipExe.StandardInput.Write (text);
|
|
|
+ // clipExe.StandardInput.Close ();
|
|
|
+ // clipExe.WaitForExit ();
|
|
|
+ //}
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|