Add QueryUserString. QueryUserFile working, fix bug in Open with line,col.
This commit is contained in:
@@ -1557,7 +1557,7 @@ void SaveBuffer(Buffer *buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
String GetBufferDirectory(Buffer *buffer) {
|
||||
String GetDirectory(Buffer *buffer) {
|
||||
#if PLUGIN_DIRECTORY_NAVIGATION
|
||||
if (buffer->is_dir) {
|
||||
return buffer->name;
|
||||
|
||||
@@ -178,7 +178,7 @@ void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret) {
|
||||
void ApplyFormattingTool(Buffer *buffer, String tool) {
|
||||
Scratch scratch;
|
||||
String string = AllocCharString(scratch, buffer);
|
||||
ExecResult exec_result = ExecAndWait(scratch, tool, GetBufferDirectory(buffer), string);
|
||||
ExecResult exec_result = ExecAndWait(scratch, tool, GetDirectory(buffer), string);
|
||||
String16 string16 = {exec_result.buffer->str, exec_result.buffer->len};
|
||||
if (exec_result.exit_code == 0) {
|
||||
ReplaceWithoutMovingCarets(buffer, GetRange(buffer), string16);
|
||||
@@ -205,7 +205,7 @@ void CMD_FormatSelection() {
|
||||
MergeCarets(primary.buffer, &primary.view->carets);
|
||||
For (primary.view->carets) {
|
||||
String input_string = ToString(scratch, GetString(primary.buffer, it.range));
|
||||
ExecResult exec_result = ExecAndWait(scratch, tool, GetBufferDirectory(primary.buffer), input_string);
|
||||
ExecResult exec_result = ExecAndWait(scratch, tool, GetDirectory(primary.buffer), input_string);
|
||||
String16 string16 = {exec_result.buffer->str, exec_result.buffer->len};
|
||||
AddEdit(&edits, it.range, string16);
|
||||
}
|
||||
@@ -217,7 +217,7 @@ void New(Window *window, String name = "") {
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
|
||||
Scratch scratch;
|
||||
String dir = GetBufferDirectory(buffer);
|
||||
String dir = GetDirectory(buffer);
|
||||
if (name != "") {
|
||||
if (!IsAbsolute(name)) {
|
||||
name = Format(scratch, "%S/%S", dir, name);
|
||||
@@ -315,7 +315,7 @@ void CO_Close(mco_coro *co) {
|
||||
}
|
||||
|
||||
String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", main.buffer->name);
|
||||
UIAction ui_action = ShowYesNoCancelUI(co, main, question);
|
||||
UIAction ui_action = QueryUserYesNoCancel(co, main, question);
|
||||
if (ui_action == UIAction_Yes) {
|
||||
SaveBuffer(main.buffer);
|
||||
Close(main.buffer->id);
|
||||
@@ -351,7 +351,7 @@ UIAction ShowCloseAllUI(mco_coro *co) {
|
||||
}
|
||||
|
||||
String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", it->name);
|
||||
UIAction ui_action = ShowYesNoCancelUI(co, main, question);
|
||||
UIAction ui_action = QueryUserYesNoCancel(co, main, question);
|
||||
it = GetBuffer(id, NULL);
|
||||
if (it && ui_action == UIAction_Yes) {
|
||||
SaveBuffer(it);
|
||||
@@ -458,4 +458,9 @@ void CMD_ToggleFullscreen() {
|
||||
SDL_SetWindowPosition(SDLWindow, 0, 0);
|
||||
}
|
||||
IsInFullscreen = !IsInFullscreen;
|
||||
} RegisterCommand(CMD_ToggleFullscreen, "f11", "switches between the fullscreen and non-fulscreen mode");
|
||||
} RegisterCommand(CMD_ToggleFullscreen, "f11", "Switches between the fullscreen and non-fulscreen mode");
|
||||
|
||||
void CMD_OpenLogs() {
|
||||
Buffer *buffer = GetBuffer(NullBufferID);
|
||||
Open(buffer->name);
|
||||
} RegisterCommand(CMD_OpenLogs, "", "Opens the text editor logs");
|
||||
@@ -61,10 +61,10 @@ void CMD_RunFile() {
|
||||
|
||||
if (OS_WINDOWS) {
|
||||
String cmd = Format(scratch, "cl %S -Fe:cfile.exe /Zi /FC /nologo /WX /W3 /wd4200 /wd4334 /diagnostics:column && cfile.exe", primary.buffer->name);
|
||||
ExecBuild(cmd, GetBufferDirectory(primary.buffer));
|
||||
ExecBuild(cmd, GetDirectory(primary.buffer));
|
||||
} else {
|
||||
String cmd = Format(scratch, "bash <<EOF\nclang %S -o cfile.exe -g -Wall -Wno-missing-braces -Wno-writable-strings -Wno-writable-strings -fsanitize=address -fdiagnostics-absolute-paths -lm \n ./cfile.exe\nEOF", primary.buffer->name);
|
||||
ExecBuild(cmd, GetBufferDirectory(primary.buffer));
|
||||
ExecBuild(cmd, GetDirectory(primary.buffer));
|
||||
}
|
||||
build.window->visible = true;
|
||||
} RegisterCommand(CMD_RunFile, "", "Run and build current file, currently only C/C++ supported");
|
||||
|
||||
@@ -11,7 +11,7 @@ void SetProjectDirectory(String dir) {
|
||||
|
||||
void CMD_SetProjectDirectoryHere() {
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
SetProjectDirectory(GetBufferDirectory(main.buffer));
|
||||
SetProjectDirectory(GetDirectory(main.buffer));
|
||||
} RegisterCommand(CMD_SetProjectDirectoryHere, "", "Sets work directory to the directory of the current buffer, it also renames couple special buffers to make them accomodate the new ProjectDirectory");
|
||||
|
||||
void CO_OpenCode(mco_coro *co) {
|
||||
|
||||
@@ -41,6 +41,32 @@ enum UIAction {
|
||||
UIAction_No,
|
||||
};
|
||||
|
||||
enum OpenKind {
|
||||
OpenKind_Invalid,
|
||||
OpenKind_Skip,
|
||||
OpenKind_Exec,
|
||||
OpenKind_BackgroundExec,
|
||||
OpenKind_Goto,
|
||||
OpenKind_Command,
|
||||
#if PLUGIN_CONFIG
|
||||
OpenKind_Set,
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef uint32_t ResolveOpenMeta;
|
||||
enum {
|
||||
ResolveOpenMeta_Normal = 0,
|
||||
ResolveOpenMeta_DontError = 2,
|
||||
ResolveOpenMeta_DontExec = 4, // dont error +
|
||||
};
|
||||
|
||||
struct ResolvedOpen {
|
||||
OpenKind kind;
|
||||
String path;
|
||||
Int line, col;
|
||||
bool existing_buffer;
|
||||
};
|
||||
|
||||
struct Buffer {
|
||||
BufferID id;
|
||||
String name;
|
||||
@@ -125,6 +151,8 @@ struct Window {
|
||||
ViewID active_goto_list;
|
||||
Int goto_list_pos;
|
||||
|
||||
String ui_query_file;
|
||||
void (*after_resolve_open_hook)(Window *window, ResolvedOpen *resolved);
|
||||
Array<Command> commands;
|
||||
struct {
|
||||
uint32_t draw_scrollbar : 1;
|
||||
@@ -245,32 +273,6 @@ struct Register_Variable {
|
||||
type name = __VA_ARGS__; \
|
||||
Register_Variable var_##name(&Variables, VariableType_##type, #name, &name)
|
||||
|
||||
enum OpenKind {
|
||||
OpenKind_Invalid,
|
||||
OpenKind_Skip,
|
||||
OpenKind_Exec,
|
||||
OpenKind_BackgroundExec,
|
||||
OpenKind_Goto,
|
||||
OpenKind_Command,
|
||||
#if PLUGIN_CONFIG
|
||||
OpenKind_Set,
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef uint32_t ResolveOpenMeta;
|
||||
enum {
|
||||
ResolveOpenMeta_Normal = 0,
|
||||
ResolveOpenMeta_DontError = 2,
|
||||
ResolveOpenMeta_DontExec = 4, // dont error +
|
||||
};
|
||||
|
||||
struct ResolvedOpen {
|
||||
OpenKind kind;
|
||||
String path;
|
||||
Int line, col;
|
||||
bool existing_buffer;
|
||||
};
|
||||
|
||||
void AddCommand(Array<Command> *arr, String name, struct Trigger *trigger, CMDFunction *function);
|
||||
struct Register_Command {
|
||||
Register_Command(Array<Command> *funcs, CMDFunction *function, String name, String binding, String docs = "") {
|
||||
@@ -330,7 +332,7 @@ View *CreateView(BufferID active_buffer);
|
||||
void EvalCommand(String command);
|
||||
void EvalCommand(String16 command);
|
||||
Rect2I GetVisibleCells(Window *window);
|
||||
ResolvedOpen ResolveOpen(Allocator scratch, String path, ResolveOpenMeta meta);
|
||||
ResolvedOpen ResolveOpen(Allocator scratch, Window *window, String path, ResolveOpenMeta meta);
|
||||
BSet Open(String path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
|
||||
BSet Open(String16 path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
|
||||
void CenterView(WindowID window);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
void JumpTempBuffer(BSet *set, String buffer_name) {
|
||||
if (buffer_name.len == 0) {
|
||||
buffer_name = GetUniqueBufferName(GetBufferDirectory(set->buffer), "temp");
|
||||
buffer_name = GetUniqueBufferName(GetDirectory(set->buffer), "temp");
|
||||
}
|
||||
set->view = WindowOpenBufferView(set->window, buffer_name);
|
||||
set->buffer = GetBuffer(set->view->active_buffer);
|
||||
@@ -41,7 +41,7 @@ UIAction WaitForUIAction(mco_coro *co, BSet main) {
|
||||
return result;
|
||||
}
|
||||
|
||||
UIAction ShowYesNoCancelUI(mco_coro *co, BSet main, String question) {
|
||||
UIAction QueryUserYesNoCancel(mco_coro *co, BSet main, String question) {
|
||||
JumpTempBuffer(&main);
|
||||
NextActiveWindowID = main.window->id;
|
||||
RawAppendf(main.buffer, R"==(
|
||||
@@ -72,11 +72,53 @@ void ShowUIMessagef(const char *fmt, ...) {
|
||||
});
|
||||
}
|
||||
|
||||
void DetectUserFileCallback(Window *window, ResolvedOpen *resolved) {
|
||||
if (resolved->kind == OpenKind_Goto) {
|
||||
if (IsFile(resolved->path)) {
|
||||
resolved->kind = OpenKind_Skip;
|
||||
window->ui_query_file = Intern(&GlobalInternTable, resolved->path);
|
||||
window->after_resolve_open_hook = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String16 QueryUserString(mco_coro *co, String ask) {
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
Buffer *original_buffer = main.buffer;
|
||||
JumpTempBuffer(&main);
|
||||
NextActiveWindowID = main.window->id;
|
||||
RawAppendf(main.buffer, R"==(
|
||||
(Enter) :Submit :Cancel (Escape)
|
||||
|
||||
%S
|
||||
================================================
|
||||
>)==", ask);
|
||||
|
||||
main.view->carets[0] = MakeCaret(GetBufferEnd(main.buffer));
|
||||
AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes);
|
||||
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
||||
UIAction action = WaitForUIAction(co, main);
|
||||
if (action != UIAction_Yes) {
|
||||
return u"";
|
||||
}
|
||||
|
||||
Caret a = FindNext(main.buffer, u">", MakeCaret(-1));
|
||||
if (a.range.min == -1) {
|
||||
ReportErrorf("You changed the format of the UI buffer, I was looking for the '>' but can't find it, can't proceed");
|
||||
return u"";
|
||||
}
|
||||
|
||||
a.range.min = a.range.max + 1;
|
||||
a.range.max = GetBufferEnd(main.buffer);
|
||||
return GetString(main.buffer, a.range);
|
||||
}
|
||||
|
||||
String QueryUserFile(mco_coro *co) {
|
||||
// @todo: how to make it so that it doesn't open the file?
|
||||
#if PLUGIN_DIRECTORY_NAVIGATION
|
||||
Open(GetPrimaryDirectory());
|
||||
Window *window = GetWindow(PrimaryWindowID);
|
||||
ViewID original_view = window->active_view;
|
||||
Open(GetPrimaryDirectory());
|
||||
window->after_resolve_open_hook = DetectUserFileCallback;
|
||||
String filename = "";
|
||||
for (;;) {
|
||||
BSet main = GetBSet(window);
|
||||
@@ -84,25 +126,34 @@ String QueryUserFile(mco_coro *co) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!main.buffer->is_dir) {
|
||||
filename = main.buffer->name;
|
||||
if (window->after_resolve_open_hook == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
CoYield(co);
|
||||
}
|
||||
return filename;
|
||||
window->active_view = original_view;
|
||||
return window->ui_query_file;
|
||||
#else
|
||||
// Just simple query
|
||||
// @todo: do we want to split like this? The plugin is maybe leaking too much?
|
||||
// @todo: String QueryUserString(mco_coro *co)
|
||||
String16 string16 = QueryUserString(co, "Please input the path to the desired file");
|
||||
String result = "";
|
||||
{
|
||||
Scratch scratch;
|
||||
String i = ToString(scratch, string16);
|
||||
result = Intern(&GlobalInternTable, i);
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
return "todo";
|
||||
}
|
||||
|
||||
void CO_TestQueryFile(mco_coro *co) {
|
||||
String file = QueryUserFile(co);
|
||||
//String file = QueryUserFile(co);
|
||||
String16 file16 = QueryUserString(co, "Input some kind of a string PLEASE!");
|
||||
{
|
||||
Scratch scratch;
|
||||
String file = ToString(scratch, file16);
|
||||
ReportConsolef("%S", file);
|
||||
}
|
||||
} RegisterCoroutineCommand(CO_TestQueryFile, "", "");
|
||||
|
||||
void MouseLoadWord(Event event, ResolveOpenMeta meta = ResolveOpenMeta_Normal) {
|
||||
@@ -124,21 +175,20 @@ void MouseLoadWord(Event event, ResolveOpenMeta meta = ResolveOpenMeta_Normal) {
|
||||
}
|
||||
}
|
||||
|
||||
ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) {
|
||||
ResolvedOpen ResolveOpen(Allocator alo, Window *window, String path, ResolveOpenMeta meta) {
|
||||
ResolvedOpen result = {};
|
||||
path = Trim(path);
|
||||
bool exec = !(ResolveOpenMeta_DontExec & meta);
|
||||
|
||||
// Editor command
|
||||
if(!(ResolveOpenMeta_DontExec & meta)) {
|
||||
if (StartsWith(path, ":")) {
|
||||
#if PLUGIN_CONFIG
|
||||
if (StartsWith(path, ":Set ")) {
|
||||
if (exec && result.kind == OpenKind_Invalid && StartsWith(path, ":Set ")) {
|
||||
result.kind = OpenKind_Set;
|
||||
result.path = Skip(path, 5);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
// :Command
|
||||
if (exec && result.kind == OpenKind_Invalid && StartsWith(path, ":")) {
|
||||
result.kind = OpenKind_Command;
|
||||
path = Skip(path, 1);
|
||||
result.path.data = path.data;
|
||||
@@ -148,44 +198,36 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) {
|
||||
}
|
||||
result.path.len += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Shell
|
||||
if (!(ResolveOpenMeta_DontExec & meta)) {
|
||||
if (StartsWith(path, "!!")) {
|
||||
// !!exec_hidden
|
||||
if (exec && result.kind == OpenKind_Invalid && StartsWith(path, "!!")) {
|
||||
result.kind = OpenKind_BackgroundExec;
|
||||
result.path = Skip(path, 2);
|
||||
return result;
|
||||
}
|
||||
if (StartsWith(path, "!")) {
|
||||
|
||||
// !exec
|
||||
if (exec && result.kind == OpenKind_Invalid && StartsWith(path, "!")) {
|
||||
result.kind = OpenKind_Exec;
|
||||
result.path = Skip(path, 1);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Web
|
||||
if (!(ResolveOpenMeta_DontExec & meta)) {
|
||||
if (StartsWith(path, "https://") || StartsWith(path, "http://")) {
|
||||
// https://web
|
||||
bool web = StartsWith(path, "https://") || StartsWith(path, "http://");
|
||||
if (exec && result.kind == OpenKind_Invalid && web) {
|
||||
result.path = Format(alo, "%S %S", InternetBrowser, path);
|
||||
result.kind = OpenKind_BackgroundExec;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Commit
|
||||
if (!(ResolveOpenMeta_DontExec & meta)) {
|
||||
if (StartsWith(path, "commit ")) {
|
||||
// commit 3kc09as92
|
||||
if (exec && result.kind == OpenKind_Invalid && StartsWith(path, "commit ")) {
|
||||
path = Skip(path, 7);
|
||||
result.path = Format(alo, "git --no-pager show %S", path);
|
||||
result.kind = OpenKind_Exec;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// c:/filename:32:12
|
||||
if (result.kind == OpenKind_Invalid) {
|
||||
String p = NormalizePath(alo, path);
|
||||
if (p.len == 2 && IsAlphabetic(ToLowerCase(At(p, 0))) && At(p, 1) == ':') {
|
||||
p = Format(alo, "%S/", p);
|
||||
@@ -225,34 +267,35 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) {
|
||||
}
|
||||
|
||||
Buffer *existing_buffer = GetBuffer(path, NULL);
|
||||
if (existing_buffer != NULL) {
|
||||
if (result.kind == OpenKind_Invalid && existing_buffer != NULL) {
|
||||
result.path = path;
|
||||
result.kind = OpenKind_Goto;
|
||||
result.existing_buffer = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (is_absolute && FileExists(path)) {
|
||||
if (result.kind == OpenKind_Invalid && is_absolute && FileExists(path)) {
|
||||
result.path = path;
|
||||
result.kind = OpenKind_Goto;
|
||||
return result;
|
||||
} else {
|
||||
String rel_path = Format(alo, "%S/%S", GetPrimaryDirectory(), path);
|
||||
}
|
||||
|
||||
if (result.kind == OpenKind_Invalid) {
|
||||
String rel_path = Format(alo, "%S/%S", GetDirectory(window), path);
|
||||
existing_buffer = GetBuffer(rel_path, NULL);
|
||||
if (existing_buffer || FileExists(rel_path)) {
|
||||
result.existing_buffer = existing_buffer;
|
||||
result.path = rel_path;
|
||||
result.kind = OpenKind_Goto;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (meta & ResolveOpenMeta_DontError) {
|
||||
if (result.kind == OpenKind_Invalid && (meta & ResolveOpenMeta_DontError)) {
|
||||
result.path = path;
|
||||
result.kind = OpenKind_Skip;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (window->after_resolve_open_hook) {
|
||||
window->after_resolve_open_hook(window, &result);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -261,7 +304,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) {
|
||||
BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = true) {
|
||||
Scratch scratch;
|
||||
BSet set = GetBSet(window);
|
||||
ResolvedOpen o = ResolveOpen(scratch, path, meta);
|
||||
ResolvedOpen o = ResolveOpen(scratch, window, path, meta);
|
||||
if (o.kind == OpenKind_Goto) {
|
||||
if (set_active) {
|
||||
NextActiveWindowID = set.window->id;
|
||||
@@ -274,8 +317,8 @@ BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = t
|
||||
}
|
||||
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
if (o.line != -1) {
|
||||
if (o.col == -1) o.col = 1;
|
||||
if (o.line != 0) {
|
||||
if (o.col == 0) o.col = 1;
|
||||
Int pos = XYToPos(buffer, {o.col - 1, o.line - 1});
|
||||
SelectRange(view, MakeCaret(pos));
|
||||
}
|
||||
|
||||
@@ -393,7 +393,12 @@ BSet GetBSet(WindowID window_id) {
|
||||
|
||||
String GetPrimaryDirectory() {
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
return GetBufferDirectory(main.buffer);
|
||||
return GetDirectory(main.buffer);
|
||||
}
|
||||
|
||||
String GetDirectory(Window *window) {
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
return GetDirectory(main.buffer);
|
||||
}
|
||||
|
||||
void MoveCursorByPageSize(Window *window, int direction, bool shift = false) {
|
||||
|
||||
Reference in New Issue
Block a user