Skip to content

bug: image doc rendering never attaches on Windows (langs() assumes forward slashes) #2941

Description

@reminiscience

Did you check docs and existing issues?

  • I have read all the snacks.nvim docs
  • I have updated the plugin to the latest version before submitting this issue
  • I have searched the existing issues of snacks.nvim
  • I have searched the existing issues of plugins related to this issue

Neovim version (nvim -v)

NVIM v0.12.5 (Release)

Operating system/version

Windows 11 Pro 26200

Describe the bug

Snacks.image.langs() builds the list of supported languages by matching the paths of the bundled query files:

function M.langs()
local queries = vim.api.nvim_get_runtime_file("queries/*/images.scm", true)
return vim.tbl_map(function(q)
return q:match("queries/(.-)/images%.scm")
end, queries)
end

function M.langs()
  local queries = vim.api.nvim_get_runtime_file("queries/*/images.scm", true)
  return vim.tbl_map(function(q)
    return q:match("queries/(.-)/images%.scm")
  end, queries)
end

On Windows nvim_get_runtime_file returns backslash-separated paths, e.g.

C:\Users\me\AppData\Local\nvim-data\lazy\snacks.nvim\queries\latex\images.scm

The pattern queries/(.-)/images%.scm therefore never matches, vim.tbl_map maps every entry to nil, and langs() returns an empty table even though all 12 query files are found.

M.setup() gates the FileType autocmd on that list:

local langs = M.langs()
vim.api.nvim_create_autocmd("FileType", {
group = group,
callback = function(e)
local ft = vim.bo[e.buf].filetype
local lang = vim.treesitter.language.get_lang(ft)
if vim.tbl_contains(langs, lang) then
vim.schedule(function()
if vim.api.nvim_buf_is_valid(e.buf) then
M.doc.attach(e.buf)

local langs = M.langs()
vim.api.nvim_create_autocmd("FileType", {
  callback = function(e)
    local lang = vim.treesitter.language.get_lang(vim.bo[e.buf].filetype)
    if vim.tbl_contains(langs, lang) then   -- always false on Windows
      ...M.doc.attach(e.buf)

Because the list is empty, doc.attach is never called. Consequence on Windows: no images and no math are rendered in markdown, latex, html, css, … buffers.

Two things make this hard to spot:

  1. Opening an image file directly still works (nvim image.png), because that path does not go through langs(). The feature therefore looks partially working rather than broken.
  2. :checkhealth snacks reports The 'latex' treesitter parser is required to render LaTeX math expressions even when the parser is installed and loadable — the health check uses the same langs(), so it misattributes the cause.

This is independent of the terminal; langs() only inspects runtime paths.

Steps To Reproduce

On Windows, with the image module enabled:

  1. :lua =Snacks.image.langs() → {} (expected: the list of languages)
  2. Directly reproducing the cause, without any config:
    :lua =vim.tbl_map(function(q) return q:match("queries/(.-)/images%.scm") end, vim.api.nvim_get_runtime_file("queries/*/images.scm", true))
    → {}, while
    :lua =#vim.api.nvim_get_runtime_file("queries/*/images.scm", true)
    → 12
  3. Open a markdown file containing ![img](some.png) or $$x^2$$ → nothing is rendered, doc.attach is never reached.
  4. :checkhealth snacks warns that the latex parser is missing, while :lua =vim.treesitter.language.add("latex") returns true.

Expected Behavior

langs() returns the languages regardless of the path separator, so doc.attach runs and images/math render in documents on Windows as they do elsewhere.

A separator-agnostic match fixes it. Filtering is needed as well, since vim.tbl_map would otherwise produce a table with holes when an entry does not match:

function M.langs()
  local ret = {} ---@type string[]
  for _, q in ipairs(vim.api.nvim_get_runtime_file("queries/*/images.scm", true)) do
    local lang = q:gsub("\\", "/"):match("queries/(.-)/images%.scm")
    if lang then
      ret[#ret + 1] = lang
    end
  end
  return ret
end

Verified locally: with this change langs() returns all 12 languages, :checkhealth snacks reports LaTeX math equations are supported, and images and pdflatex-rendered math appear in markdown buffers.

Repro

vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()

require("lazy.minit").repro({
  spec = {
    { "folke/snacks.nvim", opts = { image = { enabled = true } } },
  },
})

-- On Windows this prints {} ; on Linux/macOS it prints the list of languages.
vim.schedule(function()
  print(vim.inspect(require("snacks.image").langs()))
end)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleThis issue or PR has been inactive for a while

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions