-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathisearch.c
93 lines (79 loc) · 2.94 KB
/
isearch.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "isearch.h"
#include "edit.h"
#include <ctype.h>
ISearch isearch = {0};
// TODO It should show in Red the ending substring that doesn't match
// Like 'isearch' does in emacs
void isearch_forward(Buffer *buffer, BufferManager *bm, Buffer *minibuffer, bool updateStartIndex) {
const char *start = buffer->content + isearch.startIndex;
const char *found = strstr(start, minibuffer->content);
if (found) {
size_t matchIndex = found - buffer->content;
buffer->point = matchIndex + strlen(minibuffer->content);
isearch.lastMatchIndex = matchIndex + 1;
if (updateStartIndex) {
isearch.startIndex = buffer->point;
}
isearch.wrap = false;
} else {
if (!isearch.wrap) {
message(bm, "Reached end of buffer");
isearch.wrap = true;
} else {
if (updateStartIndex) {
isearch.startIndex = 0;
isearch.wrap = false;
isearch_forward(buffer, bm, minibuffer, false);
}
}
}
}
void isearch_backward(Buffer *buffer, Buffer *minibuffer, bool updateStartIndex) {
if (isearch.lastMatchIndex == 0 || isearch.lastMatchIndex > buffer->size) {
// No previous match or out of bounds, start from end of buffer
isearch.lastMatchIndex = buffer->size;
}
char *searchEnd = buffer->content + isearch.lastMatchIndex - 1;
char *found = NULL;
// Ensure we do not start a search from a negative index
if (searchEnd < buffer->content) {
searchEnd = buffer->content;
}
for (char *p = searchEnd; p >= buffer->content; --p) {
if (strncmp(p, minibuffer->content, strlen(minibuffer->content)) == 0) {
found = p;
break;
}
}
if (found) {
size_t matchIndex = found - buffer->content;
buffer->point = matchIndex;
if (updateStartIndex) {
isearch.lastMatchIndex = matchIndex; // Set for next potential search update
}
isearch.wrap = false;
} else {
if (!isearch.wrap) {
printf("Reached beginning of buffer. Press Ctrl+R again to wrap search.\n");
isearch.wrap = true;
} else {
if (updateStartIndex) {
isearch.lastMatchIndex = buffer->size; // Reset lastMatchIndex for wrapping
isearch.wrap = false;
isearch_backward(buffer, minibuffer, false); // Attempt to wrap around
}
}
}
}
void jumpLastOccurrence(Buffer *buffer, const char *word) {
int wordLength = strlen(word);
int startIndex = buffer->point - wordLength - 1; // start from the left of the current word
// Ensure the starting index does not go below 0
if (startIndex < 0) startIndex = 0;
for (int i = startIndex; i >= 0; i--) {
if (strncmp(buffer->content + i, word, wordLength) == 0) {
buffer->point = i + wordLength;
return;
}
}
}