diff options
66 files changed, 2064 insertions, 1106 deletions
diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index d668c7a7cc..8a5c53a139 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -25,7 +25,7 @@ runs: # if it makes the expression below simpler. hashFiles() has a timer that # will fail the job if it times out, which can happen if there are too many # files to search through. - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: .deps key: ${{ env.CACHE_KEY }}-${{ steps.image.outputs.version }}-${{ hashFiles('cmake**', diff --git a/CMakeLists.txt b/CMakeLists.txt index d64d1fc723..6dedbfd714 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,13 +37,8 @@ include(Util) # Variables #------------------------------------------------------------------------------- set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack) -set(GENERATED_RUNTIME_DIR ${PROJECT_BINARY_DIR}/runtime) set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches) -# GENERATED_RUNTIME_DIR -set(GENERATED_HELP_TAGS ${GENERATED_RUNTIME_DIR}/doc/tags) -set(GENERATED_SYN_VIM ${GENERATED_RUNTIME_DIR}/syntax/vim/generated.vim) - set_directory_properties(PROPERTIES EP_PREFIX "${DEPS_BUILD_DIR}") @@ -60,6 +55,12 @@ if(${CMAKE_VERSION} VERSION_LESS 3.20) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) endif() +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.26) + set(COPY_DIRECTORY copy_directory_if_different) +else() + set(COPY_DIRECTORY copy_directory) +endif() + # Prefer our bundled versions of dependencies. if(DEFINED ENV{DEPS_BUILD_DIR}) set(DEPS_PREFIX "$ENV{DEPS_BUILD_DIR}/usr" CACHE PATH "Path prefix for finding dependencies") @@ -231,7 +232,7 @@ set(STYLUA_DIRS runtime scripts src test) add_glob_target( TARGET lintlua-luacheck - COMMAND $<TARGET_FILE:nvim> + COMMAND $<TARGET_FILE:nvim_bin> FLAGS -ll ${PROJECT_SOURCE_DIR}/test/lua_runner.lua ${CMAKE_BINARY_DIR}/usr luacheck -q GLOB_DIRS runtime scripts src test GLOB_PAT *.lua @@ -258,8 +259,8 @@ add_glob_target( TOUCH_STRATEGY PER_DIR) add_custom_target(lintcommit - COMMAND $<TARGET_FILE:nvim> -u NONE -l ${PROJECT_SOURCE_DIR}/scripts/lintcommit.lua main) -add_dependencies(lintcommit nvim) + COMMAND $<TARGET_FILE:nvim_bin> -u NONE -l ${PROJECT_SOURCE_DIR}/scripts/lintcommit.lua main) +add_dependencies(lintcommit nvim_bin) add_custom_target(lint) add_dependencies(lint lintc lintlua lintsh lintcommit) @@ -280,6 +281,9 @@ install_helper( FILES ${CMAKE_SOURCE_DIR}/src/man/nvim.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) +add_custom_target(nvim ALL) +add_dependencies(nvim nvim_bin nvim_runtime_deps nvim_runtime) + add_subdirectory(src/nvim) add_subdirectory(cmake.config) add_subdirectory(runtime) diff --git a/INSTALL.md b/INSTALL.md index 3b882ab6c9..2246058bca 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -155,17 +155,6 @@ Python (`:python`) support is installable via the package manager on Debian unst sudo apt-get install python3-neovim -If installing via appimage, the following commands may be helpful in updating default paths: - - # CUSTOM_NVIM_PATH=/usr/local/bin/nvim.appimage - # Set the above with the correct path, then run the rest of the commands: - set -u - sudo update-alternatives --install /usr/bin/ex ex "${CUSTOM_NVIM_PATH}" 110 - sudo update-alternatives --install /usr/bin/vi vi "${CUSTOM_NVIM_PATH}" 110 - sudo update-alternatives --install /usr/bin/view view "${CUSTOM_NVIM_PATH}" 110 - sudo update-alternatives --install /usr/bin/vim vim "${CUSTOM_NVIM_PATH}" 110 - sudo update-alternatives --install /usr/bin/vimdiff vimdiff "${CUSTOM_NVIM_PATH}" 110 - ### Exherbo Linux Exhereses for scm and released versions are currently available in repository `::medvid`. Python client (with GTK+ GUI included) and Qt5 GUI are also available as suggestions: @@ -336,17 +325,6 @@ If you're using an older version Ubuntu you must use: For instructions to install the Python modules, see [`:help provider-python`]. -If you want to use Neovim for some (or all) of the editor alternatives, use the following commands: - - sudo update-alternatives --install /usr/bin/vi vi /usr/bin/nvim 60 - sudo update-alternatives --config vi - sudo update-alternatives --install /usr/bin/vim vim /usr/bin/nvim 60 - sudo update-alternatives --config vim - sudo update-alternatives --install /usr/bin/editor editor /usr/bin/nvim 60 - sudo update-alternatives --config editor - -Note, however, that special interfaces, like `view` for `nvim -R`, are not supported. (See [#1646](https://github.com/neovim/neovim/issues/1646) and [#2008](https://github.com/neovim/neovim/pull/2008).) - ### Void-Linux Neovim can be installed using the xbps package manager diff --git a/cmake.config/CMakeLists.txt b/cmake.config/CMakeLists.txt index d333cc216a..f3cc803cf5 100644 --- a/cmake.config/CMakeLists.txt +++ b/cmake.config/CMakeLists.txt @@ -148,7 +148,7 @@ foreach(BUILD_TYPE Debug Release RelWithDebInfo MinSizeRel) set(GEN_RHS "${CMAKE_C_FLAGS_${BUILD_TYPE_UPPER}} ") string(APPEND VERSION_STRING "$<${GEN_CONFIG}:${GEN_RHS}>") - set(GEN_RHS "$<$<BOOL:$<TARGET_PROPERTY:nvim,INTERPROCEDURAL_OPTIMIZATION_${BUILD_TYPE_UPPER}>>:${CMAKE_C_COMPILE_OPTIONS_IPO}>") + set(GEN_RHS "$<$<BOOL:$<TARGET_PROPERTY:nvim_bin,INTERPROCEDURAL_OPTIMIZATION_${BUILD_TYPE_UPPER}>>:${CMAKE_C_COMPILE_OPTIONS_IPO}>") string(APPEND VERSION_STRING "$<${GEN_CONFIG}:${GEN_RHS}>") endforeach() @@ -161,7 +161,7 @@ function(append_target_expression) "" ${ARGN}) - set(TARGET_EXPRESSION "$<TARGET_PROPERTY:nvim,${ARG_PROPERTY}>") + set(TARGET_EXPRESSION "$<TARGET_PROPERTY:nvim_bin,${ARG_PROPERTY}>") if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.15) set(TARGET_EXPRESSION "$<REMOVE_DUPLICATES:${TARGET_EXPRESSION}>") endif() diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index a44713d4ce..c9655ad9b9 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -1,5 +1,9 @@ -set(SYN_VIM_GENERATOR ${PROJECT_SOURCE_DIR}/src/nvim/generators/gen_vimvim.lua) +set(GENERATED_RUNTIME_DIR ${PROJECT_BINARY_DIR}/runtime) + +set(GENERATED_HELP_TAGS ${GENERATED_RUNTIME_DIR}/doc/tags) set(GENERATED_PACKAGE_DIR ${GENERATED_RUNTIME_DIR}/pack/dist/opt) +set(GENERATED_SYN_VIM ${GENERATED_RUNTIME_DIR}/syntax/vim/generated.vim) +set(SYN_VIM_GENERATOR ${PROJECT_SOURCE_DIR}/src/nvim/generators/gen_vimvim.lua) file(MAKE_DIRECTORY ${GENERATED_RUNTIME_DIR}/syntax/vim) @@ -32,7 +36,7 @@ foreach(PACKAGE ${PACKAGES}) COMMAND "${PROJECT_BINARY_DIR}/bin/nvim" -u NONE -i NONE -e --headless -c "helptags doc" -c quit DEPENDS - nvim + nvim_bin nvim_runtime_deps WORKING_DIRECTORY "${GENERATED_PACKAGE_DIR}/${PACKNAME}" ) @@ -66,7 +70,7 @@ add_custom_command(OUTPUT ${GENERATED_HELP_TAGS} COMMAND "${PROJECT_BINARY_DIR}/bin/nvim" -u NONE -i NONE -e --headless -c "helptags ++t doc" -c quit DEPENDS - nvim + nvim_bin nvim_runtime_deps WORKING_DIRECTORY "${GENERATED_RUNTIME_DIR}" ) @@ -81,7 +85,7 @@ add_custom_target(doc_html ) add_custom_target( - runtime ALL + nvim_runtime DEPENDS ${GENERATED_SYN_VIM} ${GENERATED_HELP_TAGS} diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index b5a49f6002..f37d349fd8 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -2594,8 +2594,8 @@ nvim_buf_get_extmark_by_id({buffer}, {ns_id}, {id}, {*opts}) *nvim_buf_get_extmarks()* nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {*opts}) - Gets |extmarks| (including |signs|) in "traversal order" from a |charwise| - region defined by buffer positions (inclusive, 0-indexed |api-indexing|). + Gets |extmarks| in "traversal order" from a |charwise| region defined by + buffer positions (inclusive, 0-indexed |api-indexing|). Region can be given as (row,col) tuples, or valid extmark ids (whose positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1) @@ -2611,6 +2611,10 @@ nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {*opts}) the `overlap` option might be useful. Otherwise only the start position of an extmark will be considered. + Note: legacy signs placed through the |:sign| commands are implemented as + extmarks and will show up here. Their details array will contain a + `sign_name` field. + Example: >lua local api = vim.api local pos = api.nvim_win_get_cursor(0) @@ -2742,7 +2746,9 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {*opts}) text around the mark was deleted and then restored by undo. Defaults to true. • invalidate : boolean that indicates whether to hide the - extmark if the entirety of its range is deleted. If + extmark if the entirety of its range is deleted. For + hidden marks, an "invalid" key is added to the "details" + array of |nvim_buf_get_extmarks()| and family. If "undo_restore" is false, the extmark is deleted instead. • priority: a priority value for the highlight group or sign attribute. For example treesitter highlighting uses a diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 24474255ba..433a9fc266 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -3576,8 +3576,8 @@ vim.version.cmp({v1}, {v2}) *vim.version.cmp()* otherwise-equivalent versions. Parameters: ~ - • {v1} (`Version|number[]`) Version object. - • {v2} (`Version|number[]`) Version to compare with `v1` . + • {v1} (`Version|number[]|string`) Version object. + • {v2} (`Version|number[]|string`) Version to compare with `v1` . Return: ~ (`integer`) -1 if `v1 < v2`, 0 if `v1 == v2`, 1 if `v1 > v2`. @@ -3587,8 +3587,18 @@ vim.version.eq({v1}, {v2}) *vim.version.eq()* usage. Parameters: ~ - • {v1} (`Version|number[]`) - • {v2} (`Version|number[]`) + • {v1} (`Version|number[]|string`) + • {v2} (`Version|number[]|string`) + + Return: ~ + (`boolean`) + +vim.version.ge({v1}, {v2}) *vim.version.ge()* + Returns `true` if `v1 >= v2` . See |vim.version.cmp()| for usage. + + Parameters: ~ + • {v1} (`Version|number[]|string`) + • {v2} (`Version|number[]|string`) Return: ~ (`boolean`) @@ -3597,8 +3607,8 @@ vim.version.gt({v1}, {v2}) *vim.version.gt()* Returns `true` if `v1 > v2` . See |vim.version.cmp()| for usage. Parameters: ~ - • {v1} (`Version|number[]`) - • {v2} (`Version|number[]`) + • {v1} (`Version|number[]|string`) + • {v2} (`Version|number[]|string`) Return: ~ (`boolean`) @@ -3612,12 +3622,22 @@ vim.version.last({versions}) *vim.version.last()* Return: ~ (`Version?`) +vim.version.le({v1}, {v2}) *vim.version.le()* + Returns `true` if `v1 <= v2` . See |vim.version.cmp()| for usage. + + Parameters: ~ + • {v1} (`Version|number[]|string`) + • {v2} (`Version|number[]|string`) + + Return: ~ + (`boolean`) + vim.version.lt({v1}, {v2}) *vim.version.lt()* Returns `true` if `v1 < v2` . See |vim.version.cmp()| for usage. Parameters: ~ - • {v1} (`Version|number[]`) - • {v2} (`Version|number[]`) + • {v1} (`Version|number[]|string`) + • {v2} (`Version|number[]|string`) Return: ~ (`boolean`) @@ -3638,7 +3658,8 @@ vim.version.parse({version}, {opts}) *vim.version.parse()* "1.0", "0-x", "tmux 3.2a" into valid versions. Return: ~ - (`table?`) parsed_version Version object or `nil` if input is invalid. + (`Version?`) parsed_version Version object or `nil` if input is + invalid. See also: ~ • # https://semver.org/spec/v2.0.0.html @@ -3662,9 +3683,10 @@ vim.version.range({spec}) *vim.version.range()* print(r:has(vim.version())) -- check against current Nvim version < - Or use cmp(), eq(), lt(), and gt() to compare `.to` and `.from` directly: >lua - local r = vim.version.range('1.0.0 - 2.0.0') - print(vim.version.gt({1,0,3}, r.from) and vim.version.lt({1,0,3}, r.to)) + Or use cmp(), le(), lt(), ge(), gt(), and/or eq() to compare a version + against `.to` and `.from` directly: >lua + local r = vim.version.range('1.0.0 - 2.0.0') -- >=1.0, <2.0 + print(vim.version.ge({1,0,3}, r.from) and vim.version.lt({1,0,3}, r.to)) < Parameters: ~ diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index bc7619ad82..9ef9132c65 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -112,6 +112,11 @@ The following changes may require adaptations in user config or plugins. • 'termguicolors' is enabled by default when Nvim is able to determine that the host terminal emulator supports 24-bit color. +• Treesitter highlight groups have been renamed to be more in line with + upstream tree-sitter and Helix to make it easier to share queries. The full + list is documented in |treesitter-highlight-groups|. + + ============================================================================== BREAKING CHANGES IN HEAD *news-breaking-dev* @@ -161,7 +166,7 @@ The following new APIs and features were added. • |nvim_win_text_height()| computes the number of screen lines occupied by a range of text in a given window. -• |nvim_set_keymap()| and |nvim_del_keymap()| now support abbreviations. +• Mapping APIs now support abbreviations when mode short-name has suffix "a". • Better cmdline completion for string option value. |complete-set-option| @@ -291,6 +296,8 @@ The following new APIs and features were added. • Terminal buffers respond to OSC background and foreground requests. |default-autocmds| +• |vim.version.le()| and |vim.version.ge()| are added to |vim.version|. + ============================================================================== CHANGED FEATURES *news-changed* diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index 14dedbcbd9..d082aa8cc4 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -400,58 +400,115 @@ instance, to highlight comments differently per language: >vim hi @comment.lua guifg=DarkBlue hi link @comment.doc.java String < -The following captures are linked by default to standard |group-name|s: - -@text.literal Comment -@text.reference Identifier -@text.title Title -@text.uri Underlined -@text.underline Underlined -@text.todo Todo - -@comment Comment -@punctuation Delimiter - -@constant Constant -@constant.builtin Special -@constant.macro Define -@define Define -@macro Macro -@string String -@string.escape SpecialChar -@string.special SpecialChar -@character Character -@character.special SpecialChar -@number Number -@boolean Boolean -@float Float - -@function Function -@function.builtin Special -@function.macro Macro -@parameter Identifier -@method Function -@field Identifier -@property Identifier -@constructor Special - -@conditional Conditional -@repeat Repeat -@label Label -@operator Operator -@keyword Keyword -@exception Exception - -@variable Identifier -@type Type -@type.definition Typedef -@storageclass StorageClass -@structure Structure -@namespace Identifier -@include Include -@preproc PreProc -@debug Debug -@tag Tag +The following captures are linked by default to standard |group-name|s (use +|:Inspect| on a group to see the current link): + +@variable various variable names +@variable.builtin built-in variable names (e.g. `this`) +@variable.parameter parameters of a function +@variable.member object and struct fields + +@constant constant identifiers +@constant.builtin built-in constant values +@constant.macro constants defined by the preprocessor + +@module modules or namespaces +@module.builtin built-in modules or namespaces +@label GOTO and other labels (e.g. `label:` in C), including heredoc labels + +@string string literals +@string.documentation string documenting code (e.g. Python docstrings) +@string.regexp regular expressions +@string.escape escape sequences +@string.special other special strings (e.g. dates) +@string.special.symbol symbols or atoms +@string.special.path filenames +@string.special.url URIs (e.g. hyperlinks) + +@character character literals +@character.special special characters (e.g. wildcards) + +@boolean boolean literals +@number numeric literals +@number.float floating-point number literals + +@type type or class definitions and annotations +@type.builtin built-in types +@type.definition identifiers in type definitions (e.g. `typedef <type> <identifier>` in C) +@type.qualifier type qualifiers (e.g. `const`) + +@attribute attribute annotations (e.g. Python decorators) +@property the key in key/value pairs + +@function function definitions +@function.builtin built-in functions +@function.call function calls +@function.macro preprocessor macros + +@function.method method definitions +@function.method.call method calls + +@constructor constructor calls and definitions +@operator symbolic operators (e.g. `+` / `*`) + +@keyword keywords not fitting into specific categories +@keyword.coroutine keywords related to coroutines (e.g. `go` in Go, `async/await` in Python) +@keyword.function keywords that define a function (e.g. `func` in Go, `def` in Python) +@keyword.operator operators that are English words (e.g. `and` / `or`) +@keyword.import keywords for including modules (e.g. `import` / `from` in Python) +@keyword.storage modifiers that affect storage in memory or life-time +@keyword.repeat keywords related to loops (e.g. `for` / `while`) +@keyword.return keywords like `return` and `yield` +@keyword.debug keywords related to debugging +@keyword.exception keywords related to exceptions (e.g. `throw` / `catch`) + +@keyword.conditional keywords related to conditionals (e.g. `if` / `else`) +@keyword.conditional.ternary ternary operator (e.g. `?` / `:`) + +@keyword.directive various preprocessor directives and shebangs +@keyword.directive.define preprocessor definition directives + +@punctuation.delimiter delimiters (e.g. `;` / `.` / `,`) +@punctuation.bracket brackets (e.g. `()` / `{}` / `[]`) +@punctuation.special special symbols (e.g. `{}` in string interpolation) + +@comment line and block comments +@comment.documentation comments documenting code + +@comment.error error-type comments (e.g. `ERROR`, `FIXME`, `DEPRECATED:`) +@comment.warning warning-type comments (e.g. `WARNING:`, `FIX:`, `HACK:`) +@comment.todo todo-type comments (e.g. `TODO:`, `WIP:`, `FIXME:`) +@comment.note note-type comments (e.g. `NOTE:`, `INFO:`, `XXX`) + +@markup.strong bold text +@markup.italic italic text +@markup.strikethrough struck-through text +@markup.underline underlined text (only for literal underline markup!) + +@markup.heading headings, titles (including markers) + +@markup.quote block quotes +@markup.math math environments (e.g. `$ ... $` in LaTeX) +@markup.environment environments (e.g. in LaTeX) + +@markup.link text references, footnotes, citations, etc. +@markup.link.label link, reference descriptions +@markup.link.url URL-style links + +@markup.raw literal or verbatim text (e.g. inline code) +@markup.raw.block literal or verbatim text as a stand-alone block + +@markup.list list markers +@markup.list.checked checked todo-style list markers +@markup.list.unchecked unchecked todo-style list markers + +@diff.plus added text (for diff files) +@diff.minus deleted text (for diff files) +@diff.delta changed text (for diff files) + +@tag XML-style tag names (e.g. in XML, HTML, etc.) +@tag.attribute XML-style tag attributes +@tag.delimiter XML-style tag delimiters *treesitter-highlight-spell* The special `@spell` capture can be used to indicate that a node should be diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index 8546478935..c81420d1f2 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -228,6 +228,10 @@ the editor. however a UI might still use such options when rendering raw text sent from Nvim, like for |ui-cmdline|. +["chdir", path] ~ + The |current-directory| of the embedded Nvim process changed to + `path`. + ["mode_change", mode, mode_idx] ~ Editor mode changed. The `mode` parameter is a string representing the current mode. `mode_idx` is an index into the array emitted in diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 52a21587f4..fd49f63558 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -1033,21 +1033,44 @@ end --- ---@return string|nil # Deprecated message, or nil if no message was shown. function vim.deprecate(name, alternative, version, plugin, backtrace) + vim.validate { + name = { name, 'string' }, + alternative = { alternative, 'string', true }, + version = { version, 'string', true }, + plugin = { plugin, 'string', true }, + } + plugin = plugin or 'Nvim' + -- Only issue warning if feature is hard-deprecated as specified by MAINTAIN.md. - if plugin == nil then - local current_version = vim.version() - local deprecated_version = assert(vim.version.parse(version)) - local soft_deprecated_version = - { deprecated_version.major, deprecated_version.minor - 1, deprecated_version.patch } - local deprecate = vim.version.lt(current_version, soft_deprecated_version) - if deprecate then + -- e.g., when planned to be removed in version = '0.12' (soft-deprecated since 0.10-dev), + -- show warnings since 0.11, including 0.11-dev (hard_deprecated_since = 0.11-dev). + if plugin == 'Nvim' then + local current_version = vim.version() ---@type Version + local removal_version = assert(vim.version.parse(version)) + local is_hard_deprecated ---@type boolean + + if removal_version.minor > 0 then + local hard_deprecated_since = assert(vim.version._version({ + major = removal_version.major, + minor = removal_version.minor - 1, + patch = 0, + prerelease = 'dev', -- Show deprecation warnings in devel (nightly) version as well + })) + is_hard_deprecated = (current_version >= hard_deprecated_since) + else + -- Assume there will be no next minor version before bumping up the major version; + -- therefore we can always show a warning. + assert(removal_version.minor == 0, vim.inspect(removal_version)) + is_hard_deprecated = true + end + + if not is_hard_deprecated then return end end local msg = ('%s is deprecated'):format(name) - plugin = plugin or 'Nvim' - msg = alternative and ('%s, use %s instead.'):format(msg, alternative) or msg + msg = alternative and ('%s, use %s instead.'):format(msg, alternative) or (msg .. '.') msg = ('%s%s\nThis feature will be removed in %s version %s'):format( msg, (plugin == 'Nvim' and ' :help deprecated' or ''), diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua index 3f06d4fd43..f773ddd75c 100644 --- a/runtime/lua/vim/_meta/api.lua +++ b/runtime/lua/vim/_meta/api.lua @@ -323,8 +323,8 @@ function vim.api.nvim_buf_get_commands(buffer, opts) end --- @return integer[] function vim.api.nvim_buf_get_extmark_by_id(buffer, ns_id, id, opts) end ---- Gets `extmarks` (including `signs`) in "traversal order" from a `charwise` ---- region defined by buffer positions (inclusive, 0-indexed `api-indexing`). +--- Gets `extmarks` in "traversal order" from a `charwise` region defined by +--- buffer positions (inclusive, 0-indexed `api-indexing`). --- Region can be given as (row,col) tuples, or valid extmark ids (whose --- positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1) --- respectively, thus the following are equivalent: @@ -339,6 +339,9 @@ function vim.api.nvim_buf_get_extmark_by_id(buffer, ns_id, id, opts) end --- Note: when using extmark ranges (marks with a end_row/end_col position) --- the `overlap` option might be useful. Otherwise only the start position of --- an extmark will be considered. +--- Note: legacy signs placed through the `:sign` commands are implemented as +--- extmarks and will show up here. Their details array will contain a +--- `sign_name` field. --- Example: --- --- ```lua @@ -567,7 +570,9 @@ function vim.api.nvim_buf_line_count(buffer) end --- text around the mark was deleted and then restored by --- undo. Defaults to true. --- • invalidate : boolean that indicates whether to hide the ---- extmark if the entirety of its range is deleted. If +--- extmark if the entirety of its range is deleted. For +--- hidden marks, an "invalid" key is added to the "details" +--- array of `nvim_buf_get_extmarks()` and family. If --- "undo_restore" is false, the extmark is deleted instead. --- • priority: a priority value for the highlight group or sign --- attribute. For example treesitter highlighting uses a diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index a83c74fd7c..7e1803f640 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -267,6 +267,7 @@ local extension = { crdpro = 'chordpro', cho = 'chordpro', chordpro = 'chordpro', + ck = 'chuck', eni = 'cl', icl = 'clean', cljx = 'clojure', diff --git a/runtime/lua/vim/glob.lua b/runtime/lua/vim/glob.lua index 764200dd36..ad4a915a94 100644 --- a/runtime/lua/vim/glob.lua +++ b/runtime/lua/vim/glob.lua @@ -1,7 +1,11 @@ local lpeg = vim.lpeg +local P, S, V, R, B = lpeg.P, lpeg.S, lpeg.V, lpeg.R, lpeg.B +local C, Cc, Ct, Cf = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cf local M = {} +local pathsep = P('/') + --- Parses a raw glob into an |lua-lpeg| pattern. --- --- This uses glob semantics from LSP 3.17.0: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#pattern @@ -17,18 +21,8 @@ local M = {} ---@param pattern string The raw glob pattern ---@return vim.lpeg.Pattern pattern An |lua-lpeg| representation of the pattern function M.to_lpeg(pattern) - local l = lpeg - - local P, S, V = lpeg.P, lpeg.S, lpeg.V - local C, Cc, Ct, Cf = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cf - - local pathsep = '/' - local function class(inv, ranges) - for i, r in ipairs(ranges) do - ranges[i] = r[1] .. r[2] - end - local patt = l.R(unpack(ranges)) + local patt = R(unpack(vim.tbl_map(table.concat, ranges))) if inv == '!' then patt = P(1) - patt end @@ -44,11 +38,11 @@ function M.to_lpeg(pattern) end local function star(stars, after) - return (-after * (l.P(1) - pathsep)) ^ #stars * after + return (-after * (P(1) - pathsep)) ^ #stars * after end local function dstar(after) - return (-after * l.P(1)) ^ 0 * after + return (-after * P(1)) ^ 0 * after end local p = P({ @@ -59,11 +53,17 @@ function M.to_lpeg(pattern) * (V('Elem') + V('End')), mul ), - DStar = P('**') * (P(pathsep) * (V('Elem') + V('End')) + V('End')) / dstar, + DStar = (B(pathsep) + -B(P(1))) + * P('**') + * (pathsep * (V('Elem') + V('End')) + V('End')) + / dstar, Star = C(P('*') ^ 1) * (V('Elem') + V('End')) / star, - Ques = P('?') * Cc(l.P(1) - pathsep), - Class = P('[') * C(P('!') ^ -1) * Ct(Ct(C(1) * '-' * C(P(1) - ']')) ^ 1 * ']') / class, - CondList = P('{') * Cf(V('Cond') * (P(',') * V('Cond')) ^ 0, add) * '}', + Ques = P('?') * Cc(P(1) - pathsep), + Class = P('[') + * C(P('!') ^ -1) + * Ct(Ct(C(P(1)) * P('-') * C(P(1) - P(']'))) ^ 1 * P(']')) + / class, + CondList = P('{') * Cf(V('Cond') * (P(',') * V('Cond')) ^ 0, add) * P('}'), -- TODO: '*' inside a {} condition is interpreted literally but should probably have the same -- wildcard semantics it usually has. -- Fixing this is non-trivial because '*' should match non-greedily up to "the rest of the @@ -71,9 +71,9 @@ function M.to_lpeg(pattern) -- condition means "everything after the {}" where several other options separated by ',' may -- exist in between that should not be matched by '*'. Cond = Cf((V('Ques') + V('Class') + V('CondList') + (V('Literal') - S(',}'))) ^ 1, mul) - + Cc(l.P(0)), - Literal = P(1) / l.P, - End = P(-1) * Cc(l.P(-1)), + + Cc(P(0)), + Literal = P(1) / P, + End = P(-1) * Cc(P(-1)), }) local lpeg_pattern = p:match(pattern) --[[@as vim.lpeg.Pattern?]] diff --git a/runtime/lua/vim/lsp/_meta.lua b/runtime/lua/vim/lsp/_meta.lua index 559939c236..be3222828d 100644 --- a/runtime/lua/vim/lsp/_meta.lua +++ b/runtime/lua/vim/lsp/_meta.lua @@ -14,10 +14,3 @@ error('Cannot require a meta file') ---@field code integer ---@field message string ---@field data string|number|boolean|table[]|table|nil - ---- @class lsp.DocumentFilter ---- @field language? string ---- @field scheme? string ---- @field pattern? string - ---- @alias lsp.RegisterOptions any | lsp.StaticRegistrationOptions | lsp.TextDocumentRegistrationOptions diff --git a/runtime/lua/vim/lsp/_meta/protocol.lua b/runtime/lua/vim/lsp/_meta/protocol.lua index 4c053cb57e..b897b6bba5 100644 --- a/runtime/lua/vim/lsp/_meta/protocol.lua +++ b/runtime/lua/vim/lsp/_meta/protocol.lua @@ -1,7 +1,11 @@ --[[ -This file is autogenerated from scripts/gen_lsp.lua +THIS FILE IS GENERATED by scripts/gen_lsp.lua +DO NOT EDIT MANUALLY + +Based on LSP protocol 3.18 + Regenerate: -nvim -l scripts/gen_lsp.lua gen --version 3.18 --out runtime/lua/vim/lsp/_meta/protocol.lua +nvim -l scripts/gen_lsp.lua gen --version 3.18 --]] ---@meta @@ -9,12 +13,9 @@ error('Cannot require a meta file') ---@alias lsp.null nil ---@alias uinteger integer ----@alias lsp.decimal number +---@alias decimal number ---@alias lsp.DocumentUri string ---@alias lsp.URI string ----@alias lsp.LSPObject table<string, lsp.LSPAny> ----@alias lsp.LSPArray lsp.LSPAny[] ----@alias lsp.LSPAny lsp.LSPObject|lsp.LSPArray|string|number|boolean|nil ---@class lsp.ImplementationParams: lsp.TextDocumentPositionParams, lsp.WorkDoneProgressParams, lsp.PartialResultParams diff --git a/runtime/lua/vim/version.lua b/runtime/lua/vim/version.lua index 0873402e29..4f52938c6e 100644 --- a/runtime/lua/vim/version.lua +++ b/runtime/lua/vim/version.lua @@ -259,11 +259,12 @@ end --- print(r:has(vim.version())) -- check against current Nvim version --- ``` --- ---- Or use cmp(), eq(), lt(), and gt() to compare `.to` and `.from` directly: +--- Or use cmp(), le(), lt(), ge(), gt(), and/or eq() to compare a version +--- against `.to` and `.from` directly: --- --- ```lua ---- local r = vim.version.range('1.0.0 - 2.0.0') ---- print(vim.version.gt({1,0,3}, r.from) and vim.version.lt({1,0,3}, r.to)) +--- local r = vim.version.range('1.0.0 - 2.0.0') -- >=1.0, <2.0 +--- print(vim.version.ge({1,0,3}, r.from) and vim.version.lt({1,0,3}, r.to)) --- ``` --- --- @see # https://github.com/npm/node-semver#ranges @@ -364,8 +365,8 @@ end --- --- @note Per semver, build metadata is ignored when comparing two otherwise-equivalent versions. --- ----@param v1 Version|number[] Version object. ----@param v2 Version|number[] Version to compare with `v1`. +---@param v1 Version|number[]|string Version object. +---@param v2 Version|number[]|string Version to compare with `v1`. ---@return integer -1 if `v1 < v2`, 0 if `v1 == v2`, 1 if `v1 > v2`. function M.cmp(v1, v2) local v1_parsed = assert(M._version(v1), create_err_msg(v1)) @@ -380,24 +381,40 @@ function M.cmp(v1, v2) end ---Returns `true` if the given versions are equal. See |vim.version.cmp()| for usage. ----@param v1 Version|number[] ----@param v2 Version|number[] +---@param v1 Version|number[]|string +---@param v2 Version|number[]|string ---@return boolean function M.eq(v1, v2) return M.cmp(v1, v2) == 0 end +---Returns `true` if `v1 <= v2`. See |vim.version.cmp()| for usage. +---@param v1 Version|number[]|string +---@param v2 Version|number[]|string +---@return boolean +function M.le(v1, v2) + return M.cmp(v1, v2) <= 0 +end + ---Returns `true` if `v1 < v2`. See |vim.version.cmp()| for usage. ----@param v1 Version|number[] ----@param v2 Version|number[] +---@param v1 Version|number[]|string +---@param v2 Version|number[]|string ---@return boolean function M.lt(v1, v2) return M.cmp(v1, v2) == -1 end +---Returns `true` if `v1 >= v2`. See |vim.version.cmp()| for usage. +---@param v1 Version|number[]|string +---@param v2 Version|number[]|string +---@return boolean +function M.ge(v1, v2) + return M.cmp(v1, v2) >= 0 +end + ---Returns `true` if `v1 > v2`. See |vim.version.cmp()| for usage. ----@param v1 Version|number[] ----@param v2 Version|number[] +---@param v1 Version|number[]|string +---@param v2 Version|number[]|string ---@return boolean function M.gt(v1, v2) return M.cmp(v1, v2) == 1 @@ -417,7 +434,7 @@ end --- - strict (boolean): Default false. If `true`, no coercion is attempted on --- input not conforming to semver v2.0.0. If `false`, `parse()` attempts to --- coerce input such as "1.0", "0-x", "tmux 3.2a" into valid versions. ----@return table|nil parsed_version Version object or `nil` if input is invalid. +---@return Version? parsed_version Version object or `nil` if input is invalid. function M.parse(version, opts) assert(type(version) == 'string', create_err_msg(version)) opts = opts or { strict = false } @@ -426,6 +443,7 @@ end setmetatable(M, { --- Returns the current Nvim version. + ---@return Version __call = function() local version = vim.fn.api_info().version -- Workaround: vim.fn.api_info().version reports "prerelease" as a boolean. diff --git a/runtime/queries/bash/folds.scm b/runtime/queries/bash/folds.scm index 851c67eed4..766dbe598b 100644 --- a/runtime/queries/bash/folds.scm +++ b/runtime/queries/bash/folds.scm @@ -5,4 +5,5 @@ (for_statement) (while_statement) (c_style_for_statement) + (heredoc_redirect) ] @fold diff --git a/runtime/queries/bash/highlights.scm b/runtime/queries/bash/highlights.scm index 23bf03e697..21346ded8f 100644 --- a/runtime/queries/bash/highlights.scm +++ b/runtime/queries/bash/highlights.scm @@ -1,81 +1,100 @@ -(simple_expansion) @none -(expansion - "${" @punctuation.special - "}" @punctuation.special) @none [ - "(" - ")" - "((" - "))" - "{" - "}" - "[" - "]" - "[[" - "]]" - ] @punctuation.bracket + "(" + ")" + "{" + "}" + "[" + "]" + "[[" + "]]" + "((" + "))" +] @punctuation.bracket [ - ";" - ";;" - (heredoc_start) - ] @punctuation.delimiter + ";" + ";;" + ";&" + ";;&" + "&" +] @punctuation.delimiter [ - "$" -] @punctuation.special - + ">" + ">>" + "<" + "<<" + "&&" + "|" + "|&" + "||" + "=" + "+=" + "=~" + "==" + "!=" + "&>" + "&>>" + "<&" + ">&" + ">|" + "<&-" + ">&-" + "<<-" + "<<<" + ".." +] @operator + +; Do *not* spell check strings since they typically have some sort of +; interpolation in them, or, are typically used for things like filenames, URLs, +; flags and file content. [ - ">" - ">>" - "<" - "<<" - "&" - "&&" - "|" - "||" - "=" - "=~" - "==" - "!=" - ] @operator + (string) + (raw_string) + (ansi_c_string) + (heredoc_body) +] @string [ - (string) - (raw_string) - (ansi_c_string) - (heredoc_body) -] @string @spell + (heredoc_start) + (heredoc_end) +] @label -(variable_assignment (word) @string) +(variable_assignment + (word) @string) + +(command + argument: "$" @string) ; bare dollar [ - "if" - "then" - "else" - "elif" - "fi" - "case" - "in" - "esac" - ] @conditional + "if" + "then" + "else" + "elif" + "fi" + "case" + "in" + "esac" +] @keyword.conditional [ - "for" - "do" - "done" - "select" - "until" - "while" - ] @repeat + "for" + "do" + "done" + "select" + "until" + "while" +] @keyword.repeat [ - "declare" - "export" - "local" - "readonly" - "unset" - ] @keyword + "declare" + "typeset" + "export" + "readonly" + "local" + "unset" + "unsetenv" +] @keyword "function" @keyword.function @@ -83,28 +102,56 @@ ; trap -l ((word) @constant.builtin - (#match? @constant.builtin "^SIG(HUP|INT|QUIT|ILL|TRAP|ABRT|BUS|FPE|KILL|USR[12]|SEGV|PIPE|ALRM|TERM|STKFLT|CHLD|CONT|STOP|TSTP|TT(IN|OU)|URG|XCPU|XFSZ|VTALRM|PROF|WINCH|IO|PWR|SYS|RTMIN([+]([1-9]|1[0-5]))?|RTMAX(-([1-9]|1[0-4]))?)$")) + (#match? @constant.builtin "^SIG(HUP|INT|QUIT|ILL|TRAP|ABRT|BUS|FPE|KILL|USR[12]|SEGV|PIPE|ALRM|TERM|STKFLT|CHLD|CONT|STOP|TSTP|TT(IN|OU)|URG|XCPU|XFSZ|VTALRM|PROF|WINCH|IO|PWR|SYS|RTMIN([+]([1-9]|1[0-5]))?|RTMAX(-([1-9]|1[0-4]))?)$")) ((word) @boolean (#any-of? @boolean "true" "false")) (comment) @comment @spell -(test_operator) @string + +(test_operator) @operator (command_substitution - [ "$(" ")" ] @punctuation.bracket) + "$(" @punctuation.bracket) (process_substitution - [ "<(" ")" ] @punctuation.bracket) + "<(" @punctuation.bracket) +(arithmetic_expansion + [ + "$((" + "((" + ] @punctuation.special + "))" @punctuation.special) + +(arithmetic_expansion + "," @punctuation.delimiter) + +(ternary_expression + [ + "?" + ":" + ] @keyword.conditional.ternary) + +(binary_expression + operator: _ @operator) + +(unary_expression + operator: _ @operator) + +(postfix_expression + operator: _ @operator) (function_definition name: (word) @function) -(command_name (word) @function.call) +(command_name + (word) @function.call) -((command_name (word) @function.builtin) - (#any-of? @function.builtin +((command_name + (word) @function.builtin) + ; format-ignore + (#any-of? @function.builtin "alias" "bg" "bind" "break" "builtin" "caller" "cd" "command" "compgen" "complete" "compopt" "continue" "coproc" "dirs" "disown" "echo" "enable" "eval" @@ -116,30 +163,59 @@ "ulimit" "umask" "unalias" "wait")) (command - argument: [ - (word) @parameter - (concatenation (word) @parameter) - ]) + argument: + [ + (word) @variable.parameter + (concatenation + (word) @variable.parameter) + ]) + +(number) @number ((word) @number (#lua-match? @number "^[0-9]+$")) (file_redirect - descriptor: (file_descriptor) @operator - destination: (word) @parameter) + destination: (word) @variable.parameter) + +(file_descriptor) @operator + +(simple_expansion + "$" @punctuation.special) @none + +(expansion + "${" @punctuation.special + "}" @punctuation.special) @none (expansion - [ "${" "}" ] @punctuation.bracket) + operator: _ @punctuation.special) + +(expansion + "@" + . + operator: _ @character.special) + +((expansion + (subscript + index: (word) @character.special)) + (#any-of? @character.special "@" "*")) + +"``" @punctuation.special (variable_name) @variable ((variable_name) @constant - (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) + (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) (case_item - value: (word) @parameter) - -(regex) @string.regex + value: (word) @variable.parameter) -((program . (comment) @preproc) - (#lua-match? @preproc "^#!/")) +[ + (regex) + (extglob_pattern) +] @string.regexp + +((program + . + (comment) @keyword.directive) + (#lua-match? @keyword.directive "^#!/")) diff --git a/runtime/queries/c/folds.scm b/runtime/queries/c/folds.scm index 5a35334a24..2e2a6b4d0c 100644 --- a/runtime/queries/c/folds.scm +++ b/runtime/queries/c/folds.scm @@ -1,19 +1,21 @@ [ - (for_statement) - (if_statement) - (while_statement) - (switch_statement) - (case_statement) - (function_definition) - (struct_specifier) - (enum_specifier) - (comment) - (preproc_if) - (preproc_elif) - (preproc_else) - (preproc_ifdef) - (initializer_list) - (gnu_asm_expression) + (for_statement) + (if_statement) + (while_statement) + (do_statement) + (switch_statement) + (case_statement) + (function_definition) + (struct_specifier) + (enum_specifier) + (comment) + (preproc_if) + (preproc_elif) + (preproc_else) + (preproc_ifdef) + (preproc_function_def) + (initializer_list) + (gnu_asm_expression) ] @fold (compound_statement diff --git a/runtime/queries/c/highlights.scm b/runtime/queries/c/highlights.scm index 29fb5747ca..c848f68dca 100644 --- a/runtime/queries/c/highlights.scm +++ b/runtime/queries/c/highlights.scm @@ -1,6 +1,9 @@ -; Lower priority to prefer @parameter when identifier appears in parameter_declaration. -((identifier) @variable (#set! "priority" 95)) -(preproc_def (preproc_arg) @variable) +; Lower priority to prefer @variable.parameter when identifier appears in parameter_declaration. +((identifier) @variable + (#set! "priority" 95)) + +(preproc_def + (preproc_arg) @variable) [ "default" @@ -17,7 +20,10 @@ "sizeof" "offsetof" ] @keyword.operator -(alignof_expression . _ @keyword.operator) + +(alignof_expression + . + _ @keyword.operator) "return" @keyword.return @@ -27,14 +33,14 @@ "do" "continue" "break" -] @repeat +] @keyword.repeat [ - "if" - "else" - "case" - "switch" -] @conditional + "if" + "else" + "case" + "switch" +] @keyword.conditional [ "#if" @@ -46,48 +52,54 @@ "#elifdef" "#elifndef" (preproc_directive) -] @preproc +] @keyword.directive -"#define" @define +"#define" @keyword.directive.define -"#include" @include +"#include" @keyword.import -[ ";" ":" "," "::" ] @punctuation.delimiter +[ + ";" + ":" + "," + "::" +] @punctuation.delimiter "..." @punctuation.special -[ "(" ")" "[" "]" "{" "}"] @punctuation.bracket +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket [ "=" - "-" "*" "/" "+" "%" - "~" "|" "&" "^" "<<" ">>" - "->" "." - "<" "<=" ">=" ">" "==" "!=" - "!" "&&" "||" - "-=" "+=" "*=" @@ -102,45 +114,57 @@ "++" ] @operator -;; Make sure the comma operator is given a highlight group after the comma -;; punctuator so the operator is highlighted properly. -(comma_expression [ "," ] @operator) +; Make sure the comma operator is given a highlight group after the comma +; punctuator so the operator is highlighted properly. +(comma_expression + "," @operator) [ (true) (false) ] @boolean -(conditional_expression [ "?" ":" ] @conditional.ternary) +(conditional_expression + [ + "?" + ":" + ] @keyword.conditional.ternary) (string_literal) @string + (system_lib_string) @string + (escape_sequence) @string.escape (null) @constant.builtin + (number_literal) @number + (char_literal) @character -((preproc_arg) @function.macro (#set! "priority" 90)) +((preproc_arg) @function.macro + (#set! "priority" 90)) + (preproc_defined) @function.macro -(((field_expression - (field_identifier) @property)) @_parent - (#not-has-parent? @_parent template_method function_declarator call_expression)) +((field_expression + (field_identifier) @property) @_parent + (#not-has-parent? @_parent template_method function_declarator call_expression)) (field_designator) @property -(((field_identifier) @property) - (#has-ancestor? @property field_declaration) - (#not-has-ancestor? @property function_declarator)) + +((field_identifier) @property + (#has-ancestor? @property field_declaration) + (#not-has-ancestor? @property function_declarator)) (statement_identifier) @label [ - (type_identifier) - (type_descriptor) + (type_identifier) + (type_descriptor) ] @type -(storage_class_specifier) @storageclass +(storage_class_specifier) @keyword.storage [ (type_qualifier) @@ -149,25 +173,32 @@ ] @type.qualifier (linkage_specification - "extern" @storageclass) + "extern" @keyword.storage) (type_definition declarator: (type_identifier) @type.definition) (primitive_type) @type.builtin -(sized_type_specifier _ @type.builtin type: _?) +(sized_type_specifier + _ @type.builtin + type: _?) ((identifier) @constant - (#lua-match? @constant "^[A-Z][A-Z0-9_]+$")) -(preproc_def (preproc_arg) @constant (#lua-match? @constant "^[A-Z][A-Z0-9_]+$")) + +(preproc_def + (preproc_arg) @constant + (#lua-match? @constant "^[A-Z][A-Z0-9_]+$")) + (enumerator name: (identifier) @constant) + (case_statement value: (identifier) @constant) ((identifier) @constant.builtin + ; format-ignore (#any-of? @constant.builtin "stderr" "stdin" "stdout" "__FILE__" "__LINE__" "__DATE__" "__TIME__" @@ -180,7 +211,10 @@ "__clang_wide_literal_encoding__" "__FUNCTION__" "__func__" "__PRETTY_FUNCTION__" "__VA_ARGS__" "__VA_OPT__")) -(preproc_def (preproc_arg) @constant.builtin + +(preproc_def + (preproc_arg) @constant.builtin + ; format-ignore (#any-of? @constant.builtin "stderr" "stdin" "stdout" "__FILE__" "__LINE__" "__DATE__" "__TIME__" @@ -195,21 +229,26 @@ "__VA_ARGS__" "__VA_OPT__")) (attribute_specifier - (argument_list (identifier) @variable.builtin)) + (argument_list + (identifier) @variable.builtin)) + ((attribute_specifier - (argument_list (call_expression - function: (identifier) @variable.builtin)))) + (argument_list + (call_expression + function: (identifier) @variable.builtin)))) ((call_expression function: (identifier) @function.builtin) (#lua-match? @function.builtin "^__builtin_")) + ((call_expression - function: (identifier) @function.builtin) + function: (identifier) @function.builtin) (#has-ancestor? @function.builtin attribute_specifier)) -;; Preproc def / undef +; Preproc def / undef (preproc_def name: (_) @constant) + (preproc_call directive: (preproc_directive) @_u argument: (_) @constant @@ -217,15 +256,21 @@ (call_expression function: (identifier) @function.call) + (call_expression - function: (field_expression - field: (field_identifier) @function.call)) + function: + (field_expression + field: (field_identifier) @function.call)) + (function_declarator declarator: (identifier) @function) + (function_declarator - declarator: (parenthesized_declarator - (pointer_declarator - declarator: (field_identifier) @function))) + declarator: + (parenthesized_declarator + (pointer_declarator + declarator: (field_identifier) @function))) + (preproc_function_def name: (identifier) @function.macro) @@ -234,17 +279,40 @@ ((comment) @comment.documentation (#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$")) -;; Parameters +; Parameters (parameter_declaration - declarator: (identifier) @parameter) + declarator: (identifier) @variable.parameter) (parameter_declaration - declarator: (array_declarator) @parameter) + declarator: (array_declarator) @variable.parameter) (parameter_declaration - declarator: (pointer_declarator) @parameter) - -(preproc_params (identifier) @parameter) + declarator: (pointer_declarator) @variable.parameter) + +; K&R functions +; To enable support for K&R functions, +; add the following lines to your own query config and uncomment them. +; They are commented out as they'll conflict with C++ +; Note that you'll need to have `; extends` at the top of your query file. +; +; (parameter_list (identifier) @variable.parameter) +; +; (function_definition +; declarator: _ +; (declaration +; declarator: (identifier) @variable.parameter)) +; +; (function_definition +; declarator: _ +; (declaration +; declarator: (array_declarator) @variable.parameter)) +; +; (function_definition +; declarator: _ +; (declaration +; declarator: (pointer_declarator) @variable.parameter)) +(preproc_params + (identifier) @variable.parameter) [ "__attribute__" @@ -259,5 +327,3 @@ (ms_pointer_modifier) (attribute_declaration) ] @attribute - -(ERROR) @error diff --git a/runtime/queries/c/injections.scm b/runtime/queries/c/injections.scm index 5a49e20df5..ce2f88a215 100644 --- a/runtime/queries/c/injections.scm +++ b/runtime/queries/c/injections.scm @@ -1,21 +1,2 @@ -((preproc_def - (preproc_arg) @injection.content) - (#lua-match? @injection.content "\n") - (#set! injection.language "c")) - -(preproc_function_def - (preproc_arg) @injection.content - (#set! injection.language "c")) - -(preproc_call - (preproc_arg) @injection.content - (#set! injection.language "c")) - -; ((comment) @injection.content -; (#set! injection.language "comment")) - -; TODO: add when asm is added -; (gnu_asm_expression assembly_code: (string_literal) @injection.content -; (#set! injection.language "asm")) -; (gnu_asm_expression assembly_code: (concatenated_string (string_literal) @injection.content) -; (#set! injection.language "asm")) +((preproc_arg) @injection.content + (#set! injection.self)) diff --git a/runtime/queries/lua/folds.scm b/runtime/queries/lua/folds.scm index d8f0b42df3..9dfac3abc6 100644 --- a/runtime/queries/lua/folds.scm +++ b/runtime/queries/lua/folds.scm @@ -1,10 +1,12 @@ [ - (do_statement) - (while_statement) - (repeat_statement) - (if_statement) - (for_statement) - (function_declaration) - (function_definition) - (table_constructor) + (do_statement) + (while_statement) + (repeat_statement) + (if_statement) + (for_statement) + (function_declaration) + (function_definition) + (parameters) + (arguments) + (table_constructor) ] @fold diff --git a/runtime/queries/lua/highlights.scm b/runtime/queries/lua/highlights.scm index 96ffeae793..0b0bf35a8b 100644 --- a/runtime/queries/lua/highlights.scm +++ b/runtime/queries/lua/highlights.scm @@ -1,81 +1,79 @@ -;; Keywords - +; Keywords "return" @keyword.return [ - "goto" - "in" - "local" + "goto" + "in" + "local" ] @keyword (break_statement) @keyword (do_statement -[ - "do" - "end" -] @keyword) + [ + "do" + "end" + ] @keyword) (while_statement -[ - "while" - "do" - "end" -] @repeat) + [ + "while" + "do" + "end" + ] @keyword.repeat) (repeat_statement -[ - "repeat" - "until" -] @repeat) + [ + "repeat" + "until" + ] @keyword.repeat) (if_statement -[ - "if" - "elseif" - "else" - "then" - "end" -] @conditional) + [ + "if" + "elseif" + "else" + "then" + "end" + ] @keyword.conditional) (elseif_statement -[ - "elseif" - "then" - "end" -] @conditional) + [ + "elseif" + "then" + "end" + ] @keyword.conditional) (else_statement -[ - "else" - "end" -] @conditional) + [ + "else" + "end" + ] @keyword.conditional) (for_statement -[ - "for" - "do" - "end" -] @repeat) + [ + "for" + "do" + "end" + ] @keyword.repeat) (function_declaration -[ - "function" - "end" -] @keyword.function) + [ + "function" + "end" + ] @keyword.function) (function_definition -[ - "function" - "end" -] @keyword.function) - -;; Operators + [ + "function" + "end" + ] @keyword.function) +; Operators [ - "and" - "not" - "or" + "and" + "not" + "or" ] @keyword.operator [ @@ -102,8 +100,7 @@ ".." ] @operator -;; Punctuations - +; Punctuations [ ";" ":" @@ -112,19 +109,17 @@ "." ] @punctuation.delimiter -;; Brackets - +; Brackets [ - "(" - ")" - "[" - "]" - "{" - "}" + "(" + ")" + "[" + "]" + "{" + "}" ] @punctuation.bracket -;; Variables - +; Variables (identifier) @variable ((identifier) @constant.builtin @@ -133,27 +128,28 @@ ((identifier) @variable.builtin (#eq? @variable.builtin "self")) -((identifier) @namespace.builtin - (#any-of? @namespace.builtin "_G" "debug" "io" "jit" "math" "os" "package" "string" "table" "utf8")) +((identifier) @module.builtin + (#any-of? @module.builtin "_G" "debug" "io" "jit" "math" "os" "package" "string" "table" "utf8")) ((identifier) @keyword.coroutine (#eq? @keyword.coroutine "coroutine")) (variable_list - attribute: (attribute - (["<" ">"] @punctuation.bracket - (identifier) @attribute))) - -;; Labels + (attribute + "<" @punctuation.bracket + (identifier) @attribute + ">" @punctuation.bracket)) -(label_statement (identifier) @label) +; Labels +(label_statement + (identifier) @label) -(goto_statement (identifier) @label) - -;; Constants +(goto_statement + (identifier) @label) +; Constants ((identifier) @constant - (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) + (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) (vararg_expression) @constant @@ -164,41 +160,49 @@ (true) ] @boolean -;; Tables - -(field name: (identifier) @field) +; Tables +(field + name: (identifier) @variable.member) -(dot_index_expression field: (identifier) @field) +(dot_index_expression + field: (identifier) @variable.member) (table_constructor -[ - "{" - "}" -] @constructor) + [ + "{" + "}" + ] @constructor) -;; Functions +; Functions +(parameters + (identifier) @variable.parameter) -(parameters (identifier) @parameter) - -(function_declaration - name: [ - (identifier) @function - (dot_index_expression - field: (identifier) @function) - ]) +(vararg_expression) @variable.parameter.builtin (function_declaration - name: (method_index_expression - method: (identifier) @method)) - -(assignment_statement - (variable_list . - name: [ + name: + [ (identifier) @function (dot_index_expression field: (identifier) @function) ]) - (expression_list . + +(function_declaration + name: + (method_index_expression + method: (identifier) @function.method)) + +(assignment_statement + (variable_list + . + name: + [ + (identifier) @function + (dot_index_expression + field: (identifier) @function) + ]) + (expression_list + . value: (function_definition))) (table_constructor @@ -207,18 +211,20 @@ value: (function_definition))) (function_call - name: [ - (identifier) @function.call - (dot_index_expression - field: (identifier) @function.call) - (method_index_expression - method: (identifier) @method.call) - ]) + name: + [ + (identifier) @function.call + (dot_index_expression + field: (identifier) @function.call) + (method_index_expression + method: (identifier) @function.method.call) + ]) (function_call (identifier) @function.builtin + ; format-ignore (#any-of? @function.builtin - ;; built-in functions in Lua 5.1 + ; built-in functions in Lua 5.1 "assert" "collectgarbage" "dofile" "error" "getfenv" "getmetatable" "ipairs" "load" "loadfile" "loadstring" "module" "next" "pairs" "pcall" "print" "rawequal" "rawget" "rawlen" "rawset" "require" "select" "setfenv" "setmetatable" @@ -227,8 +233,7 @@ "__idiv" "__index" "__le" "__len" "__lt" "__metatable" "__mod" "__mul" "__name" "__newindex" "__pairs" "__pow" "__shl" "__shr" "__sub" "__tostring" "__unm")) -;; Others - +; Others (comment) @comment @spell ((comment) @comment.documentation @@ -237,13 +242,34 @@ ((comment) @comment.documentation (#lua-match? @comment.documentation "^[-][-](%s?)@")) -(hash_bang_line) @preproc +(hash_bang_line) @keyword.directive (number) @number -(string) @string @spell +(string) @string (escape_sequence) @string.escape -;; Error -(ERROR) @error +; string.match("123", "%d+") +(function_call + (dot_index_expression + field: (identifier) @_method + (#any-of? @_method "find" "match" "gmatch" "gsub")) + arguments: + (arguments + . + (_) + . + (string + content: (string_content) @string.regexp))) + +;("123"):match("%d+") +(function_call + (method_index_expression + method: (identifier) @_method + (#any-of? @_method "find" "match" "gmatch" "gsub")) + arguments: + (arguments + . + (string + content: (string_content) @string.regexp))) diff --git a/runtime/queries/lua/injections.scm b/runtime/queries/lua/injections.scm index dbfe75ae31..c8a1843c84 100644 --- a/runtime/queries/lua/injections.scm +++ b/runtime/queries/lua/injections.scm @@ -1,35 +1,130 @@ ((function_call - name: [ - (identifier) @_cdef_identifier - (_ _ (identifier) @_cdef_identifier) - ] + name: + [ + (identifier) @_cdef_identifier + (_ + _ + (identifier) @_cdef_identifier) + ] arguments: (arguments - (string content: _ @injection.content))) + (string + content: _ @injection.content))) (#set! injection.language "c") (#eq? @_cdef_identifier "cdef")) ((function_call name: (_) @_vimcmd_identifier - arguments: (arguments (string content: _ @injection.content))) + arguments: + (arguments + (string + content: _ @injection.content))) (#set! injection.language "vim") (#any-of? @_vimcmd_identifier "vim.cmd" "vim.api.nvim_command" "vim.api.nvim_command" "vim.api.nvim_exec2")) ((function_call name: (_) @_vimcmd_identifier - arguments: (arguments (string content: _ @injection.content) .)) + arguments: + (arguments + (string + content: _ @injection.content) .)) (#set! injection.language "query") (#any-of? @_vimcmd_identifier "vim.treesitter.query.set" "vim.treesitter.query.parse")) ((function_call name: (_) @_vimcmd_identifier - arguments: (arguments . (_) . (string content: _ @_method) . (string content: _ @injection.content))) + arguments: + (arguments + . + (_) + . + (string + content: _ @_method) + . + (string + content: _ @injection.content))) (#any-of? @_vimcmd_identifier "vim.rpcrequest" "vim.rpcnotify") (#eq? @_method "nvim_exec_lua") (#set! injection.language "lua")) -;; highlight string as query if starts with `;; query` -(string content: _ @injection.content - (#lua-match? @injection.content "^%s*;+%s?query") - (#set! injection.language "query")) +; vim.api.nvim_create_autocmd("FileType", { command = "injected here" }) +(function_call + name: (_) @_vimcmd_identifier + arguments: + (arguments + . + (_) + . + (table_constructor + (field + name: (identifier) @_command + value: + (string + content: (_) @injection.content))) .) + ; limit so only 2-argument functions gets matched before pred handle + (#eq? @_vimcmd_identifier "vim.api.nvim_create_autocmd") + (#eq? @_command "command") + (#set! injection.language "vim")) + +(function_call + name: (_) @_user_cmd + arguments: + (arguments + . + (_) + . + (string + content: (_) @injection.content) + . + (_) .) + (#eq? @_user_cmd "vim.api.nvim_create_user_command") + (#set! injection.language "vim")) + +(function_call + name: (_) @_user_cmd + arguments: + (arguments + . + (_) + . + (_) + . + (string + content: (_) @injection.content) + . + (_) .) + ; Limiting predicate handling to only functions with 4 arguments + (#eq? @_user_cmd "vim.api.nvim_buf_create_user_command") + (#set! injection.language "vim")) +; rhs highlighting for vim.keymap.set/vim.api.nvim_set_keymap/vim.api.nvim_buf_set_keymap +; (function_call +; name: (_) @_map +; arguments: +; (arguments +; . (_) +; . (_) +; . +; (string +; content: (_) @injection.content)) +; (#any-of? @_map "vim.api.nvim_set_keymap" "vim.keymap.set") +; (#set! injection.language "vim")) +; +; (function_call +; name: (_) @_map +; arguments: +; (arguments +; . (_) +; . (_) +; . (_) +; . +; (string +; content: (_) @injection.content) +; . (_) .) +; (#eq? @_map "vim.api.nvim_buf_set_keymap") +; (#set! injection.language "vim")) +; highlight string as query if starts with `;; query` +(string + content: _ @injection.content + (#lua-match? @injection.content "^%s*;+%s?query") + (#set! injection.language "query")) diff --git a/runtime/queries/markdown/folds.scm b/runtime/queries/markdown/folds.scm index 5900f7ffbe..a682e20e00 100644 --- a/runtime/queries/markdown/folds.scm +++ b/runtime/queries/markdown/folds.scm @@ -1,9 +1,7 @@ -( - [ - (fenced_code_block) - (indented_code_block) - (list) - (section) - ] @fold - (#trim! @fold) -) +([ + (fenced_code_block) + (indented_code_block) + (list) + (section) +] @fold + (#trim! @fold)) diff --git a/runtime/queries/markdown/highlights.scm b/runtime/queries/markdown/highlights.scm index 2cc5546bac..7c26fd710c 100644 --- a/runtime/queries/markdown/highlights.scm +++ b/runtime/queries/markdown/highlights.scm @@ -1,40 +1,73 @@ ;From MDeiml/tree-sitter-markdown & Helix -(setext_heading (paragraph) @text.title.1 (setext_h1_underline) @text.title.1.marker) -(setext_heading (paragraph) @text.title.2 (setext_h2_underline) @text.title.2.marker) +(setext_heading + (paragraph) @markup.heading.1 + (setext_h1_underline) @markup.heading.1.marker) -(atx_heading (atx_h1_marker) @text.title.1.marker (inline) @text.title.1) -(atx_heading (atx_h2_marker) @text.title.2.marker (inline) @text.title.2) -(atx_heading (atx_h3_marker) @text.title.3.marker (inline) @text.title.3) -(atx_heading (atx_h4_marker) @text.title.4.marker (inline) @text.title.4) -(atx_heading (atx_h5_marker) @text.title.5.marker (inline) @text.title.5) -(atx_heading (atx_h6_marker) @text.title.6.marker (inline) @text.title.6) +(setext_heading + (paragraph) @markup.heading.2 + (setext_h2_underline) @markup.heading.2.marker) -(link_title) @text.literal -(indented_code_block) @text.literal.block -((fenced_code_block) @text.literal.block (#set! "priority" 90)) +(atx_heading + (atx_h1_marker) @markup.heading.1.marker + (inline) @markup.heading.1) + +(atx_heading + (atx_h2_marker) @markup.heading.2.marker + (inline) @markup.heading.2) + +(atx_heading + (atx_h3_marker) @markup.heading.3.marker + (inline) @markup.heading.3) + +(atx_heading + (atx_h4_marker) @markup.heading.4.marker + (inline) @markup.heading.4) + +(atx_heading + (atx_h5_marker) @markup.heading.5.marker + (inline) @markup.heading.5) + +(atx_heading + (atx_h6_marker) @markup.heading.6.marker + (inline) @markup.heading.6) (info_string) @label -(pipe_table_header (pipe_table_cell) @text.title) +(pipe_table_header + (pipe_table_cell) @markup.heading) + +(pipe_table_header + "|" @punctuation.special) + +(pipe_table_row + "|" @punctuation.special) + +(pipe_table_delimiter_row + "|" @punctuation.special) -(pipe_table_header "|" @punctuation.special) -(pipe_table_row "|" @punctuation.special) -(pipe_table_delimiter_row "|" @punctuation.special) (pipe_table_delimiter_cell) @punctuation.special -[ - (fenced_code_block_delimiter) -] @punctuation.delimiter +; Code blocks (conceal backticks and language annotation) +(indented_code_block) @markup.raw.block -(code_fence_content) @none +((fenced_code_block) @markup.raw.block + (#set! "priority" 90)) -[ - (link_destination) -] @text.uri +(fenced_code_block + (fenced_code_block_delimiter) @markup.raw.delimiter + (#set! conceal "")) + +(fenced_code_block + (info_string + (language) @conceal + (#set! conceal ""))) + +(link_destination) @markup.link.url [ + (link_title) (link_label) -] @text.reference +] @markup.link.label [ (list_marker_plus) @@ -42,30 +75,43 @@ (list_marker_star) (list_marker_dot) (list_marker_parenthesis) - (thematic_break) -] @punctuation.special - - -(task_list_marker_unchecked) @text.todo.unchecked -(task_list_marker_checked) @text.todo.checked - -(block_quote) @text.quote +] @markup.list + +; NOTE: The following has been commented out due to issues with spaces in the +; list marker nodes generated by the parser. If those spaces ever get captured +; by a different node (e.g. block_continuation) we can safely readd these +; conceals. +; ;; Conceal bullet points +; ([(list_marker_plus) (list_marker_star)] +; @punctuation.special +; (#offset! @punctuation.special 0 0 0 -1) +; (#set! conceal "•")) +; ([(list_marker_plus) (list_marker_star)] +; @punctuation.special +; (#any-of? @punctuation.special "+" "*") +; (#set! conceal "•")) +; ((list_marker_minus) +; @punctuation.special +; (#offset! @punctuation.special 0 0 0 -1) +; (#set! conceal "—")) +; ((list_marker_minus) +; @punctuation.special +; (#eq? @punctuation.special "-") +; (#set! conceal "—")) +(thematic_break) @punctuation.special + +(task_list_marker_unchecked) @markup.list.unchecked + +(task_list_marker_checked) @markup.list.checked + +((block_quote) @markup.quote + (#set! "priority" 90)) [ (block_continuation) (block_quote_marker) ] @punctuation.special -[ - (backslash_escape) -] @string.escape +(backslash_escape) @string.escape (inline) @spell - -;; Conceal backticks -(fenced_code_block - (fenced_code_block_delimiter) @conceal - (#set! conceal "")) -(fenced_code_block - (info_string (language) @conceal - (#set! conceal ""))) diff --git a/runtime/queries/markdown/injections.scm b/runtime/queries/markdown/injections.scm index fda7036830..1f33c30b63 100644 --- a/runtime/queries/markdown/injections.scm +++ b/runtime/queries/markdown/injections.scm @@ -3,23 +3,23 @@ (language) @injection.language) (code_fence_content) @injection.content) -((html_block) @injection.content - (#set! injection.language "html") - (#set! injection.combined) - (#set! injection.include-children)) +((html_block) @injection.content + (#set! injection.language "html") + (#set! injection.combined) + (#set! injection.include-children)) -((minus_metadata) @injection.content - (#set! injection.language "yaml") - (#offset! @injection.content 1 0 -1 0) - (#set! injection.include-children)) +((minus_metadata) @injection.content + (#set! injection.language "yaml") + (#offset! @injection.content 1 0 -1 0) + (#set! injection.include-children)) -((plus_metadata) @injection.content - (#set! injection.language "toml") - (#offset! @injection.content 1 0 -1 0) - (#set! injection.include-children)) +((plus_metadata) @injection.content + (#set! injection.language "toml") + (#offset! @injection.content 1 0 -1 0) + (#set! injection.include-children)) ([ (inline) (pipe_table_cell) - ] @injection.content - (#set! injection.language "markdown_inline")) +] @injection.content + (#set! injection.language "markdown_inline")) diff --git a/runtime/queries/markdown_inline/highlights.scm b/runtime/queries/markdown_inline/highlights.scm index c75da478af..e9b41c31d5 100644 --- a/runtime/queries/markdown_inline/highlights.scm +++ b/runtime/queries/markdown_inline/highlights.scm @@ -1,49 +1,26 @@ -;; From MDeiml/tree-sitter-markdown -[ - (code_span) - (link_title) -] @text.literal @nospell - -[ - (emphasis_delimiter) - (code_span_delimiter) -] @punctuation.delimiter - -(emphasis) @text.emphasis +; From MDeiml/tree-sitter-markdown +(code_span) @markup.raw @nospell -(strong_emphasis) @text.strong +(emphasis) @markup.italic -(strikethrough) @text.strike - -[ - (link_destination) - (uri_autolink) -] @text.uri @nospell +(strong_emphasis) @markup.strong -(shortcut_link (link_text) @nospell) +(strikethrough) @markup.strikethrough -[ - (link_label) - (link_text) - (image_description) -] @text.reference +(shortcut_link + (link_text) @nospell) [ (backslash_escape) (hard_line_break) ] @string.escape -(image "!" @punctuation.special) -(image ["[" "]" "(" ")"] @punctuation.bracket) -(inline_link ["[" "]" "(" ")"] @punctuation.bracket) -(shortcut_link ["[" "]"] @punctuation.bracket) - ; Conceal codeblock and text style markers -([ - (code_span_delimiter) - (emphasis_delimiter) -] @conceal -(#set! conceal "")) +((code_span_delimiter) @markup.raw.delimiter + (#set! conceal "")) + +((emphasis_delimiter) @conceal + (#set! conceal "")) ; Conceal inline links (inline_link @@ -53,7 +30,7 @@ "(" (link_destination) ")" - ] @conceal + ] @markup.link (#set! conceal "")) ; Conceal image links @@ -65,7 +42,7 @@ "(" (link_destination) ")" - ] @conceal + ] @markup.link (#set! conceal "")) ; Conceal full reference links @@ -74,7 +51,7 @@ "[" "]" (link_label) - ] @conceal + ] @markup.link (#set! conceal "")) ; Conceal collapsed reference links @@ -82,7 +59,7 @@ [ "[" "]" - ] @conceal + ] @markup.link (#set! conceal "")) ; Conceal shortcut links @@ -90,13 +67,42 @@ [ "[" "]" - ] @conceal + ] @markup.link (#set! conceal "")) -;; Replace common HTML entities. -((entity_reference) @conceal (#eq? @conceal " ") (#set! conceal "")) -((entity_reference) @conceal (#eq? @conceal "<") (#set! conceal "<")) -((entity_reference) @conceal (#eq? @conceal ">") (#set! conceal ">")) -((entity_reference) @conceal (#eq? @conceal "&") (#set! conceal "&")) -((entity_reference) @conceal (#eq? @conceal """) (#set! conceal "\"")) -((entity_reference) @conceal (#any-of? @conceal " " " ") (#set! conceal " ")) +[ + (link_destination) + (uri_autolink) +] @markup.link.url @nospell + +[ + (link_label) + (link_text) + (link_title) + (image_description) +] @markup.link.label + +; Replace common HTML entities. +((entity_reference) @character.special + (#eq? @character.special " ") + (#set! conceal "")) + +((entity_reference) @character.special + (#eq? @character.special "<") + (#set! conceal "<")) + +((entity_reference) @character.special + (#eq? @character.special ">") + (#set! conceal ">")) + +((entity_reference) @character.special + (#eq? @character.special "&") + (#set! conceal "&")) + +((entity_reference) @character.special + (#eq? @character.special """) + (#set! conceal "\"")) + +((entity_reference) @character.special + (#any-of? @character.special " " " ") + (#set! conceal " ")) diff --git a/runtime/queries/markdown_inline/injections.scm b/runtime/queries/markdown_inline/injections.scm index f7aa19caff..6448b77c1b 100644 --- a/runtime/queries/markdown_inline/injections.scm +++ b/runtime/queries/markdown_inline/injections.scm @@ -1,8 +1,7 @@ ((html_tag) @injection.content - (#set! injection.language "html") - (#set! injection.combined) - (#set! injection.include-children)) + (#set! injection.language "html") + (#set! injection.combined)) ((latex_block) @injection.content - (#set! injection.language "latex") - (#set! injection.include-children)) + (#set! injection.language "latex") + (#set! injection.include-children)) diff --git a/runtime/queries/python/folds.scm b/runtime/queries/python/folds.scm index 78e1e2c00d..7c547db38f 100644 --- a/runtime/queries/python/folds.scm +++ b/runtime/queries/python/folds.scm @@ -1,28 +1,23 @@ [ (function_definition) (class_definition) - (while_statement) (for_statement) (if_statement) (with_statement) (try_statement) (match_statement) - (import_from_statement) (parameters) (argument_list) - (parenthesized_expression) (generator_expression) (list_comprehension) (set_comprehension) (dictionary_comprehension) - (tuple) (list) (set) (dictionary) - (string) ] @fold diff --git a/runtime/queries/python/highlights.scm b/runtime/queries/python/highlights.scm index 04398668e9..764521c7be 100644 --- a/runtime/queries/python/highlights.scm +++ b/runtime/queries/python/highlights.scm @@ -1,183 +1,223 @@ -;; From tree-sitter-python licensed under MIT License +; From tree-sitter-python licensed under MIT License ; Copyright (c) 2016 Max Brunsfeld - ; Variables (identifier) @variable ; Reset highlighting in f-string interpolations (interpolation) @none -;; Identifier naming conventions +; Identifier naming conventions ((identifier) @type - (#lua-match? @type "^[A-Z].*[a-z]")) + (#lua-match? @type "^[A-Z].*[a-z]")) + ((identifier) @constant - (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) + (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) ((identifier) @constant.builtin - (#lua-match? @constant.builtin "^__[a-zA-Z0-9_]*__$")) + (#lua-match? @constant.builtin "^__[a-zA-Z0-9_]*__$")) ((identifier) @constant.builtin - (#any-of? @constant.builtin - ;; https://docs.python.org/3/library/constants.html - "NotImplemented" - "Ellipsis" - "quit" - "exit" - "copyright" - "credits" - "license")) + ; format-ignore + (#any-of? @constant.builtin + ; https://docs.python.org/3/library/constants.html + "NotImplemented" "Ellipsis" + "quit" "exit" "copyright" "credits" "license")) "_" @constant.builtin ; match wildcard ((attribute - attribute: (identifier) @field) - (#lua-match? @field "^[%l_].*$")) + attribute: (identifier) @variable.member) + (#lua-match? @variable.member "^[%l_].*$")) ((assignment left: (identifier) @type.definition - (type (identifier) @_annotation)) - (#eq? @_annotation "TypeAlias")) + (type + (identifier) @_annotation)) + (#eq? @_annotation "TypeAlias")) ((assignment left: (identifier) @type.definition - right: (call - function: (identifier) @_func)) - (#any-of? @_func "TypeVar" "NewType")) + right: + (call + function: (identifier) @_func)) + (#any-of? @_func "TypeVar" "NewType")) ; Function calls - (call function: (identifier) @function.call) (call - function: (attribute - attribute: (identifier) @method.call)) + function: + (attribute + attribute: (identifier) @function.method.call)) ((call - function: (identifier) @constructor) - (#lua-match? @constructor "^%u")) + function: (identifier) @constructor) + (#lua-match? @constructor "^%u")) ((call - function: (attribute - attribute: (identifier) @constructor)) - (#lua-match? @constructor "^%u")) - -;; Decorators + function: + (attribute + attribute: (identifier) @constructor)) + (#lua-match? @constructor "^%u")) -((decorator "@" @attribute) - (#set! "priority" 101)) +; Decorators +((decorator + "@" @attribute) + (#set! "priority" 101)) (decorator (identifier) @attribute) + (decorator (attribute attribute: (identifier) @attribute)) + (decorator - (call (identifier) @attribute)) + (call + (identifier) @attribute)) + (decorator - (call (attribute - attribute: (identifier) @attribute))) + (call + (attribute + attribute: (identifier) @attribute))) ((decorator (identifier) @attribute.builtin) - (#any-of? @attribute.builtin "classmethod" "property")) - -;; Builtin functions + (#any-of? @attribute.builtin "classmethod" "property")) +; Builtin functions ((call function: (identifier) @function.builtin) - (#any-of? @function.builtin - "abs" "all" "any" "ascii" "bin" "bool" "breakpoint" "bytearray" "bytes" "callable" "chr" "classmethod" - "compile" "complex" "delattr" "dict" "dir" "divmod" "enumerate" "eval" "exec" "filter" "float" "format" - "frozenset" "getattr" "globals" "hasattr" "hash" "help" "hex" "id" "input" "int" "isinstance" "issubclass" - "iter" "len" "list" "locals" "map" "max" "memoryview" "min" "next" "object" "oct" "open" "ord" "pow" - "print" "property" "range" "repr" "reversed" "round" "set" "setattr" "slice" "sorted" "staticmethod" "str" - "sum" "super" "tuple" "type" "vars" "zip" "__import__")) - -;; Function definitions + (#any-of? @function.builtin "abs" "all" "any" "ascii" "bin" "bool" "breakpoint" "bytearray" "bytes" "callable" "chr" "classmethod" "compile" "complex" "delattr" "dict" "dir" "divmod" "enumerate" "eval" "exec" "filter" "float" "format" "frozenset" "getattr" "globals" "hasattr" "hash" "help" "hex" "id" "input" "int" "isinstance" "issubclass" "iter" "len" "list" "locals" "map" "max" "memoryview" "min" "next" "object" "oct" "open" "ord" "pow" "print" "property" "range" "repr" "reversed" "round" "set" "setattr" "slice" "sorted" "staticmethod" "str" "sum" "super" "tuple" "type" "vars" "zip" "__import__")) +; Function definitions (function_definition name: (identifier) @function) -(type (identifier) @type) +(type + (identifier) @type) + (type (subscript (identifier) @type)) ; type subscript: Tuple[int] ((call function: (identifier) @_isinstance - arguments: (argument_list - (_) - (identifier) @type)) - (#eq? @_isinstance "isinstance")) + arguments: + (argument_list + (_) + (identifier) @type)) + (#eq? @_isinstance "isinstance")) -;; Normal parameters +; Normal parameters (parameters - (identifier) @parameter) -;; Lambda parameters + (identifier) @variable.parameter) + +; Lambda parameters (lambda_parameters - (identifier) @parameter) + (identifier) @variable.parameter) + (lambda_parameters (tuple_pattern - (identifier) @parameter)) + (identifier) @variable.parameter)) + ; Default parameters (keyword_argument - name: (identifier) @parameter) + name: (identifier) @variable.parameter) + ; Naming parameters on call-site (default_parameter - name: (identifier) @parameter) + name: (identifier) @variable.parameter) + (typed_parameter - (identifier) @parameter) + (identifier) @variable.parameter) + (typed_default_parameter - (identifier) @parameter) + name: (identifier) @variable.parameter) + ; Variadic parameters *args, **kwargs (parameters (list_splat_pattern ; *args - (identifier) @parameter)) + (identifier) @variable.parameter)) + (parameters (dictionary_splat_pattern ; **kwargs - (identifier) @parameter)) + (identifier) @variable.parameter)) +; Typed variadic parameters +(parameters + (typed_parameter + (list_splat_pattern ; *args: type + (identifier) @variable.parameter))) -;; Literals +(parameters + (typed_parameter + (dictionary_splat_pattern ; *kwargs: type + (identifier) @variable.parameter))) + +; Lambda parameters +(lambda_parameters + (list_splat_pattern + (identifier) @variable.parameter)) +(lambda_parameters + (dictionary_splat_pattern + (identifier) @variable.parameter)) + +; Literals (none) @constant.builtin -[(true) (false)] @boolean + +[ + (true) + (false) +] @boolean + ((identifier) @variable.builtin - (#eq? @variable.builtin "self")) + (#eq? @variable.builtin "self")) + ((identifier) @variable.builtin - (#eq? @variable.builtin "cls")) + (#eq? @variable.builtin "cls")) (integer) @number -(float) @float + +(float) @number.float (comment) @comment @spell -((module . (comment) @preproc) - (#lua-match? @preproc "^#!/")) +((module + . + (comment) @keyword.directive) + (#lua-match? @keyword.directive "^#!/")) (string) @string + [ (escape_sequence) (escape_interpolation) ] @string.escape ; doc-strings - -(module . (expression_statement (string) @string.documentation @spell)) +(module + . + (expression_statement + (string) @string.documentation @spell)) (class_definition body: (block - . (expression_statement (string) @string.documentation @spell))) + . + (expression_statement + (string) @string.documentation @spell))) (function_definition body: (block - . (expression_statement (string) @string.documentation @spell))) + . + (expression_statement + (string) @string.documentation @spell))) ; Tokens - [ "-" "-=" @@ -227,7 +267,6 @@ "or" "is not" "not in" - "del" ] @keyword.operator @@ -258,19 +297,36 @@ "return" "yield" ] @keyword.return -(yield "from" @keyword.return) + +(yield + "from" @keyword.return) (future_import_statement - "from" @include + "from" @keyword.import "__future__" @constant.builtin) -(import_from_statement "from" @include) -"import" @include -(aliased_import "as" @include) +(import_from_statement + "from" @keyword.import) + +"import" @keyword.import -["if" "elif" "else" "match" "case"] @conditional +(aliased_import + "as" @keyword.import) -["for" "while" "break" "continue"] @repeat +[ + "if" + "elif" + "else" + "match" + "case" +] @keyword.conditional + +[ + "for" + "while" + "break" + "continue" +] @keyword.repeat [ "try" @@ -278,15 +334,23 @@ "except*" "raise" "finally" -] @exception +] @keyword.exception -(raise_statement "from" @exception) +(raise_statement + "from" @keyword.exception) (try_statement (else_clause - "else" @exception)) + "else" @keyword.exception)) -["(" ")" "[" "]" "{" "}"] @punctuation.bracket +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket (interpolation "{" @punctuation.special @@ -294,58 +358,80 @@ (type_conversion) @function.macro -["," "." ":" ";" (ellipsis)] @punctuation.delimiter - -;; Class definitions - -(class_definition name: (identifier) @type) +[ + "," + "." + ":" + ";" + (ellipsis) +] @punctuation.delimiter + +; Class definitions +(class_definition + name: (identifier) @type) (class_definition - body: (block - (function_definition - name: (identifier) @method))) + body: + (block + (function_definition + name: (identifier) @function.method))) (class_definition - superclasses: (argument_list - (identifier) @type)) + superclasses: + (argument_list + (identifier) @type)) ((class_definition - body: (block - (expression_statement - (assignment - left: (identifier) @field)))) - (#lua-match? @field "^%l.*$")) + body: + (block + (expression_statement + (assignment + left: (identifier) @variable.member)))) + (#lua-match? @variable.member "^%l.*$")) + ((class_definition - body: (block - (expression_statement - (assignment - left: (_ - (identifier) @field))))) - (#lua-match? @field "^%l.*$")) + body: + (block + (expression_statement + (assignment + left: + (_ + (identifier) @variable.member))))) + (#lua-match? @variable.member "^%l.*$")) ((class_definition (block (function_definition name: (identifier) @constructor))) - (#any-of? @constructor "__new__" "__init__")) + (#any-of? @constructor "__new__" "__init__")) ((identifier) @type.builtin - (#any-of? @type.builtin - ;; https://docs.python.org/3/library/exceptions.html - "BaseException" "Exception" "ArithmeticError" "BufferError" "LookupError" "AssertionError" "AttributeError" - "EOFError" "FloatingPointError" "GeneratorExit" "ImportError" "ModuleNotFoundError" "IndexError" "KeyError" - "KeyboardInterrupt" "MemoryError" "NameError" "NotImplementedError" "OSError" "OverflowError" "RecursionError" - "ReferenceError" "RuntimeError" "StopIteration" "StopAsyncIteration" "SyntaxError" "IndentationError" "TabError" - "SystemError" "SystemExit" "TypeError" "UnboundLocalError" "UnicodeError" "UnicodeEncodeError" "UnicodeDecodeError" - "UnicodeTranslateError" "ValueError" "ZeroDivisionError" "EnvironmentError" "IOError" "WindowsError" - "BlockingIOError" "ChildProcessError" "ConnectionError" "BrokenPipeError" "ConnectionAbortedError" - "ConnectionRefusedError" "ConnectionResetError" "FileExistsError" "FileNotFoundError" "InterruptedError" - "IsADirectoryError" "NotADirectoryError" "PermissionError" "ProcessLookupError" "TimeoutError" "Warning" - "UserWarning" "DeprecationWarning" "PendingDeprecationWarning" "SyntaxWarning" "RuntimeWarning" - "FutureWarning" "ImportWarning" "UnicodeWarning" "BytesWarning" "ResourceWarning" - ;; https://docs.python.org/3/library/stdtypes.html - "bool" "int" "float" "complex" "list" "tuple" "range" "str" - "bytes" "bytearray" "memoryview" "set" "frozenset" "dict" "type" "object")) - -;; Error -(ERROR) @error + ; format-ignore + (#any-of? @type.builtin + ; https://docs.python.org/3/library/exceptions.html + "BaseException" "Exception" "ArithmeticError" "BufferError" "LookupError" "AssertionError" "AttributeError" + "EOFError" "FloatingPointError" "GeneratorExit" "ImportError" "ModuleNotFoundError" "IndexError" "KeyError" + "KeyboardInterrupt" "MemoryError" "NameError" "NotImplementedError" "OSError" "OverflowError" "RecursionError" + "ReferenceError" "RuntimeError" "StopIteration" "StopAsyncIteration" "SyntaxError" "IndentationError" "TabError" + "SystemError" "SystemExit" "TypeError" "UnboundLocalError" "UnicodeError" "UnicodeEncodeError" "UnicodeDecodeError" + "UnicodeTranslateError" "ValueError" "ZeroDivisionError" "EnvironmentError" "IOError" "WindowsError" + "BlockingIOError" "ChildProcessError" "ConnectionError" "BrokenPipeError" "ConnectionAbortedError" + "ConnectionRefusedError" "ConnectionResetError" "FileExistsError" "FileNotFoundError" "InterruptedError" + "IsADirectoryError" "NotADirectoryError" "PermissionError" "ProcessLookupError" "TimeoutError" "Warning" + "UserWarning" "DeprecationWarning" "PendingDeprecationWarning" "SyntaxWarning" "RuntimeWarning" + "FutureWarning" "ImportWarning" "UnicodeWarning" "BytesWarning" "ResourceWarning" + ; https://docs.python.org/3/library/stdtypes.html + "bool" "int" "float" "complex" "list" "tuple" "range" "str" + "bytes" "bytearray" "memoryview" "set" "frozenset" "dict" "type" "object")) + +; Regex from the `re` module +(call + function: + (attribute + object: (identifier) @_re) + arguments: + (argument_list + . + (string + (string_content) @string.regexp)) + (#eq? @_re "re")) diff --git a/runtime/queries/query/highlights.scm b/runtime/queries/query/highlights.scm index f2d2ef6c7f..cdedb23e29 100644 --- a/runtime/queries/query/highlights.scm +++ b/runtime/queries/query/highlights.scm @@ -1,14 +1,30 @@ (string) @string + (escape_sequence) @string.escape -(capture (identifier) @type) -(anonymous_node (identifier) @string) -(predicate name: (identifier) @function) -(named_node name: (identifier) @variable) -(field_definition name: (identifier) @property) -(negated_field "!" @operator (identifier) @property) + +(capture + (identifier) @type) + +(anonymous_node + (identifier) @string) + +(predicate + name: (identifier) @function.call) + +(named_node + name: (identifier) @variable) + +(field_definition + name: (identifier) @property) + +(negated_field + "!" @operator + (identifier) @property) + (comment) @comment @spell (quantifier) @operator + (predicate_type) @punctuation.special "." @operator @@ -21,14 +37,51 @@ ] @punctuation.bracket ":" @punctuation.delimiter -["@" "#"] @punctuation.special + +[ + "@" + "#" +] @punctuation.special + "_" @constant -((parameters (identifier) @number) - (#match? @number "^[-+]?[0-9]+(.[0-9]+)?$")) +((parameters + (identifier) @number) + (#match? @number "^[-+]?[0-9]+(.[0-9]+)?$")) + +((program + . + (comment)* + . + (comment) @keyword.import) + (#lua-match? @keyword.import "^;+ *inherits *:")) + +((program + . + (comment)* + . + (comment) @keyword.directive) + (#lua-match? @keyword.directive "^;+ *extends *$")) + +((comment) @keyword.directive + (#lua-match? @keyword.directive "^;+%s*format%-ignore%s*$")) -((program . (comment)* . (comment) @include) - (#lua-match? @include "^;+ *inherits *:")) +((predicate + name: (identifier) @_name + parameters: + (parameters + (string + "\"" @string + "\"" @string) @string.regexp)) + (#any-of? @_name "match" "not-match" "vim-match" "not-vim-match" "lua-match" "not-lua-match")) -((program . (comment)* . (comment) @preproc) - (#lua-match? @preproc "^;+ *extends")) +((predicate + name: (identifier) @_name + parameters: + (parameters + (string + "\"" @string + "\"" @string) @string.regexp + . + (string) .)) + (#any-of? @_name "gsub" "not-gsub")) diff --git a/runtime/queries/vim/folds.scm b/runtime/queries/vim/folds.scm index 4c99735836..0a1fb695f3 100644 --- a/runtime/queries/vim/folds.scm +++ b/runtime/queries/vim/folds.scm @@ -1,4 +1,4 @@ [ - (if_statement) - (function_definition) + (if_statement) + (function_definition) ] @fold diff --git a/runtime/queries/vim/highlights.scm b/runtime/queries/vim/highlights.scm index 09188ddb68..54832ffa56 100644 --- a/runtime/queries/vim/highlights.scm +++ b/runtime/queries/vim/highlights.scm @@ -1,15 +1,15 @@ (identifier) @variable -((identifier) @constant - (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) -;; Keywords +((identifier) @constant + (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) +; Keywords [ "if" "else" "elseif" "endif" -] @conditional +] @keyword.conditional [ "try" @@ -17,7 +17,7 @@ "finally" "endtry" "throw" -] @exception +] @keyword.exception [ "for" @@ -27,31 +27,50 @@ "endwhile" "break" "continue" -] @repeat +] @keyword.repeat [ "function" "endfunction" ] @keyword.function -;; Function related -(function_declaration name: (_) @function) -(call_expression function: (identifier) @function.call) -(call_expression function: (scoped_identifier (identifier) @function.call)) -(parameters (identifier) @parameter) -(default_parameter (identifier) @parameter) +; Function related +(function_declaration + name: (_) @function) + +(call_expression + function: (identifier) @function.call) + +(call_expression + function: + (scoped_identifier + (identifier) @function.call)) -[ (bang) (spread) ] @punctuation.special +(parameters + (identifier) @variable.parameter) + +(default_parameter + (identifier) @variable.parameter) + +[ + (bang) + (spread) +] @punctuation.special + +[ + (no_option) + (inv_option) + (default_option) + (option_name) +] @variable.builtin -[ (no_option) (inv_option) (default_option) (option_name) ] @variable.builtin [ (scope) "a:" "$" -] @namespace - -;; Commands and user defined commands +] @module +; Commands and user defined commands [ "let" "unlet" @@ -83,6 +102,7 @@ "delcommand" "comclear" "colorscheme" + "scriptencoding" "startinsert" "stopinsert" "global" @@ -106,41 +126,48 @@ "visual" "view" "eval" + "sign" ] @keyword -(map_statement cmd: _ @keyword) + +(map_statement + cmd: _ @keyword) + (command_name) @function.macro -;; Filetype command - -(filetype_statement [ - "detect" - "plugin" - "indent" - "on" - "off" -] @keyword) - -;; Syntax command - -(syntax_statement (keyword) @string) -(syntax_statement [ - "enable" - "on" - "off" - "reset" - "case" - "spell" - "foldlevel" - "iskeyword" - "keyword" - "match" - "cluster" - "region" - "clear" - "include" -] @keyword) - -(syntax_argument name: _ @keyword) +; Filetype command +(filetype_statement + [ + "detect" + "plugin" + "indent" + "on" + "off" + ] @keyword) + +; Syntax command +(syntax_statement + (keyword) @string) + +(syntax_statement + [ + "enable" + "on" + "off" + "reset" + "case" + "spell" + "foldlevel" + "iskeyword" + "keyword" + "match" + "cluster" + "region" + "clear" + "include" + ] @keyword) + +(syntax_argument + name: _ @keyword) [ "<buffer>" @@ -151,70 +178,96 @@ "<unique>" ] @constant.builtin -(augroup_name) @namespace +(augroup_name) @module (au_event) @constant -(normal_statement (commands) @constant) -;; Highlight command +(normal_statement + (commands) @constant) +; Highlight command (hl_attribute key: _ @property val: _ @constant) (hl_group) @type -(highlight_statement [ - "default" - "link" - "clear" -] @keyword) - -;; Command command +(highlight_statement + [ + "default" + "link" + "clear" + ] @keyword) +; Command command (command) @string (command_attribute name: _ @property - val: (behavior - name: _ @constant - val: (identifier)? @function)?) + val: + (behavior + name: _ @constant + val: (identifier)? @function)?) -;; Edit command +; Edit command (plus_plus_opt val: _? @constant) @property -(plus_cmd "+" @property) @property - -;; Runtime command -(runtime_statement (where) @keyword.operator) +(plus_cmd + "+" @property) @property -;; Colorscheme command +; Runtime command +(runtime_statement + (where) @keyword.operator) -(colorscheme_statement (name) @string) +; Colorscheme command +(colorscheme_statement + (name) @string) -;; Literals +; Scriptencoding command +(scriptencoding_statement + (encoding) @string.special) +; Literals (string_literal) @string + (integer_literal) @number -(float_literal) @float + +(float_literal) @number.float + (comment) @comment @spell + (line_continuation_comment) @comment @spell + (pattern) @string.special -(pattern_multi) @string.regex -(filename) @string -(heredoc (body) @string) -(heredoc (parameter) @keyword) -[ (marker_definition) (endmarker) ] @label -(literal_dictionary (literal_key) @label) -((scoped_identifier - (scope) @_scope . (identifier) @boolean) - (#eq? @_scope "v:") - (#any-of? @boolean "true" "false")) -;; Operators +(pattern_multi) @string.regexp + +(filename) @string.special.path + +(heredoc + (body) @string) + +(heredoc + (parameter) @keyword) [ + (marker_definition) + (endmarker) +] @label + +(literal_dictionary + (literal_key) @property) + +((scoped_identifier + (scope) @_scope + . + (identifier) @boolean) + (#eq? @_scope "v:") + (#any-of? @boolean "true" "false")) + +; Operators +[ "||" "&&" "&" @@ -248,12 +301,13 @@ ] @operator ; Some characters have different meanings based on the context -(unary_operation "!" @operator) -(binary_operation "." @operator) - +(unary_operation + "!" @operator) -;; Punctuation +(binary_operation + "." @operator) +; Punctuation [ "(" ")" @@ -264,27 +318,31 @@ "#{" ] @punctuation.bracket -(field_expression "." @punctuation.delimiter) +(field_expression + "." @punctuation.delimiter) [ "," ":" ] @punctuation.delimiter -(ternary_expression ["?" ":"] @conditional.ternary) +(ternary_expression + [ + "?" + ":" + ] @keyword.conditional.ternary) ; Options ((set_value) @number - (#lua-match? @number "^[%d]+(%.[%d]+)?$")) + (#lua-match? @number "^[%d]+(%.[%d]+)?$")) + +(inv_option + "!" @operator) -(inv_option "!" @operator) -(set_item "?" @operator) +(set_item + "?" @operator) ((set_item - option: (option_name) @_option - value: (set_value) @function) - (#any-of? @_option - "tagfunc" "tfu" - "completefunc" "cfu" - "omnifunc" "ofu" - "operatorfunc" "opfunc")) + option: (option_name) @_option + value: (set_value) @function) + (#any-of? @_option "tagfunc" "tfu" "completefunc" "cfu" "omnifunc" "ofu" "operatorfunc" "opfunc")) diff --git a/runtime/queries/vim/injections.scm b/runtime/queries/vim/injections.scm index 50f0190112..16ec57ca99 100644 --- a/runtime/queries/vim/injections.scm +++ b/runtime/queries/vim/injections.scm @@ -1,48 +1,32 @@ -((lua_statement (script (body) @injection.content)) - (#set! injection.language "lua")) +(lua_statement + (script + (body) @injection.content + (#set! injection.language "lua"))) -((lua_statement (chunk) @injection.content) - (#set! injection.language "lua")) +(lua_statement + (chunk) @injection.content + (#set! injection.language "lua")) -((ruby_statement (script (body) @injection.content)) - (#set! injection.language "ruby")) +(ruby_statement + (script + (body) @injection.content + (#set! injection.language "ruby"))) -((ruby_statement (chunk) @injection.content) - (#set! injection.language "ruby")) +(ruby_statement + (chunk) @injection.content + (#set! injection.language "ruby")) -((python_statement (script (body) @injection.content)) - (#set! injection.language "python")) +(python_statement + (script + (body) @injection.content + (#set! injection.language "python"))) -((python_statement (chunk) @injection.content) - (#set! injection.language "python")) - -;; If we support perl at some point... -;; ((perl_statement (script (body) @injection.content)) -;; (#set! injection.language "perl")) -;; ((perl_statement (chunk) @injection.content) -;; (#set! injection.language "perl")) - -((autocmd_statement (pattern) @injection.content) - (#set! injection.language "regex")) +(python_statement + (chunk) @injection.content + (#set! injection.language "python")) ((set_item - option: (option_name) @_option - value: (set_value) @injection.content) - (#any-of? @_option - "includeexpr" "inex" - "printexpr" "pexpr" - "formatexpr" "fex" - "indentexpr" "inde" - "foldtext" "fdt" - "foldexpr" "fde" - "diffexpr" "dex" - "patchexpr" "pex" - "charconvert" "ccv") + option: (option_name) @_option + value: (set_value) @injection.content) + (#any-of? @_option "includeexpr" "inex" "printexpr" "pexpr" "formatexpr" "fex" "indentexpr" "inde" "foldtext" "fdt" "foldexpr" "fde" "diffexpr" "dex" "patchexpr" "pex" "charconvert" "ccv") (#set! injection.language "vim")) - - -; ((comment) @injection.content -; (#set! injection.language "comment")) - -; ((line_continuation_comment) @injection.content -; (#set! injection.language "comment")) diff --git a/runtime/queries/vimdoc/highlights.scm b/runtime/queries/vimdoc/highlights.scm index e0dce49b2a..294fa94f10 100644 --- a/runtime/queries/vimdoc/highlights.scm +++ b/runtime/queries/vimdoc/highlights.scm @@ -1,25 +1,58 @@ -(h1) @text.title.1 -(h2) @text.title.2 -(h3) @text.title.3 -(column_heading) @text.title.4 +(h1) @markup.heading.1 + +(h2) @markup.heading.2 + +(h3) @markup.heading.3 + +(column_heading) @markup.heading.4 + (column_heading - "~" @conceal (#set! conceal "")) + "~" @markup.heading.4.marker + (#set! conceal "")) + (tag - "*" @conceal (#set! conceal "") - text: (_) @label) + "*" @markup.heading.5.marker + (#set! conceal "") + text: (_) @label) + (taglink - "|" @conceal (#set! conceal "") - text: (_) @text.reference) + "|" @markup.link + (#set! conceal "") + text: (_) @markup.link) + (optionlink - text: (_) @text.reference) + text: (_) @markup.link) + (codespan - "`" @conceal (#set! conceal "") - text: (_) @text.literal) -(codeblock) @text.literal + "`" @markup.raw.delimiter + (#set! conceal "") + text: (_) @markup.raw) + +((codeblock) @markup.raw.block + (#set! "priority" 90)) + (codeblock - [">" (language)] @conceal (#set! conceal "")) + [ + ">" + (language) + ] @markup.raw.delimiter + (#set! conceal "")) + (block - "<" @conceal (#set! conceal "")) -(argument) @parameter + "<" @markup.raw.delimiter + (#set! conceal "")) + +(argument) @variable.parameter + (keycode) @string.special -(url) @text.uri + +(url) @string.special.url + +((note) @comment.note + (#any-of? @comment.note "Note:" "NOTE:" "Notes:")) + +((note) @comment.warning + (#any-of? @comment.warning "Warning:" "WARNING:")) + +((note) @comment.error + (#any-of? @comment.error "Deprecated:" "DEPRECATED:")) diff --git a/runtime/queries/vimdoc/injections.scm b/runtime/queries/vimdoc/injections.scm index 260a05d863..3b8fbf0f36 100644 --- a/runtime/queries/vimdoc/injections.scm +++ b/runtime/queries/vimdoc/injections.scm @@ -1,4 +1,4 @@ ((codeblock (language) @injection.language (code) @injection.content) - (#set! injection.include-children)) + (#set! injection.include-children)) diff --git a/scripts/gen_lsp.lua b/scripts/gen_lsp.lua index 0e7eb38cca..b332a17fdc 100644 --- a/scripts/gen_lsp.lua +++ b/scripts/gen_lsp.lua @@ -159,11 +159,13 @@ function M.gen(opt) local output = { '--' .. '[[', - 'This file is autogenerated from scripts/gen_lsp.lua', + 'THIS FILE IS GENERATED by scripts/gen_lsp.lua', + 'DO NOT EDIT MANUALLY', + '', + 'Based on LSP protocol ' .. opt.version, + '', 'Regenerate:', - ([=[nvim -l scripts/gen_lsp.lua gen --version %s --out runtime/lua/vim/lsp/_meta/protocol.lua]=]):format( - DEFAULT_LSP_VERSION - ), + ([=[nvim -l scripts/gen_lsp.lua gen --version %s]=]):format(DEFAULT_LSP_VERSION), '--' .. ']]', '', '---@meta', @@ -171,12 +173,9 @@ function M.gen(opt) '', '---@alias lsp.null nil', '---@alias uinteger integer', - '---@alias lsp.decimal number', + '---@alias decimal number', '---@alias lsp.DocumentUri string', '---@alias lsp.URI string', - '---@alias lsp.LSPObject table<string, lsp.LSPAny>', - '---@alias lsp.LSPArray lsp.LSPAny[]', - '---@alias lsp.LSPAny lsp.LSPObject|lsp.LSPArray|string|number|boolean|nil', '', } diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 98a9301da6..4f9edad6a8 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -1,7 +1,11 @@ add_library(main_lib INTERFACE) -add_executable(nvim) -set_target_properties(nvim +# Internally we need to make a distinction between "nvim without runtime files" +# (nvim_bin) and "nvim with runtime files" (nvim). +add_executable(nvim_bin EXCLUDE_FROM_ALL) +set_target_properties(nvim_bin PROPERTIES OUTPUT_NAME nvim) + +set_target_properties(nvim_bin PROPERTIES EXPORT_COMPILE_COMMANDS ON ENABLE_EXPORTS TRUE) @@ -115,7 +119,7 @@ elseif(MINGW) target_compile_definitions(main_lib INTERFACE __USE_MINGW_ANSI_STDIO) # Enable wmain - target_link_libraries(nvim PRIVATE -municode) + target_link_libraries(nvim_bin PRIVATE -municode) elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") if(CMAKE_C_COMPILER_VERSION VERSION_LESS 10) target_compile_options(main_lib INTERFACE -Wno-conversion) @@ -134,7 +138,7 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") # workaround for clang-11 on macOS, supported on later versions if(NOT APPLE) - target_link_libraries(nvim PRIVATE -Wl,--no-undefined) + target_link_libraries(nvim_bin PRIVATE -Wl,--no-undefined) endif() endif() @@ -150,16 +154,16 @@ if(CMAKE_SYSTEM_NAME MATCHES "Windows") target_compile_definitions(main_lib INTERFACE _WIN32_WINNT=0x0602 MSWIN) target_link_libraries(main_lib INTERFACE netapi32) elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") - target_link_libraries(nvim PRIVATE "-framework CoreServices") + target_link_libraries(nvim_bin PRIVATE "-framework CoreServices") # Actually export symbols - symbols may not be visible even though # ENABLE_EXPORTS is set to true. See # https://github.com/neovim/neovim/issues/25295 - target_link_options(nvim PRIVATE "-Wl,-export_dynamic") + target_link_options(nvim_bin PRIVATE "-Wl,-export_dynamic") elseif(CMAKE_SYSTEM_NAME MATCHES "OpenBSD") target_link_libraries(main_lib INTERFACE pthread c++abi) elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS") - target_link_libraries(nvim PRIVATE -lsocket) + target_link_libraries(nvim_bin PRIVATE -lsocket) endif() check_c_compiler_flag(-Wimplicit-fallthrough HAVE_WIMPLICIT_FALLTHROUGH_FLAG) @@ -205,35 +209,35 @@ if(ENABLE_ASAN_UBSAN) if(NOT MSVC) if(CI_BUILD) # Try to recover from all sanitize issues so we get reports about all failures - target_compile_options(nvim PRIVATE -fsanitize-recover=all) + target_compile_options(nvim_bin PRIVATE -fsanitize-recover=all) else() - target_compile_options(nvim PRIVATE -fno-sanitize-recover=all) + target_compile_options(nvim_bin PRIVATE -fno-sanitize-recover=all) endif() - target_compile_options(nvim PRIVATE + target_compile_options(nvim_bin PRIVATE -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=undefined) endif() - target_compile_options(nvim PRIVATE -fsanitize=address) - target_link_libraries(nvim PRIVATE -fsanitize=address -fsanitize=undefined) - target_compile_definitions(nvim PRIVATE ENABLE_ASAN_UBSAN) + target_compile_options(nvim_bin PRIVATE -fsanitize=address) + target_link_libraries(nvim_bin PRIVATE -fsanitize=address -fsanitize=undefined) + target_compile_definitions(nvim_bin PRIVATE ENABLE_ASAN_UBSAN) endif() if(ENABLE_MSAN) message(STATUS "Enabling memory sanitizer for nvim.") - target_compile_options(nvim PRIVATE + target_compile_options(nvim_bin PRIVATE -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fno-optimize-sibling-calls) - target_link_libraries(nvim PRIVATE -fsanitize=memory -fsanitize-memory-track-origins) + target_link_libraries(nvim_bin PRIVATE -fsanitize=memory -fsanitize-memory-track-origins) endif() if(ENABLE_TSAN) message(STATUS "Enabling thread sanitizer for nvim.") - target_compile_options(nvim PRIVATE -fsanitize=thread -fPIE) - target_link_libraries(nvim PRIVATE -fsanitize=thread) + target_compile_options(nvim_bin PRIVATE -fsanitize=thread -fPIE) + target_link_libraries(nvim_bin PRIVATE -fsanitize=thread) endif() option(CI_BUILD "CI, extra flags will be set" OFF) @@ -254,7 +258,7 @@ if(ENABLE_IWYU) string(APPEND iwyu_flags "-Xiwyu;--no_fwd_decls;") string(APPEND iwyu_flags "-Xiwyu;--mapping_file=${PROJECT_SOURCE_DIR}/cmake.config/iwyu/mapping.imp") - set_target_properties(nvim PROPERTIES C_INCLUDE_WHAT_YOU_USE "${iwyu_flags}") + set_target_properties(nvim_bin PROPERTIES C_INCLUDE_WHAT_YOU_USE "${iwyu_flags}") target_compile_definitions(main_lib INTERFACE EXITFREE) endif() @@ -284,7 +288,7 @@ endif() #------------------------------------------------------------------------------- set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack) -set(BINARY_LIB_DIR ${PROJECT_BINARY_DIR}/lib/nvim/) +set(BINARY_LIB_DIR ${PROJECT_BINARY_DIR}/lib/nvim) set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include) set(GENERATOR_DIR ${CMAKE_CURRENT_LIST_DIR}/generators) @@ -436,7 +440,7 @@ if(CI_BUILD) # TODO(bfredl): debug log level also exposes some errors with EXITFREE in ASAN build. else() # Minimize logging for release-type builds. - target_compile_definitions(nvim PRIVATE $<$<CONFIG:Debug>:NVIM_LOG_DEBUG>) + target_compile_definitions(nvim_bin PRIVATE $<$<CONFIG:Debug>:NVIM_LOG_DEBUG>) endif() if(ENABLE_ASAN_UBSAN OR ENABLE_MSAN OR ENABLE_TSAN) @@ -685,8 +689,8 @@ if(PREFER_LUA) message(STATUS "luajit not used, skipping unit tests") else() file(GLOB UNIT_TEST_FIXTURES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c) - target_sources(nvim PRIVATE ${UNIT_TEST_FIXTURES}) - target_compile_definitions(nvim PRIVATE UNIT_TESTING) + target_sources(nvim_bin PRIVATE ${UNIT_TEST_FIXTURES}) + target_compile_definitions(nvim_bin PRIVATE UNIT_TESTING) endif() target_sources(main_lib INTERFACE @@ -700,32 +704,33 @@ target_sources(main_lib INTERFACE target_sources(nlua0 PUBLIC ${NLUA0_SOURCES}) -target_link_libraries(nvim PRIVATE main_lib PUBLIC libuv) -install_helper(TARGETS nvim) +target_link_libraries(nvim_bin PRIVATE main_lib PUBLIC libuv) +install_helper(TARGETS nvim_bin) if(MSVC) - install(FILES $<TARGET_PDB_FILE:nvim> DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) + install(FILES $<TARGET_PDB_FILE:nvim_bin> DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) endif() if(ENABLE_LTO) include(CheckIPOSupported) check_ipo_supported(RESULT IPO_SUPPORTED) if(IPO_SUPPORTED) - set_target_properties(nvim PROPERTIES + set_target_properties(nvim_bin PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL TRUE) endif() endif() +add_custom_target(nvim_runtime_deps) if(WIN32) # Copy DLLs and third-party tools to bin/ and install them along with nvim - add_custom_target(nvim_runtime_deps ALL - COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps/ + add_custom_command(TARGET nvim_runtime_deps + COMMAND ${CMAKE_COMMAND} -E ${COPY_DIRECTORY} ${PROJECT_BINARY_DIR}/windows_runtime_deps/ ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) install(DIRECTORY ${PROJECT_BINARY_DIR}/windows_runtime_deps/ DESTINATION ${CMAKE_INSTALL_BINDIR}) - add_custom_target(nvim_dll_deps DEPENDS nvim + add_custom_target(nvim_dll_deps DEPENDS nvim_bin COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps COMMAND ${CMAKE_COMMAND} -D CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} @@ -755,22 +760,17 @@ if(WIN32) add_custom_target(external_blobs COMMAND ${CMAKE_COMMAND} -P ${PROJECT_BINARY_DIR}/external_blobs.cmake) add_dependencies(nvim_runtime_deps external_blobs) -else() - add_custom_target(nvim_runtime_deps) # Stub target to avoid CMP0046. endif() file(MAKE_DIRECTORY ${BINARY_LIB_DIR}) # install treesitter parser if bundled if(EXISTS ${DEPS_PREFIX}/lib/nvim/parser) - file(GLOB TREESITTER_PARSERS CONFIGURE_DEPENDS ${DEPS_PREFIX}/lib/nvim/parser/*) - foreach(parser_lib ${TREESITTER_PARSERS}) - file(COPY ${parser_lib} DESTINATION ${BINARY_LIB_DIR}/parser) - endforeach() + add_custom_command(TARGET nvim_runtime_deps COMMAND ${CMAKE_COMMAND} -E ${COPY_DIRECTORY} ${DEPS_PREFIX}/lib/nvim/parser ${BINARY_LIB_DIR}/parser) endif() install(DIRECTORY ${BINARY_LIB_DIR} - DESTINATION ${CMAKE_INSTALL_LIBDIR}/nvim/ + DESTINATION ${CMAKE_INSTALL_LIBDIR} USE_SOURCE_PERMISSIONS) if(NOT PREFER_LUA) @@ -842,7 +842,7 @@ add_glob_target( add_custom_target(copy_compile_commands COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/compile_commands.json ${PROJECT_SOURCE_DIR}/compile_commands.json) -add_dependencies(copy_compile_commands nvim) +add_dependencies(copy_compile_commands nvim_bin) add_dependencies(lintc-clang-tidy copy_compile_commands) add_dependencies(clang-analyzer copy_compile_commands) @@ -926,7 +926,7 @@ add_custom_command( OUTPUT ${MPACK_FILES} COMMAND ${PROJECT_SOURCE_DIR}/scripts/gen_vimdoc.py DEPENDS - nvim + nvim_bin ${API_SOURCES} ${LUA_SOURCES} ${VIMDOC_FILES} @@ -938,7 +938,7 @@ add_custom_command( add_custom_command( OUTPUT ${GEN_EVAL_TOUCH} COMMAND ${CMAKE_COMMAND} -E touch ${GEN_EVAL_TOUCH} - COMMAND $<TARGET_FILE:nvim> -l ${PROJECT_SOURCE_DIR}/scripts/gen_eval_files.lua + COMMAND $<TARGET_FILE:nvim_bin> -l ${PROJECT_SOURCE_DIR}/scripts/gen_eval_files.lua DEPENDS ${API_METADATA} ${NVIM_RUNTIME_DIR}/doc/api.mpack diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index fd07ec96fe..d7e1aa2d0f 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -215,8 +215,8 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, return extmark_to_array(extmark, false, details, hl_name); } -/// Gets |extmarks| (including |signs|) in "traversal order" from a |charwise| -/// region defined by buffer positions (inclusive, 0-indexed |api-indexing|). +/// Gets |extmarks| in "traversal order" from a |charwise| region defined by +/// buffer positions (inclusive, 0-indexed |api-indexing|). /// /// Region can be given as (row,col) tuples, or valid extmark ids (whose /// positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1) @@ -234,6 +234,10 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, /// the `overlap` option might be useful. Otherwise only the start position /// of an extmark will be considered. /// +/// Note: legacy signs placed through the |:sign| commands are implemented +/// as extmarks and will show up here. Their details array will contain a +/// `sign_name` field. +/// /// Example: /// /// ```lua @@ -434,7 +438,9 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e /// if text around the mark was deleted and then restored by undo. /// Defaults to true. /// - invalidate : boolean that indicates whether to hide the -/// extmark if the entirety of its range is deleted. If +/// extmark if the entirety of its range is deleted. For +/// hidden marks, an "invalid" key is added to the "details" +/// array of |nvim_buf_get_extmarks()| and family. If /// "undo_restore" is false, the extmark is deleted instead. /// - priority: a priority value for the highlight group or sign /// attribute. For example treesitter highlighting uses a diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index bda0c72423..c2f02c34f8 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -39,6 +39,8 @@ void screenshot(String path) FUNC_API_SINCE(7); void option_set(String name, Object value) FUNC_API_SINCE(4); +void chdir(String path) + FUNC_API_SINCE(12); // Stop event is not exported as such, represented by EOF in the msgpack stream. void stop(void) FUNC_API_NOEXPORT; diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 7cce6b3ad1..5224a07fd9 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -975,19 +975,19 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name) if (sh_hl.hl_id) { PUT(*dict, "hl_group", hl_group_name(sh_hl.hl_id, hl_name)); PUT(*dict, "hl_eol", BOOLEAN_OBJ(sh_hl.flags & kSHHlEol)); - if (sh_hl.flags & kSHConceal) { - char buf[MAX_SCHAR_SIZE]; - schar_get(buf, sh_hl.text[0]); - PUT(*dict, "conceal", CSTR_TO_OBJ(buf)); - } + priority = sh_hl.priority; + } - if (sh_hl.flags & kSHSpellOn) { - PUT(*dict, "spell", BOOLEAN_OBJ(true)); - } else if (sh_hl.flags & kSHSpellOff) { - PUT(*dict, "spell", BOOLEAN_OBJ(false)); - } + if (sh_hl.flags & kSHConceal) { + char buf[MAX_SCHAR_SIZE]; + schar_get(buf, sh_hl.text[0]); + PUT(*dict, "conceal", CSTR_TO_OBJ(buf)); + } - priority = sh_hl.priority; + if (sh_hl.flags & kSHSpellOn) { + PUT(*dict, "spell", BOOLEAN_OBJ(true)); + } else if (sh_hl.flags & kSHSpellOff) { + PUT(*dict, "spell", BOOLEAN_OBJ(false)); } if (sh_hl.flags & kSHUIWatched) { diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index 0321a11b0f..4e4db93a7b 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -150,7 +150,11 @@ void extmark_del(buf_T *buf, MarkTreeIter *itr, MTKey key, bool restore) } if (mt_decor_any(key)) { - buf_decor_remove(buf, key.pos.row, key2.pos.row, mt_decor(key), true); + if (mt_invalid(key)) { + decor_free(mt_decor(key)); + } else { + buf_decor_remove(buf, key.pos.row, key2.pos.row, mt_decor(key), true); + } } // TODO(bfredl): delete it from current undo header, opportunistically? @@ -352,14 +356,12 @@ void extmark_splice_delete(buf_T *buf, int l_row, colnr_T l_col, int u_row, coln // Push mark to undo header if (only_copy || (uvp != NULL && op == kExtmarkUndo && !mt_no_undo(mark))) { - ExtmarkSavePos pos; - pos.mark = mt_lookup_key(mark); - pos.invalidated = invalidated; - pos.old_row = mark.pos.row; - pos.old_col = mark.pos.col; - pos.row = -1; - pos.col = -1; - + ExtmarkSavePos pos = { + .mark = mt_lookup_key(mark), + .invalidated = invalidated, + .old_row = mark.pos.row, + .old_col = mark.pos.col + }; undo.data.savepos = pos; undo.type = kExtmarkSavePos; kv_push(*uvp, undo); @@ -393,22 +395,17 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) } else if (undo_info.type == kExtmarkSavePos) { ExtmarkSavePos pos = undo_info.data.savepos; if (undo) { - if (pos.old_row >= 0) { - extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col); - } - if (pos.invalidated) { + if (pos.old_row >= 0 + && extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col) + && pos.invalidated) { MarkTreeIter itr[1] = { 0 }; MTKey mark = marktree_lookup(curbuf->b_marktree, pos.mark, itr); mt_itr_rawkey(itr).flags &= (uint16_t) ~MT_FLAG_INVALID; MTPos end = marktree_get_altpos(curbuf->b_marktree, mark, itr); buf_put_decor(curbuf, mt_decor(mark), mark.pos.row, end.row); } - // Redo - } else { - if (pos.row >= 0) { - extmark_setraw(curbuf, pos.mark, pos.row, pos.col); - } } + // No Redo since kExtmarkSplice will move marks back } else if (undo_info.type == kExtmarkMove) { ExtmarkMove move = undo_info.data.move; if (undo) { diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h index a68bbf33f2..b1ef5cf214 100644 --- a/src/nvim/extmark.h +++ b/src/nvim/extmark.h @@ -45,8 +45,6 @@ typedef struct { uint64_t mark; // raw mark id of the marktree int old_row; colnr_T old_col; - int row; - colnr_T col; bool invalidated; } ExtmarkSavePos; diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 9c12a5bda1..e9fd1c3f44 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -230,60 +230,98 @@ static const char *highlight_init_both[] = { "default link DiagnosticSignOk DiagnosticOk", "default link DiagnosticUnnecessary Comment", - // Text - "default link @text.literal Comment", - "default link @text.reference Identifier", - "default link @text.title Title", - "default link @text.uri Underlined", - "default link @text.underline Underlined", - "default link @text.todo Todo", - - // Miscs - "default link @comment Comment", - "default link @punctuation Delimiter", - - // Constants + // Treesitter standard groups + "default link @variable NONE", // don't highlight to reduce visual overload + "default link @variable.builtin Special", + "default link @variable.parameter Identifier", + "default link @variable.member Identifier", + "default link @constant Constant", "default link @constant.builtin Special", "default link @constant.macro Define", - "default link @define Define", - "default link @macro Macro", - "default link @string String", - "default link @string.escape SpecialChar", - "default link @string.special SpecialChar", - "default link @character Character", - "default link @character.special SpecialChar", - "default link @number Number", - "default link @boolean Boolean", - "default link @float Float", - - // Functions - "default link @function Function", - "default link @function.builtin Special", - "default link @function.macro Macro", - "default link @parameter Identifier", - "default link @method Function", - "default link @field Identifier", - "default link @property Identifier", - "default link @constructor Special", - - // Keywords - "default link @conditional Conditional", - "default link @repeat Repeat", - "default link @label Label", - "default link @operator Operator", - "default link @keyword Keyword", - "default link @exception Exception", - - "default link @variable NONE", // don't highlight to reduce visual overload - "default link @type Type", - "default link @type.definition Typedef", - "default link @storageclass StorageClass", - "default link @namespace Identifier", - "default link @include Include", - "default link @preproc PreProc", - "default link @debug Debug", - "default link @tag Tag", + + "default link @module Structure", + "default link @label Label", + + "default link @string String", + "default link @string.regexp SpecialChar", + "default link @string.escape SpecialChar", + "default link @string.special SpecialChar", + "default link @string.special.symbol Constant", + "default link @string.special.url Underlined", + + "default link @character Character", + "default link @character.special SpecialChar", + + "default link @boolean Boolean", + "default link @number Number", + "default link @number.float Float", + + "default link @type Type", + "default link @type.builtin Special", + "default link @type.definition Typedef", + "default link @type.qualifier StorageClass", + + "default link @attribute Macro", + "default link @property Identifier", + + "default link @function Function", + "default link @function.builtin Special", + "default link @function.macro Macro", + + "default link @constructor Special", + "default link @operator Operator", + + "default link @keyword Keyword", + "default link @keyword.function Statement", + "default link @keyword.operator Operator", + "default link @keyword.import Include", + "default link @keyword.storage StorageClass", + "default link @keyword.repeat Repeat", + "default link @keyword.debug Debug", + "default link @keyword.exception Exception", + + "default link @keyword.conditional Conditional", + + "default link @keyword.directive Preproc", + "default link @keyword.directive.define Define", + + "default link @punctuation.delimiter Delimiter", + "default link @punctuation.bracket Delimiter", + "default link @punctuation.special Special", + + "default link @comment Comment", + + "default link @comment.error DiagnosticError", + "default link @comment.warning DiagnosticWarn", + "default link @comment.note DiagnosticInfo", + "default link @comment.todo Todo", + + "@markup.strong gui=bold cterm=bold", + "@markup.italic gui=italic cterm=italic", + "@markup.strikethrough gui=strikethrough, cterm=strikethrough", + "@markup.underline gui=underline, cterm=underline", + + "default link @markup.heading Title", + + "default link @markup.raw Comment", + "default link @markup.quote Comment", + "default link @markup.math Comment", + "default link @markup.environment Comment", + + "default link @markup.link Underlined", + "default link @markup.link.label Identifier", + + "default link @markup.list Special", + "default link @markup.list.checked DiagnosticOk", + "default link @markup.list.unchecked DiagnosticWarn", + + "default link @diff.plus Added", + "default link @diff.minus Removed", + "default link @diff.delta Changed", + + "default link @tag Tag", + "default link @tag.delimiter Delimiter", // LSP semantic tokens "default link @lsp.type.class Structure", diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index a8af2168c5..d36fbb32d7 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -36,6 +36,7 @@ #include "nvim/lua/executor.h" #include "nvim/macros_defs.h" #include "nvim/mapping.h" +#include "nvim/mapping_defs.h" #include "nvim/mbyte.h" #include "nvim/mbyte_defs.h" #include "nvim/memory.h" @@ -142,20 +143,6 @@ mapblock_T *get_buf_maphash_list(int state, int c) return curbuf->b_maphash[MAP_HASH(state, c)]; } -/// Retrieve the mapblock at the index either globally or for a certain buffer -/// -/// @param index The index in the maphash[] -/// @param buf The buffer to get the maphash from. NULL for global -mapblock_T *get_maphash(int index, buf_T *buf) - FUNC_ATTR_PURE -{ - if (index >= MAX_MAPHASH) { - return NULL; - } - - return (buf == NULL) ? maphash[index] : buf->b_maphash[index]; -} - /// Delete one entry from the abbrlist or maphash[]. /// "mpp" is a pointer to the m_next field of the PREVIOUS entry! static void mapblock_free(mapblock_T **mpp) @@ -2820,16 +2807,23 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf) { Array mappings = ARRAY_DICT_INIT; - // Convert the string mode to the integer mode - // that is stored within each mapblock - char *p = mode.data; - int int_mode = get_map_mode(&p, 0); + char *p = mode.size > 0 ? mode.data : "m"; + bool forceit = *p == '!'; + // Convert the string mode to the integer mode stored within each mapblock. + int int_mode = get_map_mode(&p, forceit); + if (forceit) { + assert(p == mode.data); + p++; + } + bool is_abbrev = (int_mode & (MODE_INSERT | MODE_CMDLINE)) != 0 && *p == 'a'; // Determine the desired buffer value int buffer_value = (buf == NULL) ? 0 : buf->handle; - for (int i = 0; i < MAX_MAPHASH; i++) { - for (const mapblock_T *current_maphash = get_maphash(i, buf); + for (int i = 0; i < (is_abbrev ? 1 : MAX_MAPHASH); i++) { + for (const mapblock_T *current_maphash = is_abbrev + ? (buf ? buf->b_first_abbr : first_abbr) + : (buf ? buf->b_maphash[i] : maphash[i]); current_maphash; current_maphash = current_maphash->m_next) { if (current_maphash->m_simplified) { @@ -2839,7 +2833,7 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf) if (int_mode & current_maphash->m_mode) { ADD(mappings, DICTIONARY_OBJ(mapblock_fill_dict(current_maphash, NULL, - buffer_value, false, false))); + buffer_value, is_abbrev, false))); } } } diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 286bb8098a..0178ef622b 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -304,8 +304,11 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data, p->read_ptr = rbuffer_read_ptr(rbuf, &size); p->read_size = size; parse_msgpack(channel); - size_t consumed = size - p->read_size; - rbuffer_consumed_compact(rbuf, consumed); + + if (!unpacker_closed(p)) { + size_t consumed = size - p->read_size; + rbuffer_consumed_compact(rbuf, consumed); + } end: channel_decref(channel); diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 09203990bb..d80539708d 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -33,6 +33,7 @@ # include <sys/xattr.h> #endif +#include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/gettext_defs.h" #include "nvim/globals.h" @@ -44,6 +45,7 @@ #include "nvim/os/os.h" #include "nvim/path.h" #include "nvim/types_defs.h" +#include "nvim/ui.h" #include "nvim/vim_defs.h" #ifdef HAVE_SYS_UIO_H @@ -90,7 +92,11 @@ int os_chdir(const char *path) smsg(0, "chdir(%s)", path); verbose_leave(); } - return uv_chdir(path); + int err = uv_chdir(path); + if (err == 0) { + ui_call_chdir(cstr_as_string((char *)path)); + } + return err; } /// Get the name of current directory. diff --git a/src/nvim/po/CMakeLists.txt b/src/nvim/po/CMakeLists.txt index 68e572911c..a4c95df3f1 100644 --- a/src/nvim/po/CMakeLists.txt +++ b/src/nvim/po/CMakeLists.txt @@ -53,16 +53,16 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG) list(SORT NVIM_RELATIVE_SOURCES) add_custom_command( OUTPUT ${NVIM_POT} - COMMAND $<TARGET_FILE:nvim> -u NONE -i NONE -n --headless --cmd "set cpo+=+" + COMMAND $<TARGET_FILE:nvim_bin> -u NONE -i NONE -n --headless --cmd "set cpo+=+" -S ${CMAKE_CURRENT_SOURCE_DIR}/tojavascript.vim ${NVIM_POT} ${PROJECT_SOURCE_DIR}/runtime/optwin.vim COMMAND ${XGETTEXT_PRG} -o ${NVIM_POT} --default-domain=nvim --add-comments --keyword=_ --keyword=N_ --keyword=NGETTEXT:1,2 -D ${CMAKE_CURRENT_SOURCE_DIR} -D ${CMAKE_CURRENT_BINARY_DIR} ${NVIM_RELATIVE_SOURCES} optwin.js - COMMAND $<TARGET_FILE:nvim> -u NONE -i NONE -n --headless --cmd "set cpo+=+" + COMMAND $<TARGET_FILE:nvim_bin> -u NONE -i NONE -n --headless --cmd "set cpo+=+" -S ${CMAKE_CURRENT_SOURCE_DIR}/fixfilenames.vim ${NVIM_POT} ../../../runtime/optwin.vim VERBATIM - DEPENDS ${NVIM_SOURCES} nvim nvim_runtime_deps) + DEPENDS ${NVIM_SOURCES} nvim_bin nvim_runtime_deps) set(LANGUAGE_MO_FILES) set(UPDATE_PO_TARGETS) @@ -88,7 +88,7 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG) set(poFile ${CMAKE_CURRENT_SOURCE_DIR}/${name}.po) add_custom_target(check-po-${name} - COMMAND $<TARGET_FILE:nvim> -u NONE -n -e + COMMAND $<TARGET_FILE:nvim_bin> -u NONE -n -e -S ${CMAKE_CURRENT_SOURCE_DIR}/check.vim -c "if error == 0 | q | endif" -c cq ${poFile} || ${CMAKE_COMMAND} -E echo "${name}.po failed the check." @@ -182,6 +182,6 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG) BuildMo(${LANGUAGE}) endforeach() - add_custom_target(translations ALL DEPENDS ${LANGUAGE_MO_FILES}) + add_custom_target(nvim_translations ALL DEPENDS ${LANGUAGE_MO_FILES}) add_custom_target(update-po DEPENDS ${UPDATE_PO_TARGETS}) endif() diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 6b8b73a2a0..f9560ce076 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1500,6 +1500,14 @@ void tui_option_set(TUIData *tui, String name, Object value) } } +void tui_chdir(TUIData *tui, String path) +{ + int err = uv_chdir(path.data); + if (err != 0) { + ELOG("Failed to chdir to %s: %s", path.data, strerror(err)); + } +} + void tui_raw_line(TUIData *tui, Integer g, Integer linerow, Integer startcol, Integer endcol, Integer clearcol, Integer clearattr, LineFlags flags, const schar_T *chunk, const sattr_T *attrs) diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 8888535878..316342c028 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -384,6 +384,12 @@ void ui_attach_impl(UI *ui, uint64_t chanid) ui_refresh_options(); resettitle(); + char cwd[MAXPATHL]; + size_t cwdlen = sizeof(cwd); + if (uv_cwd(cwd, &cwdlen) == 0) { + ui_call_chdir((String){ .data = cwd, .size = cwdlen }); + } + for (UIExtension i = kUIGlobalCount; (int)i < kUIExtCount; i++) { ui_set_ext_option(ui, i, ui->ui_ext[i]); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index da2c29010b..3ae11bd1a7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,7 +7,7 @@ set(TEST_OPTIONS -D CIRRUS_CI=$ENV{CIRRUS_CI} -D CI_BUILD=${CI_BUILD} -D DEPS_INSTALL_DIR=${DEPS_INSTALL_DIR} - -D NVIM_PRG=$<TARGET_FILE:nvim> + -D NVIM_PRG=$<TARGET_FILE:nvim_bin> -D TEST_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D WORKING_DIR=${PROJECT_SOURCE_DIR}) @@ -18,9 +18,8 @@ if(LUA_HAS_FFI) -D TEST_TYPE=unit ${TEST_OPTIONS} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake - DEPENDS nvim USES_TERMINAL) - add_dependencies(unittest lua-dev-deps) + add_dependencies(unittest lua-dev-deps nvim) else() message(WARNING "disabling unit tests: no Luajit FFI in ${LUA_PRG}") endif() @@ -34,16 +33,15 @@ add_custom_target(functionaltest -D TEST_TYPE=functional ${TEST_OPTIONS} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake - DEPENDS nvim printenv-test printargs-test shell-test pwsh-test streams-test tty-test ${GENERATED_HELP_TAGS} ${GENERATED_SYN_VIM} + DEPENDS printenv-test printargs-test shell-test pwsh-test streams-test tty-test USES_TERMINAL) +add_dependencies(functionaltest lua-dev-deps nvim) add_custom_target(benchmark COMMAND ${CMAKE_COMMAND} -D TEST_TYPE=benchmark ${TEST_OPTIONS} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake - DEPENDS nvim tty-test + DEPENDS tty-test USES_TERMINAL) - -add_dependencies(functionaltest lua-dev-deps) -add_dependencies(benchmark lua-dev-deps) +add_dependencies(benchmark lua-dev-deps nvim) diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua index 54f4aaab03..cb16f49e7c 100644 --- a/test/functional/api/extmark_spec.lua +++ b/test/functional/api/extmark_spec.lua @@ -1639,6 +1639,40 @@ describe('API/extmarks', function() right_gravity = true, }, }, get_extmark_by_id(ns, marks[3], { details = true })) + set_extmark(ns, marks[4], 0, 0, { + end_col = 1, + conceal = 'a', + spell = true, + }) + eq({ + 0, + 0, + { + conceal = 'a', + end_col = 1, + end_right_gravity = false, + end_row = 0, + ns_id = 1, + right_gravity = true, + spell = true, + }, + }, get_extmark_by_id(ns, marks[4], { details = true })) + set_extmark(ns, marks[5], 0, 0, { + end_col = 1, + spell = false, + }) + eq({ + 0, + 0, + { + end_col = 1, + end_right_gravity = false, + end_row = 0, + ns_id = 1, + right_gravity = true, + spell = false, + }, + }, get_extmark_by_id(ns, marks[5], { details = true })) api.nvim_buf_clear_namespace(0, ns, 0, -1) -- legacy sign mark includes sign name command('sign define sign1 text=s1 texthl=Title linehl=LineNR numhl=Normal culhl=CursorLine') @@ -1712,6 +1746,10 @@ describe('API/extmarks', function() aaa bbb ccc |*2 | ]]) + -- decor is not removed twice + command('d3') + api.nvim_buf_del_extmark(0, ns, 1) + command('silent undo') -- mark is deleted with undo_restore == false set_extmark(ns, 1, 0, 0, { invalidate = true, undo_restore = false, sign_text = 'S1' }) set_extmark(ns, 2, 1, 0, { invalidate = true, undo_restore = false, sign_text = 'S2' }) diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua index 4f57f6d0bd..0decd710e9 100644 --- a/test/functional/api/keymap_spec.lua +++ b/test/functional/api/keymap_spec.lua @@ -460,6 +460,57 @@ describe('nvim_get_keymap', function() desc = 'map description', }, api.nvim_get_keymap('n')[1]) end) + + it('can get abbreviations', function() + command('inoreabbr foo bar') + command('cnoreabbr <buffer> foo baz') + + local mapargs_i = { + abbr = 1, + buffer = 0, + expr = 0, + lhs = 'foo', + lhsraw = 'foo', + lnum = 0, + mode = 'i', + mode_bits = 0x10, + noremap = 1, + nowait = 0, + rhs = 'bar', + script = 0, + scriptversion = 1, + sid = 0, + silent = 0, + } + local mapargs_c = { + abbr = 1, + buffer = 1, + expr = 0, + lhs = 'foo', + lhsraw = 'foo', + lnum = 0, + mode = 'c', + mode_bits = 0x08, + noremap = 1, + nowait = 0, + rhs = 'baz', + script = 0, + scriptversion = 1, + sid = 0, + silent = 0, + } + + local curbuf = api.nvim_get_current_buf() + + eq({ mapargs_i }, api.nvim_get_keymap('ia')) + eq({}, api.nvim_buf_get_keymap(curbuf, 'ia')) + + eq({}, api.nvim_get_keymap('ca')) + eq({ mapargs_c }, api.nvim_buf_get_keymap(curbuf, 'ca')) + + eq({ mapargs_i }, api.nvim_get_keymap('!a')) + eq({ mapargs_c }, api.nvim_buf_get_keymap(curbuf, '!a')) + end) end) describe('nvim_set_keymap, nvim_del_keymap', function() diff --git a/test/functional/core/channels_spec.lua b/test/functional/core/channels_spec.lua index ce13c4755d..56a2f5a571 100644 --- a/test/functional/core/channels_spec.lua +++ b/test/functional/core/channels_spec.lua @@ -4,7 +4,7 @@ local clear, eq, eval, next_msg, ok, source = local command, fn, api = helpers.command, helpers.fn, helpers.api local sleep = vim.uv.sleep local spawn, nvim_argv = helpers.spawn, helpers.nvim_argv -local set_session = helpers.set_session +local get_session, set_session = helpers.get_session, helpers.set_session local nvim_prog = helpers.nvim_prog local is_os = helpers.is_os local retry = helpers.retry @@ -59,6 +59,43 @@ describe('channels', function() eq({ 'notification', 'data', { id, { '' } } }, next_msg()) end) + it('dont crash due to garbage in rpc #23781', function() + local client = get_session() + local server = spawn(nvim_argv, nil, nil, true) + set_session(server) + local address = fn.serverlist()[1] + set_session(client) + + api.nvim_set_var('address', address) + command("let g:id = sockconnect('pipe', address, {'on_data':'OnEvent'})") + local id = eval('g:id') + ok(id > 0) + + command("call chansend(g:id, 'F')") + eq({ 'notification', 'data', { id, { '' } } }, next_msg()) + set_session(server) + assert_alive() + + set_session(client) + command('call chanclose(g:id)') + command("let g:id = sockconnect('pipe', address, {'on_data':'OnEvent'})") + id = eval('g:id') + ok(id > 0) + + command("call chansend(g:id, msgpackdump([[2, 'redraw', 'F']], 'B')[:-4])") + set_session(server) + assert_alive() + set_session(client) + command("call chansend(g:id, 'F')") + eq({ 'notification', 'data', { id, { '' } } }, next_msg()) + + set_session(server) + assert_alive() + set_session(client) + command('call chanclose(g:id)') + server:close() + end) + it('can use stdio channel', function() source([[ let g:job_opts = { diff --git a/test/functional/fixtures/CMakeLists.txt b/test/functional/fixtures/CMakeLists.txt index 6e64b1e4dc..150407fe46 100644 --- a/test/functional/fixtures/CMakeLists.txt +++ b/test/functional/fixtures/CMakeLists.txt @@ -5,7 +5,7 @@ endif() if(WIN32) target_compile_definitions(test_lib INTERFACE MSWIN) endif() -target_link_libraries(test_lib INTERFACE nvim) +target_link_libraries(test_lib INTERFACE nvim_bin) add_executable(tty-test EXCLUDE_FROM_ALL tty-test.c) add_executable(shell-test EXCLUDE_FROM_ALL shell-test.c) diff --git a/test/functional/lua/glob_spec.lua b/test/functional/lua/glob_spec.lua index c7ef498008..1eac037575 100644 --- a/test/functional/lua/glob_spec.lua +++ b/test/functional/lua/glob_spec.lua @@ -67,18 +67,16 @@ describe('glob', function() eq(true, match('dir/*/file.txt', 'dir/subdir/file.txt')) eq(false, match('dir/*/file.txt', 'dir/subdir/subdir/file.txt')) - -- TODO: The spec does not describe this, but VSCode only interprets ** when it's by + -- The spec does not describe this, but VSCode only interprets ** when it's by -- itself in a path segment, and otherwise interprets ** as consecutive * directives. - -- The following tests show how this behavior should work, but is not yet fully implemented. - -- Currently, "a**" parses incorrectly as "a" "**" and "**a" parses correctly as "*" "*" "a". -- see: https://github.com/microsoft/vscode/blob/eef30e7165e19b33daa1e15e92fa34ff4a5df0d3/src/vs/base/common/glob.ts#L112 eq(true, match('a**', 'abc')) -- '**' should parse as two '*'s when not by itself in a path segment eq(true, match('**c', 'abc')) - -- eq(false, match('a**', 'ab')) -- each '*' should still represent at least one character + eq(false, match('a**', 'ab')) -- each '*' should still represent at least one character eq(false, match('**c', 'bc')) eq(true, match('a**', 'abcd')) eq(true, match('**d', 'abcd')) - -- eq(false, match('a**', 'abc/d')) + eq(false, match('a**', 'abc/d')) eq(false, match('**d', 'abc/d')) end) diff --git a/test/functional/lua/version_spec.lua b/test/functional/lua/version_spec.lua index c321421ad0..3bc9e26d41 100644 --- a/test/functional/lua/version_spec.lua +++ b/test/functional/lua/version_spec.lua @@ -288,21 +288,55 @@ describe('version', function() eq(vim.version.last({ v('2.0.0'), v('1.2.3') }), v('2.0.0')) end) + it('le()', function() + eq(true, vim.version.le('1', '1')) + eq(true, vim.version.le({ 3, 1, 4 }, '3.1.4')) + eq(true, vim.version.le('1', '2')) + eq(true, vim.version.le({ 0, 7, 4 }, { 3 })) + eq(false, vim.version.le({ 3 }, { 0, 7, 4 })) + eq(false, vim.version.le({ major = 3, minor = 3, patch = 0 }, { 3, 2, 0 })) + eq(false, vim.version.le('2', '1')) + end) + it('lt()', function() + eq(false, vim.version.lt('1', '1')) + eq(false, vim.version.lt({ 3, 1, 4 }, '3.1.4')) eq(true, vim.version.lt('1', '2')) + eq(true, vim.version.lt({ 0, 7, 4 }, { 3 })) eq(false, vim.version.lt({ 3 }, { 0, 7, 4 })) eq(false, vim.version.lt({ major = 3, minor = 3, patch = 0 }, { 3, 2, 0 })) + eq(false, vim.version.lt('2', '1')) + end) + + it('ge()', function() + eq(true, vim.version.ge('1', '1')) + eq(true, vim.version.ge({ 3, 1, 4 }, '3.1.4')) + eq(true, vim.version.ge('2', '1')) + eq(true, vim.version.ge({ 3 }, { 0, 7, 4 })) + eq(true, vim.version.ge({ major = 3, minor = 3, patch = 0 }, { 3, 2, 0 })) + eq(false, vim.version.ge('1', '2')) + eq(false, vim.version.ge({ 0, 7, 4 }, { 3 })) end) it('gt()', function() + eq(false, vim.version.gt('1', '1')) + eq(false, vim.version.gt({ 3, 1, 4 }, '3.1.4')) eq(true, vim.version.gt('2', '1')) eq(true, vim.version.gt({ 3 }, { 0, 7, 4 })) eq(true, vim.version.gt({ major = 3, minor = 3, patch = 0 }, { 3, 2, 0 })) + eq(false, vim.version.gt('1', '2')) + eq(false, vim.version.gt({ 0, 7, 4 }, { 3 })) end) it('eq()', function() eq(true, vim.version.eq('2', '2')) eq(true, vim.version.eq({ 3, 1, 0 }, '3.1.0')) eq(true, vim.version.eq({ major = 3, minor = 3, patch = 0 }, { 3, 3, 0 })) + eq(false, vim.version.eq('2', '3')) + + -- semver: v3 == v3.0 == v3.0.0 + eq(true, vim.version.eq('3', { 3, 0, 0 })) + eq(true, vim.version.eq({ 3, 0 }, { 3 })) + eq(true, vim.version.eq({ 3, 0, 0 }, { 3 })) end) end) diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 98968f3695..6e05728b0c 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -128,33 +128,93 @@ describe('lua stdlib', function() eq(1, fn.luaeval('vim.stricmp("\\0C\\0", "\\0B\\0")')) end) - it('vim.deprecate', function() + local function test_vim_deprecate(current_version) -- vim.deprecate(name, alternative, version, plugin, backtrace) - eq( - dedent [[ - foo.bar() is deprecated, use zub.wooo{ok=yay} instead. :help deprecated - This feature will be removed in Nvim version 0.10]], - exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10') - ) - -- Same message, skipped. - eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10')) - -- Don't show error if not hard deprecated - eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'nil', '5000.0.0')) - -- When `plugin` is specified, don't show ":help deprecated". #22235 - eq( - dedent [[ - foo.bar() is deprecated, use zub.wooo{ok=yay} instead. - This feature will be removed in my-plugin.nvim version 0.3.0]], - exec_lua( - 'return vim.deprecate(...)', - 'foo.bar()', - 'zub.wooo{ok=yay}', - '0.3.0', - 'my-plugin.nvim', - false - ) - ) - end) + -- See MAINTAIN.md for the soft/hard deprecation policy + + describe(('vim.deprecate [current_version = %s]'):format(current_version), function() + before_each(function() + -- mock vim.version() behavior, should be pinned for consistent testing + exec_lua( + [[ + local current_version_mock = vim.version.parse(...) + getmetatable(vim.version).__call = function() + return current_version_mock + end + ]], + current_version + ) + end) + + it('when plugin = nil', function() + eq( + dedent [[ + foo.bar() is deprecated, use zub.wooo{ok=yay} instead. :help deprecated + This feature will be removed in Nvim version 0.10]], + exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10') + ) + -- Same message, skipped. + eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10')) + + -- Don't show error if not hard-deprecated (only soft-deprecated) + eq( + vim.NIL, + exec_lua('return vim.deprecate(...)', 'foo.baz()', 'foo.better_baz()', '0.12.0') + ) + + -- Show error if hard-deprecated + eq( + dedent [[ + foo.hard_dep() is deprecated, use vim.new_api() instead. :help deprecated + This feature will be removed in Nvim version 0.11]], + exec_lua('return vim.deprecate(...)', 'foo.hard_dep()', 'vim.new_api()', '0.11') + ) + + -- To be deleted in the next major version (1.0) + eq( + dedent [[ + foo.baz() is deprecated. :help deprecated + This feature will be removed in Nvim version 1.0]], + exec_lua [[ return vim.deprecate('foo.baz()', nil, '1.0') ]] + ) + end) + + it('when plugin is specified', function() + -- When `plugin` is specified, don't show ":help deprecated". #22235 + eq( + dedent [[ + foo.bar() is deprecated, use zub.wooo{ok=yay} instead. + This feature will be removed in my-plugin.nvim version 0.3.0]], + exec_lua( + 'return vim.deprecate(...)', + 'foo.bar()', + 'zub.wooo{ok=yay}', + '0.3.0', + 'my-plugin.nvim', + false + ) + ) + + -- plugins: no soft deprecation period + eq( + dedent [[ + foo.bar() is deprecated, use zub.wooo{ok=yay} instead. + This feature will be removed in my-plugin.nvim version 0.11.0]], + exec_lua( + 'return vim.deprecate(...)', + 'foo.bar()', + 'zub.wooo{ok=yay}', + '0.11.0', + 'my-plugin.nvim', + false + ) + ) + end) + end) + end + + test_vim_deprecate('0.10') + test_vim_deprecate('0.10-dev+g0000000') it('vim.startswith', function() eq(true, fn.luaeval('vim.startswith("123", "1")')) diff --git a/test/functional/treesitter/fold_spec.lua b/test/functional/treesitter/fold_spec.lua index 2302cf869e..ac9d227bb6 100644 --- a/test/functional/treesitter/fold_spec.lua +++ b/test/functional/treesitter/fold_spec.lua @@ -729,7 +729,7 @@ void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, con feed('ggVGzf') screen:expect { grid = [[ - {2:^void}{1: }{3:qsort}{4:(}{2:void}{1: }{5:*}{3:base}{4:,}{1: }{2:size_t}{1: }{3:nel}{4:,}{1: }{2:size_t}{1: }{3:width}{4:,}{1: }{2:int}{1: }{4:(}{5:*}{3:compa}| + {4:^void}{1: }{3:qsort}{4:(void}{1: }{5:*}{3:base}{4:,}{1: }{4:size_t}{1: }{3:nel}{4:,}{1: }{4:size_t}{1: }{3:width}{4:,}{1: }{4:int}{1: }{4:(}{5:*}{3:compa}| {0:~ }|*3 | ]], diff --git a/test/functional/treesitter/highlight_spec.lua b/test/functional/treesitter/highlight_spec.lua index f4f7bc691c..932af0332b 100644 --- a/test/functional/treesitter/highlight_spec.lua +++ b/test/functional/treesitter/highlight_spec.lua @@ -766,7 +766,7 @@ describe('treesitter highlighting (help)', function() {1:>ruby} | {1: -- comment} | {1: local this_is = 'actually_lua'} | - < | + {1:<} | ^ | | ]], @@ -779,7 +779,7 @@ describe('treesitter highlighting (help)', function() {1:>lua} | {1: -- comment} | {1: }{3:local}{1: }{4:this_is}{1: }{3:=}{1: }{5:'actually_lua'} | - < | + {1:<} | ^ | | ]], @@ -792,7 +792,7 @@ describe('treesitter highlighting (help)', function() {1:>ruby} | {1: -- comment} | {1: local this_is = 'actually_lua'} | - < | + {1:<} | ^ | | ]], diff --git a/test/functional/ui/embed_spec.lua b/test/functional/ui/embed_spec.lua index e655ee1b54..f6bdd2215d 100644 --- a/test/functional/ui/embed_spec.lua +++ b/test/functional/ui/embed_spec.lua @@ -171,6 +171,56 @@ describe('--embed UI', function() } eq({ [16711935] = true }, seen) -- we only saw the last one, despite 16777215 was set internally earlier end) + + it('updates cwd of attached UI #21771', function() + clear { args_rm = { '--headless' } } + + local screen = Screen.new(40, 8) + screen:attach() + + screen:expect { + condition = function() + eq(helpers.paths.test_source_path, screen.pwd) + end, + } + + -- Change global cwd + helpers.command(string.format('cd %s/src/nvim', helpers.paths.test_source_path)) + + screen:expect { + condition = function() + eq(string.format('%s/src/nvim', helpers.paths.test_source_path), screen.pwd) + end, + } + + -- Split the window and change the cwd in the split + helpers.command('new') + helpers.command(string.format('lcd %s/test', helpers.paths.test_source_path)) + + screen:expect { + condition = function() + eq(string.format('%s/test', helpers.paths.test_source_path), screen.pwd) + end, + } + + -- Move to the original window + helpers.command('wincmd p') + + screen:expect { + condition = function() + eq(string.format('%s/src/nvim', helpers.paths.test_source_path), screen.pwd) + end, + } + + -- Change global cwd again + helpers.command(string.format('cd %s', helpers.paths.test_source_path)) + + screen:expect { + condition = function() + eq(helpers.paths.test_source_path, screen.pwd) + end, + } + end) end) describe('--embed --listen UI', function() diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 644ee910b6..07333f2e21 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -140,6 +140,7 @@ function Screen.new(width, height) suspended = false, mode = 'normal', options = {}, + pwd = '', popupmenu = nil, cmdline = {}, cmdline_block = {}, @@ -212,7 +213,6 @@ function Screen:attach(options, session) if options.ext_linegrid == nil then options.ext_linegrid = true end - self._session = session self._options = options self._clear_attrs = (not options.ext_linegrid) and {} or nil @@ -1108,6 +1108,10 @@ function Screen:_handle_option_set(name, value) self.options[name] = value end +function Screen:_handle_chdir(path) + self.pwd = vim.fs.normalize(path, { expand_env = false }) +end + function Screen:_handle_popupmenu_show(items, selected, row, col, grid) self.popupmenu = { items = items, pos = selected, anchor = { grid, row, col } } end diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim index 50e60de484..e0c3fdd6c4 100644 --- a/test/old/testdir/test_filetype.vim +++ b/test/old/testdir/test_filetype.vim @@ -140,6 +140,7 @@ func s:GetFilenameChecks() abort \ 'chatito': ['file.chatito'], \ 'chill': ['file..ch'], \ 'chordpro': ['file.chopro', 'file.crd', 'file.cho', 'file.crdpro', 'file.chordpro'], + \ 'chuck': ['file.ck'], \ 'cl': ['file.eni'], \ 'clean': ['file.dcl', 'file.icl'], \ 'clojure': ['file.clj', 'file.cljs', 'file.cljx', 'file.cljc'], diff --git a/test/old/testdir/test_syntax.vim b/test/old/testdir/test_syntax.vim index 10dc798df7..711b2adf7c 100644 --- a/test/old/testdir/test_syntax.vim +++ b/test/old/testdir/test_syntax.vim @@ -197,14 +197,14 @@ func Test_syntax_completion() " Check that clearing "Aap" avoids it showing up before Boolean. hi @Aap ctermfg=blue call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_match('^"syn list @Aap @boolean @character ', @:) + call assert_match('^"syn list @Aap @attribute @boolean @character ', @:) hi clear @Aap call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_match('^"syn list @boolean @character ', @:) + call assert_match('^"syn list @attribute @boolean @character ', @:) call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_match('^"syn match @boolean @character ', @:) + call assert_match('^"syn match @attribute @boolean @character ', @:) syn cluster Aax contains=Aap call feedkeys(":syn list @A\<C-A>\<C-B>\"\<CR>", 'tx') |