bug: oil can't handle emojis
Did you check the docs and existing issues?
- [X] I have read the docs
- [X] I have searched the 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?
- [X] I have confirmed that the bug reproduces with
nvim -u repro.luausing the repro.lua file above.
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.