feat: experimental support for git operations (#290)
This commit is contained in:
parent
354c53080a
commit
1f05774e1c
5 changed files with 184 additions and 1 deletions
13
README.md
13
README.md
|
|
@ -226,6 +226,19 @@ require("oil").setup({
|
||||||
{ "name", "asc" },
|
{ "name", "asc" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
-- EXPERIMENTAL support for performing file operations with git
|
||||||
|
git = {
|
||||||
|
-- Return true to automatically git add/mv/rm files
|
||||||
|
add = function(path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
mv = function(src_path, dest_path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
rm = function(path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
},
|
||||||
-- Configuration for the floating window in oil.open_float
|
-- Configuration for the floating window in oil.open_float
|
||||||
float = {
|
float = {
|
||||||
-- Padding around the floating window
|
-- Padding around the floating window
|
||||||
|
|
|
||||||
13
doc/oil.txt
13
doc/oil.txt
|
|
@ -117,6 +117,19 @@ CONFIG *oil-confi
|
||||||
{ "name", "asc" },
|
{ "name", "asc" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
-- EXPERIMENTAL support for performing file operations with git
|
||||||
|
git = {
|
||||||
|
-- Return true to automatically git add/mv/rm files
|
||||||
|
add = function(path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
mv = function(src_path, dest_path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
rm = function(path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
},
|
||||||
-- Configuration for the floating window in oil.open_float
|
-- Configuration for the floating window in oil.open_float
|
||||||
float = {
|
float = {
|
||||||
-- Padding around the floating window
|
-- Padding around the floating window
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ local columns = require("oil.columns")
|
||||||
local config = require("oil.config")
|
local config = require("oil.config")
|
||||||
local constants = require("oil.constants")
|
local constants = require("oil.constants")
|
||||||
local fs = require("oil.fs")
|
local fs = require("oil.fs")
|
||||||
|
local git = require("oil.git")
|
||||||
local permissions = require("oil.adapters.files.permissions")
|
local permissions = require("oil.adapters.files.permissions")
|
||||||
local trash = require("oil.adapters.files.trash")
|
local trash = require("oil.adapters.files.trash")
|
||||||
local util = require("oil.util")
|
local util = require("oil.util")
|
||||||
|
|
@ -476,6 +477,18 @@ M.perform_action = function(action, cb)
|
||||||
local _, path = util.parse_url(action.url)
|
local _, path = util.parse_url(action.url)
|
||||||
assert(path)
|
assert(path)
|
||||||
path = fs.posix_to_os_path(path)
|
path = fs.posix_to_os_path(path)
|
||||||
|
|
||||||
|
if config.git.add(path) then
|
||||||
|
local old_cb = cb
|
||||||
|
cb = vim.schedule_wrap(function(err)
|
||||||
|
if not err then
|
||||||
|
git.add(path, old_cb)
|
||||||
|
else
|
||||||
|
old_cb(err)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
if action.entry_type == "directory" then
|
if action.entry_type == "directory" then
|
||||||
uv.fs_mkdir(path, 493, function(err)
|
uv.fs_mkdir(path, 493, function(err)
|
||||||
-- Ignore if the directory already exists
|
-- Ignore if the directory already exists
|
||||||
|
|
@ -503,6 +516,18 @@ M.perform_action = function(action, cb)
|
||||||
local _, path = util.parse_url(action.url)
|
local _, path = util.parse_url(action.url)
|
||||||
assert(path)
|
assert(path)
|
||||||
path = fs.posix_to_os_path(path)
|
path = fs.posix_to_os_path(path)
|
||||||
|
|
||||||
|
if config.git.rm(path) then
|
||||||
|
local old_cb = cb
|
||||||
|
cb = function(err)
|
||||||
|
if not err then
|
||||||
|
git.rm(path, old_cb)
|
||||||
|
else
|
||||||
|
old_cb(err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if config.delete_to_trash then
|
if config.delete_to_trash then
|
||||||
if config.trash_command then
|
if config.trash_command then
|
||||||
vim.notify_once(
|
vim.notify_once(
|
||||||
|
|
@ -525,7 +550,11 @@ M.perform_action = function(action, cb)
|
||||||
assert(dest_path)
|
assert(dest_path)
|
||||||
src_path = fs.posix_to_os_path(src_path)
|
src_path = fs.posix_to_os_path(src_path)
|
||||||
dest_path = fs.posix_to_os_path(dest_path)
|
dest_path = fs.posix_to_os_path(dest_path)
|
||||||
|
if config.git.mv(src_path, dest_path) then
|
||||||
|
git.mv(action.entry_type, src_path, dest_path, cb)
|
||||||
|
else
|
||||||
fs.recursive_move(action.entry_type, src_path, dest_path, cb)
|
fs.recursive_move(action.entry_type, src_path, dest_path, cb)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- We should never hit this because we don't implement supported_cross_adapter_actions
|
-- We should never hit this because we don't implement supported_cross_adapter_actions
|
||||||
cb("files adapter doesn't support cross-adapter move")
|
cb("files adapter doesn't support cross-adapter move")
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,19 @@ local default_config = {
|
||||||
{ "name", "asc" },
|
{ "name", "asc" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
-- EXPERIMENTAL support for performing file operations with git
|
||||||
|
git = {
|
||||||
|
-- Return true to automatically git add/mv/rm files
|
||||||
|
add = function(path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
mv = function(src_path, dest_path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
rm = function(path)
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
},
|
||||||
-- Configuration for the floating window in oil.open_float
|
-- Configuration for the floating window in oil.open_float
|
||||||
float = {
|
float = {
|
||||||
-- Padding around the floating window
|
-- Padding around the floating window
|
||||||
|
|
|
||||||
115
lua/oil/git.lua
Normal file
115
lua/oil/git.lua
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
-- integration with git operations
|
||||||
|
local fs = require("oil.fs")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
---@param path string
|
||||||
|
---@return string|nil
|
||||||
|
M.get_root = function(path)
|
||||||
|
local git_dir = vim.fs.find(".git", { upward = true, path = path })[1]
|
||||||
|
if git_dir then
|
||||||
|
return vim.fs.dirname(git_dir)
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param path string
|
||||||
|
---@param cb fun(err: nil|string)
|
||||||
|
M.add = function(path, cb)
|
||||||
|
local root = M.get_root(path)
|
||||||
|
if not root then
|
||||||
|
return cb()
|
||||||
|
end
|
||||||
|
|
||||||
|
local stderr = ""
|
||||||
|
local jid = vim.fn.jobstart({ "git", "add", path }, {
|
||||||
|
cwd = root,
|
||||||
|
stderr_buffered = true,
|
||||||
|
on_stderr = function(_, data)
|
||||||
|
stderr = table.concat(data, "\n")
|
||||||
|
end,
|
||||||
|
on_exit = function(_, code)
|
||||||
|
if code ~= 0 then
|
||||||
|
cb("Error in git add: " .. stderr)
|
||||||
|
else
|
||||||
|
cb()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
if jid <= 0 then
|
||||||
|
cb()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param path string
|
||||||
|
---@param cb fun(err: nil|string)
|
||||||
|
M.rm = function(path, cb)
|
||||||
|
local root = M.get_root(path)
|
||||||
|
if not root then
|
||||||
|
return cb()
|
||||||
|
end
|
||||||
|
|
||||||
|
local stderr = ""
|
||||||
|
local jid = vim.fn.jobstart({ "git", "rm", "-r", path }, {
|
||||||
|
cwd = root,
|
||||||
|
stderr_buffered = true,
|
||||||
|
on_stderr = function(_, data)
|
||||||
|
stderr = table.concat(data, "\n")
|
||||||
|
end,
|
||||||
|
on_exit = function(_, code)
|
||||||
|
if code ~= 0 then
|
||||||
|
stderr = vim.trim(stderr)
|
||||||
|
if stderr:match("^fatal: pathspec '.*' did not match any files$") then
|
||||||
|
cb()
|
||||||
|
else
|
||||||
|
cb("Error in git rm: " .. stderr)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cb()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
if jid <= 0 then
|
||||||
|
cb()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param entry_type oil.EntryType
|
||||||
|
---@param src_path string
|
||||||
|
---@param dest_path string
|
||||||
|
---@param cb fun(err: nil|string)
|
||||||
|
M.mv = function(entry_type, src_path, dest_path, cb)
|
||||||
|
local src_git = M.get_root(src_path)
|
||||||
|
if not src_git or src_git ~= M.get_root(dest_path) then
|
||||||
|
fs.recursive_move(entry_type, src_path, dest_path, cb)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local stderr = ""
|
||||||
|
local jid = vim.fn.jobstart({ "git", "mv", src_path, dest_path }, {
|
||||||
|
cwd = src_git,
|
||||||
|
stderr_buffered = true,
|
||||||
|
on_stderr = function(_, data)
|
||||||
|
stderr = table.concat(data, "\n")
|
||||||
|
end,
|
||||||
|
on_exit = function(_, code)
|
||||||
|
if code ~= 0 then
|
||||||
|
stderr = vim.trim(stderr)
|
||||||
|
if stderr:match("^fatal: not under version control") then
|
||||||
|
fs.recursive_move(entry_type, src_path, dest_path, cb)
|
||||||
|
else
|
||||||
|
cb("Error in git mv: " .. stderr)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cb()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
if jid <= 0 then
|
||||||
|
-- Failed to run git, fall back to normal filesystem operations
|
||||||
|
fs.recursive_move(entry_type, src_path, dest_path, cb)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
Loading…
Add table
Add a link
Reference in a new issue