Skip to content

feat(sdk)!: add case_mode: smart, sensitive, insensitive option#609

Open
gustav-fff wants to merge 5 commits into
mainfrom
feat/case-mode-api
Open

feat(sdk)!: add case_mode: smart, sensitive, insensitive option#609
gustav-fff wants to merge 5 commits into
mainfrom
feat/case-mode-api

Conversation

@gustav-fff

Copy link
Copy Markdown
Collaborator

Split out from #561 per @dmtrKovalenko request.

What

Adds fff::CaseMode { Smart, Sensitive, Insensitive } and a new optional case_mode: Option<CaseMode> field on GrepSearchOptions. Adds GrepSearchOptions::effective_case_mode() to resolve the effective mode.

Non-breaking

The legacy smart_case: bool field is preserved. When case_mode is None, the existing boolean is used (true => Smart, false => Sensitive) — identical behavior to before. New callers that need Insensitive set case_mode = Some(CaseMode::Insensitive).

No public function signatures changed. Default still emits smart_case: true, case_mode: None. Existing consumers (fff-c, fff-nvim, benches, tests) compile unchanged.

Why this shape

The original PR #561 changed smart_case: bool to case_mode: CaseMode directly, which is a breaking field change for anyone constructing GrepSearchOptions. This PR adds the new API alongside the old one so #561 (and future consumers) can adopt case_mode without a major version bump.

How verified

cargo check -p fff-search passes. Internal call sites in grep.rs route through effective_case_mode() so behavior is preserved when only smart_case is set.

Co-authored-by: Marko Vejnovic contact@markovejnovic.com

Automated triage via Gustav. Honk-Honk 🪿

Adds explicit `CaseMode { Smart, Sensitive, Insensitive }` and a new
`case_mode: Option<CaseMode>` field on `GrepSearchOptions`. The legacy
`smart_case: bool` is preserved for backward compatibility — when
`case_mode` is `None`, the boolean is used (true => Smart, false =>
Sensitive). New callers that need `Insensitive` set `case_mode`
explicitly.

Co-authored-by: Marko Vejnovic <contact@markovejnovic.com>
@dmtrKovalenko

Copy link
Copy Markdown
Owner

@gustav-fff you need to make sure that it is getting compiled everywhere and mark

@dmtrKovalenko dmtrKovalenko changed the title feat(grep): add CaseMode enum and case_mode option (non-breaking) feat(sdk)!: add case_mode: smart, sensitive, insensitive option Jun 17, 2026
@dmtrKovalenko

Copy link
Copy Markdown
Owner

@gustav-fff also make it configurable for neovim lua

Add case_mode: None to all GrepSearchOptions construction sites across
fff-c, fff-mcp, fff-nvim, fff-python, and tests so the new field
compiles everywhere.

Expose case_mode in the neovim lua API: new optional config
grep.case_mode ("smart"|"sensitive"|"insensitive") flows through
live_grep FFI and content_search opts. smart_case remains the legacy
default; case_mode overrides it when set.
@gustav-fff

Copy link
Copy Markdown
Collaborator Author

[triage-bot] DIRECTED: pushed 2ecd02d.

  • Added case_mode: None to every GrepSearchOptions construction site across fff-c, fff-mcp, fff-nvim, fff-python, and the integration/fuzz tests so cargo check --workspace --all-targets is clean.
  • Exposed case_mode to neovim lua: new optional grep.case_mode = "smart"|"sensitive"|"insensitive" in lua/fff/conf.lua, plumbed through live_grep FFI in crates/fff-nvim/src/lib.rs:435 (parsed into Option<fff::CaseMode>), lua/fff/picker_ui/grep_renderer.lua:34, and M.content_search opts in lua/fff/main.lua:304.
  • Legacy smart_case boolean still works; case_mode overrides when set, matching effective_case_mode() semantics.

README update for the new config option not included — flagging for @dmtrKovalenko since per CLAUDE.md new neovim config options should be documented there. Want me to add a section?

Honk-Honk 🪿

@dmtrKovalenko dmtrKovalenko left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@gustav-fff apply changes

