diff options
author | Enan Ajmain <3nan.ajmain@gmail.com> | 2023-03-19 23:23:34 +0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-19 10:23:34 -0700 |
commit | 8786b2066d39e45295eacfe7b10263af4a330f2e (patch) | |
tree | 5f5167adebe656e0ce4ba1442c2536d23ab4882a | |
parent | 65046c830e14f8988d9c3b477187f6b871e45af2 (diff) | |
download | rneovim-8786b2066d39e45295eacfe7b10263af4a330f2e.tar.gz rneovim-8786b2066d39e45295eacfe7b10263af4a330f2e.tar.bz2 rneovim-8786b2066d39e45295eacfe7b10263af4a330f2e.zip |
fix: pasting in terminal buffer on windows #22566
Problem:
On Windows, pasting multiple lines on a terminal buffer cause all the
lines to appear on the same line, i.e., the line breaks are lost.
Cause:
Windows shells expect "\r\n" as line break but "terminal_paste" function
uses "\n".
Solution:
Use "\r\n" as line break for pasting in terminal buffer on Windows.
Note:
Although this issue was reported with powershell set as 'shell', it
occurs in cmd too.
Fixes #14621
-rw-r--r-- | src/nvim/terminal.c | 4 | ||||
-rw-r--r-- | test/functional/terminal/buffer_spec.lua | 68 |
2 files changed, 72 insertions, 0 deletions
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index fca8515fab..76fa3049f6 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -723,7 +723,11 @@ void terminal_paste(long count, char **y_array, size_t y_size) for (size_t j = 0; j < y_size; j++) { if (j) { // terminate the previous line +#ifdef MSWIN + terminal_send(curbuf->terminal, "\r\n", 2); +#else terminal_send(curbuf->terminal, "\n", 1); +#endif } size_t len = strlen(y_array[j]); if (len > buff_len) { diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 9c8b983ff7..676be151ee 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -429,3 +429,71 @@ it('terminal truncates number of composing characters to 5', function() meths.chan_send(chan, 'a' .. composing:rep(8)) retry(nil, nil, function() eq('a' .. composing:rep(5), meths.get_current_line()) end) end) + +if is_os('win') then + describe(':terminal in Windows', function() + local screen + + before_each(function() + clear() + feed_command('set modifiable swapfile undolevels=20') + poke_eventloop() + local cmd = '["cmd.exe","/K","PROMPT=$g$s"]' + screen = thelpers.screen_setup(nil, cmd) + end) + + it('"put" operator sends data normally', function() + feed('<c-\\><c-n>G') + feed_command('let @a = ":: tty ready"') + feed_command('let @a = @a . "\\n:: appended " . @a . "\\n\\n"') + feed('"ap"ap') + screen:expect([[ + | + > :: tty ready | + > :: appended :: tty ready | + > :: tty ready | + > :: appended :: tty ready | + ^> {2: } | + :let @a = @a . "\n:: appended " . @a . "\n\n" | + ]]) + -- operator count is also taken into consideration + feed('3"ap') + screen:expect([[ + > :: appended :: tty ready | + > :: tty ready | + > :: appended :: tty ready | + > :: tty ready | + > :: appended :: tty ready | + ^> {2: } | + :let @a = @a . "\n:: appended " . @a . "\n\n" | + ]]) + end) + + it('":put" command sends data normally', function() + feed('<c-\\><c-n>G') + feed_command('let @a = ":: tty ready"') + feed_command('let @a = @a . "\\n:: appended " . @a . "\\n\\n"') + feed_command('put a') + screen:expect([[ + | + > :: tty ready | + > :: appended :: tty ready | + > {2: } | + | + ^ | + :put a | + ]]) + -- line argument is only used to move the cursor + feed_command('6put a') + screen:expect([[ + | + > :: tty ready | + > :: appended :: tty ready | + > :: tty ready | + > :: appended :: tty ready | + ^> {2: } | + :6put a | + ]]) + end) + end) +end |