diff --git a/crates/fff-nvim/src/lib.rs b/crates/fff-nvim/src/lib.rs index 8e31c38b..0ca44294 100644 --- a/crates/fff-nvim/src/lib.rs +++ b/crates/fff-nvim/src/lib.rs @@ -5,8 +5,9 @@ use fff::frecency::FrecencyTracker; use fff::path_utils::expand_tilde; use fff::query_tracker::QueryTracker; use fff::{ - DbHealthChecker, Error, FFFMode, FileSearchConfig, FuzzySearchOptions, PaginationArgs, - QueryParser, Score, SearchResult, SharedFrecency, SharedPicker, SharedQueryTracker, + DbHealthChecker, Error, FFFMode, FileSearchConfig, FuzzySearchOptions, GrepConfig, + PaginationArgs, QueryParser, Score, SearchResult, SharedFrecency, SharedPicker, + SharedQueryTracker, }; use mimalloc::MiMalloc; use mlua::prelude::*; @@ -582,6 +583,18 @@ pub fn get_historical_grep_query(_: &Lua, offset: usize) -> LuaResult LuaResult { + let parser = QueryParser::new(GrepConfig); + let parsed = parser.parse(&query); + let table = lua.create_table()?; + table.set("grep_text", parsed.grep_text())?; + Ok(table) +} + pub fn wait_for_initial_scan(_: &Lua, timeout_ms: Option) -> LuaResult { // Extract the scan signal Arc WITHOUT holding the read lock, so the // scan thread can acquire the write lock to store its results. @@ -822,6 +835,7 @@ fn create_exports(lua: &Lua) -> LuaResult { exports.set("health_check", lua.create_function(health_check)?)?; exports.set("shorten_path", lua.create_function(shorten_path)?)?; exports.set("hex_dump", lua.create_function(hex_dump::hex_dump)?)?; + exports.set("parse_grep_query", lua.create_function(parse_grep_query)?)?; Ok(exports) } diff --git a/lua/fff/fuzzy.lua b/lua/fff/fuzzy.lua index 78900c03..e28c4202 100644 --- a/lua/fff/fuzzy.lua +++ b/lua/fff/fuzzy.lua @@ -46,6 +46,7 @@ M.get_git_root = rust_module.get_git_root -- Grep functions M.live_grep = rust_module.live_grep +M.parse_grep_query = rust_module.parse_grep_query -- Utility functions M.health_check = rust_module.health_check diff --git a/lua/fff/location_utils.lua b/lua/fff/location_utils.lua index 0cc78d60..662af73e 100644 --- a/lua/fff/location_utils.lua +++ b/lua/fff/location_utils.lua @@ -178,16 +178,13 @@ function M.highlight_grep_matches(bufnr, location, namespace) local query = location.grep_query - -- Extract the actual search text from the grep query (strip file constraints like *.rs /src/) - -- The query parser uses space-separated tokens; the first non-constraint token is the pattern. - -- Simple heuristic: strip tokens that look like constraints (start with *, /, or !) - local search_text = query - local parts = vim.split(query, '%s+') - local text_parts = {} - for _, part in ipairs(parts) do - if part ~= '' and not part:match('^[%*!/]') and not part:match('^%.') then table.insert(text_parts, part) end - end - if #text_parts > 0 then search_text = text_parts[1] end + -- Use the Rust GrepConfig parser as the single source of truth for + -- stripping constraint tokens. This avoids duplicating constraint + -- detection in Lua, which would break whenever a new token type is added. + local fuzzy = require('fff.fuzzy') + local parsed = fuzzy.parse_grep_query(query) + local search_text = parsed.grep_text + if search_text == '' then search_text = query end if not search_text or search_text == '' then return nil end