2025-06-28 15:04:23 -07:00
|
|
|
use codex_file_search::FileMatch;
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
use ratatui::buffer::Buffer;
|
|
|
|
|
use ratatui::layout::Rect;
|
|
|
|
|
use ratatui::prelude::Constraint;
|
|
|
|
|
use ratatui::style::Color;
|
2025-06-28 15:04:23 -07:00
|
|
|
use ratatui::style::Modifier;
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
use ratatui::style::Style;
|
2025-06-28 15:04:23 -07:00
|
|
|
use ratatui::text::Line;
|
|
|
|
|
use ratatui::text::Span;
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
use ratatui::widgets::Block;
|
|
|
|
|
use ratatui::widgets::BorderType;
|
|
|
|
|
use ratatui::widgets::Borders;
|
|
|
|
|
use ratatui::widgets::Cell;
|
|
|
|
|
use ratatui::widgets::Row;
|
|
|
|
|
use ratatui::widgets::Table;
|
|
|
|
|
use ratatui::widgets::Widget;
|
|
|
|
|
use ratatui::widgets::WidgetRef;
|
|
|
|
|
|
|
|
|
|
/// Maximum number of suggestions shown in the popup.
|
|
|
|
|
const MAX_RESULTS: usize = 8;
|
|
|
|
|
|
|
|
|
|
/// Visual state for the file-search popup.
|
|
|
|
|
pub(crate) struct FileSearchPopup {
|
|
|
|
|
/// Query corresponding to the `matches` currently shown.
|
|
|
|
|
display_query: String,
|
|
|
|
|
/// Latest query typed by the user. May differ from `display_query` when
|
|
|
|
|
/// a search is still in-flight.
|
|
|
|
|
pending_query: String,
|
|
|
|
|
/// When `true` we are still waiting for results for `pending_query`.
|
|
|
|
|
waiting: bool,
|
|
|
|
|
/// Cached matches; paths relative to the search dir.
|
2025-06-28 15:04:23 -07:00
|
|
|
matches: Vec<FileMatch>,
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
/// Currently selected index inside `matches` (if any).
|
|
|
|
|
selected_idx: Option<usize>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl FileSearchPopup {
|
|
|
|
|
pub(crate) fn new() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
display_query: String::new(),
|
|
|
|
|
pending_query: String::new(),
|
|
|
|
|
waiting: true,
|
|
|
|
|
matches: Vec::new(),
|
|
|
|
|
selected_idx: None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Update the query and reset state to *waiting*.
|
|
|
|
|
pub(crate) fn set_query(&mut self, query: &str) {
|
|
|
|
|
if query == self.pending_query {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Determine if current matches are still relevant.
|
|
|
|
|
let keep_existing = query.starts_with(&self.display_query);
|
|
|
|
|
|
|
|
|
|
self.pending_query.clear();
|
|
|
|
|
self.pending_query.push_str(query);
|
|
|
|
|
|
|
|
|
|
self.waiting = true; // waiting for new results
|
|
|
|
|
|
|
|
|
|
if !keep_existing {
|
|
|
|
|
self.matches.clear();
|
|
|
|
|
self.selected_idx = None;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Replace matches when a `FileSearchResult` arrives.
|
|
|
|
|
/// Replace matches. Only applied when `query` matches `pending_query`.
|
2025-06-28 15:04:23 -07:00
|
|
|
pub(crate) fn set_matches(&mut self, query: &str, matches: Vec<FileMatch>) {
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
if query != self.pending_query {
|
|
|
|
|
return; // stale
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.display_query = query.to_string();
|
|
|
|
|
self.matches = matches;
|
|
|
|
|
self.waiting = false;
|
|
|
|
|
self.selected_idx = if self.matches.is_empty() {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
Some(0)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Move selection cursor up.
|
|
|
|
|
pub(crate) fn move_up(&mut self) {
|
|
|
|
|
if let Some(idx) = self.selected_idx {
|
|
|
|
|
if idx > 0 {
|
|
|
|
|
self.selected_idx = Some(idx - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Move selection cursor down.
|
|
|
|
|
pub(crate) fn move_down(&mut self) {
|
|
|
|
|
if let Some(idx) = self.selected_idx {
|
|
|
|
|
if idx + 1 < self.matches.len() {
|
|
|
|
|
self.selected_idx = Some(idx + 1);
|
|
|
|
|
}
|
|
|
|
|
} else if !self.matches.is_empty() {
|
|
|
|
|
self.selected_idx = Some(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn selected_match(&self) -> Option<&str> {
|
|
|
|
|
self.selected_idx
|
|
|
|
|
.and_then(|idx| self.matches.get(idx))
|
2025-06-28 15:04:23 -07:00
|
|
|
.map(|file_match| file_match.path.as_str())
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Preferred height (rows) including border.
|
2025-07-30 17:06:55 -07:00
|
|
|
pub(crate) fn calculate_required_height(&self) -> u16 {
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
// Row count depends on whether we already have matches. If no matches
|
|
|
|
|
// yet (e.g. initial search or query with no results) reserve a single
|
|
|
|
|
// row so the popup is still visible. When matches are present we show
|
|
|
|
|
// up to MAX_RESULTS regardless of the waiting flag so the list
|
|
|
|
|
// remains stable while a newer search is in-flight.
|
2025-07-31 00:43:21 -07:00
|
|
|
|
|
|
|
|
self.matches.len().clamp(1, MAX_RESULTS) as u16
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl WidgetRef for &FileSearchPopup {
|
|
|
|
|
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
|
|
|
|
|
// Prepare rows.
|
|
|
|
|
let rows: Vec<Row> = if self.matches.is_empty() {
|
2025-07-31 00:43:21 -07:00
|
|
|
vec![Row::new(vec![
|
|
|
|
|
Cell::from(if self.waiting {
|
|
|
|
|
"(searching …)"
|
|
|
|
|
} else {
|
|
|
|
|
"no matches"
|
|
|
|
|
})
|
|
|
|
|
.style(Style::new().add_modifier(Modifier::ITALIC | Modifier::DIM)),
|
|
|
|
|
])]
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
} else {
|
|
|
|
|
self.matches
|
|
|
|
|
.iter()
|
|
|
|
|
.take(MAX_RESULTS)
|
|
|
|
|
.enumerate()
|
2025-06-28 15:04:23 -07:00
|
|
|
.map(|(i, file_match)| {
|
|
|
|
|
let FileMatch { path, indices, .. } = file_match;
|
|
|
|
|
let path = path.as_str();
|
|
|
|
|
#[allow(clippy::expect_used)]
|
|
|
|
|
let indices = indices.as_ref().expect("indices should be present");
|
|
|
|
|
|
|
|
|
|
// Build spans with bold on matching indices.
|
|
|
|
|
let mut idx_iter = indices.iter().peekable();
|
|
|
|
|
let mut spans: Vec<Span> = Vec::with_capacity(path.len());
|
|
|
|
|
|
|
|
|
|
for (char_idx, ch) in path.chars().enumerate() {
|
|
|
|
|
let mut style = Style::default();
|
|
|
|
|
if idx_iter
|
|
|
|
|
.peek()
|
|
|
|
|
.is_some_and(|next| **next == char_idx as u32)
|
|
|
|
|
{
|
|
|
|
|
idx_iter.next();
|
|
|
|
|
style = style.add_modifier(Modifier::BOLD);
|
|
|
|
|
}
|
|
|
|
|
spans.push(Span::styled(ch.to_string(), style));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create cell from the spans.
|
|
|
|
|
let mut cell = Cell::from(Line::from(spans));
|
|
|
|
|
|
|
|
|
|
// If selected, also paint yellow.
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
if Some(i) == self.selected_idx {
|
|
|
|
|
cell = cell.style(Style::default().fg(Color::Yellow));
|
|
|
|
|
}
|
2025-06-28 15:04:23 -07:00
|
|
|
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
Row::new(vec![cell])
|
|
|
|
|
})
|
|
|
|
|
.collect()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let table = Table::new(rows, vec![Constraint::Percentage(100)])
|
|
|
|
|
.block(
|
|
|
|
|
Block::default()
|
2025-07-31 00:43:21 -07:00
|
|
|
.borders(Borders::LEFT)
|
|
|
|
|
.border_type(BorderType::QuadrantOutside)
|
|
|
|
|
.border_style(Style::default().fg(Color::DarkGray)),
|
feat: add support for @ to do file search (#1401)
Introduces support for `@` to trigger a fuzzy-filename search in the
composer. Under the hood, this leverages
https://crates.io/crates/nucleo-matcher to do the fuzzy matching and
https://crates.io/crates/ignore to build up the list of file candidates
(so that it respects `.gitignore`).
For simplicity (at least for now), we do not do any caching between
searches like VS Code does for its file search:
https://github.com/microsoft/vscode/blob/1d89ed699b2e924d418c856318a3e12bca67ff3a/src/vs/workbench/services/search/node/rawSearchService.ts#L212-L218
Because we do not do any caching, I saw queries take up to three seconds
on large repositories with hundreds of thousands of files. To that end,
we do not perform searches synchronously on each keystroke, but instead
dispatch an event to do the search on a background thread that
asynchronously reports back to the UI when the results are available.
This is largely handled by the `FileSearchManager` introduced in this
PR, which also has logic for debouncing requests so there is at most one
search in flight at a time.
While we could potentially polish and tune this feature further, it may
already be overengineered for how it will be used, in practice, so we
can improve things going forward if it turns out that this is not "good
enough" in the wild.
Note this feature does not work like `@` in the TypeScript CLI, which
was more like directory-based tab completion. In the Rust CLI, `@`
triggers a full-repo fuzzy-filename search.
Fixes https://github.com/openai/codex/issues/1261.
2025-06-28 13:47:42 -07:00
|
|
|
)
|
|
|
|
|
.widths([Constraint::Percentage(100)]);
|
|
|
|
|
|
|
|
|
|
table.render(area, buf);
|
|
|
|
|
}
|
|
|
|
|
}
|