Skip to content

Commit 64ffb08

Browse files
committed
Merge branch 'master' of https://github.com/rkeithhill/PSReadLine into rkeithhill-master
Conflicts: PSReadLine/PSReadLine.csproj PSReadLine/PSReadLineResources.Designer.cs PSReadLine/PSReadLineResources.resx PSReadLine/ReadLine.cs
2 parents 87dff3f + b0b441c commit 64ffb08

File tree

8 files changed

+232
-13
lines changed

8 files changed

+232
-13
lines changed

PSReadLine/BasicEditing.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,5 +515,65 @@ public static void AddLine(ConsoleKeyInfo? key = null, object arg = null)
515515
{
516516
Insert('\n');
517517
}
518+
519+
/// <summary>
520+
/// A new empty line is created above the current line regardless of where the cursor
521+
/// is on the current line. The cursor moves to the beginning of the new line.
522+
/// </summary>
523+
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
524+
public static void InsertLineAbove(ConsoleKeyInfo? key = null, object arg = null)
525+
{
526+
// Move the current postion to the beginning of the current line and only the current line.
527+
if (_singleton.LineIsMultiLine())
528+
{
529+
int i = Math.Max(0, _singleton._current - 1);
530+
for (; i > 0; i--)
531+
{
532+
if (_singleton._buffer[i] == '\n')
533+
{
534+
i += 1;
535+
break;
536+
}
537+
}
538+
539+
_singleton._current = i;
540+
}
541+
else
542+
{
543+
_singleton._current = 0;
544+
}
545+
546+
Insert('\n');
547+
PreviousLine();
548+
}
549+
550+
/// <summary>
551+
/// A new empty line is created below the current line regardless of where the cursor
552+
/// is on the current line. The cursor moves to the beginning of the new line.
553+
/// </summary>
554+
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
555+
public static void InsertLineBelow(ConsoleKeyInfo? key = null, object arg = null)
556+
{
557+
// Move the current postion to the end of the current line and only the current line.
558+
if (_singleton.LineIsMultiLine())
559+
{
560+
int i = _singleton._current;
561+
for (; i < _singleton._buffer.Length; i++)
562+
{
563+
if (_singleton._buffer[i] == '\n')
564+
{
565+
break;
566+
}
567+
}
568+
569+
_singleton._current = i;
570+
}
571+
else
572+
{
573+
_singleton._current = _singleton._buffer.Length;
574+
}
575+
576+
Insert('\n');
577+
}
518578
}
519579
}

PSReadLine/Changes.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
### Version 1.1.1
2+
3+
New functions:
4+
* InsertLineAbove
5+
- A new empty line is created above the current line regardless of where the cursor
6+
is on the current line. The cursor moves to the beginning of the new line.
7+
* InsertLineBelow
8+
- A new empty line is created below the current line regardless of where the cursor
9+
is on the current line. The cursor moves to the beginning of the new line.
10+
11+
New key bindings:
12+
* Ctrl+Enter bound to InsertLineAbove in Windows mode
13+
* Ctrl+Shift+Enter bound to InsertLineBelow in Windows mode
14+
115
### Version 1.1.0
216

317
Breaking change:

PSReadLine/KeyBindings.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ void SetDefaultWindowsBindings()
104104
{
105105
{ Keys.Enter, MakeKeyHandler(AcceptLine, "AcceptLine") },
106106
{ Keys.ShiftEnter, MakeKeyHandler(AddLine, "AddLine") },
107+
{ Keys.CtrlEnter, MakeKeyHandler(InsertLineAbove, "InsertLineAbove") },
108+
{ Keys.CtrlShiftEnter, MakeKeyHandler(InsertLineBelow, "InsertLineBelow") },
107109
{ Keys.Escape, MakeKeyHandler(RevertLine, "RevertLine") },
108110
{ Keys.LeftArrow, MakeKeyHandler(BackwardChar, "BackwardChar") },
109111
{ Keys.RightArrow, MakeKeyHandler(ForwardChar, "ForwardChar") },
@@ -372,6 +374,5 @@ public static void WhatIsKey(ConsoleKeyInfo? key = null, object arg = null)
372374
_singleton._initialY = _singleton._console.CursorTop;
373375
_singleton.Render();
374376
}
375-
376377
}
377378
}

PSReadLine/Keys.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,11 @@ public static class Keys
230230
public static ConsoleKeyInfo ShiftCtrlLeftArrow = new ConsoleKeyInfo((char)0, ConsoleKey.LeftArrow, true, false, true);
231231
public static ConsoleKeyInfo ShiftCtrlRightArrow = new ConsoleKeyInfo((char)0, ConsoleKey.RightArrow, true, false, true);
232232

