1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
return {
{
"moyiz/git-dev.nvim",
event = "VeryLazy",
opts = {},
config = function()
require("git-dev").setup()
local function copy_git_repo_url()
-- Get the Git repository root
local git_root = vim.fn.system("git rev-parse --show-toplevel"):gsub("\n", "")
if git_root == "" then
vim.notify("Not inside a Git repository", vim.log.levels.WARN)
return nil
end
-- Get the remote URL
local remote_url = vim.fn.system("git config --get remote.origin.url"):gsub("\n", "")
if remote_url == "" then
vim.notify("No remote URL found", vim.log.levels.WARN)
return nil
end
-- Convert SSH URL to HTTPS if needed
if remote_url:match("^git@") then
remote_url = remote_url:gsub("git@", "https://"):gsub(":", "/")
end
-- Remove `.git` from the remote URL
remote_url = remote_url:gsub("%.git$", "")
-- Get the relative path of the current file
local file_path = vim.fn.expand("%:~:.")
if file_path == "" then
vim.notify("No file currently open", vim.log.levels.WARN)
return nil
end
-- Get the relative path to the repository root
local relative_path =
vim.fn.system("git ls-files --full-name " .. vim.fn.shellescape(file_path)):gsub("\n", "")
-- Combine the remote URL with the relative file path
local full_url = remote_url .. "/" .. relative_path
-- Copy to clipboard
vim.fn.setreg("+", full_url)
vim.notify("Copied to clipboard: " .. full_url, vim.log.levels.INFO)
return full_url
end
-- Keybinding to copy the Git repository URL
vim.keymap.set("n", "<leader>cg", function()
copy_git_repo_url()
end, { desc = "Copy git repository URL to clipboard" })
-- Function to open a repository from the clipboard
vim.keymap.set("n", "<leader>eg", function()
local url = vim.fn.getreg("+") -- Get URL from clipboard
if not url or url == "" then
vim.notify("Clipboard is empty. Copy a valid URL first.", vim.log.levels.WARN)
return
end
if url:match("^https://") then
require("git-dev").open(url)
else
vim.notify("Not a valid URL: " .. url, vim.log.levels.ERROR)
end
end, { desc = "Open Git repository from clipboard" })
end,
},
{
"lewis6991/gitsigns.nvim",
opts = {
signs = {
add = { text = "▎" },
change = { text = "▎" },
delete = { text = "" },
topdelete = { text = "" },
changedelete = { text = "▎" },
untracked = { text = "▎" },
},
signs_staged = {
add = { text = "▎" },
change = { text = "▎" },
delete = { text = "" },
topdelete = { text = "" },
changedelete = { text = "▎" },
},
on_attach = function(buffer)
local gs = package.loaded.gitsigns
local function map(mode, l, r, desc)
vim.keymap.set(mode, l, r, { buffer = buffer, desc = desc })
end
-- stylua: ignore start
map("n", "]h", function()
if vim.wo.diff then
vim.cmd.normal({ "]c", bang = true })
else
gs.nav_hunk("next")
end
end, "Next hunk")
map("n", "[h", function()
if vim.wo.diff then
vim.cmd.normal({ "[c", bang = true })
else
gs.nav_hunk("prev")
end
end, "Previous hunk")
map("n", "]H", function() gs.nav_hunk("last") end, "Last hunk")
map("n", "[H", function() gs.nav_hunk("first") end, "First hunk")
map({ "n", "v" }, "<leader>gs", ":Gitsigns stage_hunk<CR>", "Stage hunk")
map({ "n", "v" }, "<leader>gr", ":Gitsigns reset_hunk<CR>", "Reset hunk")
map("n", "<leader>gS", gs.stage_buffer, "Stage buffer")
map("n", "<leader>gu", gs.undo_stage_hunk, "Undo stage hunk")
map("n", "<leader>gR", gs.reset_buffer, "Reset buffer")
map("n", "<leader>gpv", gs.preview_hunk_inline, "Preview hunk inline")
map("n", "<leader>gb", function() gs.blame_line({ full = true }) end, "Blame line")
map("n", "<leader>gB", function() gs.blame() end, "Blame buffer")
map("n", "<leader>gd", gs.diffthis, "Diff this")
map("n", "<leader>gD", function() gs.diffthis("~") end, "Diff this ~")
-- map("n", "<leader>gD", function() gs.diffthis("@") end, "Diff this @")
map({ "o", "x" }, "ih", ":<C-U>Gitsigns select_hunk<CR>", "GitSigns select hunk")
map("n", "<leader>gtb", gs.toggle_current_line_blame, "Toggle line blame")
map("n", "<leader>gtd", gs.toggle_deleted, "Toggle delete")
end,
},
init = function()
local wk = require("which-key")
wk.add({
mode = { "n", "v", "x" },
{ "<leader>g", group = "Git" },
{ "<leader>gt", group = "Toggle" },
})
end,
},
{
"kdheepak/lazygit.nvim",
cmd = {
"LazyGit",
"LazyGitConfig",
"LazyGitCurrentFile",
"LazyGitFilter",
"LazyGitFilterCurrentFile",
},
-- optional for floating window border decoration
dependencies = {
"nvim-lua/plenary.nvim",
},
-- setting the keybinding for LazyGit with 'keys' is recommended in
-- order to load the plugin when the command is run for the first time
keys = {
{ "<leader>gg", "<cmd>LazyGit<cr>", desc = "Lazygit" },
},
},
{
"mbbill/undotree",
config = function()
vim.keymap.set("n", "<leader>gu", vim.cmd.UndotreeToggle, { desc = "Undo tree" })
end,
},
{
"tpope/vim-fugitive",
config = function()
local TheSiahxyz_Fugitive = vim.api.nvim_create_augroup("TheSiahxyz_Fugitive", {})
local autocmd = vim.api.nvim_create_autocmd
autocmd("BufWinEnter", {
group = TheSiahxyz_Fugitive,
pattern = "*",
callback = function()
if vim.bo.ft ~= "fugitive" then
return
end
local bufnr = vim.api.nvim_get_current_buf()
vim.keymap.set("n", "<leader>P", function()
vim.cmd.Git("push")
end, { buffer = bufnr, remap = false, desc = "Git push" })
vim.keymap.set("n", "<leader>p", function()
vim.cmd.Git({ "pull", "--rebase" })
end, { buffer = bufnr, remap = false, desc = "Git pull" })
vim.keymap.set(
"n",
"<leader>o",
":Git push -u origin ",
{ buffer = bufnr, remap = false, desc = "Git push origin" }
)
vim.keymap.set(
"n",
"<leader>h",
":Git push home ",
{ buffer = bufnr, remap = false, desc = "Git push home" }
)
end,
})
autocmd("FileType", {
group = TheSiahxyz_Fugitive,
pattern = "fugitive",
callback = function(event)
vim.bo[event.buf].buflisted = false
vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = event.buf, silent = true })
end,
})
end,
keys = {
{ mode = "n", "<leader>g<leader>", ":Git ", desc = "Git" },
{ mode = "n", "<leader>gf", vim.cmd.Git, desc = "Git fugitive" },
{ mode = "n", "gm", "<cmd>diffget //2<cr>", desc = "Git diff on my side" },
{ mode = "n", "go", "<cmd>diffget //3<cr>", desc = "Git diff on their side" },
},
},
}
|