diff --git a/PSReadLine/BasicEditing.cs b/PSReadLine/BasicEditing.cs
index a59bdf4e..a07434c2 100644
--- a/PSReadLine/BasicEditing.cs
+++ b/PSReadLine/BasicEditing.cs
@@ -246,6 +246,72 @@ public static void DeleteCharOrExit(ConsoleKeyInfo? key = null, object arg = nul
_singleton.DeleteCharImpl(1, orExit: true);
}
+ ///
+ /// A helper function to change the case of the current word.
+ ///
+ 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();
+ }
+
+ ///
+ /// Upcase the current word and move to the next one.
+ ///
+ public static void UpcaseWord(ConsoleKeyInfo? key = null, object arg = null)
+ {
+ UpdateWordCase(true, key, arg);
+ }
+
+ ///
+ /// Downcase the current word and move to the next one.
+ ///
+ public static void DowncaseWord(ConsoleKeyInfo? key = null, object arg = null)
+ {
+ UpdateWordCase(false, key, arg);
+ }
+
+ ///
+ /// Capitalize the current word and move to the next one.
+ ///
+ 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();
diff --git a/PSReadLine/KeyBindings.cs b/PSReadLine/KeyBindings.cs
index 9315cd56..08474b54 100644
--- a/PSReadLine/KeyBindings.cs
+++ b/PSReadLine/KeyBindings.cs
@@ -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
@@ -399,14 +402,15 @@ 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):
@@ -414,13 +418,14 @@ public static KeyHandlerGroup GetDisplayGrouping(string function)
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):
@@ -442,6 +447,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):