diff options
-rw-r--r-- | CMakeLists.txt | 33 | ||||
-rw-r--r-- | cmake/LuaHelpers.cmake | 4 | ||||
-rw-r--r-- | runtime/autoload/remote/host.vim | 1 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 20 | ||||
-rw-r--r-- | src/nvim/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/nvim/eval.c | 33 | ||||
-rw-r--r-- | src/nvim/misc2.c | 5 | ||||
-rw-r--r-- | src/nvim/ops.c | 19 | ||||
-rw-r--r-- | src/nvim/option.c | 19 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 4 | ||||
-rw-r--r-- | src/nvim/syntax.c | 3 | ||||
-rw-r--r-- | src/nvim/version.c | 14 | ||||
-rw-r--r-- | test/functional/legacy/file_perm_spec.lua | 42 | ||||
-rw-r--r-- | test/functional/legacy/set_spec.lua | 15 | ||||
-rw-r--r-- | test/functional/ui/highlight_spec.lua | 41 | ||||
-rw-r--r-- | test/unit/os/fs_spec.lua | 19 |
16 files changed, 222 insertions, 51 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1abc05f0da..317d2a1a5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -300,9 +300,6 @@ include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS}) find_package(Msgpack 1.0.0 REQUIRED) include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS}) -find_package(LuaJit REQUIRED) -include_directories(SYSTEM ${LUAJIT_INCLUDE_DIRS}) - find_package(Unibilium REQUIRED) include_directories(SYSTEM ${UNIBILIUM_INCLUDE_DIRS}) @@ -477,18 +474,24 @@ if(BUSTED_PRG) add_custom_target(benchmark-prereqs DEPENDS ${BENCHMARK_PREREQS}) - add_custom_target(unittest - COMMAND ${CMAKE_COMMAND} - -DBUSTED_PRG=${BUSTED_PRG} - -DLUA_PRG=${LUA_PRG} - -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR} - -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE} - -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test - -DBUILD_DIR=${CMAKE_BINARY_DIR} - -DTEST_TYPE=unit - -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake - DEPENDS ${UNITTEST_PREREQS} - ${TEST_TARGET_ARGS}) + check_lua_module(${LUA_PRG} "ffi" LUA_HAS_FFI) + if(LUA_HAS_FFI) + add_custom_target(unittest + COMMAND ${CMAKE_COMMAND} + -DBUSTED_PRG=${BUSTED_PRG} + -DLUA_PRG=${LUA_PRG} + -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR} + -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE} + -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test + -DBUILD_DIR=${CMAKE_BINARY_DIR} + -DTEST_TYPE=unit + -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake + DEPENDS ${UNITTEST_PREREQS} + ${TEST_TARGET_ARGS}) + else() + message(WARNING "The Luajit ffi is not available in ${LUA_PRG}" + ", disabling unit tests") + endif() add_custom_target(functionaltest COMMAND ${CMAKE_COMMAND} diff --git a/cmake/LuaHelpers.cmake b/cmake/LuaHelpers.cmake index b1e67e0ca7..32f7e46a57 100644 --- a/cmake/LuaHelpers.cmake +++ b/cmake/LuaHelpers.cmake @@ -8,8 +8,6 @@ function(check_lua_module LUA_PRG_PATH MODULE RESULT_VAR) RESULT_VARIABLE module_missing ERROR_QUIET) if(module_missing) - message(STATUS - "[${LUA_PRG_PATH}] The '${MODULE}' lua package is required for building Neovim") set(${RESULT_VAR} False PARENT_SCOPE) else() set(${RESULT_VAR} True PARENT_SCOPE) @@ -29,6 +27,8 @@ function(check_lua_deps LUA_PRG_PATH MODULES RESULT_VAR) foreach(module ${MODULES}) check_lua_module(${LUA_PRG_PATH} ${module} has_module) if(NOT has_module) + message(STATUS + "[${LUA_PRG_PATH}] The '${module}' lua package is required for building Neovim") set(${RESULT_VAR} False PARENT_SCOPE) return() endif() diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim index 8faeaed2ea..a63c6a923b 100644 --- a/runtime/autoload/remote/host.vim +++ b/runtime/autoload/remote/host.vim @@ -140,6 +140,7 @@ function! s:RegistrationCommands(host) abort call remote#host#RegisterClone(host_id, a:host) let pattern = s:plugin_patterns[a:host] let paths = globpath(&rtp, 'rplugin/'.a:host.'/'.pattern, 0, 1) + let paths = map(paths, 'tr(v:val,"\\","/")') " Normalize slashes #4795 if empty(paths) return [] endif diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 87b90900cb..eebdabd154 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2051,6 +2051,7 @@ serverlist() String get a list of available servers setbufvar({expr}, {varname}, {val}) set {varname} in buffer {expr} to {val} setcharsearch({dict}) Dict set character search from {dict} setcmdpos({pos}) Number set cursor position in command-line +setfperm({fname}, {mode} Number set {fname} file permissions to {mode} setline({lnum}, {line}) Number set line {lnum} to {line} setloclist({nr}, {list}[, {action}[, {title}]]) Number modify location list using {list} @@ -3628,6 +3629,8 @@ getfperm({fname}) *getfperm()* < This will hopefully (from a security point of view) display the string "rw-r--r--" or even "rw-------". + For setting permissions use |setfperm()|. + getftime({fname}) *getftime()* The result is a Number, which is the last modification time of the given file {fname}. The value is measured as seconds @@ -5866,6 +5869,23 @@ setcmdpos({pos}) *setcmdpos()* Returns 0 when successful, 1 when not editing the command line. +setfperm({fname}, {mode}) *setfperm()* *chmod* + Set the file permissions for {fname} to {mode}. + {mode} must be a string with 9 characters. It is of the form + "rwxrwxrwx", where each group of "rwx" flags represent, in + turn, the permissions of the owner of the file, the group the + file belongs to, and other users. A '-' character means the + permission is off, any other character means on. Multi-byte + characters are not supported. + + For example "rw-r-----" means read-write for the user, + readable by the group, not accessible by others. "xx-x-----" + would do the same thing. + + Returns non-zero for success, zero for failure. + + To read permissions see |getfperm()|. + setline({lnum}, {text}) *setline()* Set line {lnum} of the current buffer to {text}. To insert lines use |append()|. diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 6b2ce08d36..172643091a 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -231,7 +231,6 @@ endif() list(APPEND NVIM_LINK_LIBRARIES ${LIBUV_LIBRARIES} ${MSGPACK_LIBRARIES} - ${LUAJIT_LIBRARIES} ${LIBVTERM_LIBRARIES} ${LIBTERMKEY_LIBRARIES} ${UNIBILIUM_LIBRARIES} diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 201a71facb..96c008b0e0 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6877,6 +6877,7 @@ static struct fst { { "setbufvar", 3, 3, f_setbufvar }, { "setcharsearch", 1, 1, f_setcharsearch }, { "setcmdpos", 1, 1, f_setcmdpos }, + { "setfperm", 2, 2, f_setfperm }, { "setline", 2, 2, f_setline }, { "setloclist", 2, 4, f_setloclist }, { "setmatches", 1, 1, f_setmatches }, @@ -14446,6 +14447,38 @@ static void f_setcmdpos(typval_T *argvars, typval_T *rettv) rettv->vval.v_number = set_cmdline_pos(pos); } + +/// "setfperm({fname}, {mode})" function +static void f_setfperm(typval_T *argvars, typval_T *rettv) +{ + rettv->vval.v_number = 0; + + char_u *fname = get_tv_string_chk(&argvars[0]); + if (fname == NULL) { + return; + } + + char_u modebuf[NUMBUFLEN]; + char_u *mode_str = get_tv_string_buf_chk(&argvars[1], modebuf); + if (mode_str == NULL) { + return; + } + if (STRLEN(mode_str) != 9) { + EMSG2(_(e_invarg2), mode_str); + return; + } + + int mask = 1; + int mode = 0; + for (int i = 8; i >= 0; i--) { + if (mode_str[i] != '-') { + mode |= mask; + } + mask = mask << 1; + } + rettv->vval.v_number = os_setperm(fname, mode) == OK; +} + /* * "setline()" function */ diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c index 4b64de1be0..368f83cfb5 100644 --- a/src/nvim/misc2.c +++ b/src/nvim/misc2.c @@ -467,11 +467,12 @@ bool put_bytes(FILE *fd, uintmax_t number, size_t len) } /// Writes time_t to file "fd" in 8 bytes. -void put_time(FILE *fd, time_t time_) +/// @returns FAIL when the write failed. +int put_time(FILE *fd, time_t time_) { uint8_t buf[8]; time_to_bytes(time_, buf); - (void)fwrite(buf, sizeof(uint8_t), ARRAY_SIZE(buf), fd); + return fwrite(buf, sizeof(uint8_t), ARRAY_SIZE(buf), fd) == 1 ? OK : FAIL; } /// Writes time_t to "buf[8]". diff --git a/src/nvim/ops.c b/src/nvim/ops.c index eda963ff77..adfd0424f0 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5372,11 +5372,10 @@ void cursor_pos_info(dict_T *dict) } } - // Don't shorten this message, the user asked for it. bom_count = bomb_size(); if (bom_count > 0) { vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff), - _("(+%" PRId64 " for BOM)"), (int64_t)byte_count); + _("(+%" PRId64 " for BOM)"), (int64_t)bom_count); } if (dict == NULL) { p = p_shm; @@ -5387,20 +5386,18 @@ void cursor_pos_info(dict_T *dict) } if (dict != NULL) { + // Don't shorten this message, the user asked for it. dict_add_nr_str(dict, "words", word_count, NULL); dict_add_nr_str(dict, "chars", char_count, NULL); dict_add_nr_str(dict, "bytes", byte_count + bom_count, NULL); - if (l_VIsual_active) { - dict_add_nr_str(dict, "visual_bytes", byte_count_cursor, NULL); - dict_add_nr_str(dict, "visual_chars", char_count_cursor, NULL); - dict_add_nr_str(dict, "visual_words", word_count_cursor, NULL); - } else { - dict_add_nr_str(dict, "cursor_bytes", byte_count_cursor, NULL); - dict_add_nr_str(dict, "cursor_chars", char_count_cursor, NULL); - dict_add_nr_str(dict, "cursor_words", word_count_cursor, NULL); + dict_add_nr_str(dict, l_VIsual_active ? "visual_bytes" : "cursor_bytes", + byte_count_cursor, NULL); + dict_add_nr_str(dict, l_VIsual_active ? "visual_chars" : "cursor_chars", + char_count_cursor, NULL); + dict_add_nr_str(dict, l_VIsual_active ? "visual_words" : "cursor_words", + word_count_cursor, NULL); } - } } /// Check if the default register (used in an unnamed paste) should be a diff --git a/src/nvim/option.c b/src/nvim/option.c index 2f22c245dd..45ebb4fa4c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1639,18 +1639,21 @@ do_set ( && STRNCMP(s, newval, i) == 0 && (!(flags & P_COMMA) || s[i] == ',' - || s[i] == NUL)) + || s[i] == NUL)) { break; - /* Count backslashes. Only a comma with an - * even number of backslashes before it is - * recognized as a separator */ - if (s > origval && s[-1] == '\\') - ++bs; - else + } + // Count backslashes. Only a comma with an even number of + // backslashes or a single backslash preceded by a comma + // before it is recognized as a separator + if ((s > origval + 1 && s[-1] == '\\' && s[-2] != ',') + || (s == origval + 1 && s[-1] == '\\')) { + bs++; + } else { bs = 0; + } } - /* do not add if already there */ + // do not add if already there if ((adding || prepending) && *s) { prepending = FALSE; adding = FALSE; diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 49a74cf0d1..143a7160b0 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -111,8 +111,8 @@ int os_nodetype(const char *name) #endif uv_stat_t statbuf; - if (os_stat(name, &statbuf) == 0) { - return NODE_NORMAL; + if (0 != os_stat(name, &statbuf)) { + return NODE_NORMAL; // File doesn't exist. } #ifndef WIN32 diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 9a5484704e..1f9dbd8228 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6972,6 +6972,9 @@ set_hl_attr ( || at_en.rgb_sp_color != -1 || at_en.cterm_ae_attr != 0 || at_en.rgb_ae_attr != 0) { sgp->sg_attr = get_attr_entry(&at_en); + } else { + // If all the fields are cleared, clear the attr field back to default value + sgp->sg_attr = 0; } } diff --git a/src/nvim/version.c b/src/nvim/version.c index 82a15f9833..23bfca6221 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -163,12 +163,12 @@ static int included_patches[] = { // 1524 NA // 1523 NA // 1522 NA - // 1521, + 1521, // 1520 NA // 1519 NA // 1518 NA // 1517 NA - // 1516, + 1516, // 1515 NA // 1514 NA 1513, @@ -623,7 +623,7 @@ static int included_patches[] = { // 1064, // 1063 NA // 1062 NA - // 1061, + 1061, // 1060 NA 1059, // 1058, @@ -634,7 +634,7 @@ static int included_patches[] = { // 1053, 1052, // 1051, - // 1050, + 1050, 1049, 1048, 1047, @@ -650,7 +650,7 @@ static int included_patches[] = { 1037, 1036, 1035, - // 1034, + 1034, // 1033 NA 1032, // 1031 NA, @@ -666,8 +666,8 @@ static int included_patches[] = { // 1021 NA // 1020 NA // 1019 NA - // 1018, - // 1017, + 1018, + 1017, // 1016 NA 1015, // 1014 NA diff --git a/test/functional/legacy/file_perm_spec.lua b/test/functional/legacy/file_perm_spec.lua new file mode 100644 index 0000000000..cabeecdc9c --- /dev/null +++ b/test/functional/legacy/file_perm_spec.lua @@ -0,0 +1,42 @@ +-- Test getting and setting file permissions. +require('os') + +local helpers = require('test.functional.helpers') +local clear, call, eq = helpers.clear, helpers.call, helpers.eq +local neq, exc_exec = helpers.neq, helpers.exc_exec + +describe('Test getting and setting file permissions', function() + local tempfile = os.tmpname() + + before_each(function() + os.remove(tempfile) + clear() + end) + + it('file permissions', function() + eq('', call('getfperm', tempfile)) + eq(0, call('setfperm', tempfile, 'r------')) + + call('writefile', {'one'}, tempfile) + eq(9, call('len', call('getfperm', tempfile))) + + eq(1, call('setfperm', tempfile, 'rwx------')) + if helpers.os_name == 'windows' then + eq('rw-rw-rw-', call('getfperm', tempfile)) + else + eq('rwx------', call('getfperm', tempfile)) + end + + eq(1, call('setfperm', tempfile, 'r--r--r--')) + eq('r--r--r--', call('getfperm', tempfile)) + + local err = exc_exec(('call setfperm("%s", "---")'):format(tempfile)) + neq(err:find('E475:'), nil) + + eq(1, call('setfperm', tempfile, 'rwx------')) + end) + + after_each(function() + os.remove(tempfile) + end) +end) diff --git a/test/functional/legacy/set_spec.lua b/test/functional/legacy/set_spec.lua index f81fcd3700..f2c907084e 100644 --- a/test/functional/legacy/set_spec.lua +++ b/test/functional/legacy/set_spec.lua @@ -7,6 +7,21 @@ local clear, execute, eval, eq = describe(':set', function() before_each(clear) + it('handles backslash properly', function() + execute('set iskeyword=a,b,c') + execute('set iskeyword+=d') + eq('a,b,c,d', eval('&iskeyword')) + + execute([[set iskeyword+=\\,e]]) + eq([[a,b,c,d,\,e]], eval('&iskeyword')) + + execute('set iskeyword-=e') + eq([[a,b,c,d,\]], eval('&iskeyword')) + + execute([[set iskeyword-=\]]) + eq('a,b,c,d', eval('&iskeyword')) + end) + it('recognizes a trailing comma with +=', function() execute('set wildignore=*.png,') execute('set wildignore+=*.jpg') diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index 0229b8bbf7..85fca4d7ca 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -302,6 +302,47 @@ describe('Default highlight groups', function() {1:-- INSERT --} | ]], {[1] = {foreground = Screen.colors.Red, background = Screen.colors.Green}}) end) + it('can be cleared by assigning NONE', function() + execute('syn keyword TmpKeyword neovim') + execute('hi link TmpKeyword ErrorMsg') + insert('neovim') + screen:expect([[ + {1:neovi^m} | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + | + ]], { + [1] = {foreground = Screen.colors.White, background = Screen.colors.Red} + }) + execute("hi ErrorMsg term=NONE cterm=NONE ctermfg=NONE ctermbg=NONE" + .. " gui=NONE guifg=NONE guibg=NONE guisp=NONE") + screen:expect([[ + neovi^m | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + ~ | + | + ]], {}) + end) end) describe('guisp (special/undercurl)', function() diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua index 71b5e7f576..857a5001f1 100644 --- a/test/unit/os/fs_spec.lua +++ b/test/unit/os/fs_spec.lua @@ -14,6 +14,8 @@ local to_cstr = helpers.to_cstr local OK = helpers.OK local FAIL = helpers.FAIL local NULL = helpers.NULL +local NODE_NORMAL = 0 +local NODE_WRITABLE = 1 cimport('unistd.h') cimport('./src/nvim/os/shell.h') @@ -357,15 +359,12 @@ describe('fs function', function() local function os_file_exists(filename) return fs.os_file_exists((to_cstr(filename))) end - local function os_rename(path, new_path) return fs.os_rename((to_cstr(path)), (to_cstr(new_path))) end - local function os_remove(path) return fs.os_remove((to_cstr(path))) end - local function os_open(path, flags, mode) return fs.os_open((to_cstr(path)), flags, mode) end @@ -484,6 +483,20 @@ describe('fs function', function() assert.is_true(0 <= (os_open(existing_file, ffi.C.kO_RDWR, 0))) end) end) + + describe('os_nodetype', function() + before_each(function() + os.remove('non-existing-file') + end) + + it('returns NODE_NORMAL for non-existing file', function() + eq(NODE_NORMAL, fs.os_nodetype(to_cstr('non-existing-file'))) + end) + + it('returns NODE_WRITABLE for /dev/stderr', function() + eq(NODE_WRITABLE, fs.os_nodetype(to_cstr('/dev/stderr'))) + end) + end) end) describe('folder operations', function() |