summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buffer.c29
-rw-r--r--command.c2
-rw-r--r--lsp.c4
-rw-r--r--main.c5
-rw-r--r--os-posix.c2
-rw-r--r--os-win.c2
-rw-r--r--os.h2
-rw-r--r--ted.c2
-rw-r--r--ted.h91
9 files changed, 110 insertions, 29 deletions
diff --git a/buffer.c b/buffer.c
index cfebcac..bcb8345 100644
--- a/buffer.c
+++ b/buffer.c
@@ -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;
diff --git a/command.c b/command.c
index 464f240..ff1bc3f 100644
--- a/command.c
+++ b/command.c
@@ -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;
diff --git a/lsp.c b/lsp.c
index 877e56f..01dc2a3 100644
--- a/lsp.c
+++ b/lsp.c
@@ -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) {
diff --git a/main.c b/main.c
index 898ebe4..7a9b507 100644
--- a/main.c
+++ b/main.c
@@ -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)
diff --git a/os-posix.c b/os-posix.c
index 0d00882..f98f029 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -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;
diff --git a/os-win.c b/os-win.c
index 1d0f21e..a32215a 100644
--- a/os-win.c
+++ b/os-win.c
@@ -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);
diff --git a/os.h b/os.h
index 27b0d79..fd4bf8e 100644
--- a/os.h
+++ b/os.h
@@ -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
diff --git a/ted.c b/ted.c
index 13e01a8..ea585b9 100644
--- a/ted.c
+++ b/ted.c
@@ -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 {
diff --git a/ted.h b/ted.h
index d6ece2c..7793f14 100644
--- a/ted.h
+++ b/ted.h
@@ -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);