233-
public static ConsoleKeyInfo ShiftTab = new ConsoleKeyInfo((char)9, ConsoleKey.Tab, true, false, false);
234-
public static ConsoleKeyInfo ShiftEnter = new ConsoleKeyInfo((char)13, ConsoleKey.Enter, true, false, false);
233+
public static ConsoleKeyInfo ShiftTab = new ConsoleKeyInfo((char)9, ConsoleKey.Tab, true, false, false);
234+
235+
public static ConsoleKeyInfo CtrlEnter = new ConsoleKeyInfo((char)10, ConsoleKey.Enter, false, false, true);
236+
public static ConsoleKeyInfo CtrlShiftEnter = new ConsoleKeyInfo((char)0, ConsoleKey.Enter, true, false, true);
237+
public static ConsoleKeyInfo ShiftEnter = new ConsoleKeyInfo((char)13, ConsoleKey.Enter, true, false, false);
235238

236239
public static ConsoleKeyInfo F1 = new ConsoleKeyInfo((char)0, ConsoleKey.F1, false, false, false);
237240
public static ConsoleKeyInfo F2 = new ConsoleKeyInfo((char)0, ConsoleKey.F2, false, false, false);
@@ -286,7 +289,7 @@ public static class Keys
286289
public static ConsoleKeyInfo ShiftF3 = new ConsoleKeyInfo((char)0, ConsoleKey.F3, true, false, false);
287290
public static ConsoleKeyInfo ShiftF8 = new ConsoleKeyInfo((char)0, ConsoleKey.F8, true, false, false);
288291

289-
// Keys to ignore
292+
// Keys to ignore
290293
public static ConsoleKeyInfo VolumeUp = new ConsoleKeyInfo((char)0, ConsoleKey.VolumeUp, false, false, false);
291294
public static ConsoleKeyInfo VolumeDown = new ConsoleKeyInfo((char)0, ConsoleKey.VolumeDown, false, false, false);
292295
public static ConsoleKeyInfo VolumeMute = new ConsoleKeyInfo((char)0, ConsoleKey.VolumeMute, false, false, false);

PSReadLine/PSReadLine.csproj

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<ProjectGuid>{615788CB-1B9A-4B34-97B3-4608686E59CA}</ProjectGuid>
88
<OutputType>Library</OutputType>
99
<AppDesignerFolder>Properties</AppDesignerFolder>
10-
<RootNamespace>PSReadLine</RootNamespace>
10+
<RootNamespace>Microsoft.PowerShell</RootNamespace>
1111
<AssemblyName>Microsoft.PowerShell.PSReadLine</AssemblyName>
1212
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
1313
<FileAlignment>512</FileAlignment>
@@ -91,8 +91,10 @@
9191
<ItemGroup>
9292
<EmbeddedResource Include="PSReadLineResources.resx">
9393
<Generator>ResXFileCodeGenerator</Generator>
94-
<LogicalName>Microsoft.PowerShell.PSReadline.PSReadLineResources.resources</LogicalName>
94+
<LogicalName>Microsoft.PowerShell.PSReadLineResources.resources</LogicalName>
95+
<LastGenOutput>PSReadlineResources.Designer.cs</LastGenOutput>
9596
<CustomToolNamespace>Microsoft.PowerShell</CustomToolNamespace>
97+
<SubType>Designer</SubType>
9698
</EmbeddedResource>
9799
</ItemGroup>
98100
<ItemGroup>
@@ -141,4 +143,4 @@
141143
<Target Name="AfterBuild">
142144
</Target>
143145
-->
144-
</Project>
146+
</Project>

PSReadLine/PSReadLineResources.Designer.cs

Lines changed: 23 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

PSReadLine/PSReadLineResources.resx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,4 +720,10 @@ If there are other parse errors, unresolved commands, or incorrect parameters, s
720720
<data name="NotInViMode" xml:space="preserve">
721721
<value>The -ViMode parameter was used, but the current EditMode is not Vi.</value>
722722
</data>
723-
</root>
723+
<data name="InsertLineAboveDescription" xml:space="preserve">
724+
<value>Inserts a new empty line above the current line without attempting to execute the input</value>
725+
</data>
726+
<data name="InsertLineBelowDescription" xml:space="preserve">
727+
<value>Inserts a new empty line below the current line without attempting to execute the input</value>
728+
</data>
729+
</root>

UnitTestPSReadLine/BasicEditingTest.cs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,121 @@ public void TestAddLine()
212212
Test("1\n2", Keys('1', _.ShiftEnter, '2'));
213213
}
214214

