canola.nvim/spec/per_host_args_spec.lua
Barrett Ruth e387a57c0e
feat(config): add per-host/bucket extra args for SSH, S3, and FTP (#171)
* fix(view): reapply column highlights after paste and buffer edits

Problem: Column extmarks (icon color, per-character permissions) are
applied via `util.set_highlights` only during `render_buffer`. Neovim
does not duplicate extmarks on yank/paste, so lines inserted via `yyp`
or `p` render without any column highlights.

Solution: Store `col_width` and `col_align` in `session[bufnr]` after
each render. Add `M.reapply_highlights` which re-parses all buffer
lines, reconstructs the column chunk table, and re-applies extmarks via
`util.set_highlights`. Wire it to a `TextChanged` autocmd (guarded by
`_rendering[bufnr]` to skip oil's own `nvim_buf_set_lines` calls).

* fix(view): resolve LuaLS warnings in `reapply_highlights`

* feat(config): add per-host/bucket extra args for SSH, S3, and FTP

Problem: `extra_scp_args`, `extra_s3_args`, and `extra_curl_args` are
global — there's no way to pass adapter-specific args only to a single
host or bucket (e.g. `-O` for a Synology NAS that requires legacy SCP
protocol, or `--endpoint-url` for an R2 bucket).

Solution: add `ssh_hosts`, `s3_buckets`, and `ftp_hosts` config tables
that map exact hostnames/bucket names to per-target arg lists. Per-target
args are appended after the global args at call time. The `scp()` helper
in `ssh.lua` accepts a `hosts` list so cross-host copies deduplicate
host lookups. `create_s3_command` in `s3fs.lua` extracts the bucket from
the command args with no call-site changes needed. `resolved_curl_args`
in `ftp.lua` is called by both `curl()` and `ftpcmd()`.

Based on: stevearc/oil.nvim#607
2026-03-18 12:40:32 -04:00

97 lines
3.4 KiB
Lua

local config = require('oil.config')
local test_util = require('spec.test_util')
describe('per-host/bucket arg overrides', function()
after_each(function()
test_util.reset_editor()
end)
describe('ssh_hosts', function()
it('stores ssh_hosts from setup', function()
config.setup({ ssh_hosts = { ['myserver.com'] = { extra_scp_args = { '-O' } } } })
assert.are.equal('-O', config.ssh_hosts['myserver.com'].extra_scp_args[1])
end)
it('defaults to empty table when not set', function()
config.setup({})
assert.are.same({}, config.ssh_hosts)
end)
it('returns nil for unknown host', function()
config.setup({ ssh_hosts = { ['known.host'] = { extra_scp_args = { '-O' } } } })
assert.is_nil(config.ssh_hosts['unknown.host'])
end)
end)
describe('s3_buckets', function()
it('stores s3_buckets from setup', function()
config.setup({
s3_buckets = {
['my-r2-bucket'] = { extra_s3_args = { '--endpoint-url', 'https://r2.example.com' } },
},
})
assert.are.equal('--endpoint-url', config.s3_buckets['my-r2-bucket'].extra_s3_args[1])
assert.are.equal('https://r2.example.com', config.s3_buckets['my-r2-bucket'].extra_s3_args[2])
end)
it('defaults to empty table when not set', function()
config.setup({})
assert.are.same({}, config.s3_buckets)
end)
it('returns nil for unknown bucket', function()
config.setup({
s3_buckets = { ['known-bucket'] = { extra_s3_args = { '--no-sign-request' } } },
})
assert.is_nil(config.s3_buckets['unknown-bucket'])
end)
end)
describe('ftp_hosts', function()
it('stores ftp_hosts from setup', function()
config.setup({ ftp_hosts = { ['ftp.internal.com'] = { extra_curl_args = { '--insecure' } } } })
assert.are.equal('--insecure', config.ftp_hosts['ftp.internal.com'].extra_curl_args[1])
end)
it('defaults to empty table when not set', function()
config.setup({})
assert.are.same({}, config.ftp_hosts)
end)
it('returns nil for unknown host', function()
config.setup({ ftp_hosts = { ['known.host'] = { extra_curl_args = { '--insecure' } } } })
assert.is_nil(config.ftp_hosts['unknown.host'])
end)
it('reflects --insecure in per-host curl args', function()
config.setup({ ftp_hosts = { ['ftp.internal.com'] = { extra_curl_args = { '--insecure' } } } })
local host_cfg = config.ftp_hosts['ftp.internal.com']
assert.is_truthy(vim.tbl_contains(host_cfg.extra_curl_args, '--insecure'))
end)
end)
describe('merge semantics', function()
it('per-host ssh args supplement global args', function()
config.setup({
extra_scp_args = { '-C' },
ssh_hosts = { ['myserver.com'] = { extra_scp_args = { '-O' } } },
})
assert.are.same({ '-C' }, config.extra_scp_args)
assert.are.same({ '-O' }, config.ssh_hosts['myserver.com'].extra_scp_args)
end)
it('per-bucket s3 args supplement global args', function()
config.setup({
extra_s3_args = { '--sse', 'aws:kms' },
s3_buckets = {
['special-bucket'] = { extra_s3_args = { '--endpoint-url', 'https://...' } },
},
})
assert.are.same({ '--sse', 'aws:kms' }, config.extra_s3_args)
assert.are.same(
{ '--endpoint-url', 'https://...' },
config.s3_buckets['special-bucket'].extra_s3_args
)
end)
end)
end)