build: replace luacheck with selene, add nix devshell and pre-commit (#20)
* 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.
This commit is contained in:
parent
df53b172a9
commit
86f553cd0a
72 changed files with 2762 additions and 2649 deletions
|
|
@ -1,6 +1,6 @@
|
|||
local config = require("oil.config")
|
||||
local constants = require("oil.constants")
|
||||
local util = require("oil.util")
|
||||
local config = require('oil.config')
|
||||
local constants = require('oil.constants')
|
||||
local util = require('oil.util')
|
||||
local M = {}
|
||||
|
||||
local FIELD_NAME = constants.FIELD_NAME
|
||||
|
|
@ -38,7 +38,7 @@ end
|
|||
---@return oil.ColumnSpec[]
|
||||
M.get_supported_columns = function(adapter_or_scheme)
|
||||
local adapter
|
||||
if type(adapter_or_scheme) == "string" then
|
||||
if type(adapter_or_scheme) == 'string' then
|
||||
adapter = config.get_adapter_by_scheme(adapter_or_scheme)
|
||||
else
|
||||
adapter = adapter_or_scheme
|
||||
|
|
@ -53,7 +53,7 @@ M.get_supported_columns = function(adapter_or_scheme)
|
|||
return ret
|
||||
end
|
||||
|
||||
local EMPTY = { "-", "OilEmpty" }
|
||||
local EMPTY = { '-', 'OilEmpty' }
|
||||
|
||||
M.EMPTY = EMPTY
|
||||
|
||||
|
|
@ -71,17 +71,17 @@ M.render_col = function(adapter, col_def, entry, bufnr)
|
|||
end
|
||||
|
||||
local chunk = column.render(entry, conf, bufnr)
|
||||
if type(chunk) == "table" then
|
||||
if chunk[1]:match("^%s*$") then
|
||||
if type(chunk) == 'table' then
|
||||
if chunk[1]:match('^%s*$') then
|
||||
return EMPTY
|
||||
end
|
||||
else
|
||||
if not chunk or chunk:match("^%s*$") then
|
||||
if not chunk or chunk:match('^%s*$') then
|
||||
return EMPTY
|
||||
end
|
||||
if conf and conf.highlight then
|
||||
local highlight = conf.highlight
|
||||
if type(highlight) == "function" then
|
||||
if type(highlight) == 'function' then
|
||||
highlight = conf.highlight(chunk)
|
||||
end
|
||||
return { chunk, highlight }
|
||||
|
|
@ -98,13 +98,13 @@ end
|
|||
M.parse_col = function(adapter, line, col_def)
|
||||
local name, conf = util.split_config(col_def)
|
||||
-- If rendering failed, there will just be a "-"
|
||||
local empty_col, rem = line:match("^%s*(-%s+)(.*)$")
|
||||
local empty_col, rem = line:match('^%s*(-%s+)(.*)$')
|
||||
if empty_col then
|
||||
return nil, rem
|
||||
end
|
||||
local column = M.get_column(adapter, name)
|
||||
if column then
|
||||
return column.parse(line:gsub("^%s+", ""), conf)
|
||||
return column.parse(line:gsub('^%s+', ''), conf)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -128,12 +128,12 @@ end
|
|||
M.render_change_action = function(adapter, action)
|
||||
local column = M.get_column(adapter, action.column)
|
||||
if not column then
|
||||
error(string.format("Received change action for nonexistant column %s", action.column))
|
||||
error(string.format('Received change action for nonexistant column %s', action.column))
|
||||
end
|
||||
if column.render_action then
|
||||
return column.render_action(action)
|
||||
else
|
||||
return string.format("CHANGE %s %s = %s", action.url, action.column, action.value)
|
||||
return string.format('CHANGE %s %s = %s', action.url, action.column, action.value)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ M.perform_change_action = function(adapter, action, callback)
|
|||
local column = M.get_column(adapter, action.column)
|
||||
if not column then
|
||||
return callback(
|
||||
string.format("Received change action for nonexistant column %s", action.column)
|
||||
string.format('Received change action for nonexistant column %s', action.column)
|
||||
)
|
||||
end
|
||||
column.perform_action(action, callback)
|
||||
|
|
@ -152,12 +152,12 @@ end
|
|||
|
||||
local icon_provider = util.get_icon_provider()
|
||||
if icon_provider then
|
||||
M.register("icon", {
|
||||
M.register('icon', {
|
||||
render = function(entry, conf, bufnr)
|
||||
local field_type = entry[FIELD_TYPE]
|
||||
local name = entry[FIELD_NAME]
|
||||
local meta = entry[FIELD_META]
|
||||
if field_type == "link" and meta then
|
||||
if field_type == 'link' and meta then
|
||||
if meta.link then
|
||||
name = meta.link
|
||||
end
|
||||
|
|
@ -170,11 +170,11 @@ if icon_provider then
|
|||
end
|
||||
|
||||
local ft = nil
|
||||
if conf and conf.use_slow_filetype_detection and field_type == "file" then
|
||||
if conf and conf.use_slow_filetype_detection and field_type == 'file' then
|
||||
local bufname = vim.api.nvim_buf_get_name(bufnr)
|
||||
local _, path = util.parse_url(bufname)
|
||||
if path then
|
||||
local lines = vim.fn.readfile(path .. name, "", 16)
|
||||
local lines = vim.fn.readfile(path .. name, '', 16)
|
||||
if lines and #lines > 0 then
|
||||
ft = vim.filetype.match({ filename = name, contents = lines })
|
||||
end
|
||||
|
|
@ -183,10 +183,10 @@ if icon_provider then
|
|||
|
||||
local icon, hl = icon_provider(field_type, name, conf, ft)
|
||||
if not conf or conf.add_padding ~= false then
|
||||
icon = icon .. " "
|
||||
icon = icon .. ' '
|
||||
end
|
||||
if conf and conf.highlight then
|
||||
if type(conf.highlight) == "function" then
|
||||
if type(conf.highlight) == 'function' then
|
||||
hl = conf.highlight(icon)
|
||||
else
|
||||
hl = conf.highlight
|
||||
|
|
@ -196,29 +196,29 @@ if icon_provider then
|
|||
end,
|
||||
|
||||
parse = function(line, conf)
|
||||
return line:match("^(%S+)%s+(.*)$")
|
||||
return line:match('^(%S+)%s+(.*)$')
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local default_type_icons = {
|
||||
directory = "dir",
|
||||
socket = "sock",
|
||||
directory = 'dir',
|
||||
socket = 'sock',
|
||||
}
|
||||
---@param entry oil.InternalEntry
|
||||
---@return boolean
|
||||
local function is_entry_directory(entry)
|
||||
local type = entry[FIELD_TYPE]
|
||||
if type == "directory" then
|
||||
if type == 'directory' then
|
||||
return true
|
||||
elseif type == "link" then
|
||||
elseif type == 'link' then
|
||||
local meta = entry[FIELD_META]
|
||||
return (meta and meta.link_stat and meta.link_stat.type == "directory") == true
|
||||
return (meta and meta.link_stat and meta.link_stat.type == 'directory') == true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
M.register("type", {
|
||||
M.register('type', {
|
||||
render = function(entry, conf)
|
||||
local entry_type = entry[FIELD_TYPE]
|
||||
if conf and conf.icons then
|
||||
|
|
@ -229,7 +229,7 @@ M.register("type", {
|
|||
end,
|
||||
|
||||
parse = function(line, conf)
|
||||
return line:match("^(%S+)%s+(.*)$")
|
||||
return line:match('^(%S+)%s+(.*)$')
|
||||
end,
|
||||
|
||||
get_sort_value = function(entry)
|
||||
|
|
@ -242,22 +242,22 @@ M.register("type", {
|
|||
})
|
||||
|
||||
local function adjust_number(int)
|
||||
return string.format("%03d%s", #int, int)
|
||||
return string.format('%03d%s', #int, int)
|
||||
end
|
||||
|
||||
M.register("name", {
|
||||
M.register('name', {
|
||||
render = function(entry, conf)
|
||||
error("Do not use the name column. It is for sorting only")
|
||||
error('Do not use the name column. It is for sorting only')
|
||||
end,
|
||||
|
||||
parse = function(line, conf)
|
||||
error("Do not use the name column. It is for sorting only")
|
||||
error('Do not use the name column. It is for sorting only')
|
||||
end,
|
||||
|
||||
create_sort_value_factory = function(num_entries)
|
||||
if
|
||||
config.view_options.natural_order == false
|
||||
or (config.view_options.natural_order == "fast" and num_entries > 5000)
|
||||
or (config.view_options.natural_order == 'fast' and num_entries > 5000)
|
||||
then
|
||||
if config.view_options.case_insensitive then
|
||||
return function(entry)
|
||||
|
|
@ -272,7 +272,7 @@ M.register("name", {
|
|||
local memo = {}
|
||||
return function(entry)
|
||||
if memo[entry] == nil then
|
||||
local name = entry[FIELD_NAME]:gsub("0*(%d+)", adjust_number)
|
||||
local name = entry[FIELD_NAME]:gsub('0*(%d+)', adjust_number)
|
||||
if config.view_options.case_insensitive then
|
||||
name = name:lower()
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue