Compare commits

...

3 Commits

Author SHA1 Message Date
krzosa
c67db4e495 Implement new search window 2025-12-23 08:52:42 +01:00
krzosa
edc941bf53 Make OpenCode into coroutine 2025-12-23 08:14:22 +01:00
krzosa
edb2379bce Invert command window 2025-12-22 21:24:35 +01:00
14 changed files with 203 additions and 134 deletions

View File

@@ -1,7 +1,9 @@
- What precise workflow do I need for me to be viable to use this? - What precise workflow do I need for me to be viable to use this?
- From a user (novice) point of view, how does it look like? - From a user (novice) point of view, how does it look like?
- Show what process/coroutines are running and allow to kill (active process buffer?)
- ctrl + p like in VSCode (without special buffers) - ctrl + p like in VSCode (without special buffers)
- I THINK WE NEED A SPECIAL VIEW, this is too slow
- Move to the top so that it can be progressively expanded using coroutines by appending at the end - Move to the top so that it can be progressively expanded using coroutines by appending at the end
- Maybe 2 windows? - Maybe 2 windows?
- Guide on the first page for new users with links to configs, tutorials - Guide on the first page for new users with links to configs, tutorials

View File

@@ -553,55 +553,6 @@ API Range GetIndentRangeAtPos(Buffer *buffer, Int pos) {
return {range.min, range.min + indent}; return {range.min, range.min + indent};
} }
const Int FuzzyCloserWordBegin = 5;
const Int FuzzyConsecutiveMultiplier = 3;
API Int FuzzyRate(String16 string, String16 with) {
if (with.len == 0) return 0;
Int points = 0;
Int consecutive = 0;
Int with_i = 0;
for (Int i = 0; i < string.len; i++) {
if (string.data[i] == with[with_i]) {
Int closer_begin = ClampBottom((Int)0, FuzzyCloserWordBegin - i);
points += closer_begin;
consecutive++;
with_i += 1;
} else {
points += consecutive * FuzzyConsecutiveMultiplier;
consecutive = 0;
with_i = 0;
}
if (with_i >= with.len) with_i = 0;
}
points += consecutive * FuzzyConsecutiveMultiplier;
return points;
}
API Array<FuzzyPair> FuzzySearchLines(Allocator allocator, Buffer *buffer, Int line_min, Int line_max, String16 needle) {
if (line_min < 0 || line_min >= buffer->line_starts.len) return {};
if (line_max < 0 || line_min > buffer->line_starts.len) return {};
Array<FuzzyPair> ratings = {allocator};
for (Int i = line_min; i < line_max; i += 1) {
String16 s = GetLineStringWithoutNL(buffer, i);
Int rating = FuzzyRate(s, needle);
Add(&ratings, {i, rating});
}
// bubble sort
for (Int i = 0; i < ratings.len - 1; i++) {
for (Int j = 0; j < ratings.len - 1; j++) {
if (ratings[j].rating < ratings[j + 1].rating) {
FuzzyPair temp = ratings[j];
ratings[j] = ratings[j + 1];
ratings[j + 1] = temp;
}
}
}
return ratings;
}
API Int FindRangeByPos(Array<Range> *ranges, Int pos) { API Int FindRangeByPos(Array<Range> *ranges, Int pos) {
// binary search // binary search
Int low = 0; Int low = 0;
@@ -1538,6 +1489,7 @@ String16 ToUnixString16(Allocator allocator, String string_) {
} }
Buffer *BufferOpenFile(String path) { Buffer *BufferOpenFile(String path) {
ProfileFunction();
Allocator sys_allocator = GetSystemAllocator(); Allocator sys_allocator = GetSystemAllocator();
Scratch scratch; Scratch scratch;

View File

@@ -18,6 +18,7 @@ struct HistoryEntry {
struct Buffer { struct Buffer {
BufferID id; BufferID id;
String name; String name;
Int begin_frame_change_id;
Int change_id; Int change_id;
Int user_change_id; Int user_change_id;
Int file_mod_time; Int file_mod_time;

View File

@@ -646,33 +646,51 @@ void Command_SetWorkDir() {
} RegisterCommand(Command_SetWorkDir, ""); } RegisterCommand(Command_SetWorkDir, "");
String CodeEndings[] = { ".c", ".cpp", ".h", ".hpp", ".py", ".lua", ".cxx", ".hxx", }; String CodeEndings[] = { ".c", ".cpp", ".h", ".hpp", ".py", ".lua", ".cxx", ".hxx", };
String Coro_OpenCodeDir;
void OpenCodeRecursive(String dir) { void Coro_OpenCode(mco_coro *co) {
Scratch scratch; BlockArena arena = {};
for (FileIter it = IterateFiles(scratch, dir); IsValid(it); Advance(&it)) { Array<String> dirs = {arena};
if (it.filename == ".git") { Add(&dirs, Coro_OpenCodeDir);
continue; int i = 0;
} for (int diri = 0; diri < dirs.len; diri += 1) {
for (FileIter it = IterateFiles(arena, dirs[diri]); IsValid(it); Advance(&it)) {
if (it.filename == ".git") {
continue;
}
if (it.is_directory) { if (it.is_directory) {
OpenCodeRecursive(it.absolute_path); Add(&dirs, it.absolute_path);
} else { } else {
bool match = false; bool match = false;
ForItem (ending, CodeEndings) { ForItem (ending, CodeEndings) {
if (EndsWith(it.absolute_path, ending)) { if (EndsWith(it.absolute_path, ending)) {
match = true; match = true;
break; break;
}
}
if (match) {
BufferOpenFile(it.absolute_path);
} }
} }
if (match) {
BufferOpenFile(it.absolute_path);
if ((i%16) == 0) {
CoYield(co);
} }
i += 1;
} }
} }
Release(&arena);
}
void OpenCode(String dir) {
Coro_OpenCodeDir = dir;
CoAdd(Coro_OpenCode);
} }
void Command_OpenCode() { void Command_OpenCode() {
OpenCodeRecursive(WorkDir); OpenCode(WorkDir);
} RegisterCommand(Command_OpenCode, ""); } RegisterCommand(Command_OpenCode, "");
void Command_KillProcess() { void Command_KillProcess() {
@@ -818,7 +836,7 @@ void Command_MakeFontSmaller() {
void Command_Open() { void Command_Open() {
BSet active = GetBSet(ActiveWindowID); BSet active = GetBSet(ActiveWindowID);
if (active.window->id == CommandBarWindowID) { if (active.window->id == CommandWindowID) {
CommandWindowOpen(active); CommandWindowOpen(active);
} else { } else {
Open(FetchLoadWord(active.view)); Open(FetchLoadWord(active.view));
@@ -1043,8 +1061,10 @@ void Command_InsertNewLineDown() {
void Command_NewLine() { void Command_NewLine() {
BSet active = GetBSet(ActiveWindowID); BSet active = GetBSet(ActiveWindowID);
if (active.window->id == CommandBarWindowID) { if (active.window->id == CommandWindowID) {
CommandWindowOpen(active); CommandWindowOpen(active);
} else if (active.window->id == SearchWindowID) {
SearchWindowFindNext(true);
} else { } else {
IdentedNewLine(active.view); IdentedNewLine(active.view);
} }
@@ -1090,7 +1110,6 @@ void Command_ClearCarets() {
active.view->carets.len = 1; active.view->carets.len = 1;
active.view->carets[0] = MakeCaret(GetFront(active.view->carets[0])); active.view->carets[0] = MakeCaret(GetFront(active.view->carets[0]));
// @todo: move to hook post command???
if (active.window->lose_focus_on_escape && active.window->id == ActiveWindowID) { if (active.window->lose_focus_on_escape && active.window->id == ActiveWindowID) {
if (active.window->layout) { if (active.window->layout) {
// //
@@ -1098,4 +1117,13 @@ void Command_ClearCarets() {
ActiveWindowID = LastActiveLayoutWindowID; ActiveWindowID = LastActiveLayoutWindowID;
} }
} }
For (Windows) {
if (it->lose_visibility_on_escape && it->visible) {
if (ActiveWindowID == it->id) {
ActiveWindowID = LastActiveLayoutWindowID;
}
it->visible = false;
}
}
} RegisterCommand(Command_ClearCarets, "escape"); } RegisterCommand(Command_ClearCarets, "escape");

View File

@@ -1,4 +1,4 @@
typedef void CoroutineProc(mco_coro *co); typedef void CoroutineProc(mco_coro *co);
Array<mco_coro *> ActiveCoroutines; Array<mco_coro *> ActiveCoroutines;
mco_coro *CoAdd(CoroutineProc *proc) { mco_coro *CoAdd(CoroutineProc *proc) {
@@ -18,6 +18,7 @@ mco_coro *CoAdd(CoroutineProc *proc) {
void CoUpdate(Event *event) { void CoUpdate(Event *event) {
ProfileFunction(); ProfileFunction();
double start = GetTimeSeconds();
IterRemove(ActiveCoroutines) { IterRemove(ActiveCoroutines) {
IterRemovePrepare(ActiveCoroutines); IterRemovePrepare(ActiveCoroutines);
@@ -34,6 +35,11 @@ void CoUpdate(Event *event) {
remove_item = true; remove_item = true;
} }
} }
double took = GetTimeSeconds() - start;
if (took > 0.01) {
break;
}
} }
} }
@@ -47,3 +53,8 @@ Event *CoYield(mco_coro *co) {
return event; return event;
} }
void CoRemove(mco_coro *co) {
UnorderedRemove(&ActiveCoroutines, co);
mco_destroy(co);
}

View File

@@ -25,9 +25,9 @@ WindowID DebugWindowID;
ViewID DebugViewID; ViewID DebugViewID;
BufferID DebugBufferID; BufferID DebugBufferID;
WindowID CommandBarWindowID; WindowID CommandWindowID;
WindowID StatusBarWindowID; WindowID StatusBarWindowID;
WindowID SearchBarWindowID; WindowID SearchWindowID;
ViewID SearchViewID; ViewID SearchViewID;
BufferID SearchBufferID; BufferID SearchBufferID;

View File

@@ -396,12 +396,12 @@ void EndProfileScope() {
(uint64_t)GetTimeMicros() // timestamp in microseconds -- end of your timing block (uint64_t)GetTimeMicros() // timestamp in microseconds -- end of your timing block
); );
} }
#define ProfileScopeD(name) ProfileScopeEx PROFILE_SCOPE_VAR_##name((name).data, (name).len) #define ProfileScopeEx(name) ProfileScopeClass PROFILE_SCOPE_VAR_((name).data, (int)(name).len)
#define ProfileScope(name) ProfileScopeEx PROFILE_SCOPE_VAR_##name(#name, sizeof(#name) - 1) #define ProfileScope(name) ProfileScopeClass PROFILE_SCOPE_VAR_##name(#name, sizeof(#name) - 1)
#define ProfileFunction() ProfileScopeEx PROFILE_SCOPE_FUNCTION(__FUNCTION__, sizeof(__FUNCTION__) - 1) #define ProfileFunction() ProfileScopeClass PROFILE_SCOPE_FUNCTION(__FUNCTION__, sizeof(__FUNCTION__) - 1)
struct ProfileScopeEx { struct ProfileScopeClass {
ProfileScopeEx(const char *name, int len) { _BeginProfileScope(name, len); } ProfileScopeClass(const char *name, int len) { _BeginProfileScope(name, len); }
~ProfileScopeEx() { EndProfileScope(); } ~ProfileScopeClass() { EndProfileScope(); }
}; };
#else #else
#define ProfileScope(name) #define ProfileScope(name)

View File

@@ -23,6 +23,7 @@
#include "text_editor.h" #include "text_editor.h"
#include "globals.cpp" #include "globals.cpp"
#include "coroutines.cpp"
#include "buffer.cpp" #include "buffer.cpp"
#include "view.cpp" #include "view.cpp"
#include "window.cpp" #include "window.cpp"
@@ -39,7 +40,6 @@
#include "commands_clipboard.cpp" #include "commands_clipboard.cpp"
#include "draw.cpp" #include "draw.cpp"
#include "coroutines.cpp"
#include "test/tests.cpp" #include "test/tests.cpp"
@@ -388,11 +388,10 @@ void OnCommand(Event event) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
BSet active = GetBSet(ActiveWindowID); BSet active = GetBSet(ActiveWindowID);
Int buffer_change_id = active.buffer->change_id;
For (CommandFunctions) { For (CommandFunctions) {
if (it.trigger && MatchEvent(it.trigger, &event)) { if (it.trigger && MatchEvent(it.trigger, &event)) {
ProfileScopeEx(it.name.data, (int)it.name.len); ProfileScopeEx(it.name);
it.function(); it.function();
LastExecutedCommand = it.function; LastExecutedCommand = it.function;
} }
@@ -500,6 +499,7 @@ void GarbageCollect() {
} }
void Update(Event event) { void Update(Event event) {
ProfileFunction();
LayoutWindows(event.xwindow, event.ywindow); LayoutWindows(event.xwindow, event.ywindow);
Scratch scratch; Scratch scratch;
@@ -513,12 +513,15 @@ void Update(Event event) {
view->update_scroll = true; view->update_scroll = true;
} }
OnCommand(event); OnCommand(event);
StatusWindowUpdate(); StatusWindowUpdate();
DebugWindowUpdate(); DebugWindowUpdate();
CommandWindowUpdate(); CommandWindowUpdate();
SearchWindowUpdate();
UpdateProcesses(); UpdateProcesses();
CoUpdate(&event); CoUpdate(&event);
For (Buffers) it->begin_frame_change_id = it->change_id; // after last place we modify
{ {
ProfileScope(WindowEndOfFrameVisibilityAndLastActive); ProfileScope(WindowEndOfFrameVisibilityAndLastActive);

View File

@@ -186,3 +186,4 @@ struct Register_Variable {
#define RegisterVariable(type, name, ...) \ #define RegisterVariable(type, name, ...) \
type name = __VA_ARGS__; \ type name = __VA_ARGS__; \
Register_Variable var_##name(&Variables, VariableType_##type, #name, &name) Register_Variable var_##name(&Variables, VariableType_##type, #name, &name)

View File

@@ -182,25 +182,6 @@ void Find(View *seek_view, String16 needle, bool forward = true) {
IF_DEBUG(AssertRanges(seek_view->carets)); IF_DEBUG(AssertRanges(seek_view->carets));
} }
void FuzzySortView(View *view, String16 needle) {
Buffer *buffer = GetBuffer(view->active_buffer);
Scratch scratch;
Array<FuzzyPair> ratings = FuzzySearchLines(scratch, buffer, 0, buffer->line_starts.len, needle);
Buffer *temp_buffer = CreateTempBuffer(scratch, buffer->cap);
For(ratings) {
String16 s = GetLineStringWithoutNL(buffer, it.index);
if (s.len == 0) continue;
RawReplaceText(temp_buffer, GetBufferEndAsRange(temp_buffer), s);
RawReplaceText(temp_buffer, GetBufferEndAsRange(temp_buffer), u"\n");
}
SelectEntireBuffer(view);
Replace(view, GetString(temp_buffer));
SelectRange(view, MakeRange(0));
}
void SelectAll(View *view, String16 needle) { void SelectAll(View *view, String16 needle) {
Buffer *buffer = GetBuffer(view->active_buffer); Buffer *buffer = GetBuffer(view->active_buffer);
String16 string_buffer = GetString(buffer); String16 string_buffer = GetString(buffer);

View File

@@ -15,7 +15,7 @@ struct Window {
double mouse_scroller_offset; double mouse_scroller_offset;
int z; int z;
double weight; double weight;
Int status_bar_last_buffer_change_id; Caret search_bar_anchor;
Array<GotoCrumb> goto_history; Array<GotoCrumb> goto_history;
Array<GotoCrumb> goto_redo; Array<GotoCrumb> goto_redo;
@@ -33,6 +33,7 @@ struct Window {
bool close : 1; bool close : 1;
bool sync_visibility_with_focus : 1; bool sync_visibility_with_focus : 1;
bool lose_focus_on_escape : 1; bool lose_focus_on_escape : 1;
bool lose_visibility_on_escape : 1;
bool jump_history : 1; bool jump_history : 1;
bool eval_command : 1; bool eval_command : 1;
}; };

View File

@@ -1,6 +1,6 @@
void CommandWindowInit() { void CommandWindowInit() {
Window *window = CreateWind(); Window *window = CreateWind();
CommandBarWindowID = window->id; CommandWindowID = window->id;
Buffer *buffer = CreateBuffer(SysAllocator, "command_bar"); Buffer *buffer = CreateBuffer(SysAllocator, "command_bar");
buffer->special = true; buffer->special = true;
View *view = CreateView(buffer->id); View *view = CreateView(buffer->id);
@@ -18,7 +18,7 @@ void CommandWindowInit() {
} }
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy) { void CommandWindowLayout(Rect2I *rect, Int wx, Int wy) {
Window *n = GetWindow(CommandBarWindowID); Window *n = GetWindow(CommandWindowID);
Rect2I copy_rect = *rect; Rect2I copy_rect = *rect;
if (!n->visible) { if (!n->visible) {
rect = &copy_rect; rect = &copy_rect;
@@ -27,25 +27,81 @@ void CommandWindowLayout(Rect2I *rect, Int wx, Int wy) {
n->document_rect = n->total_rect = CutBottom(rect, barsize); n->document_rect = n->total_rect = CutBottom(rect, barsize);
} }
const Int FuzzyCloserWordBegin = 5;
const Int FuzzyConsecutiveMultiplier = 3;
Int FuzzyRate(String16 string, String16 with) {
ProfileFunction();
if (with.len == 0) return 0;
Int points = 0;
Int consecutive = 0;
Int with_i = 0;
for (Int i = 0; i < string.len; i++) {
if (string.data[i] == with[with_i]) {
Int closer_begin = ClampBottom((Int)0, FuzzyCloserWordBegin - i);
points += closer_begin;
consecutive++;
with_i += 1;
} else {
points += consecutive * FuzzyConsecutiveMultiplier;
consecutive = 0;
with_i = 0;
}
if (with_i >= with.len) with_i = 0;
}
points += consecutive * FuzzyConsecutiveMultiplier;
return points;
}
Array<FuzzyPair> FuzzySearchLines(Allocator allocator, Buffer *buffer, Int line_min, Int line_max, String16 needle) {
ProfileFunction();
if (line_min < 0 || line_min >= buffer->line_starts.len) return {};
if (line_max < 0 || line_min > buffer->line_starts.len) return {};
Array<FuzzyPair> ratings = {allocator};
for (Int i = line_min; i < line_max; i += 1) {
String16 s = GetLineStringWithoutNL(buffer, i);
Int idx = 0;
if (Seek(s, u" || ", &idx)) {
s.len = idx;
}
s = Trim(s);
Int rating = FuzzyRate(s, needle);
Add(&ratings, {i, rating});
}
// bubble sort
for (Int i = 0; i < ratings.len - 1; i++) {
for (Int j = 0; j < ratings.len - 1; j++) {
if (ratings[j].rating > ratings[j + 1].rating) {
FuzzyPair temp = ratings[j];
ratings[j] = ratings[j + 1];
ratings[j + 1] = temp;
}
}
}
return ratings;
}
void CommandWindowUpdate() { void CommandWindowUpdate() {
ProfileFunction(); ProfileFunction();
BSet active = GetBSet(ActiveWindowID); BSet active = GetBSet(ActiveWindowID);
if (active.window->id == CommandBarWindowID) { if (active.window->id == CommandWindowID) {
if (!ProcessIsActive(active.view->id)) { if (!ProcessIsActive(active.view->id)) {
Scratch scratch; Scratch scratch;
String16 last_line_string = GetLineStringWithoutNL(active.buffer, active.buffer->line_starts.len - 1); String16 line_string = GetLineStringWithoutNL(active.buffer, 0);
if (active.view->prev_search_line != last_line_string) { if (active.view->prev_search_line != line_string) {
active.view->prev_search_line = last_line_string; active.view->prev_search_line = line_string;
Array<FuzzyPair> ratings = FuzzySearchLines(scratch, active.buffer, 0, active.buffer->line_starts.len - 1, last_line_string); Array<FuzzyPair> ratings = FuzzySearchLines(scratch, active.buffer, 1, active.buffer->line_starts.len, line_string);
Buffer *temp_buffer = CreateTempBuffer(scratch, active.buffer->cap); Buffer *temp_buffer = CreateTempBuffer(scratch, active.buffer->cap);
RawAppend(temp_buffer, line_string);
For(IterateInReverse(&ratings)) { For(IterateInReverse(&ratings)) {
String16 s = GetLineStringWithoutNL(active.buffer, it.index); String16 s = GetLineStringWithoutNL(active.buffer, it.index);
if (s.len == 0) continue; if (s.len == 0) continue;
RawReplaceText(temp_buffer, GetBufferEndAsRange(temp_buffer), s); RawAppend(temp_buffer, u"\n");
RawReplaceText(temp_buffer, GetBufferEndAsRange(temp_buffer), u"\n"); RawAppend(temp_buffer, s);
} }
RawReplaceText(temp_buffer, GetBufferEndAsRange(temp_buffer), last_line_string);
Caret caret = active.view->carets[0]; Caret caret = active.view->carets[0];
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets); SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
@@ -58,65 +114,69 @@ void CommandWindowUpdate() {
} }
void Command_ShowCommands() { void Command_ShowCommands() {
if (ActiveWindowID == CommandBarWindowID && LastExecutedCommand == Command_ShowCommands) { if (ActiveWindowID == CommandWindowID && LastExecutedCommand == Command_ShowCommands) {
ActiveWindowID = LastActiveLayoutWindowID; ActiveWindowID = LastActiveLayoutWindowID;
return; return;
} }
ProfileFunction();
BSet command_bar = GetBSet(CommandBarWindowID); BSet command_bar = GetBSet(CommandWindowID);
command_bar.window->visible = true; command_bar.window->visible = true;
command_bar.window->eval_command = true; command_bar.window->eval_command = true;
ActiveWindowID = command_bar.window->id; ActiveWindowID = command_bar.window->id;
ResetBuffer(command_bar.buffer); ResetBuffer(command_bar.buffer);
For(CommandFunctions) { For(CommandFunctions) {
RawAppendf(command_bar.buffer, "%S\n", it.name); RawAppendf(command_bar.buffer, "\n%S", it.name);
} }
command_bar.view->update_scroll = true; command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer)); SelectRange(command_bar.view, GetBufferBeginAsRange(command_bar.buffer));
} RegisterCommand(Command_ShowCommands, "ctrl-shift-p"); } RegisterCommand(Command_ShowCommands, "ctrl-shift-p");
void Command_ShowDebugBufferList() { void Command_ShowDebugBufferList() {
if (ActiveWindowID == CommandBarWindowID && LastExecutedCommand == Command_ShowDebugBufferList) { if (ActiveWindowID == CommandWindowID && LastExecutedCommand == Command_ShowDebugBufferList) {
ActiveWindowID = LastActiveLayoutWindowID; ActiveWindowID = LastActiveLayoutWindowID;
return; return;
} }
ProfileFunction();
BSet command_bar = GetBSet(CommandBarWindowID); BSet command_bar = GetBSet(CommandWindowID);
command_bar.window->visible = true; command_bar.window->visible = true;
command_bar.window->eval_command = false; command_bar.window->eval_command = false;
ActiveWindowID = command_bar.window->id; ActiveWindowID = command_bar.window->id;
ResetBuffer(command_bar.buffer); ResetBuffer(command_bar.buffer);
For(Buffers) { For (Buffers) {
RawAppendf(command_bar.buffer, "%-80S || %S\n", SkipToLastSlash(it->name), it->name); RawAppendf(command_bar.buffer, "\n%-80S || %S", SkipToLastSlash(it->name), it->name);
} }
command_bar.view->update_scroll = true; command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer)); SelectRange(command_bar.view, GetBufferBeginAsRange(command_bar.buffer));
} RegisterCommand(Command_ShowDebugBufferList, ""); } RegisterCommand(Command_ShowDebugBufferList, "");
void Command_ShowBufferList() { void Command_ShowBufferList() {
if (ActiveWindowID == CommandBarWindowID && LastExecutedCommand == Command_ShowBufferList) { if (ActiveWindowID == CommandWindowID && LastExecutedCommand == Command_ShowBufferList) {
ActiveWindowID = LastActiveLayoutWindowID; ActiveWindowID = LastActiveLayoutWindowID;
return; return;
} }
ProfileFunction();
BSet command_bar = GetBSet(CommandBarWindowID); BSet command_bar = GetBSet(CommandWindowID);
command_bar.window->visible = true; command_bar.window->visible = true;
command_bar.window->eval_command = false; command_bar.window->eval_command = false;
ActiveWindowID = command_bar.window->id; ActiveWindowID = command_bar.window->id;
ResetBuffer(command_bar.buffer); ResetBuffer(command_bar.buffer);
For(Buffers) { For (Buffers) {
if (it->special) { if (it->special) {
continue; continue;
} }
RawAppendf(command_bar.buffer, "%-80S || %S\n", SkipToLastSlash(it->name), it->name); RawAppendf(command_bar.buffer, "\n%-80S || %S", SkipToLastSlash(it->name), it->name);
} }
command_bar.view->update_scroll = true; command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer)); SelectRange(command_bar.view, GetBufferBeginAsRange(command_bar.buffer));
} RegisterCommand(Command_ShowBufferList, "ctrl-p"); } RegisterCommand(Command_ShowBufferList, "ctrl-p");
void EvalCommand(String command) { void EvalCommand(String command) {
For (CommandFunctions) { For (CommandFunctions) {
if (it.name == command) { if (it.name == command) {
ProfileScopeEx(it.name);
it.function(); it.function();
break; break;
} }
@@ -129,12 +189,13 @@ void EvalCommand(String16 command) {
} }
void CommandWindowOpen(BSet active) { void CommandWindowOpen(BSet active) {
ProfileFunction();
Range range = active.view->carets[0].range; Range range = active.view->carets[0].range;
String16 string = FetchLoadWord(active.view); String16 string = FetchLoadWord(active.view);
if (GetSize(range) == 0) { if (GetSize(range) == 0) {
Int line = PosToLine(active.buffer, range.min); Int line = PosToLine(active.buffer, range.min);
if ((active.buffer->line_starts.len - 1) == line) { if (line == 0) {
line = ClampBottom(0ll, line - 1ll); line = ClampTop(1ll, active.buffer->line_starts.len - 1ll);
} }
string = GetLineStringWithoutNL(active.buffer, line); string = GetLineStringWithoutNL(active.buffer, line);

View File

@@ -1,6 +1,6 @@
void SearchWindowInit() { void SearchWindowInit() {
Window *window = CreateWind(); Window *window = CreateWind();
SearchBarWindowID = window->id; SearchWindowID = window->id;
Buffer *buffer = CreateBuffer(SysAllocator, "search_bar"); Buffer *buffer = CreateBuffer(SysAllocator, "search_bar");
buffer->special = true; buffer->special = true;
SearchBufferID = buffer->id; SearchBufferID = buffer->id;
@@ -14,11 +14,11 @@ void SearchWindowInit() {
window->draw_line_highlight = false; window->draw_line_highlight = false;
window->layout = false; window->layout = false;
window->visible = false; window->visible = false;
window->lose_focus_on_escape = true; window->lose_visibility_on_escape = true;
} }
void SearchWindowLayout(Rect2I *rect, Int wx, Int wy) { void SearchWindowLayout(Rect2I *rect, Int wx, Int wy) {
Window *n = GetWindow(SearchBarWindowID); Window *n = GetWindow(SearchWindowID);
Rect2I copy_rect = *rect; Rect2I copy_rect = *rect;
if (!n->visible) { if (!n->visible) {
rect = &copy_rect; rect = &copy_rect;
@@ -28,6 +28,35 @@ void SearchWindowLayout(Rect2I *rect, Int wx, Int wy) {
} }
void Command_Search() { void Command_Search() {
Window *window = GetWindow(SearchBarWindowID); BSet set = GetBSet(SearchWindowID);
window->visible = !window->visible; set.window->visible = true;
ActiveWindowID = SearchWindowID;
SelectEntireBuffer(set.view);
} RegisterCommand(Command_Search, "ctrl-f"); } RegisterCommand(Command_Search, "ctrl-f");
void SearchWindowFindNext(bool forward = true) {
BSet main = GetBSet(LastActiveLayoutWindowID);
BSet set = GetBSet(SearchWindowID);
String16 seek = GetString(set.buffer, GetRange(set.buffer));
Find(main.view, seek, forward);
main.window->search_bar_anchor = main.view->carets[0];
}
void Command_SearchNext() {
SearchWindowFindNext(true);
} RegisterCommand(Command_SearchNext, "f3");
void Command_SearchPrev() {
SearchWindowFindNext(false);
} RegisterCommand(Command_SearchPrev, "shift-f3 | shift-enter");
void SearchWindowUpdate() {
BSet active = GetBSet(ActiveWindowID);
if (active.window->id == SearchWindowID && active.buffer->begin_frame_change_id != active.buffer->change_id) {
BSet main = GetBSet(LastActiveLayoutWindowID);
BSet set = GetBSet(SearchWindowID);
main.view->carets[0] = main.window->search_bar_anchor;
String16 seek = GetString(set.buffer, GetRange(set.buffer));
Find(main.view, seek, true);
}
}

View File

@@ -42,7 +42,7 @@ void StatusWindowUpdate() {
// Parse the title and line // Parse the title and line
if (title.window->id == ActiveWindowID) { if (title.window->id == ActiveWindowID) {
if (title.buffer->change_id == title.window->status_bar_last_buffer_change_id) { if (title.buffer->change_id == title.buffer->begin_frame_change_id) {
return; return;
} }
String16 buffer_name = GetString(title.buffer, replace_range); String16 buffer_name = GetString(title.buffer, replace_range);
@@ -63,7 +63,6 @@ void StatusWindowUpdate() {
if (GetFront(caret) != buffer_pos) { if (GetFront(caret) != buffer_pos) {
caret = MakeCaret(buffer_pos); caret = MakeCaret(buffer_pos);
} }
title.window->status_bar_last_buffer_change_id = title.buffer->change_id;
return; return;
} }