Skip to content

Commit

Permalink
Feat: upcasing, downcasing, and capitalizing word
Browse files Browse the repository at this point in the history
  • Loading branch information
3N4N committed Jul 13, 2022
1 parent 0ac6c07 commit 0ffc443
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 2 deletions.
66 changes: 66 additions & 0 deletions PSReadLine/BasicEditing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,72 @@ public static void DeleteCharOrExit(ConsoleKeyInfo? key = null, object arg = nul
_singleton.DeleteCharImpl(1, orExit: true);
}

/// <summary>
/// A helper function to change the case of the current word.
/// </summary>
private static void UpdateWordCase(bool toUpper, ConsoleKeyInfo? key = null, object arg = null)
{
if (_singleton._current >= _singleton._buffer.Length)
{
Ding();
return;
}

int endOfWord = _singleton.FindForwardWordPoint(_singleton.Options.WordDelimiters);
int wordlen = endOfWord - _singleton._current;

string word = _singleton._buffer.ToString(_singleton._current, wordlen);
word = toUpper ? word.ToUpper() : word.ToLower();

Replace(_singleton._current, wordlen, word);

_singleton.MoveCursor(endOfWord);
_singleton.Render();
}

/// <summary>
/// Upcase the current word and move to the next one.
/// </summary>
public static void UpcaseWord(ConsoleKeyInfo? key = null, object arg = null)
{
UpdateWordCase(true, key, arg);
}

/// <summary>
/// Downcase the current word and move to the next one.
/// </summary>
public static void DowncaseWord(ConsoleKeyInfo? key = null, object arg = null)
{
UpdateWordCase(false, key, arg);
}

/// <summary>
/// Capitalize the current word and move to the next one.
/// </summary>
public static void CapitalizeWord(ConsoleKeyInfo? key = null, object arg = null)
{
if (_singleton._current >= _singleton._buffer.Length)
{
Ding();
return;
}

int endOfWord = _singleton.FindForwardWordPoint(_singleton.Options.WordDelimiters);
int wordlen = endOfWord - _singleton._current;

char[] word = _singleton._buffer.ToString(_singleton._current, wordlen).ToLower().ToCharArray();
int idxFirstLetter = Array.FindIndex(word, x => char.IsLetter(x));

if (idxFirstLetter >= 0)
{
word[idxFirstLetter] = Char.ToUpper(word[idxFirstLetter]);
Replace(_singleton._current, wordlen, new string(word));
}

_singleton.MoveCursor(endOfWord);
_singleton.Render();
}

private bool AcceptLineImpl(bool validate)
{
using var _ = _prediction.DisableScoped();
Expand Down
13 changes: 11 additions & 2 deletions PSReadLine/KeyBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,9 @@ void SetDefaultEmacsBindings()
{ Keys.AltH, MakeKeyHandler(ShowParameterHelp, "ShowParameterHelp") },
{ Keys.F1, MakeKeyHandler(ShowCommandHelp, "ShowCommandHelp") },
{ Keys.F2, MakeKeyHandler(SwitchPredictionView, "SwitchPredictionView") },
{ Keys.AltU, MakeKeyHandler(UpcaseWord, "UpcaseWord") },
{ Keys.AltL, MakeKeyHandler(DowncaseWord, "DowncaseWord") },
{ Keys.AltC, MakeKeyHandler(CapitalizeWord, "CapitalizeWord") },
};

