@@ -32,40 +32,112 @@ function Buffer.setup(opts)
3232 Buffer ._setup_gitcommit_keymap (event .buf )
3333
3434 if config .auto_generate then
35- -- Auto-generation triggers once when entering gitcommit window
36- -- Avoids race conditions with plugins like neogit
37- -- Skip auto-generation during git amend to preserve user intent
38- vim .api .nvim_create_autocmd (" WinEnter" , {
35+ -- Auto-generation with stable timing detection for different Git tools
36+ local auto_generate_attempted = false
37+ local pending_timer = nil
38+
39+ local function should_attempt_auto_generate (bufnr )
40+ -- Don't attempt if we already successfully generated for this buffer
41+ if auto_generate_attempted then
42+ return false
43+ end
44+
45+ -- Ensure buffer is valid
46+ if not vim .api .nvim_buf_is_valid (bufnr ) then
47+ return false
48+ end
49+
50+ -- Check if buffer already has commit message
51+ local lines = vim .api .nvim_buf_get_lines (bufnr , 0 , - 1 , false )
52+ local has_message = false
53+ for _ , line in ipairs (lines ) do
54+ if not line :match (" ^%s*#" ) and vim .trim (line ) ~= " " then
55+ has_message = true
56+ break
57+ end
58+ end
59+
60+ -- Skip if buffer already has content
61+ if has_message then
62+ return false
63+ end
64+
65+ -- Skip auto-generation during git amend operation
66+ local should_skip_amend = config .skip_auto_generate_on_amend and Git .is_amending ()
67+ if should_skip_amend then
68+ return false
69+ end
70+
71+ return true
72+ end
73+
74+ local function schedule_auto_generate (bufnr )
75+ -- Cancel any pending timer to avoid multiple generations
76+ if pending_timer then
77+ pending_timer :stop ()
78+ pending_timer = nil
79+ end
80+
81+ -- Schedule generation with extended delay for stability
82+ pending_timer = vim .defer_fn (function ()
83+ pending_timer = nil
84+ if should_attempt_auto_generate (bufnr ) then
85+ auto_generate_attempted = true
86+ Buffer ._generate_and_insert_commit_message (bufnr )
87+ end
88+ end , config .auto_generate_delay + 300 ) -- Extra delay for window stability
89+ end
90+
91+ -- Multiple event triggers to ensure compatibility with different Git tools
92+ local autocmd_opts = {
3993 buffer = event .buf ,
40- once = true ,
41- callback = function (args )
42- -- Defer execution to ensure other plugins finish UI setup
43- vim .defer_fn (function ()
44- if not vim .api .nvim_buf_is_valid (args .buf ) then
45- return
46- end
94+ desc = " Auto-generate GitCommit message" ,
95+ }
4796
48- -- Check if buffer already has commit message
49- local lines = vim .api .nvim_buf_get_lines ( args . buf , 0 , - 1 , false )
50- local has_message = false
51- for _ , line in ipairs ( lines ) do
52- if not line : match ( " ^%s*# " ) and vim . trim ( line ) ~= " " then
53- has_message = true
54- break
55- end
56- end
97+ -- Primary trigger: WinEnter (works with most tools)
98+ vim .api .nvim_create_autocmd (
99+ " WinEnter " ,
100+ vim . tbl_extend ( " force " , autocmd_opts , {
101+ callback = function ( args )
102+ schedule_auto_generate ( args . buf )
103+ end ,
104+ })
105+ )
57106
58- -- Skip auto-generation if:
59- -- 1. Buffer already has commit message
60- -- 2. In git amend operation (user may want to keep existing message)
61- local should_skip_amend = config .skip_auto_generate_on_amend and Git .is_amending ()
62- if not has_message and not should_skip_amend then
63- Buffer ._generate_and_insert_commit_message (args .buf )
107+ -- Secondary trigger: BufWinEnter (works with Fugitive)
108+ vim .api .nvim_create_autocmd (
109+ " BufWinEnter" ,
110+ vim .tbl_extend (" force" , autocmd_opts , {
111+ once = true ,
112+ callback = function (args )
113+ schedule_auto_generate (args .buf )
114+ end ,
115+ })
116+ )
117+
118+ -- Tertiary trigger: CursorMoved (fallback, with debouncing)
119+ vim .api .nvim_create_autocmd (
120+ " CursorMoved" ,
121+ vim .tbl_extend (" force" , autocmd_opts , {
122+ once = true ,
123+ callback = function (args )
124+ schedule_auto_generate (args .buf )
125+ end ,
126+ })
127+ )
128+
129+ -- Cleanup timer when buffer is deleted or unloaded
130+ vim .api .nvim_create_autocmd (
131+ { " BufDelete" , " BufUnload" },
132+ vim .tbl_extend (" force" , autocmd_opts , {
133+ callback = function ()
134+ if pending_timer then
135+ pending_timer :stop ()
136+ pending_timer = nil
64137 end
65- end , config .auto_generate_delay )
66- end ,
67- desc = " Auto-generate GitCommit message" ,
68- })
138+ end ,
139+ })
140+ )
69141 end
70142 end ,
71143 desc = " Setup GitCommit AI assistant" ,
0 commit comments