Fix GetWordEnd type of functions to make sure range.max is past the last index even on buffer end
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user