aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/after_success.sh6
-rw-r--r--.ci/common/test.sh10
-rw-r--r--.travis.yml3
-rw-r--r--CMakeLists.txt3
-rw-r--r--cmake/RunTests.cmake2
-rw-r--r--runtime/autoload/provider/clipboard.vim7
-rw-r--r--runtime/doc/nvim_terminal_emulator.txt22
-rw-r--r--scripts/genvimvim.lua2
-rw-r--r--src/nvim/event/process.c25
-rw-r--r--src/nvim/map.c5
-rw-r--r--src/nvim/msgpack_rpc/server.c4
-rw-r--r--src/nvim/ops.c2
-rw-r--r--src/nvim/po/ja.po2
-rw-r--r--src/nvim/terminal.c19
-rw-r--r--src/nvim/version.c2
-rw-r--r--src/nvim/window.c5
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua2
-rw-r--r--test/functional/core/job_spec.lua (renamed from test/functional/job/job_spec.lua)49
-rw-r--r--test/functional/fixtures/autoload/provider/clipboard.vim5
-rw-r--r--test/functional/ui/output_spec.lua39
20 files changed, 169 insertions, 45 deletions
diff --git a/.ci/after_success.sh b/.ci/after_success.sh
index 580b988061..0215eb139b 100755
--- a/.ci/after_success.sh
+++ b/.ci/after_success.sh
@@ -3,8 +3,6 @@
set -e
set -o pipefail
-if [[ -n "${CI_TARGET}" ]]; then
- exit
+if [[ -n "${GCOV}" ]]; then
+ coveralls --gcov "$(which "${GCOV}")" --encoding iso-8859-1 || echo 'coveralls upload failed.'
fi
-
-[ "$USE_GCOV" = on ] && { coveralls --gcov "$(which "${GCOV}")" --encoding iso-8859-1 || echo 'coveralls upload failed.' ; }
diff --git a/.ci/common/test.sh b/.ci/common/test.sh
index 225d88e072..1e66ecb239 100644
--- a/.ci/common/test.sh
+++ b/.ci/common/test.sh
@@ -83,8 +83,9 @@ install_nvim() {
exit 1
}
+ local genvimsynf=syntax/vim/generated.vim
# Check that all runtime files were installed
- for file in doc/tags syntax/vim/generated.vim $(
+ for file in doc/tags $genvimsynf $(
cd runtime ; git ls-files | grep -e '.vim$' -e '.ps$' -e '.dict$' -e '.py$' -e '.tutor$'
) ; do
if ! test -e "${INSTALL_PREFIX}/share/nvim/runtime/$file" ; then
@@ -93,6 +94,13 @@ install_nvim() {
fi
done
+ # Check that generated syntax file has function names, #5060.
+ local gpat='syn keyword vimFuncName .*eval'
+ if ! grep -q "$gpat" "${INSTALL_PREFIX}/share/nvim/runtime/$genvimsynf"; then
+ echo "It appears that $genvimsynf does not contain $gpat."
+ exit 1
+ fi
+
for file in $(
cd runtime ; git ls-files | grep -e '.awk$' -e '.sh$' -e '.bat$'
) ; do
diff --git a/.travis.yml b/.travis.yml
index 8334b03cdf..9d529c2632 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -61,6 +61,7 @@ matrix:
env: CI_TARGET=lint
- os: linux
compiler: gcc-5
+ env: GCOV=gcov-5 CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON"
- os: linux
compiler: gcc-5
env: FUNCTIONALTEST=functionaltest-lua
@@ -72,7 +73,7 @@ matrix:
env: BUILD_32BIT=ON
- os: linux
compiler: clang
- env: GCOV=llvm-cov CLANG_SANITIZER=ASAN_UBSAN CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON"
+ env: CLANG_SANITIZER=ASAN_UBSAN
- os: linux
compiler: clang
env: CLANG_SANITIZER=TSAN
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0b3e6ec85e..1787f4e306 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -501,6 +501,7 @@ if(BUSTED_PRG)
add_custom_target(functionaltest
COMMAND ${CMAKE_COMMAND}
-DBUSTED_PRG=${BUSTED_PRG}
+ -DLUA_PRG=${LUA_PRG}
-DNVIM_PRG=$<TARGET_FILE:nvim>
-DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
@@ -514,6 +515,7 @@ if(BUSTED_PRG)
add_custom_target(benchmark
COMMAND ${CMAKE_COMMAND}
-DBUSTED_PRG=${BUSTED_PRG}
+ -DLUA_PRG=${LUA_PRG}
-DNVIM_PRG=$<TARGET_FILE:nvim>
-DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
@@ -529,6 +531,7 @@ if(BUSTED_LUA_PRG)
add_custom_target(functionaltest-lua
COMMAND ${CMAKE_COMMAND}
-DBUSTED_PRG=${BUSTED_LUA_PRG}
+ -DLUA_PRG=${LUA_PRG}
-DNVIM_PRG=$<TARGET_FILE:nvim>
-DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
diff --git a/cmake/RunTests.cmake b/cmake/RunTests.cmake
index 0858ea24ac..9fa91ffb5d 100644
--- a/cmake/RunTests.cmake
+++ b/cmake/RunTests.cmake
@@ -27,7 +27,7 @@ endif()
execute_process(
COMMAND ${BUSTED_PRG} ${TEST_TAG} ${TEST_FILTER} -v -o ${BUSTED_OUTPUT_TYPE}
- --lazy --helper=${TEST_DIR}/${TEST_TYPE}/preload.lua
+ --lua=${LUA_PRG} --lazy --helper=${TEST_DIR}/${TEST_TYPE}/preload.lua
--lpath=${BUILD_DIR}/?.lua ${TEST_PATH}
WORKING_DIRECTORY ${WORKING_DIR}
ERROR_VARIABLE err
diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim
index 77bc8c781d..0f4aa78ddd 100644
--- a/runtime/autoload/provider/clipboard.vim
+++ b/runtime/autoload/provider/clipboard.vim
@@ -65,11 +65,10 @@ endif
let s:clipboard = {}
function! s:clipboard.get(reg)
- let reg = a:reg == '"' ? '+' : a:reg
- if s:selections[reg].owner > 0
- return s:selections[reg].data
+ if s:selections[a:reg].owner > 0
+ return s:selections[a:reg].data
end
- return s:try_cmd(s:paste[reg])
+ return s:try_cmd(s:paste[a:reg])
endfunction
function! s:clipboard.set(lines, regtype, reg)
diff --git a/runtime/doc/nvim_terminal_emulator.txt b/runtime/doc/nvim_terminal_emulator.txt
index 4296ef6490..8f7dc0dbf0 100644
--- a/runtime/doc/nvim_terminal_emulator.txt
+++ b/runtime/doc/nvim_terminal_emulator.txt
@@ -10,6 +10,7 @@ Embedded terminal emulator *terminal-emulator*
2. Spawning |terminal-emulator-spawning|
3. Input |terminal-emulator-input|
4. Configuration |terminal-emulator-configuration|
+5. Status Variables |terminal-emulator-status|
==============================================================================
1. Introduction *terminal-emulator-intro*
@@ -113,4 +114,25 @@ The terminal cursor can be highlighted via |hl-TermCursor| and
|hl-TermCursorNC|.
==============================================================================
+5. Status Variables *terminal-emulator-status*
+
+Terminal buffers maintain some information about the terminal in buffer-local
+variables:
+
+- *b:term_title* The settable title of the terminal, typically displayed in
+ the window title or tab title of a graphical terminal emulator. Programs
+ running in the terminal can set this title via an escape sequence.
+- *b:terminal_job_id* The nvim job ID of the job running in the terminal. See
+ |job-control| for more information.
+- *b:terminal_job_pid* The PID of the top-level process running in the
+ terminal.
+
+These variables will have a value by the time the TermOpen autocmd runs, and
+will continue to have a value for the lifetime of the terminal buffer, making
+them suitable for use in 'statusline'. For example, to show the terminal title
+as the status line:
+>
+ :autocmd TermOpen * setlocal statusline=%{b:term_title}
+<
+==============================================================================
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/scripts/genvimvim.lua b/scripts/genvimvim.lua
index 9135c8e3ab..2a82181841 100644
--- a/scripts/genvimvim.lua
+++ b/scripts/genvimvim.lua
@@ -123,7 +123,7 @@ for line in eval_fd:lines() do
if line == '};' then
break
end
- local func_name = line:match('^ {"(%w+)",')
+ local func_name = line:match('^ { "([%w_]+)",')
if func_name then
if lld.line_length > 850 then
w('\n' .. vimfun_start)
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 1c4c9737c3..317e40e43a 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -116,23 +116,20 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
process_is_tearing_down = true;
kl_iter(WatcherPtr, loop->children, current) {
Process *proc = (*current)->data;
- if (proc->detach) {
+ if (proc->detach || proc->type == kProcessTypePty) {
// Close handles to process without killing it.
CREATE_EVENT(loop->events, process_close_handles, 1, proc);
} else {
- if (proc->type == kProcessTypeUv) {
- uv_kill(proc->pid, SIGTERM);
- proc->term_sent = true;
- process_stop(proc);
- } else { // kProcessTypePty
- process_close_streams(proc);
- pty_process_close_master((PtyProcess *)proc);
- }
+ uv_kill(proc->pid, SIGTERM);
+ proc->term_sent = true;
+ process_stop(proc);
}
}
- // Wait until all children exit
- LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1, kl_empty(loop->children));
+ // Wait until all children exit and all close events are processed.
+ LOOP_PROCESS_EVENTS_UNTIL(
+ loop, loop->events, -1,
+ kl_empty(loop->children) && queue_empty(loop->events));
pty_process_teardown(loop);
}
@@ -315,8 +312,10 @@ static void decref(Process *proc)
static void process_close(Process *proc)
FUNC_ATTR_NONNULL_ARG(1)
{
- if (process_is_tearing_down && proc->detach && proc->closed) {
- // If a detached process dies while tearing down it might get closed twice.
+ if (process_is_tearing_down && (proc->detach || proc->type == kProcessTypePty)
+ && proc->closed) {
+ // If a detached/pty process dies while tearing down it might get closed
+ // twice.
return;
}
assert(!proc->closed);
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 03439e7a9c..398e74268f 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -129,7 +129,10 @@ static inline khint_t String_hash(String s)
static inline bool String_eq(String a, String b)
{
- return strncmp(a.data, b.data, MIN(a.size, b.size)) == 0;
+ if (a.size != b.size) {
+ return false;
+ }
+ return memcmp(a.data, b.data, a.size) == 0;
}
diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c
index abbd3e8aff..d7c2926a0f 100644
--- a/src/nvim/msgpack_rpc/server.c
+++ b/src/nvim/msgpack_rpc/server.c
@@ -40,6 +40,10 @@ bool server_init(void)
listen_address = server_address_new();
}
+ if (!listen_address) {
+ return false;
+ }
+
bool ok = (server_start(listen_address) == 0);
if (must_free) {
xfree((char *) listen_address);
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index a498fc481a..25b3b85497 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -5452,7 +5452,7 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
yankreg_T *target;
if (cb_flags & CB_UNNAMEDPLUS) {
- *name = cb_flags & CB_UNNAMED ? '"': '+';
+ *name = (cb_flags & CB_UNNAMED && writing) ? '"': '+';
target = &y_regs[PLUS_REGISTER];
} else {
*name = '*';
diff --git a/src/nvim/po/ja.po b/src/nvim/po/ja.po
index 8a3fcb8f78..0326f33bb5 100644
--- a/src/nvim/po/ja.po
+++ b/src/nvim/po/ja.po
@@ -5653,7 +5653,7 @@ msgstr "単語 '%.*s' が %s から削除されました"
#: ../spell.c:8117
#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "%s に単語が追加されました"
+msgstr "単語 '%.*s' が %s へ追加されました"
#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index fd416b3dcc..6f50c03be9 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -241,6 +241,7 @@ Terminal *terminal_open(TerminalOptions opts)
set_option_value((uint8_t *)"wrap", false, NULL, OPT_LOCAL);
set_option_value((uint8_t *)"number", false, NULL, OPT_LOCAL);
set_option_value((uint8_t *)"relativenumber", false, NULL, OPT_LOCAL);
+ buf_set_term_title(curbuf, (char *)curbuf->b_ffname);
RESET_BINDING(curwin);
// Apply TermOpen autocmds so the user can configure the terminal
apply_autocmds(EVENT_TERMOPEN, NULL, NULL, false, curbuf);
@@ -618,6 +619,17 @@ static int term_movecursor(VTermPos new, VTermPos old, int visible,
return 1;
}
+static void buf_set_term_title(buf_T *buf, char *title)
+ FUNC_ATTR_NONNULL_ALL
+{
+ Error err;
+ api_free_object(dict_set_value(buf->b_vars,
+ cstr_as_string("term_title"),
+ STRING_OBJ(cstr_as_string(title)),
+ false,
+ &err));
+}
+
static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
{
Terminal *term = data;
@@ -633,12 +645,7 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
case VTERM_PROP_TITLE: {
buf_T *buf = handle_get_buffer(term->buf_handle);
- Error err;
- api_free_object(dict_set_value(buf->b_vars,
- cstr_as_string("term_title"),
- STRING_OBJ(cstr_as_string(val->string)),
- false,
- &err));
+ buf_set_term_title(buf, val->string);
break;
}
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 5fdbb7db57..70c6af2a12 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -513,7 +513,7 @@ static int included_patches[] = {
// 1189 NA
// 1188 NA
// 1187 NA
- // 1186,
+ // 1186 NA
// 1185 NA
// 1184 NA
// 1183 NA
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 1298248f1e..e267d493bf 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3296,8 +3296,11 @@ void tabpage_move(int nr)
tabpage_T *tp;
tabpage_T *tp_dst;
- if (first_tabpage->tp_next == NULL)
+ assert(curtab != NULL);
+
+ if (first_tabpage->tp_next == NULL) {
return;
+ }
for (tp = first_tabpage; tp->tp_next != NULL && n < nr; tp = tp->tp_next) {
++n;
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index b4febe4bfb..15977b9777 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -308,6 +308,7 @@ describe('clipboard usage', function()
end)
it('links the "+ and unnamed registers', function()
+ eq('+', eval('v:register'))
insert("one two")
feed('^"+dwdw"+P')
expect('two')
@@ -335,6 +336,7 @@ describe('clipboard usage', function()
eq({{'really unnamed', ''}, 'V'}, eval("g:test_clip['*']"))
-- unnamedplus takes predecence when pasting
+ eq('+', eval('v:register'))
execute("let g:test_clip['+'] = ['the plus','']")
execute("let g:test_clip['*'] = ['the star','']")
feed("p")
diff --git a/test/functional/job/job_spec.lua b/test/functional/core/job_spec.lua
index b54d5166ac..61ecdd1835 100644
--- a/test/functional/job/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -1,4 +1,3 @@
-
local helpers = require('test.functional.helpers')(after_each)
local clear, eq, eval, execute, feed, insert, neq, next_msg, nvim,
nvim_dir, ok, source, write_file, mkdir, rmdir = helpers.clear,
@@ -120,7 +119,7 @@ describe('jobs', function()
{0, {'a', '', 'c', '', '', '', 'b', '', ''}}}, next_msg())
end)
- it('can preserve nuls', function()
+ it('can preserve NULs', function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
nvim('command', 'call jobsend(j, ["\n123\n", "abc\\nxyz\n", ""])')
eq({'notification', 'stdout', {0, {'\n123\n', 'abc\nxyz\n', ''}}},
@@ -144,7 +143,7 @@ describe('jobs', function()
eq({'notification', 'exit', {0, 0}}, next_msg())
end)
- it("won't allow jobsend with a job that closed stdin", function()
+ it("disallows jobsend on a job that closed stdin", function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
nvim('command', 'call jobclose(j, "stdin")')
eq(false, pcall(function()
@@ -152,12 +151,12 @@ describe('jobs', function()
end))
end)
- it('will not allow jobsend/stop on a non-existent job', function()
+ it('disallows jobsend/stop on a non-existent job', function()
eq(false, pcall(eval, "jobsend(-1, 'lol')"))
eq(false, pcall(eval, "jobstop(-1)"))
end)
- it('will not allow jobstop twice on the same job', function()
+ it('disallows jobstop twice on the same job', function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
neq(0, eval('j'))
eq(true, pcall(eval, "jobstop(j)"))
@@ -244,7 +243,7 @@ describe('jobs', function()
eq({'notification', 'exit', {45, 10}}, next_msg())
end)
- it('cant redefine callbacks being used by a job', function()
+ it('cannot redefine callbacks being used by a job', function()
local screen = Screen.new()
screen:attach()
local script = [[
@@ -467,3 +466,41 @@ describe('jobs', function()
end)
end)
end)
+
+describe("pty process teardown", function()
+ local screen
+ before_each(function()
+ clear()
+ screen = Screen.new(30, 6)
+ screen:attach()
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ end)
+ after_each(function()
+ screen:detach()
+ end)
+
+ it("does not prevent/delay exit. #4798 #4900", function()
+ -- Use a nested nvim (in :term) to test without --headless.
+ execute(":terminal '"..helpers.nvim_prog
+ -- Use :term again in the _nested_ nvim to get a PTY process.
+ -- Use `sleep` to simulate a long-running child of the PTY.
+ .."' +terminal +'!(sleep 300 &)' +qa")
+
+ -- Exiting should terminate all descendants (PTY, its children, ...).
+ screen:expect([[
+ |
+ [Process exited 0] |
+ |
+ |
+ |
+ -- TERMINAL -- |
+ ]])
+ end)
+end)
diff --git a/test/functional/fixtures/autoload/provider/clipboard.vim b/test/functional/fixtures/autoload/provider/clipboard.vim
index 0935ea45ff..411e095c71 100644
--- a/test/functional/fixtures/autoload/provider/clipboard.vim
+++ b/test/functional/fixtures/autoload/provider/clipboard.vim
@@ -9,13 +9,12 @@ function! s:methods.get(reg)
if g:cliperror
return 0
end
- let reg = a:reg == '"' ? '+' : a:reg
if g:cliplossy
" behave like pure text clipboard
- return g:test_clip[reg][0]
+ return g:test_clip[a:reg][0]
else
" behave like VIMENC clipboard
- return g:test_clip[reg]
+ return g:test_clip[a:reg]
end
endfunction
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
new file mode 100644
index 0000000000..c7c8986527
--- /dev/null
+++ b/test/functional/ui/output_spec.lua
@@ -0,0 +1,39 @@
+local session = require('test.functional.helpers')(after_each)
+local child_session = require('test.functional.terminal.helpers')
+
+describe("shell command :!", function()
+ local screen
+ before_each(function()
+ session.clear()
+ screen = child_session.screen_setup(0, '["'..session.nvim_prog..
+ '", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile"]')
+ screen:expect([[
+ {1: } |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ |
+ -- TERMINAL -- |
+ ]])
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ it("displays output even without LF/EOF. #4646 #4569 #3772", function()
+ -- NOTE: We use a child nvim (within a :term buffer)
+ -- to avoid triggering a UI flush.
+ child_session.feed_data(":!printf foo; sleep 200\n")
+ screen:expect([[
+ ~ |
+ ~ |
+ [No Name] |
+ :!printf foo; sleep 200 |
+ |
+ foo |
+ -- TERMINAL -- |
+ ]])
+ end)
+end)