@@ -335,6 +343,10 @@ pub struct GrepSearchOptions {
pub max_file_size: u64,
pub max_matches_per_file: usize,
pub smart_case: bool,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

deprecate it

Comment thread crates/fff-core/src/grep.rs Outdated
pub max_file_size: u64,
pub max_matches_per_file: usize,
pub smart_case: bool,
/// Explicit case mode. When `Some`, overrides `smart_case`. When `None`,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

make comment smaller

Comment thread crates/fff-core/src/grep.rs Outdated
impl GrepSearchOptions {
/// Resolves the effective case mode, preferring explicit `case_mode` over
/// the legacy `smart_case` boolean.
pub fn effective_case_mode(&self) -> CaseMode {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

make privat eremov ecommetn

@gustav-fff

Copy link
Copy Markdown
Collaborator Author

[triage-bot] DIRECTED: pushed 9e49990.

  • smart_case field marked #[deprecated(note = "use case_mode instead")].
  • effective_case_mode() is now private (fn instead of pub fn); only used internally in grep.rs.
  • Trimmed the case_mode doc to a single line.

cargo check --workspace --all-targets clean (only deprecation warnings on legacy callers, expected).

Honk-Honk 🪿

@dmtrKovalenko

Copy link
Copy Markdown
Owner

@gustav-fff CI !!!

Tests, benches, FFI bindings, and the MCP server still construct
GrepSearchOptions with the legacy smart_case field. Suppress the
deprecation lint per file/site so RUSTFLAGS=-D warnings stays clean.
@gustav-fff

Copy link
Copy Markdown
Collaborator Author

[triage-bot] DIRECTED: pushed 19c5018.

CI failed because RUSTFLAGS=-D warnings promoted #[deprecated] on the legacy smart_case field into hard errors at every existing call site.

  • Wrapped the few first-party constructors in fff-core/src/grep.rs (Default + 2 in-module tests) with #[allow(deprecated)].
  • Crate-level #![allow(deprecated)] on fff-c, fff-nvim, fff-python (lib.rs/finder.rs) — they still set smart_case from the FFI/PyO3 boundary intentionally.
  • #[allow(deprecated)] on make_grep_options in fff-mcp/src/server.rs.
  • Module-level #![allow(deprecated)] on every fff-core integration test, fff-nvim bench, and fff-nvim binary that constructs GrepSearchOptions literally.

RUSTFLAGS="-D warnings" cargo test --workspace --exclude fff-nvim --no-run and cargo clippy -- -D warnings both clean locally.

Honk-Honk 🪿

@dmtrKovalenko

Copy link
Copy Markdown
Owner

@gustav-fff you should change all the internal occurances to be using new option - WTF?

Convert all in-tree GrepSearchOptions constructions to set
case_mode: Some(...) instead of the deprecated smart_case bool
field. FFI boundaries (fff-c, fff-nvim, fff-python) still accept
smart_case bool from external callers but translate to CaseMode
before constructing the options struct.

Removes the blanket #[allow(deprecated)] attrs added in 19c5018;
only Default for GrepSearchOptions retains it since it must
initialize the deprecated field by name.
@gustav-fff

Copy link
Copy Markdown
Collaborator Author

[triage-bot] DIRECTED: pushed 2ce2a51.

Converted every internal GrepSearchOptions { ... } literal to case_mode: Some(CaseMode::Smart) and dropped the smart_case: field name from internal sites. Boundary FFI (fff-c, fff-nvim lua, fff-python) still accepts smart_case: bool from external callers but translates to CaseMode before constructing the options struct.

  • Removed every #![allow(deprecated)] and #[allow(deprecated)] added in 19c5018. Only one remains: Default for GrepSearchOptions in crates/fff-core/src/grep.rs, since Default must initialize the deprecated public field by name. effective_case_mode() also keeps a local allow because it reads the legacy bool to honor old callers.
  • 20 files touched: 8 fff-core integration tests, fff-core grep.rs in-module tests, fff-mcp server.rs, 2 fff-nvim benches, 4 fff-nvim bins, fff-c lib.rs, fff-nvim lib.rs, fff-python finder.rs.
  • RUSTFLAGS=\"-D warnings\" cargo check --workspace --all-targets clean for all library/bin crates. Two pre-existing dead_code errors in crates/fff-nvim/benches/{query_tracker,fuzzy_search}_bench.rs reproduce on main unchanged — unrelated to this PR.

Honk-Honk 🪿

@dmtrKovalenko

Copy link
Copy Markdown
Owner

@gustav-fff DOOOO THE WORK AND WAIT FOR THE CI TO ACTUALLY FINISH HELOOOO

@gustav-fff

Copy link
Copy Markdown
Collaborator Author

[triage-bot] DIRECTED: CI green on 2ce2a51.

All required checks pass: clippy, check (RUSTFLAGS=-D warnings), test (linux/mac/windows), e2e (alpine/linux/mac/windows), stress, python bindings, stylua, luacheck, lua-ls, typos, all C FFI / MCP / Neovim cross-builds.

Honk-Honk 🪿

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