Skip to content

Conversation

@glepnir
Copy link
Member

@glepnir glepnir commented Nov 9, 2025

No description provided.

@glepnir glepnir requested a review from Copilot November 9, 2025 05:38
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors lua/guard/format.lua by inlining helper functions, simplifying error handling, and optimizing buffer update logic. The main changes consolidate the formatter application logic directly into the do_fmt function and improve the efficiency of content comparison.

Key Changes

  • Inlined apply_pure_formatter, apply_impure_formatter, and emit_event helper functions into the main do_fmt function
  • Changed buffer update logic to compare string content directly instead of line arrays
  • Introduced centralized error handling with an errno variable to track formatter errors

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +123 to +124
local prev_lines = api.nvim_buf_get_lines(buf, srow, erow, false)
local prev_content = table.concat(prev_lines, '\n')
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a potential issue with capturing prev_lines and prev_content at lines 123-124. These are captured outside the async.run block, before the changedtick is initialized inside async.run at line 130-134. If the buffer changes between line 124 (capturing content) and line 134 (capturing changedtick), the changedtick validation at line 189 would pass but prev_content would be stale. Consider moving lines 123-124 inside the async.run block, within the same scheduled callback as the changedtick capture (lines 130-134) to ensure atomic capture of both values.

Copilot uses AI. Check for mistakes.
vim.system(util.get_cmd(cfg, fname, buf), {
text = true,
cwd = cwd,
env = cfg.env or {},
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The impure formatter execution is missing the timeout parameter that was present in the original code. This could lead to formatters hanging indefinitely if they don't complete. The timeout should be added to the vim.system call options.

Suggested change
env = cfg.env or {},
env = cfg.env or {},
timeout = cfg.timeout or 5000,

Copilot uses AI. Check for mistakes.
Comment on lines +251 to +255
vim.schedule(function()
api.nvim_buf_call(buf, function()
local views = save_views(buf)
api.nvim_command('silent! edit!')
restore_views(views)
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final vim.schedule call for impure formatters is missing the async.await wrapper. This means the code won't wait for the buffer refresh to complete before emitting the 'done' event. This could cause a race condition where the 'done' event fires before the buffer is actually refreshed. The original code wrapped this in async.await(1, function(callback) ... callback() end) to ensure proper sequencing.

Suggested change
vim.schedule(function()
api.nvim_buf_call(buf, function()
local views = save_views(buf)
api.nvim_command('silent! edit!')
restore_views(views)
async.await(1, function(callback)
vim.schedule(function()
api.nvim_buf_call(buf, function()
local views = save_views(buf)
api.nvim_command('silent! edit!')
restore_views(views)
end)
callback()

Copilot uses AI. Check for mistakes.
Comment on lines +208 to +210
if errno then
return
end
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic has a flaw: when an error occurs in pure formatters (errno is set at line 163-168), the code continues to the buffer update section (line 176) which checks for errno and reports the error. However, after reporting the error and returning at line 188, the code then checks errno again at line 208 and returns again. This second check at line 208 is unreachable because the earlier return at line 188 has already exited. This creates confusion in the control flow.

Suggested change
if errno then
return
end

Copilot uses AI. Check for mistakes.
Comment on lines +179 to +180
if errno.reason:match('exited with errors$') then
fail(('%s exited with code %d\n%s'):format(errno.cmd, errno.code, errno.stderr))
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error checking at line 179 uses pattern matching with match('exited with errors$') to distinguish error types, but this is fragile. The error reason is set as a string literal at line 167 ('exited with errors'), so the pattern matching is unnecessary - a direct string comparison would be more reliable and maintainable. Alternatively, use a separate error type field instead of parsing the reason string.

Copilot uses AI. Check for mistakes.
@glepnir glepnir closed this Nov 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants