diff options
-rw-r--r-- | build.c | 50 | ||||
-rw-r--r-- | config.c | 19 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | process-posix.c | 4 | ||||
-rw-r--r-- | process-win.c | 38 | ||||
-rw-r--r-- | process.h | 3 | ||||
-rw-r--r-- | ted.cfg | 1 | ||||
-rw-r--r-- | ted.h | 1 |
8 files changed, 78 insertions, 40 deletions
@@ -7,16 +7,26 @@ static void build_clear(Ted *ted) { } static void build_start(Ted *ted) { + Settings *settings = &ted->settings; + ted_save_all(ted); // get rid of any old build errors build_clear(ted); - bool cargo = false; + bool cargo = false, make = false; change_directory(ted->cwd); strcpy(ted->build_dir, ted->cwd); + char *command = settings->build_default_command; + +#if _WIN32 + if (fs_file_exists("make.bat")) { + command = "make.bat"; + } else +#endif + // check if Cargo.toml exists in this or the parent/parent's parent directory if (fs_file_exists("Cargo.toml")) { cargo = true; } else if (fs_file_exists(".." PATH_SEPARATOR_STR "Cargo.toml")) { @@ -27,34 +37,28 @@ static void build_start(Ted *ted) { change_directory(".." PATH_SEPARATOR_STR ".."); ted_full_path(ted, "../..", ted->build_dir, sizeof ted->build_dir); cargo = true; + } else + // Check if Makefile exists in this or the parent directory + if (fs_file_exists("Makefile")) { + make = true; + } else if (fs_file_exists(".." PATH_SEPARATOR_STR "Makefile")) { + change_directory(".."); + ted_full_path(ted, "..", ted->build_dir, sizeof ted->build_dir); + make = true; } - -#if __unix__ - char *program = "/bin/sh"; - char *argv[5] = { - program, "-c", NULL, NULL, NULL - }; - if (cargo) { - argv[2] = "cargo build"; - } else { - argv[2] = "make"; - } -#else - char *program = NULL; - char *argv[2] = {NULL, NULL}; + + // @TODO(eventually): go build + if (cargo) { - program = "cargo"; - argv[0] = "build"; - } else if (fs_file_exists("make.bat")) { - program = "make.bat"; - } else { - program = "make"; + command = "cargo build"; + } else if (make) { + command = "make"; } -#endif - if (process_exec(&ted->build_process, program, argv)) { + if (process_run(&ted->build_process, command)) { ted->building = true; ted->build_shown = true; + // new empty build output buffer buffer_new_file(&ted->build_buffer, NULL); ted->build_buffer.store_undo_events = false; // don't need undo events for build output buffer ted->build_buffer.view_only = true; @@ -169,6 +169,11 @@ void config_read(Ted *ted, char const *filename) { char const *name; u16 *control, min, max; } OptionU16; + typedef struct { + char const *name; + char *control; + size_t buf_size; + } OptionString; // core options // (these go at the start so they don't need to be re-computed each time) OptionBool const options_bool[] = { @@ -195,6 +200,9 @@ void config_read(Ted *ted, char const *filename) { {"max-menu-width", &settings->max_menu_width, 10, U16_MAX}, {"error-display-time", &settings->error_display_time, 0, U16_MAX}, }; + OptionString const options_string[] = { + {"build-default-command", settings->build_default_command, sizeof settings->build_default_command}, + }; FILE *fp = fopen(filename, "rb"); if (fp) { @@ -377,6 +385,17 @@ void config_read(Ted *ted, char const *filename) { config_err(cfg, "Invalid %s: %s. This should be a number from %g to %g.", option->name, value, option->min, option->max); } } + + for (size_t i = 0; i < arr_count(options_string); ++i) { + OptionString const *option = &options_string[i]; + if (streq(key, option->name)) { + if (strlen(value) >= option->buf_size) { + config_err(cfg, "%s is too long (length: %zu, maximum length: %zu).", key, strlen(value), option->buf_size - 1); + } else { + str_cpy(option->control, option->buf_size, value); + } + } + } } break; } @@ -1,6 +1,4 @@ // @TODO: -// - :build (F4) -- cargo build if editing .rs file or file called Cargo.toml, otherwise make. - // - go to definition (with ctags) -- ctrl+click would be nice // - :run -- if .html file, open in browser, otherwise figure out a way of sending a command to bash?? diff --git a/process-posix.c b/process-posix.c index 6434f6e..8bfe036 100644 --- a/process-posix.c +++ b/process-posix.c @@ -9,7 +9,7 @@ struct Process { char error[64]; }; -bool process_exec(Process *proc, char const *program, char **argv) { +bool process_run(Process *proc, char const *command) { memset(proc, 0, sizeof *proc); bool success = false; @@ -24,6 +24,8 @@ bool process_exec(Process *proc, char const *program, char **argv) { dup2(pipefd[1], STDERR_FILENO); close(pipefd[0]); close(pipefd[1]); + char *program = "/bin/sh"; + char *argv[] = {program, "-c", (char *)command, NULL}; if (execv(program, argv) == -1) { dprintf(STDERR_FILENO, "%s: %s\n", program, strerror(errno)); exit(127); diff --git a/process-win.c b/process-win.c index 95f3fbe..b24dd68 100644 --- a/process-win.c +++ b/process-win.c @@ -3,13 +3,26 @@ struct Process { HANDLE pipe_read, pipe_write; PROCESS_INFORMATION process_info; - char error[64]; + char error[200]; }; -bool process_exec(Process *process, char const *program, char **argv) { +static void get_last_error_str(char *out, size_t out_sz) { + size_t size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), out, (DWORD)out_sz - 1, NULL); + out[size] = 0; + char *cr = strchr(out, '\r'); + if (cr) *cr = '\0'; // get rid of carriage return+newline at end of error +} + +bool process_run(Process *process, char const *command) { // thanks to https://stackoverflow.com/a/35658917 bool success = false; memset(process, 0, sizeof *process); + char *command_line = str_dup(command); + if (!command_line) { + strbuf_printf(process->error, "Out of memory."); + return false; + } HANDLE pipe_read, pipe_write; SECURITY_ATTRIBUTES security_attrs = {sizeof(SECURITY_ATTRIBUTES)}; security_attrs.bInheritHandle = TRUE; @@ -20,28 +33,25 @@ bool process_exec(Process *process, char const *program, char **argv) { startup.hStdError = pipe_write; startup.wShowWindow = SW_HIDE; - // fuckin windows - char command_line[4096]; - strbuf_cpy(command_line, program); - strbuf_catf(command_line, " "); - for (int i = 0; argv[i]; ++i) { - strbuf_catf(command_line, "%s ", argv[i]); - } - if (CreateProcessA(NULL, command_line, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &startup, &process->process_info)) { process->pipe_read = pipe_read; process->pipe_write = pipe_write; success = true; } else { - strbuf_printf(process->error, "Couldn't create process (error code %u)", (unsigned)GetLastError()); + char buf[150]; + get_last_error_str(buf, sizeof buf); + strbuf_printf(process->error, "Couldn't run `%s`: %s", command, buf); } + free(command_line); if (!success) { CloseHandle(pipe_read); CloseHandle(pipe_write); } } else { - strbuf_printf(process->error, "Couldn't create pipe (error code %u)", (unsigned)GetLastError()); + char buf[150]; + get_last_error_str(buf, sizeof buf); + strbuf_printf(process->error, "Couldn't create pipe: %s", buf); } return success; } @@ -60,7 +70,9 @@ long long process_read(Process *process, char *data, size_t size) { return bytes_read; } } else { - strbuf_printf(process->error, "Couldn't read from pipe (error code %u)", (unsigned)GetLastError()); + char buf[150]; + get_last_error_str(buf, sizeof buf); + strbuf_printf(process->error, "Couldn't read from pipe: %s", buf); return -2; } } @@ -4,8 +4,9 @@ typedef struct Process Process; +// execute the given command (like if it was passed to system()). // returns false on failure -bool process_exec(Process *process, char const *program, char **argv); +bool process_run(Process *process, char const *command); // returns the error last error produced, or NULL if there was no error. char const *process_geterr(Process *process); // returns: @@ -23,6 +23,7 @@ syntax-highlighting = on line-numbers = on # If set to "on", when a file is changed by another program, it will be reloaded by ted without asking you. auto-reload = off +build-default-command = timeout /t 5 [keyboard] # motion and selection @@ -78,6 +78,7 @@ typedef struct { u8 border_thickness; u8 padding; u8 scrolloff; + char build_default_command[256]; // [i] = comma-separated string of file extensions for language i, or NULL for none char *language_extensions[LANG_COUNT]; } Settings; |