Adjust carets in title bar, Command_ReplaceEx, adjust look of underline

This commit is contained in:
Krzosa Karol
2024-08-08 17:36:18 +02:00
parent a004976c6b
commit 95b7ded031
10 changed files with 81 additions and 46 deletions

View File

@@ -350,8 +350,8 @@ function GenericTextFileRule(_s)
end
end
line, col, _s = ChopLineAndColumn(_s)
_s = ChopColon(_s)
line, col, _s = ChopLineAndColumn(_s)
file_path = match_path(_s)
return {kind = "text", file_path = file_path, line = line, col = col}
end
@@ -457,6 +457,8 @@ void GenerateConfig() {
colors.add({"SubCaret", "GruvboxGray245"});
colors.add({"Selection", "GruvboxLight1"});
colors.add({"WhitespaceDuringSelection", "GruvboxLight4"});
colors.add({"MouseUnderline", "GruvboxDark0Hard"});
colors.add({"CaretUnderline", "GruvboxGray245"});
colors.add({"FuzzySearchLineHighlight", "GruvboxDark0"});

View File

@@ -71,6 +71,11 @@ XY XYLine(Int line) {
return result;
}
wchar_t GetChar(Buffer *buffer, Int pos) {
if (pos >= 0 && pos < buffer->len) return buffer->str[pos];
return 0;
}
Caret MakeCaret(Int front, Int back) {
Caret result = {};
if (front >= back) {
@@ -299,6 +304,7 @@ Int GetExecWordStart(Buffer *buffer, Int pos) {
pos = Clamp(pos, (Int)0, buffer->len);
for (Int i = pos - 1; i >= 0; i -= 1) {
if (IsWhitespace(buffer->str[i])) break;
if (GetChar(buffer, i) == L'|' && GetChar(buffer, i + 1) == L'>') break;
pos = i;
}
return pos;
@@ -313,6 +319,7 @@ Int GetExecWordEnd(Buffer *buffer, Int pos) {
// semantics - proper max is one past last index
if (!(i < buffer->len)) break;
if (IsWhitespace(buffer->str[i])) break;
if (GetChar(buffer, i - 1) == L'<' && GetChar(buffer, i) == L'|') break;
}
return pos;
}
@@ -438,6 +445,18 @@ Range EncloseExecWord(Buffer *buffer, Int pos) {
return result;
}
Range TrimButtonChars(Buffer *buffer, Range range) {
bool left0 = range.min < range.max && range.min + 1 < range.max;
bool left1 = GetChar(buffer, range.min) == L'|' && GetChar(buffer, range.min + 1) == L'>';
if (left0 && left1) range.min += 2;
bool right0 = range.max - 2 >= range.min && range.max - 1 >= range.min;
bool right1 = GetChar(buffer, range.max - 2) == L'<' && GetChar(buffer, range.max - 1) == L'|';
if (right0 && right1) range.max -= 2;
return range;
}
Range EncloseLine(Buffer *buffer, Int pos) {
Range result = {GetLineStart(buffer, pos), GetLineEnd(buffer, pos)};
return result;
@@ -464,11 +483,6 @@ Int GetPrevChar(Buffer *buffer, Int pos) {
return result;
}
wchar_t GetChar(Buffer *buffer, Int pos) {
if (pos >= 0 && pos < buffer->len) return buffer->str[pos];
return 0;
}
Int GetLineIndent(Buffer *buffer, Int line) {
String16 string = GetLineStringWithoutNL(*buffer, line);
Int indent = 0;

View File

@@ -113,31 +113,10 @@ void PreBeginEdit_SaveCaretHistory(Buffer *buffer, Array<Caret> &carets) {
BeginEdit({}, buffer, carets);
}
bool KILL_SELECTION = true;
void EndEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets, bool kill_selection = true) {
ProfileFunction();
IKnowWhatImDoing_ApplyEdits(buffer, *edits);
Assert(buffer->edit_phase == 2);
buffer->edit_phase -= 2;
#if BUFFER_DEBUG
if (buffer->no_history == false) {
HistoryEntry *entry = GetLast(buffer->undo_stack);
Assert(entry->carets.len);
Assert(entry->edits.len);
for (Int i = 0; i < edits->len - 1; i += 1) {
Assert(edits->data[i].range.min <= edits->data[i + 1].range.min);
}
}
#endif
//
// Offset all carets by edits
//
void AdjustCarets(Array<Edit> edits, Array<Caret> *carets, bool kill_selection = false) {
Scratch scratch;
Array<Caret> new_carets = TightCopy(scratch, *carets);
ForItem(edit, *edits) {
ForItem(edit, edits) {
Int remove_size = GetSize(edit.range);
Int insert_size = edit.string.len;
Int offset = insert_size - remove_size;
@@ -167,3 +146,25 @@ void EndEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets, bool kill
}
}
}
bool KILL_SELECTION = true;
void EndEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets, bool kill_selection = true) {
ProfileFunction();
IKnowWhatImDoing_ApplyEdits(buffer, *edits);
Assert(buffer->edit_phase == 2);
buffer->edit_phase -= 2;
#if BUFFER_DEBUG
if (buffer->no_history == false) {
HistoryEntry *entry = GetLast(buffer->undo_stack);
Assert(entry->carets.len);
Assert(entry->edits.len);
for (Int i = 0; i < edits->len - 1; i += 1) {
Assert(edits->data[i].range.min <= edits->data[i + 1].range.min);
}
}
#endif
AdjustCarets(*edits, carets, kill_selection);
}

View File

@@ -267,7 +267,10 @@ bool GlobalCommand(Event event) {
Int p = ScreenSpaceToBufferPosErrorOutOfBounds(window, view, buffer, mouse);
if (p != -1) {
Range enclose = EncloseExecWord(buffer, p);
if (InBounds(view->carets[0].range, p)) enclose = view->carets[0].range;
if (InBounds(view->carets[0].range, p)) {
enclose = view->carets[0].range;
}
enclose = TrimButtonChars(buffer, enclose);
String16 string = GetString(*buffer, enclose);
Command_EvalLua(view, string);
}

View File

@@ -201,14 +201,18 @@ void Command_MoveLine(View *view, int direction) {
}
}
void Command_Replace(View *view, String16 string) {
Scratch scratch;
Array<Edit> Command_ReplaceEx(Allocator scratch, View *view, String16 string) {
Buffer *buffer = GetBuffer(view->active_buffer);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
For(view->carets) AddEdit(&edits, it.range, string);
EndEdit(buffer, &edits, &view->carets);
return edits;
}
void Command_Replace(View *view, String16 string) {
Scratch scratch;
Command_ReplaceEx(scratch, view, string);
}
void Command_DuplicateLine(View *view, int direction) {
@@ -889,7 +893,10 @@ void WindowCommand(Event event, Window *window, View *view) {
} else if (Alt(SDLK_Q)) {
Caret caret = view->carets[0];
Range range = caret.range;
if (GetSize(caret.range) == 0) range = EncloseExecWord(buffer, GetFront(caret));
if (GetSize(caret.range) == 0) {
range = EncloseExecWord(buffer, GetFront(caret));
range = TrimButtonChars(buffer, range);
}
String16 string = GetString(*buffer, range);
Command_EvalLua(view, string);

View File

@@ -47,6 +47,8 @@ Color.MainCaret = GruvboxDark0Hard
Color.SubCaret = GruvboxGray245
Color.Selection = GruvboxLight1
Color.WhitespaceDuringSelection = GruvboxLight4
Color.MouseUnderline = GruvboxDark0Hard
Color.CaretUnderline = GruvboxGray245
Color.FuzzySearchLineHighlight = GruvboxDark0
Color.ScrollbarBackground = GruvboxLight2
Color.ScrollbarScroller = GruvboxLight1
@@ -237,8 +239,8 @@ function GenericTextFileRule(_s)
end
end
line, col, _s = ChopLineAndColumn(_s)
_s = ChopColon(_s)
line, col, _s = ChopLineAndColumn(_s)
file_path = match_path(_s)
return {kind = "text", file_path = file_path, line = line, col = col}
end
@@ -299,6 +301,8 @@ void ReloadStyle() {
ColorSubCaret = GetColor("SubCaret", ColorSubCaret);
ColorSelection = GetColor("Selection", ColorSelection);
ColorWhitespaceDuringSelection = GetColor("WhitespaceDuringSelection", ColorWhitespaceDuringSelection);
ColorMouseUnderline = GetColor("MouseUnderline", ColorMouseUnderline);
ColorCaretUnderline = GetColor("CaretUnderline", ColorCaretUnderline);
ColorFuzzySearchLineHighlight = GetColor("FuzzySearchLineHighlight", ColorFuzzySearchLineHighlight);
ColorScrollbarBackground = GetColor("ScrollbarBackground", ColorScrollbarBackground);
ColorScrollbarScroller = GetColor("ScrollbarScroller", ColorScrollbarScroller);

View File

@@ -45,6 +45,8 @@ Color ColorMainCaret = GruvboxDark0Hard;
Color ColorSubCaret = GruvboxGray245;
Color ColorSelection = GruvboxLight1;
Color ColorWhitespaceDuringSelection = GruvboxLight4;
Color ColorMouseUnderline = GruvboxDark0Hard;
Color ColorCaretUnderline = GruvboxGray245;
Color ColorFuzzySearchLineHighlight = GruvboxDark0;
Color ColorScrollbarBackground = GruvboxLight2;
Color ColorScrollbarScroller = GruvboxLight1;

View File

@@ -111,6 +111,9 @@ void ReplaceTitleBarData(Window *window) {
Caret caret = last_view->carets[0];
XY xy = PosToXY(*last_buffer, GetFront(caret));
// @todo: this is still not quite correct, the carets here are not offset by edits
// so there will some problems here. I need to think about this in the future, maybe
// Command_Replace should return the edits and then you can offset manually!
Array<Caret> caret_copy = Copy(GetSystemAllocator(), view->carets);
defer {
Dealloc(&view->carets);
@@ -121,7 +124,8 @@ void ReplaceTitleBarData(Window *window) {
Range replace_range = {0, buffer->len};
if (!Seek(buffer_string, L" |", &replace_range.max)) {
Command_SelectRangeOneCursor(view, GetEndAsRange(*buffer));
Command_Replace(view, L" |");
Array<Edit> edits = Command_ReplaceEx(scratch, view, L" |");
AdjustCarets(edits, &caret_copy);
}
String s = Format(scratch, "%.*s:%lld:%lld", FmtString(last_buffer->name), (long long)xy.line + 1ll, (long long)xy.col + 1ll);
@@ -129,7 +133,8 @@ void ReplaceTitleBarData(Window *window) {
String16 string_to_replace = GetString(*buffer, replace_range);
if (string_to_replace != string) {
Command_SelectRangeOneCursor(view, replace_range);
Command_Replace(view, string);
Array<Edit> edits = Command_ReplaceEx(scratch, view, string);
Command_SelectRangeOneCursor(view, {});
AdjustCarets(edits, &caret_copy);
}
}

View File

@@ -4,10 +4,7 @@
- I think clipboard adds \r\n, let's execute the conversion on that
- prevent lua from infinite looping
- Append to console and change console directory
- c'git grep'
- EncloseExecWord should enclose the string also (add limitation)
- hotkey to select window title
- change colors of underline for caret or cursor
- search as a command to execute which is going to be in the title bar
- search backwards

View File

@@ -89,7 +89,7 @@ void DrawCaret(Window *window, XY xy, float size, Color color) {
DrawRect(ToRect2(rect), color);
}
void DrawUnderline(Window *window, View *view, Buffer *buffer, Range range) {
void DrawUnderline(Window *window, View *view, Buffer *buffer, Range range, Color color, Int size = 1) {
XY xy_min = PosToXY(*buffer, range.min);
XY xy_max = PosToXY(*buffer, range.max);
@@ -97,12 +97,12 @@ void DrawUnderline(Window *window, View *view, Buffer *buffer, Range range) {
// optimizing and so on
if (xy_min.line != xy_max.line) return;
Vec2I min = {xy_min.col * FontCharSpacing, (xy_min.line + 1) * FontLineSpacing - 1};
Vec2I min = {xy_min.col * FontCharSpacing, (xy_min.line + 1) * FontLineSpacing - size};
Vec2I max = {xy_max.col * FontCharSpacing, (xy_max.line + 1) * FontLineSpacing};
Rect2I rect = {min, max};
rect -= view->scroll;
rect += window->document_rect.min;
DrawRectOutline(rect, ColorText);
DrawRectOutline(rect, color);
}
void DrawWindow(Window *window, Event &event) {
@@ -197,16 +197,16 @@ void DrawWindow(Window *window, Event &event) {
if (p != -1) {
Range range = enclose_proc(buffer, p);
if (InBounds(caret.range, p)) range = caret.range;
DrawUnderline(window, view, buffer, range);
DrawUnderline(window, view, buffer, range, ColorMouseUnderline, 2);
}
}
if (is_active) {
if (GetSize(caret.range) == 0) {
Range range = enclose_proc(buffer, caret.range.min);
DrawUnderline(window, view, buffer, range);
DrawUnderline(window, view, buffer, range, ColorCaretUnderline);
} else {
DrawUnderline(window, view, buffer, caret.range);
DrawUnderline(window, view, buffer, caret.range, ColorCaretUnderline);
}
}
}