Skip to content

Commit e4bd694

Browse files
WestRyanKRyan West
authored and
Ryan West
committed
Add ViClipboardMode Option
This option allows the user to choose if they want the ViRegister to use the system clipboard or the default local clipboard. By setting ViClipboardMode to SystemClipboard, the user can easily copy and paste text in the PowerShell prompt using Vi shortcuts in Command mode.
1 parent e5537d8 commit e4bd694

File tree

4 files changed

+64
-11
lines changed

4 files changed

+64
-11
lines changed

PSReadLine/Cmdlets.cs

+19
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ public enum ViMode
5050
Command
5151
}
5252

53+
public enum ViClipboardMode
54+
{
55+
ViRegister,
56+
SystemClipboard
57+
}
58+
5359
public enum HistorySaveStyle
5460
{
5561
SaveIncrementally,
@@ -342,6 +348,11 @@ public object ContinuationPromptColor
342348
/// </summary>
343349
public ScriptBlock ViModeChangeHandler { get; set; }
344350

351+
/// <summary>
352+
/// Which source should be used when copying and pasting in vi edit mode?
353+
/// </summary>
354+
public ViClipboardMode ViClipboardMode { get; set; }
355+
345356
/// <summary>
346357
/// The path to the saved history.
347358
/// </summary>
@@ -789,6 +800,14 @@ public ViModeStyle ViModeIndicator
789800
[Parameter]
790801
public ScriptBlock ViModeChangeHandler { get; set; }
791802

803+
[Parameter]
804+
public ViClipboardMode ViClipboardMode
805+
{
806+
get => _viClipboardMode.GetValueOrDefault();
807+
set => _viClipboardMode = value;
808+
}
809+
internal ViClipboardMode? _viClipboardMode;
810+
792811
[Parameter]
793812
public PredictionSource PredictionSource
794813
{

PSReadLine/Options.cs

+4
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ private void SetOptionsInternal(SetPSReadLineOption options)
120120
}
121121
Options.ViModeChangeHandler = options.ViModeChangeHandler;
122122
}
123+
if (options._viClipboardMode.HasValue)
124+
{
125+
Options.ViClipboardMode = options.ViClipboardMode;
126+
}
123127
if (options.HistorySavePath != null)
124128
{
125129
Options.HistorySavePath = options.HistorySavePath;

PSReadLine/PSReadLine.format.ps1xml

+3
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ $d = [Microsoft.PowerShell.KeyHandler]::GetGroupingDescription($_.Group)
152152
<ItemSelectionCondition><ScriptBlock>$null -ne $_.ViModeChangeHandler</ScriptBlock></ItemSelectionCondition>
153153
<PropertyName>ViModeChangeHandler</PropertyName>
154154
</ListItem>
155+
<ListItem>
156+
<PropertyName>ViClipboardMode</PropertyName>
157+
</ListItem>
155158
<ListItem>
156159
<PropertyName>WordDelimiters</PropertyName>
157160
</ListItem>

PSReadLine/ViRegister.cs

+38-11
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,32 @@ public partial class PSConsoleReadLine
1111
internal sealed class ViRegister
1212
{
1313
private readonly PSConsoleReadLine _singleton;
14-
private string _text;
14+
private string _localText;
15+
private string Text
16+
{
17+
get
18+
{
19+
if (_singleton.Options.ViClipboardMode == ViClipboardMode.ViRegister)
20+
{
21+
return _localText;
22+
}
23+
else
24+
{
25+
return Internal.Clipboard.GetText();
26+
}
27+
}
28+
set
29+
{
30+
if (_singleton.Options.ViClipboardMode == ViClipboardMode.ViRegister)
31+
{
32+
_localText = value;
33+
}
34+
else
35+
{
36+
Internal.Clipboard.SetText(value);
37+
}
38+
}
39+
}
1540

1641
/// <summary>
1742
/// Initialize a new instance of the <see cref="ViRegister" /> class.
@@ -29,7 +54,7 @@ public ViRegister(PSConsoleReadLine singleton)
2954
/// Returns whether this register is empty.
3055
/// </summary>
3156
public bool IsEmpty
32-
=> String.IsNullOrEmpty(_text);
57+
=> String.IsNullOrEmpty(Text);
3358

3459
/// <summary>
3560
/// Returns whether this register contains
@@ -41,7 +66,7 @@ public bool IsEmpty
4166
/// Gets the raw text contained in the register
4267
/// </summary>
4368
public string RawText
44-
=> _text;
69+
=> Text;
4570

4671
/// <summary>
4772
/// Records the entire buffer in the register.
@@ -67,7 +92,7 @@ public void Record(StringBuilder buffer, int offset, int count)
6792
System.Diagnostics.Debug.Assert(offset + count <= buffer.Length);
6893

6994
HasLinewiseText = false;
70-
_text = buffer.ToString(offset, count);
95+
Text = buffer.ToString(offset, count);
7196
}
7297

7398
/// <summary>
@@ -77,7 +102,7 @@ public void Record(StringBuilder buffer, int offset, int count)
77102
public void LinewiseRecord(string text)
78103
{
79104
HasLinewiseText = true;
80-
_text = text;
105+
Text = text;
81106
}
82107

83108
public int PasteAfter(StringBuilder buffer, int position)
@@ -89,7 +114,7 @@ public int PasteAfter(StringBuilder buffer, int position)
89114

90115
if (HasLinewiseText)
91116
{
92-
var text = _text;
117+
var text = Text;
93118

94119
if (text[0] != '\n')
95120
{
@@ -127,8 +152,9 @@ public int PasteAfter(StringBuilder buffer, int position)
127152
position += 1;
128153
}
129154

130-
InsertAt(buffer, _text, position, position);
131-
position += _text.Length - 1;
155+
var text = Text;
156+
InsertAt(buffer, text, position, position);
157+
position += text.Length - 1;
132158

133159
return position;
134160
}
@@ -145,7 +171,7 @@ public int PasteBefore(StringBuilder buffer, int position)
145171

146172
position = Math.Max(0, Math.Min(position, buffer.Length - 1));
147173

148-
var text = _text;
174+
var text = Text;
149175

150176
if (text[0] == '\n')
151177
{
@@ -184,8 +210,9 @@ public int PasteBefore(StringBuilder buffer, int position)
184210
}
185211
else
186212
{
187-
InsertAt(buffer, _text, position, position);
188-
return position + _text.Length - 1;
213+
var text = Text;
214+
InsertAt(buffer, text, position, position);
215+
return position + text.Length - 1;
189216
}
190217
}
191218

0 commit comments

Comments
 (0)