Command bar, undo merge time

This commit is contained in:
Krzosa Karol
2025-12-07 13:57:51 +01:00
parent df84d1605d
commit ef6a7be285
15 changed files with 161 additions and 79 deletions

View File

@@ -68,6 +68,7 @@ Style.Font = GetExeDir().."/CascadiaMono.ttf"
Style.VCVarsall = "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat"
Style.TrimWhitespaceOnSave = true
Style.ClangFormatOnSave = false
Style.StyleUndoMergeTimeout = 0.3
INTERNET_BROWSER = 'C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe'
OS_WINDOWS = 0
@@ -332,7 +333,7 @@ function MatchExec(s, meta)
end
Eval(s)
return {kind = "skip"}
return nil
end
BuiltinOnOpenMatchers = {

View File

@@ -1097,3 +1097,7 @@ API void CloseStdin(Process *process) {
}
#endif
API double GetTimeSeconds() {
return GetTimeMicros() / 1000000.0;
}

View File

@@ -917,6 +917,7 @@ API void AddEdit(Array<Edit> *e, Range range, String16 string) {
void SaveHistoryBeforeMergeCursor(Buffer *buffer, Array<HistoryEntry> *stack, Array<Caret> &carets) {
if (buffer->no_history) return;
HistoryEntry entry = {};
entry.time = GetTimeSeconds();
entry.carets = TightCopy(GetSystemAllocator(), carets);
Add(stack, entry);
}
@@ -992,7 +993,15 @@ API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
Allocator sys_allocator = GetSystemAllocator();
For(entry.edits) Dealloc(sys_allocator, it.string.data);
Dealloc(&entry.edits);
if (buffer->undo_stack.len > 0) {
HistoryEntry *next = GetLast(buffer->undo_stack);
if (entry.time - next->time <= 0.3) {
UndoEdit(buffer, carets);
}
}
}
API void DeallocHistoryEntries(Array<HistoryEntry> *entries) {
For(*entries) {
@@ -1003,6 +1012,11 @@ API void DeallocHistoryEntries(Array<HistoryEntry> *entries) {
entries->len = 0;
}
API void ResetHistory(Buffer *buffer) {
DeallocHistoryEntries(&buffer->redo_stack);
DeallocHistoryEntries(&buffer->undo_stack);
}
void ClearRedoStack(Buffer *buffer) {
DeallocHistoryEntries(&buffer->redo_stack);
}

View File

@@ -12,6 +12,7 @@ struct Edit {
struct HistoryEntry {
Array<Edit> edits;
Array<Caret> carets;
double time;
};
struct Buffer {
@@ -156,6 +157,7 @@ API void AssertRanges(Array<Caret> carets);
API void RedoEdit(Buffer *buffer, Array<Caret> *carets);
API void UndoEdit(Buffer *buffer, Array<Caret> *carets);
API void ResetHistory(Buffer *buffer);
API void DeallocHistoryArray(Array<HistoryEntry> *entries);
API void DeallocHistoryEntries(Array<HistoryEntry> *entries);

View File

@@ -1141,7 +1141,7 @@ int Lua_Cmd(lua_State *L) {
}
void Command_ListBuffers() {
BSet main = GetLastActiveLayoutSet();
BSet main = GetActiveSet();
ActiveWindow = main.window->id;
JumpGarbageBuffer(&main);
For(Buffers) {

View File

@@ -46,6 +46,29 @@ void UpdateScroll(Window *window, bool update_caret_scrolling) {
}
}
void FuzzySearchOpen(BSet active) {
bool success = false;
Range range = active.view->carets[0].range;
if (GetSize(range) == 0) {
Int line = PosToLine(active.buffer, range.min);
if ((active.buffer->line_starts.len - 1) == line) {
line = ClampBottom(0ll, line - 1ll);
}
String16 string = GetLineStringWithoutNL(active.buffer, line);
Int idx = 0;
if (Seek(string, u"||", &idx)) {
string = Skip(string, idx + 3);
Command_Open(string);
success = true;
}
}
if (!success) {
Command_Open(FetchLoadWord());
}
}
void OnCommand(Event event) {
ProfileFunction();
//
@@ -196,9 +219,7 @@ void OnCommand(Event event) {
}
}
if (Shift() && Ctrl() && Mouse(LEFT)) {
MouseLoadWord(event, "exec");
} else if (Ctrl() && Mouse(LEFT)) {
if (Ctrl() && Mouse(LEFT)) {
MouseLoadWord(event);
} else if (Mouse(LEFT)) { // Uses Alt and shift
Vec2I mouse = MouseVec2I();
@@ -270,23 +291,21 @@ void OnCommand(Event event) {
main.window->kill = true;
}
if (CtrlAltPress(SDLK_P)) {
Command_ListBuffers();
} else if (CtrlPress(SDLK_P)) {
Command_ListCode();
// Command_ListCode();
Window *window = GetWindow(CommandBarWindowID);
window->visible = !window->visible;
ActiveWindow = window->id;
BSet set = GetBSet(window);
Command_ListBuffers();
}
if (CtrlPress(SDLK_0)) {
ToggleVisibility(DebugWindowID);
Window *window = GetWindow(DebugWindowID);
window->visible = !window->visible;
}
if (CtrlPress(SDLK_GRAVE)) {
if (ActiveWindow != NullWindowID) {
ActiveWindow = NullWindowID;
} else {
}
}
if (CtrlPress(SDLK_1)) {
ActiveWindow = GetOverlappingWindow({0,0}, GetWindow(ActiveWindow))->id;
}
@@ -320,8 +339,12 @@ void OnCommand(Event event) {
return;
}
if (active.view->fuzzy_search) {
if (Press(SDLK_RETURN)) {
FuzzySearchOpen(active);
return;
}
}
if (event.kind == EVENT_DROP_FILE) {
WindowOpenBufferView(active.window, event.text);
@@ -522,6 +545,7 @@ void OnCommand(Event event) {
RawReplaceText(temp_buffer, GetBufferEndAsRange(temp_buffer), last_line_string);
Caret caret = active.view->carets[0];
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
Command_SelectEntireBuffer(active.view);
Command_Replace(active.view, GetString(temp_buffer));
active.view->carets[0] = caret;
@@ -562,32 +586,9 @@ void OnCommand(Event event) {
}
if (CtrlPress(SDLK_SEMICOLON) || CtrlShiftPress(SDLK_Q)) {
Command_Open(FetchLoadWord(), "exec");
}
else if (CtrlPress(SDLK_Q)) {
if (CtrlPress(SDLK_Q)) {
if (active.view->fuzzy_search) {
bool success = false;
Range range = active.view->carets[0].range;
if (GetSize(range) == 0) {
Int line = PosToLine(active.buffer, range.min);
if ((active.buffer->line_starts.len - 1) == line) {
line = ClampBottom(0ll, line - 1ll);
}
String16 string = GetLineStringWithoutNL(active.buffer, line);
Int idx = 0;
if (Seek(string, u"||", &idx)) {
string = Skip(string, idx + 3);
Command_Open(string);
success = true;
}
}
if (!success) {
Command_Open(FetchLoadWord());
}
FuzzySearchOpen(active);
} else {
Command_Open(FetchLoadWord());
}
@@ -602,3 +603,22 @@ void OnCommand(Event event) {
MergeCarets(active.buffer, &active.view->carets);
IF_DEBUG(AssertRanges(active.view->carets));
}
void PostCommandUpdate() {
For (Windows) {
if (it->sync_visibility_with_focus) {
if (it->id == ActiveWindow) {
it->visible = true;
} else {
it->visible = false;
}
}
}
if (ActiveWindow.id != LastActiveLayoutWindowID.id) {
Window *window = GetWindow(ActiveWindow);
if (window->layout) {
LastActiveLayoutWindowID = ActiveWindow;
}
}
}

View File

@@ -29,4 +29,5 @@ void ReloadStyle() {
StyleFontFilter = GetStyleInt("FontFilter", StyleFontFilter);
StyleFont = GetStyleString("Font", StyleFont);
StyleVCVarsall = GetStyleString("VCVarsall", StyleVCVarsall);
StyleUndoMergeTimeout = GetStyleFloat("UndoMergeTimeout", StyleUndoMergeTimeout);
}

View File

@@ -69,6 +69,7 @@ Style.Font = GetExeDir().."/CascadiaMono.ttf"
Style.VCVarsall = "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat"
Style.TrimWhitespaceOnSave = true
Style.ClangFormatOnSave = false
Style.StyleUndoMergeTimeout = 0.3
INTERNET_BROWSER = 'C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe'
OS_WINDOWS = 0
@@ -333,7 +334,7 @@ function MatchExec(s, meta)
end
Eval(s)
return {kind = "skip"}
return nil
end
BuiltinOnOpenMatchers = {

View File

@@ -65,3 +65,4 @@ Int StyleFontSize = 15;
Int StyleFontFilter = 0;
String StyleFont = "/home/krz/text_editor/package/CascadiaMono.ttf";
String StyleVCVarsall = "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat";
double StyleUndoMergeTimeout = 0.3;

View File

@@ -130,6 +130,22 @@ static void HookLuaForceExit(lua_State *L, lua_Debug *debug) {
luaL_error(L, "lua execution got interrupted");
}
double GetStyleFloat(String name, double default_float) {
double result = default_float;
lua_getglobal(LuaState, "Style");
defer { lua_pop(LuaState, 1); };
if (lua_istable(LuaState, -1)) {
lua_pushlstring(LuaState, name.data, name.len);
lua_gettable(LuaState, -2);
defer { lua_pop(LuaState, 1); };
if (lua_isnumber(LuaState, -1) || lua_isboolean(LuaState, -1) || lua_isinteger(LuaState, -1)) {
lua_Number num = lua_tonumber(LuaState, -1);
result = (double)num;
}
}
return result;
}
Int GetStyleInt(String name, Int default_int) {
Int result = default_int;
lua_getglobal(LuaState, "Style");
@@ -194,23 +210,24 @@ String GetFieldString(lua_State *L, String name) {
return result;
}
Int GetInt(lua_State *L, const char *name) {
Int GetFieldInt(lua_State *L, const char *name) {
lua_getfield(L, -1, name);
lua_Integer num = lua_tointeger(L, -1);
lua_pop(L, 1);
return (Int)num;
}
double GetFloat(lua_State *L, const char *name) {
double GetFieldFloat(lua_State *L, const char *name) {
lua_getfield(L, -1, name);
double num = lua_tonumber(L, -1);
lua_pop(L, 1);
return num;
}
const char *GetString(lua_State *L, const char *name) {
const char *GetFieldString(lua_State *L, const char *name) {
lua_getfield(L, -1, name);
const char *result = lua_tostring(L, -1);
lua_pop(L, 1);
return result;
}
@@ -239,7 +256,7 @@ int Lua_Play(lua_State *L) {
defer { lua_pop(L, 1); };
Event event = {};
#define X(TYPE, KIND, NAME) event.NAME = (TYPE)Get##KIND(L, #NAME);
#define X(TYPE, KIND, NAME) event.NAME = (TYPE)GetField##KIND(L, #NAME);
EVENT_FIELDS
#undef X
Add(&EventPlayback, event);

View File

@@ -15,6 +15,7 @@ WindowID DebugWindowID;
ViewID DebugViewID;
BufferID DebugBufferID;
WindowID CommandBarWindowID;
WindowID StatusBarWindowID;
WindowID SearchBarWindowID;
ViewID SearchViewID;
@@ -407,13 +408,6 @@ bool BufferIsReferenced(BufferID buffer_id) {
void GarbageCollect() {
Allocator sys_allocator = GetSystemAllocator();
if (ActiveWindow.id != LastActiveLayoutWindowID.id) {
Window *window = GetWindow(ActiveWindow);
if (window->layout) {
LastActiveLayoutWindowID = ActiveWindow;
}
}
For(Buffers) {
if (it->file_mod_time) {
int64_t new_file_mod_time = GetFileModTime(it->name);

View File

@@ -246,6 +246,7 @@ void Update(Event event) {
}
OnCommand(event);
PostCommandUpdate();
UpdateProcesses();
CoUpdate(&event);
ReloadLuaConfigs();

View File

@@ -40,6 +40,7 @@ struct Window {
bool visible : 1;
bool layout : 1;
bool kill : 1;
bool sync_visibility_with_focus : 1;
};
};

View File

@@ -110,4 +110,5 @@ void StatusBarUpdate() {
}
Command_SelectRangeOneCursor(title.view, MakeRange(0));
ResetHistory(title.buffer);
}

View File

@@ -6,19 +6,7 @@ Array<Window *> GetWindowZOrder(Allocator allocator) {
return order;
}
void SetVisibility(WindowID window_id, bool v) {
Window *window = GetWindow(window_id);
window->visible = v;
}
bool ToggleVisibility(WindowID window_id) {
Window *window = GetWindow(window_id);
bool visible = !window->visible;
SetVisibility(window_id, visible);
return visible;
}
Int GetTitleBarSize(Window *window) {
Int GetExpandingBarSize(Window *window) {
View *view = GetView(window->active_view);
Buffer *buffer = GetBuffer(view->active_buffer);
float result = (float)buffer->line_starts.len * window->font->line_spacing;
@@ -40,6 +28,23 @@ void InitWindows() {
}
}
// COMMAND BAR
{
Window *window = CreateWind();
CommandBarWindowID = window->id;
Buffer *buffer = CreateBuffer(SysAllocator, "command_bar");
View *view = CreateView(buffer->id);
window->active_view = view->id;
window->draw_line_numbers = false;
window->draw_scrollbar = false;
window->draw_darker = true;
window->draw_line_highlight = false;
window->layout = false;
window->visible = false;
window->sync_visibility_with_focus = true;
buffer->no_history = true;
}
// SEARCH BAR
{
Window *window = CreateWind();
@@ -64,7 +69,6 @@ void InitWindows() {
Buffer *buffer = CreateBuffer(SysAllocator, "status_bar");
View *view = CreateView(buffer->id);
window->active_view = view->id;
buffer->no_history = true;
window->font = &SecondaryFont;
window->draw_line_numbers = false;
window->draw_scrollbar = false;
@@ -91,7 +95,7 @@ void InitWindows() {
DebugViewID = view->id;
window->active_view = view->id;
SetVisibility(window->id, false);
window->visible = false;
}
}
@@ -118,20 +122,40 @@ double WindowCalcEvenResizerValue(Int screen_size_x, Int *out_count = NULL) {
void LayoutWindows(int16_t wx, int16_t wy) {
Rect2I screen_rect = RectI0Size(wx, wy);
// Command bar
{
Window *n = GetWindow(CommandBarWindowID);
Rect2I *rect = &screen_rect;
Rect2I copy_rect = screen_rect;
if (!n->visible) {
rect = &copy_rect;
}
Int barsize = Clamp((Int)n->font->line_spacing*10, (Int)0, (Int)wx - 100);
n->document_rect = n->total_rect = CutBottom(rect, barsize);
}
// bar at the bottom
{
Window *n = GetWindow(StatusBarWindowID);
Int barsize = GetTitleBarSize(n);
n->document_rect = n->total_rect = CutBottom(&screen_rect, barsize);
Rect2I *rect = &screen_rect;
Rect2I copy_rect = screen_rect;
if (!n->visible) {
rect = &copy_rect;
}
Int barsize = GetExpandingBarSize(n);
n->document_rect = n->total_rect = CutBottom(rect, barsize);
}
// search bar
{
Window *n = GetWindow(SearchBarWindowID);
if (n->visible) {
Int barsize = GetTitleBarSize(n);
n->document_rect = n->total_rect = CutBottom(&screen_rect, barsize);
Rect2I *rect = &screen_rect;
Rect2I copy_rect = screen_rect;
if (!n->visible) {
rect = &copy_rect;
}
Int barsize = GetExpandingBarSize(n);
n->document_rect = n->total_rect = CutBottom(rect, barsize);
}
// floating debug window