Skip to content

Commit 5f722dc

Browse files
feat: Highlight and prioritize code definitions in grep results
1 parent 4b83987 commit 5f722dc

6 files changed

Lines changed: 24 additions & 2 deletions

File tree

crates/fff-core/src/grep.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,12 @@ fn collect_grep_results<'a>(
11501150
}
11511151
}
11521152

1153+
// Prioritize definition matches by sorting them to the top.
1154+
// Use a stable sort to maintain relative order within each category.
1155+
if options.classify_definitions {
1156+
crate::sort_buffer::sort_by_key_with_buffer(&mut all_matches, |m| !m.is_definition);
1157+
}
1158+
11531159
// If no file had any match, we searched the entire slice.
11541160
if result_files.is_empty() {
11551161
files_consumed = files_to_search_len;

crates/fff-nvim/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ pub fn live_grep(
311311
smart_case,
312312
grep_mode,
313313
time_budget_ms,
314+
classify_definitions,
314315
): (
315316
String,
316317
Option<usize>,
@@ -320,6 +321,7 @@ pub fn live_grep(
320321
Option<bool>,
321322
Option<String>,
322323
Option<u64>,
324+
Option<bool>,
323325
),
324326
) -> LuaResult<LuaValue> {
325327
let file_picker_guard = FILE_PICKER
@@ -348,7 +350,7 @@ pub fn live_grep(
348350
time_budget_ms: time_budget_ms.unwrap_or(0),
349351
before_context: 0,
350352
after_context: 0,
351-
classify_definitions: false,
353+
classify_definitions: classify_definitions.unwrap_or(false),
352354
};
353355

354356
let result = fff_core::grep::grep_search(picker.get_files(), &parsed, &options);

crates/fff-nvim/src/lua_types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ impl IntoLua for GrepResultLua<'_> {
141141
item.set("col", m.col)?;
142142
item.set("byte_offset", m.byte_offset)?;
143143
item.set("line_content", m.line_content.as_str())?;
144+
item.set("is_definition", m.is_definition)?;
144145

145146
// Match byte ranges within line_content
146147
let ranges = lua.create_table()?;

lua/fff/conf.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ local M = {}
5454
--- @field smart_case boolean
5555
--- @field time_budget_ms number
5656
--- @field modes string[]
57+
--- @field classify_definitions boolean
5758

5859
--- @class FffConfig
5960
--- @field base_path string
@@ -332,6 +333,7 @@ local function init()
332333
smart_case = true, -- Case-insensitive unless query has uppercase
333334
time_budget_ms = 150, -- Max search time in ms per call (prevents UI freeze, 0 = no limit)
334335
modes = { 'plain', 'regex', 'fuzzy' }, -- Available grep modes and their cycling order
336+
classify_definitions = false, -- Mark definition lines like fn/struct/class
335337
},
336338
}
337339

lua/fff/grep/grep_renderer.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ end
4747
local function render_match_line(item, ctx)
4848
local location = string.format(':%d:%d', item.line_number or 0, (item.col or 0) + 1)
4949
local separator = ' '
50+
5051
-- vim.json.decode may return Blobs for strings with NUL bytes; coerce to string.
5152
local raw_content = item.line_content
5253
if type(raw_content) ~= 'string' then raw_content = raw_content and tostring(raw_content) or '' end
@@ -193,6 +194,15 @@ local function apply_match_highlights(item, ctx, item_idx, buf, ns_id, row, line
193194
})
194195
end
195196
end
197+
198+
-- 7. Definition indicator as virtual text
199+
if item.is_definition then
200+
pcall(vim.api.nvim_buf_set_extmark, buf, ns_id, row, 0, {
201+
virt_text = { { ' [def]', config.hl.combo_header or 'Number' } },
202+
virt_text_pos = 'eol',
203+
priority = 250,
204+
})
205+
end
196206
end
197207

198208
--- Render a single item's lines (called by list_renderer's generate_item_lines).

lua/fff/grep/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ function M.search(query, file_offset, page_size, config, grep_mode)
3333
conf.max_matches_per_file,
3434
conf.smart_case,
3535
grep_mode or 'plain',
36-
conf.time_budget_ms
36+
conf.time_budget_ms,
37+
conf.classify_definitions
3738
)
3839
return last_result
3940
end

0 commit comments

Comments
 (0)