diff --git a/src/text_editor/commands_window.cpp b/src/text_editor/commands_window.cpp index 870842d..85f9b88 100644 --- a/src/text_editor/commands_window.cpp +++ b/src/text_editor/commands_window.cpp @@ -153,6 +153,56 @@ void Command_Move(View *view, int direction, bool ctrl = false, bool shift = fal } } +void Command_MoveLine(View *view, int direction) { + Assert(direction == DIR_DOWN || direction == DIR_UP); + Scratch scratch; + + struct XYPair { + XY front; + XY back; + }; + + Buffer *buffer = GetBuffer(view->active_buffer); + BeforeEdit(buffer, view->carets); + MergeCarets(view); + Array saved_xy = {scratch}; + Array edits = {scratch}; + For(view->carets) { + Add(&saved_xy, {PosToXY(*buffer, GetFront(it)), PosToXY(*buffer, GetBack(it))}); + Range lines_to_move_range = {GetFullLineStart(buffer, it.range.min), GetFullLineEnd(buffer, it.range.max)}; + + String16 string = GetString(*buffer, lines_to_move_range); + string = Copy(scratch, string); + AddEdit(&edits, lines_to_move_range, {}); + + // @todo: GetPrevLine, GetNextLine, GetNextFull + // GetPrevLineStart, GetNextLineEnd + if (direction == DIR_DOWN) { + Int next_line_start = lines_to_move_range.max; + Int next_line_end = GetFullLineEnd(buffer, next_line_start); + AddEdit(&edits, Rng(next_line_end), string); + } else { + Int prev_line_end = lines_to_move_range.min - 1; + Int prev_line_start = GetFullLineStart(buffer, prev_line_end); + AddEdit(&edits, Rng(prev_line_start), string); + } + } + ApplyEdits(buffer, edits); + AfterEdit(buffer, &edits, &view->carets); + + Int line_offset = direction == DIR_UP ? -1 : +1; + for (Int i = 0; i < saved_xy.len; i += 1) { + Caret &caret = view->carets[i]; + XYPair &xypair = saved_xy[i]; + xypair.front.line += line_offset; + xypair.back.line += line_offset; + Int front = XYToPos(*buffer, xypair.front); + Int back = XYToPos(*buffer, xypair.back); + + caret = MakeCaret(front, back); + } +} + void Command_Replace(View *view, String16 string) { Buffer *buffer = GetBuffer(view->active_buffer); Scratch scratch; @@ -540,6 +590,8 @@ void WindowCommand(Event event, Window *window, View *view) { Command_CreateCursorVertical(view, DIR_DOWN); } else if (CtrlShift(SDLK_DOWN)) { Command_Move(view, DIR_DOWN, CTRL_PRESSED, SHIFT_PRESSED); + } else if (Alt(SDLK_DOWN)) { + Command_MoveLine(view, DIR_DOWN); } else if (Ctrl(SDLK_DOWN)) { Command_Move(view, DIR_DOWN, CTRL_PRESSED); } else if (Shift(SDLK_DOWN)) { @@ -554,6 +606,8 @@ void WindowCommand(Event event, Window *window, View *view) { Command_CreateCursorVertical(view, DIR_UP); } else if (CtrlShift(SDLK_UP)) { Command_Move(view, DIR_UP, CTRL_PRESSED, SHIFT_PRESSED); + } else if (Alt(SDLK_UP)) { + Command_MoveLine(view, DIR_UP); } else if (Ctrl(SDLK_UP)) { Command_Move(view, DIR_UP, CTRL_PRESSED); } else if (Shift(SDLK_UP)) { diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index 6d86213..e2be1fd 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -1,4 +1,3 @@ -- we should be able to execute a buffer (even scratch - search as a command to execute which is going to be in the title bar - each buffer needs a directory even the special ones: C:\a\b\c\+errors? - open directories - resulting in buffer with dir listing and proper buffer name