Trim whitespace on save and skip lines with cursor
This commit is contained in:
@@ -398,6 +398,7 @@ void GenerateConfig() {
|
||||
style.add({"DrawLineNumbers", "1"});
|
||||
style.add({"DrawScrollbar", "1"});
|
||||
style.add({"IndentSize", "2"});
|
||||
style.add({"TrimWhitespaceOnSave", "1"});
|
||||
|
||||
{
|
||||
MA_Scratch scratch;
|
||||
|
||||
@@ -31,6 +31,34 @@ void Command_DuplicateLine(View *view, int direction) {
|
||||
For(view->carets) it = MakeCaret(MovePos(*buffer, it.range.min, direction, false));
|
||||
}
|
||||
|
||||
Array<Range> GetSortedSelectedLines(Allocator allocator, View *view) {
|
||||
Scratch scratch(allocator);
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
Array<Caret> caret_copy = TightCopy(scratch, view->carets);
|
||||
Array<Caret> temp = TightCopy(scratch, view->carets);
|
||||
MergeSort(view->carets.len, caret_copy.data, temp.data);
|
||||
|
||||
Array<Range> result = {allocator};
|
||||
For(caret_copy) {
|
||||
Int min_line = PosToLine(*buffer, it.range.min);
|
||||
Int max_line = PosToLine(*buffer, it.range.max);
|
||||
Range line_range = {min_line, max_line + 1};
|
||||
|
||||
if (result.len == 0) {
|
||||
Add(&result, line_range);
|
||||
continue;
|
||||
}
|
||||
|
||||
Range *last = GetLast(result);
|
||||
if (AreOverlapping(*last, line_range)) {
|
||||
last->max = Max(last->max, line_range.max);
|
||||
} else {
|
||||
Add(&result, line_range);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Command_IndentSelectedLines(View *view, bool shift = false) {
|
||||
Scratch scratch;
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
@@ -38,32 +66,10 @@ void Command_IndentSelectedLines(View *view, bool shift = false) {
|
||||
BeforeEdit(buffer, view->carets);
|
||||
MergeCarets(view);
|
||||
|
||||
Array<Caret> caret_copy = TightCopy(scratch, view->carets);
|
||||
Array<Caret> temp = TightCopy(scratch, view->carets);
|
||||
MergeSort(view->carets.len, caret_copy.data, temp.data);
|
||||
|
||||
Array<Range> line_ranges_to_indent = {scratch};
|
||||
For(caret_copy) {
|
||||
Int min_line = PosToLine(*buffer, it.range.min);
|
||||
Int max_line = PosToLine(*buffer, it.range.max);
|
||||
Range line_range = {min_line, max_line};
|
||||
|
||||
if (line_ranges_to_indent.len == 0) {
|
||||
Add(&line_ranges_to_indent, line_range);
|
||||
continue;
|
||||
}
|
||||
|
||||
Range *last = GetLast(line_ranges_to_indent);
|
||||
if (AreOverlapping(*last, line_range)) {
|
||||
last->max = Max(last->max, line_range.max);
|
||||
} else {
|
||||
Add(&line_ranges_to_indent, line_range);
|
||||
}
|
||||
}
|
||||
|
||||
Array<Edit> edits = {scratch};
|
||||
Array<Range> line_ranges_to_indent = GetSortedSelectedLines(scratch, view);
|
||||
Array<Edit> edits = {scratch};
|
||||
For(line_ranges_to_indent) {
|
||||
for (Int i = it.min; i <= it.max; i += 1) {
|
||||
for (Int i = it.min; i < it.max; i += 1) {
|
||||
Range pos_range_of_line = GetLineRange(*buffer, i);
|
||||
|
||||
if (!shift) {
|
||||
@@ -86,15 +92,45 @@ void Command_IndentSelectedLines(View *view, bool shift = false) {
|
||||
view->update_scroll = false;
|
||||
}
|
||||
|
||||
void Command_TrimTrailingWhitespace(View *view) {
|
||||
Int FindRangeByPos(Array<Range> &ranges, Int pos) {
|
||||
// binary search
|
||||
Int low = 0;
|
||||
Int high = ranges.len - 1;
|
||||
Int result = -1;
|
||||
|
||||
while (low <= high) {
|
||||
Int mid = low + (high - low) / 2;
|
||||
Range range = ranges[mid];
|
||||
if (pos >= range.min && pos < range.max) {
|
||||
result = mid;
|
||||
break;
|
||||
}
|
||||
|
||||
if (range.min < pos) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Command_TrimTrailingWhitespace(View *view, bool dont_trim_lines_with_cursor) {
|
||||
Scratch scratch;
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
|
||||
BeforeEdit(buffer, view->carets);
|
||||
MergeCarets(view);
|
||||
|
||||
Array<Range> lines_to_skip_triming = {};
|
||||
if (dont_trim_lines_with_cursor) lines_to_skip_triming = GetSortedSelectedLines(scratch, view);
|
||||
|
||||
Array<Edit> edits = {scratch};
|
||||
for (Int i = 0; i < buffer->line_starts.len; i += 1) {
|
||||
Int range_index = FindRangeByPos(lines_to_skip_triming, i);
|
||||
if (range_index != -1) continue;
|
||||
|
||||
Range range = GetLineRangeWithoutNL(*buffer, i);
|
||||
Int whitespace_end = range.max;
|
||||
for (; whitespace_end > range.min; whitespace_end -= 1) {
|
||||
@@ -448,7 +484,7 @@ void WindowCommand(Event event, Window *window, View *view) {
|
||||
}
|
||||
|
||||
if (Ctrl(SDLK_W)) {
|
||||
Command_TrimTrailingWhitespace(view);
|
||||
Command_TrimTrailingWhitespace(view, false);
|
||||
}
|
||||
|
||||
if (Ctrl(SDLK_BACKSPACE)) {
|
||||
@@ -570,6 +606,11 @@ void WindowCommand(Event event, Window *window, View *view) {
|
||||
}
|
||||
|
||||
if (Ctrl(SDLK_S)) {
|
||||
if (StyleTrimWhitespaceOnSave) {
|
||||
bool dont_trim_lines_with_cursor = true;
|
||||
Command_TrimTrailingWhitespace(view, dont_trim_lines_with_cursor);
|
||||
}
|
||||
|
||||
String16 string16 = GetString(*buffer);
|
||||
Scratch scratch;
|
||||
String string = ToString(scratch, string16);
|
||||
|
||||
@@ -58,6 +58,7 @@ Style = {}
|
||||
Style.DrawLineNumbers = 1
|
||||
Style.DrawScrollbar = 1
|
||||
Style.IndentSize = 2
|
||||
Style.TrimWhitespaceOnSave = 1
|
||||
|
||||
-- @todo: should we rewrite linux paths to windows on windows and vice-versa?
|
||||
|
||||
@@ -217,4 +218,5 @@ void ReloadStyle() {
|
||||
StyleDrawLineNumbers = GetStyle("DrawLineNumbers", StyleDrawLineNumbers);
|
||||
StyleDrawScrollbar = GetStyle("DrawScrollbar", StyleDrawScrollbar);
|
||||
StyleIndentSize = GetStyle("IndentSize", StyleIndentSize);
|
||||
StyleTrimWhitespaceOnSave = GetStyle("TrimWhitespaceOnSave", StyleTrimWhitespaceOnSave);
|
||||
}
|
||||
@@ -54,4 +54,5 @@ Color ColorTitleBarBackground = GruvboxLight1;
|
||||
Color ColorTitleBarSelection = GruvboxLight3;
|
||||
Int StyleDrawLineNumbers = 1;
|
||||
Int StyleDrawScrollbar = 1;
|
||||
Int StyleIndentSize = 2;
|
||||
Int StyleIndentSize = 2;
|
||||
Int StyleTrimWhitespaceOnSave = 1;
|
||||
@@ -4,10 +4,10 @@
|
||||
- don't trim lines with cursor or selection on it
|
||||
- fix history of ctrl + enter
|
||||
|
||||
- option trim trailing whitespace before save and dont' trim on cursor
|
||||
- improve cursor movement, it's too clunky, too much stopping
|
||||
- kill selected lines
|
||||
- better enclosures
|
||||
- kill selected lines
|
||||
- should be able click on title bar of windows which disappear on losing focus
|
||||
- search backwards
|
||||
- load selected string or auto enclosed word when midclick?, ctrl + click, ctrl + e?
|
||||
- experiment with using multiple cursors to select command and it's input
|
||||
|
||||
Reference in New Issue
Block a user