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
|
||||||
end
|
end
|
||||||
|
|
||||||
line, col, _s = ChopLineAndColumn(_s)
|
|
||||||
_s = ChopColon(_s)
|
_s = ChopColon(_s)
|
||||||
|
line, col, _s = ChopLineAndColumn(_s)
|
||||||
file_path = match_path(_s)
|
file_path = match_path(_s)
|
||||||
return {kind = "text", file_path = file_path, line = line, col = col}
|
return {kind = "text", file_path = file_path, line = line, col = col}
|
||||||
end
|
end
|
||||||
@@ -457,6 +457,8 @@ void GenerateConfig() {
|
|||||||
colors.add({"SubCaret", "GruvboxGray245"});
|
colors.add({"SubCaret", "GruvboxGray245"});
|
||||||
colors.add({"Selection", "GruvboxLight1"});
|
colors.add({"Selection", "GruvboxLight1"});
|
||||||
colors.add({"WhitespaceDuringSelection", "GruvboxLight4"});
|
colors.add({"WhitespaceDuringSelection", "GruvboxLight4"});
|
||||||
|
colors.add({"MouseUnderline", "GruvboxDark0Hard"});
|
||||||
|
colors.add({"CaretUnderline", "GruvboxGray245"});
|
||||||
|
|
||||||
colors.add({"FuzzySearchLineHighlight", "GruvboxDark0"});
|
colors.add({"FuzzySearchLineHighlight", "GruvboxDark0"});
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,11 @@ XY XYLine(Int line) {
|
|||||||
return result;
|
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 MakeCaret(Int front, Int back) {
|
||||||
Caret result = {};
|
Caret result = {};
|
||||||
if (front >= back) {
|
if (front >= back) {
|
||||||
@@ -299,6 +304,7 @@ Int GetExecWordStart(Buffer *buffer, Int pos) {
|
|||||||
pos = Clamp(pos, (Int)0, buffer->len);
|
pos = Clamp(pos, (Int)0, buffer->len);
|
||||||
for (Int i = pos - 1; i >= 0; i -= 1) {
|
for (Int i = pos - 1; i >= 0; i -= 1) {
|
||||||
if (IsWhitespace(buffer->str[i])) break;
|
if (IsWhitespace(buffer->str[i])) break;
|
||||||
|
if (GetChar(buffer, i) == L'|' && GetChar(buffer, i + 1) == L'>') break;
|
||||||
pos = i;
|
pos = i;
|
||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
@@ -313,6 +319,7 @@ Int GetExecWordEnd(Buffer *buffer, Int pos) {
|
|||||||
// semantics - proper max is one past last index
|
// semantics - proper max is one past last index
|
||||||
if (!(i < buffer->len)) break;
|
if (!(i < buffer->len)) break;
|
||||||
if (IsWhitespace(buffer->str[i])) break;
|
if (IsWhitespace(buffer->str[i])) break;
|
||||||
|
if (GetChar(buffer, i - 1) == L'<' && GetChar(buffer, i) == L'|') break;
|
||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
@@ -438,6 +445,18 @@ Range EncloseExecWord(Buffer *buffer, Int pos) {
|
|||||||
return result;
|
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 EncloseLine(Buffer *buffer, Int pos) {
|
||||||
Range result = {GetLineStart(buffer, pos), GetLineEnd(buffer, pos)};
|
Range result = {GetLineStart(buffer, pos), GetLineEnd(buffer, pos)};
|
||||||
return result;
|
return result;
|
||||||
@@ -464,11 +483,6 @@ Int GetPrevChar(Buffer *buffer, Int pos) {
|
|||||||
return result;
|
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) {
|
Int GetLineIndent(Buffer *buffer, Int line) {
|
||||||
String16 string = GetLineStringWithoutNL(*buffer, line);
|
String16 string = GetLineStringWithoutNL(*buffer, line);
|
||||||
Int indent = 0;
|
Int indent = 0;
|
||||||
|
|||||||
@@ -113,31 +113,10 @@ void PreBeginEdit_SaveCaretHistory(Buffer *buffer, Array<Caret> &carets) {
|
|||||||
BeginEdit({}, buffer, carets);
|
BeginEdit({}, buffer, carets);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KILL_SELECTION = true;
|
void AdjustCarets(Array<Edit> edits, Array<Caret> *carets, bool kill_selection = false) {
|
||||||
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
|
|
||||||
//
|
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Array<Caret> new_carets = TightCopy(scratch, *carets);
|
Array<Caret> new_carets = TightCopy(scratch, *carets);
|
||||||
ForItem(edit, *edits) {
|
ForItem(edit, edits) {
|
||||||
Int remove_size = GetSize(edit.range);
|
Int remove_size = GetSize(edit.range);
|
||||||
Int insert_size = edit.string.len;
|
Int insert_size = edit.string.len;
|
||||||
Int offset = insert_size - remove_size;
|
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);
|
Int p = ScreenSpaceToBufferPosErrorOutOfBounds(window, view, buffer, mouse);
|
||||||
if (p != -1) {
|
if (p != -1) {
|
||||||
Range enclose = EncloseExecWord(buffer, p);
|
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);
|
String16 string = GetString(*buffer, enclose);
|
||||||
Command_EvalLua(view, string);
|
Command_EvalLua(view, string);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,14 +201,18 @@ void Command_MoveLine(View *view, int direction) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Replace(View *view, String16 string) {
|
Array<Edit> Command_ReplaceEx(Allocator scratch, View *view, String16 string) {
|
||||||
Scratch scratch;
|
|
||||||
|
|
||||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||||
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
|
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
|
||||||
MergeCarets(view);
|
MergeCarets(view);
|
||||||
For(view->carets) AddEdit(&edits, it.range, string);
|
For(view->carets) AddEdit(&edits, it.range, string);
|
||||||
EndEdit(buffer, &edits, &view->carets);
|
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) {
|
void Command_DuplicateLine(View *view, int direction) {
|
||||||
@@ -889,7 +893,10 @@ void WindowCommand(Event event, Window *window, View *view) {
|
|||||||
} else if (Alt(SDLK_Q)) {
|
} else if (Alt(SDLK_Q)) {
|
||||||
Caret caret = view->carets[0];
|
Caret caret = view->carets[0];
|
||||||
Range range = caret.range;
|
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);
|
String16 string = GetString(*buffer, range);
|
||||||
|
|
||||||
Command_EvalLua(view, string);
|
Command_EvalLua(view, string);
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ Color.MainCaret = GruvboxDark0Hard
|
|||||||
Color.SubCaret = GruvboxGray245
|
Color.SubCaret = GruvboxGray245
|
||||||
Color.Selection = GruvboxLight1
|
Color.Selection = GruvboxLight1
|
||||||
Color.WhitespaceDuringSelection = GruvboxLight4
|
Color.WhitespaceDuringSelection = GruvboxLight4
|
||||||
|
Color.MouseUnderline = GruvboxDark0Hard
|
||||||
|
Color.CaretUnderline = GruvboxGray245
|
||||||
Color.FuzzySearchLineHighlight = GruvboxDark0
|
Color.FuzzySearchLineHighlight = GruvboxDark0
|
||||||
Color.ScrollbarBackground = GruvboxLight2
|
Color.ScrollbarBackground = GruvboxLight2
|
||||||
Color.ScrollbarScroller = GruvboxLight1
|
Color.ScrollbarScroller = GruvboxLight1
|
||||||
@@ -237,8 +239,8 @@ function GenericTextFileRule(_s)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
line, col, _s = ChopLineAndColumn(_s)
|
|
||||||
_s = ChopColon(_s)
|
_s = ChopColon(_s)
|
||||||
|
line, col, _s = ChopLineAndColumn(_s)
|
||||||
file_path = match_path(_s)
|
file_path = match_path(_s)
|
||||||
return {kind = "text", file_path = file_path, line = line, col = col}
|
return {kind = "text", file_path = file_path, line = line, col = col}
|
||||||
end
|
end
|
||||||
@@ -299,6 +301,8 @@ void ReloadStyle() {
|
|||||||
ColorSubCaret = GetColor("SubCaret", ColorSubCaret);
|
ColorSubCaret = GetColor("SubCaret", ColorSubCaret);
|
||||||
ColorSelection = GetColor("Selection", ColorSelection);
|
ColorSelection = GetColor("Selection", ColorSelection);
|
||||||
ColorWhitespaceDuringSelection = GetColor("WhitespaceDuringSelection", ColorWhitespaceDuringSelection);
|
ColorWhitespaceDuringSelection = GetColor("WhitespaceDuringSelection", ColorWhitespaceDuringSelection);
|
||||||
|
ColorMouseUnderline = GetColor("MouseUnderline", ColorMouseUnderline);
|
||||||
|
ColorCaretUnderline = GetColor("CaretUnderline", ColorCaretUnderline);
|
||||||
ColorFuzzySearchLineHighlight = GetColor("FuzzySearchLineHighlight", ColorFuzzySearchLineHighlight);
|
ColorFuzzySearchLineHighlight = GetColor("FuzzySearchLineHighlight", ColorFuzzySearchLineHighlight);
|
||||||
ColorScrollbarBackground = GetColor("ScrollbarBackground", ColorScrollbarBackground);
|
ColorScrollbarBackground = GetColor("ScrollbarBackground", ColorScrollbarBackground);
|
||||||
ColorScrollbarScroller = GetColor("ScrollbarScroller", ColorScrollbarScroller);
|
ColorScrollbarScroller = GetColor("ScrollbarScroller", ColorScrollbarScroller);
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ Color ColorMainCaret = GruvboxDark0Hard;
|
|||||||
Color ColorSubCaret = GruvboxGray245;
|
Color ColorSubCaret = GruvboxGray245;
|
||||||
Color ColorSelection = GruvboxLight1;
|
Color ColorSelection = GruvboxLight1;
|
||||||
Color ColorWhitespaceDuringSelection = GruvboxLight4;
|
Color ColorWhitespaceDuringSelection = GruvboxLight4;
|
||||||
|
Color ColorMouseUnderline = GruvboxDark0Hard;
|
||||||
|
Color ColorCaretUnderline = GruvboxGray245;
|
||||||
Color ColorFuzzySearchLineHighlight = GruvboxDark0;
|
Color ColorFuzzySearchLineHighlight = GruvboxDark0;
|
||||||
Color ColorScrollbarBackground = GruvboxLight2;
|
Color ColorScrollbarBackground = GruvboxLight2;
|
||||||
Color ColorScrollbarScroller = GruvboxLight1;
|
Color ColorScrollbarScroller = GruvboxLight1;
|
||||||
|
|||||||
@@ -111,6 +111,9 @@ void ReplaceTitleBarData(Window *window) {
|
|||||||
Caret caret = last_view->carets[0];
|
Caret caret = last_view->carets[0];
|
||||||
XY xy = PosToXY(*last_buffer, GetFront(caret));
|
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);
|
Array<Caret> caret_copy = Copy(GetSystemAllocator(), view->carets);
|
||||||
defer {
|
defer {
|
||||||
Dealloc(&view->carets);
|
Dealloc(&view->carets);
|
||||||
@@ -121,7 +124,8 @@ void ReplaceTitleBarData(Window *window) {
|
|||||||
Range replace_range = {0, buffer->len};
|
Range replace_range = {0, buffer->len};
|
||||||
if (!Seek(buffer_string, L" |", &replace_range.max)) {
|
if (!Seek(buffer_string, L" |", &replace_range.max)) {
|
||||||
Command_SelectRangeOneCursor(view, GetEndAsRange(*buffer));
|
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);
|
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);
|
String16 string_to_replace = GetString(*buffer, replace_range);
|
||||||
if (string_to_replace != string) {
|
if (string_to_replace != string) {
|
||||||
Command_SelectRangeOneCursor(view, replace_range);
|
Command_SelectRangeOneCursor(view, replace_range);
|
||||||
Command_Replace(view, string);
|
Array<Edit> edits = Command_ReplaceEx(scratch, view, string);
|
||||||
Command_SelectRangeOneCursor(view, {});
|
Command_SelectRangeOneCursor(view, {});
|
||||||
|
AdjustCarets(edits, &caret_copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,10 +4,7 @@
|
|||||||
- I think clipboard adds \r\n, let's execute the conversion on that
|
- I think clipboard adds \r\n, let's execute the conversion on that
|
||||||
- prevent lua from infinite looping
|
- prevent lua from infinite looping
|
||||||
- Append to console and change console directory
|
- Append to console and change console directory
|
||||||
- c'git grep'
|
|
||||||
- EncloseExecWord should enclose the string also (add limitation)
|
|
||||||
- hotkey to select window title
|
- 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 as a command to execute which is going to be in the title bar
|
||||||
- search backwards
|
- search backwards
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ void DrawCaret(Window *window, XY xy, float size, Color color) {
|
|||||||
DrawRect(ToRect2(rect), 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_min = PosToXY(*buffer, range.min);
|
||||||
XY xy_max = PosToXY(*buffer, range.max);
|
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
|
// optimizing and so on
|
||||||
if (xy_min.line != xy_max.line) return;
|
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};
|
Vec2I max = {xy_max.col * FontCharSpacing, (xy_max.line + 1) * FontLineSpacing};
|
||||||
Rect2I rect = {min, max};
|
Rect2I rect = {min, max};
|
||||||
rect -= view->scroll;
|
rect -= view->scroll;
|
||||||
rect += window->document_rect.min;
|
rect += window->document_rect.min;
|
||||||
DrawRectOutline(rect, ColorText);
|
DrawRectOutline(rect, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawWindow(Window *window, Event &event) {
|
void DrawWindow(Window *window, Event &event) {
|
||||||
@@ -197,16 +197,16 @@ void DrawWindow(Window *window, Event &event) {
|
|||||||
if (p != -1) {
|
if (p != -1) {
|
||||||
Range range = enclose_proc(buffer, p);
|
Range range = enclose_proc(buffer, p);
|
||||||
if (InBounds(caret.range, p)) range = caret.range;
|
if (InBounds(caret.range, p)) range = caret.range;
|
||||||
DrawUnderline(window, view, buffer, range);
|
DrawUnderline(window, view, buffer, range, ColorMouseUnderline, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_active) {
|
if (is_active) {
|
||||||
if (GetSize(caret.range) == 0) {
|
if (GetSize(caret.range) == 0) {
|
||||||
Range range = enclose_proc(buffer, caret.range.min);
|
Range range = enclose_proc(buffer, caret.range.min);
|
||||||
DrawUnderline(window, view, buffer, range);
|
DrawUnderline(window, view, buffer, range, ColorCaretUnderline);
|
||||||
} else {
|
} else {
|
||||||
DrawUnderline(window, view, buffer, caret.range);
|
DrawUnderline(window, view, buffer, caret.range, ColorCaretUnderline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user