No description
Find a file
Barrett Ruth a5cfee05a4
feat(ftp): add FTP/FTPS adapter via curl
Problem: canola has no way to browse or edit files on FTP servers,
despite the adapter system being designed for exactly this pattern.
curl speaks FTP natively, including FTPS (FTP over TLS), and requires
no new dependencies.

Solution: implement `lua/oil/adapters/ftp.lua` with `oil-ftp://` and
`oil-ftps://` schemes. Parses Unix and IIS LIST output, supports
`size`, `mtime`, and `permissions` columns, and implements the full
adapter API (list, read_file, write_file, render_action, perform_action).
Same-host renames use RNFR/RNTO; cross-host and local↔FTP copies use
curl download/upload through a tmpfile. Adds `extra_curl_args` config
option and documents the adapter in `doc/oil.txt`.

Based on: stevearc/oil.nvim#210
2026-03-17 23:43:37 -04:00
.github refactor: revert canola namespace to oil and remove vim.g config (#120) 2026-03-10 22:49:56 -04:00
doc feat(ftp): add FTP/FTPS adapter via curl 2026-03-17 23:43:37 -04:00
lua feat(ftp): add FTP/FTPS adapter via curl 2026-03-17 23:43:37 -04:00
perf refactor: revert canola namespace to oil and remove vim.g config (#120) 2026-03-10 22:49:56 -04:00
plugin refactor: revert canola namespace to oil and remove vim.g config (#120) 2026-03-10 22:49:56 -04:00
scripts Ci/digest final (#69) 2026-03-04 14:10:07 -05:00
spec fix(test): resolve trash_spec.lua flakes from leaked mutation state (#163) 2026-03-17 11:47:01 -04:00
syntax refactor: revert canola namespace to oil and remove vim.g config (#120) 2026-03-10 22:49:56 -04:00
.busted build: migrate test framework from plenary to busted 2026-02-22 00:26:54 -05:00
.editorconfig build: modernize repository (#27) 2026-02-22 16:06:31 -05:00
.gitignore refactor: drop nvim 0.8/0.9 compat shims from init.lua (#79) 2026-03-06 16:36:37 -05:00
.luarc.json ci: scripts and format (#68) 2026-03-04 13:49:06 -05:00
.pre-commit-config.yaml build: replace luacheck with selene, add nix devshell and pre-commit (#20) 2026-02-21 23:52:27 -05:00
.prettierrc build: modernize repository (#27) 2026-02-22 16:06:31 -05:00
.stylua.toml build: replace luacheck with selene, add nix devshell and pre-commit (#20) 2026-02-21 23:52:27 -05:00
.styluaignore ci: scripts and format (#68) 2026-03-04 13:49:06 -05:00
canola.nvim-scm-1.rockspec docs: rename repository from oil.nvim to canola.nvim 2026-02-22 22:01:34 -05:00
flake.lock build: replace luacheck with selene, add nix devshell and pre-commit (#20) 2026-02-21 23:52:27 -05:00
flake.nix refactor: rename oil to canola across entire codebase (#70) 2026-03-05 14:50:10 -05:00
LICENSE build: modernize repository (#27) 2026-02-22 16:06:31 -05:00
README.md doc: update install instructions 2026-03-16 15:57:35 -04:00
selene.toml ci: migrate to nix 2026-02-23 18:13:51 -05:00
vim.yaml ci: add bit luajit global 2026-02-23 18:18:35 -05:00

canola.nvim

A refined oil.nvim — edit your filesystem like a buffer, with bug fixes and community PRs that haven't landed upstream.

Upstream tracker — full PR and issue triage against oil.nvim

https://user-images.githubusercontent.com/506791/209727111-6b4a11f4-634a-4efa-9461-80e9717cea94.mp4

Features

  • Edit directory listings as normal buffers — mutations are derived by diffing
  • Cross-directory move, copy, and rename across any adapter
  • Adapters for local filesystem, SSH, S3, and OS trash
  • File preview in split or floating window
  • Configurable columns (icon, size, permissions, timestamps)
  • Executable file highlighting and filetype-aware icons
  • Floating window and split layouts

Requirements

Installation

Install with your package manager of choice or via luarocks:

luarocks install canola.nvim

Documentation

:help canola.nvim

FAQ

Q: How do I migrate from stevearc/oil.nvim?

Simply change the plugin source from stevearc/oil.nvim to barretruth/oil.nvim.

Before (stevearc/oil.nvim):

{
  'stevearc/oil.nvim',
  opts = { ... },
  config = function(_, opts)
    require('oil').setup(opts)
  end,
}

After (barrettruth/oil.nvim):

{
  'barrettruth/oil.nvim',
  opts = { ... },
  config = function(_, opts)
    require('oil').setup(opts)
  end,
}

init runs before the plugin loads; config runs after. oil.nvim reads vim.g.canola at load time, so init is the correct hook. Do not use config, opts, or lazy — oil.nvim loads itself when you open a directory.

Q: Why "canola"?

Canola oil! But...

Q: Why "oil"?

From the vim-vinegar README, a quote by Drew Neil:

Split windows and the project drawer go together like oil and vinegar

Q: What are some alternatives?

Acknowledgements