188 lines
6.5 KiB
C++
188 lines
6.5 KiB
C++
void CommandWindowInit() {
|
|
Window *window = CreateWind();
|
|
CommandWindowID = window->id;
|
|
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "command_bar"));
|
|
buffer->special = true;
|
|
View *view = CreateView(buffer->id);
|
|
view->special = true;
|
|
window->active_view = view->id;
|
|
window->draw_line_numbers = false;
|
|
window->draw_scrollbar = false;
|
|
window->draw_darker = true;
|
|
window->draw_line_highlight = true;
|
|
window->layout = false;
|
|
window->visible = false;
|
|
window->sync_visibility_with_focus = true;
|
|
window->lose_focus_on_escape = true;
|
|
window->jump_history = false;
|
|
}
|
|
|
|
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy) {
|
|
Window *n = GetWindow(CommandWindowID);
|
|
Rect2I copy_rect = *rect;
|
|
if (!n->visible) {
|
|
rect = ©_rect;
|
|
}
|
|
Int barsize = Clamp((Int)n->font->line_spacing*10, (Int)0, (Int)wx - 100);
|
|
n->document_rect = n->total_rect = CutBottom(rect, barsize);
|
|
}
|
|
|
|
int32_t FuzzyRate(String16 string, String16 with) {
|
|
ProfileFunction();
|
|
if (with.len == 0) return 0;
|
|
int32_t points = 0;
|
|
int32_t consecutive = 0;
|
|
int32_t with_i = 0;
|
|
for (int32_t i = 0; i < string.len; i++) {
|
|
if (ToLowerCase(string.data[i]) == ToLowerCase(with[with_i])) {
|
|
consecutive += 1;
|
|
with_i += 1;
|
|
} else {
|
|
with_i = 0;
|
|
points += consecutive * consecutive;
|
|
consecutive = 0;
|
|
}
|
|
|
|
if (with_i >= with.len) with_i = 0;
|
|
}
|
|
points += consecutive * consecutive;
|
|
return points;
|
|
}
|
|
|
|
inline bool MergeSortCompare(FuzzyPair *a, FuzzyPair *b) {
|
|
bool result = a->rating > b->rating;
|
|
return result;
|
|
}
|
|
|
|
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};
|
|
Reserve(&ratings, line_max - line_min + 4);
|
|
for (Int i = line_min; i < line_max; i += 1) {
|
|
String16 s = GetLineStringWithoutNL(buffer, i);
|
|
int32_t rating = FuzzyRate(s, needle);
|
|
Add(&ratings, {(int32_t)i, rating});
|
|
}
|
|
|
|
Array<FuzzyPair> temp = Copy(allocator, ratings);
|
|
MergeSort(ratings.len, ratings.data, temp.data);
|
|
return ratings;
|
|
}
|
|
|
|
void CommandWindowUpdate() {
|
|
ProfileFunction();
|
|
BSet active = GetBSet(ActiveWindowID);
|
|
if (active.window->id == CommandWindowID) {
|
|
if (!ProcessIsActive(active.view->id)) {
|
|
Scratch scratch;
|
|
String16 line_string = GetLineStringWithoutNL(active.buffer, 0);
|
|
if (active.view->prev_search_line != line_string) {
|
|
active.view->prev_search_line = line_string;
|
|
Array<FuzzyPair> ratings = FuzzySearchLines(scratch, active.buffer, 1, active.buffer->line_starts.len, line_string);
|
|
|
|
Buffer *scratch_buff = CreateScratchBuffer(scratch, active.buffer->cap);
|
|
RawAppend(scratch_buff, line_string);
|
|
For(IterateInReverse(&ratings)) {
|
|
String16 s = GetLineStringWithoutNL(active.buffer, it.index);
|
|
if (s.len == 0) continue;
|
|
RawAppend(scratch_buff, u"\n");
|
|
RawAppend(scratch_buff, s);
|
|
}
|
|
|
|
Caret caret = active.view->carets[0];
|
|
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
|
|
SelectEntireBuffer(active.view);
|
|
Replace(active.view, GetString(scratch_buff));
|
|
active.view->carets[0] = caret;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Command_ShowCommands() {
|
|
if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == Command_ShowCommands) {
|
|
NextActiveWindowID = LastActiveLayoutWindowID;
|
|
return;
|
|
}
|
|
ProfileFunction();
|
|
|
|
BSet command_bar = GetBSet(CommandWindowID);
|
|
command_bar.window->visible = true;
|
|
NextActiveWindowID = command_bar.window->id;
|
|
ResetBuffer(command_bar.buffer);
|
|
For (CommandFunctions) {
|
|
if (it.name == "OpenCommand") {
|
|
continue;
|
|
}
|
|
RawAppendf(command_bar.buffer, "\n:%S", it.name);
|
|
}
|
|
command_bar.view->update_scroll = true;
|
|
SelectRange(command_bar.view, GetBufferBeginAsRange(command_bar.buffer));
|
|
} RegisterCommand(Command_ShowCommands, "ctrl-shift-p");
|
|
|
|
void Command_ShowDebugBufferList() {
|
|
if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == Command_ShowDebugBufferList) {
|
|
NextActiveWindowID = LastActiveLayoutWindowID;
|
|
return;
|
|
}
|
|
ProfileFunction();
|
|
|
|
BSet command_bar = GetBSet(CommandWindowID);
|
|
command_bar.window->visible = true;
|
|
NextActiveWindowID = command_bar.window->id;
|
|
ResetBuffer(command_bar.buffer);
|
|
For (Buffers) {
|
|
RawAppendf(command_bar.buffer, "\n%S", it->name);
|
|
}
|
|
command_bar.view->update_scroll = true;
|
|
SelectRange(command_bar.view, GetBufferBeginAsRange(command_bar.buffer));
|
|
} RegisterCommand(Command_ShowDebugBufferList, "");
|
|
|
|
void Command_ShowBufferList() {
|
|
if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == Command_ShowBufferList) {
|
|
NextActiveWindowID = LastActiveLayoutWindowID;
|
|
return;
|
|
}
|
|
ProfileFunction();
|
|
|
|
BSet command_bar = GetBSet(CommandWindowID);
|
|
command_bar.window->visible = true;
|
|
NextActiveWindowID = command_bar.window->id;
|
|
ResetBuffer(command_bar.buffer);
|
|
For (Buffers) {
|
|
if (it->special || it->temp) {
|
|
continue;
|
|
}
|
|
RawAppendf(command_bar.buffer, "\n%S", it->name);
|
|
}
|
|
command_bar.view->update_scroll = true;
|
|
SelectRange(command_bar.view, GetBufferBeginAsRange(command_bar.buffer));
|
|
} RegisterCommand(Command_ShowBufferList, "ctrl-p");
|
|
|
|
void OpenCommand(BSet active) {
|
|
ProfileFunction();
|
|
Range range = active.view->carets[0].range;
|
|
String16 string = FetchLoadWord(active.view);
|
|
if (GetSize(range) == 0) {
|
|
Int line = PosToLine(active.buffer, range.min);
|
|
if (line == 0) {
|
|
line = ClampTop(1ll, active.buffer->line_starts.len - 1ll);
|
|
}
|
|
string = GetLineStringWithoutNL(active.buffer, line);
|
|
}
|
|
|
|
Open(string);
|
|
}
|
|
|
|
void Command_OpenCommand() {
|
|
if (ActiveWindowID != CommandWindowID) {
|
|
return;
|
|
}
|
|
BSet active = GetBSet(ActiveWindowID);
|
|
BSet main = GetBSet(LastActiveLayoutWindowID);
|
|
NextActiveWindowID = main.window->id;
|
|
OpenCommand(active);
|
|
} RegisterCommand(Command_OpenCommand, "ctrl-q | enter");
|