Skip to content

Commit

Permalink
feat: 添加控制台输出可点击目录功能,类似.NET SDK中发布程序的输出结果. (#577)
Browse files Browse the repository at this point in the history
  • Loading branch information
joesdu authored Oct 12, 2024
2 parents dfbcc27 + 5d5a528 commit 8b1c4a1
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 7 deletions.
59 changes: 52 additions & 7 deletions src/EasilyNET.Core/Misc/StringExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public static string ToTitleUpperCase(this string value, bool lower = true)
{
var regex = ToTitleUpperCaseRegex();
return regex.Replace(value,
delegate(Match m)
delegate (Match m)
{
var str = m.ToString();
if (!char.IsLower(str[0])) return str;
Expand Down Expand Up @@ -163,12 +163,12 @@ public static string Mask(this string value, char mask = '*')
return value.Length switch
{
>= 11 => MaskElevenRegex().Replace(value, $"$1{masks}$2"),
10 => MaskTenRegex().Replace(value, $"$1{masks}$2"),
9 => MaskNineRegex().Replace(value, $"$1{masks}$2"),
8 => MaskEightRegex().Replace(value, $"$1{masks}$2"),
7 => MaskSevenRegex().Replace(value, $"$1{masks}$2"),
6 => MaskSixRegex().Replace(value, $"$1{masks}$2"),
_ => MaskLessThanSixRegex().Replace(value, $"$1{masks}")
10 => MaskTenRegex().Replace(value, $"$1{masks}$2"),
9 => MaskNineRegex().Replace(value, $"$1{masks}$2"),
8 => MaskEightRegex().Replace(value, $"$1{masks}$2"),
7 => MaskSevenRegex().Replace(value, $"$1{masks}$2"),
6 => MaskSixRegex().Replace(value, $"$1{masks}$2"),
_ => MaskLessThanSixRegex().Replace(value, $"$1{masks}")
};
}

Expand Down Expand Up @@ -683,4 +683,49 @@ public static string SnakeCaseToCamelCase(this string value, ECamelCase toType =
}
return string.Concat(words);
}

/// <summary>
/// 获取一个能在控制台中点击的路径,使用 [<see langword="Ctrl + 鼠标左键" />] 点击打开对应目录
/// <remarks>
/// <para>
/// 使用方式:
/// <code>
/// <![CDATA[
/// @"F:\tools\test\test\bin\Release\net9.0\win-x64\publish".GetClickablePath();
/// Output:
/// F:\tools\test\test\bin\Release\net9.0\win-x64\publish
/// ]]>
/// </code>
/// </para>
/// </remarks>
/// </summary>
/// <param name="path">需要处理的路径</param>
/// <returns></returns>
public static string GetClickablePath(this string path) => $"\e]8;;file://\e\\{path}\e]8;;\e\\";

/// <summary>
/// 获取一个能在控制台中点击的相对路径,使用 [<see langword="Ctrl + 鼠标左键" />] 点击打开对应目录
/// <remarks>
/// <para>
/// 使用方式:
/// <code>
/// <![CDATA[
/// @"F:\tools\test\test\bin\Release\net9.0\win-x64\publish".GetClickableRelativePath();
/// Output:
/// bin\Release\net9.0\win-x64\publish
/// ]]>
/// </code>
/// </para>
/// </remarks>
/// </summary>
/// <param name="path">需要处理的路径</param>
/// <param name="maxDeep">仅保留最后 N 层目录,默认5层,当超过最大层数后显示全路径</param>
/// <returns></returns>
public static string GetClickableRelativePath(this string path, int maxDeep = 5)
{
// 分割路径并仅保留最后 N 层目录
var pathParts = path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
var displayPath = pathParts.Length > maxDeep ? string.Join(Path.DirectorySeparatorChar, pathParts[^maxDeep..]) : path;
return $"\e]8;;file://{path}\e\\{displayPath}\e]8;;\e\\";
}
}
35 changes: 35 additions & 0 deletions src/EasilyNET.Core/Misc/TextWriterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,41 @@ public static async Task SafeClearPreviousLine(this TextWriter _)
}
}

/// <summary>
/// 在控制台输出可点击的路径,使用 [<see langword="Ctrl + 鼠标左键" />] 即可打开路径
/// <remarks>
/// <para>
/// 使用方式:
/// <code>
/// <![CDATA[
/// var path = @"F:\tools\test\test\bin\Release\net9.0\win-x64\publish";
/// Console.Out.WriteClickablePath(path, true, 5, true);
/// Output:
/// bin\Release\net9.0\win-x64\publish
/// ]]>
/// </code>
/// </para>
/// </remarks>
/// </summary>
/// <param name="_"></param>
/// <param name="path">需要处理的完整路径</param>
/// <param name="relative">是否输出相对路径,默认: <see langword="false" /></param>
/// <param name="deep">当为相对路径的时候配置目录深度,仅保留最后 N 层目录</param>
/// <param name="newLine">是否换行,默认: <see langword="false" />,行为同: Console.Write()</param>
public static void WriteClickablePath(this TextWriter _, string path, bool relative = false, int deep = 5, bool newLine = false)
{
if (string.IsNullOrWhiteSpace(path)) return;
switch (newLine)
{
case true:
Console.WriteLine(relative ? path.GetClickableRelativePath(deep) : path.GetClickablePath());
break;
default:
Console.Write(relative ? path.GetClickableRelativePath(deep) : path.GetClickablePath());
break;
}
}

private static void UpdateClearLine()
{
if (Console.WindowWidth == _lastWindowWidth) return;
Expand Down

0 comments on commit 8b1c4a1

Please sign in to comment.