diff options
author | cflip <cflip@cflip.net> | 2023-01-31 13:31:21 -0700 |
---|---|---|
committer | cflip <cflip@cflip.net> | 2023-01-31 14:00:17 -0700 |
commit | 1b8261071ef3ad3b8d1c2db6e712b0e590c563b3 (patch) | |
tree | ca7e8528b37ccd1d7748b5c70582239b506f8b6a | |
parent | 264c4186ed8e3d2e3275a6514c8714903036cb26 (diff) |
Now there there is a new way to prompt for text, we can reimplement the
long abandoned editor_prompt function and use it to allow saving to new
files.
The new editor_prompt function takes a callback that will be called
after the user presses enter on the prompt.
-rw-r--r-- | editor.c | 67 | ||||
-rw-r--r-- | editor.h | 5 | ||||
-rw-r--r-- | file.c | 48 | ||||
-rw-r--r-- | file.h | 2 | ||||
-rw-r--r-- | input.c | 2 |
5 files changed, 76 insertions, 48 deletions
@@ -7,6 +7,7 @@ #include <string.h> #include <unistd.h> +#include "file.h" #include "input.h" #include "syntax.h" #include "window.h" @@ -49,22 +50,56 @@ void editor_set_status_message(struct editor_state* editor, const char* format, editor->status_message_time = time(NULL); } -char* editor_prompt(struct editor_state* editor, char* prompt, void (*callback)(struct editor_state*, char*, int)) +static prompt_callback_t saved_prompt_callback; + +void editor_prompt(struct editor_state* editor, char* prompt, prompt_callback_t callback) { - /* TODO: The previous implementation of this function relied on reading - * input from the terminal, but now that we get input through window events - * it's no longer possible to sit in an infinite loop waiting for keys here. - */ - printf("TODO: editor_prompt unimplemented\n"); - return NULL; + saved_prompt_callback = callback; + editor_set_mode(editor, EDITOR_MODE_PROMPT); } void editor_run_command(struct editor_state *editor) { - /* TODO: Do something here */ + textbuf_append(&editor->cmdline, "\0", 1); + + if (saved_prompt_callback) { + saved_prompt_callback(editor, editor->cmdline.buffer, editor->cmdline.length); + } + + /* TODO: Parse and run a command by its name */ editor_set_mode(editor, EDITOR_MODE_NORMAL); } +static void save_callback(struct editor_state *editor, char *filename, size_t namelen) +{ + if (filename == NULL) + return; + + editor->filename = malloc(namelen); + memcpy(editor->filename, filename, namelen); + + editor_select_syntax_highlight(editor); + window_set_filename(editor->filename); + + editor_try_save(editor); +} + +void editor_try_save(struct editor_state *editor) +{ + /* + * If there is no filename, set a callback to change the filename and + * come back here later once it is set. + */ + if (editor->filename == NULL) { + editor_prompt(editor, "Save as: ", save_callback); + return; + } + + int saverr = file_save_current_file(editor); + if (saverr != 0) + editor_set_status_message(editor, "Failed to save file: %s", strerror(saverr)); +} + void editor_try_quit(struct editor_state *editor) { if (editor->dirty && quit_message_time == 0) { @@ -191,6 +226,7 @@ void editor_set_mode(struct editor_state *editor, enum editor_mode mode) /* Clear the command line if we are leaving prompt mode. */ if (last_mode == EDITOR_MODE_PROMPT) { textbuf_clear(&editor->cmdline); + saved_prompt_callback = NULL; } /* Ignore the extra first letter if we are entering a typing mode. */ @@ -263,20 +299,7 @@ static void editor_find_callback(struct editor_state* editor, char* query, int k void editor_find(struct editor_state* editor) { - int saved_cursor_x = editor->cursor_x; - int saved_cursor_y = editor->cursor_y; - int saved_col_offset = editor->col_offset; - int saved_line_offset = editor->line_offset; - - char* query = editor_prompt(editor, "Search: %s (Use Esc/Arrows/Enter)", editor_find_callback); - if (query) { - free(query); - } else { - editor->cursor_x = saved_cursor_x; - editor->cursor_y = saved_cursor_y; - editor->col_offset = saved_col_offset; - editor->line_offset = saved_line_offset; - } + /* TODO: Unimplemented */ } void editor_scroll(struct editor_state* editor) @@ -36,11 +36,14 @@ struct editor_state { struct textbuf cmdline; }; +typedef void (*prompt_callback_t)(struct editor_state*, char*, size_t); + void init_editor(struct editor_state* editor); void editor_set_status_message(struct editor_state* editor, const char* format, ...); -char* editor_prompt(struct editor_state* editor, char* prompt, void (*callback)(struct editor_state*, char*, int)); +void editor_prompt(struct editor_state* editor, char* prompt, prompt_callback_t callback); void editor_run_command(struct editor_state *editor); +void editor_try_save(struct editor_state *editor); void editor_try_quit(struct editor_state *editor); void editor_move_left(struct editor_state *); @@ -10,6 +10,7 @@ #include "error.h" #include "line.h" #include "syntax.h" +#include "window.h" static char *lines_to_string(struct editor_state *editor, int *buffer_length) { @@ -70,34 +71,35 @@ void editor_open(struct editor_state* editor, char* filename) editor->dirty = 0; } -void editor_save(struct editor_state* editor) +int file_save_current_file(struct editor_state *editor) { - if (editor->filename == NULL) { - editor->filename = editor_prompt(editor, "Save as: %s", NULL); - - if (editor->filename == NULL) - return; - - editor_select_syntax_highlight(editor); - window_set_filename(editor->filename); - } + /* Assume that the editor has already prompted the user for a name */ + if (editor->filename == NULL) + return EINVAL; int length; char *buffer = lines_to_string(editor, &length); int fd = open(editor->filename, O_RDWR | O_CREAT, 0644); - if (fd != -1) { - if (ftruncate(fd, length) != -1) { - if (write(fd, buffer, length) == length) { - close(fd); - free(buffer); - editor_set_status_message(editor, "%d bytes written to disk", length); - editor->dirty = 0; - return; - } - } - close(fd); - } + if (fd == -1) + goto fail; + + if (ftruncate(fd, length) == -1) + goto fail; + + if (write(fd, buffer, length) != length) + goto fail; + + close(fd); + free(buffer); + editor_set_status_message(editor, "%d bytes written to disk", length); + editor->dirty = 0; + + return 0; + +fail: + int saved_errno = errno; + close(fd); free(buffer); - editor_set_status_message(editor, "Failed to write to disk: %s", strerror(errno)); + return saved_errno; } @@ -4,6 +4,6 @@ #include "editor.h" void editor_open(struct editor_state* editor, char* filename); -void editor_save(struct editor_state* editor); +int file_save_current_file(struct editor_state *editor); #endif @@ -56,7 +56,7 @@ void editor_process_keypress(struct editor_state *editor, SDL_Keysym *keysym) break; case SDLK_s: if (keysym->mod & KMOD_CTRL) { - editor_save(editor); + editor_try_save(editor); break; } editor_move_down(editor); |