require_last_push_approval blocked barrettruth from approving their
own push. Disabled that restriction in the ruleset — 1 approval is
still required for all PRs, but the approver can now be the pusher.
DIGEST_PAT (barrettruth) approves, CI runs via PAT push, auto-merge
fires when checks pass.
require_last_push_approval blocked barrettruth from approving their
own push. Disabled that restriction in the ruleset — 1 approval is
still required for all PRs, but the approver can now be the pusher.
DIGEST_PAT (barrettruth) approves, CI runs via PAT push, auto-merge
fires when checks pass.
The GITHUB_TOKEN has admin-level bypass on the ruleset. When
gh pr merge --auto is called, the bypass satisfies the review
requirement automatically — no explicit approve step needed.
The self-review error is gone. PAT still handles the push so
CI triggers.
require_last_push_approval blocks barrettruth from approving their
own push. The bot (GITHUB_TOKEN) approves instead — different actor
from the PAT pusher, satisfying the rule.
Problem: actions/checkout sets an http.extraheader with GITHUB_TOKEN
that overrides any credentials in the remote URL, so git push uses
GITHUB_TOKEN regardless of the URL — suppressing CI triggers.
Solution: unset the extraheader before pushing, forcing git to use
the DIGEST_PAT embedded in the remote URL.
ci(digest): push branch with PAT so CI triggers
Problem: GITHUB_TOKEN suppresses all downstream workflow triggers
including push events, so CI never runs on the digest branch.
Solution: push with DIGEST_PAT (triggers CI as a real user push),
then reset the remote to GITHUB_TOKEN for PR creation. Admin bypass
on the ruleset handles the review requirement.
Problem: GITHUB_TOKEN-created PRs suppress pull_request triggers,
so CI never runs and auto-merge stalls.
Solution: add ci/upstream-digest to the push trigger in test and
quality workflows. CI runs on the branch push before the PR exists;
check results attach to the commit SHA so the PR sees them as
passing. The digest workflow reverts to GITHUB_TOKEN for PR
creation — no PAT needed, no contribution inflation.
Problem: GITHUB_TOKEN-created PRs suppress pull_request workflow
triggers, so CI never runs and auto-merge stalls indefinitely.
Solution: use DIGEST_PAT to create the PR. A PAT-created PR is
treated as a real user action, triggering CI normally. Auto-approve
handles the review requirement, auto-merge fires when checks pass.
Problem: the main branch ruleset requires 1 approving review, which
blocks auto-merge. The GITHUB_TOKEN cannot approve its own PR.
Solution: after creating the PR, approve it using DIGEST_PAT (a
fine-grained PAT stored as a repo secret), then enable auto-merge.
The approval comes from a different actor than the bot, satisfying
require_last_push_approval.
Problem: the workflow creates a new dated branch each run. If a digest
PR is not merged before the next run, duplicate PRs accumulate.
Solution: use a single canonical branch ci/upstream-digest with
--force push. Each run resets to main, applies any new items, and
force-pushes. If a PR is already open for the branch, GitHub updates
it in place. A new PR is only created (with auto-merge) when none
exists. The close-stale step is no longer needed.
Problem: if a digest PR is not merged before the next weekly run, a
second PR is created for the same items plus any new ones, leading
to duplicate open PRs.
Solution: before fetching upstream activity, close any open PRs
labeled upstream/digest (deleting their branches). The new run
re-fetches all items since the last merged baseline and produces a
single up-to-date PR.
Problem: new upstream issues and PRs slip through because there's no
mechanism to surface them — manual polling of stevearc/oil.nvim is
required and easy to forget.
Solution: add a Monday 9am UTC scheduled workflow that reads the
highest stevearc/oil.nvim number from doc/upstream.md, fetches merged
PRs and new open issues/PRs above that threshold via the gh CLI, and
creates a structured digest issue in barrettruth/canola.nvim. No issue
is created when there's nothing new. Falls back to a 30-day window if
doc/upstream.md can't be parsed.
Problem: when the nonicons direct API was detected, all icons were
returned with the generic 'OilFileIcon' highlight group, losing
per-filetype colors from nvim-web-devicons.
Solution: resolve highlight groups from devicons when available so
nonicons glyphs retain their per-filetype colors.
Problem: the full upstream PR and issue triage was removed from the
README during the repository modernization, leaving no user-facing
record of what the fork addresses.
Solution: restore the triage tables in a dedicated doc/upstream.md and
link to it from the top of the README. Keeps the README clean while
giving the full picture a permanent home.
Problem: the fork shared the same name as upstream, making it difficult
to distinguish and discover independently.
Solution: rename the repository to canola.nvim — a type of oil, making
the lineage obvious while establishing a distinct identity. Update all
references in the README, rockspec, and issue templates.
Problem: nonicons.nvim exposes a public get_icon/get_icon_by_filetype
API, but oil.nvim can only use nonicons glyphs indirectly through the
devicons monkey-patch. This couples oil to devicons even when nonicons
is available standalone.
Solution: add a nonicons provider in get_icon_provider() between
mini.icons and devicons. Feature-gated on nonicons.get_icon existing
so old nonicons versions fall through to devicons. Uses OilDirIcon
and OilFileIcon highlight groups.
* feat(icons): add nonicons.nvim icon provider support
Problem: oil.nvim only recognizes mini.icons and nvim-web-devicons as
icon providers. nonicons.nvim works when paired with devicons (via its
apply() monkey-patch), but has no standalone support.
Solution: add a nonicons.nvim fallback in get_icon_provider(), placed
after devicons so the patched devicons path is preferred when both are
installed. The standalone path handles directories via
nonicons.get('file-directory'), files via filetype/extension lookup with
a generic file icon fallback.
* fix(doc): improve readme phrasing
Problem: mrcjkb/lua-typecheck-action runs lua-language-server in a bare
nix sandbox without neovim installed, causing 71 type errors for all
vim.* and uv.* types. LuaLS 3.17.x also introduced stricter type
checking that flags uv.aliases.fs_types mismatches not present in
3.16.4. The .luarc.json workspace.library entries conflicted with the
action's auto-appended luvit-meta, producing duplicate uv type unions.
Solution: switch to stevearc/nvim-typecheck-action@v2 (matching
upstream), pin LuaLS to 3.16.4, convert .luarc.json to nested format
without workspace.library (let the action provide VIMRUNTIME and
luvit-meta), and add .direnv/* to selene.toml exclude for local use.
* build: clean up gitignore and remove empty gitmodules
Problem: .gitignore contained 48 lines of C/shared-object boilerplate
irrelevant to a Lua Neovim plugin. .gitmodules was tracked but empty.
Solution: replace .gitignore with minimal entries covering only files
this project actually produces. Delete the vestigial .gitmodules.
* build: add editorconfig and prettierrc
Problem: no editor or formatter configuration, inconsistent with
cp.nvim and diffs.nvim conventions.
Solution: add .editorconfig (2-space Lua indent, utf-8, final newline)
and .prettierrc (prose wrap, 80 cols, single quotes, no semi) matching
the other repos.
* build: add Makefile for lint and test targets
Problem: .github/pre-commit calls `make fastlint` and .github/pre-push
calls `make lint && make test`, but no Makefile existed, so the git
hooks failed.
Solution: add Makefile with lint (stylua + selene), fastlint
(pre-commit), and test (luarocks test) targets.
* docs: add fork copyright to LICENSE
Problem: LICENSE only contained the original author's copyright notice.
Solution: add a second copyright line for the fork maintainer. MIT
requires retaining the original notice; adding a line for derivative
work is standard practice.
* ci: restructure workflows to quality/test/luarocks pattern
Problem: CI used a single tests.yml for linting, typechecking, and
testing. No conditional path filtering, no markdown format check, and
a stale mirror_upstream_prs.yml and duplicate luarocks.yml existed.
Solution: replace tests.yml with quality.yaml (stylua, selene,
lua-typecheck, prettier with dorny/paths-filter) and test.yaml
(nvim-busted, stable+nightly matrix). Update luarocks.yaml to
reference quality.yaml. Delete mirror_upstream_prs.yml and duplicate
luarocks.yml. Fix automation workflow sender check.
* build: rewrite issue templates
Problem: issue templates used upstream stevearc references, severity
dropdowns, outdated lazy.nvim bootstrap, and the .yml extension
inconsistent with other repos.
Solution: replace with .yaml templates matching cp.nvim/diffs.nvim
style. Bug report uses prerequisites checkboxes, checkhealth output,
modern lazy.nvim bootstrap with vim.g.oil pattern. Feature request
uses problem/solution/alternatives format. Add config.yaml to disable
blank issues and link discussions.
* docs: rewrite README
Problem: README contained upstream triage tables, severity dropdowns,
the old setup() pattern, a tree view question, and references to
stevearc/oil.nvim as the primary source.
Solution: full rewrite matching cp.nvim/diffs.nvim style with bold
tagline, features list, requirements, installation, documentation,
FAQ (lazy.nvim setup with vim.g.oil, migration guide, alternatives),
and acknowledgements crediting the original author.
* revert: remove Makefile
Problem: Makefile was added in b9279b5 but was previously deleted
intentionally.
Solution: remove it.
* fix(test): resolve busted migration test isolation issues
Problem: Two issues introduced during the plenary-to-busted migration
(6be0148). First, altbuf_spec waited for two BufEnter events but
oil:// → file resolution only fires one async BufEnter (the synchronous
one from vim.cmd.edit fires before wait_for_autocmd is registered).
Second, reset_editor kept the first window which could be a preview
window with stale oil_preview/oil_source_win state, causing
close_preview_window_if_not_in_oil to close the wrong window in
subsequent tests.
Solution: Wait for a single BufEnter in the altbuf test. Replace the
window-keeping logic in reset_editor with vim.cmd.new() +
vim.cmd.only() to guarantee a fresh window with no inherited state.
This also fixes the preview_spec.lua:30 timeout which had the same
root cause. 114/114 tests pass.
* fix(ci): fix nightly tests and remove unused Makefile
Problem: Neovim nightly's ftplugin/markdown.lua now calls
vim.treesitter.start() unconditionally, which crashes in CI where the
markdown parser is not installed. The Makefile is unused — CI runs
selene, stylua, and nvim-busted-action directly.
Solution: Change filetype plugin indent on to filetype on in
minimal_init.lua. Tests only need filetype detection for
vim.bo.filetype assertions, not ftplugin or indent loading. Remove
the Makefile.
Problem: plenary.nvim is deprecated. The test suite depends on
plenary's async test runner and coroutine-based utilities, tying the
project to an unmaintained dependency. CI also tests against Neovim
0.8-0.11, which are no longer relevant.
Solution: replace plenary with busted + nlua (nvim -l). Convert all
async test patterns (a.wrap, a.util.sleep, a.util.scheduler) to
synchronous equivalents using vim.wait. Rename tests/ to spec/ to
follow busted convention. Replace the CI test matrix with
nvim-busted-action targeting stable/nightly only. Add .busted config,
luarocks test_dependencies, and update the nix devshell.
* build: replace luacheck with selene
Problem: luacheck is unmaintained (last release 2018) and required
suppressing four warning classes to avoid false positives. It also
lacks first-class vim/neovim awareness.
Solution: switch to selene with std='vim' for vim-aware linting.
Replace the luacheck CI job with selene, update the Makefile lint
target, and delete .luacheckrc.
* build: add nix devshell and pre-commit hooks
Problem: oil.nvim had no reproducible dev environment. The .envrc
set up a Python venv for the now-removed docgen pipeline, and there
were no pre-commit hooks for local formatting checks.
Solution: add flake.nix with stylua, selene, and prettier in the
devshell. Replace the stale Python .envrc with 'use flake'. Add
.pre-commit-config.yaml with stylua and prettier hooks matching
other plugins in the repo collection.
* fix: format with stylua
* build(selene): configure lints and add inline suppressions
Problem: selene fails on 5 errors and 3 warnings from upstream code
patterns that are intentional (mixed tables in config API, unused
callback parameters, identical if branches for readability).
Solution: globally allow mixed_table and unused_variable (high volume,
inherent to the codebase design). Add inline selene:allow directives
for the 8 remaining issues: if_same_then_else (4), mismatched_arg_count
(1), empty_if (2), global_usage (1). Remove .envrc from tracking.
* build: switch typecheck action to mrcjkb/lua-typecheck-action
Problem: oil.nvim used stevearc/nvim-typecheck-action, which required
cloning the action repo locally for the Makefile lint target. All
other plugins in the collection use mrcjkb/lua-typecheck-action.
Solution: swap to mrcjkb/lua-typecheck-action@v0 for consistency.
Remove the nvim-typecheck-action git clone from the Makefile and
.gitignore. Drop LuaLS from the local lint target since it requires
a full language server install — CI handles it.
Problem: oil.nvim had no luarocks rockspec, so users of rocks.nvim
and similar tools could not install it from the registry. The stylua
CI action was also pinned to an older version.
Solution: add scm-1 rockspec and a luarocks publish workflow that
gates on tests passing before publishing on version tags. Bump
stylua action from v2.0.2 to v2.1.0.
Closes: barrettruth/oil.nvim#14
* feat: support vim.g.oil declarative configuration
Problem: oil.nvim requires an imperative require("oil").setup(opts)
call to initialize. The Neovim ecosystem is moving toward vim.g.plugin
as a declarative config source that works without explicit setup calls.
Solution: fall back to vim.g.oil in config.setup() when no opts are
passed, and add plugin/oil.lua to auto-initialize when vim.g.oil is
set. Explicit setup(opts) calls still take precedence. Update docs
and add tests for the new resolution order.
Closes: barrettruth/oil.nvim#1
* doc: minor phrasing "improvements"
* fix(doc): restore Q/A format in FAQ and close lua block