aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/nvim/CMakeLists.txt20
-rw-r--r--src/nvim/api/options.c203
-rw-r--r--src/nvim/testdir/test_mksession.vim18
3 files changed, 95 insertions, 146 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index f465d911f9..37f3aa1a23 100755
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -82,10 +82,10 @@ set(LINT_SUPPRESSES_ARCHIVE ${LINT_SUPPRESSES_ROOT}/errors.tar.gz)
set(LINT_SUPPRESSES_TOUCH_FILE "${TOUCHES_DIR}/unpacked-clint-errors-archive")
set(LINT_SUPPRESSES_INSTALL_SCRIPT "${PROJECT_SOURCE_DIR}/cmake/InstallClintErrors.cmake")
-file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt)
-file(GLOB API_HEADERS api/*.h)
+glob_wrapper(UNICODE_FILES ${UNICODE_DIR}/*.txt)
+glob_wrapper(API_HEADERS api/*.h)
list(REMOVE_ITEM API_HEADERS ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h)
-file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
+glob_wrapper(MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
include_directories(${GENERATED_DIR})
include_directories(${CACHED_GENERATED_DIR})
@@ -97,10 +97,10 @@ file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR})
file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT})
file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src)
-file(GLOB NVIM_SOURCES *.c)
-file(GLOB NVIM_HEADERS *.h)
-file(GLOB EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c ../cjson/*.c)
-file(GLOB EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h ../cjson/*.h)
+glob_wrapper(NVIM_SOURCES *.c)
+glob_wrapper(NVIM_HEADERS *.h)
+glob_wrapper(EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c ../cjson/*.c)
+glob_wrapper(EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h ../cjson/*.h)
foreach(subdir
os
@@ -120,13 +120,13 @@ foreach(subdir
file(MAKE_DIRECTORY ${GENERATED_DIR}/${subdir})
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/${subdir})
- file(GLOB sources ${subdir}/*.c)
- file(GLOB headers ${subdir}/*.h)
+ glob_wrapper(sources ${subdir}/*.c)
+ glob_wrapper(headers ${subdir}/*.h)
list(APPEND NVIM_SOURCES ${sources})
list(APPEND NVIM_HEADERS ${headers})
endforeach()
-file(GLOB UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c)
+glob_wrapper(UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c)
# Sort file lists to ensure generated files are created in the same order from
# build to build.
diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c
index a35c7222ed..3067a6e6b4 100644
--- a/src/nvim/api/options.c
+++ b/src/nvim/api/options.c
@@ -21,75 +21,87 @@
# include "api/options.c.generated.h"
#endif
-/// Gets the value of an option. The behavior of this function matches that of
-/// |:set|: the local value of an option is returned if it exists; otherwise,
-/// the global value is returned. Local values always correspond to the current
-/// buffer or window, unless "buf" or "win" is set in {opts}.
-///
-/// @param name Option name
-/// @param opts Optional parameters
-/// - scope: One of "global" or "local". Analogous to
-/// |:setglobal| and |:setlocal|, respectively.
-/// - win: |window-ID|. Used for getting window local options.
-/// - buf: Buffer number. Used for getting buffer local options.
-/// Implies {scope} is "local".
-/// @param[out] err Error details, if any
-/// @return Option value
-Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
- FUNC_API_SINCE(9)
+static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_type, void **from,
+ Error *err)
{
- Object rv = OBJECT_INIT;
-
- int scope = 0;
if (opts->scope.type == kObjectTypeString) {
if (!strcmp(opts->scope.data.string.data, "local")) {
- scope = OPT_LOCAL;
+ *scope = OPT_LOCAL;
} else if (!strcmp(opts->scope.data.string.data, "global")) {
- scope = OPT_GLOBAL;
+ *scope = OPT_GLOBAL;
} else {
api_set_error(err, kErrorTypeValidation, "invalid scope: must be 'local' or 'global'");
- goto end;
+ return FAIL;
}
} else if (HAS_KEY(opts->scope)) {
api_set_error(err, kErrorTypeValidation, "invalid value for key: scope");
- goto end;
+ return FAIL;
}
- int opt_type = SREQ_GLOBAL;
- void *from = NULL;
+ *opt_type = SREQ_GLOBAL;
if (opts->win.type == kObjectTypeInteger) {
- opt_type = SREQ_WIN;
- from = find_window_by_handle((int)opts->win.data.integer, err);
+ *opt_type = SREQ_WIN;
+ *from = find_window_by_handle((int)opts->win.data.integer, err);
} else if (HAS_KEY(opts->win)) {
api_set_error(err, kErrorTypeValidation, "invalid value for key: win");
- goto end;
+ return FAIL;
}
if (opts->buf.type == kObjectTypeInteger) {
- scope = OPT_LOCAL;
- opt_type = SREQ_BUF;
- from = find_buffer_by_handle((int)opts->buf.data.integer, err);
+ *scope = OPT_LOCAL;
+ *opt_type = SREQ_BUF;
+ *from = find_buffer_by_handle((int)opts->buf.data.integer, err);
} else if (HAS_KEY(opts->buf)) {
api_set_error(err, kErrorTypeValidation, "invalid value for key: buf");
- goto end;
+ return FAIL;
}
if (HAS_KEY(opts->scope) && HAS_KEY(opts->buf)) {
api_set_error(err, kErrorTypeValidation, "scope and buf cannot be used together");
- goto end;
+ return FAIL;
}
if (HAS_KEY(opts->win) && HAS_KEY(opts->buf)) {
api_set_error(err, kErrorTypeValidation, "buf and win cannot be used together");
- goto end;
+ return FAIL;
+ }
+
+ return OK;
+}
+
+/// Gets the value of an option. The behavior of this function matches that of
+/// |:set|: the local value of an option is returned if it exists; otherwise,
+/// the global value is returned. Local values always correspond to the current
+/// buffer or window, unless "buf" or "win" is set in {opts}.
+///
+/// @param name Option name
+/// @param opts Optional parameters
+/// - scope: One of "global" or "local". Analogous to
+/// |:setglobal| and |:setlocal|, respectively.
+/// - win: |window-ID|. Used for getting window local options.
+/// - buf: Buffer number. Used for getting buffer local options.
+/// Implies {scope} is "local".
+/// @param[out] err Error details, if any
+/// @return Option value
+Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
+ FUNC_API_SINCE(9)
+{
+ Object rv = OBJECT_INIT;
+
+ int scope = 0;
+ int opt_type = SREQ_GLOBAL;
+ void *from = NULL;
+ if (!validate_option_value_args(opts, &scope, &opt_type, &from, err)) {
+ return rv;
}
long numval = 0;
char *stringval = NULL;
- int result = get_option_value_for(name.data, &numval, &stringval, scope, opt_type, from, err);
+ int result = access_option_value_for(name.data, &numval, &stringval, scope, opt_type, from,
+ true, err);
if (ERROR_SET(err)) {
- goto end;
+ return rv;
}
switch (result) {
@@ -114,10 +126,9 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
break;
default:
api_set_error(err, kErrorTypeValidation, "unknown option '%s'", name.data);
- goto end;
+ return rv;
}
-end:
return rv;
}
@@ -139,47 +150,9 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error
FUNC_API_SINCE(9)
{
int scope = 0;
- if (opts->scope.type == kObjectTypeString) {
- if (!strcmp(opts->scope.data.string.data, "local")) {
- scope = OPT_LOCAL;
- } else if (!strcmp(opts->scope.data.string.data, "global")) {
- scope = OPT_GLOBAL;
- } else {
- api_set_error(err, kErrorTypeValidation, "invalid scope: must be 'local' or 'global'");
- return;
- }
- } else if (HAS_KEY(opts->scope)) {
- api_set_error(err, kErrorTypeValidation, "invalid value for key: scope");
- return;
- }
-
int opt_type = SREQ_GLOBAL;
void *to = NULL;
-
- if (opts->win.type == kObjectTypeInteger) {
- opt_type = SREQ_WIN;
- to = find_window_by_handle((int)opts->win.data.integer, err);
- } else if (HAS_KEY(opts->win)) {
- api_set_error(err, kErrorTypeValidation, "invalid value for key: win");
- return;
- }
-
- if (opts->buf.type == kObjectTypeInteger) {
- scope = OPT_LOCAL;
- opt_type = SREQ_BUF;
- to = find_buffer_by_handle((int)opts->buf.data.integer, err);
- } else if (HAS_KEY(opts->buf)) {
- api_set_error(err, kErrorTypeValidation, "invalid value for key: buf");
- return;
- }
-
- if (HAS_KEY(opts->scope) && HAS_KEY(opts->buf)) {
- api_set_error(err, kErrorTypeValidation, "scope and buf cannot be used together");
- return;
- }
-
- if (HAS_KEY(opts->win) && HAS_KEY(opts->buf)) {
- api_set_error(err, kErrorTypeValidation, "buf and win cannot be used together");
+ if (!validate_option_value_args(opts, &scope, &opt_type, &to, err)) {
return;
}
@@ -204,7 +177,7 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error
return;
}
- set_option_value_for(name.data, numval, stringval, scope, opt_type, to, err);
+ access_option_value_for(name.data, &numval, &stringval, scope, opt_type, to, false, err);
}
/// Gets the option information for all options.
@@ -441,7 +414,7 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object
}
}
- int numval = 0;
+ long numval = 0;
char *stringval = NULL;
if (flags & SOPT_BOOL) {
@@ -486,66 +459,30 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object
? 0 : (type == SREQ_GLOBAL)
? OPT_GLOBAL : OPT_LOCAL;
- set_option_value_for(name.data, numval, stringval,
- opt_flags, type, to, err);
+ access_option_value_for(name.data, &numval, &stringval, opt_flags, type, to, false, err);
});
}
-void set_option_value_for(char *key, long numval, char *stringval, int opt_flags, int opt_type,
- void *from, Error *err)
+static int access_option_value(char *key, long *numval, char **stringval, int opt_flags, bool get,
+ Error *err)
{
- switchwin_T switchwin;
- aco_save_T aco;
-
- try_start();
- switch (opt_type) {
- case SREQ_WIN:
- if (switch_win_noblock(&switchwin, (win_T *)from, win_find_tabpage((win_T *)from), true)
- == FAIL) {
- restore_win_noblock(&switchwin, true);
+ if (get) {
+ return get_option_value(key, numval, stringval, opt_flags);
+ } else {
+ char *errmsg;
+ if ((errmsg = set_option_value(key, *numval, *stringval, opt_flags))) {
if (try_end(err)) {
- return;
+ return 0;
}
- api_set_error(err,
- kErrorTypeException,
- "Problem while switching windows");
- return;
- }
- set_option_value_err(key, numval, stringval, opt_flags, err);
- restore_win_noblock(&switchwin, true);
- break;
- case SREQ_BUF:
- aucmd_prepbuf(&aco, (buf_T *)from);
- set_option_value_err(key, numval, stringval, opt_flags, err);
- aucmd_restbuf(&aco);
- break;
- case SREQ_GLOBAL:
- set_option_value_err(key, numval, stringval, opt_flags, err);
- break;
- }
-
- if (ERROR_SET(err)) {
- return;
- }
-
- try_end(err);
-}
-static void set_option_value_err(char *key, long numval, char *stringval, int opt_flags, Error *err)
-{
- char *errmsg;
-
- if ((errmsg = set_option_value(key, numval, stringval, opt_flags))) {
- if (try_end(err)) {
- return;
+ api_set_error(err, kErrorTypeException, "%s", errmsg);
}
-
- api_set_error(err, kErrorTypeException, "%s", errmsg);
+ return 0;
}
}
-int get_option_value_for(char *key, long *numval, char **stringval, int opt_flags, int opt_type,
- void *from, Error *err)
+static int access_option_value_for(char *key, long *numval, char **stringval, int opt_flags,
+ int opt_type, void *from, bool get, Error *err)
{
switchwin_T switchwin;
aco_save_T aco;
@@ -565,19 +502,23 @@ int get_option_value_for(char *key, long *numval, char **stringval, int opt_flag
"Problem while switching windows");
return result;
}
- result = get_option_value(key, numval, stringval, opt_flags);
+ result = access_option_value(key, numval, stringval, opt_flags, get, err);
restore_win_noblock(&switchwin, true);
break;
case SREQ_BUF:
aucmd_prepbuf(&aco, (buf_T *)from);
- result = get_option_value(key, numval, stringval, opt_flags);
+ result = access_option_value(key, numval, stringval, opt_flags, get, err);
aucmd_restbuf(&aco);
break;
case SREQ_GLOBAL:
- result = get_option_value(key, numval, stringval, opt_flags);
+ result = access_option_value(key, numval, stringval, opt_flags, get, err);
break;
}
+ if (ERROR_SET(err)) {
+ return result;
+ }
+
try_end(err);
return result;
diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim
index c55ba391a5..cf90e416c4 100644
--- a/src/nvim/testdir/test_mksession.vim
+++ b/src/nvim/testdir/test_mksession.vim
@@ -363,21 +363,29 @@ func Test_mkview_open_folds()
call append(0, ['a', 'b', 'c'])
1,3fold
+ write! Xtestfile
+
+ call assert_notequal(-1, foldclosed(1))
+ call assert_notequal(-1, foldclosed(2))
+ call assert_notequal(-1, foldclosed(3))
+
+ " Save the view with folds closed
+ mkview! Xtestview
+
" zR affects 'foldlevel', make sure the option is applied after the folds
" have been recreated.
+ " Open folds to ensure they get closed when restoring the view
normal zR
- write! Xtestfile
call assert_equal(-1, foldclosed(1))
call assert_equal(-1, foldclosed(2))
call assert_equal(-1, foldclosed(3))
- mkview! Xtestview
source Xtestview
- call assert_equal(-1, foldclosed(1))
- call assert_equal(-1, foldclosed(2))
- call assert_equal(-1, foldclosed(3))
+ call assert_notequal(-1, foldclosed(1))
+ call assert_notequal(-1, foldclosed(2))
+ call assert_notequal(-1, foldclosed(3))
call delete('Xtestview')
call delete('Xtestfile')