Movement with new semantics fully completed
This commit is contained in:
@@ -1,128 +0,0 @@
|
||||
const int DIR_RIGHT = 0;
|
||||
const int DIR_LEFT = 1;
|
||||
const int DIR_DOWN = 2;
|
||||
const int DIR_UP = 3;
|
||||
const int DIR_COUNT = 4;
|
||||
|
||||
const bool CTRL_PRESSED = true;
|
||||
|
||||
Int MoveOnWhitespaceBoundary(Buffer &buffer, Int pos, int direction) {
|
||||
Assert(direction == DIR_RIGHT || direction == DIR_LEFT);
|
||||
bool right = direction == DIR_RIGHT;
|
||||
|
||||
pos = Clamp(pos, (Int)0, buffer.len);
|
||||
bool standing_on_whitespace = IsWhitespace(buffer.str[pos]);
|
||||
bool standing_on_symbol = IsSymbol(buffer.str[pos]);
|
||||
bool standing_on_word = !standing_on_whitespace && !standing_on_symbol;
|
||||
bool seek_whitespace = standing_on_whitespace == false;
|
||||
bool seek_word = standing_on_whitespace || standing_on_symbol;
|
||||
bool seek_symbol = standing_on_whitespace || standing_on_word;
|
||||
|
||||
Int result = right ? buffer.len : 0;
|
||||
Int delta = right ? 1 : -1;
|
||||
Int prev_pos = pos;
|
||||
for (Int i = pos; right ? i < buffer.len : i >= 0; i += delta) {
|
||||
bool is_whitespace = IsWhitespace(buffer.str[i]);
|
||||
bool is_symbol = IsSymbol(buffer.str[i]);
|
||||
bool is_word = !is_whitespace && !is_symbol;
|
||||
Int res = right ? i : prev_pos;
|
||||
if (seek_word && is_word) {
|
||||
result = res;
|
||||
break;
|
||||
}
|
||||
if (seek_whitespace && is_whitespace) {
|
||||
result = res;
|
||||
break;
|
||||
}
|
||||
if (seek_symbol && is_symbol) {
|
||||
result = res;
|
||||
break;
|
||||
}
|
||||
prev_pos = i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Int MoveOnWhitespaceBoundaryVertical(Buffer &buffer, Int pos, int direction) {
|
||||
Assert(direction == DIR_UP || direction == DIR_DOWN);
|
||||
|
||||
bool up = direction == DIR_UP;
|
||||
Int delta = up ? -1 : 1;
|
||||
|
||||
Int result = pos;
|
||||
Int next_line = PosToLine(buffer, pos) + delta;
|
||||
for (Int line = next_line; up ? line >= 0 : line < buffer.line_starts.len; line += delta) {
|
||||
Range line_range = GetLineRange(buffer, line);
|
||||
result = line_range.min;
|
||||
|
||||
bool whitespace_line = true;
|
||||
for (Int i = line_range.min; i < line_range.max; i += 1) {
|
||||
if (!IsWhitespace(buffer.str[i])) {
|
||||
whitespace_line = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (whitespace_line) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Int MovePos(Buffer &buffer, Int pos, int direction, bool ctrl_pressed = false) {
|
||||
Assert(direction >= 0 && direction <= 3);
|
||||
if (ctrl_pressed) {
|
||||
switch (direction) {
|
||||
case DIR_RIGHT: return MoveOnWhitespaceBoundary(buffer, pos, direction);
|
||||
case DIR_LEFT: return MoveOnWhitespaceBoundary(buffer, pos - 1, direction);
|
||||
case DIR_DOWN: return MoveOnWhitespaceBoundaryVertical(buffer, pos, direction);
|
||||
case DIR_UP: return MoveOnWhitespaceBoundaryVertical(buffer, pos, direction);
|
||||
default: return pos;
|
||||
}
|
||||
} else {
|
||||
switch (direction) {
|
||||
case DIR_RIGHT: return Clamp(pos + 1, (Int)0, buffer.len);
|
||||
case DIR_LEFT: return Clamp(pos - 1, (Int)0, buffer.len);
|
||||
case DIR_DOWN: return OffsetByLine(&buffer, pos, 1);
|
||||
case DIR_UP: return OffsetByLine(&buffer, pos, -1);
|
||||
default: return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Caret FindInBuffer(Buffer *buffer, String16 needle, Caret caret, bool find_next = false) {
|
||||
Int pos = caret.range.min;
|
||||
String16 medium = GetString(*buffer, {pos, INT64_MAX});
|
||||
|
||||
Caret result = {};
|
||||
Int index = 0;
|
||||
if (Seek(medium, needle, &index)) {
|
||||
result = MakeCaret(pos + index + needle.len, pos + index);
|
||||
} else {
|
||||
medium = GetString(*buffer);
|
||||
if (Seek(medium, needle, &index)) {
|
||||
result = MakeCaret(index + needle.len, index);
|
||||
}
|
||||
}
|
||||
|
||||
if (find_next && AreEqual(result, caret)) {
|
||||
caret.range.min = Clamp(*buffer, caret.range.min + 1);
|
||||
caret.range.max = Clamp(*buffer, caret.range.max + 1);
|
||||
result = FindInBuffer(buffer, needle, caret, false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needle) {
|
||||
Array<Range> result = {allocator};
|
||||
String16 string_buffer = GetString(*buffer);
|
||||
for (Int pos = 0;;) {
|
||||
Int index = 0;
|
||||
String16 medium = Skip(string_buffer, pos);
|
||||
if (!Seek(medium, needle, &index)) {
|
||||
break;
|
||||
}
|
||||
Add(&result, Rng(pos + index, pos + index + needle.len));
|
||||
pos += needle.len;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -39,6 +39,14 @@ struct Event {
|
||||
const char *text;
|
||||
};
|
||||
|
||||
const int DIR_RIGHT = 0;
|
||||
const int DIR_LEFT = 1;
|
||||
const int DIR_DOWN = 2;
|
||||
const int DIR_UP = 3;
|
||||
const int DIR_COUNT = 4;
|
||||
const bool CTRL_PRESSED = true;
|
||||
bool SHIFT_PRESSED = true;
|
||||
|
||||
#define Press(KEY) (event.key == KEY)
|
||||
#define Ctrl(KEY) (event.key == KEY && event.ctrl)
|
||||
#define Shift(KEY) (event.key == KEY && event.shift)
|
||||
|
||||
@@ -1,3 +1,152 @@
|
||||
|
||||
void Command_MoveCursorsByPageSize(Window *window, int direction, bool shift = false) {
|
||||
Assert(direction == DIR_UP || direction == DIR_DOWN);
|
||||
View &view = *GetActiveView(window);
|
||||
Buffer *buffer = GetBuffer(view.active_buffer);
|
||||
|
||||
Rect2I visible_cells_rect = GetVisibleCells(window);
|
||||
Int y = GetSize(visible_cells_rect).y - 2;
|
||||
if (direction == DIR_UP) y = -y;
|
||||
|
||||
For(view.carets) {
|
||||
XY xy = PosToXY(*buffer, GetFront(it));
|
||||
if (direction == DIR_DOWN && xy.line == buffer->line_starts.len - 1) {
|
||||
Range line_range = GetLineRange(*buffer, xy.line);
|
||||
xy.col = line_range.max - line_range.min;
|
||||
} else if (direction == DIR_UP && xy.line == 0) {
|
||||
xy.col = 0;
|
||||
}
|
||||
xy.line += y;
|
||||
|
||||
Int pos = XYToPos(*buffer, xy);
|
||||
if (shift) {
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
it = MakeCaret(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Command_MoveCursorsToSide(View *view, int direction, bool shift = false) {
|
||||
Assert(direction == DIR_LEFT || direction == DIR_RIGHT);
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
|
||||
For(view->carets) {
|
||||
Int pos = GetFront(it);
|
||||
if (direction == DIR_RIGHT) {
|
||||
pos = GetLineEnd(buffer, pos);
|
||||
} else {
|
||||
pos = GetLineStart(buffer, pos);
|
||||
}
|
||||
|
||||
if (shift) {
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
it.range.max = it.range.min = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Caret MoveCaret(Buffer *buffer, Caret it, int direction, bool ctrl = false, bool shift = false) {
|
||||
Int front = GetFront(it);
|
||||
Int range_size = GetSize(it.range);
|
||||
switch (direction) {
|
||||
case DIR_UP: {
|
||||
if (ctrl && shift) {
|
||||
Int pos = GetPrevEmptyLineStart(buffer, front);
|
||||
it = ChangeFront(it, pos);
|
||||
} else if (ctrl) {
|
||||
Int pos = GetPrevEmptyLineStart(buffer, it.range.min);
|
||||
it = MakeCaret(pos);
|
||||
} else if (shift) {
|
||||
Int pos = OffsetByLine(buffer, front, -1);
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
if (range_size == 0) {
|
||||
Int pos = OffsetByLine(buffer, it.range.min, -1);
|
||||
it = MakeCaret(pos);
|
||||
} else {
|
||||
it = MakeCaret(it.range.min);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case DIR_DOWN: {
|
||||
if (ctrl && shift) {
|
||||
Int pos = GetNextEmptyLineStart(buffer, front);
|
||||
it = ChangeFront(it, pos);
|
||||
} else if (ctrl) {
|
||||
Int pos = GetNextEmptyLineStart(buffer, it.range.max);
|
||||
it = MakeCaret(pos);
|
||||
} else if (shift) {
|
||||
Int pos = OffsetByLine(buffer, front, 1);
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
if (range_size == 0) {
|
||||
Int pos = OffsetByLine(buffer, it.range.max, 1);
|
||||
it = MakeCaret(pos);
|
||||
} else {
|
||||
it = MakeCaret(it.range.max);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case DIR_LEFT: {
|
||||
if (ctrl && shift) {
|
||||
Int pos = GetPrevWordStart(buffer, front);
|
||||
it = ChangeFront(it, pos);
|
||||
} else if (ctrl) {
|
||||
if (range_size != 0 && front != it.range.min) {
|
||||
it = MakeCaret(it.range.min);
|
||||
} else {
|
||||
Int pos = GetPrevWordStart(buffer, it.range.min);
|
||||
it = MakeCaret(pos);
|
||||
}
|
||||
} else if (shift) {
|
||||
Int pos = GetPrevChar(buffer, front);
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
if (range_size == 0) {
|
||||
Int pos = GetPrevChar(buffer, it.range.min);
|
||||
it = MakeCaret(pos);
|
||||
} else {
|
||||
it = MakeCaret(it.range.min);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case DIR_RIGHT: {
|
||||
if (ctrl && shift) {
|
||||
Int pos = GetNextWordEnd(buffer, front);
|
||||
it = ChangeFront(it, pos);
|
||||
} else if (ctrl) {
|
||||
if (range_size != 0 && front != it.range.max) {
|
||||
it = MakeCaret(it.range.max);
|
||||
} else {
|
||||
Int pos = GetNextWordEnd(buffer, it.range.max);
|
||||
it = MakeCaret(pos);
|
||||
}
|
||||
} else if (shift) {
|
||||
Int pos = GetNextChar(buffer, front);
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
if (range_size == 0) {
|
||||
Int pos = GetNextChar(buffer, it.range.max);
|
||||
it = MakeCaret(pos);
|
||||
} else {
|
||||
it = MakeCaret(it.range.max);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
void Command_Move(View *view, int direction, bool ctrl = false, bool shift = false) {
|
||||
Assert(direction < DIR_COUNT);
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
For(view->carets) {
|
||||
it = MoveCaret(buffer, it, direction, ctrl, shift);
|
||||
}
|
||||
}
|
||||
|
||||
void Command_Replace(View *view, String16 string) {
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
Scratch scratch;
|
||||
@@ -28,7 +177,7 @@ void Command_DuplicateLine(View *view, int direction) {
|
||||
ApplyEdits(buffer, edits);
|
||||
AfterEdit(buffer, &edits, &view->carets);
|
||||
|
||||
For(view->carets) it = MakeCaret(MovePos(*buffer, it.range.min, direction, false));
|
||||
Command_Move(view, direction);
|
||||
}
|
||||
|
||||
Int FindRangeByPos(Array<Range> &ranges, Int pos) {
|
||||
@@ -177,90 +326,6 @@ void Command_KillSelectedLines(View *view) {
|
||||
AfterEdit(buffer, &edits, &view->carets, KILL_SELECTION);
|
||||
}
|
||||
|
||||
bool SHIFT_PRESSED = true;
|
||||
void Command_MoveCursorsByPageSize(Window *window, int direction, bool shift = false) {
|
||||
Assert(direction == DIR_UP || direction == DIR_DOWN);
|
||||
View &view = *GetActiveView(window);
|
||||
Buffer *buffer = GetBuffer(view.active_buffer);
|
||||
|
||||
Rect2I visible_cells_rect = GetVisibleCells(window);
|
||||
Int y = GetSize(visible_cells_rect).y - 2;
|
||||
if (direction == DIR_UP) y = -y;
|
||||
|
||||
For(view.carets) {
|
||||
XY xy = PosToXY(*buffer, GetFront(it));
|
||||
if (direction == DIR_DOWN && xy.line == buffer->line_starts.len - 1) {
|
||||
Range line_range = GetLineRange(*buffer, xy.line);
|
||||
xy.col = line_range.max - line_range.min;
|
||||
} else if (direction == DIR_UP && xy.line == 0) {
|
||||
xy.col = 0;
|
||||
}
|
||||
xy.line += y;
|
||||
|
||||
Int pos = XYToPos(*buffer, xy);
|
||||
if (shift) {
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
it = MakeCaret(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Command_MoveCursorsToSide(View *view, int direction, bool shift = false) {
|
||||
Assert(direction == DIR_LEFT || direction == DIR_RIGHT);
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
|
||||
For(view->carets) {
|
||||
Int pos = GetFront(it);
|
||||
if (direction == DIR_RIGHT) {
|
||||
pos = GetLineEnd(buffer, pos);
|
||||
} else {
|
||||
pos = GetLineStart(buffer, pos);
|
||||
}
|
||||
|
||||
if (shift) {
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
it.range.max = it.range.min = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Command_Move(View *view, int direction, bool ctrl = false, bool shift = false) {
|
||||
Assert(direction < DIR_COUNT);
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
For(view->carets) {
|
||||
Int front = GetFront(it);
|
||||
switch (direction) {
|
||||
case DIR_UP: {
|
||||
} break;
|
||||
case DIR_DOWN: {
|
||||
if (ctrl && shift) {
|
||||
Int pos = GetNextEmptyLineStart(buffer, front);
|
||||
it = ChangeFront(it, pos);
|
||||
} else if (ctrl) {
|
||||
Int pos = GetNextEmptyLineStart(buffer, it.range.max);
|
||||
it = MakeCaret(pos);
|
||||
} else if (shift) {
|
||||
Int pos = OffsetByLine(buffer, front, 1);
|
||||
it = ChangeFront(it, pos);
|
||||
} else {
|
||||
if (GetSize(it.range) == 0) {
|
||||
Int pos = OffsetByLine(buffer, it.range.max, 1);
|
||||
it = MakeCaret(pos);
|
||||
} else {
|
||||
it = MakeCaret(it.range.max);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case DIR_LEFT: {
|
||||
} break;
|
||||
case DIR_RIGHT: {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Command_Delete(View *view, int direction, bool ctrl = false) {
|
||||
Assert(direction == DIR_LEFT || direction == DIR_RIGHT);
|
||||
Scratch scratch;
|
||||
@@ -271,8 +336,7 @@ void Command_Delete(View *view, int direction, bool ctrl = false) {
|
||||
// Select things to delete
|
||||
For(view->carets) {
|
||||
if (GetSize(it.range)) continue;
|
||||
Int pos = MovePos(*buffer, it.range.min, direction, ctrl);
|
||||
it = MakeCaret(pos, it.range.min);
|
||||
it = MoveCaret(buffer, it, direction, ctrl, SHIFT_PRESSED);
|
||||
}
|
||||
|
||||
MergeCarets(view);
|
||||
@@ -306,17 +370,20 @@ void Command_CreateCursorVertical(View *_view, int direction) {
|
||||
View &view = *_view;
|
||||
Buffer *buffer = GetBuffer(view.active_buffer);
|
||||
|
||||
Int line_offset = direction == DIR_UP ? -1 : 1;
|
||||
|
||||
Scratch scratch;
|
||||
Array<Caret> arr = {scratch};
|
||||
For(view.carets) {
|
||||
if (PosToLine(*buffer, it.range.min) == PosToLine(*buffer, it.range.max)) {
|
||||
Int f = MovePos(*buffer, GetFront(it), direction);
|
||||
Int b = MovePos(*buffer, GetBack(it), direction);
|
||||
Int f = OffsetByLine(buffer, GetFront(it), line_offset);
|
||||
Int b = OffsetByLine(buffer, GetBack(it), line_offset);
|
||||
Add(&arr, MakeCaret(f, b));
|
||||
} else {
|
||||
Int pos = direction == DIR_UP ? it.range.min : it.range.max;
|
||||
Int min = MovePos(*buffer, pos, direction);
|
||||
Add(&arr, MakeCaret(min));
|
||||
Int pos = direction == DIR_UP ? it.range.min : it.range.max;
|
||||
Caret caret = MakeCaret(pos);
|
||||
caret = MoveCaret(buffer, caret, direction);
|
||||
Add(&arr, caret);
|
||||
}
|
||||
}
|
||||
For(arr) Add(&view.carets, it);
|
||||
@@ -391,6 +458,45 @@ void MergeCarets(View *view, Range *mouse_selection_anchor) {
|
||||
Swap(&view->carets[first_caret_index], &view->carets[0]);
|
||||
}
|
||||
|
||||
Caret FindInBuffer(Buffer *buffer, String16 needle, Caret caret, bool find_next = false) {
|
||||
Int pos = caret.range.min;
|
||||
String16 medium = GetString(*buffer, {pos, INT64_MAX});
|
||||
|
||||
Caret result = {};
|
||||
Int index = 0;
|
||||
if (Seek(medium, needle, &index)) {
|
||||
result = MakeCaret(pos + index + needle.len, pos + index);
|
||||
} else {
|
||||
medium = GetString(*buffer);
|
||||
if (Seek(medium, needle, &index)) {
|
||||
result = MakeCaret(index + needle.len, index);
|
||||
}
|
||||
}
|
||||
|
||||
if (find_next && AreEqual(result, caret)) {
|
||||
caret.range.min = Clamp(*buffer, caret.range.min + 1);
|
||||
caret.range.max = Clamp(*buffer, caret.range.max + 1);
|
||||
result = FindInBuffer(buffer, needle, caret, false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needle) {
|
||||
Array<Range> result = {allocator};
|
||||
String16 string_buffer = GetString(*buffer);
|
||||
for (Int pos = 0;;) {
|
||||
Int index = 0;
|
||||
String16 medium = Skip(string_buffer, pos);
|
||||
if (!Seek(medium, needle, &index)) {
|
||||
break;
|
||||
}
|
||||
Add(&result, Rng(pos + index, pos + index + needle.len));
|
||||
pos += needle.len;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void WindowCommand(Event event, Window *window, View *view) {
|
||||
ProfileFunction();
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
@@ -409,33 +515,6 @@ void WindowCommand(Event event, Window *window, View *view) {
|
||||
}
|
||||
}
|
||||
|
||||
// Underline
|
||||
if (event.ctrl) {
|
||||
Caret caret = view->carets[0];
|
||||
if (GetSize(caret.range) == 0) {
|
||||
view->underline_pos[view->underline_count++] = caret.range.min;
|
||||
Assert(view->underline_count <= 2);
|
||||
}
|
||||
|
||||
{
|
||||
Vec2I mouse = MouseVec2I();
|
||||
Vec2I mworld = mouse - window->document_rect.min + view->scroll;
|
||||
Vec2I pos = mworld / Vec2I{FontCharSpacing, FontLineSpacing};
|
||||
XY xy = {(Int)(pos.x), (Int)(pos.y)};
|
||||
Int p = XYToPosErrorOutOfBounds(*buffer, xy);
|
||||
if (p != -1) {
|
||||
view->underline_pos[view->underline_count++] = p;
|
||||
Assert(view->underline_count <= 2);
|
||||
|
||||
if (Mouse(LEFT)) {
|
||||
Range enclose = EncloseLoadWord(buffer, p);
|
||||
String16 string = GetString(*buffer, enclose);
|
||||
Open(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CtrlAlt(SDLK_DOWN)) {
|
||||
Command_DuplicateLine(view, DIR_DOWN);
|
||||
} else if (AltShift(SDLK_DOWN)) {
|
||||
@@ -455,63 +534,33 @@ void WindowCommand(Event event, Window *window, View *view) {
|
||||
} else if (AltShift(SDLK_UP)) {
|
||||
Command_CreateCursorVertical(view, DIR_UP);
|
||||
} else if (CtrlShift(SDLK_UP)) {
|
||||
For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP, CTRL_PRESSED));
|
||||
Command_Move(view, DIR_UP, CTRL_PRESSED, SHIFT_PRESSED);
|
||||
} else if (Ctrl(SDLK_UP)) {
|
||||
For(view->carets) it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP, CTRL_PRESSED));
|
||||
Command_Move(view, DIR_UP, CTRL_PRESSED);
|
||||
} else if (Shift(SDLK_UP)) {
|
||||
For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP));
|
||||
Command_Move(view, DIR_UP, false, SHIFT_PRESSED);
|
||||
} else if (Press(SDLK_UP)) {
|
||||
For(view->carets) {
|
||||
if (GetSize(it.range) == 0) {
|
||||
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP));
|
||||
} else {
|
||||
it = MakeCaret(it.range.min);
|
||||
}
|
||||
}
|
||||
Command_Move(view, DIR_UP);
|
||||
}
|
||||
|
||||
if (CtrlShift(SDLK_LEFT)) {
|
||||
For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, true));
|
||||
Command_Move(view, DIR_LEFT, CTRL_PRESSED, SHIFT_PRESSED);
|
||||
} else if (Ctrl(SDLK_LEFT)) {
|
||||
For(view->carets) {
|
||||
if (GetSize(it.range) != 0 && GetFront(it) != it.range.min) {
|
||||
it = MakeCaret(it.range.min);
|
||||
} else {
|
||||
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, true));
|
||||
}
|
||||
}
|
||||
Command_Move(view, DIR_LEFT, CTRL_PRESSED);
|
||||
} else if (Shift(SDLK_LEFT)) {
|
||||
For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, false));
|
||||
Command_Move(view, DIR_LEFT, false, SHIFT_PRESSED);
|
||||
} else if (Press(SDLK_LEFT)) {
|
||||
For(view->carets) {
|
||||
if (GetSize(it.range) == 0) {
|
||||
it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, false));
|
||||
} else {
|
||||
it = MakeCaret(it.range.min);
|
||||
}
|
||||
}
|
||||
Command_Move(view, DIR_LEFT);
|
||||
}
|
||||
|
||||
if (CtrlShift(SDLK_RIGHT)) {
|
||||
For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, true));
|
||||
Command_Move(view, DIR_RIGHT, CTRL_PRESSED, SHIFT_PRESSED);
|
||||
} else if (Ctrl(SDLK_RIGHT)) {
|
||||
For(view->carets) {
|
||||
if (GetSize(it.range) != 0 && GetFront(it) != it.range.max) {
|
||||
it = MakeCaret(it.range.max);
|
||||
} else {
|
||||
it = MakeCaret(MovePos(*buffer, it.range.max, DIR_RIGHT, true));
|
||||
}
|
||||
}
|
||||
Command_Move(view, DIR_RIGHT, CTRL_PRESSED);
|
||||
} else if (Shift(SDLK_RIGHT)) {
|
||||
For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, false));
|
||||
Command_Move(view, DIR_RIGHT, false, SHIFT_PRESSED);
|
||||
} else if (Press(SDLK_RIGHT)) {
|
||||
For(view->carets) {
|
||||
if (GetSize(it.range) == 0) {
|
||||
it = MakeCaret(MovePos(*buffer, it.range.max, DIR_RIGHT, false));
|
||||
} else {
|
||||
it = MakeCaret(it.range.max);
|
||||
}
|
||||
}
|
||||
Command_Move(view, DIR_RIGHT);
|
||||
}
|
||||
|
||||
if (CtrlShift(SDLK_Z)) {
|
||||
@@ -718,6 +767,33 @@ void WindowCommand(Event event, Window *window, View *view) {
|
||||
}
|
||||
}
|
||||
|
||||
// Underline
|
||||
if (event.ctrl) {
|
||||
Caret caret = view->carets[0];
|
||||
if (GetSize(caret.range) == 0) {
|
||||
view->underline_pos[view->underline_count++] = caret.range.min;
|
||||
Assert(view->underline_count <= 2);
|
||||
}
|
||||
|
||||
{
|
||||
Vec2I mouse = MouseVec2I();
|
||||
Vec2I mworld = mouse - window->document_rect.min + view->scroll;
|
||||
Vec2I pos = mworld / Vec2I{FontCharSpacing, FontLineSpacing};
|
||||
XY xy = {(Int)(pos.x), (Int)(pos.y)};
|
||||
Int p = XYToPosErrorOutOfBounds(*buffer, xy);
|
||||
if (p != -1) {
|
||||
view->underline_pos[view->underline_count++] = p;
|
||||
Assert(view->underline_count <= 2);
|
||||
|
||||
if (Mouse(LEFT)) {
|
||||
Range enclose = EncloseLoadWord(buffer, p);
|
||||
String16 string = GetString(*buffer, enclose);
|
||||
Open(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Vec2I mouse = MouseVec2I();
|
||||
|
||||
@@ -26,7 +26,6 @@ int FullScreenPositionX, FullScreenPositionY;
|
||||
#include "buffer_helpers.cpp"
|
||||
#include "buffer.cpp"
|
||||
#include "buffer_multi_cursor.cpp"
|
||||
#include "buffer_ops.cpp"
|
||||
#include "buffer_history.cpp"
|
||||
#include "buffer_fuzzy_search.cpp"
|
||||
#include "buffer_test_load.cpp"
|
||||
|
||||
Reference in New Issue
Block a user