215+
[TestMethod]
216+
public void TestInsertLineAbove()
217+
{
218+
TestSetup(KeyMode.Cmd);
219+
220+
var continutationPromptLength = PSConsoleReadlineOptions.DefaultContinuationPrompt.Length;
221+
222+
// Test case - start with single line, cursor at end
223+
Test("56\n1234", Keys("1234", _.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(0, 0)), "56"));
224+
225+
// Test case - start with single line, cursor in home position
226+
Test("56\n1234", Keys("1234", _.Home, _.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(0, 0)), "56"));
227+
228+
// Test case - start with single line, cursor in middle
229+
Test("56\n1234", Keys("1234",
230+
_.LeftArrow, _.LeftArrow, _.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(0, 0)),
231+
"56"));
232+
233+
234+
// Test case - start with multi-line, cursor at end of second line (end of input)
235+
Test("1234\n9ABC\n5678", Keys("1234", _.ShiftEnter, "5678",
236+
_.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
237+
"9ABC"));
238+
239+
// Test case - start with multi-line, cursor at beginning of second line
240+
Test("1234\n9ABC\n5678", Keys("1234", _.ShiftEnter, "5678",
241+
_.LeftArrow, _.Home, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
242+
_.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
243+
"9ABC"));
244+
245+
// Test case - start with multi-line, cursor at end of first line
246+
Test("9ABC\n1234\n5678", Keys("1234", _.ShiftEnter, "5678",
247+
_.UpArrow, _.LeftArrow, _.End, CheckThat(() => AssertCursorLeftTopIs(4, 0)),
248+
_.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(0, 0)),
249+
"9ABC"));
250+
251+
// Test case - start with multi-line, cursor at beginning of first line - temporarily having to press Home twice to
252+
// work around bug in home handler.
253+
Test("9ABC\n1234\n5678", Keys("1234", _.ShiftEnter, "5678",
254+
_.UpArrow, _.LeftArrow, _.Home, _.Home, CheckThat(() => AssertCursorLeftTopIs(0, 0)),
255+
_.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(0, 0)),
256+
"9ABC"));
257+
258+
// Test case - insert multiple blank lines
259+
Test("1234\n9ABC\n\n5678", Keys("1234", _.ShiftEnter, "5678",
260+
_.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
261+
_.CtrlEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
262+
"9ABC"));
263+
}
264+
265+
[TestMethod]
266+
public void TestInsertLineBelow()
267+
{
268+
TestSetup(KeyMode.Cmd);
269+
270+
var continutationPromptLength = PSConsoleReadlineOptions.DefaultContinuationPrompt.Length;
271+
272+
// Test case - start with single line, cursor at end
273+
Test("1234\n56", Keys("1234",
274+
_.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
275+
"56"));
276+
277+
// Test case - start with single line, cursor in home position
278+
Test("1234\n56", Keys("1234",
279+
_.Home, _.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
280+
"56"));
281+
282+
// Test case - start with single line, cursor in middle
283+
Test("1234\n56", Keys("1234",
284+
_.LeftArrow, _.LeftArrow, _.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
285+
"56"));
286+
287+
// Test case - start with multi-line, cursor at end of second line (end of input)
288+
Test("1234\n5678\n9ABC", Keys("1234", _.ShiftEnter, "5678",
289+
_.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 2)),
290+
"9ABC"));
291+
292+
// Test case - start with multi-line, cursor at beginning of second line
293+
Test("1234\n5678\n9ABC", Keys("1234", _.ShiftEnter, "5678",
294+
_.LeftArrow, _.Home, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
295+
_.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 2)),
296+
"9ABC"));
297+
298+
// Test case - start with multi-line, cursor at end of first line
299+
Test("1234\n9ABC\n5678", Keys("1234", _.ShiftEnter, "5678",
300+
_.UpArrow, _.LeftArrow, _.End, CheckThat(() => AssertCursorLeftTopIs(4, 0)),
301+
_.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
302+
"9ABC"));
303+
304+
// Test case - start with multi-line, cursor at beginning of first line - temporarily having to press Home twice to
305+
// work around bug in home handler.
306+
Test("1234\n9ABC\n5678", Keys("1234", _.ShiftEnter, "5678",
307+
_.UpArrow, _.LeftArrow, _.Home, _.Home, CheckThat(() => AssertCursorLeftTopIs(0, 0)),
308+
_.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 1)),
309+
"9ABC"));
310+
311+
// Test case - insert multiple blank lines
312+
Test("1234\n5678\n\n9ABC", Keys("1234", _.ShiftEnter, "5678",
313+
_.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 2)),
314+
_.CtrlShiftEnter, CheckThat(() => AssertCursorLeftTopIs(continutationPromptLength, 3)),
315+
"9ABC"));
316+
}
317+
318+
[TestMethod]
319+
public void TestMultilineHomeBugFixed()
320+
{
321+
TestSetup(KeyMode.Cmd);
322+
323+
// Going from second line to first line, press left arrow and then home.
324+
// That puts cursor in column 1 instead of 0. Bug? This could have something
325+
// to do with BeginningOfLine testing against i > 1 in multiline edit instead
326+
// of i > 0.
327+
Test("1234\n9ABC", Keys("1234", _.ShiftEnter, "9ABC", _.UpArrow, _.LeftArrow, _.Home, CheckThat(() => AssertCursorLeftTopIs(0, 0))));
328+
}
329+
215330
[TestMethod]
216331
public void TestIgnore()
217332
{

0 commit comments

Comments
 (0)