Skip to content

Commit

Permalink
Support /code copy <n> and key bindings for it (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
daxian-dbw authored Jan 23, 2024
1 parent 249faf0 commit 3989de2
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 22 deletions.
35 changes: 26 additions & 9 deletions shell/ShellCopilot.Kernel/Command/CodeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ public CodeCommand()
var copy = new Command("copy", "Copy the code snippet from the last response to clipboard.");
var save = new Command("save", "Save the code snippet from the last response to a file.");

var nth = new Argument<int>("n", () => -1, "The n-th (starts from 1) code block to copy.");
nth.AddValidator(result => {
int value = result.GetValueForArgument(nth);
if (value is not -1 && value < 1)
{
result.ErrorMessage = "The argument <n> must be equal to or greater than 1.";
}
});
copy.AddArgument(nth);

var append = new Option<bool>("--append", "Append to the end of the file.");
var file = new Argument<FileInfo>("file", "The file path to save the code to.");
save.AddArgument(file);
Expand All @@ -20,16 +30,22 @@ public CodeCommand()
AddCommand(copy);
AddCommand(save);

copy.SetHandler(CopyAction);
copy.SetHandler(CopyAction, nth);
save.SetHandler(SaveAction, file, append);
}

private string GetCodeText()
private string GetCodeText(int index)
{
var shellImpl = (Shell)Shell;
List<string> code = shellImpl.GetCodeBlockFromLastResponse();

if (code is not null && code.Count > 0)
if (code is null || code.Count is 0 || index >= code.Count)
{
return null;
}

// The index being -1 means to combine all code blocks.
if (index is -1)
{
// Use LF as line ending to be consistent with the response from LLM.
StringBuilder sb = new(capacity: 50);
Expand All @@ -40,19 +56,20 @@ private string GetCodeText()
sb.Append('\n');
}

sb.Append(code[i])
.Append('\n');
sb.Append(code[i]).Append('\n');
}

return sb.ToString();
}

return null;
// Otherwise, return the specific code block.
return code[index];
}

private void CopyAction()
private void CopyAction(int nth)
{
string code = GetCodeText();
int index = nth > 0 ? nth - 1 : nth;
string code = GetCodeText(index);
if (code is null)
{
Shell.Host.MarkupLine("[olive]No code snippet available for copy.[/]");
Expand All @@ -65,7 +82,7 @@ private void CopyAction()

private void SaveAction(FileInfo file, bool append)
{
string code = GetCodeText();
string code = GetCodeText(index: -1);
if (code is null)
{
Shell.Host.MarkupLine("[olive]No code snippet available for save.[/]");
Expand Down
15 changes: 2 additions & 13 deletions shell/ShellCopilot.Kernel/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,19 +296,8 @@ private void OnCancelKeyPress(object sender, ConsoleCancelEventArgs args)
/// </summary>
private void SetReadLineExperience()
{
PSConsoleReadLineOptions options = PSConsoleReadLine.GetOptions();
options.RenderHelper = new ReadLineHelper(CommandRunner);

PSConsoleReadLine.SetKeyHandler(
new[] { "Ctrl+d,Ctrl+c" },
(key, arg) =>
{
PSConsoleReadLine.RevertLine();
PSConsoleReadLine.Insert("/code copy");
PSConsoleReadLine.AcceptLine();
},
"CopyCode",
"Copy the code snippet from the last response to clipboard.");
Utils.SetDefaultKeyHandlers();
PSConsoleReadLine.GetOptions().RenderHelper = new ReadLineHelper(CommandRunner);
}

/// <summary>
Expand Down
70 changes: 70 additions & 0 deletions shell/ShellCopilot.Kernel/Utility/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Security.Principal;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.PowerShell;

namespace ShellCopilot.Kernel;

Expand Down Expand Up @@ -70,6 +71,75 @@ internal static JsonSerializerOptions GetJsonSerializerOptions()
};
}

internal static void SetDefaultKeyHandlers()
{
PSConsoleReadLine.SetKeyHandler(
new[] { "Ctrl+d,Ctrl+c" },
(key, arg) =>
{
PSConsoleReadLine.RevertLine();
PSConsoleReadLine.Insert("/code copy");
PSConsoleReadLine.AcceptLine();
},
"CopyCodeAll",
"Copy all the code snippets from the last response to clipboard.");

PSConsoleReadLine.SetKeyHandler(
new[] { "Ctrl+1" },
(key, arg) =>
{
PSConsoleReadLine.RevertLine();
PSConsoleReadLine.Insert("/code copy 1");
PSConsoleReadLine.AcceptLine();
},
"CopyCodeFirst",
"Copy the 1st code snippet from the last response to clipboard.");

PSConsoleReadLine.SetKeyHandler(
new[] { "Ctrl+2" },
(key, arg) =>
{
PSConsoleReadLine.RevertLine();
PSConsoleReadLine.Insert("/code copy 2");
PSConsoleReadLine.AcceptLine();
},
"CopyCodeSecond",
"Copy the 2nd code snippet from the last response to clipboard.");

PSConsoleReadLine.SetKeyHandler(
new[] { "Ctrl+3" },
(key, arg) =>
{
PSConsoleReadLine.RevertLine();
PSConsoleReadLine.Insert("/code copy 3");
PSConsoleReadLine.AcceptLine();
},
"CopyCodeThird",
"Copy the 3rd code snippet from the last response to clipboard.");

PSConsoleReadLine.SetKeyHandler(
new[] { "Ctrl+4" },
(key, arg) =>
{
PSConsoleReadLine.RevertLine();
PSConsoleReadLine.Insert("/code copy 4");
PSConsoleReadLine.AcceptLine();
},
"CopyCodeThird",
"Copy the 4th code snippet from the last response to clipboard.");

PSConsoleReadLine.SetKeyHandler(
new[] { "Ctrl+5" },
(key, arg) =>
{
PSConsoleReadLine.RevertLine();
PSConsoleReadLine.Insert("/code copy 5");
PSConsoleReadLine.AcceptLine();
},
"CopyCodeThird",
"Copy the 5th code snippet from the last response to clipboard.");
}

private static void CreateFolderWithRightPermission(string dirPath)
{
if (Directory.Exists(dirPath))
Expand Down

0 comments on commit 3989de2

Please sign in to comment.