const es = @import("root"); const std = @import("std"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; const Buffer = es.Buffer; const Editor = es.Editor; const Highlight = es.Highlight; const Key = es.Key; const CallbackData = struct { allocator: Allocator, last_match: usize, saved_hl: ?struct { line: usize, data: []Highlight, }, buffer: *Buffer, }; const Error = std.mem.Allocator.Error; pub fn search(editor: *Editor, buffer: *Buffer) !void { const saved_cx = buffer.cx; const saved_cy = buffer.cy; const saved_coloff = buffer.coloff; const saved_rowoff = buffer.rowoff; var data = CallbackData{ .allocator = editor.allocator, .last_match = buffer.cy, .saved_hl = null, .buffer = buffer, }; defer if (data.saved_hl) |saved_hl| { data.allocator.free(saved_hl.data); }; if (try editor.promptEx( *CallbackData, Error, editor.allocator, "Search", searchCallback, &data, )) |response| { editor.allocator.free(response); } else { // Cancelled buffer.cx = saved_cx; buffer.cy = saved_cy; buffer.coloff = saved_coloff; buffer.rowoff = saved_rowoff; } } fn searchCallback(editor: *Editor, query: []const u8, last_key: Key, data: *CallbackData) Error!void { _ = editor; if (data.saved_hl) |saved_hl| { const row = &data.buffer.rows.items[saved_hl.line]; row.hldata.shrinkRetainingCapacity(0); row.hldata.appendSliceAssumeCapacity(saved_hl.data); data.allocator.free(saved_hl.data); data.saved_hl = null; } if (last_key == Key.return_ or last_key == Key.ctrl('g')) { return; } if (last_key == Key.ctrl('s') and query.len != 0) { data.last_match += 1; } var i: usize = 0; while (i < data.buffer.rows.items.len) : (i += 1) { const idx = (data.last_match + i) % data.buffer.rows.items.len; const row = &data.buffer.rows.items[idx]; if (std.mem.indexOf(u8, row.rdata.items, query)) |match| { data.last_match = idx; data.buffer.cy = idx; data.buffer.cx = row.rxToCx(data.buffer.config, match); data.saved_hl = .{ .line = idx, .data = try data.allocator.dupe(Highlight, row.hldata.items), }; var j: usize = 0; while (j < query.len) : (j += 1) { row.hldata.items[match + j] = .match; } return; } } }