Skip to content
Open
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
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ Run `:checkhealth coderabbit` to verify everything is wired up.
| `:CodeRabbitReview [type]` | Run a review. Defaults to `all`, or pass `committed`/`uncommitted` |
| `:CodeRabbitStop` | Cancel a running review |
| `:CodeRabbitClear` | Clear diagnostics |
| `:CodeRabbitShow [id]` | View results (float or buffer). Defaults to the latest review |
| `:CodeRabbitShow [id] [severity]` | View results (float or buffer). Defaults to the latest review; severity can be `critical`, `major`, or `minor` |
| `:CodeRabbitRestore [id]` | Reapply diagnostics from a saved review. Defaults to the most recent |
| `:CodeRabbitQuickfix [id]` | Populate quickfix list with findings |
| `:CodeRabbitQuickfix [id] [severity]` | Populate quickfix list with findings |
| `:CodeRabbitHistory` | Browse past reviews |

Examples: `:CodeRabbitShow critical` shows only critical findings from the latest review, and `:CodeRabbitShow 1 critical` shows only critical findings from saved review `1`.

For your statusline:

```lua
Expand All @@ -77,6 +79,7 @@ require("coderabbit").setup({
},
diagnostics = {
enabled = true,
severity_filter = nil, -- nil/all, "critical", "major", "minor", or a list
severity_map = {
critical = vim.diagnostic.severity.ERROR,
major = vim.diagnostic.severity.WARN,
Expand All @@ -88,6 +91,7 @@ require("coderabbit").setup({
},
show = {
layout = "float", -- "float" or "buffer"
severity_filter = nil,
float = {
width = 0.6,
height = 0.7,
Expand All @@ -96,6 +100,7 @@ require("coderabbit").setup({
},
quickfix = {
auto = false, -- populate on review complete
severity_filter = nil,
},
history = {
max_entries = 50, -- keep the most recent saved reviews per repo
Expand Down
27 changes: 23 additions & 4 deletions doc/coderabbit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ All options are optional. Defaults: >lua
},
diagnostics = {
enabled = true,
severity_filter = nil,
severity_map = {
critical = vim.diagnostic.severity.ERROR,
major = vim.diagnostic.severity.WARN,
Expand All @@ -56,6 +57,7 @@ All options are optional. Defaults: >lua
},
show = {
layout = "float",
severity_filter = nil,
float = {
width = 0.6,
height = 0.7,
Expand All @@ -64,6 +66,7 @@ All options are optional. Defaults: >lua
},
quickfix = {
auto = false,
severity_filter = nil,
},
history = {
max_entries = 50,
Expand All @@ -81,6 +84,10 @@ review.base Base branch for comparison.
review.base_commit Base commit SHA for comparison.

diagnostics.enabled Populate |vim.diagnostic| with findings.
diagnostics.severity_filter
Limit diagnostics to one or more CodeRabbit severities.
Accepts nil, `"all"`, `"critical"`, `"major"`,
`"minor"`, or a list of those strings.
diagnostics.severity_map Map CodeRabbit severities to |vim.diagnostic.severity|.
diagnostics.virtual_text Show inline virtual text.
diagnostics.signs Show sign column indicators.
Expand All @@ -89,12 +96,16 @@ diagnostics.underline Underline diagnostic ranges.
show.layout `"float"` or `"buffer"`. Default: `"float"`.
`"float"` opens a centered floating window.
`"buffer"` replaces the current buffer (oil.nvim style).
show.severity_filter Default severity filter for |:CodeRabbitShow|.
show.float.width Fraction of editor width (0-1). Default: `0.6`.
show.float.height Fraction of editor height (0-1). Default: `0.7`.
show.float.border Border style for the floating window. Default: `"rounded"`.

quickfix.auto Populate the quickfix list automatically when a review
completes. Default: `false`.
quickfix.severity_filter
Default severity filter for |:CodeRabbitQuickfix| and
automatic quickfix population.

history.max_entries Maximum saved reviews kept per repo. Default: `50`.
Set to `0` to keep all saved reviews.
Expand All @@ -114,9 +125,14 @@ COMMANDS *coderabbit-commands*
:CodeRabbitClear *:CodeRabbitClear*
Clear all CodeRabbit diagnostics.

:CodeRabbitShow [id] *:CodeRabbitShow*
:CodeRabbitShow [id] [severity] *:CodeRabbitShow*
Open review results. Display mode is controlled by `show.layout`.
Pass an `id` from `:CodeRabbitHistory` to view a saved review.
Pass a severity (`critical`, `major`, `minor`) to focus the output.
Examples: >
:CodeRabbitShow critical
:CodeRabbitShow 1 critical
<
Press `q` to close.

:CodeRabbitRestore [id] *:CodeRabbitRestore*
Expand All @@ -127,10 +143,11 @@ COMMANDS *coderabbit-commands*
:CodeRabbitHistory *:CodeRabbitHistory*
Browse saved reviews via |vim.ui.select|.

:CodeRabbitQuickfix [id] *:CodeRabbitQuickfix*
:CodeRabbitQuickfix [id] [severity] *:CodeRabbitQuickfix*
Populate the quickfix list with findings. Pass an `id` from
`:CodeRabbitHistory` to load a saved review. Without an `id`,
uses the current review findings. Navigate with |:cnext| and |:cprev|.
Pass a severity (`critical`, `major`, `minor`) to focus the list.

==============================================================================
LUA API *coderabbit-api*
Expand All @@ -147,17 +164,19 @@ require("coderabbit").stop() *coderabbit.stop()*
require("coderabbit").clear() *coderabbit.clear()*
Clear diagnostics and reset state.

require("coderabbit").show({id}) *coderabbit.show()*
require("coderabbit").show({id}, {opts}) *coderabbit.show()*
Open the review buffer. `nil` = current, number = saved.
Optional opts: `{ severity_filter = "critical" }`.

require("coderabbit").restore({id}) *coderabbit.restore()*
Reapply diagnostics from a saved review. `nil` = most recent.

require("coderabbit").history() *coderabbit.history()*
Open the review history picker.

require("coderabbit").quickfix({id}) *coderabbit.quickfix()*
require("coderabbit").quickfix({id}, {opts}) *coderabbit.quickfix()*
Populate the quickfix list with findings. `nil` = current, number = saved.
Optional opts: `{ severity_filter = "critical" }`.

require("coderabbit").status() *coderabbit.status()*
Returns `"⠋ CodeRabbit (12s)"` while reviewing, `nil` when idle.
Expand Down
3 changes: 3 additions & 0 deletions lua/coderabbit/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ M.defaults = {
},
diagnostics = {
enabled = true,
severity_filter = nil,
severity_map = {
critical = vim.diagnostic.severity.ERROR,
major = vim.diagnostic.severity.WARN,
Expand All @@ -24,6 +25,7 @@ M.defaults = {
},
show = {
layout = "float",
severity_filter = nil,
float = {
width = 0.6,
height = 0.7,
Expand All @@ -32,6 +34,7 @@ M.defaults = {
},
quickfix = {
auto = false,
severity_filter = nil,
},
history = {
max_entries = 50,
Expand Down
8 changes: 4 additions & 4 deletions lua/coderabbit/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ function M.restore(id)
require("coderabbit.review").restore(id)
end

function M.show(id)
require("coderabbit.show").open(id)
function M.show(id, opts)
require("coderabbit.show").open(id, opts)
end

function M.history()
require("coderabbit.history").open()
end

function M.quickfix(id)
require("coderabbit.quickfix").populate(id)
function M.quickfix(id, opts)
require("coderabbit.quickfix").populate(id, opts)
end

function M.status()
Expand Down
38 changes: 32 additions & 6 deletions lua/coderabbit/quickfix.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local M = {}

local utils = require("coderabbit.utils")
local severity_filter = require("coderabbit.severity")

local severity_types = {
[vim.diagnostic.severity.ERROR] = "E",
Expand All @@ -16,8 +17,12 @@ end

--- Convert findings to quickfix items (pure function, no side effects).
--- @param findings table[] Array of { diagnostic, filepath }
--- @param opts table|nil { severity_filter = table }
--- @return table[] Array of { filename, lnum, col, text, type } for setqflist()
function M.findings_to_qf_items(findings)
function M.findings_to_qf_items(findings, opts)
opts = opts or {}
findings = severity_filter.filter_findings(findings, opts.severity_filter)

local items = {}
for _, f in ipairs(findings) do
local d = f.diagnostic
Expand All @@ -37,20 +42,34 @@ end

--- Populate the quickfix list from findings and open the window.
--- @param findings table[] Array of { diagnostic, filepath }
--- @param opts table|nil { title = string }
--- @param opts table|nil { title = string, severity_filter = table|string|string[] }
function M.set(findings, opts)
opts = opts or {}
local items = M.findings_to_qf_items(findings)
local filter, err = severity_filter.parse_filter(opts.severity_filter)
if err then
utils.notify("Invalid severity filter: " .. err, vim.log.levels.ERROR)
return
end

local title = opts.title or "CodeRabbit Review"
local filter_label = severity_filter.describe(filter)
if filter_label then
title = title .. " (" .. filter_label .. ")"
end

local items = M.findings_to_qf_items(findings, { severity_filter = filter })
vim.fn.setqflist({}, "r", {
title = opts.title or "CodeRabbit Review",
title = title,
items = items,
})
vim.cmd("copen")
end

--- Populate quickfix from current review or a saved review by ID.
--- @param id number|nil Review ID (nil = current in-memory findings)
function M.populate(id)
--- @param opts table|nil { severity_filter = table|string|string[] }
function M.populate(id, opts)
opts = opts or {}
local findings, title

local review = require("coderabbit.review")
Expand All @@ -72,7 +91,14 @@ function M.populate(id)
title = "CodeRabbit Review"
end

M.set(findings, { title = title })
local filter_arg
if opts.severity_filter ~= nil then
filter_arg = opts.severity_filter
else
filter_arg = require("coderabbit.config").get().quickfix.severity_filter
end

M.set(findings, { title = title, severity_filter = filter_arg })
end

return M
27 changes: 23 additions & 4 deletions lua/coderabbit/review.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ local cli = require("coderabbit.cli")
local parser = require("coderabbit.parser")
local diagnostics = require("coderabbit.diagnostics")
local utils = require("coderabbit.utils")
local severity = require("coderabbit.severity")

local spinner_frames = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" }
local FRAME_MS = 80
Expand Down Expand Up @@ -114,6 +115,11 @@ function M.run(opts)
state.findings = {}
state.cwd = vim.fn.getcwd()
local cfg = config.get()
local diagnostics_filter, diagnostics_filter_err = severity.parse_filter(cfg.diagnostics.severity_filter)
if diagnostics_filter_err then
utils.notify("Invalid diagnostics severity filter: " .. diagnostics_filter_err, vim.log.levels.ERROR)
return
end
local finding_count = 0
local got_error = false

Expand Down Expand Up @@ -152,8 +158,9 @@ function M.run(opts)
finding_count = finding_count + 1
local diag, filepath = parser.finding_to_diagnostic(event, state.cwd, cfg.diagnostics.severity_map)
if diag then
table.insert(state.findings, { diagnostic = diag, filepath = filepath })
if cfg.diagnostics.enabled then
local finding = { diagnostic = diag, filepath = filepath }
table.insert(state.findings, finding)
if cfg.diagnostics.enabled and severity.matches(finding, diagnostics_filter) then
diagnostics.set(filepath, { diag })
end
end
Expand Down Expand Up @@ -211,6 +218,7 @@ function M.run(opts)
if type(cfg.quickfix) == "table" and cfg.quickfix.auto and #state.findings > 0 then
require("coderabbit.quickfix").set(state.findings, {
title = "CodeRabbit Review",
severity_filter = cfg.quickfix.severity_filter,
})
end

Expand Down Expand Up @@ -249,14 +257,25 @@ function M.restore(id)
return
end

local cfg = config.get()
local diagnostics_filter, diagnostics_filter_err = severity.parse_filter(cfg.diagnostics.severity_filter)
if diagnostics_filter_err then
utils.notify("Invalid diagnostics severity filter: " .. diagnostics_filter_err, vim.log.levels.ERROR)
return
end

diagnostics.clear()
local findings = type(review.findings) == "table" and review.findings or {}
vim.schedule(function()
local restored = 0
for _, finding in ipairs(findings) do
diagnostics.set(finding.filepath, { finding.diagnostic })
if severity.matches(finding, diagnostics_filter) then
diagnostics.set(finding.filepath, { finding.diagnostic })
restored = restored + 1
end
end

utils.notify(string.format("Restored %d findings from review #%d", #findings, id))
utils.notify(string.format("Restored %d findings from review #%d", restored, id))
end)
end

Expand Down
Loading
Loading