diff options
| author | 2021-12-21 05:56:41 +0200 | |
|---|---|---|
| committer | 2021-12-21 05:56:41 +0200 | |
| commit | 2d2278364b6186c6cdf0f0497b0498431dfe7dd1 (patch) | |
| tree | 8f2329afbc90817c855f5c5154a547a58a9458aa /src/search.zig | |
| download | es-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.tar.gz es-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.tar.xz es-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.zip | |
Initial config
Diffstat (limited to 'src/search.zig')
| -rw-r--r-- | src/search.zig | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/search.zig b/src/search.zig new file mode 100644 index 0000000..bc29813 --- /dev/null +++ b/src/search.zig | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | const Allocator = std.mem.Allocator; | ||
| 4 | const ArrayList = std.ArrayList; | ||
| 5 | const Buffer = @import("Buffer.zig"); | ||
| 6 | const Editor = @import("Editor.zig"); | ||
| 7 | const Highlight = @import("highlight.zig").Highlight; | ||
| 8 | const Key = @import("key.zig").Key; | ||
| 9 | |||
| 10 | const CallbackData = struct { | ||
| 11 | allocator: Allocator, | ||
| 12 | last_match: usize, | ||
| 13 | saved_hl: ?struct { | ||
| 14 | line: usize, | ||
| 15 | data: []Highlight, | ||
| 16 | }, | ||
| 17 | buffer: *Buffer, | ||
| 18 | }; | ||
| 19 | |||
| 20 | const Error = std.mem.Allocator.Error; | ||
| 21 | |||
| 22 | pub fn search(editor: *Editor, buffer: *Buffer) !void { | ||
| 23 | const saved_cx = buffer.cx; | ||
| 24 | const saved_cy = buffer.cy; | ||
| 25 | const saved_coloff = buffer.coloff; | ||
| 26 | const saved_rowoff = buffer.rowoff; | ||
| 27 | |||
| 28 | var data = CallbackData{ | ||
| 29 | .allocator = editor.allocator, | ||
| 30 | .last_match = buffer.cy, | ||
| 31 | .saved_hl = null, | ||
| 32 | .buffer = buffer, | ||
| 33 | }; | ||
| 34 | |||
| 35 | defer if (data.saved_hl) |saved_hl| { | ||
| 36 | data.allocator.free(saved_hl.data); | ||
| 37 | }; | ||
| 38 | |||
| 39 | if (try editor.promptEx(*CallbackData, Error, "Search", searchCallback, &data)) |response| { | ||
| 40 | editor.allocator.free(response); | ||
| 41 | } else { | ||
| 42 | // Cancelled | ||
| 43 | buffer.cx = saved_cx; | ||
| 44 | buffer.cy = saved_cy; | ||
| 45 | buffer.coloff = saved_coloff; | ||
| 46 | buffer.rowoff = saved_rowoff; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | fn searchCallback(editor: *Editor, query: []const u8, last_key: Key, data: *CallbackData) Error!void { | ||
| 51 | _ = editor; | ||
| 52 | |||
| 53 | if (data.saved_hl) |saved_hl| { | ||
| 54 | const row = &data.buffer.rows.items[saved_hl.line]; | ||
| 55 | row.hldata.shrinkRetainingCapacity(0); | ||
| 56 | row.hldata.appendSliceAssumeCapacity(saved_hl.data); | ||
| 57 | |||
| 58 | data.allocator.free(saved_hl.data); | ||
| 59 | data.saved_hl = null; | ||
| 60 | } | ||
| 61 | |||
| 62 | if (last_key == Key.return_ or last_key == Key.ctrl('g')) { | ||
| 63 | return; | ||
| 64 | } | ||
| 65 | |||
| 66 | if (last_key == Key.ctrl('s') and query.len != 0) { | ||
| 67 | data.last_match += 1; | ||
| 68 | } | ||
| 69 | |||
| 70 | var i: usize = 0; | ||
| 71 | while (i < data.buffer.rows.items.len) : (i += 1) { | ||
| 72 | const idx = (data.last_match + i) % data.buffer.rows.items.len; | ||
| 73 | |||
| 74 | const row = &data.buffer.rows.items[idx]; | ||
| 75 | if (std.mem.indexOf(u8, row.rdata.items, query)) |match| { | ||
| 76 | data.last_match = idx; | ||
| 77 | data.buffer.cy = idx; | ||
| 78 | data.buffer.cx = row.rxToCx(data.buffer.config, match); | ||
| 79 | // TODO: data.buffer.rowoff = data.buffer.rows.items.len; | ||
| 80 | |||
| 81 | data.saved_hl = .{ | ||
| 82 | .line = idx, | ||
| 83 | .data = try data.allocator.dupe(Highlight, row.hldata.items), | ||
| 84 | }; | ||
| 85 | |||
| 86 | var j: usize = 0; | ||
| 87 | while (j < query.len) : (j += 1) { | ||
| 88 | row.hldata.items[match + j] = .match; | ||
| 89 | } | ||
| 90 | |||
| 91 | return; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | } | ||