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

Bracketed Paste does not preserve newline characters in some terminal #576

Closed
sigoden opened this issue Apr 27, 2023 · 9 comments · Fixed by #577
Closed

Bracketed Paste does not preserve newline characters in some terminal #576

sigoden opened this issue Apr 27, 2023 · 9 comments · Fixed by #577
Labels
bug Something isn't working

Comments

@sigoden
Copy link
Contributor

sigoden commented Apr 27, 2023

Platform macOS
Terminal software iTerm2

Bracketed Paste does not preserve newline characters in some terminal.

Steps to reproduce

  1. run demo
cargo run --example demo
  1. copy multiple line text
struct BufferEditor {
    editor: String,
    extension: String,
}
  1. paste texts to demo repl
}   extension: String,ufferEditor {   

This may related to crossterm-rs/crossterm#780
In some terminal, they write \r instead of \n when pasting.

Event: Paste("struct BufferEditor {\r    editor: String,\r    extension: String,\r}")
@sigoden sigoden added the bug Something isn't working label Apr 27, 2023
@sholderbach
Copy link
Member

Thanks for the report!

This seems to be related to the trouble we were observing in nushell/nushell#8907

@sigoden
Copy link
Contributor Author

sigoden commented Apr 27, 2023

We can fix it with following patch.

diff --git a/src/edit_mode/emacs.rs b/src/edit_mode/emacs.rs
index ec35384..54067aa 100644
--- a/src/edit_mode/emacs.rs
+++ b/src/edit_mode/emacs.rs
@@ -156,7 +156,7 @@ impl EditMode for Emacs {
             Event::Resize(width, height) => ReedlineEvent::Resize(width, height),
             Event::FocusGained => ReedlineEvent::None,
             Event::FocusLost => ReedlineEvent::None,
-            Event::Paste(body) => ReedlineEvent::Edit(vec![EditCommand::InsertString(body)]),
+            Event::Paste(body) => ReedlineEvent::Edit(vec![EditCommand::InsertString(body.replace('\r', "\n"))]),
         }
     }
 
diff --git a/src/edit_mode/vi/mod.rs b/src/edit_mode/vi/mod.rs
index 2a20155..ab5dc1b 100644
--- a/src/edit_mode/vi/mod.rs
+++ b/src/edit_mode/vi/mod.rs
@@ -153,7 +153,7 @@ impl EditMode for Vi {
             Event::Resize(width, height) => ReedlineEvent::Resize(width, height),
             Event::FocusGained => ReedlineEvent::None,
             Event::FocusLost => ReedlineEvent::None,
-            Event::Paste(body) => ReedlineEvent::Edit(vec![EditCommand::InsertString(body)]),
+            Event::Paste(body) => ReedlineEvent::Edit(vec![EditCommand::InsertString(body.replace('\r', "\n"))]),
         }
     }
 

@fdncred
Copy link
Collaborator

fdncred commented Apr 27, 2023

Tagging @WindSoilder since could be a work-around to nushell/nushell#8907

@sholderbach
Copy link
Member

sholderbach commented Apr 27, 2023

We can fix it with following patch.

Mhh worth checking if there are differences on Windows here.

@WindSoilder
Copy link
Contributor

WindSoilder commented Apr 27, 2023

So maybe we need to do something like this?

  1. replace \r\n to a single \n
  2. replace a single \r to \n

@sigoden
Copy link
Contributor Author

sigoden commented Apr 27, 2023

git clone https://github.com/crossterm-rs/crossterm
cd crossterm
cargo run --example event-read

Copy following text.

a
b

In macos/linux, after paste text above, I get events:

Event: FocusGained
Event: Paste("a\rb")
Event: Key(KeyEvent { code: Esc, modifiers: NONE, kind: Press, state: NONE })

In windows, after paste text above, I get events:

Event: Key(KeyEvent { code: Char('a'), modifiers: KeyModifiers(0x0), kind: Press, state: KeyEventState(0x0) })
Event: Key(KeyEvent { code: Char('a'), modifiers: KeyModifiers(0x0), kind: Release, state: KeyEventState(0x0) })
Event: Key(KeyEvent { code: Enter, modifiers: KeyModifiers(0x0), kind: Press, state: KeyEventState(0x0) })
Event: Key(KeyEvent { code: Enter, modifiers: KeyModifiers(0x0), kind: Release, state: KeyEventState(0x0) })
Event: Key(KeyEvent { code: Char('b'), modifiers: KeyModifiers(0x0), kind: Press, state: KeyEventState(0x0) })
Event: Key(KeyEvent { code: Char('b'), modifiers: KeyModifiers(0x0), kind: Release, state: KeyEventState(0x0) })
Event: Key(KeyEvent { code: Esc, modifiers: KeyModifiers(0x0), kind: Press, state: KeyEventState(0x0) })

In windows, crossterm dispatchs individual key events other than paste event.

No need to replace \r\n to a single \n.

@sigoden sigoden closed this as completed Apr 27, 2023
@sigoden sigoden reopened this Apr 27, 2023
@fdncred
Copy link
Collaborator

fdncred commented Apr 27, 2023

It's interesting that it does a Press and Release in Windows but not in MacOS & Linux.

@WindSoilder
Copy link
Contributor

WindSoilder commented Apr 27, 2023

It's interesting that it does a Press and Release in Windows but not in MacOS & Linux.

Yeah because it's always enabled on Windows, here is a relative pr to make it optional: crossterm-rs/crossterm#778

@WindSoilder
Copy link
Contributor

@sigoden Thank you for your testing on windows and mac.

So bracketed paste still doesn't work on windows. And currently we can simply replace from \r to \n.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants