Files
Dmitriy Kovalenko a9df55d18e feat(sdk): Expose file watcher (#674)
* feat: Expose fff watcher

* fix: Snapshots

* fix: Snapshots

* fix: CI cache
2026-07-16 12:14:10 -07:00

1359 lines
43 KiB
C

/* Generated by cbindgen — do not edit manually. */
#ifndef FFF_C_H
#define FFF_C_H
/* Generated with cbindgen:0.29.2 */
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/**
* Current used version of [`FffCreateOptions`].
*/
#define FFF_CREATE_OPTIONS_VERSION 2
/**
* Current version of [`FffWatchOptions`].
*/
#define FFF_WATCH_OPTIONS_VERSION 1
/**
* Result envelope returned by all `fff_*` functions.
*
* Heap-allocated. The caller must free it with `fff_free_result`. Calling `fff_free_result`
* **does not** deallocate the underlying `handle` pointer. It needs to be cleaned separately.
* see (`fff_destroy`, `fff_free_search_result`, `fff_free_grep_result`, `fff_free_string`, etc.).
*
* Depending on the function, the payload is delivered through different fields:
*
* | Function | Payload field | Type |
* |----------------------------|---------------|-------------------------------|
* | `fff_create_instance` | `handle` | opaque instance pointer |
* | `fff_search` | `handle` | `*mut FffSearchResult` |
* | `fff_live_grep` | `handle` | `*mut FffGrepResult` |
* | `fff_multi_grep` | `handle` | `*mut FffGrepResult` |
* | `fff_get_scan_progress` | `handle` | `*mut FffScanProgress` |
* | `fff_health_check` | `handle` | `*mut c_char` (JSON string) |
* | `fff_get_historical_query` | `handle` | `*mut c_char` (string or null)|
* | `fff_wait_for_scan` | `int_value` | 1 = completed, 0 = timed out |
* | `fff_track_query` | `int_value` | 1 = success, 0 = failure |
* | `fff_refresh_git_status` | `int_value` | number of files updated |
* | `fff_scan_files` | (none) | success flag only |
* | `fff_restart_index` | (none) | success flag only |
*
* On failure, `success` is false and `error` contains the message.
*/
typedef struct FffResult {
/**
* Whether the operation succeeded.
*/
bool success;
/**
* Error message on failure. Null on success.
*/
char *error;
/**
* Opaque pointer payload. May be null.
*/
void *handle;
/**
* Integer payload for simple return values (bool as 0/1, counts, etc.).
*/
int64_t int_value;
} FffResult;
/**
* Options for `fff_create_instance_with`.
*
* Versioned struct: the layout is stable across releases, new fields are
* only appended.
*/
typedef struct FffCreateOptions {
/**
* Set to [`FFF_CREATE_OPTIONS_VERSION`] when allocating; tells the
* library which trailing fields are populated.
*/
uint32_t version;
/**
* Directory to index (required, non-NULL).
*/
const char *base_path;
/**
* Frecency LMDB database path. NULL/empty to skip frecency tracking.
*/
const char *frecency_db_path;
/**
* Query history LMDB database path. NULL/empty to skip query tracking.
*/
const char *history_db_path;
/**
* Pre-populate mmap caches for top-frecency files after the initial scan.
*/
bool enable_mmap_cache;
/**
* Build content index after the initial scan for faster grep.
*/
bool enable_content_indexing;
/**
* Start a background file-system watcher for live updates.
*/
bool watch;
/**
* Enable AI-agent optimizations.
*/
bool ai_mode;
/**
* Tracing log file path. NULL/empty to skip log init.
*/
const char *log_file_path;
/**
* Log level: `"trace" | "debug" | "info" | "warn" | "error"`.
* NULL/empty defaults to `"info"`. Ignored when `log_file_path` is unset.
*/
const char *log_level;
/**
* Content cache file-count cap. 0 = auto.
*/
uint64_t cache_budget_max_files;
/**
* Content cache byte cap. 0 = auto.
*/
uint64_t cache_budget_max_bytes;
/**
* Per-file byte cap inside the content cache. 0 = auto.
*/
uint64_t cache_budget_max_file_size;
/**
* Allow indexing the filesystem root (`/`). Off by default: root is rarely
* intended and floods the watcher with churn.
*/
bool enable_fs_root_scanning;
/**
* Allow indexing the user's home directory. Same trade-off as `enable_fs_root_scanning`.
*/
bool enable_home_dir_scanning;
/**
* Follow symlinks during scan and watcher walks. Off by default: without
* external loop protection cyclic symlinks can wedge the watcher.
*/
bool follow_symlinks;
} FffCreateOptions;
/**
* A file item returned by `fff_search`. Strings are owned by the parent
* `FffSearchResult`; free everything with `fff_free_search_result`.
*/
typedef struct FffFileItem {
char *relative_path;
char *file_name;
char *git_status;
uint64_t size;
uint64_t modified;
int64_t access_frecency_score;
int64_t modification_frecency_score;
int64_t total_frecency_score;
bool is_binary;
} FffFileItem;
/**
* Score breakdown for a search result.
*/
typedef struct FffScore {
int32_t total;
int32_t base_score;
int32_t filename_bonus;
int32_t special_filename_bonus;
int32_t frecency_boost;
int32_t distance_penalty;
int32_t current_file_penalty;
int32_t combo_match_boost;
int32_t path_alignment_bonus;
bool exact_match;
char *match_type;
} FffScore;
/**
* Location parsed from a query string (e.g. `"file.ts:42:10"`). `tag`:
* 0 = none, 1 = line, 2 = position (`line` + `col`),
* 3 = range (`line`/`col` = start, `end_line`/`end_col` = end).
*/
typedef struct FffLocation {
uint8_t tag;
int32_t line;
int32_t col;
int32_t end_line;
int32_t end_col;
} FffLocation;
/**
* Search result returned by `fff_search`; free with `fff_free_search_result`.
*/
typedef struct FffSearchResult {
/**
* Heap array of `FffFileItem` (length = `count`).
*/
struct FffFileItem *items;
/**
* Heap array of `FffScore` (length = `count`).
*/
struct FffScore *scores;
/**
* Number of items/scores in the arrays.
*/
uint32_t count;
/**
* Total number of files that matched the query.
*/
uint32_t total_matched;
/**
* Total number of indexed files.
*/
uint32_t total_files;
/**
* Location parsed from the query string.
*/
struct FffLocation location;
} FffSearchResult;
/**
* A byte range within a matched line, used for highlighting.
*/
typedef struct FffMatchRange {
uint32_t start;
uint32_t end;
} FffMatchRange;
/**
* A single grep match with file and line information. Strings and arrays are
* owned by the parent `FffGrepResult`; free everything with `fff_free_grep_result`.
*/
typedef struct FffGrepMatch {
char *relative_path;
char *file_name;
char *git_status;
char *line_content;
struct FffMatchRange *match_ranges;
char **context_before;
char **context_after;
uint64_t size;
uint64_t modified;
int64_t total_frecency_score;
int64_t access_frecency_score;
int64_t modification_frecency_score;
uint64_t line_number;
uint64_t byte_offset;
uint32_t col;
uint32_t match_ranges_count;
uint32_t context_before_count;
uint32_t context_after_count;
uint16_t fuzzy_score;
bool has_fuzzy_score;
bool is_binary;
bool is_definition;
} FffGrepMatch;
/**
* Grep result returned by `fff_live_grep` and `fff_multi_grep`;
* free with `fff_free_grep_result`.
*/
typedef struct FffGrepResult {
/**
* Heap array of `FffGrepMatch` (length = `count`).
*/
struct FffGrepMatch *items;
/**
* Number of matches in the `items` array.
*/
uint32_t count;
/**
* Total number of matches (always equal to `count`).
*/
uint32_t total_matched;
/**
* Number of files actually opened and searched in this call.
*/
uint32_t total_files_searched;
/**
* Total number of indexed files (before any filtering).
*/
uint32_t total_files;
/**
* Number of files eligible for search after filtering.
*/
uint32_t filtered_file_count;
/**
* File offset for the next page. 0 if all files have been searched.
*/
uint32_t next_file_offset;
/**
* Regex compilation error when falling back to literal matching. Null if none.
*/
char *regex_fallback_error;
} FffGrepResult;
/**
* Scan progress returned by `fff_get_scan_progress`.
* The caller must free this with `fff_free_scan_progress`.
*/
typedef struct FffScanProgress {
uint64_t scanned_files_count;
bool is_scanning;
bool is_watcher_ready;
bool is_warmup_complete;
} FffScanProgress;
/**
* A directory item returned by `fff_search_directories`. Strings are owned by
* the parent `FffDirSearchResult`; free everything with `fff_free_dir_search_result`.
*/
typedef struct FffDirItem {
char *relative_path;
char *dir_name;
int32_t max_access_frecency;
} FffDirItem;
/**
* Directory search result returned by `fff_search_directories`;
* free with `fff_free_dir_search_result`.
*/
typedef struct FffDirSearchResult {
/**
* Heap array of `FffDirItem` (length = `count`).
*/
struct FffDirItem *items;
/**
* Heap array of `FffScore` (length = `count`).
*/
struct FffScore *scores;
/**
* Number of items/scores in the arrays.
*/
uint32_t count;
/**
* Total number of directories that matched the query.
*/
uint32_t total_matched;
/**
* Total number of indexed directories.
*/
uint32_t total_dirs;
} FffDirSearchResult;
/**
* A single item in a mixed (files + directories) search result.
* `item_type`: 0 = file, 1 = directory. Strings are owned by the parent
* `FffMixedSearchResult`.
*/
typedef struct FffMixedItem {
/**
* 0 = file, 1 = directory.
*/
uint8_t item_type;
char *relative_path;
/**
* Filename for files, last directory segment for directories.
*/
char *display_name;
char *git_status;
uint64_t size;
uint64_t modified;
/**
* Access frecency for files; max among immediate children for directories.
*/
int64_t access_frecency_score;
/**
* Always 0 for directories
*/
int64_t modification_frecency_score;
/**
* Always 0 for directories
*/
int64_t total_frecency_score;
/**
* Always 0 for directories
*/
bool is_binary;
} FffMixedItem;
/**
* Mixed search result returned by `fff_search_mixed`
* free with `fff_free_mixed_search_result`.
*/
typedef struct FffMixedSearchResult {
/**
* Heap array of `FffMixedItem` (length = `count`).
*/
struct FffMixedItem *items;
/**
* Heap array of `FffScore` (length = `count`).
*/
struct FffScore *scores;
/**
* Number of items/scores in the arrays.
*/
uint32_t count;
/**
* Total number of items (files + dirs) that matched the query.
*/
uint32_t total_matched;
/**
* Total number of indexed files.
*/
uint32_t total_files;
/**
* Total number of indexed directories.
*/
uint32_t total_dirs;
/**
* Location parsed from the query string.
*/
struct FffLocation location;
} FffMixedSearchResult;
/**
* A single watch event. `kind`: 0 = created, 1 = modified, 2 = removed,
* 3 = rescan (events were lost; re-stat what you care about).
*/
typedef struct FffWatchEvent {
/**
* Absolute path (heap C string owned by the parent batch).
*/
char *path;
uint8_t kind;
} FffWatchEvent;
/**
* A batch of watch events. Free with `fff_free_watch_events`.
*/
typedef struct FffWatchEventBatch {
struct FffWatchEvent *events;
uint32_t count;
} FffWatchEventBatch;
/**
* Instance-wide callback invoked with `(watch_id, batch)` for every `fff_watch`
* subscription. The callee owns and frees `batch` via `fff_free_watch_events`.
*/
typedef void (*FffWatchCallback)(uint64_t watch_id,
struct FffWatchEventBatch *batch,
void *user_data);
/**
* Options for `fff_watch`. Versioned: new fields are only appended.
*/
typedef struct FffWatchOptions {
/**
* Set to [`FFF_WATCH_OPTIONS_VERSION`] when allocating.
*/
uint32_t version;
/**
* Per-subscription excludes (parcel-watcher style): entries with wildcards
* are base-relative globs, entries without are path prefixes. NULL when
* `ignore_count` is 0.
*/
const char *const *ignore;
uint32_t ignore_count;
} FffWatchOptions;
/**
* Create a new file finder instance (legacy 8-arg positional signature).
*
* @deprecated Use [`fff_create_instance_with`] (or [`fff_create_instance_with_value`]
* for FFI bindings). The `use_unsafe_no_lock` parameter is ignored.
*
* ## Safety
* See `fff_create_instance_with`.
*/
__attribute__((deprecated("Use fff_create_instance_with (by pointer) or fff_create_instance_with_value (by value) with FffCreateOptions instead. The struct evolves without ABI breaks.")))
struct FffResult *fff_create_instance(const char *base_path,
const char *frecency_db_path,
const char *history_db_path,
bool _use_unsafe_no_lock,
bool enable_mmap_cache,
bool enable_content_indexing,
bool watch,
bool ai_mode);
/**
* Create a new file finder instance (legacy 13-arg positional signature).
*
* @deprecated Use [`fff_create_instance_with`] (or [`fff_create_instance_with_value`]
* for FFI bindings). The `use_unsafe_no_lock` parameter is ignored.
*
* ## Safety
* See `fff_create_instance_with`.
*/
__attribute__((deprecated("Use fff_create_instance_with (by pointer) or fff_create_instance_with_value (by value) with FffCreateOptions instead. The struct evolves without ABI breaks.")))
struct FffResult *fff_create_instance2(const char *base_path,
const char *frecency_db_path,
const char *history_db_path,
bool _use_unsafe_no_lock,
bool enable_mmap_cache,
bool enable_content_indexing,
bool watch,
bool ai_mode,
const char *log_file_path,
const char *log_level,
uint64_t cache_budget_max_files,
uint64_t cache_budget_max_bytes,
uint64_t cache_budget_max_file_size);
/**
* Create a new file finder instance from a versioned [`FffCreateOptions`] struct.
*
* Populate the struct, set `version` to [`FFF_CREATE_OPTIONS_VERSION`], pass by
* pointer. New fields are only appended; older `version` values keep working.
* FFI bindings needing struct-by-value should use [`fff_create_instance_with_value`].
*
* `opts.base_path` is required (non-NULL, non-empty). Zero `cache_budget_*`
* values are auto-computed from repo size after the initial scan.
*
* ## Safety
* * `opts` must be a valid pointer to an `FffCreateOptions` whose `version`
* is in the range `1..=FFF_CREATE_OPTIONS_VERSION`.
* * All string pointers inside `opts` must be valid null-terminated UTF-8
* or NULL.
*/
struct FffResult *fff_create_instance_with(const struct FffCreateOptions *opts);
/**
* [`fff_create_instance_with`] adapter taking [`FffCreateOptions`] **by value**,
* for FFI libraries that pass native structs by value (e.g. Node's `ffi-rs`).
*
* ## Safety
* All `*const c_char` fields inside `opts` must be valid null-terminated
* UTF-8 or NULL. The struct itself is consumed by value.
*/
struct FffResult *fff_create_instance_with_value(struct FffCreateOptions opts);
/**
* Destroy a file finder instance and free all its resources.
*
* ## Safety
* `fff_handle` must be a valid pointer returned by `fff_create_instance`, or null (no-op).
*/
void fff_destroy(void *fff_handle);
/**
* Perform fuzzy search on indexed files.
*
* `current_file` deprioritizes the currently open file (NULL/empty to skip).
* Zero picks the default: `max_threads` auto, `page_size` 100,
* `combo_boost_multiplier` 100, `min_combo_count` 3.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `query` and `current_file` must be valid null-terminated UTF-8 strings or NULL.
*/
struct FffResult *fff_search(void *fff_handle,
const char *query,
const char *current_file,
uint32_t max_threads,
uint32_t page_index,
uint32_t page_size,
int32_t combo_boost_multiplier,
uint32_t min_combo_count);
/**
* Glob-only search: filter indexed files by a single glob pattern (passed
* through verbatim, no query parsing), rank by frecency, and paginate.
*
* `current_file` deprioritizes the currently open file (NULL/empty to skip).
* Zero picks the default: `max_threads` auto, `page_size` 100.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `pattern` and `current_file` must be valid null-terminated UTF-8 strings or NULL.
*/
struct FffResult *fff_glob(void *fff_handle,
const char *pattern,
const char *current_file,
uint32_t max_threads,
uint32_t page_index,
uint32_t page_size);
/**
* Perform fuzzy search on indexed directories.
*
* `current_file` is used for distance scoring (NULL/empty to skip).
* Zero picks the default: `max_threads` auto, `page_size` 100.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `query` and `current_file` must be valid null-terminated UTF-8 strings or NULL.
*/
struct FffResult *fff_search_directories(void *fff_handle,
const char *query,
const char *current_file,
uint32_t max_threads,
uint32_t page_index,
uint32_t page_size);
/**
* Perform a mixed fuzzy search across both files and directories.
*
* Returns one flat list interleaved by descending total score; each item's
* `item_type` is 0 = file, 1 = directory. Parameters as in [`fff_search`].
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `query` and `current_file` must be valid null-terminated UTF-8 strings or NULL.
*/
struct FffResult *fff_search_mixed(void *fff_handle,
const char *query,
const char *current_file,
uint32_t max_threads,
uint32_t page_index,
uint32_t page_size,
int32_t combo_boost_multiplier,
uint32_t min_combo_count);
/**
* Perform content search (grep) across indexed files.
*
* `query` supports constraint syntax like `*.rs pattern`; `mode` is
* 0 = plain text (SIMD), 1 = regex, 2 = fuzzy. Zero picks the default:
* `max_file_size` 10 MB, `page_limit` 50, `max_matches_per_file` and
* `time_budget_ms` unlimited. `smart_case` is case-insensitive for
* all-lowercase queries; `classify_definitions` tags code definitions.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `query` must be a valid null-terminated UTF-8 string.
*/
struct FffResult *fff_live_grep(void *fff_handle,
const char *query,
uint8_t mode,
uint64_t max_file_size,
uint32_t max_matches_per_file,
bool smart_case,
uint32_t file_offset,
uint32_t page_limit,
uint64_t time_budget_ms,
uint32_t before_context,
uint32_t after_context,
bool classify_definitions);
/**
* Multi-pattern OR search (SIMD Aho-Corasick): lines matching ANY pattern.
*
* `patterns_joined` is `\n`-separated (e.g. `"foo\nbar"`); `constraints` is an
* optional file filter like `"*.rs"` or `"/src/"` (NULL/empty to skip).
* Remaining parameters as in [`fff_live_grep`].
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `patterns_joined` and `constraints` must be valid null-terminated UTF-8 or NULL.
*/
struct FffResult *fff_multi_grep(void *fff_handle,
const char *patterns_joined,
const char *constraints,
uint64_t max_file_size,
uint32_t max_matches_per_file,
bool smart_case,
uint32_t file_offset,
uint32_t page_limit,
uint64_t time_budget_ms,
uint32_t before_context,
uint32_t after_context,
bool classify_definitions);
/**
* Trigger a rescan of the file index.
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
struct FffResult *fff_scan_files(void *fff_handle);
/**
* Check if a scan is currently in progress.
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
bool fff_is_scanning(void *fff_handle);
/**
* Get the picker's base path as a heap C string in `handle`;
* free it with `fff_free_string`.
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
struct FffResult *fff_get_base_path(void *fff_handle);
/**
* Get scan progress information.
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
struct FffResult *fff_get_scan_progress(void *fff_handle);
/**
* Wait for initial scan to complete.
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
struct FffResult *fff_wait_for_scan(void *fff_handle, uint64_t timeout_ms);
/**
* Wait for the background file watcher to be ready.
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
struct FffResult *fff_wait_for_watcher(void *fff_handle, uint64_t timeout_ms);
/**
* Restart indexing in a new directory.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `new_path` must be a valid null-terminated UTF-8 string.
*/
struct FffResult *fff_restart_index(void *fff_handle, const char *new_path);
/**
* Refresh git status cache.
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
struct FffResult *fff_refresh_git_status(void *fff_handle);
/**
* Track query completion for smart suggestions.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `query` and `file_path` must be valid null-terminated UTF-8 strings.
*/
struct FffResult *fff_track_query(void *fff_handle, const char *query, const char *file_path);
/**
* Get historical query by offset (0 = most recent).
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
struct FffResult *fff_get_historical_query(void *fff_handle, uint64_t offset);
/**
* Get health check information.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`, or null for
* a limited health check (version + git only).
* * `test_path` can be null or a valid null-terminated UTF-8 string.
*/
struct FffResult *fff_health_check(void *fff_handle, const char *test_path);
/**
* Free a search result returned by `fff_search`: the struct, its `items`
* and `scores` arrays, and every string within.
*
* ## Safety
* `result` must be a valid pointer previously returned via `FffResult.handle`
* from `fff_search`, or null (no-op).
*/
void fff_free_search_result(struct FffSearchResult *result);
/**
* Pointer to the `index`-th `FffFileItem`; null if `result` is null or
* `index >= count`. Valid until the search result is freed.
*
* ## Safety
* `result` must be a valid `FffSearchResult` pointer from `fff_search`.
*/
const struct FffFileItem *fff_search_result_get_item(const struct FffSearchResult *result,
uint32_t index);
/**
* Pointer to the `index`-th `FffScore`; null if `result` is null or
* `index >= count`. Valid until the search result is freed.
*
* ## Safety
* `result` must be a valid `FffSearchResult` pointer from `fff_search`.
*/
const struct FffScore *fff_search_result_get_score(const struct FffSearchResult *result,
uint32_t index);
/**
* Free a grep result returned by `fff_live_grep` or `fff_multi_grep`:
* the struct, its `items` array, and all strings/ranges/context within.
*
* ## Safety
* `result` must be a valid pointer previously returned via `FffResult.handle`
* from `fff_live_grep` or `fff_multi_grep`, or null (no-op).
*/
void fff_free_grep_result(struct FffGrepResult *result);
/**
* Pointer to the `index`-th `FffGrepMatch`; null if `result` is null or
* `index >= count`. Valid until the grep result is freed.
*
* ## Safety
* `result` must be a valid `FffGrepResult` pointer from `fff_live_grep` or `fff_multi_grep`.
*/
const struct FffGrepMatch *fff_grep_result_get_match(const struct FffGrepResult *result,
uint32_t index);
/**
* Free a scan progress result returned by `fff_get_scan_progress`.
*
* ## Safety
* `result` must be a valid pointer previously returned via `FffResult.handle`
* from `fff_get_scan_progress`, or null (no-op).
*/
void fff_free_scan_progress(struct FffScanProgress *result);
/**
* Offset a pointer by `byte_offset` bytes (FFI array iteration helper).
* Returns null if `base` is null.
*
* ## Safety
* The resulting pointer must be within the bounds of the original allocation.
*/
const void *fff_ptr_offset(const void *base, uintptr_t byte_offset);
/**
* Free a result envelope returned by any `fff_*` function.
* **IMPORTANT:** the `handle` payload is NOT freed release it separately
* using handle specific cleaning methods (`fff_destroy`, `fff_free_search_result`, etc.).
*
* ## Safety
* `result_ptr` must be a valid pointer returned by a `fff_*` function.
*/
void fff_free_result(struct FffResult *result_ptr);
/**
* Free a string returned by `fff_*` functions.
*
* ## Safety
* `s` must be a valid C string allocated by this library.
*/
void fff_free_string(char *s);
/**
* Free a directory search result returned by `fff_search_directories`.
*
* ## Safety
* `result` must be a valid pointer previously returned via `FffResult.handle`
* from `fff_search_directories`, or null (no-op).
*/
void fff_free_dir_search_result(struct FffDirSearchResult *result);
/**
* Get a pointer to the `index`-th `FffDirItem` in a directory search result.
*
* ## Safety
* `result` must be a valid `FffDirSearchResult` pointer from `fff_search_directories`.
*/
const struct FffDirItem *fff_dir_search_result_get_item(const struct FffDirSearchResult *result,
uint32_t index);
/**
* Get a pointer to the `index`-th `FffScore` in a directory search result.
*
* ## Safety
* `result` must be a valid `FffDirSearchResult` pointer from `fff_search_directories`.
*/
const struct FffScore *fff_dir_search_result_get_score(const struct FffDirSearchResult *result,
uint32_t index);
/**
* Free a mixed search result returned by `fff_search_mixed`.
*
* ## Safety
* `result` must be a valid pointer previously returned via `FffResult.handle`
* from `fff_search_mixed`, or null (no-op).
*/
void fff_free_mixed_search_result(struct FffMixedSearchResult *result);
/**
* Get a pointer to the `index`-th `FffMixedItem` in a mixed search result.
*
* ## Safety
* `result` must be a valid `FffMixedSearchResult` pointer from `fff_search_mixed`.
*/
const struct FffMixedItem *fff_mixed_search_result_get_item(const struct FffMixedSearchResult *result,
uint32_t index);
/**
* Get a pointer to the `index`-th `FffScore` in a mixed search result.
*
* ## Safety
* `result` must be a valid `FffMixedSearchResult` pointer from `fff_search_mixed`.
*/
const struct FffScore *fff_mixed_search_result_get_score(const struct FffMixedSearchResult *result,
uint32_t index);
/**
* Returns whether the operation completed successfully. Returns `false` if `result` is null.
*
* ## Safety
* `result` must be a valid `FffResult` pointer or null.
*/
bool fff_result_get_success(const struct FffResult *result);
/**
* Returns the operation error message, or null when there is no error or `result` is null.
*
* Do not free the returned pointer. It remains valid until `fff_free_result` is called.
*
* ## Safety
* `result` must be a valid `FffResult` pointer or null.
*/
const char *fff_result_get_error(const struct FffResult *result);
/**
* Returns the result payload handle, or null if `result` is null.
*
* ## Safety
* `result` must be a valid `FffResult` pointer or null.
*/
void *fff_result_get_handle(const struct FffResult *result);
/**
* Returns the result integer payload. Returns `0` if `result` is null.
*
* ## Safety
* `result` must be a valid `FffResult` pointer or null.
*/
int64_t fff_result_get_int_value(const struct FffResult *result);
/**
* Relative path of a file item (e.g. `"src/main.rs"`); null if `item` is null. Do not free.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
const char *fff_file_item_get_relative_path(const struct FffFileItem *item);
/**
* File-name component of a file item (e.g. `"main.rs"`); null if `item` is null. Do not free.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
const char *fff_file_item_get_file_name(const struct FffFileItem *item);
/**
* Git status string of a file item (e.g. `"M "`, `"??"`); null if git is unavailable,
* the file is untracked, or `item` is null. Do not free.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
const char *fff_file_item_get_git_status(const struct FffFileItem *item);
/**
* File size in bytes; `0` if `item` is null.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
uint64_t fff_file_item_get_size(const struct FffFileItem *item);
/**
* Last-modified time as seconds since the UNIX epoch; `0` if `item` is null.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
uint64_t fff_file_item_get_modified(const struct FffFileItem *item);
/**
* Combined frecency score; `0` if `item` is null.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
int64_t fff_file_item_get_total_frecency_score(const struct FffFileItem *item);
/**
* Access-based frecency score; `0` if `item` is null.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
int64_t fff_file_item_get_access_frecency_score(const struct FffFileItem *item);
/**
* Modification-based frecency score; `0` if `item` is null.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
int64_t fff_file_item_get_modification_frecency_score(const struct FffFileItem *item);
/**
* `true` if the file was detected as binary; `false` if `item` is null.
*
* ## Safety
* `item` must be a valid `FffFileItem` pointer or null.
*/
bool fff_file_item_get_is_binary(const struct FffFileItem *item);
/**
* Relative path of the file containing this grep match; null if `m` is null. Do not free.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
const char *fff_grep_match_get_relative_path(const struct FffGrepMatch *m);
/**
* File-name component of the file containing this grep match; null if `m` is null. Do not free.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
const char *fff_grep_match_get_file_name(const struct FffGrepMatch *m);
/**
* Git status string of the matched file (e.g. `"M "`, `"??"`); null if git is unavailable,
* the file is untracked, or `m` is null. Do not free.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
const char *fff_grep_match_get_git_status(const struct FffGrepMatch *m);
/**
* Full text content of the matched line; null if `m` is null. Do not free.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
const char *fff_grep_match_get_line_content(const struct FffGrepMatch *m);
/**
* 1-based line number of the match within its file; `0` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint64_t fff_grep_match_get_line_number(const struct FffGrepMatch *m);
/**
* 0-based column of the match start within its line; `0` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint32_t fff_grep_match_get_col(const struct FffGrepMatch *m);
/**
* Byte offset of the match start from the beginning of the file; `0` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint64_t fff_grep_match_get_byte_offset(const struct FffGrepMatch *m);
/**
* File size in bytes of the matched file; `0` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint64_t fff_grep_match_get_size(const struct FffGrepMatch *m);
/**
* Combined frecency score of the matched file; `0` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
int64_t fff_grep_match_get_total_frecency_score(const struct FffGrepMatch *m);
/**
* Access-based frecency score of the matched file; `0` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
int64_t fff_grep_match_get_access_frecency_score(const struct FffGrepMatch *m);
/**
* Modification-based frecency score of the matched file; `0` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
int64_t fff_grep_match_get_modification_frecency_score(const struct FffGrepMatch *m);
/**
* Last-modified time of the matched file as seconds since the UNIX epoch; `0` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint64_t fff_grep_match_get_modified(const struct FffGrepMatch *m);
/**
* Number of highlight ranges in this match; `0` if `m` is null.
* Use with [`fff_grep_match_get_match_range`] to iterate the highlight spans.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint32_t fff_grep_match_get_match_ranges_count(const struct FffGrepMatch *m);
/**
* Pointer to the `index`-th [`FffMatchRange`] highlight span; null if `m` is null,
* `index >= match_ranges_count`, or the ranges array is null. Valid until the owning `FffGrepResult` is freed; do not free.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
const struct FffMatchRange *fff_grep_match_get_match_range(const struct FffGrepMatch *m,
uint32_t index);
/**
* Number of context lines captured before the match; `0` if `m` is null.
* Use with [`fff_grep_match_get_context_before`] to read each line.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint32_t fff_grep_match_get_context_before_count(const struct FffGrepMatch *m);
/**
* The `index`-th context line before the match; null if `m` is null,
* `index >= context_before_count`, or the context array is null. Do not free.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
const char *fff_grep_match_get_context_before(const struct FffGrepMatch *m, uint32_t index);
/**
* Number of context lines captured after the match; `0` if `m` is null.
* Use with [`fff_grep_match_get_context_after`] to read each line.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint32_t fff_grep_match_get_context_after_count(const struct FffGrepMatch *m);
/**
* The `index`-th context line after the match; null if `m` is null,
* `index >= context_after_count`, or the context array is null. Do not free.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
const char *fff_grep_match_get_context_after(const struct FffGrepMatch *m, uint32_t index);
/**
* Fuzzy match score; `0` if `m` is null or no fuzzy score is present.
* Always check [`fff_grep_match_get_has_fuzzy_score`] first; `0` is ambiguous without that flag.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
uint16_t fff_grep_match_get_fuzzy_score(const struct FffGrepMatch *m);
/**
* `true` if this match carries a valid fuzzy score; `false` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
bool fff_grep_match_get_has_fuzzy_score(const struct FffGrepMatch *m);
/**
* `true` if the match was identified as a symbol definition; `false` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
bool fff_grep_match_get_is_definition(const struct FffGrepMatch *m);
/**
* `true` if the matched file was detected as binary; `false` if `m` is null.
*
* ## Safety
* `m` must be a valid `FffGrepMatch` pointer or null.
*/
bool fff_grep_match_get_is_binary(const struct FffGrepMatch *m);
/**
* Number of items in the result; `0` if `r` is null.
*
* ## Safety
* `r` must be a valid `FffSearchResult` pointer or null.
*/
uint32_t fff_search_result_get_count(const struct FffSearchResult *r);
/**
* Total number of files that matched before truncation to the page size; `0` if `r` is null.
*
* ## Safety
* `r` must be a valid `FffSearchResult` pointer or null.
*/
uint32_t fff_search_result_get_total_matched(const struct FffSearchResult *r);
/**
* Total number of indexed files considered during search; `0` if `r` is null.
*
* ## Safety
* `r` must be a valid `FffSearchResult` pointer or null.
*/
uint32_t fff_search_result_get_total_files(const struct FffSearchResult *r);
/**
* Number of matches in the result; `0` if `r` is null.
*
* ## Safety
* `r` must be a valid `FffGrepResult` pointer or null.
*/
uint32_t fff_grep_result_get_count(const struct FffGrepResult *r);
/**
* Total number of matches found across all pages; `0` if `r` is null.
*
* ## Safety
* `r` must be a valid `FffGrepResult` pointer or null.
*/
uint32_t fff_grep_result_get_total_matched(const struct FffGrepResult *r);
/**
* Number of files actually opened and searched in this call; `0` if `r` is null.
*
* ## Safety
* `r` must be a valid `FffGrepResult` pointer or null.
*/
uint32_t fff_grep_result_get_total_files_searched(const struct FffGrepResult *r);
/**
* Total number of indexed files before any filtering; `0` if `r` is null.
*
* ## Safety
* `r` must be a valid `FffGrepResult` pointer or null.
*/
uint32_t fff_grep_result_get_total_files(const struct FffGrepResult *r);
/**
* Number of files eligible for search after path/type filtering; `0` if `r` is null.
*
* ## Safety
* `r` must be a valid `FffGrepResult` pointer or null.
*/
uint32_t fff_grep_result_get_filtered_file_count(const struct FffGrepResult *r);
/**
* File offset for the next page; `0` if all files have been searched or `r` is null.
* Pass as `file_offset` to a subsequent `fff_live_grep`/`fff_multi_grep` call to continue pagination.
*
* ## Safety
* `r` must be a valid `FffGrepResult` pointer or null.
*/
uint32_t fff_grep_result_get_next_file_offset(const struct FffGrepResult *r);
/**
* Regex compilation error string if the engine fell back to literal matching;
* null if there was no error or `r` is null. Do not free.
*
* ## Safety
* `r` must be a valid `FffGrepResult` pointer or null.
*/
const char *fff_grep_result_get_regex_fallback_error(const struct FffGrepResult *r);
/**
* Register the instance-wide watch callback used by all `fff_watch`
* subscriptions; call before the first `fff_watch`, calling again replaces it.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `callback` must remain callable until fff_unwatch called
* `fff_destroy(fff_handle)` returns.
*/
struct FffResult *fff_set_watch_callback(void *fff_handle,
FffWatchCallback callback,
void *user_data);
/**
* Subscribe to filesystem changes, delivered through the instance callback
* registered by `fff_set_watch_callback`.
*
* Returns the watch id, pass it to `fff_unwatch` to stop.
*
* `pattern` if non `NULL` can be wildcard pattern, absolute, or relative path
* that will be used to filter the events triggering exact subscription.
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `pattern` must be NULL or valid null-terminated UTF-8.
* * `opts` must be NULL or a valid `FffWatchOptions` pointer.
*/
struct FffResult *fff_watch(void *fff_handle,
const char *pattern,
const struct FffWatchOptions *opts);
/**
* [`fff_watch`] adapter with flattened options, for FFI libraries that cannot
* marshal pointer arrays inside structs (e.g. Node's `ffi-rs`).
*
* ## Safety
* * `fff_handle` must be a valid instance pointer from `fff_create_instance`.
* * `pattern` must be NULL (watch everything) or valid null-terminated UTF-8.
* * `ignore` must be NULL or point to `ignore_count` valid C strings.
*/
struct FffResult *fff_watch_args(void *fff_handle,
const char *pattern,
const char *const *ignore,
uint32_t ignore_count);
/**
* Remove a watch subscription. `int_value` = 1 if the id existed, 0 otherwise.
*
* ## Safety
* `fff_handle` must be a valid instance pointer from `fff_create_instance`.
*/
struct FffResult *fff_unwatch(void *fff_handle, uint64_t watch_id);
/**
* Number of events in a batch; 0 if `batch` is null.
*
* ## Safety
* `batch` must be a valid `FffWatchEventBatch` pointer or null.
*/
uint32_t fff_watch_events_count(const struct FffWatchEventBatch *batch);
/**
* Absolute path of event `index`, will be null when out of bounds
*
* ## Safety
* `batch` must be a valid `FffWatchEventBatch` pointer or null.
*/
const char *fff_watch_events_get_path(const struct FffWatchEventBatch *batch, uint32_t index);
/**
* Kind of event `index` (0 = created, 1 = modified, 2 = removed, 3 = rescan)
* 3 (rescan aka "re-stat something" kind) returned when OS based buffer
* has been overflown and some events might be loss. Paths will contain a list of
* directories that needs to be rescanned to ensure consistency.
*
* ## Safety
* `batch` must be a valid `FffWatchEventBatch` pointer or null.
*/
uint8_t fff_watch_events_get_kind(const struct FffWatchEventBatch *batch, uint32_t index);
/**
* Free a watch event batch delivered to the instance callback.
*
* ## Safety
* `batch` must be a pointer produced by this library, or null (no-op).
*/
void fff_free_watch_events(struct FffWatchEventBatch *batch);
#endif /* FFF_C_H */