+1
.gitignore
+1
.gitignore
···
···
1
+
.mise.local.toml
+21
LICENSE
+21
LICENSE
···
···
1
+
MIT License
2
+
3
+
Copyright (c) 2024 ejrichards
4
+
5
+
Permission is hereby granted, free of charge, to any person obtaining a copy
6
+
of this software and associated documentation files (the "Software"), to deal
7
+
in the Software without restriction, including without limitation the rights
8
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+
copies of the Software, and to permit persons to whom the Software is
10
+
furnished to do so, subject to the following conditions:
11
+
12
+
The above copyright notice and this permission notice shall be included in all
13
+
copies or substantial portions of the Software.
14
+
15
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+
SOFTWARE.
+50
README.md
+50
README.md
···
···
1
+
# Baredot
2
+
3
+
This is a Neovim plugin to automatically adjust `git` env vars when syncing dotfiles using the "bare git repo" method:
4
+
5
+
[Dotfiles: Best way to store in a bare git repository](https://www.atlassian.com/git/tutorials/dotfiles)
6
+
7
+
## Details
8
+
9
+
When launching and when changing directory (eg. `:cd`), the plugin will detect if the current
10
+
directory is in a git repo by searching for a `.git` folder.
11
+
12
+
- If a `.git` folder is found, the env vars are cleared and `git` will work as normal.
13
+
- If a `.git` folder is not found, and we are in `$HOME`, the env vars will be adjusted to use the
14
+
bare git repo. This will let other git plugins function using that repo.
15
+
16
+
## Setup
17
+
18
+
lazy.nvim
19
+
```lua
20
+
{
21
+
"ejrichards/baredot.nvim",
22
+
opts = {
23
+
git_dir = "~/.cfg" -- Change this path
24
+
}
25
+
}
26
+
```
27
+
28
+
## Configuration
29
+
30
+
```lua
31
+
{
32
+
-- These two options set the GIT_DIR and GIT_WORK_TREE env vars
33
+
-- They are expanded using "vim.fn.expand"
34
+
git_dir = "~/.cfg",
35
+
git_work_tree = "~",
36
+
-- Filename pattern to find that will disable Baredot
37
+
disable_pattern = "%.git"
38
+
}
39
+
```
40
+
41
+
## Commands
42
+
43
+
- `:BaredotInfo` - Print current status
44
+
- `:BaredotToggle` - Manually toggle the env vars on / off
45
+
46
+
## Functions
47
+
48
+
- `require("baredot").info()` - Print current status
49
+
- `require("baredot").toggle()` - Manually toggle the env vars on / off
50
+
- `require("baredot").set(boolean)` - Set the env vars on / off
+44
lua/baredot/commands.lua
+44
lua/baredot/commands.lua
···
···
1
+
local Commands = {}
2
+
3
+
---@type BaredotConfig
4
+
local options
5
+
6
+
function Commands.set(enable)
7
+
if enable then
8
+
vim.env.GIT_WORK_TREE = options.git_work_tree
9
+
vim.env.GIT_DIR = options.git_dir
10
+
else
11
+
vim.env.GIT_WORK_TREE = nil
12
+
vim.env.GIT_DIR = nil
13
+
end
14
+
end
15
+
16
+
function Commands.toggle()
17
+
if vim.env.GIT_DIR == nil or vim.env.GIT_WORK_TREE == nil then
18
+
Commands.set(true)
19
+
else
20
+
Commands.set(false)
21
+
end
22
+
Commands.info()
23
+
end
24
+
25
+
function Commands.info()
26
+
if vim.env.GIT_DIR == nil or vim.env.GIT_WORK_TREE == nil then
27
+
vim.notify("Baredot mode off", vim.log.levels.INFO, { title = "baredot.nvim" });
28
+
else
29
+
vim.notify(
30
+
"Baredot mode on: GIT_DIR=" .. vim.env.GIT_DIR .. " GIT_WORK_TREE=" .. vim.env.GIT_WORK_TREE,
31
+
vim.log.levels.INFO,
32
+
{ title = "baredot.nvim" }
33
+
);
34
+
end
35
+
end
36
+
37
+
function Commands.setup(opt)
38
+
options = opt
39
+
40
+
vim.api.nvim_create_user_command("BaredotInfo", Commands.info, { desc = "BaredotInfo" })
41
+
vim.api.nvim_create_user_command("BaredotToggle", Commands.toggle, { desc = "BaredotToggle" })
42
+
end
43
+
44
+
return Commands
+51
lua/baredot/init.lua
+51
lua/baredot/init.lua
···
···
1
+
local commands = require("baredot.commands")
2
+
local scan = require("baredot.scan")
3
+
4
+
local Baredot = {}
5
+
6
+
---@class BaredotConfig
7
+
local defaults = {
8
+
git_dir = "~/.cfg",
9
+
git_work_tree = "~",
10
+
disable_pattern = "%.git"
11
+
}
12
+
13
+
---@param opt? BaredotConfig
14
+
function Baredot.setup(opt)
15
+
---@type BaredotConfig
16
+
local options = vim.tbl_deep_extend("force", {}, defaults, opt or {})
17
+
18
+
options.git_dir = vim.fn.expand(options.git_dir)
19
+
options.git_work_tree = vim.fn.expand(options.git_work_tree)
20
+
21
+
commands.setup(options)
22
+
scan.setup(options)
23
+
24
+
if scan.in_work_tree_no_dot_git() then
25
+
commands.set(true)
26
+
end
27
+
28
+
local group = vim.api.nvim_create_augroup("baredot", { clear = true })
29
+
vim.api.nvim_create_autocmd("DirChanged", {
30
+
group = group,
31
+
desc = "Baredot: scan for .git",
32
+
callback = function()
33
+
if vim.v.event.scope == "global" then
34
+
commands.set(scan.in_work_tree_no_dot_git())
35
+
end
36
+
end,
37
+
})
38
+
end
39
+
40
+
function Baredot.info()
41
+
return commands.info()
42
+
end
43
+
---@param enable boolean
44
+
function Baredot.set(enable)
45
+
return commands.set(enable)
46
+
end
47
+
function Baredot.toggle()
48
+
return commands.toggle()
49
+
end
50
+
51
+
return Baredot
+72
lua/baredot/scan.lua
+72
lua/baredot/scan.lua
···
···
1
+
local Scan = {}
2
+
3
+
---@type BaredotConfig
4
+
local options
5
+
6
+
-- Modified from ahmedkhalf/project.nvim
7
+
local function get_parent(path)
8
+
path = path:match("^(.*)/")
9
+
if path == "" then
10
+
path = "/"
11
+
end
12
+
return path
13
+
end
14
+
15
+
local function get_files(file_dir)
16
+
local files = {}
17
+
local dir = vim.loop.fs_scandir(file_dir)
18
+
if dir == nil then
19
+
return files
20
+
end
21
+
22
+
while true do
23
+
local file = vim.loop.fs_scandir_next(dir)
24
+
if file == nil then
25
+
return files
26
+
end
27
+
28
+
table.insert(files, file)
29
+
end
30
+
end
31
+
32
+
local function has(dir, pattern)
33
+
for _, file in ipairs(get_files(dir)) do
34
+
if file:match(pattern) ~= nil then
35
+
return true
36
+
end
37
+
end
38
+
return false
39
+
end
40
+
41
+
function Scan.in_work_tree_no_dot_git()
42
+
local search_dir = vim.fn.getcwd()
43
+
local work_tree_root = options.git_work_tree
44
+
if vim.fn.has("win32") > 0 then
45
+
search_dir = search_dir:gsub("\\", "/")
46
+
work_tree_root = work_tree_root:gsub("\\", "/")
47
+
end
48
+
49
+
while true do
50
+
if search_dir == work_tree_root then
51
+
return true
52
+
end
53
+
54
+
local pattern = options.disable_pattern
55
+
if has(search_dir, pattern) then
56
+
return false
57
+
end
58
+
59
+
local parent = get_parent(search_dir)
60
+
if parent == nil or parent == search_dir then
61
+
return false
62
+
end
63
+
64
+
search_dir = parent
65
+
end
66
+
end
67
+
68
+
function Scan.setup(opt)
69
+
options = opt
70
+
end
71
+
72
+
return Scan