Some checks are pending
quality / changes (push) Waiting to run
quality / Lua Format Check (push) Blocked by required conditions
quality / Lua Lint Check (push) Blocked by required conditions
quality / Lua Type Check (push) Blocked by required conditions
quality / Markdown Format Check (push) Blocked by required conditions
test / Test (Neovim nightly) (push) Waiting to run
test / Test (Neovim stable) (push) Waiting to run
* refactor: revert module namespace from canola back to oil
Problem: the canola rename creates unnecessary friction for users
migrating from stevearc/oil.nvim — every `require('oil')` call and
config reference must change.
Solution: revert all module paths, URL schemes, autocmd groups,
highlight groups, and filetype names back to `oil`. The repo stays
`canola.nvim` for identity; the code is a drop-in replacement.
* refactor: remove `vim.g.oil` declarative config
Problem: the `vim.g.oil` configuration path was added prematurely.
It adds a second config entrypoint before the plugin has stabilized
enough to justify it.
Solution: remove `vim.g.oil` support from `plugin/oil.lua`,
`config.setup()`, docs, and tests. Users configure via
`require("oil").setup({})`.
249 lines
7.6 KiB
Lua
249 lines
7.6 KiB
Lua
local constants = require('oil.constants')
|
|
local parser = require('oil.mutator.parser')
|
|
local test_adapter = require('oil.adapters.test')
|
|
local test_util = require('spec.test_util')
|
|
local util = require('oil.util')
|
|
local view = require('oil.view')
|
|
|
|
local FIELD_ID = constants.FIELD_ID
|
|
local FIELD_META = constants.FIELD_META
|
|
|
|
local function set_lines(bufnr, lines)
|
|
vim.bo[bufnr].modifiable = true
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines)
|
|
end
|
|
|
|
describe('parser', function()
|
|
after_each(function()
|
|
test_util.reset_editor()
|
|
end)
|
|
|
|
it('detects new files', function()
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
'a.txt',
|
|
})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({ { entry_type = 'file', name = 'a.txt', type = 'new' } }, diffs)
|
|
end)
|
|
|
|
it('detects new directories', function()
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
'foo/',
|
|
})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({ { entry_type = 'directory', name = 'foo', type = 'new' } }, diffs)
|
|
end)
|
|
|
|
it('detects new links', function()
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
'a.txt -> b.txt',
|
|
})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same(
|
|
{ { entry_type = 'link', name = 'a.txt', type = 'new', link = 'b.txt' } },
|
|
diffs
|
|
)
|
|
end)
|
|
|
|
it('detects deleted files', function()
|
|
local file = test_adapter.test_set('/foo/a.txt', 'file')
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({
|
|
{ name = 'a.txt', type = 'delete', id = file[FIELD_ID] },
|
|
}, diffs)
|
|
end)
|
|
|
|
it('detects deleted directories', function()
|
|
local dir = test_adapter.test_set('/foo/bar', 'directory')
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({
|
|
{ name = 'bar', type = 'delete', id = dir[FIELD_ID] },
|
|
}, diffs)
|
|
end)
|
|
|
|
it('detects deleted links', function()
|
|
local file = test_adapter.test_set('/foo/a.txt', 'link')
|
|
file[FIELD_META] = { link = 'b.txt' }
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({
|
|
{ name = 'a.txt', type = 'delete', id = file[FIELD_ID] },
|
|
}, diffs)
|
|
end)
|
|
|
|
it('ignores empty lines', function()
|
|
local file = test_adapter.test_set('/foo/a.txt', 'file')
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
local cols = view.format_entry_cols(file, {}, {}, test_adapter, false)
|
|
local lines = util.render_table({ cols }, {})
|
|
table.insert(lines, '')
|
|
table.insert(lines, ' ')
|
|
set_lines(bufnr, lines)
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({}, diffs)
|
|
end)
|
|
|
|
it('errors on missing filename', function()
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
'/008',
|
|
})
|
|
local _, errors = parser.parse(bufnr)
|
|
assert.are_same({
|
|
{
|
|
message = 'Malformed ID at start of line',
|
|
lnum = 0,
|
|
end_lnum = 1,
|
|
col = 0,
|
|
},
|
|
}, errors)
|
|
end)
|
|
|
|
it('errors on empty dirname', function()
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
'/008 /',
|
|
})
|
|
local _, errors = parser.parse(bufnr)
|
|
assert.are.same({
|
|
{
|
|
message = 'No filename found',
|
|
lnum = 0,
|
|
end_lnum = 1,
|
|
col = 0,
|
|
},
|
|
}, errors)
|
|
end)
|
|
|
|
it('errors on duplicate names', function()
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
'foo',
|
|
'foo/',
|
|
})
|
|
local _, errors = parser.parse(bufnr)
|
|
assert.are.same({
|
|
{
|
|
message = 'Duplicate filename',
|
|
lnum = 1,
|
|
end_lnum = 2,
|
|
col = 0,
|
|
},
|
|
}, errors)
|
|
end)
|
|
|
|
it('errors on duplicate names for existing files', function()
|
|
local file = test_adapter.test_set('/foo/a.txt', 'file')
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
'a.txt',
|
|
string.format('/%d a.txt', file[FIELD_ID]),
|
|
})
|
|
local _, errors = parser.parse(bufnr)
|
|
assert.are.same({
|
|
{
|
|
message = 'Duplicate filename',
|
|
lnum = 1,
|
|
end_lnum = 2,
|
|
col = 0,
|
|
},
|
|
}, errors)
|
|
end)
|
|
|
|
it('ignores new dirs with empty name', function()
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
'/',
|
|
})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({}, diffs)
|
|
end)
|
|
|
|
it('parses a rename as a delete + new', function()
|
|
local file = test_adapter.test_set('/foo/a.txt', 'file')
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
string.format('/%d b.txt', file[FIELD_ID]),
|
|
})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({
|
|
{ type = 'new', id = file[FIELD_ID], name = 'b.txt', entry_type = 'file' },
|
|
{ type = 'delete', id = file[FIELD_ID], name = 'a.txt' },
|
|
}, diffs)
|
|
end)
|
|
|
|
it('detects a new trailing slash as a delete + create', function()
|
|
local file = test_adapter.test_set('/foo', 'file')
|
|
vim.cmd.edit({ args = { 'oil-test:///' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
string.format('/%d foo/', file[FIELD_ID]),
|
|
})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({
|
|
{ type = 'new', name = 'foo', entry_type = 'directory' },
|
|
{ type = 'delete', id = file[FIELD_ID], name = 'foo' },
|
|
}, diffs)
|
|
end)
|
|
|
|
it('detects renamed files that conflict', function()
|
|
local afile = test_adapter.test_set('/foo/a.txt', 'file')
|
|
local bfile = test_adapter.test_set('/foo/b.txt', 'file')
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
string.format('/%d a.txt', bfile[FIELD_ID]),
|
|
string.format('/%d b.txt', afile[FIELD_ID]),
|
|
})
|
|
local diffs = parser.parse(bufnr)
|
|
local first_two = { diffs[1], diffs[2] }
|
|
local last_two = { diffs[3], diffs[4] }
|
|
table.sort(first_two, function(a, b)
|
|
return a.id < b.id
|
|
end)
|
|
table.sort(last_two, function(a, b)
|
|
return a.id < b.id
|
|
end)
|
|
assert.are.same({
|
|
{ name = 'b.txt', type = 'new', id = afile[FIELD_ID], entry_type = 'file' },
|
|
{ name = 'a.txt', type = 'new', id = bfile[FIELD_ID], entry_type = 'file' },
|
|
}, first_two)
|
|
assert.are.same({
|
|
{ name = 'a.txt', type = 'delete', id = afile[FIELD_ID] },
|
|
{ name = 'b.txt', type = 'delete', id = bfile[FIELD_ID] },
|
|
}, last_two)
|
|
end)
|
|
|
|
it('views link targets with trailing slashes as the same', function()
|
|
local file = test_adapter.test_set('/foo/mydir', 'link')
|
|
file[FIELD_META] = { link = 'dir/' }
|
|
vim.cmd.edit({ args = { 'oil-test:///foo/' } })
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
set_lines(bufnr, {
|
|
string.format('/%d mydir/ -> dir/', file[FIELD_ID]),
|
|
})
|
|
local diffs = parser.parse(bufnr)
|
|
assert.are.same({}, diffs)
|
|
end)
|
|
end)
|