aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml12
-rw-r--r--ci/common/suite.sh40
-rw-r--r--ci/common/test.sh29
-rwxr-xr-xci/run_lint.sh39
-rwxr-xr-xci/run_tests.sh42
-rw-r--r--src/nvim/api/autocmd.c122
-rw-r--r--src/nvim/api/buffer.c7
-rw-r--r--src/nvim/api/extmark.c1
-rw-r--r--src/nvim/api/vim.c19
-rw-r--r--src/nvim/autocmd.c3
-rw-r--r--src/nvim/decoration.c53
-rw-r--r--src/nvim/decoration.h27
-rw-r--r--src/nvim/decoration_provider.c231
-rw-r--r--src/nvim/decoration_provider.h26
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/eval/funcs.c2
-rw-r--r--src/nvim/eval/typval.c8
-rw-r--r--src/nvim/event/rstream.c2
-rw-r--r--src/nvim/ex_docmd.h2
-rw-r--r--src/nvim/extmark.c2
-rw-r--r--src/nvim/extmark.h2
-rw-r--r--src/nvim/fileio.c2
-rw-r--r--src/nvim/highlight.c8
-rw-r--r--src/nvim/input.c2
-rw-r--r--src/nvim/lua/executor.c47
-rw-r--r--src/nvim/lua/executor.h8
-rw-r--r--src/nvim/lua/spell.c8
-rw-r--r--src/nvim/lua/stdlib.c4
-rw-r--r--src/nvim/main.c1
-rw-r--r--src/nvim/mark.c2
-rw-r--r--src/nvim/marktree.c4
-rw-r--r--src/nvim/marktree.h4
-rw-r--r--src/nvim/memory.c2
-rw-r--r--src/nvim/normal.c1
-rw-r--r--src/nvim/option.c6
-rw-r--r--src/nvim/os/os_defs.h2
-rw-r--r--src/nvim/os/pty_process_unix.c21
-rw-r--r--src/nvim/os/shell.c4
-rw-r--r--src/nvim/popupmnu.c7
-rw-r--r--src/nvim/quickfix.c5
-rw-r--r--src/nvim/screen.c154
-rw-r--r--src/nvim/search.c6
-rw-r--r--src/nvim/tui/tui.c4
-rw-r--r--src/nvim/vim.h4
-rw-r--r--third-party/CMakeLists.txt4
45 files changed, 495 insertions, 486 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 41a22af538..ea3185d2a1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -80,11 +80,11 @@ jobs:
run: ./ci/before_script.sh
- name: Build nvim
- run: ./ci/run_tests.sh build
+ run: ./ci/run_tests.sh build_nvim
- if: "!cancelled()"
- name: clint
- run: ./ci/run_lint.sh clint
+ name: clint-full
+ run: ./ci/run_lint.sh clint-full
- if: "!cancelled()"
name: lualint
@@ -99,8 +99,8 @@ jobs:
run: ./ci/run_lint.sh shlint
- if: "!cancelled()"
- name: single-includes
- run: ./ci/run_lint.sh single-includes
+ name: check-single-includes
+ run: ./ci/run_lint.sh check-single-includes
- name: Cache dependencies
run: ./ci/before_cache.sh
@@ -201,7 +201,7 @@ jobs:
run: ./ci/before_script.sh
- name: Build
- run: ./ci/run_tests.sh build
+ run: ./ci/run_tests.sh build_nvim
- if: matrix.flavor != 'tsan' && matrix.flavor != 'functionaltest-lua' && !cancelled()
name: Unittests
diff --git a/ci/common/suite.sh b/ci/common/suite.sh
index 5110e22ec2..c0c470dce1 100644
--- a/ci/common/suite.sh
+++ b/ci/common/suite.sh
@@ -1,9 +1,3 @@
-# HACK: get newline for use in strings given that "\n" and $'' do not work.
-NL="$(printf '\nE')"
-NL="${NL%E}"
-
-FAIL_SUMMARY=""
-
# Test success marker. If END_MARKER file exists, we know that all tests
# finished. If FAIL_SUMMARY_FILE exists we know that some tests failed, this
# file will contain information about failed tests. Build is considered
@@ -11,35 +5,15 @@ FAIL_SUMMARY=""
END_MARKER="$BUILD_DIR/.tests_finished"
FAIL_SUMMARY_FILE="$BUILD_DIR/.test_errors"
-enter_suite() {
- FAILED=0
- rm -f "${END_MARKER}"
- local suite_name="$1"
- export NVIM_TEST_CURRENT_SUITE="${NVIM_TEST_CURRENT_SUITE}/$suite_name"
-}
-
-exit_suite() {
- if test $FAILED -ne 0 ; then
- echo "Suite ${NVIM_TEST_CURRENT_SUITE} failed, summary:"
- echo "${FAIL_SUMMARY}"
- fi
- export NVIM_TEST_CURRENT_SUITE="${NVIM_TEST_CURRENT_SUITE%/*}"
- FAILED=0
-}
-
fail() {
local test_name="$1"
- local fail_char="$2"
- local message="$3"
+ local message="$2"
- : ${fail_char:=F}
: ${message:=Test $test_name failed}
- local full_msg="$fail_char $NVIM_TEST_CURRENT_SUITE|$test_name :: $message"
- FAIL_SUMMARY="${FAIL_SUMMARY}${NL}${full_msg}"
+ local full_msg="$test_name :: $message"
echo "${full_msg}" >> "${FAIL_SUMMARY_FILE}"
echo "Failed: $full_msg"
- FAILED=1
}
ended_successfully() {
@@ -64,13 +38,3 @@ end_tests() {
touch "${END_MARKER}"
ended_successfully
}
-
-run_suite() {
- local command="$1"
- local suite_name="$2"
-
- enter_suite "$suite_name"
- eval "$command" || fail "$suite_name"
- exit_suite
-}
-
diff --git a/ci/common/test.sh b/ci/common/test.sh
index f211a2e7aa..7db39a0e5f 100644
--- a/ci/common/test.sh
+++ b/ci/common/test.sh
@@ -51,7 +51,7 @@ check_core_dumps() {
fi
done
if test "$app" != quiet ; then
- fail 'cores' E 'Core dumps found'
+ fail 'cores' 'Core dumps found'
fi
}
@@ -72,7 +72,7 @@ check_logs() {
rm "${log}"
done
if test -n "${err}" ; then
- fail 'logs' E 'Runtime errors detected.'
+ fail 'logs' 'Runtime errors detected.'
fi
}
@@ -86,19 +86,19 @@ check_sanitizer() {
fi
}
-run_unittests() {(
+unittests() {(
ulimit -c unlimited || true
if ! build_make unittest ; then
- fail 'unittests' F 'Unit tests failed'
+ fail 'unittests' 'Unit tests failed'
fi
submit_coverage unittest
check_core_dumps "$(command -v luajit)"
)}
-run_functionaltests() {(
+functionaltests() {(
ulimit -c unlimited || true
if ! build_make ${FUNCTIONALTEST}; then
- fail 'functionaltests' F 'Functional tests failed'
+ fail 'functionaltests' 'Functional tests failed'
fi
submit_coverage functionaltest
check_sanitizer "${LOG_DIR}"
@@ -106,11 +106,11 @@ run_functionaltests() {(
check_core_dumps
)}
-run_oldtests() {(
+oldtests() {(
ulimit -c unlimited || true
if ! make oldtest; then
reset
- fail 'oldtests' F 'Legacy tests failed'
+ fail 'oldtests' 'Legacy tests failed'
fi
submit_coverage oldtest
check_sanitizer "${LOG_DIR}"
@@ -129,26 +129,25 @@ check_runtime_files() {(
# Prefer failing the build over using more robust construct because files
# with IFS are not welcome.
if ! test -e "$file" ; then
- fail "$test_name" E \
- "It appears that $file is only a part of the file name"
+ fail "$test_name" "It appears that $file is only a part of the file name"
fi
if ! test "$tst" "$INSTALL_PREFIX/share/nvim/runtime/$file" ; then
- fail "$test_name" F "$(printf "$message" "$file")"
+ fail "$test_name" "$(printf "$message" "$file")"
fi
done
)}
install_nvim() {(
if ! build_make install ; then
- fail 'install' E 'make install failed'
- exit_suite
+ fail 'install' 'make install failed'
+ exit 1
fi
"${INSTALL_PREFIX}/bin/nvim" --version
if ! "${INSTALL_PREFIX}/bin/nvim" -u NONE -e -c ':help' -c ':qall' ; then
echo "Running ':help' in the installed nvim failed."
echo "Maybe the helptags have not been generated properly."
- fail 'help' F 'Failed running :help'
+ fail 'help' 'Failed running :help'
fi
# Check that all runtime files were installed
@@ -169,6 +168,6 @@ install_nvim() {(
local genvimsynf=syntax/vim/generated.vim
local gpat='syn keyword vimFuncName .*eval'
if ! grep -q "$gpat" "${INSTALL_PREFIX}/share/nvim/runtime/$genvimsynf" ; then
- fail 'funcnames' F "It appears that $genvimsynf does not contain $gpat."
+ fail 'funcnames' "It appears that $genvimsynf does not contain $gpat."
fi
)}
diff --git a/ci/run_lint.sh b/ci/run_lint.sh
index 2fea7a40c0..3a524b4ed6 100755
--- a/ci/run_lint.sh
+++ b/ci/run_lint.sh
@@ -8,34 +8,17 @@ CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CI_DIR}/common/build.sh"
source "${CI_DIR}/common/suite.sh"
-if [[ "$GITHUB_ACTIONS" != "true" ]]; then
- run_suite 'make clint-full' 'clint'
- run_suite 'make lualint' 'lualint'
- run_suite 'make pylint' 'pylint'
- run_suite 'make shlint' 'shlint'
- run_suite 'make check-single-includes' 'single-includes'
+rm -f "$END_MARKER"
- end_tests
+# Run all tests if no input argument is given
+if (($# == 0)); then
+ tests=('clint-full' 'lualint' 'pylint' 'shlint' 'check-single-includes')
else
- case "$1" in
- clint)
- run_suite 'make clint-full' 'clint'
- ;;
- lualint)
- run_suite 'make lualint' 'lualint'
- ;;
- pylint)
- run_suite 'make pylint' 'pylint'
- ;;
- shlint)
- run_suite 'make shlint' 'shlint'
- ;;
- single-includes)
- run_suite 'make check-single-includes' 'single-includes'
- ;;
- *)
- :;;
- esac
-
- end_tests
+ tests=("$@")
fi
+
+for i in "${tests[@]}"; do
+ make "$i" || fail "$i"
+done
+
+end_tests
diff --git a/ci/run_tests.sh b/ci/run_tests.sh
index ae85246ab6..23460b682e 100755
--- a/ci/run_tests.sh
+++ b/ci/run_tests.sh
@@ -8,42 +8,28 @@ source "${CI_DIR}/common/build.sh"
source "${CI_DIR}/common/test.sh"
source "${CI_DIR}/common/suite.sh"
+rm -f "$END_MARKER"
-if [[ "$GITHUB_ACTIONS" != "true" ]]; then
- run_suite 'build_nvim' 'build'
+# Run all tests (with some caveats) if no input argument is given
+if (($# == 0)); then
+ tests=('build_nvim')
if test "$CLANG_SANITIZER" != "TSAN"; then
# Additional threads are only created when the builtin UI starts, which
# doesn't happen in the unit/functional tests
if test "${FUNCTIONALTEST}" != "functionaltest-lua"; then
- run_suite run_unittests unittests
+ tests+=('unittests')
fi
- run_suite run_functionaltests functionaltests
+ tests+=('functionaltests')
fi
- run_suite run_oldtests oldtests
- run_suite install_nvim install_nvim
- end_tests
+ tests+=('oldtests' 'install_nvim')
else
- case "$1" in
- build)
- run_suite 'build_nvim' 'build'
- ;;
- unittests)
- run_suite 'run_unittests' 'unittests'
- ;;
- functionaltests)
- run_suite 'run_functionaltests' 'functionaltests'
- ;;
- oldtests)
- run_suite 'run_oldtests' 'oldtests'
- ;;
- install_nvim)
- run_suite 'install_nvim' 'install_nvim'
- ;;
- *)
- :;;
- esac
-
- end_tests
+ tests=("$@")
fi
+
+for i in "${tests[@]}"; do
+ eval "$i" || fail "$i"
+done
+
+end_tests
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c
index 5ede0e5265..8a7dd00b2a 100644
--- a/src/nvim/api/autocmd.c
+++ b/src/nvim/api/autocmd.c
@@ -63,26 +63,26 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err)
int group = 0;
switch (opts->group.type) {
- case kObjectTypeNil:
- break;
- case kObjectTypeString:
- group = augroup_find(opts->group.data.string.data);
- if (group < 0) {
- api_set_error(err, kErrorTypeValidation, "invalid augroup passed.");
- goto cleanup;
- }
- break;
- case kObjectTypeInteger:
- group = (int)opts->group.data.integer;
- char *name = augroup_name(group);
- if (!augroup_exists(name)) {
- api_set_error(err, kErrorTypeValidation, "invalid augroup passed.");
- goto cleanup;
- }
- break;
- default:
- api_set_error(err, kErrorTypeValidation, "group must be a string or an integer.");
+ case kObjectTypeNil:
+ break;
+ case kObjectTypeString:
+ group = augroup_find(opts->group.data.string.data);
+ if (group < 0) {
+ api_set_error(err, kErrorTypeValidation, "invalid augroup passed.");
goto cleanup;
+ }
+ break;
+ case kObjectTypeInteger:
+ group = (int)opts->group.data.integer;
+ char *name = augroup_name(group);
+ if (!augroup_exists(name)) {
+ api_set_error(err, kErrorTypeValidation, "invalid augroup passed.");
+ goto cleanup;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation, "group must be a string or an integer.");
+ goto cleanup;
}
if (opts->event.type != kObjectTypeNil) {
@@ -415,28 +415,28 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
bool is_nested = api_object_to_bool(opts->nested, "nested", false, err);
switch (opts->group.type) {
- case kObjectTypeNil:
- break;
- case kObjectTypeString:
- au_group = augroup_find(opts->group.data.string.data);
- if (au_group == AUGROUP_ERROR) {
- api_set_error(err,
- kErrorTypeValidation,
- "invalid augroup: %s", opts->group.data.string.data);
- goto cleanup;
- }
- break;
- case kObjectTypeInteger:
- au_group = (int)opts->group.data.integer;
- char *name = augroup_name(au_group);
- if (!augroup_exists(name)) {
- api_set_error(err, kErrorTypeValidation, "invalid augroup: %d", au_group);
- goto cleanup;
- }
- break;
- default:
- api_set_error(err, kErrorTypeValidation, "'group' must be a string or an integer.");
+ case kObjectTypeNil:
+ break;
+ case kObjectTypeString:
+ au_group = augroup_find(opts->group.data.string.data);
+ if (au_group == AUGROUP_ERROR) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "invalid augroup: %s", opts->group.data.string.data);
goto cleanup;
+ }
+ break;
+ case kObjectTypeInteger:
+ au_group = (int)opts->group.data.integer;
+ char *name = augroup_name(au_group);
+ if (!augroup_exists(name)) {
+ api_set_error(err, kErrorTypeValidation, "invalid augroup: %d", au_group);
+ goto cleanup;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation, "'group' must be a string or an integer.");
+ goto cleanup;
}
if (opts->pattern.type != kObjectTypeNil && opts->buffer.type != kObjectTypeNil) {
@@ -659,28 +659,28 @@ void nvim_do_autocmd(Object event, Dict(do_autocmd) *opts, Error *err)
}
switch (opts->group.type) {
- case kObjectTypeNil:
- break;
- case kObjectTypeString:
- au_group = augroup_find(opts->group.data.string.data);
- if (au_group == AUGROUP_ERROR) {
- api_set_error(err,
- kErrorTypeValidation,
- "invalid augroup: %s", opts->group.data.string.data);
- goto cleanup;
- }
- break;
- case kObjectTypeInteger:
- au_group = (int)opts->group.data.integer;
- char *name = augroup_name(au_group);
- if (!augroup_exists(name)) {
- api_set_error(err, kErrorTypeValidation, "invalid augroup: %d", au_group);
- goto cleanup;
- }
- break;
- default:
- api_set_error(err, kErrorTypeValidation, "'group' must be a string or an integer.");
+ case kObjectTypeNil:
+ break;
+ case kObjectTypeString:
+ au_group = augroup_find(opts->group.data.string.data);
+ if (au_group == AUGROUP_ERROR) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "invalid augroup: %s", opts->group.data.string.data);
goto cleanup;
+ }
+ break;
+ case kObjectTypeInteger:
+ au_group = (int)opts->group.data.integer;
+ char *name = augroup_name(au_group);
+ if (!augroup_exists(name)) {
+ api_set_error(err, kErrorTypeValidation, "invalid augroup: %d", au_group);
+ goto cleanup;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation, "'group' must be a string or an integer.");
+ goto cleanup;
}
if (opts->buffer.type != kObjectTypeNil) {
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 3bddbe8fe6..a3af51008f 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -965,8 +965,7 @@ void nvim_buf_set_keymap(uint64_t channel_id, Buffer buffer, String mode, String
/// @see |nvim_del_keymap()|
///
/// @param buffer Buffer handle, or 0 for current buffer
-void nvim_buf_del_keymap(uint64_t channel_id, Buffer buffer, String mode,
- String lhs, Error *err)
+void nvim_buf_del_keymap(uint64_t channel_id, Buffer buffer, String mode, String lhs, Error *err)
FUNC_API_SINCE(6)
{
String rhs = { .data = "", .size = 0 };
@@ -1380,8 +1379,8 @@ Object nvim_buf_call(Buffer buffer, LuaRef fun, Error *err)
/// @param buffer Buffer handle, or 0 for current buffer.
/// @param[out] err Error details, if any.
/// @see nvim_add_user_command
-void nvim_buf_add_user_command(Buffer buffer, String name, Object command,
- Dict(user_command) *opts, Error *err)
+void nvim_buf_add_user_command(Buffer buffer, String name, Object command, Dict(user_command) *opts,
+ Error *err)
FUNC_API_SINCE(9)
{
buf_T *target_buf = find_buffer_by_handle(buffer, err);
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index 0ee8134ec4..e355f82f4d 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -8,6 +8,7 @@
#include "nvim/api/extmark.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/decoration_provider.h"
#include "nvim/extmark.h"
#include "nvim/lua/executor.h"
#include "nvim/memline.h"
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 1a324bfaa5..ebf4f65c91 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -22,6 +22,7 @@
#include "nvim/charset.h"
#include "nvim/context.h"
#include "nvim/decoration.h"
+#include "nvim/decoration_provider.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
@@ -722,15 +723,15 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
break;
case 2:
switch (numval) {
- case 0:
- case 1:
- rv = BOOLEAN_OBJ(numval);
- break;
- default:
- // Boolean options that return something other than 0 or 1 should return nil. Currently this
- // only applies to 'autoread' which uses -1 as a local value to indicate "unset"
- rv = NIL;
- break;
+ case 0:
+ case 1:
+ rv = BOOLEAN_OBJ(numval);
+ break;
+ default:
+ // Boolean options that return something other than 0 or 1 should return nil. Currently this
+ // only applies to 'autoread' which uses -1 as a local value to indicate "unset"
+ rv = NIL;
+ break;
}
break;
default:
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index a850e5c1a0..dfcdfd8203 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -2428,9 +2428,8 @@ char *aucmd_exec_default_desc(AucmdExecutable acc)
default:
return NULL;
}
-
- abort();
}
+
char *aucmd_exec_to_string(AutoCmd *ac, AucmdExecutable acc)
{
switch (acc.type) {
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index b533f4c46f..94bf1feeee 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -523,59 +523,6 @@ void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col,
}
-DecorProvider *get_decor_provider(NS ns_id, bool force)
-{
- size_t i;
- size_t len = kv_size(decor_providers);
- for (i = 0; i < len; i++) {
- DecorProvider *item = &kv_A(decor_providers, i);
- if (item->ns_id == ns_id) {
- return item;
- } else if (item->ns_id > ns_id) {
- break;
- }
- }
-
- if (!force) {
- return NULL;
- }
-
- // Adding a new provider, so allocate room in the vector
- (void)kv_a(decor_providers, len);
- if (i < len) {
- // New ns_id needs to be inserted between existing providers to maintain
- // ordering, so shift other providers with larger ns_id
- memmove(&kv_A(decor_providers, i + 1),
- &kv_A(decor_providers, i),
- (len - i) * sizeof(kv_a(decor_providers, i)));
- }
- DecorProvider *item = &kv_a(decor_providers, i);
- *item = DECORATION_PROVIDER_INIT(ns_id);
-
- return item;
-}
-
-void decor_provider_clear(DecorProvider *p)
-{
- if (p == NULL) {
- return;
- }
- NLUA_CLEAR_REF(p->redraw_start);
- NLUA_CLEAR_REF(p->redraw_buf);
- NLUA_CLEAR_REF(p->redraw_win);
- NLUA_CLEAR_REF(p->redraw_line);
- NLUA_CLEAR_REF(p->redraw_end);
- p->active = false;
-}
-
-void decor_free_all_mem(void)
-{
- for (size_t i = 0; i < kv_size(decor_providers); i++) {
- decor_provider_clear(&kv_A(decor_providers, i));
- }
- kv_destroy(decor_providers);
-}
-
int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines)
{
diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h
index 2277a0ef1c..8df53caa0a 100644
--- a/src/nvim/decoration.h
+++ b/src/nvim/decoration.h
@@ -82,34 +82,15 @@ typedef struct {
int eol_col;
} DecorState;
-typedef struct {
- NS ns_id;
- bool active;
- LuaRef redraw_start;
- LuaRef redraw_buf;
- LuaRef redraw_win;
- LuaRef redraw_line;
- LuaRef redraw_end;
- LuaRef hl_def;
- int hl_valid;
-} DecorProvider;
-
-EXTERN kvec_t(DecorProvider) decor_providers INIT(= KV_INITIAL_VALUE);
EXTERN DecorState decor_state INIT(= { 0 });
-EXTERN bool provider_active INIT(= false);
-
-#define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \
- { ns_id, false, LUA_NOREF, LUA_NOREF, \
- LUA_NOREF, LUA_NOREF, LUA_NOREF, \
- LUA_NOREF, -1 }
static inline bool decor_has_sign(Decoration *decor)
{
return decor->sign_text
- || decor->sign_hl_id
- || decor->number_hl_id
- || decor->line_hl_id
- || decor->cursorline_hl_id;
+ || decor->sign_hl_id
+ || decor->number_hl_id
+ || decor->line_hl_id
+ || decor->cursorline_hl_id;
}
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/decoration_provider.c b/src/nvim/decoration_provider.c
new file mode 100644
index 0000000000..6efcb08b9d
--- /dev/null
+++ b/src/nvim/decoration_provider.c
@@ -0,0 +1,231 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/api/extmark.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/buffer.h"
+#include "nvim/decoration.h"
+#include "nvim/decoration_provider.h"
+#include "nvim/highlight.h"
+#include "nvim/lua/executor.h"
+
+static kvec_t(DecorProvider) decor_providers = KV_INITIAL_VALUE;
+
+#define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \
+ { ns_id, false, LUA_NOREF, LUA_NOREF, \
+ LUA_NOREF, LUA_NOREF, LUA_NOREF, \
+ LUA_NOREF, -1 }
+
+static bool decor_provider_invoke(NS ns_id, const char *name, LuaRef ref,
+ Array args, bool default_true, char **perr)
+{
+ Error err = ERROR_INIT;
+
+ textlock++;
+ provider_active = true;
+ Object ret = nlua_call_ref(ref, name, args, true, &err);
+ provider_active = false;
+ textlock--;
+
+ if (!ERROR_SET(&err)
+ && api_object_to_bool(ret, "provider %s retval", default_true, &err)) {
+ return true;
+ }
+
+ if (ERROR_SET(&err)) {
+ const char *ns_name = describe_ns(ns_id);
+ ELOG("error in provider %s:%s: %s", ns_name, name, err.msg);
+ bool verbose_errs = true; // TODO(bfredl):
+ if (verbose_errs && perr && *perr == NULL) {
+ static char errbuf[IOSIZE];
+ snprintf(errbuf, sizeof errbuf, "%s: %s", ns_name, err.msg);
+ *perr = xstrdup(errbuf);
+ }
+ }
+
+ api_free_object(ret);
+ return false;
+}
+
+/// For each provider invoke the 'start' callback
+///
+/// @param[out] providers Decoration providers
+/// @param[out] err Provider err
+void decor_providers_start(DecorProviders *providers, int type, char **err)
+{
+ kvi_init(*providers);
+
+ for (size_t i = 0; i < kv_size(decor_providers); i++) {
+ DecorProvider *p = &kv_A(decor_providers, i);
+ if (!p->active) {
+ continue;
+ }
+
+ bool active;
+ if (p->redraw_start != LUA_NOREF) {
+ FIXED_TEMP_ARRAY(args, 2);
+ args.items[0] = INTEGER_OBJ((int)display_tick);
+ args.items[1] = INTEGER_OBJ(type);
+ active = decor_provider_invoke(p->ns_id, "start", p->redraw_start, args, true, err);
+ } else {
+ active = true;
+ }
+
+ if (active) {
+ kvi_push(*providers, p);
+ }
+ }
+}
+
+/// For each provider run 'win'. If result is not false, then collect the
+/// 'on_line' callback to call inside win_line
+///
+/// @param wp Window
+/// @param providers Decoration providers
+/// @param[out] line_providers Enabled line providers to invoke in win_line
+/// @param[out] err Provider error
+void decor_providers_invoke_win(win_T *wp, DecorProviders *providers,
+ DecorProviders *line_providers, char **err)
+{
+ kvi_init(*line_providers);
+
+ linenr_T knownmax = ((wp->w_valid & VALID_BOTLINE)
+ ? wp->w_botline
+ : (wp->w_topline + wp->w_height_inner));
+
+ for (size_t k = 0; k < kv_size(*providers); k++) {
+ DecorProvider *p = kv_A(*providers, k);
+ if (p && p->redraw_win != LUA_NOREF) {
+ FIXED_TEMP_ARRAY(args, 4);
+ args.items[0] = WINDOW_OBJ(wp->handle);
+ args.items[1] = BUFFER_OBJ(wp->w_buffer->handle);
+ // TODO(bfredl): we are not using this, but should be first drawn line?
+ args.items[2] = INTEGER_OBJ(wp->w_topline-1);
+ args.items[3] = INTEGER_OBJ(knownmax);
+ if (decor_provider_invoke(p->ns_id, "win", p->redraw_win, args, true, err)) {
+ kvi_push(*line_providers, p);
+ }
+ }
+ }
+
+ win_check_ns_hl(wp);
+}
+
+/// For each provider invoke the 'line' callback for a given window row.
+///
+/// @param wp Window
+/// @param providers Decoration providers
+/// @param row Row to invoke line callback for
+/// @param[out] has_decor Set when at least one provider invokes a line callback
+/// @param[out] err Provider error
+void providers_invoke_line(win_T *wp, DecorProviders *providers, int row, bool *has_decor,
+ char **err)
+{
+ for (size_t k = 0; k < kv_size(*providers); k++) {
+ DecorProvider *p = kv_A(*providers, k);
+ if (p && p->redraw_line != LUA_NOREF) {
+ FIXED_TEMP_ARRAY(args, 3);
+ args.items[0] = WINDOW_OBJ(wp->handle);
+ args.items[1] = BUFFER_OBJ(wp->w_buffer->handle);
+ args.items[2] = INTEGER_OBJ(row);
+ if (decor_provider_invoke(p->ns_id, "line", p->redraw_line, args, true, err)) {
+ *has_decor = true;
+ } else {
+ // return 'false' or error: skip rest of this window
+ kv_A(*providers, k) = NULL;
+ }
+
+ win_check_ns_hl(wp);
+ }
+ }
+}
+
+
+/// For each provider invoke the 'buf' callback for a given buffer.
+///
+/// @param buf Buffer
+/// @param providers Decoration providers
+/// @param[out] err Provider error
+void decor_providers_invoke_buf(buf_T *buf, DecorProviders *providers, char **err)
+{
+ for (size_t i = 0; i < kv_size(*providers); i++) {
+ DecorProvider *p = kv_A(*providers, i);
+ if (p && p->redraw_buf != LUA_NOREF) {
+ FIXED_TEMP_ARRAY(args, 1);
+ args.items[0] = BUFFER_OBJ(buf->handle);
+ decor_provider_invoke(p->ns_id, "buf", p->redraw_buf, args, true, err);
+ }
+ }
+}
+
+
+/// For each provider invoke the 'end' callback
+///
+/// @param providers Decoration providers
+/// @param displaytick Display tick
+/// @param[out] err Provider error
+void decor_providers_invoke_end(DecorProviders *providers, char **err)
+{
+ for (size_t i = 0; i < kv_size(*providers); i++) {
+ DecorProvider *p = kv_A(*providers, i);
+ if (p && p->active && p->redraw_end != LUA_NOREF) {
+ FIXED_TEMP_ARRAY(args, 1);
+ args.items[0] = INTEGER_OBJ((int)display_tick);
+ decor_provider_invoke(p->ns_id, "end", p->redraw_end, args, true, err);
+ }
+ }
+}
+
+DecorProvider *get_decor_provider(NS ns_id, bool force)
+{
+ size_t i;
+ size_t len = kv_size(decor_providers);
+ for (i = 0; i < len; i++) {
+ DecorProvider *item = &kv_A(decor_providers, i);
+ if (item->ns_id == ns_id) {
+ return item;
+ } else if (item->ns_id > ns_id) {
+ break;
+ }
+ }
+
+ if (!force) {
+ return NULL;
+ }
+
+ // Adding a new provider, so allocate room in the vector
+ (void)kv_a(decor_providers, len);
+ if (i < len) {
+ // New ns_id needs to be inserted between existing providers to maintain
+ // ordering, so shift other providers with larger ns_id
+ memmove(&kv_A(decor_providers, i + 1),
+ &kv_A(decor_providers, i),
+ (len - i) * sizeof(kv_a(decor_providers, i)));
+ }
+ DecorProvider *item = &kv_a(decor_providers, i);
+ *item = DECORATION_PROVIDER_INIT(ns_id);
+
+ return item;
+}
+
+void decor_provider_clear(DecorProvider *p)
+{
+ if (p == NULL) {
+ return;
+ }
+ NLUA_CLEAR_REF(p->redraw_start);
+ NLUA_CLEAR_REF(p->redraw_buf);
+ NLUA_CLEAR_REF(p->redraw_win);
+ NLUA_CLEAR_REF(p->redraw_line);
+ NLUA_CLEAR_REF(p->redraw_end);
+ p->active = false;
+}
+
+void decor_free_all_mem(void)
+{
+ for (size_t i = 0; i < kv_size(decor_providers); i++) {
+ decor_provider_clear(&kv_A(decor_providers, i));
+ }
+ kv_destroy(decor_providers);
+}
+
diff --git a/src/nvim/decoration_provider.h b/src/nvim/decoration_provider.h
new file mode 100644
index 0000000000..3ec7c80357
--- /dev/null
+++ b/src/nvim/decoration_provider.h
@@ -0,0 +1,26 @@
+#ifndef NVIM_DECORATION_PROVIDER_H
+#define NVIM_DECORATION_PROVIDER_H
+
+#include "nvim/buffer_defs.h"
+
+typedef struct {
+ NS ns_id;
+ bool active;
+ LuaRef redraw_start;
+ LuaRef redraw_buf;
+ LuaRef redraw_win;
+ LuaRef redraw_line;
+ LuaRef redraw_end;
+ LuaRef hl_def;
+ int hl_valid;
+} DecorProvider;
+
+typedef kvec_withinit_t(DecorProvider *, 4) DecorProviders;
+
+EXTERN bool provider_active INIT(= false);
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "decoration_provider.h.generated.h"
+#endif
+
+#endif // NVIM_DECORATION_PROVIDER_H
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 8cdb03c341..83223cdd5c 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -2710,7 +2710,7 @@ bool next_for_item(void *fi_void, char_u *arg)
tv.vval.v_string = vim_strnsave(fi->fi_string + fi->fi_byte_idx, len);
fi->fi_byte_idx += len;
const int result
- = ex_let_vars(arg, &tv, true, fi->fi_semicolon, fi->fi_varcount, false, NULL) == OK;
+ = ex_let_vars(arg, &tv, true, fi->fi_semicolon, fi->fi_varcount, false, NULL) == OK;
xfree(tv.vval.v_string);
return result;
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index d81a408663..85c49c20e7 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -7066,10 +7066,12 @@ static void init_srand(uint32_t *const x)
if (dev_urandom_state != OK) {
// Reading /dev/urandom doesn't work, fall back to time().
#endif
+ // uncrustify:off
*x = time(NULL);
#ifndef MSWIN
}
#endif
+ // uncrustify:on
}
static inline uint32_t splitmix32(uint32_t *const x)
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index d492c67877..2a432ecb47 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1171,10 +1171,10 @@ void callback_put(Callback *cb, typval_T *tv)
func_ref(cb->data.funcref);
break;
case kCallbackLua:
- // TODO(tjdevries): Unified Callback.
- // At this point this isn't possible, but it'd be nice to put
- // these handled more neatly in one place.
- // So instead, we just do the default and put nil
+ // TODO(tjdevries): Unified Callback.
+ // At this point this isn't possible, but it'd be nice to put
+ // these handled more neatly in one place.
+ // So instead, we just do the default and put nil
default:
tv->v_type = VAR_SPECIAL;
tv->vval.v_special = kSpecialVarNull;
diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c
index 3c43d1f98d..e51689543f 100644
--- a/src/nvim/event/rstream.c
+++ b/src/nvim/event/rstream.c
@@ -11,8 +11,8 @@
#include "nvim/event/loop.h"
#include "nvim/event/rstream.h"
#include "nvim/log.h"
-#include "nvim/memory.h"
#include "nvim/main.h"
+#include "nvim/memory.h"
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h
index abf6ec347b..be9f97e27d 100644
--- a/src/nvim/ex_docmd.h
+++ b/src/nvim/ex_docmd.h
@@ -1,8 +1,8 @@
#ifndef NVIM_EX_DOCMD_H
#define NVIM_EX_DOCMD_H
-#include "nvim/ex_cmds_defs.h"
#include "nvim/eval/funcs.h"
+#include "nvim/ex_cmds_defs.h"
#include "nvim/globals.h"
// flags for do_cmdline()
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index 2916e3e978..6b879f5139 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -118,7 +118,7 @@ void extmark_set(buf_T *buf, uint32_t ns_id, uint32_t *idp, int row, colnr_T col
}
mtkey_t mark = { { row, col }, ns_id, id, 0,
- mt_flags(right_gravity, decor_level), 0, NULL };
+ mt_flags(right_gravity, decor_level), 0, NULL };
if (decor_full) {
mark.decor_full = decor;
} else if (decor) {
diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h
index af9526cd43..b856a1148f 100644
--- a/src/nvim/extmark.h
+++ b/src/nvim/extmark.h
@@ -2,8 +2,8 @@
#define NVIM_EXTMARK_H
#include "nvim/buffer_defs.h"
-#include "nvim/extmark_defs.h"
#include "nvim/decoration.h"
+#include "nvim/extmark_defs.h"
#include "nvim/marktree.h"
#include "nvim/pos.h"
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 971ae9abae..41e67e5b3b 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -3,6 +3,8 @@
// fileio.c: read from and write to a file
+// uncrustify:off
+
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index a1fd0d0d66..abbda1e9fa 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -5,6 +5,7 @@
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/decoration_provider.h"
#include "nvim/highlight.h"
#include "nvim/highlight_defs.h"
#include "nvim/lua/executor.h"
@@ -819,9 +820,9 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
bool cterm_mask_provided = false;
#define CHECK_FLAG(d, m, name, extra, flag) \
- if (api_object_to_bool(d->name ## extra, #name, false, err)) { \
- m = m | flag; \
- }
+ if (api_object_to_bool(d->name##extra, #name, false, err)) { \
+ m = m | flag; \
+ }
CHECK_FLAG(dict, mask, bold, , HL_BOLD);
CHECK_FLAG(dict, mask, standout, , HL_STANDOUT);
@@ -906,7 +907,6 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
CHECK_FLAG(cterm, cterm_mask, reverse, , HL_INVERSE);
CHECK_FLAG(cterm, cterm_mask, strikethrough, , HL_STRIKETHROUGH);
CHECK_FLAG(cterm, cterm_mask, nocombine, , HL_NOCOMBINE);
-
} else if (dict->cterm.type == kObjectTypeArray && dict->cterm.data.array.size == 0) {
// empty list from Lua API should clear all cterm attributes
// TODO(clason): handle via gen_api_dispatch
diff --git a/src/nvim/input.c b/src/nvim/input.c
index 5fa9b8b343..ff6b559710 100644
--- a/src/nvim/input.c
+++ b/src/nvim/input.c
@@ -9,9 +9,9 @@
#include "nvim/func_attr.h"
#include "nvim/getchar.h"
+#include "nvim/input.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
-#include "nvim/input.h"
#include "nvim/mouse.h"
#include "nvim/os/input.h"
#include "nvim/ui.h"
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 6aaff100ca..054f6c9483 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -15,8 +15,8 @@
#include "nvim/buffer_defs.h"
#include "nvim/change.h"
#include "nvim/cursor.h"
-#include "nvim/eval/userfunc.h"
#include "nvim/eval/typval.h"
+#include "nvim/eval/userfunc.h"
#include "nvim/event/loop.h"
#include "nvim/event/time.h"
#include "nvim/ex_cmds2.h"
@@ -139,17 +139,17 @@ static void nlua_luv_error_event(void **argv)
luv_err_t type = (luv_err_t)(intptr_t)argv[1];
msg_ext_set_kind("lua_error");
switch (type) {
- case kCallback:
- semsg_multiline("Error executing luv callback:\n%s", error);
- break;
- case kThread:
- semsg_multiline("Error in luv thread:\n%s", error);
- break;
- case kThreadCallback:
- semsg_multiline("Error in luv callback, thread:\n%s", error);
- break;
- default:
- break;
+ case kCallback:
+ semsg_multiline("Error executing luv callback:\n%s", error);
+ break;
+ case kThread:
+ semsg_multiline("Error in luv thread:\n%s", error);
+ break;
+ case kThreadCallback:
+ semsg_multiline("Error in luv callback, thread:\n%s", error);
+ break;
+ default:
+ break;
}
xfree(error);
}
@@ -189,21 +189,18 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags
return retval;
}
-static int nlua_luv_thread_cb_cfpcall(lua_State *lstate, int nargs, int nresult,
- int flags)
+static int nlua_luv_thread_cb_cfpcall(lua_State *lstate, int nargs, int nresult, int flags)
{
return nlua_luv_thread_common_cfpcall(lstate, nargs, nresult, flags, true);
}
-static int nlua_luv_thread_cfpcall(lua_State *lstate, int nargs, int nresult,
- int flags)
+static int nlua_luv_thread_cfpcall(lua_State *lstate, int nargs, int nresult, int flags)
FUNC_ATTR_NONNULL_ALL
{
return nlua_luv_thread_common_cfpcall(lstate, nargs, nresult, flags, false);
}
-static int nlua_luv_thread_cfcpcall(lua_State *lstate, lua_CFunction func,
- void *ud, int flags)
+static int nlua_luv_thread_cfcpcall(lua_State *lstate, lua_CFunction func, void *ud, int flags)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
lua_pushcfunction(lstate, func);
@@ -212,8 +209,8 @@ static int nlua_luv_thread_cfcpcall(lua_State *lstate, lua_CFunction func,
return retval;
}
-static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nresult,
- int flags, bool is_callback)
+static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nresult, int flags,
+ bool is_callback)
FUNC_ATTR_NONNULL_ALL
{
int retval;
@@ -228,9 +225,9 @@ static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nres
mch_errmsg("\n");
lua_close(lstate);
#ifdef WIN32
- ExitThread(0);
+ ExitThread(0);
#else
- pthread_exit(0);
+ pthread_exit(0);
#endif
}
const char *error = lua_tostring(lstate, -1);
@@ -565,9 +562,9 @@ static bool nlua_init_packages(lua_State *lstate)
lua_getglobal(lstate, "require");
lua_pushstring(lstate, "vim._init_packages");
if (nlua_pcall(lstate, 1, 0)) {
- mch_errmsg(lua_tostring(lstate, -1));
- mch_errmsg("\n");
- return false;
+ mch_errmsg(lua_tostring(lstate, -1));
+ mch_errmsg("\n");
+ return false;
}
return true;
diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h
index d978dc55d3..e96494ec5a 100644
--- a/src/nvim/lua/executor.h
+++ b/src/nvim/lua/executor.h
@@ -4,8 +4,8 @@
#include <lauxlib.h>
#include <lua.h>
-#include "nvim/assert.h"
#include "nvim/api/private/defs.h"
+#include "nvim/assert.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
@@ -16,9 +16,9 @@
void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL;
typedef struct {
- LuaRef nil_ref;
- LuaRef empty_dict_ref;
- int ref_count;
+ LuaRef nil_ref;
+ LuaRef empty_dict_ref;
+ int ref_count;
#if __has_feature(address_sanitizer)
PMap(handle_T) ref_markers;
#endif
diff --git a/src/nvim/lua/spell.c b/src/nvim/lua/spell.c
index 3a63f61200..31a2b2d19f 100644
--- a/src/nvim/lua/spell.c
+++ b/src/nvim/lua/spell.c
@@ -1,12 +1,12 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <lua.h>
#include <lauxlib.h>
+#include <lua.h>
+#include "nvim/lua/spell.h"
#include "nvim/spell.h"
#include "nvim/vim.h"
-#include "nvim/lua/spell.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "lua/spell.c.generated.h"
@@ -45,7 +45,7 @@ int nlua_spell_check(lua_State *lstate)
size_t pos = 0;
int capcol = -1;
int no_res = 0;
- const char * result;
+ const char *result;
lua_createtable(lstate, 0, 0);
@@ -90,7 +90,7 @@ int nlua_spell_check(lua_State *lstate)
static const luaL_Reg spell_functions[] = {
{ "check", nlua_spell_check },
- { NULL , NULL }
+ { NULL, NULL }
};
int luaopen_spell(lua_State *L)
diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c
index c2ce899a74..e94c61b37c 100644
--- a/src/nvim/lua/stdlib.c
+++ b/src/nvim/lua/stdlib.c
@@ -28,10 +28,10 @@
#include "nvim/globals.h"
#include "nvim/lua/converter.h"
#include "nvim/lua/executor.h"
+#include "nvim/lua/spell.h"
#include "nvim/lua/stdlib.h"
#include "nvim/lua/treesitter.h"
#include "nvim/lua/xdiff.h"
-#include "nvim/lua/spell.h"
#include "nvim/macros.h"
#include "nvim/map.h"
#include "nvim/memline.h"
@@ -411,7 +411,7 @@ int nlua_getvar(lua_State *lstate)
dictitem_T *di = tv_dict_find(dict, name, (ptrdiff_t)len);
if (di == NULL && dict == &globvardict) { // try to autoload script
if (!script_autoload(name, len, false) || aborting()) {
- return 0; // nil
+ return 0; // nil
}
di = tv_dict_find(dict, name, (ptrdiff_t)len);
}
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 7281809c06..a575aba50a 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -14,6 +14,7 @@
#include "nvim/channel.h"
#include "nvim/charset.h"
#include "nvim/decoration.h"
+#include "nvim/decoration_provider.h"
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 8b29aa3676..b770fef05c 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -630,7 +630,7 @@ static char_u *mark_line(pos_T *mp, int lead_len)
if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) {
return vim_strsave((char_u *)"-invalid-");
}
- assert(Columns >= 0 && (size_t)Columns <= SIZE_MAX);
+ assert(Columns >= 0);
// Allow for up to 5 bytes per character.
s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5);
diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c
index 4456b28293..937582572b 100644
--- a/src/nvim/marktree.c
+++ b/src/nvim/marktree.c
@@ -558,7 +558,7 @@ void marktree_revise(MarkTree *b, MarkTreeIter *itr, uint8_t decor_level, mtkey_
{
// TODO(bfredl): clean up this mess and re-instantiate &= and |= forms
// once we upgrade to a non-broken version of gcc in functionaltest-lua CI
- rawkey(itr).flags = (uint16_t)(rawkey(itr).flags & (uint16_t)~MT_FLAG_DECOR_MASK);
+ rawkey(itr).flags = (uint16_t)(rawkey(itr).flags & (uint16_t) ~MT_FLAG_DECOR_MASK);
rawkey(itr).flags = (uint16_t)(rawkey(itr).flags
| (uint16_t)(decor_level << MT_FLAG_DECOR_OFFSET)
| (uint16_t)(key.flags & MT_FLAG_DECOR_MASK));
@@ -1111,7 +1111,7 @@ static void marktree_itr_fix_pos(MarkTree *b, MarkTreeIter *itr)
void marktree_put_test(MarkTree *b, uint32_t id, int row, int col, bool right_gravity)
{
mtkey_t key = { { row, col }, UINT32_MAX, id, 0,
- mt_flags(right_gravity, 0), 0, NULL };
+ mt_flags(right_gravity, 0), 0, NULL };
marktree_put(b, key, -1, -1, false);
}
diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h
index 440816930b..ae6da92106 100644
--- a/src/nvim/marktree.h
+++ b/src/nvim/marktree.h
@@ -1,14 +1,14 @@
#ifndef NVIM_MARKTREE_H
#define NVIM_MARKTREE_H
-#include <stdint.h>
#include <assert.h>
+#include <stdint.h>
#include "nvim/assert.h"
#include "nvim/garray.h"
#include "nvim/map.h"
-#include "nvim/types.h"
#include "nvim/pos.h"
+#include "nvim/types.h"
#define MT_MAX_DEPTH 20
#define MT_BRANCH_FACTOR 10
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 677ff8f522..d68ca6b62e 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -10,7 +10,7 @@
#include "nvim/api/extmark.h"
#include "nvim/context.h"
-#include "nvim/decoration.h"
+#include "nvim/decoration_provider.h"
#include "nvim/eval.h"
#include "nvim/highlight.h"
#include "nvim/lua/executor.h"
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 5c39e9c8bf..0e5e0ab403 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -3568,7 +3568,6 @@ static void nv_zet(cmdarg_T *cap)
bool undo = false;
int l_p_siso = (int)get_sidescrolloff_value(curwin);
- assert(l_p_siso <= INT_MAX);
if (ascii_isdigit(nchar)) {
/*
diff --git a/src/nvim/option.c b/src/nvim/option.c
index a0706dfa14..191b635dc0 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -5664,12 +5664,10 @@ void comp_col(void)
}
}
assert(sc_col >= 0
- && INT_MIN + sc_col <= Columns
- && Columns - sc_col <= INT_MAX);
+ && INT_MIN + sc_col <= Columns);
sc_col = Columns - sc_col;
assert(ru_col >= 0
- && INT_MIN + ru_col <= Columns
- && Columns - ru_col <= INT_MAX);
+ && INT_MIN + ru_col <= Columns);
ru_col = Columns - ru_col;
if (sc_col <= 0) { // screen too narrow, will become a mess
sc_col = 1;
diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h
index dce4b0c187..a4361859ec 100644
--- a/src/nvim/os/os_defs.h
+++ b/src/nvim/os/os_defs.h
@@ -14,7 +14,7 @@
#endif
#if !defined(NAME_MAX) && defined(_XOPEN_NAME_MAX)
-#define NAME_MAX _XOPEN_NAME_MAX
+# define NAME_MAX _XOPEN_NAME_MAX
#endif
#define BASENAMELEN (NAME_MAX - 5)
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index 3459646bad..58cb1b8f84 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -16,11 +16,11 @@
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
# include <util.h>
#elif defined(__sun)
-# include <sys/stream.h>
-# include <sys/syscall.h>
-# include <fcntl.h>
-# include <unistd.h>
-# include <signal.h>
+# include <fcntl.h>
+# include <signal.h>
+# include <sys/stream.h>
+# include <sys/syscall.h>
+# include <unistd.h>
#else
# include <pty.h>
#endif
@@ -49,10 +49,10 @@
// this header defines STR, just as nvim.h, but it is defined as ('S'<<8),
// to avoid #undef STR, #undef STR, #define STR ('S'<<8) just delay the
// inclusion of the header even though it gets include out of order.
-#include <sys/stropts.h>
+# include <sys/stropts.h>
-static int openpty(int *amaster, int *aslave, char *name,
- struct termios *termp, struct winsize *winp)
+static int openpty(int *amaster, int *aslave, char *name, struct termios *termp,
+ struct winsize *winp)
{
int slave = -1;
int master = open("/dev/ptmx", O_RDWR);
@@ -63,7 +63,7 @@ static int openpty(int *amaster, int *aslave, char *name,
// grantpt will invoke a setuid program to change permissions
// and might fail if SIGCHLD handler is set, temporarily reset
// while running
- void(*sig_saved)(int) = signal(SIGCHLD, SIG_DFL);
+ void (*sig_saved)(int) = signal(SIGCHLD, SIG_DFL);
int res = grantpt(master);
signal(SIGCHLD, sig_saved);
@@ -129,8 +129,7 @@ static int login_tty(int fd)
return 0;
}
-static pid_t forkpty(int *amaster, char *name,
- struct termios *termp, struct winsize *winp)
+static pid_t forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp)
{
int master, slave;
if (openpty(&master, &slave, name, termp, winp) == -1) {
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index e618b2788b..656e059303 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -9,10 +9,10 @@
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/eval.h"
#include "nvim/event/libuv_process.h"
#include "nvim/event/loop.h"
#include "nvim/event/rstream.h"
-#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/fileio.h"
#include "nvim/lib/kvec.h"
@@ -27,8 +27,8 @@
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
-#include "nvim/types.h"
#include "nvim/tag.h"
+#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/vim.h"
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index d7726409b5..e354a589a5 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -289,8 +289,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
if (pum_rl) {
pum_width = pum_col - pum_scrollbar + 1;
} else {
- assert(Columns - pum_col - pum_scrollbar >= INT_MIN
- && Columns - pum_col - pum_scrollbar <= INT_MAX);
+ assert(Columns - pum_col - pum_scrollbar >= 0);
pum_width = Columns - pum_col - pum_scrollbar;
}
@@ -356,7 +355,6 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
} else {
pum_col = 0;
}
- assert(Columns - 1 >= INT_MIN);
pum_width = Columns - 1;
} else {
if (max_width > p_pw) {
@@ -367,8 +365,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
if (pum_rl) {
pum_col = max_width - 1;
} else {
- assert(Columns - max_width >= INT_MIN
- && Columns - max_width <= INT_MAX);
+ assert(Columns - max_width >= 0);
pum_col = Columns - max_width;
}
pum_width = max_width - pum_scrollbar;
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 7e29aed51b..bddbd04af9 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -5421,9 +5421,8 @@ static int vgr_process_args(exarg_T *eap, vgr_args_T *args)
/// Search for a pattern in a list of files and populate the quickfix list with
/// the matches.
-static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args,
- bool *redraw_for_dummy, buf_T **first_match_buf,
- char_u **target_dir)
+static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args, bool *redraw_for_dummy,
+ buf_T **first_match_buf, char_u **target_dir)
{
int status = FAIL;
unsigned save_qfid = qf_get_curlist(qi)->qf_id;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 3a87cba7f9..0a1f388456 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -75,6 +75,7 @@
#include "nvim/cursor.h"
#include "nvim/cursor_shape.h"
#include "nvim/decoration.h"
+#include "nvim/decoration_provider.h"
#include "nvim/diff.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
@@ -126,8 +127,6 @@
#define MB_FILLER_CHAR '<' /* character used when a double-width character
* doesn't fit. */
-typedef kvec_withinit_t(DecorProvider *, 4) Providers;
-
// temporary buffer for rendering a single screenline, so it can be
// compared with previous contents to calculate smallest delta.
// Per-cell attributes
@@ -168,36 +167,6 @@ static bool resizing = false;
static char *provider_err = NULL;
-static bool provider_invoke(NS ns_id, const char *name, LuaRef ref, Array args, bool default_true)
-{
- Error err = ERROR_INIT;
-
- textlock++;
- provider_active = true;
- Object ret = nlua_call_ref(ref, name, args, true, &err);
- provider_active = false;
- textlock--;
-
- if (!ERROR_SET(&err)
- && api_object_to_bool(ret, "provider %s retval", default_true, &err)) {
- return true;
- }
-
- if (ERROR_SET(&err)) {
- const char *ns_name = describe_ns(ns_id);
- ELOG("error in provider %s:%s: %s", ns_name, name, err.msg);
- bool verbose_errs = true; // TODO(bfredl):
- if (verbose_errs && provider_err == NULL) {
- static char errbuf[IOSIZE];
- snprintf(errbuf, sizeof errbuf, "%s: %s", ns_name, err.msg);
- provider_err = xstrdup(errbuf);
- }
- }
-
- api_free_object(ret);
- return false;
-}
-
/// Redraw a window later, with update_screen(type).
///
/// Set must_redraw only if not already set to a higher value.
@@ -501,28 +470,8 @@ int update_screen(int type)
ui_comp_set_screen_valid(true);
- Providers providers;
- kvi_init(providers);
- for (size_t i = 0; i < kv_size(decor_providers); i++) {
- DecorProvider *p = &kv_A(decor_providers, i);
- if (!p->active) {
- continue;
- }
-
- bool active;
- if (p->redraw_start != LUA_NOREF) {
- FIXED_TEMP_ARRAY(args, 2);
- args.items[0] = INTEGER_OBJ(display_tick);
- args.items[1] = INTEGER_OBJ(type);
- active = provider_invoke(p->ns_id, "start", p->redraw_start, args, true);
- } else {
- active = true;
- }
-
- if (active) {
- kvi_push(providers, p);
- }
- }
+ DecorProviders providers;
+ decor_providers_start(&providers, type, &provider_err);
// "start" callback could have changed highlights for global elements
if (win_check_ns_hl(NULL)) {
@@ -591,14 +540,7 @@ int update_screen(int type)
}
if (buf->b_mod_tick_decor < display_tick) {
- for (size_t i = 0; i < kv_size(providers); i++) {
- DecorProvider *p = kv_A(providers, i);
- if (p && p->redraw_buf != LUA_NOREF) {
- FIXED_TEMP_ARRAY(args, 1);
- args.items[0] = BUFFER_OBJ(buf->handle);
- provider_invoke(p->ns_id, "buf", p->redraw_buf, args, true);
- }
- }
+ decor_providers_invoke_buf(buf, &providers, &provider_err);
buf->b_mod_tick_decor = display_tick;
}
}
@@ -668,18 +610,7 @@ int update_screen(int type)
}
did_intro = true;
- for (size_t i = 0; i < kv_size(providers); i++) {
- DecorProvider *p = kv_A(providers, i);
- if (!p->active) {
- continue;
- }
-
- if (p->redraw_end != LUA_NOREF) {
- FIXED_TEMP_ARRAY(args, 1);
- args.items[0] = INTEGER_OBJ(display_tick);
- provider_invoke(p->ns_id, "end", p->redraw_end, args, true);
- }
- }
+ decor_providers_invoke_end(&providers, &provider_err);
kvi_destroy(providers);
@@ -766,7 +697,7 @@ bool win_cursorline_standout(const win_T *wp)
* mid: from mid_start to mid_end (update inversion or changed text)
* bot: from bot_start to last row (when scrolled up)
*/
-static void win_update(win_T *wp, Providers *providers)
+static void win_update(win_T *wp, DecorProviders *providers)
{
buf_T *buf = wp->w_buffer;
int type;
@@ -1377,30 +1308,8 @@ static void win_update(win_T *wp, Providers *providers)
decor_redraw_reset(buf, &decor_state);
- Providers line_providers;
- kvi_init(line_providers);
-
- linenr_T knownmax = ((wp->w_valid & VALID_BOTLINE)
- ? wp->w_botline
- : (wp->w_topline + wp->w_height_inner));
-
- for (size_t k = 0; k < kv_size(*providers); k++) {
- DecorProvider *p = kv_A(*providers, k);
- if (p && p->redraw_win != LUA_NOREF) {
- FIXED_TEMP_ARRAY(args, 4);
- args.items[0] = WINDOW_OBJ(wp->handle);
- args.items[1] = BUFFER_OBJ(buf->handle);
- // TODO(bfredl): we are not using this, but should be first drawn line?
- args.items[2] = INTEGER_OBJ(wp->w_topline-1);
- args.items[3] = INTEGER_OBJ(knownmax);
- if (provider_invoke(p->ns_id, "win", p->redraw_win, args, true)) {
- kvi_push(line_providers, p);
- }
- }
- }
-
- win_check_ns_hl(wp);
-
+ DecorProviders line_providers;
+ decor_providers_invoke_win(wp, providers, &line_providers, &provider_err);
for (;;) {
/* stop updating when reached the end of the window (check for _past_
@@ -2028,6 +1937,17 @@ static size_t fill_foldcolumn(char_u *p, win_T *wp, foldinfo_T foldinfo, linenr_
return MAX(char_counter + (fdc-i), (size_t)fdc);
}
+static inline void provider_err_virt_text(linenr_T lnum, char *err)
+{
+ Decoration err_decor = DECORATION_INIT;
+ int hl_err = syn_check_group(S_LEN("ErrorMsg"));
+ kv_push(err_decor.virt_text,
+ ((VirtTextChunk){ .text = provider_err,
+ .hl_id = hl_err }));
+ err_decor.virt_text_width = mb_string2cells((char_u *)err);
+ decor_add_ephemeral(lnum-1, 0, lnum-1, 0, &err_decor);
+}
+
/// Display line "lnum" of window 'wp' on the screen.
/// wp->w_virtcol needs to be valid.
///
@@ -2043,7 +1963,7 @@ static size_t fill_foldcolumn(char_u *p, win_T *wp, foldinfo_T foldinfo, linenr_
///
/// @return the number of last row the line occupies.
static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
- bool number_only, foldinfo_T foldinfo, Providers *providers)
+ bool number_only, foldinfo_T foldinfo, DecorProviders *providers)
{
int c = 0; // init for GCC
long vcol = 0; // virtual column (for tabs)
@@ -2231,34 +2151,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
has_decor = decor_redraw_line(buf, lnum-1, &decor_state);
- for (size_t k = 0; k < kv_size(*providers); k++) {
- DecorProvider *p = kv_A(*providers, k);
- if (p && p->redraw_line != LUA_NOREF) {
- FIXED_TEMP_ARRAY(args, 3);
- args.items[0] = WINDOW_OBJ(wp->handle);
- args.items[1] = BUFFER_OBJ(buf->handle);
- args.items[2] = INTEGER_OBJ(lnum-1);
- if (provider_invoke(p->ns_id, "line", p->redraw_line, args, true)) {
- has_decor = true;
- } else {
- // return 'false' or error: skip rest of this window
- kv_A(*providers, k) = NULL;
- }
-
- win_check_ns_hl(wp);
- }
- }
+ providers_invoke_line(wp, providers, lnum-1, &has_decor, &provider_err);
if (provider_err) {
- Decoration err_decor = DECORATION_INIT;
- int hl_err = syn_check_group(S_LEN("ErrorMsg"));
- kv_push(err_decor.virt_text,
- ((VirtTextChunk){ .text = provider_err,
- .hl_id = hl_err }));
- err_decor.virt_text_width = mb_string2cells((char_u *)provider_err);
- decor_add_ephemeral(lnum-1, 0, lnum-1, 0, &err_decor);
- provider_err = NULL;
+ provider_err_virt_text(lnum, provider_err);
has_decor = true;
+ provider_err = NULL;
}
if (has_decor) {
@@ -4680,9 +4578,9 @@ static bool use_cursor_line_sign(win_T *wp, linenr_T lnum)
// @param[in, out] sign_idxp Index of the displayed sign
static void get_sign_display_info(bool nrcol, win_T *wp, linenr_T lnum, sign_attrs_T sattrs[],
int row, int startrow, int filler_lines, int filler_todo,
- int *c_extrap, int *c_finalp, char_u *extra,
- size_t extra_size, char_u **pp_extra, int *n_extrap,
- int *char_attrp, int *draw_statep, int *sign_idxp)
+ int *c_extrap, int *c_finalp, char_u *extra, size_t extra_size,
+ char_u **pp_extra, int *n_extrap, int *char_attrp,
+ int *draw_statep, int *sign_idxp)
{
int count = wp->w_scwidth;
// Draw cells with the sign value or blank.
diff --git a/src/nvim/search.c b/src/nvim/search.c
index e6b47e75b2..cc7c2ecf06 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -13,8 +13,8 @@
#include "nvim/ascii.h"
#include "nvim/buffer.h"
-#include "nvim/charset.h"
#include "nvim/change.h"
+#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
@@ -5048,8 +5048,8 @@ bool fuzzy_match(char_u *const str, const char_u *const pat_arg, const bool matc
int score = 0;
int recursionCount = 0;
const int matchCount
- = fuzzy_match_recursive(pat, str, 0, &score, str, len, NULL, matches + numMatches,
- maxMatches - numMatches, 0, &recursionCount);
+ = fuzzy_match_recursive(pat, str, 0, &score, str, len, NULL, matches + numMatches,
+ maxMatches - numMatches, 0, &recursionCount);
if (matchCount == 0) {
numMatches = 0;
break;
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 1ad82b7290..79a6b9ed0e 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1475,8 +1475,8 @@ static void tui_guess_size(UI *ui)
// 1 - look for non-default 'columns' and 'lines' options during startup
if (data->is_starting && (Columns != DFLT_COLS || Rows != DFLT_ROWS)) {
did_user_set_dimensions = true;
- assert(Columns >= INT_MIN && Columns <= INT_MAX);
- assert(Rows >= INT_MIN && Rows <= INT_MAX);
+ assert(Columns >= 0);
+ assert(Rows >= 0);
width = Columns;
height = Rows;
goto end;
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index 6e0e9922a6..5d632b1b25 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -217,9 +217,9 @@ enum { FOLD_TEXT_LEN = 51, }; //!< buffer size for get_foldtext()
#define STRLEN(s) strlen((char *)(s))
#ifdef HAVE_STRNLEN
-# define STRNLEN(s, n) strnlen((char *)(s), (size_t)(n))
+# define STRNLEN(s, n) strnlen((char *)(s), (size_t)(n))
#else
-# define STRNLEN(s, n) xstrnlen((char *)(s), (size_t)(n))
+# define STRNLEN(s, n) xstrnlen((char *)(s), (size_t)(n))
#endif
#define STRCPY(d, s) strcpy((char *)(d), (char *)(s))
#define STRNCPY(d, s, n) strncpy((char *)(d), (char *)(s), (size_t)(n))
diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt
index 30c4752b87..8a8720fca3 100644
--- a/third-party/CMakeLists.txt
+++ b/third-party/CMakeLists.txt
@@ -144,8 +144,8 @@ endif()
include(ExternalProject)
-set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.44.0.tar.gz)
-set(LIBUV_SHA256 f2482d547009d26d4d590ed6588043c540e707c833df52536744cb9a809e6617)
+set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.44.1.tar.gz)
+set(LIBUV_SHA256 e91614e6dc2dd0bfdd140ceace49438882206b7a6fb00b8750914e67a9ed6d6b)
set(MSGPACK_URL https://github.com/msgpack/msgpack-c/releases/download/cpp-3.0.0/msgpack-3.0.0.tar.gz)
set(MSGPACK_SHA256 bfbb71b7c02f806393bc3cbc491b40523b89e64f83860c58e3e54af47de176e4)