aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--CONTRIBUTING.md24
-rw-r--r--cmake.deps/cmake/BuildGettext.cmake4
-rw-r--r--cmake.deps/cmake/BuildLibiconv.cmake4
-rw-r--r--cmake.deps/cmake/BuildLibuv.cmake4
-rw-r--r--cmake.deps/cmake/BuildLibvterm.cmake4
-rw-r--r--cmake.deps/cmake/BuildLpeg.cmake4
-rw-r--r--cmake.deps/cmake/BuildLua.cmake4
-rw-r--r--cmake.deps/cmake/BuildLuajit.cmake4
-rw-r--r--cmake.deps/cmake/BuildLuv.cmake8
-rw-r--r--cmake.deps/cmake/BuildMsgpack.cmake4
-rw-r--r--cmake.deps/cmake/BuildTreesitter.cmake4
-rw-r--r--cmake.deps/cmake/BuildTreesitterParsers.cmake8
-rw-r--r--cmake.deps/cmake/BuildUnibilium.cmake4
-rw-r--r--cmake.deps/cmake/GetBinaryDeps.cmake4
-rw-r--r--cmake/Deps.cmake25
-rw-r--r--runtime/doc/builtin.txt9
-rw-r--r--runtime/filetype.lua7
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua9
-rw-r--r--runtime/lua/vim/lsp/client.lua4
-rw-r--r--runtime/syntax/vim.vim24
-rw-r--r--src/nvim/eval.c40
-rw-r--r--src/nvim/eval.lua9
-rw-r--r--src/nvim/eval/typval.c2
-rw-r--r--test/functional/lua/filetype_spec.lua24
-rw-r--r--test/old/testdir/test_functions.vim51
26 files changed, 193 insertions, 99 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 009b562953..c3b37cbb35 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -309,7 +309,7 @@ ExternalProject_Add(uncrustify
CMAKE_ARGS ${DEPS_CMAKE_ARGS}
CMAKE_CACHE_ARGS ${DEPS_CMAKE_CACHE_ARGS}
EXCLUDE_FROM_ALL TRUE
- ${EXTERNALPROJECT_OPTIONS})
+ DOWNLOAD_NO_PROGRESS TRUE)
option(USE_BUNDLED_BUSTED "Use bundled busted" ON)
if(USE_BUNDLED_BUSTED)
@@ -322,7 +322,7 @@ if(USE_BUNDLED_BUSTED)
BUILD_COMMAND ""
INSTALL_COMMAND ""
EXCLUDE_FROM_ALL TRUE
- ${EXTERNALPROJECT_OPTIONS})
+ DOWNLOAD_NO_PROGRESS TRUE)
else()
add_custom_target(lua-dev-deps)
endif()
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2f5c2cce5a..b10289a694 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -318,6 +318,30 @@ types, etc. See [:help dev-lua-doc][dev-lua-doc].
- Private functions usually should be underscore-prefixed (named "_foo", not "foo").
- Mark deprecated functions with `@deprecated`.
+Third-party dependencies
+------------------------
+
+To build Nvim using a different commit of a dependency change the appropriate
+URL in `cmake.deps/deps.txt`. For example, to use a different version of luajit
+replace the value in `LUAJIT_URL` with the wanted commit hash:
+
+```bash
+LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/<sha>.tar.gz
+```
+
+Set `DEPS_IGNORE_SHA` to `TRUE` in `cmake.deps/CMakeLists.txt` to skip hash
+check from cmake.
+
+Alternatively, you may point the URL as a local path where the repository is.
+This is convenient when bisecting a problem in a dependency with `git bisect`.
+This requires running `make distclean` the first time once to remove traces of
+the previous build. Hash checking is always skipped in this case regardless of
+`DEPS_IGNORE_SHA`.
+
+```bash
+LUAJIT_URL /home/user/luajit
+```
+
Reviewing
---------
diff --git a/cmake.deps/cmake/BuildGettext.cmake b/cmake.deps/cmake/BuildGettext.cmake
index 0d6b323fa2..c80a826f96 100644
--- a/cmake.deps/cmake/BuildGettext.cmake
+++ b/cmake.deps/cmake/BuildGettext.cmake
@@ -1,8 +1,6 @@
if(MSVC)
- get_sha(gettext ${DEPS_IGNORE_SHA})
+ get_externalproject_options(gettext ${DEPS_IGNORE_SHA})
ExternalProject_Add(gettext
- URL ${GETTEXT_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/gettext
PATCH_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/cmake/GettextCMakeLists.txt
diff --git a/cmake.deps/cmake/BuildLibiconv.cmake b/cmake.deps/cmake/BuildLibiconv.cmake
index f4d7ace2c6..93dc251166 100644
--- a/cmake.deps/cmake/BuildLibiconv.cmake
+++ b/cmake.deps/cmake/BuildLibiconv.cmake
@@ -1,8 +1,6 @@
if(MSVC)
- get_sha(libiconv ${DEPS_IGNORE_SHA})
+ get_externalproject_options(libiconv ${DEPS_IGNORE_SHA})
ExternalProject_Add(libiconv
- URL ${LIBICONV_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/libiconv
PATCH_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibiconvCMakeLists.txt
diff --git a/cmake.deps/cmake/BuildLibuv.cmake b/cmake.deps/cmake/BuildLibuv.cmake
index 98d78db8f1..aacee9fd4a 100644
--- a/cmake.deps/cmake/BuildLibuv.cmake
+++ b/cmake.deps/cmake/BuildLibuv.cmake
@@ -1,7 +1,5 @@
-get_sha(libuv ${DEPS_IGNORE_SHA})
+get_externalproject_options(libuv ${DEPS_IGNORE_SHA})
ExternalProject_Add(libuv
- URL ${LIBUV_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/libuv
CMAKE_ARGS ${DEPS_CMAKE_ARGS}
-D CMAKE_INSTALL_LIBDIR=lib
diff --git a/cmake.deps/cmake/BuildLibvterm.cmake b/cmake.deps/cmake/BuildLibvterm.cmake
index f928faad01..a3b59d9374 100644
--- a/cmake.deps/cmake/BuildLibvterm.cmake
+++ b/cmake.deps/cmake/BuildLibvterm.cmake
@@ -1,7 +1,5 @@
-get_sha(libvterm ${DEPS_IGNORE_SHA})
+get_externalproject_options(libvterm ${DEPS_IGNORE_SHA})
ExternalProject_Add(libvterm
- URL ${LIBVTERM_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/libvterm
PATCH_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibvtermCMakeLists.txt
diff --git a/cmake.deps/cmake/BuildLpeg.cmake b/cmake.deps/cmake/BuildLpeg.cmake
index e46a3cb16f..a8455a9976 100644
--- a/cmake.deps/cmake/BuildLpeg.cmake
+++ b/cmake.deps/cmake/BuildLpeg.cmake
@@ -1,7 +1,5 @@
-get_sha(lpeg ${DEPS_IGNORE_SHA})
+get_externalproject_options(lpeg ${DEPS_IGNORE_SHA})
ExternalProject_Add(lpeg
- URL ${LPEG_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/lpeg
PATCH_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/cmake/LpegCMakeLists.txt
diff --git a/cmake.deps/cmake/BuildLua.cmake b/cmake.deps/cmake/BuildLua.cmake
index e47720de47..9a9f90db31 100644
--- a/cmake.deps/cmake/BuildLua.cmake
+++ b/cmake.deps/cmake/BuildLua.cmake
@@ -40,10 +40,8 @@ set(LUA_CONFIGURE_COMMAND
-i ${DEPS_BUILD_DIR}/src/lua/src/luaconf.h)
set(LUA_INSTALL_TOP_ARG "INSTALL_TOP=${DEPS_INSTALL_DIR}")
-get_sha(lua ${DEPS_IGNORE_SHA})
+get_externalproject_options(lua ${DEPS_IGNORE_SHA})
ExternalProject_Add(lua
- URL ${LUA_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/lua
CONFIGURE_COMMAND "${LUA_CONFIGURE_COMMAND}"
BUILD_IN_SOURCE 1
diff --git a/cmake.deps/cmake/BuildLuajit.cmake b/cmake.deps/cmake/BuildLuajit.cmake
index de9add43ca..c5068d6986 100644
--- a/cmake.deps/cmake/BuildLuajit.cmake
+++ b/cmake.deps/cmake/BuildLuajit.cmake
@@ -11,10 +11,8 @@ function(BuildLuajit)
set(_luajit_TARGET "luajit")
endif()
- get_sha(luajit ${DEPS_IGNORE_SHA})
+ get_externalproject_options(luajit ${DEPS_IGNORE_SHA})
ExternalProject_Add(${_luajit_TARGET}
- URL ${LUAJIT_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/${_luajit_TARGET}
CONFIGURE_COMMAND "${_luajit_CONFIGURE_COMMAND}"
BUILD_IN_SOURCE 1
diff --git a/cmake.deps/cmake/BuildLuv.cmake b/cmake.deps/cmake/BuildLuv.cmake
index bf87cde68b..beadf028ee 100644
--- a/cmake.deps/cmake/BuildLuv.cmake
+++ b/cmake.deps/cmake/BuildLuv.cmake
@@ -17,21 +17,17 @@ if(CMAKE_GENERATOR MATCHES "Unix Makefiles" AND
list(APPEND LUV_CMAKE_ARGS -D CMAKE_MAKE_PROGRAM=gmake)
endif()
-get_sha(lua_compat53 ${DEPS_IGNORE_SHA})
+get_externalproject_options(lua_compat53 ${DEPS_IGNORE_SHA})
ExternalProject_Add(lua_compat53
- URL ${LUA_COMPAT53_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/lua_compat53
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
${EXTERNALPROJECT_OPTIONS})
-get_sha(luv ${DEPS_IGNORE_SHA})
+get_externalproject_options(luv ${DEPS_IGNORE_SHA})
ExternalProject_Add(luv
DEPENDS lua_compat53
- URL ${LUV_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/luv
SOURCE_DIR ${DEPS_BUILD_DIR}/src/luv
CMAKE_ARGS ${DEPS_CMAKE_ARGS} ${LUV_CMAKE_ARGS}
diff --git a/cmake.deps/cmake/BuildMsgpack.cmake b/cmake.deps/cmake/BuildMsgpack.cmake
index 8cc648db13..190a37bbc6 100644
--- a/cmake.deps/cmake/BuildMsgpack.cmake
+++ b/cmake.deps/cmake/BuildMsgpack.cmake
@@ -1,7 +1,5 @@
-get_sha(msgpack ${DEPS_IGNORE_SHA})
+get_externalproject_options(msgpack ${DEPS_IGNORE_SHA})
ExternalProject_Add(msgpack
- URL ${MSGPACK_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/msgpack
CMAKE_ARGS ${DEPS_CMAKE_ARGS}
-D MSGPACK_BUILD_TESTS=OFF
diff --git a/cmake.deps/cmake/BuildTreesitter.cmake b/cmake.deps/cmake/BuildTreesitter.cmake
index 839b7b19c3..6757185425 100644
--- a/cmake.deps/cmake/BuildTreesitter.cmake
+++ b/cmake.deps/cmake/BuildTreesitter.cmake
@@ -1,7 +1,5 @@
-get_sha(treesitter ${DEPS_IGNORE_SHA})
+get_externalproject_options(treesitter ${DEPS_IGNORE_SHA})
ExternalProject_Add(treesitter
- URL ${TREESITTER_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/treesitter
PATCH_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/cmake/TreesitterCMakeLists.txt
diff --git a/cmake.deps/cmake/BuildTreesitterParsers.cmake b/cmake.deps/cmake/BuildTreesitterParsers.cmake
index d251d65354..892e5928a5 100644
--- a/cmake.deps/cmake/BuildTreesitterParsers.cmake
+++ b/cmake.deps/cmake/BuildTreesitterParsers.cmake
@@ -15,14 +15,10 @@ function(BuildTSParser)
set(TS_CMAKE_FILE TreesitterParserCMakeLists.txt)
endif()
- set(NAME treesitter-${TS_LANG})
- string(TOUPPER "TREESITTER_${TS_LANG}_URL" URL_VARNAME)
- set(URL ${${URL_VARNAME}})
+ set(NAME treesitter_${TS_LANG})
- get_sha(treesitter_${TS_LANG} ${DEPS_IGNORE_SHA})
+ get_externalproject_options(${NAME} ${DEPS_IGNORE_SHA})
ExternalProject_Add(${NAME}
- URL ${URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/${NAME}
PATCH_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/cmake/${TS_CMAKE_FILE}
diff --git a/cmake.deps/cmake/BuildUnibilium.cmake b/cmake.deps/cmake/BuildUnibilium.cmake
index 5cbf8a961b..bb9c8f183b 100644
--- a/cmake.deps/cmake/BuildUnibilium.cmake
+++ b/cmake.deps/cmake/BuildUnibilium.cmake
@@ -1,7 +1,5 @@
-get_sha(unibilium ${DEPS_IGNORE_SHA})
+get_externalproject_options(unibilium ${DEPS_IGNORE_SHA})
ExternalProject_Add(unibilium
- URL ${UNIBILIUM_URL}
- ${EXTERNALPROJECT_URL_HASH}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/unibilium
CMAKE_ARGS ${DEPS_CMAKE_ARGS}
CMAKE_CACHE_ARGS ${DEPS_CMAKE_CACHE_ARGS}
diff --git a/cmake.deps/cmake/GetBinaryDeps.cmake b/cmake.deps/cmake/GetBinaryDeps.cmake
index 2f1e237588..6d3ce48e4f 100644
--- a/cmake.deps/cmake/GetBinaryDeps.cmake
+++ b/cmake.deps/cmake/GetBinaryDeps.cmake
@@ -24,7 +24,7 @@ function(GetBinaryDep)
BUILD_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}
COMMAND "${_gettool_INSTALL_COMMAND}"
- ${EXTERNALPROJECT_OPTIONS})
+ DOWNLOAD_NO_PROGRESS TRUE)
endfunction()
# Download executable and move it to DEPS_BIN_DIR
@@ -49,5 +49,5 @@ function(GetExecutable)
BUILD_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}
COMMAND ${CMAKE_COMMAND} -E copy <DOWNLOADED_FILE> ${DEPS_BIN_DIR}
- ${EXTERNALPROJECT_OPTIONS})
+ DOWNLOAD_NO_PROGRESS TRUE)
endfunction()
diff --git a/cmake/Deps.cmake b/cmake/Deps.cmake
index 4700d08427..2e9a78ee22 100644
--- a/cmake/Deps.cmake
+++ b/cmake/Deps.cmake
@@ -19,7 +19,6 @@ if(APPLE)
endif()
set(DEPS_CMAKE_CACHE_ARGS -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES})
-set(EXTERNALPROJECT_OPTIONS DOWNLOAD_NO_PROGRESS TRUE)
# MAKE_PRG
if(UNIX)
@@ -55,10 +54,24 @@ if(CMAKE_OSX_ARCHITECTURES)
endforeach()
endif()
-function(get_sha name ignore)
- unset(EXTERNALPROJECT_URL_HASH)
- if(NOT ${ignore})
- string(TOUPPER ${name} name_allcaps)
- set(EXTERNALPROJECT_URL_HASH URL_HASH SHA256=${${name_allcaps}_SHA256} PARENT_SCOPE)
+function(get_externalproject_options name DEPS_IGNORE_SHA)
+ string(TOUPPER ${name} name_allcaps)
+ set(url ${${name_allcaps}_URL})
+
+ set(EXTERNALPROJECT_OPTIONS DOWNLOAD_NO_PROGRESS TRUE)
+
+ if(EXISTS ${url})
+ list(APPEND EXTERNALPROJECT_OPTIONS
+ GIT_REPOSITORY ${${name_allcaps}_URL})
+ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.18)
+ list(APPEND EXTERNALPROJECT_OPTIONS GIT_REMOTE_UPDATE_STRATEGY CHECKOUT)
+ endif()
+ else()
+ list(APPEND EXTERNALPROJECT_OPTIONS URL ${${name_allcaps}_URL})
+ if(NOT ${DEPS_IGNORE_SHA})
+ list(APPEND EXTERNALPROJECT_OPTIONS URL_HASH SHA256=${${name_allcaps}_SHA256})
+ endif()
endif()
+
+ set(EXTERNALPROJECT_OPTIONS ${EXTERNALPROJECT_OPTIONS} PARENT_SCOPE)
endfunction()
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index be81451d08..c88513ad75 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -7411,7 +7411,8 @@ slice({expr}, {start} [, {end}]) *slice()*
Similar to using a |slice| "expr[start : end]", but "end" is
used exclusive. And for a string the indexes are used as
character indexes instead of byte indexes.
- Also, composing characters are not counted.
+ Also, composing characters are treated as a part of the
+ preceding base character.
When {end} is omitted the slice continues to the last item.
When {end} is -1 the last item is omitted.
Returns an empty value if {start} or {end} are invalid.
@@ -7758,8 +7759,8 @@ strcharpart({src}, {start} [, {len} [, {skipcc}]]) *strcharpart()*
of byte index and length.
When {skipcc} is omitted or zero, composing characters are
counted separately.
- When {skipcc} set to 1, Composing characters are ignored,
- similar to |slice()|.
+ When {skipcc} set to 1, composing characters are treated as a
+ part of the preceding base character, similar to |slice()|.
When a character index is used where a character does not
exist it is omitted and counted as one character. For
example: >vim
@@ -7773,7 +7774,7 @@ strchars({string} [, {skipcc}]) *strchars()*
in String {string}.
When {skipcc} is omitted or zero, composing characters are
counted separately.
- When {skipcc} set to 1, Composing characters are ignored.
+ When {skipcc} set to 1, composing characters are ignored.
|strcharlen()| always does this.
Returns zero on error.
diff --git a/runtime/filetype.lua b/runtime/filetype.lua
index 3f2a7c2960..4880ed55ef 100644
--- a/runtime/filetype.lua
+++ b/runtime/filetype.lua
@@ -11,7 +11,12 @@ vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile', 'StdinReadPost' }, {
if not vim.api.nvim_buf_is_valid(args.buf) then
return
end
- local ft, on_detect = vim.filetype.match({ filename = args.match, buf = args.buf })
+ local ft, on_detect = vim.filetype.match({
+ -- The unexpanded file name is needed here. #27914
+ -- Neither args.file nor args.match are guaranteed to be unexpanded.
+ filename = vim.fn.bufname(args.buf),
+ buf = args.buf,
+ })
if not ft then
-- Generic configuration file used as fallback
ft = require('vim.filetype.detect').conf(args.file, args.buf)
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index da251f89ad..caddd4dde2 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -8800,7 +8800,8 @@ function vim.fn.sinh(expr) end
--- Similar to using a |slice| "expr[start : end]", but "end" is
--- used exclusive. And for a string the indexes are used as
--- character indexes instead of byte indexes.
---- Also, composing characters are not counted.
+--- Also, composing characters are treated as a part of the
+--- preceding base character.
--- When {end} is omitted the slice continues to the last item.
--- When {end} is -1 the last item is omitted.
--- Returns an empty value if {start} or {end} are invalid.
@@ -9208,8 +9209,8 @@ function vim.fn.strcharlen(string) end
--- of byte index and length.
--- When {skipcc} is omitted or zero, composing characters are
--- counted separately.
---- When {skipcc} set to 1, Composing characters are ignored,
---- similar to |slice()|.
+--- When {skipcc} set to 1, composing characters are treated as a
+--- part of the preceding base character, similar to |slice()|.
--- When a character index is used where a character does not
--- exist it is omitted and counted as one character. For
--- example: >vim
@@ -9229,7 +9230,7 @@ function vim.fn.strcharpart(src, start, len, skipcc) end
--- in String {string}.
--- When {skipcc} is omitted or zero, composing characters are
--- counted separately.
---- When {skipcc} set to 1, Composing characters are ignored.
+--- When {skipcc} set to 1, composing characters are ignored.
--- |strcharlen()| always does this.
---
--- Returns zero on error.
diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua
index d48be131f3..b06fab7319 100644
--- a/runtime/lua/vim/lsp/client.lua
+++ b/runtime/lua/vim/lsp/client.lua
@@ -693,7 +693,7 @@ function Client:_request(method, params, handler, bufnr)
local request = { type = 'pending', bufnr = bufnr, method = method }
self.requests[request_id] = request
api.nvim_exec_autocmds('LspRequest', {
- buffer = bufnr,
+ buffer = api.nvim_buf_is_valid(bufnr) and bufnr or nil,
modeline = false,
data = { client_id = self.id, request_id = request_id, request = request },
})
@@ -804,7 +804,7 @@ function Client:_cancel_request(id)
if request and request.type == 'pending' then
request.type = 'cancel'
api.nvim_exec_autocmds('LspRequest', {
- buffer = request.bufnr,
+ buffer = api.nvim_buf_is_valid(request.bufnr) and request.bufnr or nil,
modeline = false,
data = { client_id = self.id, request_id = id, request = request },
})
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index d37c54a63f..640102562b 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -197,7 +197,7 @@ syn keyword vimFTOption contained detect indent off on plugin
" Augroup : vimAugroupError removed because long augroups caused sync'ing problems. {{{2
" ======= : Trade-off: Increasing synclines with slower editing vs augroup END error checking.
-syn cluster vimAugroupList contains=@vimCmdList,vimFilter,vimFunc,vimLineComment,vimSpecFile,vimOper,vimNumber,vimOperParen,vimComment,vim9Comment,vimString,vimSubst,vimRegister,vimCmplxRepeat,vimRegion,vimNotation,vimCtrlChar,vimFuncVar,vimContinue
+syn cluster vimAugroupList contains=@vimCmdList,vimFilter,vimFunc,vimLineComment,vimSpecFile,vimOper,vimNumber,vimOperParen,vimComment,vim9Comment,vimString,vimSubst,vimRegister,vimCmplxRepeat,vimNotation,vimCtrlChar,vimFuncVar,vimContinue
syn match vimAugroup "\<aug\%[roup]\>" contains=vimAugroupKey,vimAugroupBang skipwhite nextgroup=vimAugroupBang,vimAutoCmdGroup
if exists("g:vimsyn_folding") && g:vimsyn_folding =~# 'a'
syn region vimAugroup fold start="\<aug\%[roup]\>\ze\s\+\%([eE][nN][dD]\)\@!\S\+" matchgroup=vimAugroupKey end="\<aug\%[roup]\>\ze\s\+[eE][nN][dD]\>" contains=vimAutoCmd,@vimAugroupList,vimAugroupkey skipwhite nextgroup=vimAugroupEnd
@@ -219,7 +219,7 @@ syn cluster vimOperGroup contains=vimEnvvar,vimFunc,vimFuncVar,vimOper,vimOperPa
syn match vimOper "||\|&&\|[-+*/%.!]" skipwhite nextgroup=vimString,vimSpecFile
syn match vimOper "\%#=1\(==\|!=\|>=\|<=\|=\~\|!\~\|>\|<\|=\|!\~#\)[?#]\{0,2}" skipwhite nextgroup=vimString,vimSpecFile
syn match vimOper "\(\<is\|\<isnot\)[?#]\{0,2}\>" skipwhite nextgroup=vimString,vimSpecFile
-syn region vimOperParen matchgroup=vimParenSep start="(" end=")" contains=vimoperStar,@vimOperGroup
+syn region vimOperParen matchgroup=vimParenSep start="(" end=")" contains=@vimOperGroup
syn region vimOperParen matchgroup=vimSep start="#\={" end="}" contains=@vimOperGroup nextgroup=vimVar,vimFuncVar
if !exists("g:vimsyn_noerror") && !exists("g:vimsyn_noopererror")
syn match vimOperError ")"
@@ -272,8 +272,6 @@ endif
syn match vimFuncVar contained "a:\%(\K\k*\|\d\+\)\>"
syn match vimFuncBlank contained "\s\+"
-syn keyword vimPattern contained start skip end
-
" Types: {{{2
" =====
" vimTypes : new for vim9
@@ -292,8 +290,7 @@ syn cluster vimType contains=vimType,vimCompoundType,vimUserType
" Keymaps: (Vim Project Addition) {{{2
" =======
-" TODO: autogenerated vimCommand keyword list does not handle all abbreviations
-" : handle Vim9 script comments when something like #13104 is merged
+" TODO: handle Vim9 script comments when something like #13104 is merged
syn match vimKeymapStart "^" contained skipwhite nextgroup=vimKeymapLhs,vimKeymapLineComment
syn match vimKeymapLhs "\S\+" contained skipwhite nextgroup=vimKeymapRhs contains=vimNotation
syn match vimKeymapRhs "\S\+" contained skipwhite nextgroup=vimKeymapTailComment contains=vimNotation
@@ -314,7 +311,7 @@ syn match vimSpecFileMod "\(:[phtre]\)\+" contained
" User-Specified Commands: {{{2
" =======================
-syn cluster vimUserCmdList contains=@vimCmdList,vimCmplxRepeat,vimComment,vim9Comment,vimCtrlChar,vimEscapeBrace,vimFunc,vimNotation,vimNumber,vimOper,vimRegion,vimRegister,vimSpecFile,vimString,vimSubst,vimSubstRep,vimSubstRange
+syn cluster vimUserCmdList contains=@vimCmdList,vimCmplxRepeat,vimComment,vim9Comment,vimCtrlChar,vimEscapeBrace,vimFunc,vimNotation,vimNumber,vimOper,vimRegister,vimSpecFile,vimString,vimSubst,vimSubstRep,vimSubstRange
syn keyword vimUserCommand contained com[mand]
syn match vimUserCmd "\<com\%[mand]!\=\>.*$" contains=vimUserAttrb,vimUserAttrbError,vimUserCommand,@vimUserCmdList,vimComFilter
syn match vimUserAttrbError contained "-\a\+\ze\s"
@@ -463,6 +460,7 @@ VimFoldh syn region vimLetHereDoc matchgroup=vimLetHereDocStart start='=<<\s*\%(
" For: {{{2
" ===
syn keyword vimFor for skipwhite nextgroup=vimVar,vimVarList
+
" Abbreviations: {{{2
" =============
" GEN_SYN_VIM: vimCommand abbrev, START_STR='syn keyword vimAbb', END_STR='skipwhite nextgroup=vimMapMod,vimMapLhs'
@@ -616,7 +614,6 @@ if has("conceal")
endif
syn match vimSyntax "\<sy\%[ntax]\>" contains=vimCommand skipwhite nextgroup=vimSynType,vimComment,vim9Comment
-syn match vimAuSyntax contained "\s+sy\%[ntax]" contains=vimCommand skipwhite nextgroup=vimSynType,vimComment,vim9Comment
syn cluster vimFuncBodyList add=vimSyntax
" Syntax: case {{{2
@@ -984,7 +981,6 @@ if !exists("skip_vim_syntax_inits")
hi def link vimHiAttribList vimError
hi def link vimHiCtermError vimError
hi def link vimHiKeyError vimError
- hi def link vimKeyCodeError vimError
hi def link vimMapModErr vimError
hi def link vimSubstFlagErr vimError
hi def link vimSynCaseError vimError
@@ -997,12 +993,9 @@ if !exists("skip_vim_syntax_inits")
hi def link vimAugroupBang vimBang
hi def link vimAugroupError vimError
hi def link vimAugroupKey vimCommand
- hi def link vimAuHighlight vimHighlight
- hi def link vimAutoCmdOpt vimOption
hi def link vimAutoCmd vimCommand
hi def link vimAutoEvent Type
hi def link vimAutoCmdMod Special
- hi def link vimAutoSet vimCommand
hi def link vimBang vimOper
hi def link vimBehaveBang vimBang
hi def link vimBehaveModel vimBehave
@@ -1026,7 +1019,6 @@ if !exists("skip_vim_syntax_inits")
hi def link vimEchohlNone vimGroup
hi def link vimEchohl vimCommand
hi def link vimElseIfErr Error
- hi def link vimElseif vimCondHL
hi def link vimEndfunction vimCommand
hi def link vimEnddef vimCommand
hi def link vimEnvvar PreProc
@@ -1035,7 +1027,6 @@ if !exists("skip_vim_syntax_inits")
hi def link vimFBVar vimVar
hi def link vimFgBgAttrib vimHiAttrib
hi def link vimFuncEcho vimCommand
- hi def link vimFold Folded
hi def link vimFor vimCommand
hi def link vimFTCmd vimCommand
hi def link vimFTOption vimSynType
@@ -1072,13 +1063,10 @@ if !exists("skip_vim_syntax_inits")
hi def link vimHiStartStop vimHiTerm
hi def link vimHiTerm Type
hi def link vimHLGroup vimGroup
- hi def link vimHLMod PreProc
hi def link vimInsert vimString
hi def link vimIskSep Delimiter
- hi def link vimKeyCode vimSpecFile
hi def link vimKeymapLineComment vimComment
hi def link vimKeymapTailComment vimComment
- hi def link vimKeyword Statement
hi def link vimLet vimCommand
hi def link vimLetHereDoc vimString
hi def link vimLetHereDocStart Special
@@ -1109,7 +1097,6 @@ if !exists("skip_vim_syntax_inits")
hi def link vimNumber Number
hi def link vimOperError Error
hi def link vimOper Operator
- hi def link vimOperStar vimOper
hi def link vimOption PreProc
hi def link vimParenSep Delimiter
hi def link vimPatSepErr vimError
@@ -1131,7 +1118,6 @@ if !exists("skip_vim_syntax_inits")
hi def link vimSpecFile Identifier
hi def link vimSpecFileMod vimSpecFile
hi def link vimSpecial Type
- hi def link vimStatement Statement
hi def link vimStringCont vimString
hi def link vimString String
hi def link vimStringEnd vimString
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index f5f9c4f77b..9e15ea9369 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -7519,29 +7519,44 @@ int check_luafunc_name(const char *const str, const bool paren)
return (int)(p - str);
}
-/// Return the character "str[index]" where "index" is the character index. If
-/// "index" is out of range NULL is returned.
+/// Return the character "str[index]" where "index" is the character index,
+/// including composing characters.
+/// If "index" is out of range NULL is returned.
char *char_from_string(const char *str, varnumber_T index)
{
- size_t nbyte = 0;
varnumber_T nchar = index;
- if (str == NULL || index < 0) {
+ if (str == NULL) {
return NULL;
}
size_t slen = strlen(str);
- while (nchar > 0 && nbyte < slen) {
- nbyte += (size_t)utf_ptr2len(str + nbyte);
- nchar--;
+
+ // do the same as for a list: a negative index counts from the end
+ if (index < 0) {
+ int clen = 0;
+
+ for (size_t nbyte = 0; nbyte < slen; clen++) {
+ nbyte += (size_t)utfc_ptr2len(str + nbyte);
+ }
+ nchar = clen + index;
+ if (nchar < 0) {
+ // unlike list: index out of range results in empty string
+ return NULL;
+ }
+ }
+
+ size_t nbyte = 0;
+ for (; nchar > 0 && nbyte < slen; nchar--) {
+ nbyte += (size_t)utfc_ptr2len(str + nbyte);
}
if (nbyte >= slen) {
return NULL;
}
- return xmemdupz(str + nbyte, (size_t)utf_ptr2len(str + nbyte));
+ return xmemdupz(str + nbyte, (size_t)utfc_ptr2len(str + nbyte));
}
/// Get the byte index for character index "idx" in string "str" with length
-/// "str_len".
+/// "str_len". Composing characters are included.
/// If going over the end return "str_len".
/// If "idx" is negative count from the end, -1 is the last character.
/// When going over the start return -1.
@@ -7552,7 +7567,7 @@ static ssize_t char_idx2byte(const char *str, size_t str_len, varnumber_T idx)
if (nchar >= 0) {
while (nchar > 0 && nbyte < str_len) {
- nbyte += (size_t)utf_ptr2len(str + nbyte);
+ nbyte += (size_t)utfc_ptr2len(str + nbyte);
nchar--;
}
} else {
@@ -7569,7 +7584,8 @@ static ssize_t char_idx2byte(const char *str, size_t str_len, varnumber_T idx)
return (ssize_t)nbyte;
}
-/// Return the slice "str[first:last]" using character indexes.
+/// Return the slice "str[first : last]" using character indexes. Composing
+/// characters are included.
///
/// @param exclusive true for slice().
///
@@ -7591,7 +7607,7 @@ char *string_slice(const char *str, varnumber_T first, varnumber_T last, bool ex
end_byte = char_idx2byte(str, slen, last);
if (!exclusive && end_byte >= 0 && end_byte < (ssize_t)slen) {
// end index is inclusive
- end_byte += utf_ptr2len(str + end_byte);
+ end_byte += utfc_ptr2len(str + end_byte);
}
}
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 7df4ab71ef..6a3eabc467 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -10485,7 +10485,8 @@ M.funcs = {
Similar to using a |slice| "expr[start : end]", but "end" is
used exclusive. And for a string the indexes are used as
character indexes instead of byte indexes.
- Also, composing characters are not counted.
+ Also, composing characters are treated as a part of the
+ preceding base character.
When {end} is omitted the slice continues to the last item.
When {end} is -1 the last item is omitted.
Returns an empty value if {start} or {end} are invalid.
@@ -10957,8 +10958,8 @@ M.funcs = {
of byte index and length.
When {skipcc} is omitted or zero, composing characters are
counted separately.
- When {skipcc} set to 1, Composing characters are ignored,
- similar to |slice()|.
+ When {skipcc} set to 1, composing characters are treated as a
+ part of the preceding base character, similar to |slice()|.
When a character index is used where a character does not
exist it is omitted and counted as one character. For
example: >vim
@@ -10981,7 +10982,7 @@ M.funcs = {
in String {string}.
When {skipcc} is omitted or zero, composing characters are
counted separately.
- When {skipcc} set to 1, Composing characters are ignored.
+ When {skipcc} set to 1, composing characters are ignored.
|strcharlen()| always does this.
Returns zero on error.
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 9328f53dbd..eb8c89c36e 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -859,7 +859,7 @@ int tv_list_slice_or_index(list_T *list, bool range, varnumber_T n1_arg, varnumb
// A list index out of range is an error.
if (!range) {
if (verbose) {
- semsg(_(e_list_index_out_of_range_nr), (int64_t)n1);
+ semsg(_(e_list_index_out_of_range_nr), (int64_t)n1_arg);
}
return FAIL;
}
diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua
index 8b0e0a8beb..3ef650a1d2 100644
--- a/test/functional/lua/filetype_spec.lua
+++ b/test/functional/lua/filetype_spec.lua
@@ -5,6 +5,10 @@ local api = helpers.api
local clear = helpers.clear
local pathroot = helpers.pathroot
local command = helpers.command
+local mkdir = helpers.mkdir
+local rmdir = helpers.rmdir
+local write_file = helpers.write_file
+local uv = vim.uv
local root = pathroot()
@@ -161,10 +165,30 @@ describe('vim.filetype', function()
end)
describe('filetype.lua', function()
+ before_each(function()
+ mkdir('Xfiletype')
+ end)
+
+ after_each(function()
+ rmdir('Xfiletype')
+ end)
+
it('does not override user autocommands that set filetype #20333', function()
clear({
args = { '--clean', '--cmd', 'autocmd BufRead *.md set filetype=notmarkdown', 'README.md' },
})
eq('notmarkdown', api.nvim_get_option_value('filetype', {}))
end)
+
+ it('uses unexpanded path for matching when editing a symlink #27914', function()
+ mkdir('Xfiletype/.config')
+ mkdir('Xfiletype/actual')
+ write_file('Xfiletype/actual/config', '')
+ uv.fs_symlink(assert(uv.fs_realpath('Xfiletype/actual')), 'Xfiletype/.config/git')
+ finally(function()
+ uv.fs_unlink('Xfiletype/.config/git')
+ end)
+ clear({ args = { '--clean', 'Xfiletype/.config/git/config' } })
+ eq('gitconfig', api.nvim_get_option_value('filetype', {}))
+ end)
end)
diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim
index 3f9ac94782..fdcd93a264 100644
--- a/test/old/testdir/test_functions.vim
+++ b/test/old/testdir/test_functions.vim
@@ -3610,4 +3610,55 @@ func Test_glob_extended_mswin()
call delete('Xtestglob', 'rf')
endfunc
+" Tests for the slice() function.
+func Test_slice()
+ let lines =<< trim END
+ call assert_equal([1, 2, 3, 4, 5], slice(range(6), 1))
+ call assert_equal([2, 3, 4, 5], slice(range(6), 2))
+ call assert_equal([2, 3], slice(range(6), 2, 4))
+ call assert_equal([0, 1, 2, 3], slice(range(6), 0, 4))
+ call assert_equal([1, 2, 3], slice(range(6), 1, 4))
+ call assert_equal([1, 2, 3, 4], slice(range(6), 1, -1))
+ call assert_equal([1, 2], slice(range(6), 1, -3))
+ call assert_equal([1], slice(range(6), 1, -4))
+ call assert_equal([], slice(range(6), 1, -5))
+ call assert_equal([], slice(range(6), 1, -6))
+
+ call assert_equal(0z1122334455, slice(0z001122334455, 1))
+ call assert_equal(0z22334455, slice(0z001122334455, 2))
+ call assert_equal(0z2233, slice(0z001122334455, 2, 4))
+ call assert_equal(0z00112233, slice(0z001122334455, 0, 4))
+ call assert_equal(0z112233, slice(0z001122334455, 1, 4))
+ call assert_equal(0z11223344, slice(0z001122334455, 1, -1))
+ call assert_equal(0z1122, slice(0z001122334455, 1, -3))
+ call assert_equal(0z11, slice(0z001122334455, 1, -4))
+ call assert_equal(0z, slice(0z001122334455, 1, -5))
+ call assert_equal(0z, slice(0z001122334455, 1, -6))
+
+ call assert_equal('12345', slice('012345', 1))
+ call assert_equal('2345', slice('012345', 2))
+ call assert_equal('23', slice('012345', 2, 4))
+ call assert_equal('0123', slice('012345', 0, 4))
+ call assert_equal('123', slice('012345', 1, 4))
+ call assert_equal('1234', slice('012345', 1, -1))
+ call assert_equal('12', slice('012345', 1, -3))
+ call assert_equal('1', slice('012345', 1, -4))
+ call assert_equal('', slice('012345', 1, -5))
+ call assert_equal('', slice('012345', 1, -6))
+
+ #" Composing chars are treated as a part of the preceding base char.
+ call assert_equal('β̳́γ̳̂δ̳̃ε̳̄ζ̳̅', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1))
+ call assert_equal('γ̳̂δ̳̃ε̳̄ζ̳̅', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(2))
+ call assert_equal('γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(2, 4))
+ call assert_equal('ὰ̳β̳́γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(0, 4))
+ call assert_equal('β̳́γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, 4))
+ call assert_equal('β̳́γ̳̂δ̳̃ε̳̄', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -1))
+ call assert_equal('β̳́γ̳̂', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -3))
+ call assert_equal('β̳́', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -4))
+ call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -5))
+ call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -6))
+ END
+ call CheckLegacyAndVim9Success(lines)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab