diff options
author | pommicket <pommicket@gmail.com> | 2023-01-04 19:51:13 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2023-01-04 19:51:13 -0500 |
commit | d9cc57e9ff1725e6e63973705adbf218d6961d17 (patch) | |
tree | 4c2eaa1e0b39a3387793299c52062996ee7be3ae | |
parent | 87b0da0d33d97abc0ba94ad18d988d370d09441b (diff) |
fix command-line argument starting file if it doesn't exist
it used to open an untitled buffer.
also, clarified buffer_load_file
-rw-r--r-- | buffer.c | 29 | ||||
-rw-r--r-- | command.c | 2 | ||||
-rw-r--r-- | lsp.c | 4 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | os-posix.c | 2 | ||||
-rw-r--r-- | os-win.c | 2 | ||||
-rw-r--r-- | os.h | 2 | ||||
-rw-r--r-- | ted.c | 2 | ||||
-rw-r--r-- | ted.h | 91 |
9 files changed, 110 insertions, 29 deletions
@@ -1342,9 +1342,6 @@ i64 buffer_cursor_move_right_words(TextBuffer *buffer, i64 nwords) { return ret; } -// Returns a string of word characters (see is_word) around the position, -// or an empty string if neither of the characters to the left and right of the cursor are word characters. -// NOTE: The string is invalidated when the buffer is changed!!! String32 buffer_word_at_pos(TextBuffer *buffer, BufferPos pos) { buffer_pos_validate(buffer, &pos); Line *line = &buffer->lines[pos.line]; @@ -1723,7 +1720,6 @@ void buffer_select_to_end_of_file(TextBuffer *buffer) { buffer_select_to_pos(buffer, buffer_pos_end_of_file(buffer)); } -// select the word the cursor is inside of void buffer_select_word(TextBuffer *buffer) { BufferPos start_pos = buffer->cursor_pos, end_pos = buffer->cursor_pos; if (start_pos.index > 0) @@ -1735,7 +1731,6 @@ void buffer_select_word(TextBuffer *buffer) { buffer_select_to_pos(buffer, start_pos); } -// select the line the cursor is currently on void buffer_select_line(TextBuffer *buffer) { u32 line = buffer->cursor_pos.line; if (line == buffer->nlines - 1) @@ -1750,8 +1745,7 @@ void buffer_select_all(TextBuffer *buffer) { buffer_select_to_pos(buffer, buffer_pos_end_of_file(buffer)); } -// stop selecting -void buffer_disable_selection(TextBuffer *buffer) { +void buffer_deselect(TextBuffer *buffer) { if (buffer->selection) { buffer->cursor_pos = buffer->selection_pos; buffer->selection = false; @@ -2198,7 +2192,7 @@ void buffer_end_edit_chain(TextBuffer *buffer) { buffer->chaining_edits = buffer->will_chain_edits = false; } -void buffer_copy_or_cut(TextBuffer *buffer, bool cut) { +static void buffer_copy_or_cut(TextBuffer *buffer, bool cut) { if (buffer->selection) { BufferPos pos1 = buffer_pos_min(buffer->selection_pos, buffer->cursor_pos); BufferPos pos2 = buffer_pos_max(buffer->selection_pos, buffer->cursor_pos); @@ -2244,12 +2238,17 @@ void buffer_paste(TextBuffer *buffer) { } // if an error occurs, buffer is left untouched (except for the error field) and the function returns false. -Status buffer_load_file(TextBuffer *buffer, const char *filename) { +Status buffer_load_file(TextBuffer *buffer, const char *path) { + if (!path || !path_is_absolute(path)) { + buffer_error(buffer, "Loaded path '%s' is not an absolute path.", path); + return false; + } + // it's important we do this first, since someone might write to the file while we're reading it, // and we want to detect that in buffer_externally_changed - double modified_time = timespec_to_seconds(time_last_modified(buffer->filename)); + double modified_time = timespec_to_seconds(time_last_modified(path)); - FILE *fp = fopen(filename, "rb"); + FILE *fp = fopen(path, "rb"); bool success = true; Line *lines = NULL; u32 nlines = 0, lines_capacity = 0; @@ -2263,7 +2262,7 @@ Status buffer_load_file(TextBuffer *buffer, const char *filename) { u32 max_file_size_view_only = default_settings->max_file_size_view_only; if (file_pos == -1 || file_pos == LONG_MAX) { - buffer_error(buffer, "Couldn't get file position. There is something wrong with the file '%s'.", filename); + buffer_error(buffer, "Couldn't get file position. There is something wrong with the file '%s'.", path); success = false; } else if (file_size > max_file_size_editable && file_size > max_file_size_view_only) { buffer_error(buffer, "File too big (size: %zu).", file_size); @@ -2323,7 +2322,7 @@ Status buffer_load_file(TextBuffer *buffer, const char *filename) { } if (success) { - char *filename_copy = buffer_strdup(buffer, filename); + char *filename_copy = buffer_strdup(buffer, path); if (!filename_copy) success = false; if (success) { // everything is good @@ -2335,7 +2334,7 @@ Status buffer_load_file(TextBuffer *buffer, const char *filename) { buffer->lines_capacity = lines_capacity; buffer->filename = filename_copy; buffer->last_write_time = modified_time; - if (!(fs_path_permission(filename) & FS_PERMISSION_WRITE)) { + if (!(fs_path_permission(path) & FS_PERMISSION_WRITE)) { // can't write to this file; make the buffer view only. buffer->view_only = true; } @@ -2355,7 +2354,7 @@ Status buffer_load_file(TextBuffer *buffer, const char *filename) { } fclose(fp); } else { - buffer_error(buffer, "Couldn't open file %s: %s.", filename, strerror(errno)); + buffer_error(buffer, "Couldn't open file %s: %s.", path, strerror(errno)); success = false; } return success; @@ -546,7 +546,7 @@ void command_execute(Ted *ted, Command c, i64 argument) { build_stop(ted); } if (buffer) { - buffer_disable_selection(buffer); + buffer_deselect(buffer); } } break; @@ -421,6 +421,10 @@ static int lsp_communication_thread(void *data) { } u32 lsp_document_id(LSP *lsp, const char *path) { + if (!path) { + assert(0); + return 0; + } SDL_LockMutex(lsp->document_mutex); u32 *value = str_hash_table_get(&lsp->document_ids, path); if (!value) { @@ -26,6 +26,7 @@ - clangd bug report: - textDocumemt/definition on ted.h declarations just gives you the declaration FUTURE FEATURES: +- better handling of backspace with space indentation - CSS highlighting - styles ([color] sections) - make go-to-definition/hover/highlight modifier key configurable @@ -358,7 +359,7 @@ int main(int argc, char **argv) { // make sure signal handler has access to ted. error_signal_handler_ted = ted; - fs_get_cwd(ted->start_cwd, sizeof ted->start_cwd); + os_get_cwd(ted->start_cwd, sizeof ted->start_cwd); { // get local and global data directory #if _WIN32 wchar_t *appdata = NULL; @@ -408,7 +409,7 @@ int main(int argc, char **argv) { } { // get current working directory - fs_get_cwd(ted->cwd, sizeof ted->cwd); + os_get_cwd(ted->cwd, sizeof ted->cwd); } { // check if this is the installed version of ted (as opposed to just running it from the directory with the source) @@ -105,7 +105,7 @@ int fs_mkdir(const char *path) { } } -int fs_get_cwd(char *buf, size_t buflen) { +int os_get_cwd(char *buf, size_t buflen) { assert(buf && buflen); if (getcwd(buf, buflen)) { return 1; @@ -98,7 +98,7 @@ int fs_mkdir(const char *path) { } } -int fs_get_cwd(char *buf, size_t buflen) { +int os_get_cwd(char *buf, size_t buflen) { assert(buf && buflen); wchar_t wide_path[4100]; DWORD wide_pathlen = GetCurrentDirectoryW(sizeof wide_path - 1, wide_path); @@ -42,7 +42,7 @@ int fs_mkdir(const char *path); // 1 if the working directory was inserted into buf successfully // 0 if buf is too short to hold the cwd // -1 if we can't get the cwd for whatever reason. -int fs_get_cwd(char *buf, size_t buflen); +int os_get_cwd(char *buf, size_t buflen); struct timespec time_last_modified(const char *filename); struct timespec time_get(void); // sleep for a certain number of nanoseconds @@ -459,7 +459,7 @@ bool ted_new_file(Ted *ted, const char *filename) { strbuf_cpy(path, TED_UNTITLED); if (ted_open_buffer(ted, &buffer_idx, &tab_idx)) { TextBuffer *buffer = &ted->buffers[buffer_idx]; - buffer_new_file(buffer, TED_UNTITLED); + buffer_new_file(buffer, path); if (!buffer_has_error(buffer)) { return true; } else { @@ -786,69 +786,146 @@ i64 buffer_pos_move_right_words(TextBuffer *buffer, BufferPos *pos, i64 nwords); i64 buffer_cursor_move_left_words(TextBuffer *buffer, i64 nwords); // returns the number of words successfully moved by. i64 buffer_cursor_move_right_words(TextBuffer *buffer, i64 nwords); +// Returns a string of word characters (see is32_word) around the position, +// or an empty string if neither of the characters to the left and right of the cursor are word characters. +// NOTE: The string is invalidated when the buffer is changed!!! +// The return value should NOT be freed. String32 buffer_word_at_pos(TextBuffer *buffer, BufferPos pos); +// Get the word at the cursor. +// NOTE: The string is invalidated when the buffer is changed!!! +// The return value should NOT be freed. String32 buffer_word_at_cursor(TextBuffer *buffer); +// Get a UTF-8 string consisting of the word at the cursor. +// The return value should be freed. char *buffer_word_at_cursor_utf8(TextBuffer *buffer); +// Buffer position corresponding to the start of line `line` (0-indexed). BufferPos buffer_pos_start_of_line(TextBuffer *buffer, u32 line); +// Buffer position corresponding to the end of line `line` (0-indexed). BufferPos buffer_pos_end_of_line(TextBuffer *buffer, u32 line); +// Move cursor to the start of the line, like the Home key does. void buffer_cursor_move_to_start_of_line(TextBuffer *buffer); +// Move cursor to the end of the line, like the End key does. void buffer_cursor_move_to_end_of_line(TextBuffer *buffer); +// Move cursor to the start of the file, like Ctrl+Home does. void buffer_cursor_move_to_start_of_file(TextBuffer *buffer); +// Move cursor to the end of the file, like Ctrl+End does. void buffer_cursor_move_to_end_of_file(TextBuffer *buffer); +// Get the LSPDocumentID corresponding to the file this buffer contains. +// The return value is only useful if buffer_lsp(buffer) != NULL. LSPDocumentID buffer_lsp_document_id(TextBuffer *buffer); +// Get LSPPosition corresponding to position in buffer. LSPPosition buffer_pos_to_lsp_position(TextBuffer *buffer, BufferPos pos); +// Get LSPDocumentPosition corresponding to position in buffer. LSPDocumentPosition buffer_pos_to_lsp_document_position(TextBuffer *buffer, BufferPos pos); +// Convert LSPPosition to BufferPos. BufferPos buffer_pos_from_lsp(TextBuffer *buffer, LSPPosition lsp_pos); +// Get the cursor position as an LSPPosition. LSPPosition buffer_cursor_pos_as_lsp_position(TextBuffer *buffer); +// Get the cursor position as an LSPDocumentPosition. LSPDocumentPosition buffer_cursor_pos_as_lsp_document_position(TextBuffer *buffer); +// Put text at a position. All text insertion should eventually go through this function. BufferPos buffer_insert_text_at_pos(TextBuffer *buffer, BufferPos pos, String32 str); +// Insert a single character at a position. void buffer_insert_char_at_pos(TextBuffer *buffer, BufferPos pos, char32_t c); +// Set the selection to between `buffer->cursor_pos` and `pos`, +// and move the cursor to `pos`. void buffer_select_to_pos(TextBuffer *buffer, BufferPos pos); -// Like shift+left in most editors, move cursor nchars chars to the left, selecting everything in between +// Like shift+left, move cursor `nchars` chars to the left, selecting everything in between. void buffer_select_left(TextBuffer *buffer, i64 nchars); +// Like shift+right, move cursor `nchars` chars to the right, selecting everything in between. void buffer_select_right(TextBuffer *buffer, i64 nchars); +// Like shift+down, move cursor `nchars` lines down, selecting everything in between. void buffer_select_down(TextBuffer *buffer, i64 nchars); +// Like shift+up, move cursor `nchars` lines up, selecting everything in between. void buffer_select_up(TextBuffer *buffer, i64 nchars); +// Move the cursor `by` lines down, selecting everything in between. void buffer_select_down_blank_lines(TextBuffer *buffer, i64 by); +// Move the cursor `by` lines up, selecting everything in between. void buffer_select_up_blank_lines(TextBuffer *buffer, i64 by); +// Move the cursor `nwords` words left, selecting everything in between. void buffer_select_left_words(TextBuffer *buffer, i64 nwords); +// Move the cursor `nwords` words right, selecting everything in between. void buffer_select_right_words(TextBuffer *buffer, i64 nwords); +// Like Shift+Home, move cursor to start of line and select everything in between. void buffer_select_to_start_of_line(TextBuffer *buffer); +// Like Shift+End, move cursor to end of line and select everything in between. void buffer_select_to_end_of_line(TextBuffer *buffer); +// Like Ctrl+Shift+Home, move cursor to start of file and select everything in between. void buffer_select_to_start_of_file(TextBuffer *buffer); +// Like Ctrl+Shift+End, move cursor to end of file and select everything in between. void buffer_select_to_end_of_file(TextBuffer *buffer); +// select the word the cursor is inside of void buffer_select_word(TextBuffer *buffer); +// select the line the cursor is currently on void buffer_select_line(TextBuffer *buffer); +// select all of the buffer's contents void buffer_select_all(TextBuffer *buffer); -void buffer_disable_selection(TextBuffer *buffer); +// Remove current selection. +void buffer_deselect(TextBuffer *buffer); +// Scroll up by `npages` pages void buffer_page_up(TextBuffer *buffer, i64 npages); +// Scroll down by `npages` pages void buffer_page_down(TextBuffer *buffer, i64 npages); +// Scroll up by `npages` pages, selecting everything in between void buffer_select_page_up(TextBuffer *buffer, i64 npages); +// Scroll down by `npages` pages, selecting everything in between void buffer_select_page_down(TextBuffer *buffer, i64 npages); -void buffer_delete_chars_at_pos(TextBuffer *buffer, BufferPos pos, i64 nchars_); +// Delete `nchars` characters starting from `pos`. +// All text deletion should eventually go through this function. +void buffer_delete_chars_at_pos(TextBuffer *buffer, BufferPos pos, i64 nchars); +// Delete characters between the two positions. +// The order of `p1` and `p2` is irrelevant. i64 buffer_delete_chars_between(TextBuffer *buffer, BufferPos p1, BufferPos p2); +// Delete current selection. i64 buffer_delete_selection(TextBuffer *buffer); +// Insert UTF-32 text at the cursor, and move the cursor to the end of it. void buffer_insert_text_at_cursor(TextBuffer *buffer, String32 str); +// Insert a single character at the cursor, and move the cursor past it. void buffer_insert_char_at_cursor(TextBuffer *buffer, char32_t c); +// Insert UTF-8 text at the cursor, and move the cursor to the end of it. void buffer_insert_utf8_at_cursor(TextBuffer *buffer, const char *utf8); +// Insert a "tab" at the cursor position, and move the cursor past it. +// This inserts spaces if ted is configured to indent with spaces. void buffer_insert_tab_at_cursor(TextBuffer *buffer); +// Insert a newline at the cursor position. +// If `buffer` is a line buffer, this "submits" the buffer. +// If not, this auto-indents the next line, and moves the cursor to it. void buffer_newline(TextBuffer *buffer); +// Delete `nchars` characters after the cursor. void buffer_delete_chars_at_cursor(TextBuffer *buffer, i64 nchars); -i64 buffer_backspace_at_pos(TextBuffer *buffer, BufferPos *pos, i64 ntimes); -i64 buffer_backspace_at_cursor(TextBuffer *buffer, i64 ntimes); +// Delete `nchars` characters before *pos, and set *pos to just before the deleted characters. +// Returns the number of characters actually deleted. +i64 buffer_backspace_at_pos(TextBuffer *buffer, BufferPos *pos, i64 nchars); +// Delete `nchars` characters before the cursor position, and set the cursor position accordingly. +// Returns the number of characters actually deleted. +i64 buffer_backspace_at_cursor(TextBuffer *buffer, i64 nchars); +// Delete `nwords` words after the position. void buffer_delete_words_at_pos(TextBuffer *buffer, BufferPos pos, i64 nwords); +// Delete `nwords` words after the cursor. void buffer_delete_words_at_cursor(TextBuffer *buffer, i64 nwords); +// Delete `nwords` words before *pos, and set *pos to just before the deleted words. +// Returns the number of words actually deleted. void buffer_backspace_words_at_pos(TextBuffer *buffer, BufferPos *pos, i64 nwords); +// Delete `nwords` words before the cursor position, and set the cursor position accordingly. +// Returns the number of words actually deleted. void buffer_backspace_words_at_cursor(TextBuffer *buffer, i64 nwords); +// Undo `ntimes` times void buffer_undo(TextBuffer *buffer, i64 ntimes); +// Redo `ntimes` times void buffer_redo(TextBuffer *buffer, i64 ntimes); +// Start a new "edit chain". Undoing once after an edit chain will undo everything in the chain. void buffer_start_edit_chain(TextBuffer *buffer); +// End the edit chain. void buffer_end_edit_chain(TextBuffer *buffer); -void buffer_copy_or_cut(TextBuffer *buffer, bool cut); +// Copy the current selection to the clipboard. void buffer_copy(TextBuffer *buffer); +// Copy the current selection to the clipboard, and delete it. void buffer_cut(TextBuffer *buffer); +// Insert the clipboard contents at the cursor position. void buffer_paste(TextBuffer *buffer); -bool buffer_load_file(TextBuffer *buffer, const char *filename); +// Load the file `path`. If `path` is not an absolute path, +// this function will fail. +bool buffer_load_file(TextBuffer *buffer, const char *path); void buffer_reload(TextBuffer *buffer); bool buffer_externally_changed(TextBuffer *buffer); void buffer_new_file(TextBuffer *buffer, const char *filename); |