Adjust carets in title bar, Command_ReplaceEx, adjust look of underline
This commit is contained in:
@@ -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"});
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user