Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lua/coderabbit/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ local M = {}
M.defaults = {
cli = {
binary = "cr",
timeout = 120000,
timeout = 0,
Comment thread
smnatale marked this conversation as resolved.
extra_args = {},
},
review = {
Expand Down
4 changes: 4 additions & 0 deletions lua/coderabbit/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ function M.clear()
require("coderabbit.review").clear()
end

function M.status()
return require("coderabbit.review").status()
end

return M
69 changes: 68 additions & 1 deletion lua/coderabbit/review.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,49 @@ local cli = require("coderabbit.cli")
local parser = require("coderabbit.parser")
local diagnostics = require("coderabbit.diagnostics")

local spinner_frames = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" }
local FRAME_MS = 80

local state = {
job_id = nil,
findings = {},
cwd = nil,
start_time = nil,
fidget_handle = nil,
last_notify_time = nil,
}

local function spinner()
local idx = math.floor(vim.uv.hrtime() / (1e6 * FRAME_MS)) % #spinner_frames + 1
return spinner_frames[idx]
end

local function fidget_start()
local ok, progress = pcall(require, "fidget.progress")
if not ok then
return nil
end
return progress.handle.create({
title = "Reviewing",
message = "analyzing...",
lsp_client = { name = "coderabbit" },
})
end

local function fidget_update(msg)
if state.fidget_handle then
state.fidget_handle.message = msg
end
end

local function fidget_finish(msg)
if state.fidget_handle then
state.fidget_handle.message = msg
state.fidget_handle:finish()
state.fidget_handle = nil
end
end

function M.is_running()
return state.job_id ~= nil
end
Expand All @@ -19,6 +56,16 @@ function M.get_results()
return state.findings
end

--- Return a short status string for statusline integration.
--- Returns nil when no review is running.
function M.status()
if not state.job_id then
return nil
end
local elapsed = os.time() - state.start_time
return string.format("%s CodeRabbit (%ds)", spinner(), elapsed)
end

function M.run(opts)
opts = opts or {}

Expand All @@ -43,6 +90,9 @@ function M.run(opts)

vim.notify("CodeRabbit: Reviewing...")

state.start_time = os.time()
state.fidget_handle = fidget_start()

state.job_id = cli.review(opts, {
on_line = function(line)
local event = parser.parse_line(line)
Expand All @@ -51,7 +101,16 @@ function M.run(opts)
end

if event.type == "status" then
vim.notify("CodeRabbit: " .. (event.status or event.phase or "working..."), vim.log.levels.INFO)
local msg = event.status or event.phase or "working..."
if state.fidget_handle then
fidget_update(msg)
else
local now = os.time()
if not state.last_notify_time or (now - state.last_notify_time) >= 20 then
state.last_notify_time = now
vim.notify("CodeRabbit: " .. msg, vim.log.levels.INFO)
end
end
elseif event.type == "finding" then
finding_count = finding_count + 1
local diag, filepath = parser.finding_to_diagnostic(event, state.cwd, cfg.diagnostics.severity_map)
Expand All @@ -73,8 +132,11 @@ function M.run(opts)

on_exit = function(code, stderr)
state.job_id = nil
state.start_time = nil
state.last_notify_time = nil

if code == -1 then
fidget_finish("timed out")
vim.notify("CodeRabbit: Review timed out", vim.log.levels.ERROR)
return
end
Expand All @@ -85,14 +147,18 @@ function M.run(opts)
if msg:match("[Aa]uth") then
msg = msg .. "\nRun: cr auth login"
end
fidget_finish("failed")
vim.notify("CodeRabbit: " .. msg, vim.log.levels.ERROR)
return
end

if not got_error then
local summary =
string.format("CodeRabbit: Review complete. %d finding%s.", finding_count, finding_count == 1 and "" or "s")
fidget_finish(string.format("done — %d finding%s", finding_count, finding_count == 1 and "" or "s"))
vim.notify(summary, vim.log.levels.INFO)
else
fidget_finish("done (with errors)")
end

if cfg.on_review_complete then
Expand All @@ -104,6 +170,7 @@ end

function M.stop()
if state.job_id then
fidget_finish("cancelled")
cli.cancel(state.job_id)
state.job_id = nil
vim.notify("CodeRabbit: Review cancelled", vim.log.levels.INFO)
Expand Down
Loading