plugin_file_commands
This commit is contained in:
@@ -182,6 +182,16 @@ void ApplyFormattingTool(Buffer *buffer, String tool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveAll() {
|
||||||
|
For(Buffers) {
|
||||||
|
// NOTE: file_mod_time is only set when buffer got read or written to disk already so should be saved
|
||||||
|
if (it->file_mod_time && it->dirty) {
|
||||||
|
SaveBuffer(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo: plugin_languages ? and then branch out language_cpp ...
|
||||||
void CMD_FormatSelection() {
|
void CMD_FormatSelection() {
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
BSet primary = GetBSet(PrimaryWindowID);
|
BSet primary = GetBSet(PrimaryWindowID);
|
||||||
@@ -206,227 +216,11 @@ void CMD_FormatSelection() {
|
|||||||
EndEdit(primary.buffer, &edits, &primary.view->carets, KILL_SELECTION);
|
EndEdit(primary.buffer, &edits, &primary.view->carets, KILL_SELECTION);
|
||||||
} RegisterCommand(CMD_FormatSelection, "", "");
|
} RegisterCommand(CMD_FormatSelection, "", "");
|
||||||
|
|
||||||
void New(Window *window, String name = "") {
|
|
||||||
View *view = GetView(window->active_view);
|
|
||||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
|
||||||
|
|
||||||
Scratch scratch;
|
|
||||||
String dir = GetDirectory(buffer);
|
|
||||||
if (name != "") {
|
|
||||||
if (!IsAbsolute(name)) {
|
|
||||||
name = Format(scratch, "%S/%S", dir, name);
|
|
||||||
}
|
|
||||||
name = GetAbsolutePath(scratch, name);
|
|
||||||
} else {
|
|
||||||
name = GetUniqueBufferName(dir, "new");
|
|
||||||
}
|
|
||||||
WindowOpenBufferView(window, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMD_New() {
|
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
|
||||||
New(main.window, "");
|
|
||||||
} RegisterCommand(CMD_New, "ctrl-n", "Open a new buffer with automatically generated name, use :Rename");
|
|
||||||
|
|
||||||
void CMD_SaveAll() {
|
|
||||||
For(Buffers) {
|
|
||||||
// NOTE: file_mod_time is only set when buffer got read or written to disk already so should be saved
|
|
||||||
if (it->file_mod_time && it->dirty) {
|
|
||||||
SaveBuffer(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} RegisterCommand(CMD_SaveAll, "ctrl-shift-s", "");
|
|
||||||
|
|
||||||
void CMD_Save() {
|
|
||||||
BSet active = GetBSet(PrimaryWindowID);
|
|
||||||
SaveBuffer(active.buffer);
|
|
||||||
} RegisterCommand(CMD_Save, "ctrl-s", "Save buffer currently open in the last primary window");
|
|
||||||
|
|
||||||
void CMD_Reopen() {
|
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
|
||||||
ReopenBuffer(main.buffer);
|
|
||||||
NextActiveWindowID = main.window->id;
|
|
||||||
} RegisterCommand(CMD_Reopen, "", "Reads again from disk the current buffer");
|
|
||||||
|
|
||||||
void CMD_KillProcess() {
|
void CMD_KillProcess() {
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
KillProcess(main.view);
|
KillProcess(main.view);
|
||||||
} RegisterCommand(CMD_KillProcess, "", "Kill process in the last active primary window");
|
} RegisterCommand(CMD_KillProcess, "", "Kill process in the last active primary window");
|
||||||
|
|
||||||
void CO_Rename(mco_coro *co) {
|
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
|
||||||
Buffer *original_buffer = main.buffer;
|
|
||||||
JumpTempBuffer(&main);
|
|
||||||
NextActiveWindowID = main.window->id;
|
|
||||||
RawAppendf(main.buffer, "Rename and click enter to submit: [%S]\n :Rename :Cancel", original_buffer->name);
|
|
||||||
|
|
||||||
main.view->carets[0] = FindNext(main.buffer, u"]", MakeCaret(0));
|
|
||||||
main.view->carets[0].range.max = main.view->carets[0].range.min;
|
|
||||||
AddUIAction(main.view, "Rename", EnterKey, UIAction_Yes);
|
|
||||||
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
|
||||||
UIAction action = WaitForUIAction(co, main);
|
|
||||||
if (action != UIAction_Yes) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Caret a = FindNext(main.buffer, u"[", MakeCaret(-1));
|
|
||||||
Caret b = FindNext(main.buffer, u"]", MakeCaret(-1));
|
|
||||||
if (a.range.min == -1 || b.range.max == -1) {
|
|
||||||
ReportErrorf("Failed to extract the name for the Rename operation from the buffer");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String16 string16 = GetString(main.buffer, {a.range.max + 1, b.range.max});
|
|
||||||
String string = ToString(CoCurr->arena, string16);
|
|
||||||
original_buffer->name = Intern(&GlobalInternTable, string);
|
|
||||||
} RegisterCoroutineCommand(CO_Rename, "", "Opens a UI asking for a new name of a buffer open in the last active primary window");
|
|
||||||
|
|
||||||
void CO_Close(mco_coro *co) {
|
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
|
||||||
if (main.buffer->special || main.buffer->temp) {
|
|
||||||
Close(main.view->id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ref = false;
|
|
||||||
For (Views) {
|
|
||||||
if (it->id == main.view->id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (it->active_buffer == main.buffer->id) {
|
|
||||||
ref = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ref) {
|
|
||||||
Close(main.view->id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!main.buffer->dirty) {
|
|
||||||
Close(main.buffer->id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", main.buffer->name);
|
|
||||||
UIAction ui_action = QueryUserYesNoCancel(co, main, question);
|
|
||||||
if (ui_action == UIAction_Yes) {
|
|
||||||
SaveBuffer(main.buffer);
|
|
||||||
Close(main.buffer->id);
|
|
||||||
} else if (ui_action == UIAction_No) {
|
|
||||||
Close(main.buffer->id);
|
|
||||||
} else if (ui_action == UIAction_Cancel) {
|
|
||||||
return;
|
|
||||||
} ElseInvalidCodepath();
|
|
||||||
} RegisterCoroutineCommand(CO_Close, "ctrl-w", "Close open view in the last active primary window");
|
|
||||||
|
|
||||||
void CMD_DeleteFile() {
|
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
|
||||||
String buffer_name = main.buffer->name;
|
|
||||||
DeleteFile(main.buffer->name);
|
|
||||||
Close(main.buffer->id);
|
|
||||||
} RegisterCommand(CMD_DeleteFile, "", "Close the open buffer and delete it's corresponding file on disk");
|
|
||||||
|
|
||||||
// Considerations with coroutines:
|
|
||||||
// 1. Does scratch memory leak across Yield boundary? Or interacts badly with Yield stuff in any way?
|
|
||||||
// 2. Are pointers and globals correct over time? Or might they get deleted etc.
|
|
||||||
// 3. Imagine a scenario where the coroutine gets deleted before completion, will the memory leak?
|
|
||||||
UIAction ShowCloseAllUI(mco_coro *co) {
|
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
|
||||||
Array<BufferID> buffers = {CoCurr->arena};
|
|
||||||
For (Buffers) Add(&buffers, it->id);
|
|
||||||
ForItem (id, buffers) {
|
|
||||||
Buffer *it = GetBuffer(id, NULL);
|
|
||||||
if (it == NULL || it->special || !it->dirty) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (it->temp || it->dont_try_to_save_in_bulk_ops) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", it->name);
|
|
||||||
UIAction ui_action = QueryUserYesNoCancel(co, main, question);
|
|
||||||
it = GetBuffer(id, NULL);
|
|
||||||
if (it && ui_action == UIAction_Yes) {
|
|
||||||
SaveBuffer(it);
|
|
||||||
} else if (ui_action == UIAction_No) {
|
|
||||||
} else if (ui_action == UIAction_Cancel) {
|
|
||||||
return UIAction_Cancel;
|
|
||||||
} ElseInvalidCodepath();
|
|
||||||
}
|
|
||||||
|
|
||||||
For(Buffers) {
|
|
||||||
Close(it->id);
|
|
||||||
}
|
|
||||||
return UIAction_Yes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CO_CloseAll(mco_coro *co) {
|
|
||||||
ShowCloseAllUI(co);
|
|
||||||
} RegisterCoroutineCommand(CO_CloseAll, "", "Ask user which files to save and close all open normal views and buffers");
|
|
||||||
|
|
||||||
void CO_ReplaceAll(mco_coro *co) {
|
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
|
||||||
String16 string = FetchLoadWord(main.view);
|
|
||||||
String string8 = ToString(CoCurr->arena, string);
|
|
||||||
String16 needle = {};
|
|
||||||
String16 replace = {};
|
|
||||||
|
|
||||||
{
|
|
||||||
JumpTempBuffer(&main);
|
|
||||||
NextActiveWindowID = main.window->id;
|
|
||||||
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to search for::%S", string8);
|
|
||||||
|
|
||||||
Caret field_seek = BaseFindNext(main.buffer, u"for::", MakeCaret(0), SeekFlag_None);
|
|
||||||
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
|
|
||||||
AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes);
|
|
||||||
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
|
||||||
UIAction action = WaitForUIAction(co, main);
|
|
||||||
if (action == UIAction_Cancel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
field_seek = BaseFindNext(main.buffer, u"for::", MakeCaret(0), SeekFlag_None);
|
|
||||||
Range range = {field_seek.range.max, main.buffer->len};
|
|
||||||
needle = GetString(main.buffer, range);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
JumpTempBuffer(&main);
|
|
||||||
NextActiveWindowID = main.window->id;
|
|
||||||
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to replace with::%S", ToString(CoCurr->arena, needle));
|
|
||||||
|
|
||||||
Caret field_seek = BaseFindNext(main.buffer, u"with::", MakeCaret(0), SeekFlag_None);
|
|
||||||
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
|
|
||||||
AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes);
|
|
||||||
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
|
||||||
UIAction action = WaitForUIAction(co, main);
|
|
||||||
if (action == UIAction_Cancel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
field_seek = BaseFindNext(main.buffer, u"with::", MakeCaret(0), SeekFlag_None);
|
|
||||||
Range range = {field_seek.range.max, main.buffer->len};
|
|
||||||
replace = GetString(main.buffer, range);
|
|
||||||
}
|
|
||||||
|
|
||||||
ForItem (buffer, Buffers) {
|
|
||||||
if (buffer->special || buffer->temp || buffer->dont_try_to_save_in_bulk_ops) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#if PLUGIN_DIRECTORY_NAVIGATION
|
|
||||||
if (buffer->is_dir) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
View *view = OpenBufferView(buffer->name);
|
|
||||||
if (SelectAllOccurences(view, needle)) {
|
|
||||||
Replace(view, replace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} RegisterCoroutineCommand(CO_ReplaceAll, "ctrl-shift-r", "Search and replace over the entire project, you need to select a text with format like this 'FindAnd@>ReplaceWith' and executing the command will change all occurences of FindAnd to ReplaceWith");
|
|
||||||
|
|
||||||
void CMD_MakeFontLarger() {
|
void CMD_MakeFontLarger() {
|
||||||
FontSize += 1;
|
FontSize += 1;
|
||||||
ReloadFont(PathToFont, (U32)FontSize);
|
ReloadFont(PathToFont, (U32)FontSize);
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ void CMD_OpenForFuzzyView() {
|
|||||||
BSet active = GetBSet(ActiveWindowID);
|
BSet active = GetBSet(ActiveWindowID);
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
NextActiveWindowID = main.window->id;
|
NextActiveWindowID = main.window->id;
|
||||||
if (active.view->carets.len == 1) {
|
if (active.view->carets.len == 1 && GetSize(active.view->carets[0].range) == 0) {
|
||||||
String16 string = FetchFuzzyViewLoadLine(active.view);
|
String16 string = FetchFuzzyViewLoadLine(active.view);
|
||||||
Open(string);
|
Open(string);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ void LayoutBuildWindow(Rect2I *rect, int16_t wx, int16_t wy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BSet ExecBuild(String windows_cmd, String unix_cmd, String working_dir = ProjectDirectory) {
|
BSet ExecBuild(String windows_cmd, String unix_cmd, String working_dir = ProjectDirectory) {
|
||||||
CMD_SaveAll();
|
SaveAll();
|
||||||
BSet build = GetBSet(BuildWindowID);
|
BSet build = GetBSet(BuildWindowID);
|
||||||
BSet main = GetBSet(PrimaryWindowID);
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
SelectRange(build.view, Range{});
|
SelectRange(build.view, Range{});
|
||||||
|
|||||||
180
src/text_editor/plugin_file_commands.cpp
Normal file
180
src/text_editor/plugin_file_commands.cpp
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
#if PLUGIN_FILE_COMMANDS
|
||||||
|
|
||||||
|
void New(Window *window, String name = "") {
|
||||||
|
View *view = GetView(window->active_view);
|
||||||
|
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||||
|
|
||||||
|
Scratch scratch;
|
||||||
|
String dir = GetDirectory(buffer);
|
||||||
|
if (name != "") {
|
||||||
|
if (!IsAbsolute(name)) {
|
||||||
|
name = Format(scratch, "%S/%S", dir, name);
|
||||||
|
}
|
||||||
|
name = GetAbsolutePath(scratch, name);
|
||||||
|
} else {
|
||||||
|
name = GetUniqueBufferName(dir, "new");
|
||||||
|
}
|
||||||
|
WindowOpenBufferView(window, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMD_New() {
|
||||||
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
|
New(main.window, "");
|
||||||
|
} RegisterCommand(CMD_New, "ctrl-n", "Open a new buffer with automatically generated name, use :Rename");
|
||||||
|
|
||||||
|
void CMD_SaveAll() {
|
||||||
|
SaveAll();
|
||||||
|
} RegisterCommand(CMD_SaveAll, "ctrl-shift-s", "");
|
||||||
|
|
||||||
|
void CMD_Save() {
|
||||||
|
BSet active = GetBSet(PrimaryWindowID);
|
||||||
|
SaveBuffer(active.buffer);
|
||||||
|
} RegisterCommand(CMD_Save, "ctrl-s", "Save buffer currently open in the last primary window");
|
||||||
|
|
||||||
|
void CMD_Reopen() {
|
||||||
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
|
ReopenBuffer(main.buffer);
|
||||||
|
NextActiveWindowID = main.window->id;
|
||||||
|
} RegisterCommand(CMD_Reopen, "", "Reads again from disk the current buffer");
|
||||||
|
|
||||||
|
void CO_Rename(mco_coro *co) {
|
||||||
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
|
Buffer *original_buffer = main.buffer;
|
||||||
|
JumpTempBuffer(&main);
|
||||||
|
NextActiveWindowID = main.window->id;
|
||||||
|
RawAppendf(main.buffer, "Rename and click enter to submit: [%S]\n :Rename :Cancel", original_buffer->name);
|
||||||
|
|
||||||
|
main.view->carets[0] = FindNext(main.buffer, u"]", MakeCaret(0));
|
||||||
|
main.view->carets[0].range.max = main.view->carets[0].range.min;
|
||||||
|
AddUIAction(main.view, "Rename", EnterKey, UIAction_Yes);
|
||||||
|
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
||||||
|
UIAction action = WaitForUIAction(co, main);
|
||||||
|
if (action != UIAction_Yes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Caret a = FindNext(main.buffer, u"[", MakeCaret(-1));
|
||||||
|
Caret b = FindNext(main.buffer, u"]", MakeCaret(-1));
|
||||||
|
if (a.range.min == -1 || b.range.max == -1) {
|
||||||
|
ReportErrorf("Failed to extract the name for the Rename operation from the buffer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String16 string16 = GetString(main.buffer, {a.range.max + 1, b.range.max});
|
||||||
|
String string = ToString(CoCurr->arena, string16);
|
||||||
|
original_buffer->name = Intern(&GlobalInternTable, string);
|
||||||
|
} RegisterCoroutineCommand(CO_Rename, "", "Opens a UI asking for a new name of a buffer open in the last active primary window");
|
||||||
|
|
||||||
|
void CO_Close(mco_coro *co) {
|
||||||
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
|
if (main.buffer->special || main.buffer->temp) {
|
||||||
|
Close(main.view->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ref = false;
|
||||||
|
For (Views) {
|
||||||
|
if (it->id == main.view->id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (it->active_buffer == main.buffer->id) {
|
||||||
|
ref = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ref) {
|
||||||
|
Close(main.view->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!main.buffer->dirty) {
|
||||||
|
Close(main.buffer->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", main.buffer->name);
|
||||||
|
UIAction ui_action = QueryUserYesNoCancel(co, main, question);
|
||||||
|
if (ui_action == UIAction_Yes) {
|
||||||
|
SaveBuffer(main.buffer);
|
||||||
|
Close(main.buffer->id);
|
||||||
|
} else if (ui_action == UIAction_No) {
|
||||||
|
Close(main.buffer->id);
|
||||||
|
} else if (ui_action == UIAction_Cancel) {
|
||||||
|
return;
|
||||||
|
} ElseInvalidCodepath();
|
||||||
|
} RegisterCoroutineCommand(CO_Close, "ctrl-w", "Close open view in the last active primary window");
|
||||||
|
|
||||||
|
void CMD_DeleteFile() {
|
||||||
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
|
String buffer_name = main.buffer->name;
|
||||||
|
DeleteFile(main.buffer->name);
|
||||||
|
Close(main.buffer->id);
|
||||||
|
} RegisterCommand(CMD_DeleteFile, "", "Close the open buffer and delete it's corresponding file on disk");
|
||||||
|
|
||||||
|
void CO_CloseAll(mco_coro *co) {
|
||||||
|
ShowCloseAllUI(co);
|
||||||
|
} RegisterCoroutineCommand(CO_CloseAll, "", "Ask user which files to save and close all open normal views and buffers");
|
||||||
|
|
||||||
|
void CO_ReplaceAll(mco_coro *co) {
|
||||||
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
|
String16 string = FetchLoadWord(main.view);
|
||||||
|
String string8 = ToString(CoCurr->arena, string);
|
||||||
|
String16 needle = {};
|
||||||
|
String16 replace = {};
|
||||||
|
|
||||||
|
{
|
||||||
|
JumpTempBuffer(&main);
|
||||||
|
NextActiveWindowID = main.window->id;
|
||||||
|
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to search for::%S", string8);
|
||||||
|
|
||||||
|
Caret field_seek = BaseFindNext(main.buffer, u"for::", MakeCaret(0), SeekFlag_None);
|
||||||
|
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
|
||||||
|
AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes);
|
||||||
|
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
||||||
|
UIAction action = WaitForUIAction(co, main);
|
||||||
|
if (action == UIAction_Cancel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
field_seek = BaseFindNext(main.buffer, u"for::", MakeCaret(0), SeekFlag_None);
|
||||||
|
Range range = {field_seek.range.max, main.buffer->len};
|
||||||
|
needle = GetString(main.buffer, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JumpTempBuffer(&main);
|
||||||
|
NextActiveWindowID = main.window->id;
|
||||||
|
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to replace with::%S", ToString(CoCurr->arena, needle));
|
||||||
|
|
||||||
|
Caret field_seek = BaseFindNext(main.buffer, u"with::", MakeCaret(0), SeekFlag_None);
|
||||||
|
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
|
||||||
|
AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes);
|
||||||
|
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
||||||
|
UIAction action = WaitForUIAction(co, main);
|
||||||
|
if (action == UIAction_Cancel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
field_seek = BaseFindNext(main.buffer, u"with::", MakeCaret(0), SeekFlag_None);
|
||||||
|
Range range = {field_seek.range.max, main.buffer->len};
|
||||||
|
replace = GetString(main.buffer, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
ForItem (buffer, Buffers) {
|
||||||
|
if (buffer->special || buffer->temp || buffer->dont_try_to_save_in_bulk_ops) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#if PLUGIN_DIRECTORY_NAVIGATION
|
||||||
|
if (buffer->is_dir) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
View *view = OpenBufferView(buffer->name);
|
||||||
|
if (SelectAllOccurences(view, needle)) {
|
||||||
|
Replace(view, replace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} RegisterCoroutineCommand(CO_ReplaceAll, "ctrl-shift-r", "Search and replace over the entire project, you need to select a text with format like this 'FindAnd@>ReplaceWith' and executing the command will change all occurences of FindAnd to ReplaceWith");
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -355,20 +355,18 @@ SPALL_FN bool spall_buffer_name_process(SpallProfile *ctx, SpallBuffer *wb, cons
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define BeginProfileScopeEx(name, len) spall_buffer_begin(&spall_ctx, &spall_buffer, (name), (len), GetTimeNanos())
|
#define BeginProfileScopeEx(name, len) spall_buffer_begin(&spall_ctx, &spall_buffer, (name), (len), GetTimeNanos())
|
||||||
#define BeginProfileScope(name) BeginProfileScopeEx(#name, sizeof(#name) - 1)
|
#define BeginProfileScope(name) BeginProfileScopeEx(#name, sizeof(#name) - 1)
|
||||||
#define EndProfileScope() spall_buffer_end(&spall_ctx, &spall_buffer, GetTimeNanos())
|
#define EndProfileScope() spall_buffer_end(&spall_ctx, &spall_buffer, GetTimeNanos())
|
||||||
#define ProfileScopeEx(name) ProfileScopeClass PROFILE_SCOPE_VAR_((name).data, (int)(name).len)
|
|
||||||
#define ProfileScope(name) ProfileScopeClass PROFILE_SCOPE_VAR_##name(#name, sizeof(#name) - 1)
|
|
||||||
#define ProfileFunction() ProfileScopeClass PROFILE_SCOPE_FUNCTION(__FUNCTION__, sizeof(__FUNCTION__) - 1)
|
|
||||||
struct ProfileScopeClass {
|
struct ProfileScopeClass {
|
||||||
ProfileScopeClass(const char *name, int len) { BeginProfileScopeEx(name, len); }
|
ProfileScopeClass(const char *name, int len) { BeginProfileScopeEx(name, len); }
|
||||||
~ProfileScopeClass() { EndProfileScope(); }
|
~ProfileScopeClass() { EndProfileScope(); }
|
||||||
};
|
};
|
||||||
|
#define ProfileScopeEx(name) ProfileScopeClass PROFILE_SCOPE_VAR_((name).data, (int)(name).len)
|
||||||
|
#define ProfileScope(name) ProfileScopeClass PROFILE_SCOPE_VAR_##name(#name, sizeof(#name) - 1)
|
||||||
|
#define ProfileFunction() ProfileScopeClass PROFILE_SCOPE_FUNCTION(__FUNCTION__, sizeof(__FUNCTION__) - 1)
|
||||||
SPALL_FN void BeginProfiler();
|
SPALL_FN void BeginProfiler();
|
||||||
SPALL_FN void EndProfiler();
|
SPALL_FN void EndProfiler();
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define ProfileScopeEx(name)
|
#define ProfileScopeEx(name)
|
||||||
#define ProfileScope(name)
|
#define ProfileScope(name)
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#define PLUGIN_DIRECTORY_NAVIGATION 1
|
#define PLUGIN_DIRECTORY_NAVIGATION 1
|
||||||
#define PLUGIN_LOAD_VCVARS OS_WINDOWS
|
#define PLUGIN_LOAD_VCVARS OS_WINDOWS
|
||||||
#define PLUGIN_REMEDYBG OS_WINDOWS
|
#define PLUGIN_REMEDYBG OS_WINDOWS
|
||||||
|
#define PLUGIN_FILE_COMMANDS 1
|
||||||
|
|
||||||
#include "plugin_directory_navigation.h"
|
#include "plugin_directory_navigation.h"
|
||||||
#include "plugin_search_window.h"
|
#include "plugin_search_window.h"
|
||||||
@@ -72,6 +73,7 @@
|
|||||||
#include "plugin_load_vcvars.cpp"
|
#include "plugin_load_vcvars.cpp"
|
||||||
#include "plugin_remedybg.cpp"
|
#include "plugin_remedybg.cpp"
|
||||||
#include "plugin_profiler.cpp"
|
#include "plugin_profiler.cpp"
|
||||||
|
#include "plugin_file_commands.cpp"
|
||||||
|
|
||||||
#if OS_WASM
|
#if OS_WASM
|
||||||
EM_JS(void, JS_SetMouseCursor, (const char *cursor_str), {
|
EM_JS(void, JS_SetMouseCursor, (const char *cursor_str), {
|
||||||
|
|||||||
@@ -113,6 +113,40 @@ String16 QueryUserString(mco_coro *co, String ask) {
|
|||||||
return GetString(main.buffer, a.range);
|
return GetString(main.buffer, a.range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Considerations with coroutines:
|
||||||
|
// 1. Does scratch memory leak across Yield boundary? Or interacts badly with Yield stuff in any way?
|
||||||
|
// 2. Are pointers and globals correct over time? Or might they get deleted etc.
|
||||||
|
// 3. Imagine a scenario where the coroutine gets deleted before completion, will the memory leak?
|
||||||
|
UIAction ShowCloseAllUI(mco_coro *co) {
|
||||||
|
BSet main = GetBSet(PrimaryWindowID);
|
||||||
|
Array<BufferID> buffers = {CoCurr->arena};
|
||||||
|
For (Buffers) Add(&buffers, it->id);
|
||||||
|
ForItem (id, buffers) {
|
||||||
|
Buffer *it = GetBuffer(id, NULL);
|
||||||
|
if (it == NULL || it->special || !it->dirty) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (it->temp || it->dont_try_to_save_in_bulk_ops) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", it->name);
|
||||||
|
UIAction ui_action = QueryUserYesNoCancel(co, main, question);
|
||||||
|
it = GetBuffer(id, NULL);
|
||||||
|
if (it && ui_action == UIAction_Yes) {
|
||||||
|
SaveBuffer(it);
|
||||||
|
} else if (ui_action == UIAction_No) {
|
||||||
|
} else if (ui_action == UIAction_Cancel) {
|
||||||
|
return UIAction_Cancel;
|
||||||
|
} ElseInvalidCodepath();
|
||||||
|
}
|
||||||
|
|
||||||
|
For(Buffers) {
|
||||||
|
Close(it->id);
|
||||||
|
}
|
||||||
|
return UIAction_Yes;
|
||||||
|
}
|
||||||
|
|
||||||
String QueryUserFile(mco_coro *co) {
|
String QueryUserFile(mco_coro *co) {
|
||||||
#if PLUGIN_DIRECTORY_NAVIGATION
|
#if PLUGIN_DIRECTORY_NAVIGATION
|
||||||
Window *window = GetWindow(PrimaryWindowID);
|
Window *window = GetWindow(PrimaryWindowID);
|
||||||
|
|||||||
Reference in New Issue
Block a user