aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerw7 <erw7.github@gmail.com>2017-03-28 18:07:58 +0900
committerJustin M. Keyes <justinkz@gmail.com>2017-08-16 09:13:43 +0200
commit4b1f21de75f9981007d80aca8355239e8615d6bd (patch)
treeb0322a5b61eacbd6207603b346fca2f7d957458a
parenta79785675564a4c1f02f9aa54249fc6000187c0d (diff)
downloadrneovim-4b1f21de75f9981007d80aca8355239e8615d6bd.tar.gz
rneovim-4b1f21de75f9981007d80aca8355239e8615d6bd.tar.bz2
rneovim-4b1f21de75f9981007d80aca8355239e8615d6bd.zip
win: support :terminal
-rw-r--r--src/nvim/CMakeLists.txt1
-rw-r--r--src/nvim/os/pty_process_win.c232
-rw-r--r--src/nvim/os/pty_process_win.h13
-rw-r--r--test/functional/fixtures/tty-test.c44
-rw-r--r--test/functional/terminal/buffer_spec.lua6
-rw-r--r--test/functional/terminal/cursor_spec.lua2
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua11
-rw-r--r--test/functional/terminal/helpers.lua7
-rw-r--r--test/functional/terminal/highlight_spec.lua5
-rw-r--r--test/functional/terminal/mouse_spec.lua5
-rw-r--r--test/functional/terminal/scrollback_spec.lua64
-rw-r--r--test/functional/terminal/window_spec.lua2
12 files changed, 284 insertions, 108 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 9bb3fbfcbe..2e0a35d4ab 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -436,6 +436,7 @@ if(WIN32)
COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Network.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Svg.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Widgets.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/winpty.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/platforms/qwindows.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/platforms/
)
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c
index e75c92e7fb..ea95c1bb09 100644
--- a/src/nvim/os/pty_process_win.c
+++ b/src/nvim/os/pty_process_win.c
@@ -2,30 +2,53 @@
#include <stdbool.h>
#include <stdlib.h>
+#include "nvim/vim.h"
+#include "nvim/ascii.h"
#include "nvim/memory.h"
+#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
#include "nvim/os/pty_process_win.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/pty_process_win.c.generated.h"
#endif
+static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)
+ FUNC_ATTR_NONNULL_ALL
+{
+ PtyProcess *ptyproc =
+ (PtyProcess *)((uv_handle_t *)wait_eof_timer->data);
+ Process *proc = (Process *)ptyproc;
+
+ if (!uv_is_readable(proc->out->uvstream)) {
+ uv_timer_stop(&ptyproc->wait_eof_timer);
+ pty_process_finish2(ptyproc);
+ }
+}
+
static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused)
+ FUNC_ATTR_NONNULL_ALL
{
- uv_async_t *finish_async = (uv_async_t *)context;
- uv_async_send(finish_async);
+ PtyProcess *ptyproc = (PtyProcess *)context;
+ Process *proc = (Process *)ptyproc;
+
+ uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer);
+ ptyproc->wait_eof_timer.data = (void *)ptyproc;
+ uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
}
-bool pty_process_spawn(PtyProcess *ptyproc)
+int pty_process_spawn(PtyProcess *ptyproc)
FUNC_ATTR_NONNULL_ALL
{
Process *proc = (Process *)ptyproc;
- bool success = false;
+ int status = 0;
winpty_error_ptr_t err = NULL;
winpty_config_t *cfg = NULL;
winpty_spawn_config_t *spawncfg = NULL;
winpty_t *wp = NULL;
char *in_name = NULL, *out_name = NULL;
HANDLE process_handle = NULL;
+ uv_connect_t *in_req = NULL, *out_req = NULL;
+ wchar_t *cmdline = NULL, *cwd = NULL;
assert(proc->in && proc->out && !proc->err);
@@ -33,52 +56,70 @@ bool pty_process_spawn(PtyProcess *ptyproc)
WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err))) {
goto cleanup;
}
- winpty_config_set_initial_size(cfg, ptyproc->width, ptyproc->height);
+ winpty_config_set_initial_size(
+ cfg,
+ ptyproc->width,
+ ptyproc->height);
if (!(wp = winpty_open(cfg, &err))) {
goto cleanup;
}
- in_name = utf16_to_utf8(winpty_conin_name(wp));
- out_name = utf16_to_utf8(winpty_conout_name(wp));
+ if ((status = utf16_to_utf8(winpty_conin_name(wp), &in_name))) {
+ goto cleanup;
+ }
+ if ((status = utf16_to_utf8(winpty_conout_name(wp), &out_name))) {
+ goto cleanup;
+ }
+ in_req = xmalloc(sizeof(uv_connect_t));
+ out_req = xmalloc(sizeof(uv_connect_t));
uv_pipe_connect(
- xmalloc(sizeof(uv_connect_t)),
+ in_req,
&proc->in->uv.pipe,
in_name,
pty_process_connect_cb);
uv_pipe_connect(
- xmalloc(sizeof(uv_connect_t)),
+ out_req,
&proc->out->uv.pipe,
out_name,
pty_process_connect_cb);
- // XXX: Provide the correct ptyprocess parameters (at least, the cmdline...
- // probably cwd too? what about environ?)
+ if (proc->cwd != NULL && (status = utf8_to_utf16(proc->cwd, &cwd))) {
+ goto cleanup;
+ }
+ if ((status = build_cmdline(proc->argv, &cmdline))) {
+ goto cleanup;
+ }
if (!(spawncfg = winpty_spawn_config_new(
WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN,
- L"C:\\Windows\\System32\\cmd.exe",
- L"C:\\Windows\\System32\\cmd.exe",
- NULL, NULL,
- &err))) {
+ NULL, cmdline, cwd, NULL, &err))) {
goto cleanup;
}
if (!winpty_spawn(wp, spawncfg, &process_handle, NULL, NULL, &err)) {
goto cleanup;
}
+ proc->pid = GetProcessId(process_handle);
- uv_async_init(&proc->loop->uv, &ptyproc->finish_async, pty_process_finish2);
- if (!RegisterWaitForSingleObject(&ptyproc->finish_wait, process_handle,
- pty_process_finish1, &ptyproc->finish_async, INFINITE, 0)) {
+ if (!RegisterWaitForSingleObject(
+ &ptyproc->finish_wait,
+ process_handle, pty_process_finish1, ptyproc,
+ INFINITE, WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
abort();
}
+ while (in_req->handle || out_req->handle) {
+ uv_run(&proc->loop->uv, UV_RUN_ONCE);
+ }
+
ptyproc->wp = wp;
ptyproc->process_handle = process_handle;
wp = NULL;
process_handle = NULL;
- success = true;
cleanup:
+ if (err != NULL) {
+ status = (int)winpty_error_code(err);
+ }
winpty_error_free(err);
winpty_config_free(cfg);
winpty_spawn_config_free(spawncfg);
@@ -88,7 +129,11 @@ cleanup:
if (process_handle != NULL) {
CloseHandle(process_handle);
}
- return success;
+ xfree(in_req);
+ xfree(out_req);
+ xfree(cmdline);
+ xfree(cwd);
+ return status;
}
void pty_process_resize(PtyProcess *ptyproc, uint16_t width,
@@ -105,17 +150,10 @@ void pty_process_close(PtyProcess *ptyproc)
{
Process *proc = (Process *)ptyproc;
- ptyproc->is_closing = true;
pty_process_close_master(ptyproc);
- uv_handle_t *finish_async_handle = (uv_handle_t *)&ptyproc->finish_async;
- if (ptyproc->finish_wait != NULL) {
- // Use INVALID_HANDLE_VALUE to block until either the wait is cancelled
- // or the callback has signalled the uv_async_t.
- UnregisterWaitEx(ptyproc->finish_wait, INVALID_HANDLE_VALUE);
- uv_close(finish_async_handle, pty_process_finish_closing);
- } else {
- pty_process_finish_closing(finish_async_handle);
+ if (proc->internal_close_cb) {
+ proc->internal_close_cb(proc);
}
}
@@ -133,57 +171,123 @@ void pty_process_teardown(Loop *loop)
{
}
-// Returns a string freeable with xfree. Never returns NULL (OOM is a fatal
-// error). Windows appears to replace invalid UTF-16 code points (i.e.
-// unpaired surrogates) using U+FFFD (the replacement character).
-static char *utf16_to_utf8(LPCWSTR str)
- FUNC_ATTR_NONNULL_ALL
-{
- int len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
- assert(len >= 1); // Even L"" has a non-zero length due to NUL terminator.
- char *ret = xmalloc(len);
- int len2 = WideCharToMultiByte(CP_UTF8, 0, str, -1, ret, len, NULL, NULL);
- assert(len == len2);
- return ret;
-}
-
static void pty_process_connect_cb(uv_connect_t *req, int status)
+ FUNC_ATTR_NONNULL_ALL
{
assert(status == 0);
- xfree(req);
+ req->handle = NULL;
}
-static void pty_process_finish2(uv_async_t *finish_async)
+static void pty_process_finish2(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
{
- PtyProcess *ptyproc =
- (PtyProcess *)((char *)finish_async - offsetof(PtyProcess, finish_async));
Process *proc = (Process *)ptyproc;
- if (!ptyproc->is_closing) {
- // If pty_process_close has already been called, be consistent and never
- // call the internal_exit callback.
+ UnregisterWaitEx(ptyproc->finish_wait, NULL);
+ uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL);
+
+ DWORD exit_code = 0;
+ GetExitCodeProcess(ptyproc->process_handle, &exit_code);
+ proc->status = (int)exit_code;
- DWORD exit_code = 0;
- GetExitCodeProcess(ptyproc->process_handle, &exit_code);
- proc->status = exit_code;
+ CloseHandle(ptyproc->process_handle);
+ ptyproc->process_handle = NULL;
- if (proc->internal_exit_cb) {
- proc->internal_exit_cb(proc);
+ proc->internal_exit_cb(proc);
+}
+
+static int build_cmdline(char **argv, wchar_t **cmdline)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char *args = NULL;
+ size_t args_len = 0, argc = 0;
+ int ret;
+ QUEUE q;
+ QUEUE_INIT(&q);
+
+ while (*argv) {
+ arg_T *arg = xmalloc(sizeof(arg_T));
+ arg->arg = (char *)xmalloc(strlen(*argv) * 2 + 3);
+ quote_cmd_arg(arg->arg, *argv);
+ args_len += strlen(arg->arg);
+ QUEUE_INIT(&arg->node);
+ QUEUE_INSERT_TAIL(&q, &arg->node);
+ argc++;
+ argv++;
+ }
+ args_len += argc;
+ args = xmalloc(args_len);
+ *args = NUL;
+ while (1) {
+ QUEUE *head = QUEUE_HEAD(&q);
+ QUEUE_REMOVE(head);
+ arg_T *arg = QUEUE_DATA(head, arg_T, node);
+ xstrlcat(args, arg->arg, args_len);
+ xfree(arg->arg);
+ xfree(arg);
+ if (QUEUE_EMPTY(&q)) {
+ break;
+ } else {
+ xstrlcat(args, " ", args_len);
}
}
+ ret = utf8_to_utf16(args, cmdline);
+ xfree(args);
+ return ret;
}
-static void pty_process_finish_closing(uv_handle_t *finish_async)
+// Emulate quote_cmd_arg of libuv and quotes command line arguments
+static void quote_cmd_arg(char *target, const char *source)
+ FUNC_ATTR_NONNULL_ALL
{
- PtyProcess *ptyproc =
- (PtyProcess *)((char *)finish_async - offsetof(PtyProcess, finish_async));
- Process *proc = (Process *)ptyproc;
+ size_t len = strlen(source);
+ size_t i;
+ bool quote_hit = true;
+ char *start = target;
+ char tmp;
- if (ptyproc->process_handle != NULL) {
- CloseHandle(ptyproc->process_handle);
- ptyproc->process_handle = NULL;
+ if (len == 0) {
+ *(target++) = '"';
+ *(target++) = '"';
+ *target = NUL;
+ return;
}
- if (proc->internal_close_cb) {
- proc->internal_close_cb(proc);
+
+ if (NULL == strpbrk(source, " \t\"")) {
+ strcpy(target, source);
+ return;
+ }
+
+ if (NULL == strpbrk(source, "\"\\")) {
+ *(target++) = '"';
+ strncpy(target, source, len);
+ target += len;
+ *(target++) = '"';
+ *target = NUL;
+ return;
+ }
+
+ *(target++) = NUL;
+ *(target++) = '"';
+ for (i = len; i > 0; --i) {
+ *(target++) = source[i - 1];
+
+ if (quote_hit && source[i - 1] == '\\') {
+ *(target++) = '\\';
+ } else if (source[i - 1] == '"') {
+ quote_hit = true;
+ *(target++) = '\\';
+ } else {
+ quote_hit = false;
+ }
+ }
+ *target = '"';
+ while (start < target) {
+ tmp = *start;
+ *start = *target;
+ *target = tmp;
+ start++;
+ target--;
}
+ return;
}
diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h
index 87b2b6545d..806857f130 100644
--- a/src/nvim/os/pty_process_win.h
+++ b/src/nvim/os/pty_process_win.h
@@ -5,19 +5,24 @@
#include <winpty.h>
-#include "nvim/event/libuv_process.h"
+#include "nvim/event/process.h"
+#include "nvim/lib/queue.h"
typedef struct pty_process {
Process process;
char *term_name;
uint16_t width, height;
winpty_t *wp;
- uv_async_t finish_async;
HANDLE finish_wait;
HANDLE process_handle;
- bool is_closing;
+ uv_timer_t wait_eof_timer;
} PtyProcess;
+typedef struct arg_S {
+ char *arg;
+ QUEUE node;
+} arg_T;
+
static inline PtyProcess pty_process_init(Loop *loop, void *data)
{
PtyProcess rv;
@@ -26,10 +31,8 @@ static inline PtyProcess pty_process_init(Loop *loop, void *data)
rv.width = 80;
rv.height = 24;
rv.wp = NULL;
- // XXX: Zero rv.finish_async somehow?
rv.finish_wait = NULL;
rv.process_handle = NULL;
- rv.is_closing = false;
return rv;
}
diff --git a/test/functional/fixtures/tty-test.c b/test/functional/fixtures/tty-test.c
index 7ba21d652a..dd94d1a256 100644
--- a/test/functional/fixtures/tty-test.c
+++ b/test/functional/fixtures/tty-test.c
@@ -15,10 +15,12 @@ uv_tty_t tty;
#include <windows.h>
bool owns_tty(void)
{
- HWND consoleWnd = GetConsoleWindow();
- DWORD dwProcessId;
- GetWindowThreadProcessId(consoleWnd, &dwProcessId);
- return GetCurrentProcessId() == dwProcessId;
+ /* XXX: We need to make proper detect owns tty */
+ /* HWND consoleWnd = GetConsoleWindow(); */
+ /* DWORD dwProcessId; */
+ /* GetWindowThreadProcessId(consoleWnd, &dwProcessId); */
+ /* return GetCurrentProcessId() == dwProcessId; */
+ return true;
}
#else
#include <unistd.h>
@@ -54,16 +56,18 @@ static void sig_handler(int signum)
return;
}
}
+#else
+static void sigwinch_cb(uv_signal_t *handle, int signum)
+{
+ int width, height;
+ uv_tty_t out;
+ uv_tty_init(uv_default_loop(), &out, fileno(stdout), 0);
+ uv_tty_get_winsize(&out, &width, &height);
+ fprintf(stderr, "rows: %d, cols: %d\n", height, width);
+ uv_close((uv_handle_t *)&out, NULL);
+}
#endif
-// static void sigwinch_cb(uv_signal_t *handle, int signum)
-// {
-// int width, height;
-// uv_tty_t *tty = handle->data;
-// uv_tty_get_winsize(tty, &width, &height);
-// fprintf(stderr, "rows: %d, cols: %d\n", height, width);
-// }
-
static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
{
buf->len = BUF_SIZE;
@@ -88,7 +92,7 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
uv_loop_t write_loop;
uv_loop_init(&write_loop);
uv_tty_t out;
- uv_tty_init(&write_loop, &out, 1, 0);
+ uv_tty_init(&write_loop, &out, fileno(stdout), 0);
uv_write_t req;
uv_buf_t b = {.base = buf->base, .len = (size_t)cnt};
uv_write(&req, STRUCT_CAST(uv_stream_t, &out), &b, 1, NULL);
@@ -149,7 +153,11 @@ int main(int argc, char **argv)
uv_prepare_init(uv_default_loop(), &prepare);
uv_prepare_start(&prepare, prepare_cb);
// uv_tty_t tty;
+#ifndef WIN32
uv_tty_init(uv_default_loop(), &tty, fileno(stderr), 1);
+#else
+ uv_tty_init(uv_default_loop(), &tty, fileno(stdin), 1);
+#endif
uv_tty_set_mode(&tty, UV_TTY_MODE_RAW);
tty.data = &interrupted;
uv_read_start(STRUCT_CAST(uv_stream_t, &tty), alloc_cb, read_cb);
@@ -160,15 +168,17 @@ int main(int argc, char **argv)
sa.sa_handler = sig_handler;
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGWINCH, &sa, NULL);
- // uv_signal_t sigwinch_watcher;
- // uv_signal_init(uv_default_loop(), &sigwinch_watcher);
- // sigwinch_watcher.data = &tty;
- // uv_signal_start(&sigwinch_watcher, sigwinch_cb, SIGWINCH);
+#else
+ uv_signal_t sigwinch_watcher;
+ uv_signal_init(uv_default_loop(), &sigwinch_watcher);
+ uv_signal_start(&sigwinch_watcher, sigwinch_cb, SIGWINCH);
#endif
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+#ifndef WIN32
// XXX: Without this the SIGHUP handler is skipped on some systems.
sleep(100);
+#endif
return 0;
}
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 48b8512bf0..22ab0a8c21 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -6,8 +6,6 @@ local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.s
local eq, neq = helpers.eq, helpers.neq
local write_file = helpers.write_file
-if helpers.pending_win32(pending) then return end
-
describe('terminal buffer', function()
local screen
@@ -72,6 +70,7 @@ describe('terminal buffer', function()
end)
it('cannot be modified directly', function()
+ if helpers.pending_win32(pending) then return end
feed('<c-\\><c-n>dd')
screen:expect([[
tty ready |
@@ -160,6 +159,7 @@ describe('terminal buffer', function()
end)
it('handles loss of focus gracefully', function()
+ if helpers.pending_win32(pending) then return end
-- Change the statusline to avoid printing the file name, which varies.
nvim('set_option', 'statusline', '==========')
feed_command('set laststatus=0')
@@ -205,7 +205,7 @@ describe('terminal buffer', function()
end)
describe('No heap-buffer-overflow when using', function()
-
+ if helpers.pending_win32(pending) then return end
local testfilename = 'Xtestfile-functional-terminal-buffers_spec'
before_each(function()
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index 84d0322f12..d49f1bfc23 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -7,8 +7,6 @@ local feed_command = helpers.feed_command
local hide_cursor = thelpers.hide_cursor
local show_cursor = thelpers.show_cursor
-if helpers.pending_win32(pending) then return end
-
describe('terminal cursor', function()
local screen
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index be0fd9f8ff..5eb6a5f18c 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -3,10 +3,10 @@ local Screen = require('test.functional.ui.screen')
local clear, wait, nvim = helpers.clear, helpers.wait, helpers.nvim
local nvim_dir, source, eq = helpers.nvim_dir, helpers.source, helpers.eq
local feed_command, eval = helpers.feed_command, helpers.eval
-
-if helpers.pending_win32(pending) then return end
+local iswin = helpers.iswin
describe(':terminal', function()
+ if helpers.pending_win32(pending) then return end
local screen
before_each(function()
@@ -174,10 +174,15 @@ describe(':terminal (with fake shell)', function()
eq('term://', string.match(eval('bufname("%")'), "^term://"))
helpers.feed([[<C-\><C-N>]])
feed_command([[find */shadacat.py]])
- eq('scripts/shadacat.py', eval('bufname("%")'))
+ if iswin() then
+ eq('scripts\\shadacat.py', eval('bufname("%")'))
+ else
+ eq('scripts/shadacat.py', eval('bufname("%")'))
+ end
end)
it('works with gf', function()
+ if helpers.pending_win32(pending) then return end
terminal_with_fake_shell([[echo "scripts/shadacat.py"]])
wait()
screen:expect([[
diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua
index 3b04d17705..29381ab4f0 100644
--- a/test/functional/terminal/helpers.lua
+++ b/test/functional/terminal/helpers.lua
@@ -30,10 +30,14 @@ local function clear_attrs() feed_termcode('[0;10m') end
-- mouse
local function enable_mouse() feed_termcode('[?1002h') end
local function disable_mouse() feed_termcode('[?1002l') end
+local function wait_sigwinch()
+ helpers.sleep(1000)
+ hide_cursor()
+ show_cursor()
+end
local default_command = '["'..nvim_dir..'/tty-test'..'"]'
-
local function screen_setup(extra_rows, command, cols)
extra_rows = extra_rows and extra_rows or 0
command = command and command or default_command
@@ -112,5 +116,6 @@ return {
clear_attrs = clear_attrs,
enable_mouse = enable_mouse,
disable_mouse = disable_mouse,
+ wait_sigwinch = wait_sigwinch,
screen_setup = screen_setup
}
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index bb40770235..fddc0bbb71 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -5,8 +5,6 @@ local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local nvim_dir, command = helpers.nvim_dir, helpers.command
local eq, eval = helpers.eq, helpers.eval
-if helpers.pending_win32(pending) then return end
-
describe('terminal window highlighting', function()
local screen
@@ -55,6 +53,7 @@ describe('terminal window highlighting', function()
end)
local function pass_attrs()
+ if helpers.pending_win32(pending) then return end
screen:expect(sub([[
tty ready |
{NUM:text}text{10: } |
@@ -69,6 +68,7 @@ describe('terminal window highlighting', function()
it('will pass the corresponding attributes', pass_attrs)
it('will pass the corresponding attributes on scrollback', function()
+ if helpers.pending_win32(pending) then return end
pass_attrs()
local lines = {}
for i = 1, 8 do
@@ -145,6 +145,7 @@ describe('terminal window highlighting with custom palette', function()
end)
it('will use the custom color', function()
+ if helpers.pending_win32(pending) then return end
thelpers.set_fg(3)
thelpers.feed_data('text')
thelpers.clear_attrs()
diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua
index 9239c2ad31..29c62d7be7 100644
--- a/test/functional/terminal/mouse_spec.lua
+++ b/test/functional/terminal/mouse_spec.lua
@@ -4,8 +4,6 @@ local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval
local feed, nvim = helpers.feed, helpers.nvim
local feed_data = thelpers.feed_data
-if helpers.pending_win32(pending) then return end
-
describe('terminal mouse', function()
local screen
@@ -67,6 +65,7 @@ describe('terminal mouse', function()
end)
it('will forward mouse clicks to the program', function()
+ if helpers.pending_win32(pending) then return end
feed('<LeftMouse><1,2>')
screen:expect([[
line27 |
@@ -80,6 +79,7 @@ describe('terminal mouse', function()
end)
it('will forward mouse scroll to the program', function()
+ if helpers.pending_win32(pending) then return end
feed('<ScrollWheelUp><0,0>')
screen:expect([[
line27 |
@@ -94,6 +94,7 @@ describe('terminal mouse', function()
end)
describe('with a split window and other buffer', function()
+ if helpers.pending_win32(pending) then return end
before_each(function()
feed('<c-\\><c-n>:vsp<cr>')
screen:expect([[
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 05f81295c2..649bb4373b 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -3,6 +3,7 @@ local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
local feed, nvim_dir, feed_command = helpers.feed, helpers.nvim_dir, helpers.feed_command
+local iswin, wait_sigwinch = helpers.iswin, thelpers.wait_sigwinch
local eval = helpers.eval
local command = helpers.command
local wait = helpers.wait
@@ -11,8 +12,6 @@ local curbufmeths = helpers.curbufmeths
local nvim = helpers.nvim
local feed_data = thelpers.feed_data
-if helpers.pending_win32(pending) then return end
-
describe('terminal scrollback', function()
local screen
@@ -142,6 +141,9 @@ describe('terminal scrollback', function()
describe('and the height is decreased by 1', function()
local function will_hide_top_line()
screen:try_resize(screen._width, screen._height - 1)
+ if iswin() then
+ wait_sigwinch()
+ end
screen:expect([[
line2 |
line3 |
@@ -158,6 +160,9 @@ describe('terminal scrollback', function()
before_each(function()
will_hide_top_line()
screen:try_resize(screen._width, screen._height - 2)
+ if iswin() then
+ wait_sigwinch()
+ end
end)
it('will hide the top 3 lines', function()
@@ -184,9 +189,13 @@ describe('terminal scrollback', function()
describe('and the height is decreased by 2', function()
before_each(function()
screen:try_resize(screen._width, screen._height - 2)
+ if iswin() then
+ wait_sigwinch()
+ end
end)
local function will_delete_last_two_lines()
+ if helpers.pending_win32(pending) then return end
screen:expect([[
tty ready |
rows: 4, cols: 30 |
@@ -200,9 +209,13 @@ describe('terminal scrollback', function()
it('will delete the last two empty lines', will_delete_last_two_lines)
describe('and then decreased by 1', function()
+ if helpers.pending_win32(pending) then return end
before_each(function()
will_delete_last_two_lines()
screen:try_resize(screen._width, screen._height - 1)
+ if iswin() then
+ wait_sigwinch()
+ end
end)
it('will delete the last line and hide the first', function()
@@ -245,6 +258,9 @@ describe('terminal scrollback', function()
{3:-- TERMINAL --} |
]])
screen:try_resize(screen._width, screen._height - 3)
+ if iswin() then
+ wait_sigwinch()
+ end
screen:expect([[
line4 |
rows: 3, cols: 30 |
@@ -257,6 +273,9 @@ describe('terminal scrollback', function()
describe('and the height is increased by 1', function()
local function pop_then_push()
screen:try_resize(screen._width, screen._height + 1)
+ if iswin() then
+ wait_sigwinch()
+ end
screen:expect([[
line4 |
rows: 3, cols: 30 |
@@ -273,6 +292,9 @@ describe('terminal scrollback', function()
pop_then_push()
eq(8, curbuf('line_count'))
screen:try_resize(screen._width, screen._height + 3)
+ if iswin() then
+ wait_sigwinch()
+ end
end)
local function pop3_then_push1()
@@ -303,10 +325,14 @@ describe('terminal scrollback', function()
it('will pop 3 lines and then push one back', pop3_then_push1)
describe('and then by 4', function()
+ if helpers.pending_win32(pending) then return end
before_each(function()
pop3_then_push1()
feed('Gi')
screen:try_resize(screen._width, screen._height + 4)
+ if iswin() then
+ wait_sigwinch()
+ end
end)
it('will show all lines and leave a blank one at the end', function()
@@ -384,10 +410,20 @@ describe("'scrollback' option", function()
end
it('set to 0 behaves as 1', function()
- local screen = thelpers.screen_setup(nil, "['sh']", 30)
+ local screen
+ if iswin() then
+ screen = thelpers.screen_setup(nil,
+ "['powershell.exe', '-NoLogo', '-NoProfile', '-NoExit', '-Command', 'function global:prompt {return "..'"$"'.."}']", 30)
+ else
+ screen = thelpers.screen_setup(nil, "['sh']", 30)
+ end
curbufmeths.set_option('scrollback', 0)
- feed_data('for i in $(seq 1 30); do echo "line$i"; done\n')
+ if iswin() then
+ feed_data('for($i=1;$i -le 30;$i++){Write-Host \"line$i\"}\r')
+ else
+ feed_data('for i in $(seq 1 30); do echo "line$i"; done\n')
+ end
screen:expect('line30 ', nil, nil, nil, true)
retry(nil, nil, function() expect_lines(7) end)
@@ -395,7 +431,13 @@ describe("'scrollback' option", function()
end)
it('deletes lines (only) if necessary', function()
- local screen = thelpers.screen_setup(nil, "['sh']", 30)
+ local screen
+ if iswin() then
+ screen = thelpers.screen_setup(nil,
+ "['powershell.exe', '-NoLogo', '-NoProfile', '-NoExit', '-Command', 'function global:prompt {return "..'"$"'.."}']", 30)
+ else
+ screen = thelpers.screen_setup(nil, "['sh']", 30)
+ end
curbufmeths.set_option('scrollback', 200)
@@ -403,7 +445,11 @@ describe("'scrollback' option", function()
screen:expect('$', nil, nil, nil, true)
wait()
- feed_data('for i in $(seq 1 30); do echo "line$i"; done\n')
+ if iswin() then
+ feed_data('for($i=1;$i -le 30;$i++){Write-Host \"line$i\"}\r')
+ else
+ feed_data('for i in $(seq 1 30); do echo "line$i"; done\n')
+ end
screen:expect('line30 ', nil, nil, nil, true)
@@ -416,7 +462,11 @@ describe("'scrollback' option", function()
-- Terminal job data is received asynchronously, may happen before the
-- 'scrollback' option is synchronized with the internal sb_buffer.
command('sleep 100m')
- feed_data('for i in $(seq 1 40); do echo "line$i"; done\n')
+ if iswin() then
+ feed_data('for($i=1;$i -le 40;$i++){Write-Host \"line$i\"}\r')
+ else
+ feed_data('for i in $(seq 1 40); do echo "line$i"; done\n')
+ end
screen:expect('line40 ', nil, nil, nil, true)
diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua
index 888b1e1328..0f705cfe40 100644
--- a/test/functional/terminal/window_spec.lua
+++ b/test/functional/terminal/window_spec.lua
@@ -3,8 +3,6 @@ local thelpers = require('test.functional.terminal.helpers')
local feed, clear = helpers.feed, helpers.clear
local wait = helpers.wait
-if helpers.pending_win32(pending) then return end
-
describe('terminal window', function()
local screen