stevearc / oil.nvim

Neovim file explorer: edit your filesystem like a buffer
MIT License
3.84k stars 110 forks source link

bug: oil can't handle emojis #294

Open angelidis opened 8 months ago

angelidis commented 8 months ago

Did you check the docs and existing issues?

Neovim version (nvim -v)

0.9.5

Operating system/version

Windows 11

Describe the bug

oil.nvim is an amazing plugin and this isn't important -- just relaying it for completeness.

I use oil.nvim as a general renamer and run into the following. if you have a filename that includes emojis (*) and try to rename it, oil.nvim wont complain, but it will hang.

for example:

WILDEST Diet Ever? 😳 BJJ Star Mikey Musumeci Cooks THIS Before Fights.mp4

(*) this happens for example if you have video titles from youtube

What is the severity of this bug?

minor (annoyance)

Steps To Reproduce

try to rename file with emoji

Expected Behavior

file getting renamed

Directory structure

No response

Repro

-- save as repro.lua
-- run with nvim -u repro.lua
-- DO NOT change the paths
local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "runtime", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "--single-branch",
    "https://github.com/folke/lazy.nvim.git",
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  "folke/tokyonight.nvim",
  {
        "stevearc/oil.nvim",
        config = function()
            require("oil").setup({
              -- add any needed settings here
            })
        end,
  },
  -- add any other plugins here
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")
-- add anything else here

Did you check the bug with a clean config?

stevearc commented 5 months ago

This looks like a bug either in libuv or luv. If you run this script in the directory with the file that has an emoji in the name, you see weird behavior. Calling fs_stat on the file using the synchronous API returns ENOENT: no such file or directory, which is odd because we're just passing in the exact same name that we got from fs_readdir. What's worse is when we call fs_stat using the async API, it never calls the callback at all.

local uv = vim.uv or vim.loop

uv.fs_opendir(".", function(open_err, fd)
  if open_err then
    print(open_err)
    return
  end

  uv.fs_readdir(fd, function(read_err, entries)
    if read_err then
      print(read_err)
      return
    end

    for _, entry in ipairs(entries) do
      print("entry:", entry.name)

      local _, sync_stat_err = uv.fs_stat(entry.name)
      if sync_stat_err then
        print("sync stat err:", sync_stat_err)
      end
      uv.fs_stat(entry.name, function(stat_err, stat)
        if stat_err then
          print(stat_err)
          return
        end
        print("Stat", vim.inspect(stat))
      end)
    end
  end)
end, 100)

If you have the time you could try to repro this with bare luv outside of neovim and report it upstream.