Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Right click paste should work mostly like Ctrl+v paste #579

Open
lzybkr opened this issue Nov 11, 2017 · 34 comments
Open

Right click paste should work mostly like Ctrl+v paste #579

lzybkr opened this issue Nov 11, 2017 · 34 comments
Milestone

Comments

@lzybkr
Copy link
Member

lzybkr commented Nov 11, 2017

There are various complaints about the right click to paste behavior - all of which are non-issues with Ctrl+v paste.

This includes:

The fix for this should also address #290 by checking if the input is "complete" after a newline, though it should check if the last statement could be continued even if it is complete, e.g. if w/o an else or try without a finally.

@Tadas
Copy link

Tadas commented Nov 12, 2017

So I mentioned capturing mouse events and I came up with this PoC https://github.com/Tadas/PSReadLine/tree/MouseHook

Basically this installs a global Windows event hook to capture right clicks. It looks for ones going to our console window, makes sure that the click was in the client area and if we're in quick edit mode calls PSConsoleReadLine.Paste() directly while suppressing the event.

With some more hackery I think it would be possible to intercept Paste action from the context menu.

@lzybkr
Copy link
Member Author

lzybkr commented Nov 12, 2017

Interesting approach.

I'm not interested in taking a dependency on System.Windows.Forms - I used it for clipboard support but removed the dependency to work as a netstandard2 assembly. I haven't switched the build over though because it gets unnecessarily messy with unnecessary assemblies in the build output directory.

I'm also a bit concerned about ensuring UnhookWindowsHookEx is always called, e.g. I have some code that should be running when PowerShell exits but it doesn't seem to happen, see #262.

@lzybkr
Copy link
Member Author

lzybkr commented Nov 12, 2017

One other thing - ideally we can fix this on every platform, not just Windows. The heuristic approach should work cross-platform, but I'm open to more reliable approaches like yours if there is a solution for the various non-Windows platforms as well.

@MaximoTrinidad
Copy link

FYI

This issue still persist on PowerShell Core 6 RC.
:)

psreadline_ifelse_issue_2017-11-20_14-37-20

@lzybkr
Copy link
Member Author

lzybkr commented Nov 20, 2017

@MaximoTrinidad - PSReadLine has always worked this way and it is a little different than without PSReadLine. It wasn't much of a problem because Ctrl+v is preferred - it is way faster and characters like Tab don't get expanded incorrectly.

Now this problem is more annoying on PowerShell Core because the port that the PowerShell team did not support the clipboard. My port does, so when PSReadLine 2.0 is widely available, I'll continue to recommend folks use Ctrl+v instead of right click.

That said, it would be nice to see this fixed at some point.

@MaximoTrinidad
Copy link

MaximoTrinidad commented Nov 20, 2017

Hum! Interesting.

They force me to close my incident about the issue with the If-Else block not working after pasting it into PowerShell Core as it breaks at the "else".

I just tried using Ctrl-V and it do nothing. In the other hand, doing the right-click on the mouse works.

My issue wasn't really the pasting of the code. The If-Else should work with both structure:

PowerShell v6.0.0-rc
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/pscore6-docs
Type 'help' to get help.

PS C:\Program Files\PowerShell\6.0.0-rc> # the following code block will break:
PS C:\Program Files\PowerShell\6.0.0-rc> $m = "max"; if($m -eq "elaine")
>> {
>>   "Its elaine!!"
>> }
PS C:\Program Files\PowerShell\6.0.0-rc> else
else : The term 'else' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ else
+ ~~~~
+ CategoryInfo          : ObjectNotFound: (else:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

PS C:\Program Files\PowerShell\6.0.0-rc> {
>>  "Its not elaine"
>> }

 "Its not elaine"

PS C:\Program Files\PowerShell\6.0.0-rc> # the following code block will execute:
PS C:\Program Files\PowerShell\6.0.0-rc> $m = "max"; if ($m -eq "elaine")
>> {
>> "Its elaine!!"
>> }else{
>> "Its not elaine"
>> }
Its not elaine
PS C:\Program Files\PowerShell\6.0.0-rc>

I know if I remove the module then is works as expected.
:)

@lzybkr
Copy link
Member Author

lzybkr commented Nov 20, 2017

As I said, Ctrl+v works in Windows PowerShell, but you need PSReadLine 2.0 (no official builds available yet) for PowerShell Core.

And I fully understand the problem, you don't need to keep repeating yourself.

Without PSReadLine, if there is multi-line input, you must enter a single blank line before the input is accepted.

With PSReadLine, if the input is "complete", as in, it parses without an IncompleteParseException, then the input will be accepted without that extra blank line.

So PSReadLine is just different and that's not changing. If you aren't pasting, you use Shift+Enter when you know you're not done - this way you can enter your else without PSReadLine accepting the input.

When you paste, you can't use Shift+Enter, so the input might get accepted before you wanted.

This issue is to attempt to emulate Ctrl+v when you right click paste so that the experience is better, but I do not plan on requiring a blank line to accept multi-line input.

@MaximoTrinidad
Copy link

My Apologies!

It's been a tough day! At least, it's manageable, and not show stopper as the script will execute regardless of the way I code the If-Else block.

I appreciate all the information,

:)

@Tadas
Copy link

Tadas commented Nov 25, 2017

I don't understand why you mentioned cross platform'ness - isn't this right-click paste issue strictly a Windows thing?

Anyway, I've removed System.Windows.Forms by implementing the message loop. It needs to be improved further because right now it keeps calling PeekMessage as fast as it can which is unnecessary.

Seems like always calling UnhookWindowsHookEx might be not that important as long as the hooking process exits. At least I've never had any issues during debugging.

@lzybkr
Copy link
Member Author

lzybkr commented Nov 25, 2017

Maybe not with a right click, but Linux and Mac terminals definitely support paste. For example, the default graphical terminal in CentOS has Edit|Paste in the main menu and Paste in a right click popup menu.

My concern about UnhookWindowsHookEx is purely based on the documentation - they usually have a good reason to call it out. Maybe try running PowerShell a few thousand times to see if system performance degrades.

As you pointed out, the busy loop is too busy. I use a 300ms wait to check for idle events in the main input loop - 300ms is supposedly long enough to not hurt battery life.

@mklement0
Copy link

