Search case sensitive and word boundary
This commit is contained in:
@@ -206,26 +206,54 @@ API String NormalizePath(Allocator allocator, String s) {
|
||||
|
||||
API bool Seek(String string, String find, int64_t *index_out, SeekFlag flags) {
|
||||
bool ignore_case = flags & SeekFlag_IgnoreCase ? true : false;
|
||||
bool result = false;
|
||||
bool result = false;
|
||||
if (flags & SeekFlag_MatchFindLast) {
|
||||
for (int64_t i = string.len; i != 0; i--) {
|
||||
int64_t index = i - 1;
|
||||
String substring = GetSlice(string, index, index + find.len);
|
||||
int64_t index = i - 1;
|
||||
String substring = GetSlice(string, index, index + find.len);
|
||||
if (AreEqual(substring, find, ignore_case)) {
|
||||
if (index_out)
|
||||
*index_out = index;
|
||||
result = true;
|
||||
break;
|
||||
bool ok_boundary = true;
|
||||
if (flags & SeekFlag_WordBoundary) {
|
||||
String left = GetSlice(string, i - 1, i);
|
||||
String right = GetSlice(string, i + find.len, i + find.len + 1);
|
||||
if (left.len != 0 && !IsNonWord(left.data[0])) {
|
||||
ok_boundary = false;
|
||||
}
|
||||
if (right.len != 0 && !IsNonWord(right.data[0])) {
|
||||
ok_boundary = false;
|
||||
}
|
||||
}
|
||||
if (ok_boundary) {
|
||||
if (index_out) {
|
||||
*index_out = index;
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; i < string.len; i++) {
|
||||
String substring = GetSlice(string, i, i + find.len);
|
||||
if (AreEqual(substring, find, ignore_case)) {
|
||||
if (index_out)
|
||||
*index_out = i;
|
||||
result = true;
|
||||
break;
|
||||
bool ok_boundary = true;
|
||||
if (flags & SeekFlag_WordBoundary) {
|
||||
String left = GetSlice(string, i - 1, i);
|
||||
String right = GetSlice(string, i + find.len, i + find.len + 1);
|
||||
if (left.len != 0 && !IsNonWord(left.data[0])) {
|
||||
ok_boundary = false;
|
||||
}
|
||||
if (right.len != 0 && !IsNonWord(right.data[0])) {
|
||||
ok_boundary = false;
|
||||
}
|
||||
}
|
||||
if (ok_boundary) {
|
||||
if (index_out) {
|
||||
*index_out = i;
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ enum {
|
||||
SeekFlag_None = 0,
|
||||
SeekFlag_IgnoreCase = 1,
|
||||
SeekFlag_MatchFindLast = 2,
|
||||
SeekFlag_WordBoundary = 4,
|
||||
};
|
||||
API bool Seek(String string, String find, int64_t *index_out = NULL, SeekFlag flags = SeekFlag_None);
|
||||
|
||||
|
||||
@@ -216,26 +216,54 @@ API String16 NormalizePath(Allocator allocator, String16 s) {
|
||||
|
||||
API bool Seek(String16 string, String16 find, int64_t *index_out, SeekFlag flags) {
|
||||
bool ignore_case = flags & SeekFlag_IgnoreCase ? true : false;
|
||||
bool result = false;
|
||||
bool result = false;
|
||||
if (flags & SeekFlag_MatchFindLast) {
|
||||
for (int64_t i = string.len; i != 0; i--) {
|
||||
int64_t index = i - 1;
|
||||
String16 substring = GetSlice(string, index, index + find.len);
|
||||
int64_t index = i - 1;
|
||||
String16 substring = GetSlice(string, index, index + find.len);
|
||||
if (AreEqual(substring, find, ignore_case)) {
|
||||
if (index_out)
|
||||
*index_out = index;
|
||||
result = true;
|
||||
break;
|
||||
bool ok_boundary = true;
|
||||
if (flags & SeekFlag_WordBoundary) {
|
||||
String16 left = GetSlice(string, i - 1, i);
|
||||
String16 right = GetSlice(string, i + find.len, i + find.len + 1);
|
||||
if (left.len != 0 && !IsNonWord(left.data[0])) {
|
||||
ok_boundary = false;
|
||||
}
|
||||
if (right.len != 0 && !IsNonWord(right.data[0])) {
|
||||
ok_boundary = false;
|
||||
}
|
||||
}
|
||||
if (ok_boundary) {
|
||||
if (index_out) {
|
||||
*index_out = index;
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; i < string.len; i++) {
|
||||
String16 substring = GetSlice(string, i, i + find.len);
|
||||
if (AreEqual(substring, find, ignore_case)) {
|
||||
if (index_out)
|
||||
*index_out = i;
|
||||
result = true;
|
||||
break;
|
||||
bool ok_boundary = true;
|
||||
if (flags & SeekFlag_WordBoundary) {
|
||||
String16 left = GetSlice(string, i - 1, i);
|
||||
String16 right = GetSlice(string, i + find.len, i + find.len + 1);
|
||||
if (left.len != 0 && !IsNonWord(left.data[0])) {
|
||||
ok_boundary = false;
|
||||
}
|
||||
if (right.len != 0 && !IsNonWord(right.data[0])) {
|
||||
ok_boundary = false;
|
||||
}
|
||||
}
|
||||
if (ok_boundary) {
|
||||
if (index_out) {
|
||||
*index_out = i;
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ bool Testing = false;
|
||||
bool AppIsRunning = true;
|
||||
bool WaitForEvents = true;
|
||||
bool RunGCThisFrame;
|
||||
bool SearchCaseSensitive = false;
|
||||
bool SearchWordBoundary = false;
|
||||
|
||||
WindowID WindowIDs;
|
||||
ViewID ViewIDs;
|
||||
|
||||
@@ -124,16 +124,20 @@ void IdentedNewLine(View *view) {
|
||||
}
|
||||
|
||||
Caret FindPrev(Buffer *buffer, String16 needle, Caret caret) {
|
||||
Int pos = GetFront(caret);
|
||||
Int pos = GetFront(caret);
|
||||
String16 medium = GetString(buffer, {0, pos});
|
||||
SeekFlag flag = SearchCaseSensitive ? SeekFlag_None : SeekFlag_IgnoreCase;
|
||||
if (SearchWordBoundary) {
|
||||
flag |= SeekFlag_WordBoundary;
|
||||
}
|
||||
|
||||
Caret result = caret;
|
||||
Int index = 0;
|
||||
if (Seek(medium, needle, &index, SeekFlag_MatchFindLast)) {
|
||||
if (Seek(medium, needle, &index, flag | SeekFlag_MatchFindLast)) {
|
||||
result = MakeCaret(index, index + needle.len);
|
||||
} else {
|
||||
medium = GetString(buffer);
|
||||
if (Seek(medium, needle, &index, SeekFlag_MatchFindLast)) {
|
||||
if (Seek(medium, needle, &index, flag | SeekFlag_MatchFindLast)) {
|
||||
result = MakeCaret(index, index + needle.len);
|
||||
}
|
||||
}
|
||||
@@ -142,16 +146,20 @@ Caret FindPrev(Buffer *buffer, String16 needle, Caret caret) {
|
||||
}
|
||||
|
||||
Caret FindNext(Buffer *buffer, String16 needle, Caret caret) {
|
||||
Int pos = GetMax(caret);
|
||||
Int pos = GetMax(caret);
|
||||
String16 medium = GetString(buffer, {pos, INT64_MAX});
|
||||
SeekFlag flag = SearchCaseSensitive ? SeekFlag_None : SeekFlag_IgnoreCase;
|
||||
if (SearchWordBoundary) {
|
||||
flag |= SeekFlag_WordBoundary;
|
||||
}
|
||||
|
||||
Caret result = caret;
|
||||
Int index = 0;
|
||||
if (Seek(medium, needle, &index)) {
|
||||
if (Seek(medium, needle, &index, flag)) {
|
||||
result = MakeCaret(pos + index + needle.len, pos + index);
|
||||
} else {
|
||||
medium = GetString(buffer);
|
||||
if (Seek(medium, needle, &index)) {
|
||||
if (Seek(medium, needle, &index, flag)) {
|
||||
result = MakeCaret(index + needle.len, index);
|
||||
}
|
||||
}
|
||||
@@ -163,9 +171,13 @@ Array<Caret> FindAll(Allocator allocator, Buffer *buffer, String16 needle) {
|
||||
Array<Caret> result = {allocator};
|
||||
String16 string = GetString(buffer);
|
||||
String16 start = string;
|
||||
SeekFlag flag = SearchCaseSensitive ? SeekFlag_None : SeekFlag_IgnoreCase;
|
||||
if (SearchWordBoundary) {
|
||||
flag |= SeekFlag_WordBoundary;
|
||||
}
|
||||
for (;;) {
|
||||
Int index = 0;
|
||||
if (Seek(string, needle, &index)) {
|
||||
if (Seek(string, needle, &index, flag)) {
|
||||
Int back = index + (Int)(string.data - start.data);
|
||||
Int front = back + needle.len;
|
||||
Add(&result, MakeCaret(front, back));
|
||||
|
||||
@@ -100,7 +100,6 @@ void Command_SearchAll() {
|
||||
set.window->visible = false;
|
||||
} RegisterCommand(Command_SearchAll, "alt-f3");
|
||||
|
||||
|
||||
void Command_SearchAllInSearch() {
|
||||
if (ActiveWindowID != SearchWindowID) {
|
||||
return;
|
||||
@@ -110,6 +109,13 @@ void Command_SearchAllInSearch() {
|
||||
set.window->visible = false;
|
||||
} RegisterCommand(Command_SearchAllInSearch, "alt-enter");
|
||||
|
||||
void Command_ToggleCaseSensitiveSearch() {
|
||||
SearchCaseSensitive = !SearchCaseSensitive;
|
||||
} RegisterCommand(Command_ToggleCaseSensitiveSearch, "alt-c");
|
||||
|
||||
void Command_ToggleSearchWordBoundary() {
|
||||
SearchWordBoundary = !SearchWordBoundary;
|
||||
} RegisterCommand(Command_ToggleSearchWordBoundary, "alt-w");
|
||||
|
||||
void SearchWindowUpdate() {
|
||||
BSet active = GetBSet(ActiveWindowID);
|
||||
|
||||
@@ -81,10 +81,11 @@ void StatusWindowUpdate() {
|
||||
Array<Edit> edits = ReplaceEx(scratch, title.view, u" |");
|
||||
}
|
||||
|
||||
|
||||
// replace data up to separator with filename and stuff
|
||||
const char *reopen = main.buffer->changed_on_disk ? " :Reopen" : "";
|
||||
String s = Format(scratch, "# %S:%lld:%lld%s", main.buffer->name, (long long)xy.line + 1ll, (long long)xy.col + 1ll, reopen);
|
||||
const char *case_sens = SearchCaseSensitive ? " C" : "";
|
||||
const char *word_bound = SearchWordBoundary ? " W" : "";
|
||||
String s = Format(scratch, "# %S:%lld:%lld%s%s", main.buffer->name, (long long)xy.line + 1ll, (long long)xy.col + 1ll, case_sens, word_bound, reopen);
|
||||
For (ActiveProcesses) {
|
||||
if (it.view_id == main.view->id.id) {
|
||||
s = Format(scratch, "%S %lld :KillProcess", s, (long long)it.id);
|
||||
|
||||
Reference in New Issue
Block a user