// Some bindings are not available on certain platforms
Expand Down Expand Up @@ -371,6 +374,9 @@ void SetDefaultEmacsBindings()
{ Keys.F, MakeKeyHandler(ForwardWord, "ForwardWord")},
{ Keys.R, MakeKeyHandler(RevertLine, "RevertLine")},
{ Keys.Y, MakeKeyHandler(YankPop, "YankPop")},
{ Keys.U, MakeKeyHandler(UpcaseWord, "UpcaseWord") },
{ Keys.L, MakeKeyHandler(DowncaseWord, "DowncaseWord") },
{ Keys.C, MakeKeyHandler(CapitalizeWord, "CapitalizeWord") },
{ Keys.CtrlY, MakeKeyHandler(YankNthArg, "YankNthArg")},
{ Keys.Backspace, MakeKeyHandler(BackwardKillWord, "BackwardKillWord")},
{ Keys.Period, MakeKeyHandler(YankLastArg, "YankLastArg")},
Expand Down Expand Up @@ -399,28 +405,30 @@ public static KeyHandlerGroup GetDisplayGrouping(string function)
case nameof(AcceptAndGetNext):
case nameof(AcceptLine):
case nameof(AddLine):
case nameof(BackwardDeleteInput):
case nameof(BackwardDeleteChar):
case nameof(BackwardDeleteInput):
case nameof(BackwardDeleteLine):
case nameof(BackwardDeleteWord):
case nameof(BackwardKillInput):
case nameof(BackwardKillLine):
case nameof(BackwardKillWord):
case nameof(CancelLine):
case nameof(CapitalizeWord):
case nameof(Copy):
case nameof(CopyOrCancelLine):
case nameof(Cut):
case nameof(DeleteChar):
case nameof(DeleteCharOrExit):
case nameof(DeleteEndOfBuffer):
case nameof(DeleteEndOfWord):
case nameof(DeleteRelativeLines):
case nameof(DeleteLine):
case nameof(DeleteLineToFirstChar):
case nameof(DeleteNextLines):
case nameof(DeletePreviousLines):
case nameof(DeleteRelativeLines):
case nameof(DeleteToEnd):
case nameof(DeleteWord):
case nameof(DowncaseWord):
case nameof(ForwardDeleteInput):
case nameof(ForwardDeleteLine):
case nameof(InsertLineAbove):
Expand All @@ -442,6 +450,7 @@ public static KeyHandlerGroup GetDisplayGrouping(string function)
case nameof(Undo):
case nameof(UndoAll):
case nameof(UnixWordRubout):
case nameof(UpcaseWord):
case nameof(ValidateAndAcceptLine):
case nameof(ViAcceptLine):
case nameof(ViAcceptLineOrExit):
Expand Down
31 changes: 31 additions & 0 deletions test/BasicEditingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,37 @@ public void DeleteCharOrExit()
Test("exit", Keys("foo", _.Home, Enumerable.Repeat(_.Ctrl_d, 4), InputAcceptedNow));
}

[SkippableFact]
public void UpcaseWord()
{
TestSetup(KeyMode.Emacs);
Test("FOO", Keys("foo", _.Alt_b, _.Alt_u));
Test("FOO bar", Keys("foo bar", _.Home, _.Alt_u));
Test("foo BAR", Keys("foo bar", _.Alt_b, _.Alt_u));
Test("FOO BAR", Keys("foo bar", _.Home, Enumerable.Repeat(_.Alt_u, 2)));
}

[SkippableFact]
public void DowncaseWord()
{
TestSetup(KeyMode.Emacs);
Test("foo", Keys("fOO", _.Alt_b, _.Alt_l));
Test("FOO bar", Keys("FOO bar", _.Alt_b, _.Alt_l));
Test("foo BAR", Keys("FOO BAR", _.Home, _.Alt_l));
Test("foo bar", Keys("FOO BAR", _.Home, Enumerable.Repeat(_.Alt_l, 2)));
}

[SkippableFact]
public void CapitalizeWord()
{
TestSetup(KeyMode.Emacs);
Test("Foo", Keys("fOO", _.Alt_b, _.Alt_c));
Test("fOO Bar", Keys("fOO bAR", _.Alt_b, _.Alt_c));
Test("Foo BAR", Keys("fOO BAR", _.Home, _.Alt_c));
Test("Foo Bar", Keys("fOO BAR", _.Home, Enumerable.Repeat(_.Alt_c, 2)));
Test("Foo ^&*() Bar", Keys("Foo ^&*() bar", _.Home, Enumerable.Repeat(_.Alt_c, 2)));
}

[SkippableFact]
public void SelectAndDelete()
{
Expand Down

0 comments on commit 0ffc443

Please sign in to comment.