Just to summarize the status quo on (some) Unix-like platforms (macOS 10.13 with either Terminal.app or iTerm2.app, Ubuntu 16 with its default terminal):

  • The Ctrl+V workaround applies to Windows only (similarly, binding a custom chord to the Paste function doesn't work on Unix).

  • As with right-clicking on Windows, using the terminal-program specific keyboard shortcut for pasting (Cmd+V on macOS, Ctrl+Shift+Von Ubuntu), seems to paste by simulating interactive typing.

@MashaMSFT
Copy link

i am pasting a block of code from windows 5.1 powershel ise into powershell 6 via conhost.exe and when i paste with a right click, some of my dashes are missing, whereas if i paste with ctrl+v the dashes are there

image

@SteveL-MSFT
Copy link
Member

SteveL-MSFT commented Oct 29, 2019

I don't see an obvious way to fix this. On Windows, I can see that when pasting via Ctrl+V (which is handled by Windows Terminal and not PSRL), the end of line is \r\n where the \n is Ctrl+Enter. The \r (Enter) is handled by PSRL as AcceptLine and executes. On macOS, the line ending is just \r (without any modifier). So the best workaround is to bind PSReadLine Paste handler to some chord and use that which pastes correctly.

It is interesting that without PSReadLine, the basic ReadLine in pwsh handles this correctly...

@mklement0
Copy link

@SteveL-MSFT: As for macOS: haven't looked in detail, but multi-line pasting with the default keyboard shortcut (Cmd-V) seems to work just fine in PSRL 2.0.0 beta.4, with both CRLF- and platform-native LF-only text.

On macOS, the line ending is just \r

In case you're referring to the platform-native newline sequence on macOS: When macOS became OS X in 2001 and thereby became Unix-like, LF (\n) became the newline sequence. Only the long-obsolete Mac OS 9 and earlier used CR-only (\r) newlines.

@lzybkr
Copy link
Member Author

lzybkr commented Oct 29, 2019

@SteveL-MSFT - I hinted at the solution above and probably describe it in detail in a linked issue.

If we can infer that a user "pasted" via right click, then we can process keys differently. By tracking the time between key presses, I think it's probably reasonable to infer the user isn't actually typing.

I'm guessing that if the delay between keys is less than 25ms or so, it's not a human typing, especially if we average over enough keys.

@SteveL-MSFT
Copy link
Member

@mklement0 I'm running Catalina, the \r is just what I see in the debugger within PSRL.

@lzybkr detecting that the input isn't human may be good enough.

@mklement0
Copy link

mklement0 commented Oct 29, 2019

Thanks for clarifying and sorry fo the distraction, @SteveL-MSFT (I didn't know that Unix terminals apparently translate \n in multi-line text to \r, which traditionally acts as the accept-line key, on pasting).

So while the multi-line issues specifically appear not to affect macOS and Linux, PSRL's processing of the input as being typed by the user can cause problems in combination with custom key handlers that modify / complete input (as shown in #735), so the fix proposed by @lzybkr should help on these platforms too.

@msftrncs
Copy link
Collaborator

So while the multi-line issues specifically appear not to affect macOS and Linux, PSRL's processing of the input as being typed by the user can cause problems in combination with custom key handlers that modify / complete input (as show in #735), so the fix proposed by @lzybkr should help on these platforms too.

I didn't find the behavior to be any different in Ubuntu's terminal when pasting. Pasting a multiline IF ELSEIF ELSE statement still got executed between the statement blocks if PSReadLine was imported.

@ozdeadmeat

This comment has been minimized.

@SteveL-MSFT
Copy link
Member

@daxian-dbw looks like Windows Terminal now has support for bracketed paste, so we should be able to fix this in PSReadLine now

@SteveL-MSFT SteveL-MSFT added this to the 2.2.0-Consider milestone Sep 16, 2021
@lzybkr
Copy link
Member Author

lzybkr commented Sep 16, 2021

Hopefully I'm wrong, but it might not be easy to use bracketed paste, see #1471 (comment)

@Gilgamech
Copy link

Have you tried reversing the paste order when right clicking? Seems like it should be an easy fix, just change from [$len..0] to [0..$len]

Kinda absurd that this simple issue keeps popping up.

@robinmalik
Copy link

Hitting this issue when pasting tab indented multiline code blocks regardless of whether I use CTRL+V or right click, but only in PowerShell 7 (currently on 7.4.1). PSReadline is 2.3.4.

Example block snipped for brevity:

$SharedConfig = [PSCustomObject]@{
	'BIOSPolicyName'            = 'ESXi-BIOS'
	'BootPolicyName'            = 'ESXi-iSCSI'
	'ChassisDiscoveryPolicy'    = '2-link'
	'EthernetPinGroupName'      = 'core'
}

PS 7.4.1

image

PS 5.1
image

@mcdonamw
Copy link

mcdonamw commented Jun 7, 2024

I found my way here regarding the right-click paste in reverse issue. It's now 2024, and this is still an issue in Powershell 7. I cannot follow the thread above as it just seems the conversation about this died (unless I'm missing something), but the referenced issue (#496) is marked closed. What was the final disposition on this issue? Can it not be fixed? It's so annoying copying code from ChatGPT only to have it reversed when pasted. A right click is easier for me than ctrl+v.

@Gilgamech
Copy link

The only solution I found was to use a different console host.

@JimNim
Copy link

JimNim commented Aug 16, 2024

Still not fixed in v7, SEVEN YEARS LATER, as of v7.4.4.
FWIW though, this does not appear to be a problem with Windows 11's "terminal".
I'm also able to work-around this issue with v7 via Shift+Insert pasting

@01ax
Copy link

01ax commented Aug 21, 2024

Hey all - I was able to mitigate this by pasting snippit(s)/command(s) into notepad, ensure the formatting is correct, copy the snippit/command from notepad and paste into the console.

@mcdonamw
Copy link

FYI you have to do all that. Just use Ctrl+V on the keyboard to paste and it should be fine. The issue is only with paste via mouse right-click.

@QGtKMlLz
Copy link

QGtKMlLz commented Oct 7, 2024

I've been having the same issue; I find this unbelievable this has been open for 7 years, as we come up on the anniversary date!

@Gilgamech
Copy link

There's no AI component so the board room doesn't care.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests