add workspace grep engine + search.grep/cancel, editor.open --line
The pure-Dart content-search engine behind find-in-files (D-79): walks the ignore-pruned workspace, fans files across worker isolates (Isolate.run) for parallelism, matches each line with a literal indexOf fast-path or a RegExp, and streams match batches with cooperative cancellation. No ripgrep dependency; the search.grep IPC contract is engine-agnostic so an rg accelerator can slot in later. search.grep returns a searchId and streams search.match / search.done (or search.error) events, mirroring files.watch; search.cancel stops an in-flight search. The service reuses the files service's resolved ignore set so both honour the same ignore_files: layering. editor.open gains an optional 1-based line argument: it converts the line to a byte offset and sets the initial selection, enabling click-to-line from search results. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,28 @@ void main() {
|
||||
expect(act['path'], 'doc.md');
|
||||
});
|
||||
|
||||
test('editor.open with a 1-based line jumps the initial selection (T-52)', () async {
|
||||
await File('${sandbox.path}/multi.txt').writeAsString('one\ntwo\nthree\n');
|
||||
final r = await call('editor.open', {'path': 'multi.txt', 'line': 3});
|
||||
expect(r.ok, isTrue);
|
||||
final sel = r.data['selection'] as Map;
|
||||
// Line 3 starts after 'one\n' + 'two\n' = 8 characters.
|
||||
expect(sel['start'], 8);
|
||||
expect(sel['end'], 8);
|
||||
});
|
||||
|
||||
test('editor.open without a line opens at the top', () async {
|
||||
await File('${sandbox.path}/multi.txt').writeAsString('one\ntwo\n');
|
||||
final r = await call('editor.open', {'path': 'multi.txt'});
|
||||
expect((r.data['selection'] as Map)['start'], 0);
|
||||
});
|
||||
|
||||
test('editor.open with an out-of-range line clamps to the content end', () async {
|
||||
await File('${sandbox.path}/multi.txt').writeAsString('one\ntwo\n'); // 8 chars
|
||||
final r = await call('editor.open', {'path': 'multi.txt', 'line': 999});
|
||||
expect((r.data['selection'] as Map)['start'], 8);
|
||||
});
|
||||
|
||||
test('editor.insert without id targets the active buffer', () async {
|
||||
await call('editor.open', {'path': 'doc.md'});
|
||||
final r = await call('editor.insert', {'text': 'X '});
|
||||
|
||||
Reference in New Issue
Block a user