Compare commits

...

24 Commits

Author SHA1 Message Date
minhanghuang
723794ca0b
Merge bb7f760d03 into 3b54adc6c6 2024-09-15 14:39:59 +05:45
zeertzjq
3b54adc6c6
Merge pull request #30378 from zeertzjq/vim-9.1.0729
vim-patch:9.1.{0729,0730}
2024-09-14 19:51:11 +08:00
zeertzjq
325d349f9d
vim-patch:9.1.0728: [security]: heap-use-after-free in garbage collection with location list user data (#30377)
Problem:  heap-use-after-free in garbage collection with location list
          user data.
Solution: Mark user data as in use when no other window is referencing
          the location list (zeertzjq)

fixes: neovim/neovim#30371
closes: vim/vim#15683

be4bd189d2
2024-09-14 19:38:33 +08:00
zeertzjq
5191a11d66 vim-patch:9.1.0730: Crash with cursor-screenline and narrow window
Problem:  Crash with cursor-screenline and narrow window
          (elig0n)
Solution: Don't set right_col when width2 is 0 (zeertzjq).

fixes: vim/vim#15677
closes: vim/vim#15678

59149f0269
2024-09-14 19:29:40 +08:00
zeertzjq
90585e47fe vim-patch:9.1.0729: Wrong cursor-screenline when resizing window
Problem:  Wrong cursor-screenline when resizing window
Solution: Invalidate saved left_col and right_col when width1 or width2
          change.

closes: vim/vim#15679

86dc4f8b43
2024-09-14 19:29:37 +08:00
Jaehwang Jung
f2173b1aa2
fix(defaults): cannot remove "How-to disable mouse" menu item #30375 2024-09-14 02:18:38 -07:00
dundargoc
67d6b6f27e ci: skip automerge step if backport failed 2024-09-14 01:55:36 +02:00
Mathias Fussenegger
8512f669f0 fix(lsp): handle nil bytes in strings
Problem:

The LSP omnifunc can insert nil bytes, which when read in other places
(like semantic token) could cause an error:

    semantic_tokens.lua:304: Vim:E976: Using a Blob as a String

Solution:

Use `#line` instead of `vim.fn.strlen(line)`. Both return UTF-8 bytes
but the latter can't handle nil bytes.

Completion candidates can currently insert nil bytes, if other parts of
Alternative fix to https://github.com/neovim/neovim/pull/30359

Note that https://github.com/neovim/neovim/pull/30315 will avoid the
insertion of nil bytes from the LSP omnifunc, but the change of this PR
can more easily be backported.
2024-09-13 22:34:49 +02:00
dundargoc
755512ed60 ci: don't add reviewers for PRs created by a bot
This will ensure automatic backports created by the backport action does
not request reviewers (since the commit in question has already been
vetted and merged), but manual backports created by users does request
reviewers as these commits has not been vetted previously.
2024-09-13 16:58:15 +02:00
dundargoc
4c23b83456 ci: add needs:backport label on backport PRs with conflict
This makes it easy to keep track of which backport PRs have failed and
need manual intervention to fix.
2024-09-13 16:49:35 +02:00
dundargoc
5284a2a793 build: bump unibilium to v2.1.2
There is no real practical difference from previous commit except that
this is a tagged release.
2024-09-13 15:56:37 +02:00
Riley Bruins
b9b408a56c
feat(treesitter): start moving get_parser to return nil #30313
**Problem:** `vim.treesitter.get_parser` will throw an error if no parser
can be found.

- This means the caller is responsible for wrapping it in a `pcall`,
  which is easy to forget
- It also makes it slightly harder to potentially memoize `get_parser`
  in the future
- It's a bit unintuitive since many other `get_*` style functions
  conventionally return `nil` if no object is found (e.g. `get_node`,
  `get_lang`, `query.get`, etc.)

**Solution:** Return `nil` if no parser can be found or created

- This requires a function signature change, and some new assertions in
  places where the parser will always (or should always) be found.
- This commit starts by making this change internally, since it is
  breaking. Eventually it will be rolled out to the public API.
2024-09-13 05:09:11 -07:00
James Trew
8654a97006
fix(lsp): handle empty call hierarchy items #30349
Ensure that the function `pick_call_hierarchy_item` correctly handles
the case where `call_hierarchy_items` is nil or an empty table. This
prevents potential errors when the function is called with no items.
2024-09-13 04:59:49 -07:00
dundargoc
057314345a ci: enable automerge by default when backporting
This will automatically merge backported PRs without human intervention
if the tests pass.
2024-09-13 12:31:33 +02:00
Justin M. Keyes
deac7df80a
refactor(stream.c): unused params in stream_close #30356 2024-09-12 09:16:57 -07:00
Christian Clason
ae917dbd06 fix(treesitter): sync queries from upstream 2024-09-12 13:41:15 +02:00
Christian Clason
c65153893a build(deps): bump tree-sitter-c to v0.23.0 2024-09-12 13:41:15 +02:00
Christian Clason
f6cc0394ae build(deps): bump tree-sitter-markdown to v0.3.2 2024-09-12 13:41:15 +02:00
Christian Clason
f347c292d1 build(deps): bump tree-sitter-lua to v0.2.0 2024-09-12 13:41:15 +02:00
zeertzjq
48c14d3544
vim-patch:9.1.0725: filetype: swiftinterface files are not recognized (#30350)
Problem:  filetype: swiftinterface files are not recognized
Solution: Detect '*.swiftinterface' files as swift filetype
          (LosFarmosCTL)

closes: vim/vim#15658

03cac4b70d

Co-authored-by: LosFarmosCTL <80157503+LosFarmosCTL@users.noreply.github.com>
2024-09-12 15:16:58 +08:00
Justin M. Keyes
5931f780e0
feat(log): use "ui" as default name for TUI client #30345
The default "session name" for the builtin TUI is "ui".

before:

    INF 2024-09-10T14:57:35.385 hello.sock os_exit:692: Nvim exit: 1
    INF 2024-09-10T14:57:35.388 ?.4543     os_exit:692: Nvim exit: 1

after:

    INF 2024-09-10T14:59:19.919 hello.sock os_exit:692: Nvim exit: 1
    INF 2024-09-10T14:59:19.922 ui.5684    os_exit:692: Nvim exit: 1
2024-09-11 17:25:00 -07:00
Gregory Anders
98ba65b8be
fix: replace NVIM with Nvim in default titlestring (#30348) 2024-09-11 20:32:08 +00:00
glepnir
f9bf64d746
fix(lsp): check buffer is loaded and valid #30330
Problem: buffer mabye not valid when callback handler invoke.

Soliton: check buffer is valid and loaded in handler.
2024-09-11 08:11:09 -07:00
minhanghuang
bb7f760d03 build(cmake): standardize package naming across architectures 2024-07-13 15:50:37 +08:00
40 changed files with 318 additions and 136 deletions

View File

@ -26,3 +26,21 @@ jobs:
pull_title: "${pull_title}" pull_title: "${pull_title}"
label_pattern: "^ci:backport ([^ ]+)$" label_pattern: "^ci:backport ([^ ]+)$"
github_token: ${{ steps.app-token.outputs.token }} github_token: ${{ steps.app-token.outputs.token }}
- name: Create failed backport label
if: ${{ steps.backport.outputs.was_successful == 'false' }}
uses: actions/github-script@v7
with:
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['needs:backport']
})
- name: Enable automerge
if: ${{ steps.backport.outputs.was_successful == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh pr merge --rebase --auto ${{ steps.backport.outputs.created_pull_numbers }}

View File

@ -5,7 +5,7 @@ on:
workflow_call: workflow_call:
jobs: jobs:
request-reviewer: request-reviewer:
if: github.event.pull_request.state == 'open' && github.event.pull_request.draft == false if: github.event.pull_request.state == 'open' && github.event.pull_request.draft == false && !endsWith(github.actor, '[bot]')
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
pull-requests: write pull-requests: write

View File

@ -7,8 +7,8 @@ LUAJIT_SHA256 2b5514bd6a6573cb6111b43d013e952cbaf46762d14ebe26c872ddb80b5a84e0
LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz
LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333 LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
UNIBILIUM_URL https://github.com/neovim/unibilium/archive/ab28a2ddb86a144194a798bcf1fef1ab4f981ab7.tar.gz UNIBILIUM_URL https://github.com/neovim/unibilium/archive/v2.1.2.tar.gz
UNIBILIUM_SHA256 7c0386fc48452632868e0dcb8e7ed140d67a3da79e39ceee54c1ba7a495ad625 UNIBILIUM_SHA256 370ecb07fbbc20d91d1b350c55f1c806b06bf86797e164081ccc977fc9b3af7a
LUV_URL https://github.com/luvit/luv/releases/download/1.48.0-2/luv-1.48.0-2.tar.gz LUV_URL https://github.com/luvit/luv/releases/download/1.48.0-2/luv-1.48.0-2.tar.gz
LUV_SHA256 2c3a1ddfebb4f6550293a40ee789f7122e97647eede51511f57203de48c03b7a LUV_SHA256 2c3a1ddfebb4f6550293a40ee789f7122e97647eede51511f57203de48c03b7a
@ -38,18 +38,18 @@ LIBICONV_SHA256 8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313
UTF8PROC_URL https://github.com/JuliaStrings/utf8proc/archive/3de4596fbe28956855df2ecb3c11c0bbc3535838.tar.gz UTF8PROC_URL https://github.com/JuliaStrings/utf8proc/archive/3de4596fbe28956855df2ecb3c11c0bbc3535838.tar.gz
UTF8PROC_SHA256 fb4a16bb659b58afb7f921fcc8928d0b3c1fcab135366c8a4f9ca7de1b1cfada UTF8PROC_SHA256 fb4a16bb659b58afb7f921fcc8928d0b3c1fcab135366c8a4f9ca7de1b1cfada
TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.21.3.tar.gz TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.23.0.tar.gz
TREESITTER_C_SHA256 75a3780df6114cd37496761c4a7c9fd900c78bee3a2707f590d78c0ca3a24368 TREESITTER_C_SHA256 ee58c925e2e507c23d735aad46bf7fb0af31ca06d6f4f41bc008216d9232b0cb
TREESITTER_LUA_URL https://github.com/tree-sitter-grammars/tree-sitter-lua/archive/v0.1.0.tar.gz TREESITTER_LUA_URL https://github.com/tree-sitter-grammars/tree-sitter-lua/archive/v0.2.0.tar.gz
TREESITTER_LUA_SHA256 230cfcbfa74ed1f7b8149e9a1f34c2efc4c589a71fe0f5dc8560622f8020d722 TREESITTER_LUA_SHA256 6c41227cd0a59047b19d31f0031d4d901f08bfd78d6fc7f55c89e5b8374c794e
TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.4.0.tar.gz TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.4.0.tar.gz
TREESITTER_VIM_SHA256 9f856f8b4a10ab43348550fa2d3cb2846ae3d8e60f45887200549c051c66f9d5 TREESITTER_VIM_SHA256 9f856f8b4a10ab43348550fa2d3cb2846ae3d8e60f45887200549c051c66f9d5
TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v3.0.0.tar.gz TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v3.0.0.tar.gz
TREESITTER_VIMDOC_SHA256 a639bf92bf57bfa1cdc90ca16af27bfaf26a9779064776dd4be34c1ef1453f6c TREESITTER_VIMDOC_SHA256 a639bf92bf57bfa1cdc90ca16af27bfaf26a9779064776dd4be34c1ef1453f6c
TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/archive/v0.4.0.tar.gz TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/archive/v0.4.0.tar.gz
TREESITTER_QUERY_SHA256 d3a423ab66dc62b2969625e280116678a8a22582b5ff087795222108db2f6a6e TREESITTER_QUERY_SHA256 d3a423ab66dc62b2969625e280116678a8a22582b5ff087795222108db2f6a6e
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.2.3.tar.gz TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.3.2.tar.gz
TREESITTER_MARKDOWN_SHA256 4909d6023643f1afc3ab219585d4035b7403f3a17849782ab803c5f73c8a31d5 TREESITTER_MARKDOWN_SHA256 5dac48a6d971eb545aab665d59a18180d21963afc781bbf40f9077c06cb82ae5
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.23.0.tar.gz TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.23.0.tar.gz
TREESITTER_SHA256 6403b361b0014999e96f61b9c84d6950d42f0c7d6e806be79382e0232e48a11b TREESITTER_SHA256 6403b361b0014999e96f61b9c84d6950d42f0c7d6e806be79382e0232e48a11b

View File

@ -53,7 +53,7 @@ elseif(APPLE)
set(CPACK_GENERATOR TGZ) set(CPACK_GENERATOR TGZ)
set(CPACK_PACKAGE_ICON ${CMAKE_CURRENT_LIST_DIR}/neovim.icns) set(CPACK_PACKAGE_ICON ${CMAKE_CURRENT_LIST_DIR}/neovim.icns)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CPACK_PACKAGE_FILE_NAME "nvim-linux64") set(CPACK_PACKAGE_FILE_NAME "nvim-linux-${CMAKE_SYSTEM_PROCESSOR}")
set(CPACK_GENERATOR TGZ DEB) set(CPACK_GENERATOR TGZ DEB)
set(CPACK_DEBIAN_PACKAGE_NAME "Neovim") # required set(CPACK_DEBIAN_PACKAGE_NAME "Neovim") # required
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Neovim.io") # required set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Neovim.io") # required

View File

@ -189,7 +189,8 @@ TREESITTER
TUI TUI
• TODO • |log| messages written by the builtin UI client (TUI, |--remote-ui|) are
now prefixed with "ui" instead of "?".
UI UI

View File

@ -6713,7 +6713,7 @@ A jump table for the options with a short description can be found at |Q_op|.
global global
When on, the title of the window will be set to the value of When on, the title of the window will be set to the value of
'titlestring' (if it is not empty), or to: 'titlestring' (if it is not empty), or to:
filename [+=-] (path) - NVIM filename [+=-] (path) - Nvim
Where: Where:
filename the name of the file being edited filename the name of the file being edited
- indicates the file cannot be modified, 'ma' off - indicates the file cannot be modified, 'ma' off
@ -6721,7 +6721,7 @@ A jump table for the options with a short description can be found at |Q_op|.
= indicates the file is read-only = indicates the file is read-only
=+ indicates the file is read-only and modified =+ indicates the file is read-only and modified
(path) is the path of the file being edited (path) is the path of the file being edited
- NVIM the server name |v:servername| or "NVIM" - Nvim the server name |v:servername| or "Nvim"
*'titlelen'* *'titlelen'*
'titlelen' number (default 85) 'titlelen' number (default 85)

View File

@ -9,8 +9,8 @@
local function get_commentstring(ref_position) local function get_commentstring(ref_position)
local buf_cs = vim.bo.commentstring local buf_cs = vim.bo.commentstring
local has_ts_parser, ts_parser = pcall(vim.treesitter.get_parser) local ts_parser = vim.treesitter._get_parser()
if not has_ts_parser then if not ts_parser then
return buf_cs return buf_cs
end end

View File

@ -213,23 +213,25 @@ end
--- Default menus --- Default menus
do do
--- Right click popup menu --- Right click popup menu
local function def_menu(ctx) vim.cmd([[
vim.cmd([[ anoremenu PopUp.Go\ to\ definition <Cmd>lua vim.lsp.buf.definition()<CR>
anoremenu PopUp.Go\ to\ definition <Cmd>lua vim.lsp.buf.definition()<CR> amenu PopUp.Open\ in\ web\ browser gx
amenu PopUp.Open\ in\ web\ browser gx anoremenu PopUp.Inspect <Cmd>Inspect<CR>
anoremenu PopUp.Inspect <Cmd>Inspect<CR> anoremenu PopUp.-1- <Nop>
anoremenu PopUp.-1- <Nop> vnoremenu PopUp.Cut "+x
vnoremenu PopUp.Cut "+x vnoremenu PopUp.Copy "+y
vnoremenu PopUp.Copy "+y anoremenu PopUp.Paste "+gP
anoremenu PopUp.Paste "+gP vnoremenu PopUp.Paste "+P
vnoremenu PopUp.Paste "+P vnoremenu PopUp.Delete "_x
vnoremenu PopUp.Delete "_x nnoremenu PopUp.Select\ All ggVG
nnoremenu PopUp.Select\ All ggVG vnoremenu PopUp.Select\ All gg0oG$
vnoremenu PopUp.Select\ All gg0oG$ inoremenu PopUp.Select\ All <C-Home><C-O>VG
inoremenu PopUp.Select\ All <C-Home><C-O>VG anoremenu PopUp.-2- <Nop>
anoremenu PopUp.-2- <Nop> anoremenu PopUp.How-to\ disable\ mouse <Cmd>help disable-mouse<CR>
anoremenu PopUp.How-to\ disable\ mouse <Cmd>help disable-mouse<CR> ]])
local function enable_ctx_menu(ctx)
vim.cmd([[
amenu disable PopUp.Go\ to\ definition amenu disable PopUp.Go\ to\ definition
amenu disable PopUp.Open\ in\ web\ browser amenu disable PopUp.Open\ in\ web\ browser
]]) ]])
@ -240,7 +242,6 @@ do
vim.cmd([[anoremenu enable PopUp.Go\ to\ definition]]) vim.cmd([[anoremenu enable PopUp.Go\ to\ definition]])
end end
end end
def_menu()
local nvim_popupmenu_augroup = vim.api.nvim_create_augroup('nvim_popupmenu', {}) local nvim_popupmenu_augroup = vim.api.nvim_create_augroup('nvim_popupmenu', {})
vim.api.nvim_create_autocmd('MenuPopup', { vim.api.nvim_create_autocmd('MenuPopup', {
@ -252,7 +253,7 @@ do
local urls = require('vim.ui')._get_urls() local urls = require('vim.ui')._get_urls()
local url = vim.startswith(urls[1], 'http') local url = vim.startswith(urls[1], 'http')
local ctx = url and 'url' or (vim.lsp.get_clients({ bufnr = 0 })[1] and 'lsp' or nil) local ctx = url and 'url' or (vim.lsp.get_clients({ bufnr = 0 })[1] and 'lsp' or nil)
def_menu(ctx) enable_ctx_menu(ctx)
end, end,
}) })
end end

View File

@ -7255,7 +7255,7 @@ vim.go.tm = vim.go.timeoutlen
--- When on, the title of the window will be set to the value of --- When on, the title of the window will be set to the value of
--- 'titlestring' (if it is not empty), or to: --- 'titlestring' (if it is not empty), or to:
--- filename [+=-] (path) - NVIM --- filename [+=-] (path) - Nvim
--- Where: --- Where:
--- filename the name of the file being edited --- filename the name of the file being edited
--- - indicates the file cannot be modified, 'ma' off --- - indicates the file cannot be modified, 'ma' off
@ -7263,7 +7263,7 @@ vim.go.tm = vim.go.timeoutlen
--- = indicates the file is read-only --- = indicates the file is read-only
--- =+ indicates the file is read-only and modified --- =+ indicates the file is read-only and modified
--- (path) is the path of the file being edited --- (path) is the path of the file being edited
--- - NVIM the server name `v:servername` or "NVIM" --- - Nvim the server name `v:servername` or "Nvim"
--- ---
--- @type boolean --- @type boolean
vim.o.title = false vim.o.title = false

View File

@ -1164,6 +1164,7 @@ local extension = {
svelte = 'svelte', svelte = 'svelte',
svg = 'svg', svg = 'svg',
swift = 'swift', swift = 'swift',
swiftinterface = 'swift',
swig = 'swig', swig = 'swig',
swg = 'swig', swg = 'swig',
sys = detect.sys, sys = detect.sys,

View File

@ -447,11 +447,9 @@ function M.document_symbol(opts)
request_with_opts(ms.textDocument_documentSymbol, params, opts) request_with_opts(ms.textDocument_documentSymbol, params, opts)
end end
--- @param call_hierarchy_items lsp.CallHierarchyItem[]? --- @param call_hierarchy_items lsp.CallHierarchyItem[]
--- @return lsp.CallHierarchyItem?
local function pick_call_hierarchy_item(call_hierarchy_items) local function pick_call_hierarchy_item(call_hierarchy_items)
if not call_hierarchy_items then
return
end
if #call_hierarchy_items == 1 then if #call_hierarchy_items == 1 then
return call_hierarchy_items[1] return call_hierarchy_items[1]
end end
@ -476,7 +474,7 @@ local function call_hierarchy(method)
vim.notify(err.message, vim.log.levels.WARN) vim.notify(err.message, vim.log.levels.WARN)
return return
end end
if not result then if not result or vim.tbl_isempty(result) then
vim.notify('No item resolved', vim.log.levels.WARN) vim.notify('No item resolved', vim.log.levels.WARN)
return return
end end

View File

@ -43,17 +43,16 @@ function M.on_inlayhint(err, result, ctx, _)
return return
end end
local bufnr = assert(ctx.bufnr) local bufnr = assert(ctx.bufnr)
if util.buf_versions[bufnr] ~= ctx.version then if
util.buf_versions[bufnr] ~= ctx.version
or not result
or not api.nvim_buf_is_loaded(bufnr)
or not bufstates[bufnr].enabled
then
return return
end end
local client_id = ctx.client_id local client_id = ctx.client_id
if not result then
return
end
local bufstate = bufstates[bufnr] local bufstate = bufstates[bufnr]
if not bufstate.enabled then
return
end
if not (bufstate.client_hints and bufstate.version) then if not (bufstate.client_hints and bufstate.version) then
bufstate.client_hints = vim.defaulttable() bufstate.client_hints = vim.defaulttable()
bufstate.version = ctx.version bufstate.version = ctx.version

View File

@ -154,7 +154,7 @@ end
---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16 ---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16
---@return integer byte (utf-8) index of `encoding` index `index` in `line` ---@return integer byte (utf-8) index of `encoding` index `index` in `line`
function M._str_byteindex_enc(line, index, encoding) function M._str_byteindex_enc(line, index, encoding)
local len = vim.fn.strlen(line) local len = #line
if index > len then if index > len then
-- LSP spec: if character > line length, default to the line length. -- LSP spec: if character > line length, default to the line length.
-- https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position -- https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position
@ -167,7 +167,7 @@ function M._str_byteindex_enc(line, index, encoding)
if index then if index then
return index return index
else else
return #line return len
end end
elseif encoding == 'utf-16' then elseif encoding == 'utf-16' then
return vim.str_byteindex(line, index, true) return vim.str_byteindex(line, index, true)

View File

@ -74,14 +74,14 @@ end
--- Returns the parser for a specific buffer and attaches it to the buffer --- Returns the parser for a specific buffer and attaches it to the buffer
--- ---
--- If needed, this will create the parser. --- If needed, this will create the parser. If no parser can be found or created, returns `nil`.
--- ---
---@param bufnr (integer|nil) Buffer the parser should be tied to (default: current buffer) ---@param bufnr (integer|nil) Buffer the parser should be tied to (default: current buffer)
---@param lang (string|nil) Language of this parser (default: from buffer filetype) ---@param lang (string|nil) Language of this parser (default: from buffer filetype)
---@param opts (table|nil) Options to pass to the created language tree ---@param opts (table|nil) Options to pass to the created language tree
--- ---
---@return vim.treesitter.LanguageTree object to use for parsing ---@return vim.treesitter.LanguageTree? object to use for parsing, or `nil` if not found
function M.get_parser(bufnr, lang, opts) function M._get_parser(bufnr, lang, opts)
opts = opts or {} opts = opts or {}
if bufnr == nil or bufnr == 0 then if bufnr == nil or bufnr == 0 then
@ -94,18 +94,14 @@ function M.get_parser(bufnr, lang, opts)
if not valid_lang(lang) then if not valid_lang(lang) then
if not parsers[bufnr] then if not parsers[bufnr] then
error( return nil
string.format(
'There is no parser available for buffer %d and one could not be'
.. ' created because lang could not be determined. Either pass lang'
.. ' or set the buffer filetype',
bufnr
)
)
end end
elseif parsers[bufnr] == nil or parsers[bufnr]:lang() ~= lang then elseif parsers[bufnr] == nil or parsers[bufnr]:lang() ~= lang then
assert(lang, 'lang should be valid') local parser = vim.F.npcall(M._create_parser, bufnr, lang, opts)
parsers[bufnr] = M._create_parser(bufnr, lang, opts) if not parser then
return nil
end
parsers[bufnr] = parser
end end
parsers[bufnr]:register_cbs(opts.buf_attach_cbs) parsers[bufnr]:register_cbs(opts.buf_attach_cbs)
@ -113,6 +109,29 @@ function M.get_parser(bufnr, lang, opts)
return parsers[bufnr] return parsers[bufnr]
end end
--- Returns the parser for a specific buffer and attaches it to the buffer
---
--- If needed, this will create the parser.
---
---@param bufnr (integer|nil) Buffer the parser should be tied to (default: current buffer)
---@param lang (string|nil) Language of this parser (default: from buffer filetype)
---@param opts (table|nil) Options to pass to the created language tree
---
---@return vim.treesitter.LanguageTree object to use for parsing
function M.get_parser(bufnr, lang, opts)
-- TODO(ribru17): Remove _get_parser and move that logic back here once the breaking function
-- signature change is acceptable.
local parser = M._get_parser(bufnr, lang, opts)
if not parser then
vim.notify_once(
'WARNING: vim.treesitter.get_parser will return nil instead of raising an error in Neovim 0.12',
vim.log.levels.WARN
)
error('Parser not found.')
end
return parser
end
--- Returns a string parser --- Returns a string parser
--- ---
---@param str string Text to parse ---@param str string Text to parse
@ -386,7 +405,7 @@ function M.get_node(opts)
local ts_range = { row, col, row, col } local ts_range = { row, col, row, col }
local root_lang_tree = M.get_parser(bufnr, opts.lang) local root_lang_tree = M._get_parser(bufnr, opts.lang)
if not root_lang_tree then if not root_lang_tree then
return return
end end
@ -419,7 +438,11 @@ end
---@param lang (string|nil) Language of the parser (default: from buffer filetype) ---@param lang (string|nil) Language of the parser (default: from buffer filetype)
function M.start(bufnr, lang) function M.start(bufnr, lang)
bufnr = bufnr or api.nvim_get_current_buf() bufnr = bufnr or api.nvim_get_current_buf()
local parser = M.get_parser(bufnr, lang) local parser = M._get_parser(bufnr, lang)
if not parser then
vim.notify('No parser for the given buffer.', vim.log.levels.WARN)
return
end
M.highlighter.new(parser) M.highlighter.new(parser)
end end

View File

@ -114,7 +114,7 @@ local function compute_folds_levels(bufnr, info, srow, erow, parse_injections)
srow = srow or 0 srow = srow or 0
erow = erow or api.nvim_buf_line_count(bufnr) erow = erow or api.nvim_buf_line_count(bufnr)
local parser = ts.get_parser(bufnr) local parser = assert(ts._get_parser(bufnr))
parser:parse(parse_injections and { srow, erow } or nil) parser:parse(parse_injections and { srow, erow } or nil)
@ -392,7 +392,7 @@ function M.foldexpr(lnum)
lnum = lnum or vim.v.lnum lnum = lnum or vim.v.lnum
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local parser = vim.F.npcall(ts.get_parser, bufnr) local parser = ts._get_parser(bufnr)
if not parser then if not parser then
return '0' return '0'
end end

View File

@ -172,7 +172,7 @@ function M.lint(buf, opts)
--- @type (table|nil) --- @type (table|nil)
local parser_info = vim.F.npcall(vim.treesitter.language.inspect, lang) local parser_info = vim.F.npcall(vim.treesitter.language.inspect, lang)
local parser = vim.treesitter.get_parser(buf) local parser = assert(vim.treesitter._get_parser(buf), 'query parser not found.')
parser:parse() parser:parse()
parser:for_each_tree(function(tree, ltree) parser:for_each_tree(function(tree, ltree)
if ltree:lang() == 'query' then if ltree:lang() == 'query' then

View File

@ -76,10 +76,9 @@ end
--- ---
---@package ---@package
function TSTreeView:new(bufnr, lang) function TSTreeView:new(bufnr, lang)
local ok, parser = pcall(vim.treesitter.get_parser, bufnr or 0, lang) local parser = vim.treesitter._get_parser(bufnr or 0, lang)
if not ok then if not parser then
local err = parser --[[ @as string ]] return nil, 'No parser available for the given buffer.'
return nil, 'No parser available for the given buffer:\n' .. err
end end
-- For each child tree (injected language), find the root of the tree and locate the node within -- For each child tree (injected language), find the root of the tree and locate the node within
@ -539,7 +538,7 @@ local edit_ns = api.nvim_create_namespace('treesitter/dev-edit')
local function update_editor_highlights(query_win, base_win, lang) local function update_editor_highlights(query_win, base_win, lang)
local base_buf = api.nvim_win_get_buf(base_win) local base_buf = api.nvim_win_get_buf(base_win)
local query_buf = api.nvim_win_get_buf(query_win) local query_buf = api.nvim_win_get_buf(query_win)
local parser = vim.treesitter.get_parser(base_buf, lang) local parser = assert(vim.treesitter._get_parser(base_buf, lang))
api.nvim_buf_clear_namespace(base_buf, edit_ns, 0, -1) api.nvim_buf_clear_namespace(base_buf, edit_ns, 0, -1)
local query_content = table.concat(api.nvim_buf_get_lines(query_buf, 0, -1, false), '\n') local query_content = table.concat(api.nvim_buf_get_lines(query_buf, 0, -1, false), '\n')
@ -596,8 +595,8 @@ function M.edit_query(lang)
end end
vim.cmd(cmd) vim.cmd(cmd)
local ok, parser = pcall(vim.treesitter.get_parser, buf, lang) local parser = vim.treesitter._get_parser(buf, lang)
if not ok then if not parser then
return nil, 'No parser available for the given buffer' return nil, 'No parser available for the given buffer'
end end
lang = parser:lang() lang = parser:lang()

View File

@ -33,7 +33,7 @@ end
--- Show a table of contents for the help buffer in a loclist --- Show a table of contents for the help buffer in a loclist
function M.show_toc() function M.show_toc()
local bufnr = vim.api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local parser = vim.treesitter.get_parser(bufnr, 'vimdoc') local parser = assert(vim.treesitter._get_parser(bufnr, 'vimdoc'), 'vimdoc parser not found.')
local query = vim.treesitter.query.parse( local query = vim.treesitter.query.parse(
parser:lang(), parser:lang(),
[[ [[

View File

@ -45,6 +45,11 @@
(link_destination) @_url (link_destination) @_url
(#set! @_label url @_url)) (#set! @_label url @_url))
(image
(image_description) @_label
(link_destination) @_url
(#set! @_label url @_url))
; Conceal image links ; Conceal image links
(image (image
[ [

View File

@ -33,7 +33,10 @@
")" ")"
] @punctuation.bracket ] @punctuation.bracket
":" @punctuation.delimiter [
":"
"/"
] @punctuation.delimiter
[ [
"@" "@"

View File

@ -786,7 +786,7 @@ local function parse_buf(fname, parser_path)
if parser_path then if parser_path then
vim.treesitter.language.add('vimdoc', { path = parser_path }) vim.treesitter.language.add('vimdoc', { path = parser_path })
end end
local lang_tree = vim.treesitter.get_parser(buf) local lang_tree = assert(vim.treesitter._get_parser(buf), 'vimdoc parser not found.')
return lang_tree, buf return lang_tree, buf
end end

View File

@ -3338,7 +3338,7 @@ void maketitle(void)
#define SPACE_FOR_FNAME (sizeof(buf) - 100) #define SPACE_FOR_FNAME (sizeof(buf) - 100)
#define SPACE_FOR_DIR (sizeof(buf) - 20) #define SPACE_FOR_DIR (sizeof(buf) - 20)
#define SPACE_FOR_ARGNR (sizeof(buf) - 10) // At least room for " - NVIM". #define SPACE_FOR_ARGNR (sizeof(buf) - 10) // At least room for " - Nvim".
char *buf_p = buf; char *buf_p = buf;
if (curbuf->b_fname == NULL) { if (curbuf->b_fname == NULL) {
const size_t size = xstrlcpy(buf_p, _("[No Name]"), const size_t size = xstrlcpy(buf_p, _("[No Name]"),
@ -3412,7 +3412,7 @@ void maketitle(void)
append_arg_number(curwin, buf_p, (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf))); append_arg_number(curwin, buf_p, (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf)));
xstrlcat(buf_p, " - NVIM", (sizeof(buf) - (size_t)(buf_p - buf))); xstrlcat(buf_p, " - Nvim", (sizeof(buf) - (size_t)(buf_p - buf)));
if (maxlen > 0) { if (maxlen > 0) {
// Make it shorter by removing a bit in the middle. // Make it shorter by removing a bit in the middle.

View File

@ -170,28 +170,26 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
// cache previous calculations depending on w_virtcol // cache previous calculations depending on w_virtcol
static int saved_w_virtcol; static int saved_w_virtcol;
static win_T *prev_wp; static win_T *prev_wp;
static int prev_width1;
static int prev_width2;
static int prev_left_col; static int prev_left_col;
static int prev_right_col; static int prev_right_col;
static int prev_col_off;
int cur_col_off = win_col_off(wp); int cur_col_off = win_col_off(wp);
int width1; int width1 = wp->w_width_inner - cur_col_off;
int width2; int width2 = width1 + win_col_off2(wp);
if (saved_w_virtcol == wp->w_virtcol && prev_wp == wp if (saved_w_virtcol == wp->w_virtcol && prev_wp == wp
&& prev_col_off == cur_col_off) { && prev_width1 == width1 && prev_width2 == width2) {
*right_col = prev_right_col; *right_col = prev_right_col;
*left_col = prev_left_col; *left_col = prev_left_col;
return; return;
} }
width1 = wp->w_width_inner - cur_col_off;
width2 = width1 + win_col_off2(wp);
*left_col = 0; *left_col = 0;
*right_col = width1; *right_col = width1;
if (wp->w_virtcol >= (colnr_T)width1) { if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) {
*right_col = width1 + ((wp->w_virtcol - width1) / width2 + 1) * width2; *right_col = width1 + ((wp->w_virtcol - width1) / width2 + 1) * width2;
} }
if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) { if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) {
@ -202,8 +200,9 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
prev_left_col = *left_col; prev_left_col = *left_col;
prev_right_col = *right_col; prev_right_col = *right_col;
prev_wp = wp; prev_wp = wp;
prev_width1 = width1;
prev_width2 = width2;
saved_w_virtcol = wp->w_virtcol; saved_w_virtcol = wp->w_virtcol;
prev_col_off = cur_col_off;
} }
/// Put a single char from an UTF-8 buffer into a line buffer. /// Put a single char from an UTF-8 buffer into a line buffer.

View File

@ -94,14 +94,17 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream)
stream->events = NULL; stream->events = NULL;
} }
void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data, bool rstream) void stream_may_close(Stream *stream, bool rstream)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(1)
{ {
if (stream->closed) {
return;
}
assert(!stream->closed); assert(!stream->closed);
DLOG("closing Stream: %p", (void *)stream); DLOG("closing Stream: %p", (void *)stream);
stream->closed = true; stream->closed = true;
stream->close_cb = on_stream_close; stream->close_cb = NULL;
stream->close_cb_data = data; stream->close_cb_data = NULL;
#ifdef MSWIN #ifdef MSWIN
if (UV_TTY == uv_guess_handle(stream->fd)) { if (UV_TTY == uv_guess_handle(stream->fd)) {
@ -115,13 +118,6 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data, b
} }
} }
void stream_may_close(Stream *stream, bool rstream)
{
if (!stream->closed) {
stream_close(stream, NULL, NULL, rstream);
}
}
void stream_close_handle(Stream *stream, bool rstream) void stream_close_handle(Stream *stream, bool rstream)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {

View File

@ -29,6 +29,7 @@
#include "nvim/os/stdpaths_defs.h" #include "nvim/os/stdpaths_defs.h"
#include "nvim/os/time.h" #include "nvim/os/time.h"
#include "nvim/path.h" #include "nvim/path.h"
#include "nvim/ui_client.h"
/// Cached location of the expanded log file path decided by log_path_init(). /// Cached location of the expanded log file path decided by log_path_init().
static char log_file_path[MAXPATHL + 1] = { 0 }; static char log_file_path[MAXPATHL + 1] = { 0 };
@ -322,20 +323,28 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
millis = (int)curtime.tv_usec / 1000; millis = (int)curtime.tv_usec / 1000;
} }
bool ui = !!ui_client_channel_id; // Running as a UI client (--remote-ui).
// Regenerate the name when:
// - UI client (to ensure "ui" is in the name)
// - not set yet
// - no v:servername yet
bool regen = ui || name[0] == NUL || name[0] == '?';
// Get a name for this Nvim instance. // Get a name for this Nvim instance.
// TODO(justinmk): expose this as v:name ? // TODO(justinmk): expose this as v:name ?
if (name[0] == NUL) { if (regen) {
// Parent servername. // Parent servername ($NVIM).
const char *parent = path_tail(os_getenv(ENV_NVIM)); const char *parent = path_tail(os_getenv(ENV_NVIM));
// Servername. Empty until starting=false. // Servername. Empty until starting=false.
const char *serv = path_tail(get_vim_var_str(VV_SEND_SERVER)); const char *serv = path_tail(get_vim_var_str(VV_SEND_SERVER));
if (parent[0] != NUL) { if (parent[0] != NUL) {
snprintf(name, sizeof(name), "%s/c", parent); // "/c" indicates child. snprintf(name, sizeof(name), ui ? "ui/c/%s" : "c/%s", parent); // "c/" = child of $NVIM.
} else if (serv[0] != NUL) { } else if (serv[0] != NUL) {
snprintf(name, sizeof(name), "%s", serv); snprintf(name, sizeof(name), ui ? "ui/%s" : "%s", serv);
} else { } else {
int64_t pid = os_get_pid(); int64_t pid = os_get_pid();
snprintf(name, sizeof(name), "?.%-5" PRId64, pid); snprintf(name, sizeof(name), "%s.%-5" PRId64, ui ? "ui" : "?", pid);
} }
} }
@ -348,10 +357,6 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
log_levels[log_level], date_time, millis, name, log_levels[log_level], date_time, millis, name,
(context == NULL ? "" : context), (context == NULL ? "" : context),
func_name, line_num); func_name, line_num);
if (name[0] == '?') {
// No v:servername yet. Clear `name` so that the next log can try again.
name[0] = NUL;
}
if (rv < 0) { if (rv < 0) {
return false; return false;

View File

@ -53,7 +53,7 @@ bool server_init(const char *listen_addr)
int rv = server_start(listen_addr); int rv = server_start(listen_addr);
// TODO(justinmk): this is for logging_spec. Can remove this after nvim_log #7062 is merged. // TODO(justinmk): this is for log_spec. Can remove this after nvim_log #7062 is merged.
if (os_env_exists("__NVIM_TEST_LOG")) { if (os_env_exists("__NVIM_TEST_LOG")) {
ELOG("test log message"); ELOG("test log message");
} }

View File

@ -9047,7 +9047,7 @@ return {
desc = [=[ desc = [=[
When on, the title of the window will be set to the value of When on, the title of the window will be set to the value of
'titlestring' (if it is not empty), or to: 'titlestring' (if it is not empty), or to:
filename [+=-] (path) - NVIM filename [+=-] (path) - Nvim
Where: Where:
filename the name of the file being edited filename the name of the file being edited
- indicates the file cannot be modified, 'ma' off - indicates the file cannot be modified, 'ma' off
@ -9055,11 +9055,11 @@ return {
= indicates the file is read-only = indicates the file is read-only
=+ indicates the file is read-only and modified =+ indicates the file is read-only and modified
(path) is the path of the file being edited (path) is the path of the file being edited
- NVIM the server name |v:servername| or "NVIM" - Nvim the server name |v:servername| or "Nvim"
]=], ]=],
full_name = 'title', full_name = 'title',
scope = { 'global' }, scope = { 'global' },
short_desc = N_('Vim set the title of the window'), short_desc = N_('set the title of the window'),
type = 'boolean', type = 'boolean',
varname = 'p_title', varname = 'p_title',
}, },

View File

@ -100,7 +100,7 @@ static void reset_cursorhold_wait(int tb_change_cnt)
/// ///
/// Originally based on the Vim `mch_inchar` function. /// Originally based on the Vim `mch_inchar` function.
/// ///
/// @param buf Buffer to store read input. /// @param buf Buffer to store consumed input.
/// @param maxlen Maximum bytes to read into `buf`, or 0 to skip reading. /// @param maxlen Maximum bytes to read into `buf`, or 0 to skip reading.
/// @param ms Timeout in milliseconds. -1 for indefinite wait, 0 for no wait. /// @param ms Timeout in milliseconds. -1 for indefinite wait, 0 for no wait.
/// @param tb_change_cnt Used to detect when typeahead changes. /// @param tb_change_cnt Used to detect when typeahead changes.
@ -493,7 +493,7 @@ static TriState inbuf_poll(int ms, MultiQueue *events)
blocking = true; blocking = true;
multiqueue_process_events(ch_before_blocking_events); multiqueue_process_events(ch_before_blocking_events);
} }
DLOG("blocking... events=%d pending=%d", !!events, pending_events(events)); DLOG("blocking... events=%s", !!events ? "true" : "false");
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, os_input_ready(events) || input_eof); LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, os_input_ready(events) || input_eof);
blocking = false; blocking = false;

View File

@ -1292,7 +1292,7 @@ static void shell_write_cb(Stream *stream, void *data, int status)
msg_schedule_semsg(_("E5677: Error writing input to shell-command: %s"), msg_schedule_semsg(_("E5677: Error writing input to shell-command: %s"),
uv_err_name(status)); uv_err_name(status));
} }
stream_close(stream, NULL, NULL, false); stream_may_close(stream, false);
} }
/// Applies 'shellxescape' (p_sxe) and 'shellxquote' (p_sxq) to a command. /// Applies 'shellxescape' (p_sxe) and 'shellxquote' (p_sxq) to a command.

View File

@ -6875,7 +6875,8 @@ bool set_ref_in_quickfix(int copyID)
// In a location list window and none of the other windows is // In a location list window and none of the other windows is
// referring to this location list. Mark the location list // referring to this location list. Mark the location list
// context as still in use. // context as still in use.
if (mark_quickfix_ctx(win->w_llist_ref, copyID)) { if (mark_quickfix_ctx(win->w_llist_ref, copyID)
|| mark_quickfix_user_data(win->w_llist_ref, copyID)) {
return true; return true;
} }
} }

View File

@ -22,6 +22,7 @@
#include "nvim/memory_defs.h" #include "nvim/memory_defs.h"
#include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/channel_defs.h" #include "nvim/msgpack_rpc/channel_defs.h"
#include "nvim/os/os.h"
#include "nvim/os/os_defs.h" #include "nvim/os/os_defs.h"
#include "nvim/tui/tui.h" #include "nvim/tui/tui.h"
#include "nvim/tui/tui_defs.h" #include "nvim/tui/tui_defs.h"
@ -126,6 +127,11 @@ void ui_client_run(bool remote_ui)
ui_client_attach(width, height, term, rgb); ui_client_attach(width, height, term, rgb);
// TODO(justinmk): this is for log_spec. Can remove this after nvim_log #7062 is merged.
if (os_env_exists("__NVIM_TEST_LOG")) {
ELOG("test log message");
}
// os_exit() will be invoked when the client channel detaches // os_exit() will be invoked when the client channel detaches
while (true) { while (true) {
LOOP_PROCESS_EVENTS(&main_loop, resize_events, -1); LOOP_PROCESS_EVENTS(&main_loop, resize_events, -1);

View File

@ -14,7 +14,7 @@ EXTERN size_t grid_line_buf_size INIT( = 0);
EXTERN schar_T *grid_line_buf_char INIT( = NULL); EXTERN schar_T *grid_line_buf_char INIT( = NULL);
EXTERN sattr_T *grid_line_buf_attr INIT( = NULL); EXTERN sattr_T *grid_line_buf_attr INIT( = NULL);
// ID of the ui client channel. If zero, the client is not running. // Client-side UI channel. Zero during early startup or if not a (--remote-ui) UI client.
EXTERN uint64_t ui_client_channel_id INIT( = 0); EXTERN uint64_t ui_client_channel_id INIT( = 0);
// exit status from embedded nvim process // exit status from embedded nvim process

View File

@ -1,5 +1,6 @@
local t = require('test.testutil') local t = require('test.testutil')
local n = require('test.functional.testnvim')() local n = require('test.functional.testnvim')()
local tt = require('test.functional.terminal.testutil')
local assert_log = t.assert_log local assert_log = t.assert_log
local clear = n.clear local clear = n.clear
@ -29,10 +30,54 @@ describe('log', function()
assert(request('nvim__stats').log_skip <= 13) assert(request('nvim__stats').log_skip <= 13)
end) end)
it('messages are formatted with name or test id', function() it('TUI client name is "ui"', function()
local function setup(env)
clear()
-- Start Nvim with builtin UI.
local screen = tt.setup_child_nvim({
'-u',
'NONE',
'-i',
'NONE',
'--cmd',
n.nvim_set,
}, {
env = env,
})
screen:expect([[
{1: } |
~ |*4
|
{3:-- TERMINAL --} |
]])
end
-- Without $NVIM parent.
setup({
NVIM = '',
NVIM_LISTEN_ADDRESS = '',
NVIM_LOG_FILE = testlog,
__NVIM_TEST_LOG = '1',
})
-- Example:
-- ERR 2024-09-11T16:40:02.421 ui.47056 ui_client_run:165: test log message
assert_log(' ui%.%d+% +ui_client_run:%d+: test log message', testlog, 100)
-- With $NVIM parent.
setup({
NVIM_LOG_FILE = testlog,
__NVIM_TEST_LOG = '1',
})
-- Example:
-- ERR 2024-09-11T16:41:17.539 ui/c/T2.47826.0 ui_client_run:165: test log message
local tid = _G._nvim_test_id
assert_log(' ui/c/' .. tid .. '%.%d+%.%d +ui_client_run:%d+: test log message', testlog, 100)
end)
it('formats messages with session name or test id', function()
-- Examples: -- Examples:
-- ERR 2022-05-29T12:30:03.800 T2 log_init:110: test log message -- ERR 2024-09-11T16:44:33.794 T3.49429.0 server_init:58: test log message
-- ERR 2022-05-29T12:30:03.814 T2/child log_init:110: test log message -- ERR 2024-09-11T16:44:33.823 c/T3.49429.0 server_init:58: test log message
clear({ clear({
env = { env = {
@ -47,10 +92,10 @@ describe('log', function()
exec_lua([[ exec_lua([[
local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1', '+foochild', '+qa!' }, vim.empty_dict()) local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1', '+foochild', '+qa!' }, vim.empty_dict())
vim.fn.jobwait({ j1 }, 10000) vim.fn.jobwait({ j1 }, 5000)
]]) ]])
-- Child Nvim spawned by jobstart() appends "/c" to parent name. -- Child Nvim spawned by jobstart() prepends "c/" to parent name.
assert_log('%.%d+%.%d/c +server_init:%d+: test log message', testlog, 100) assert_log('c/' .. tid .. '%.%d+%.%d +server_init:%d+: test log message', testlog, 100)
end) end)
end) end)

View File

@ -8,6 +8,7 @@ local exec_lua = n.exec_lua
local pcall_err = t.pcall_err local pcall_err = t.pcall_err
local matches = t.matches local matches = t.matches
local insert = n.insert local insert = n.insert
local NIL = vim.NIL
before_each(clear) before_each(clear)
@ -15,10 +16,12 @@ describe('treesitter language API', function()
-- error tests not requiring a parser library -- error tests not requiring a parser library
it('handles missing language', function() it('handles missing language', function()
eq( eq(
".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", '.../treesitter.lua:0: Parser not found.',
pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')") pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')")
) )
eq(NIL, exec_lua("return vim.treesitter._get_parser(0, 'borklang')"))
-- actual message depends on platform -- actual message depends on platform
matches( matches(
"Failed to load parser for language 'borklang': uv_dlopen: .+", "Failed to load parser for language 'borklang': uv_dlopen: .+",
@ -105,9 +108,10 @@ describe('treesitter language API', function()
command('set filetype=borklang') command('set filetype=borklang')
-- Should throw an error when filetype changes to borklang -- Should throw an error when filetype changes to borklang
eq( eq(
".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", '.../treesitter.lua:0: Parser not found.',
pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0, 'borklang')") pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0, 'borklang')")
) )
eq(NIL, exec_lua("return vim.treesitter._get_parser(0, 'borklang')"))
end end
) )

View File

@ -135,9 +135,7 @@ void ui_refresh(void)
insert(test_text) insert(test_text)
eq( eq(
'.../treesitter.lua:0: There is no parser available for buffer 1 and one' '.../treesitter.lua:0: Parser not found.',
.. ' could not be created because lang could not be determined. Either'
.. ' pass lang or set the buffer filetype',
pcall_err(exec_lua, 'vim.treesitter.get_parser(0)') pcall_err(exec_lua, 'vim.treesitter.get_parser(0)')
) )

View File

@ -1078,6 +1078,44 @@ describe('CursorLine and CursorLineNr highlights', function()
]]) ]])
end) end)
-- oldtest: Test_cursorline_screenline_resize()
it("'cursorlineopt' screenline is updated on window resize", function()
local screen = Screen.new(75, 8)
screen:attach()
exec([[
50vnew
call setline(1, repeat('xyz ', 30))
setlocal number cursorline cursorlineopt=screenline
normal! $
]])
screen:expect([[
{8: 1 }xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xy |
{8: }z xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz {1:~ }|
{8: }{21:xyz xyz xyz xyz xyz xyz xyz^ }{1:~ }|
{1:~ }{1:~ }|*3
{3:[No Name] [+] }{2:[No Name] }|
|
]])
command('vertical resize -4')
screen:expect([[
{8: 1 }xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xy |
{8: }z xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz {1:~ }|
{8: }{21:xyz xyz xyz xyz xyz xyz xyz xyz xyz^ }{1:~ }|
{1:~ }{1:~ }|*3
{3:[No Name] [+] }{2:[No Name] }|
|
]])
command('set cpoptions+=n')
screen:expect([[
{8: 1 }xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xy |
z xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz {1:~ }|
{21:xyz xyz xyz xyz xyz xyz xyz xyz^ }{1:~ }|
{1:~ }{1:~ }|*3
{3:[No Name] [+] }{2:[No Name] }|
|
]])
end)
-- oldtest: Test_cursorline_after_yank() -- oldtest: Test_cursorline_after_yank()
it('always updated. vim-patch:8.1.0849', function() it('always updated. vim-patch:8.1.0849', function()
local screen = Screen.new(50, 5) local screen = Screen.new(50, 5)

View File

@ -22,7 +22,7 @@ describe('title', function()
end) end)
it('has correct default title with unnamed file', function() it('has correct default title with unnamed file', function()
local expected = '[No Name] - NVIM' local expected = '[No Name] - Nvim'
command('set title') command('set title')
screen:expect(function() screen:expect(function()
eq(expected, screen.title) eq(expected, screen.title)
@ -30,7 +30,7 @@ describe('title', function()
end) end)
it('has correct default title with named file', function() it('has correct default title with named file', function()
local expected = (is_os('win') and 'myfile (C:\\mydir) - NVIM' or 'myfile (/mydir) - NVIM') local expected = (is_os('win') and 'myfile (C:\\mydir) - Nvim' or 'myfile (/mydir) - Nvim')
command('set title') command('set title')
command(is_os('win') and 'file C:\\mydir\\myfile' or 'file /mydir/myfile') command(is_os('win') and 'file C:\\mydir\\myfile' or 'file /mydir/myfile')
screen:expect(function() screen:expect(function()
@ -41,7 +41,7 @@ describe('title', function()
describe('is not changed by', function() describe('is not changed by', function()
local file1 = is_os('win') and 'C:\\mydir\\myfile1' or '/mydir/myfile1' local file1 = is_os('win') and 'C:\\mydir\\myfile1' or '/mydir/myfile1'
local file2 = is_os('win') and 'C:\\mydir\\myfile2' or '/mydir/myfile2' local file2 = is_os('win') and 'C:\\mydir\\myfile2' or '/mydir/myfile2'
local expected = (is_os('win') and 'myfile1 (C:\\mydir) - NVIM' or 'myfile1 (/mydir) - NVIM') local expected = (is_os('win') and 'myfile1 (C:\\mydir) - Nvim' or 'myfile1 (/mydir) - Nvim')
local buf2 local buf2
before_each(function() before_each(function()

View File

@ -262,14 +262,34 @@ func Test_cursorline_callback()
call timer_start(300, 'Func') call timer_start(300, 'Func')
END END
call writefile(lines, 'Xcul_timer') call writefile(lines, 'Xcul_timer', 'D')
let buf = RunVimInTerminal('-S Xcul_timer', #{rows: 8}) let buf = RunVimInTerminal('-S Xcul_timer', #{rows: 8})
call TermWait(buf, 310) call TermWait(buf, 310)
call VerifyScreenDump(buf, 'Test_cursorline_callback_1', {}) call VerifyScreenDump(buf, 'Test_cursorline_callback_1', {})
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
call delete('Xcul_timer') endfunc
func Test_cursorline_screenline_resize()
CheckScreendump
let lines =<< trim END
50vnew
call setline(1, repeat('xyz ', 30))
setlocal number cursorline cursorlineopt=screenline
normal! $
END
call writefile(lines, 'Xcul_screenline_resize', 'D')
let buf = RunVimInTerminal('-S Xcul_screenline_resize', #{rows: 8})
call VerifyScreenDump(buf, 'Test_cursorline_screenline_resize_1', {})
call term_sendkeys(buf, ":vertical resize -4\<CR>")
call VerifyScreenDump(buf, 'Test_cursorline_screenline_resize_2', {})
call term_sendkeys(buf, ":set cpoptions+=n\<CR>")
call VerifyScreenDump(buf, 'Test_cursorline_screenline_resize_3', {})
call StopVimInTerminal(buf)
endfunc endfunc
func Test_cursorline_screenline_update() func Test_cursorline_screenline_update()
@ -280,7 +300,7 @@ func Test_cursorline_screenline_update()
set cursorline cursorlineopt=screenline set cursorline cursorlineopt=screenline
inoremap <F2> <Cmd>call cursor(1, 1)<CR> inoremap <F2> <Cmd>call cursor(1, 1)<CR>
END END
call writefile(lines, 'Xcul_screenline') call writefile(lines, 'Xcul_screenline', 'D')
let buf = RunVimInTerminal('-S Xcul_screenline', #{rows: 8}) let buf = RunVimInTerminal('-S Xcul_screenline', #{rows: 8})
call term_sendkeys(buf, "A") call term_sendkeys(buf, "A")
@ -290,7 +310,17 @@ func Test_cursorline_screenline_update()
call term_sendkeys(buf, "\<Esc>") call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
call delete('Xcul_screenline') endfunc
func Test_cursorline_screenline_zero_width()
CheckOption foldcolumn
set cursorline culopt=screenline winminwidth=1 foldcolumn=1
" This used to crash Vim
1vnew | redraw
bwipe!
set cursorline& culopt& winminwidth& foldcolumn&
endfunc endfunc
func Test_cursorline_cursorbind_horizontal_scroll() func Test_cursorline_cursorbind_horizontal_scroll()

View File

@ -710,7 +710,7 @@ func s:GetFilenameChecks() abort
\ 'svg': ['file.svg'], \ 'svg': ['file.svg'],
\ 'svn': ['svn-commitfile.tmp', 'svn-commit-file.tmp', 'svn-commit.tmp'], \ 'svn': ['svn-commitfile.tmp', 'svn-commit-file.tmp', 'svn-commit.tmp'],
\ 'swayconfig': ['/home/user/.sway/config', '/home/user/.config/sway/config', '/etc/sway/config', '/etc/xdg/sway/config'], \ 'swayconfig': ['/home/user/.sway/config', '/home/user/.config/sway/config', '/etc/sway/config', '/etc/xdg/sway/config'],
\ 'swift': ['file.swift'], \ 'swift': ['file.swift', 'file.swiftinterface'],
\ 'swiftgyb': ['file.swift.gyb'], \ 'swiftgyb': ['file.swift.gyb'],
\ 'swig': ['file.swg', 'file.swig'], \ 'swig': ['file.swg', 'file.swig'],
\ 'sysctl': ['/etc/sysctl.conf', '/etc/sysctl.d/file.conf', 'any/etc/sysctl.conf', 'any/etc/sysctl.d/file.conf'], \ 'sysctl': ['/etc/sysctl.conf', '/etc/sysctl.d/file.conf', 'any/etc/sysctl.conf', 'any/etc/sysctl.d/file.conf'],

View File

@ -4071,11 +4071,23 @@ func Test_ll_window_ctx()
enew | only enew | only
endfunc endfunc
" Similar to the problem above, but for user data.
func Test_ll_window_user_data()
call setloclist(0, [#{bufnr: bufnr(), user_data: {}}])
lopen
wincmd t
close
call test_garbagecollect_now()
call feedkeys("\<CR>", 'tx')
call test_garbagecollect_now()
%bwipe!
endfunc
" The following test used to crash vim " The following test used to crash vim
func Test_lfile_crash() func Test_lfile_crash()
sp Xtest sp Xtest
au QuickFixCmdPre * bw au QuickFixCmdPre * bw
call assert_fails('lfile', 'E40') call assert_fails('lfile', 'E40:')
au! QuickFixCmdPre au! QuickFixCmdPre
endfunc endfunc