Fix GetWordEnd type of functions to make sure range.max is past the last index even on buffer end

This commit is contained in:
Krzosa Karol
2024-08-04 08:54:08 +02:00
parent 3f16888fe0
commit ffb38664b8
4 changed files with 37 additions and 5 deletions

View File

@@ -19,6 +19,7 @@ bool IsSymbol(wchar_t w) {
}
bool IsNonWord(wchar_t w) {
if (w == '_') return false;
bool result = IsSymbol(w) || IsWhitespace(w);
return result;
}

View File

@@ -251,8 +251,12 @@ Int GetWordStart(Buffer *buffer, Int pos) {
Int GetWordEnd(Buffer *buffer, Int pos) {
pos = Clamp(pos, (Int)0, buffer->len);
for (Int i = pos; i < buffer->len; i += 1) {
for (Int i = pos;; i += 1) {
pos = i;
// this is because buffer end terminates the loop
// too early and we cannot establish the proper range
// semantics - proper max is one past last index
if (!(i < buffer->len)) break;
if (!IsWord(buffer->str[i])) break;
}
return pos;
@@ -269,8 +273,12 @@ Int GetLoadWordStart(Buffer *buffer, Int pos) {
Int GetLoadWordEnd(Buffer *buffer, Int pos) {
pos = Clamp(pos, (Int)0, buffer->len);
for (Int i = pos; i < buffer->len; i += 1) {
for (Int i = pos;; i += 1) {
pos = i;
// this is because buffer end terminates the loop
// too early and we cannot establish the proper range
// semantics - proper max is one past last index
if (!(i < buffer->len)) break;
if (!IsLoadWord(buffer->str[i])) break;
}
return pos;
@@ -279,8 +287,12 @@ Int GetLoadWordEnd(Buffer *buffer, Int pos) {
Int GetNextWordEnd(Buffer *buffer, Int pos) {
pos = Clamp(pos, (Int)0, buffer->len);
wchar_t prev = 0;
for (Int i = pos; i < buffer->len; i += 1) {
for (Int i = pos;; i += 1) {
pos = i;
// this is because buffer end terminates the loop
// too early and we cannot establish the proper range
// semantics - proper max is one past last index
if (!(i < buffer->len)) break;
if ((prev && prev != buffer->str[i]) || IsWord(buffer->str[i])) {
break;
}
@@ -408,3 +420,18 @@ Int GetIndentAtPos(Buffer *buffer, Int pos) {
Int result = GetLineIndent(buffer, line);
return result;
}
Range EncloseScope(Buffer *buffer, Int pos, wchar_t open, wchar_t close) {
Range result = {pos, pos};
for (Int i = pos; i >= 0; i -= 1) {
if (buffer->str[i] == open) {
result.min = i;
}
}
for (Int i = pos; i < buffer->len; i += 1) {
if (buffer->str[i] == close) {
result.max = i + 1;
}
}
return result;
}

View File

@@ -641,8 +641,9 @@ void WindowCommand(Event event, Window *window, View *view) {
}
if (Ctrl(SDLK_W)) {
Int pos = view->carets[0].range.min;
view->carets[0] = MakeCaret(GetPrevWordStart(buffer, pos));
Int pos = view->carets[0].range.min;
Range range = EncloseScope(buffer, pos, L'{', L'}');
view->carets[0] = MakeCaret(range.max, range.min);
}
if (Ctrl(SDLK_R)) {

View File

@@ -2,6 +2,9 @@
- page up and down should also scroll and leave you in exactly same scroll
- I think the way sublime text and we display line highlights is confusing with multiple cursors (line highlight can be confused with selection)
- ctrl + q to open, alt + q to go back
- when switching to inactive window pass it the mouse click
- delete multiple spaces (based on indent size) on delete instead one by one
- switch to previous view (ctrl + tab)
- save location on open and allow for revert (buffer id? or buffer name? - buffer name can change, buffer id is harder to serialize, I guess if internal only then buffer id)
- we could rewrite kill lines with simpler commands - extend selection to encompass lines->replace