@@ -8,6 +8,135 @@ local GitTool = {
88 description = " Execute git operations and commands" ,
99}
1010
11+ --- Get the path to the .gitignore file in the current git repo root
12+ local function get_gitignore_path ()
13+ local git_dir = vim .fn .system (" git rev-parse --show-toplevel" ):gsub (" \n " , " " )
14+ if vim .v .shell_error ~= 0 or not git_dir or git_dir == " " then
15+ return nil
16+ end
17+ local sep = package.config :sub (1 , 1 )
18+ return git_dir .. sep .. " .gitignore"
19+ end
20+
21+ --- Read .gitignore content
22+ function GitTool .get_gitignore ()
23+ local path = get_gitignore_path ()
24+ if not path then
25+ return false , " .gitignore not found (not in a git repo)"
26+ end
27+ local stat = vim .uv .fs_stat (path )
28+ if not stat then
29+ return true , " " -- treat as empty if not exists
30+ end
31+ local fd = vim .uv .fs_open (path , " r" , 438 )
32+ if not fd then
33+ return false , " Failed to open .gitignore for reading"
34+ end
35+ local data = vim .uv .fs_read (fd , stat .size , 0 )
36+ vim .uv .fs_close (fd )
37+ return true , data or " "
38+ end
39+
40+ --- Add rule(s) to .gitignore (no duplicates)
41+ function GitTool .add_gitignore_rule (rule )
42+ local path = get_gitignore_path ()
43+ if not path then
44+ return false , " .gitignore not found (not in a git repo)"
45+ end
46+ local rules = type (rule ) == " table" and rule or { rule }
47+ local stat = vim .uv .fs_stat (path )
48+ local lines = {}
49+ if stat then
50+ local fd = vim .uv .fs_open (path , " r" , 438 )
51+ if fd then
52+ local data = vim .uv .fs_read (fd , stat .size , 0 )
53+ vim .uv .fs_close (fd )
54+ if data then
55+ for line in data :gmatch (" ([^\r\n ]+)" ) do
56+ table.insert (lines , line )
57+ end
58+ end
59+ end
60+ end
61+ local set = {}
62+ for _ , l in ipairs (lines ) do set [l ] = true end
63+ local added = {}
64+ for _ , r in ipairs (rules ) do
65+ if not set [r ] then
66+ table.insert (lines , r )
67+ set [r ] = true
68+ table.insert (added , r )
69+ end
70+ end
71+ local fdw = vim .uv .fs_open (path , " w" , 420 )
72+ if not fdw then
73+ return false , " Failed to open .gitignore for writing"
74+ end
75+ vim .uv .fs_write (fdw , table.concat (lines , " \n " ) .. " \n " , 0 )
76+ vim .uv .fs_close (fdw )
77+ if # added == 0 then
78+ return true , " No new rule added (already present)"
79+ end
80+ return true , " Added rule(s): " .. table.concat (added , " , " )
81+ end
82+
83+ --- Remove rule(s) from .gitignore
84+ function GitTool .remove_gitignore_rule (rule )
85+ local path = get_gitignore_path ()
86+ if not path then
87+ return false , " .gitignore not found (not in a git repo)"
88+ end
89+ local rules = type (rule ) == " table" and rule or { rule }
90+ local stat = vim .uv .fs_stat (path )
91+ if not stat then
92+ return false , " .gitignore does not exist"
93+ end
94+ local fd = vim .uv .fs_open (path , " r" , 438 )
95+ if not fd then
96+ return false , " Failed to open .gitignore for reading"
97+ end
98+ local data = vim .uv .fs_read (fd , stat .size , 0 )
99+ vim .uv .fs_close (fd )
100+ if not data then
101+ return false , " Failed to read .gitignore"
102+ end
103+ local lines = {}
104+ local removed = {}
105+ local rule_set = {}
106+ for _ , r in ipairs (rules ) do rule_set [r ] = true end
107+ for line in data :gmatch (" ([^\r\n ]+)" ) do
108+ if rule_set [line ] then
109+ table.insert (removed , line )
110+ else
111+ table.insert (lines , line )
112+ end
113+ end
114+ local fdw = vim .uv .fs_open (path , " w" , 420 )
115+ if not fdw then
116+ return false , " Failed to open .gitignore for writing"
117+ end
118+ vim .uv .fs_write (fdw , table.concat (lines , " \n " ) .. " \n " , 0 )
119+ vim .uv .fs_close (fdw )
120+ if # removed == 0 then
121+ return true , " No rule removed (not present)"
122+ end
123+ return true , " Removed rule(s): " .. table.concat (removed , " , " )
124+ end
125+
126+ --- Check if a file is ignored by .gitignore
127+ function GitTool .is_ignored (file )
128+ if not file or file == " " then
129+ return false , " No file specified"
130+ end
131+ local ok , result = pcall (function ()
132+ return vim .fn .system ({" git" , " check-ignore" , file })
133+ end )
134+ if not ok or vim .v .shell_error ~= 0 then
135+ return false , " File is not ignored or not in a git repo"
136+ end
137+ return true , vim .trim (result )
138+ end
139+
11140--- Check if we're in a git repository
12141--- @return boolean
13142local function is_git_repo ()
0 commit comments