diff --git a/src/basic/string16.cpp b/src/basic/string16.cpp index 822bd76..672444c 100644 --- a/src/basic/string16.cpp +++ b/src/basic/string16.cpp @@ -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; } diff --git a/src/text_editor/buffer_helpers.cpp b/src/text_editor/buffer_helpers.cpp index 337396e..833f064 100644 --- a/src/text_editor/buffer_helpers.cpp +++ b/src/text_editor/buffer_helpers.cpp @@ -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; +} \ No newline at end of file diff --git a/src/text_editor/commands_window.cpp b/src/text_editor/commands_window.cpp index 4c29a70..11323c0 100644 --- a/src/text_editor/commands_window.cpp +++ b/src/text_editor/commands_window.cpp @@ -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)) { diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index 86b0fa9..382b791 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -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