@@ -49,7 +49,6 @@ local GIT_COMMANDS = {
4949 w = { type = ' boolean' , description = ' Ignore whitespace' },
5050 show_email = { type = ' boolean' , description = ' Show email' },
5151 date = { type = ' string' , description = ' Date format' },
52- pretty = { type = ' string' , description = ' Pretty format' },
5352
5453 lens = { type = ' boolean' , description = ' Lens mode' },
5554 screen = { type = ' boolean' , description = ' Screen mode (default)' },
@@ -59,226 +58,8 @@ local GIT_COMMANDS = {
5958
6059GitPorcelain ._commands = GIT_COMMANDS
6160
62- function GitPorcelain :get_commands ()
63- return self ._commands
64- end
65-
6661function GitPorcelain :get_command (command_name )
6762 return self ._commands [command_name ]
6863end
6964
70- function GitPorcelain :parse_args (args )
71- if not args or # args == 0 then
72- return {
73- command = nil ,
74- arguments = {},
75- options = {},
76- files = {},
77- commits = {},
78- }
79- end
80-
81- local result = {
82- command = args [1 ],
83- arguments = {},
84- options = {},
85- files = {},
86- commits = {},
87- }
88-
89- local i = 2
90- while i <= # args do
91- local arg = args [i ]
92-
93- -- Handle options
94- if arg :match (' ^%-%-' ) then
95- local option_name , option_value = arg :match (' ^%-%-([^=]+)=?(.*)$' )
96- local option_def = self ._commands [result .command ] and self ._commands [result .command ].options [option_name ]
97-
98- if option_def then
99- if option_def .type == ' boolean' then
100- result .options [option_name ] = true
101- elseif option_def .type == ' string' or option_def .type == ' number' then
102- -- Check if value is provided with = syntax
103- if option_value and option_value ~= ' ' then
104- if option_def .type == ' number' then
105- result .options [option_name ] = tonumber (option_value ) or 0
106- else
107- result .options [option_name ] = option_value
108- end
109- elseif option_def .optional_value and option_def .default_when_present ~= nil then
110- -- Handle --option without value (use default)
111- result .options [option_name ] = option_def .default_when_present
112- else
113- -- Handle --option with separate value
114- i = i + 1
115- if i <= # args then
116- if option_def .type == ' number' then
117- result .options [option_name ] = tonumber (args [i ]) or 0
118- else
119- result .options [option_name ] = args [i ]
120- end
121- end
122- end
123- end
124- end
125- elseif arg :match (' ^%-' ) then
126- local short_opts = arg :sub (2 )
127- for j = 1 , # short_opts do
128- local opt = short_opts :sub (j , j )
129- result .options [opt ] = true
130- end
131- elseif arg :match (' ^[a-f0-9]{7,40}$' ) or arg :match (' ^HEAD$' ) or arg :match (' ^[A-Za-z0-9/_-]+$' ) then
132- result .commits [# result .commits + 1 ] = arg
133- else
134- result .files [# result .files + 1 ] = arg
135- end
136-
137- i = i + 1
138- end
139-
140- return result
141- end
142-
143- function GitPorcelain :validate (parsed )
144- if not parsed .command then return true , nil end
145-
146- local command_def = self ._commands [parsed .command ]
147- if not command_def then return false , string.format (' Unknown command: %s' , parsed .command ) end
148-
149- for option_name , value in pairs (parsed .options ) do
150- local option_def = command_def .options [option_name ]
151- if not option_def then return false , string.format (' Unknown option: --%s' , option_name ) end
152-
153- if option_def .type == ' number' and type (value ) ~= ' number' then
154- return false , string.format (' Option --%s requires a number' , option_name )
155- end
156- end
157-
158- if parsed .command == ' diff' then
159- return self :_validate_diff_options (parsed )
160- elseif parsed .command == ' blame' then
161- return self :_validate_blame_options (parsed )
162- end
163-
164- return true , nil
165- end
166-
167- function GitPorcelain :_validate_diff_options (parsed )
168- if parsed .options .split and parsed .options .unified_view then
169- return false , ' Cannot use both --split and --unified options'
170- end
171-
172- if parsed .options .lens and parsed .options .screen then return false , ' Cannot use both --lens and --screen options' end
173-
174- return true , nil
175- end
176-
177- function GitPorcelain :_validate_blame_options (parsed )
178- if parsed .options .lens and parsed .options .screen then return false , ' Cannot use both --lens and --screen options' end
179-
180- if parsed .options .line then
181- if type (parsed .options .line ) ~= ' number' or parsed .options .line < 1 then
182- return false , ' Line number must be a positive integer'
183- end
184- end
185-
186- return true , nil
187- end
188-
189- function GitPorcelain :get_display_mode (parsed )
190- if parsed .options .lens then return ' lens' end
191- if parsed .options .screen then return ' screen' end
192- return ' screen'
193- end
194-
195- function GitPorcelain :get_layout_type (parsed )
196- if parsed .options .split then return ' split' end
197- if parsed .options .unified_view then return ' unified' end
198- end
199-
200- function GitPorcelain :get_git_diff_options (parsed )
201- local git_opts = {}
202-
203- if parsed .options .cached or parsed .options .staged then git_opts [# git_opts + 1 ] = ' --cached' end
204-
205- if parsed .options .unified then git_opts [# git_opts + 1 ] = ' --unified=' .. parsed .options .unified end
206-
207- if parsed .options .no_unified then git_opts [# git_opts + 1 ] = ' --unified=0' end
208-
209- if parsed .options .raw then git_opts [# git_opts + 1 ] = ' --raw' end
210-
211- if parsed .options .patch_with_raw then git_opts [# git_opts + 1 ] = ' --patch-with-raw' end
212-
213- if parsed .options .patch_with_stat then git_opts [# git_opts + 1 ] = ' --patch-with-stat' end
214-
215- if parsed .options .name_only then git_opts [# git_opts + 1 ] = ' --name-only' end
216-
217- if parsed .options .name_status then git_opts [# git_opts + 1 ] = ' --name-status' end
218-
219- if parsed .options .stat then git_opts [# git_opts + 1 ] = ' --stat' end
220-
221- if parsed .options .numstat then git_opts [# git_opts + 1 ] = ' --numstat' end
222-
223- if parsed .options .shortstat then git_opts [# git_opts + 1 ] = ' --shortstat' end
224-
225- if parsed .options .summary then git_opts [# git_opts + 1 ] = ' --summary' end
226-
227- return git_opts
228- end
229-
230- function GitPorcelain :get_git_blame_options (parsed )
231- local git_opts = {}
232-
233- if parsed .options .line then
234- git_opts [# git_opts + 1 ] = ' -L'
235- git_opts [# git_opts + 1 ] = string.format (' %d,+1' , parsed .options .line )
236- end
237-
238- if parsed .options .C then git_opts [# git_opts + 1 ] = ' -C' end
239-
240- if parsed .options .M then git_opts [# git_opts + 1 ] = ' -M' end
241-
242- if parsed .options .w then git_opts [# git_opts + 1 ] = ' -w' end
243-
244- if parsed .options .show_email then git_opts [# git_opts + 1 ] = ' --show-email' end
245-
246- if parsed .options .date then git_opts [# git_opts + 1 ] = ' --date=' .. parsed .options .date end
247-
248- if parsed .options .pretty then git_opts [# git_opts + 1 ] = ' --pretty=' .. parsed .options .pretty end
249-
250- return git_opts
251- end
252-
253- function GitPorcelain :get_help (command_name )
254- local command_def = self ._commands [command_name ]
255- if not command_def then return nil end
256-
257- local help = {
258- string.format (' vgit %s - %s' , command_name , command_def .description ),
259- ' ' ,
260- ' Options:' ,
261- }
262-
263- for option_name , option_def in pairs (command_def .options ) do
264- local type_str = option_def .type == ' boolean' and ' ' or (' =' .. option_def .type :upper ())
265- help [# help + 1 ] = string.format (' --%s%s %s' , option_name , type_str , option_def .description )
266- end
267-
268- return table.concat (help , ' \n ' )
269- end
270-
271- function GitPorcelain :get_all_help ()
272- local help = { ' VGit - Git porcelain interface for Neovim' , ' ' , ' Available commands:' , ' ' }
273-
274- for command_name , command_def in pairs (self ._commands ) do
275- help [# help + 1 ] = string.format (' %s %s' , command_name , command_def .description )
276- end
277-
278- help [# help + 1 ] = ' '
279- help [# help + 1 ] = ' Use "vgit <command> --help" for detailed help on a specific command.'
280-
281- return table.concat (help , ' \n ' )
282- end
283-
28465return GitPorcelain
0 commit comments