summaryrefslogtreecommitdiff
path: root/src/search.zig
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2021-12-21 05:56:41 +0200
committerGravatar Uko Kokņevičs2021-12-21 05:56:41 +0200
commit2d2278364b6186c6cdf0f0497b0498431dfe7dd1 (patch)
tree8f2329afbc90817c855f5c5154a547a58a9458aa /src/search.zig
downloades-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.tar.gz
es-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.tar.xz
es-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.zip
Initial config
Diffstat (limited to 'src/search.zig')
-rw-r--r--src/search.zig94
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 @@
1const std = @import("std");
2
3const Allocator = std.mem.Allocator;
4const ArrayList = std.ArrayList;
5const Buffer = @import("Buffer.zig");
6const Editor = @import("Editor.zig");
7const Highlight = @import("highlight.zig").Highlight;
8const Key = @import("key.zig").Key;
9
10const 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
20const Error = std.mem.Allocator.Error;
21
22pub 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
50fn 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}