From 8944eb64682f626f76b9b204a58afc8fa5d0a522 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Fri, 5 Mar 2021 16:11:01 -0500 Subject: fix some little problems with the file selector --- README.md | 6 ++---- command.c | 3 +++ command.h | 4 +++- main.c | 3 --- node.c | 18 +++++++++++++++--- ted.c | 2 +- ted.cfg | 4 +++- ui.c | 19 ++++++++++++------- util.c | 23 +++++++++++++++++++++-- windows_installer/ted/ted/ted.vdproj | 6 +++--- 10 files changed, 63 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 9b457c5..cb79acc 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,12 @@ A text editor. -**ted is still very new, and there are almost certainly bugs. I don't recommend using this as your main text editor yet.** +**ted is still very new. There is no nice installer yet (if you want ted, you'll have to build it from source). +I'll release installers after testing it a bit more to try to find any bugs there might be.** -To install ted, you will need to build it from source (see below). Eventually there will be a nice installer, but only when it's stable and bug-free enough for -ordinary use. - ## Why? There are a lot of text editors out there. ted doesn't do anything new. diff --git a/command.c b/command.c index d6108bd..310c76d 100644 --- a/command.c +++ b/command.c @@ -373,6 +373,9 @@ void command_execute(Ted *ted, Command c, i64 argument) { case CMD_SPLIT_JOIN: if (node) node_join(ted, node); break; + case CMD_SPLIT_SWITCH: + if (node) node_split_switch(ted); + break; case CMD_SPLIT_SWAP: if (node) node_split_swap(ted); break; diff --git a/command.h b/command.h index aadac48..97812b0 100644 --- a/command.h +++ b/command.h @@ -86,7 +86,8 @@ ENUM_U16 { CMD_SPLIT_HORIZONTAL, CMD_SPLIT_VERTICAL, CMD_SPLIT_JOIN, - CMD_SPLIT_SWAP, // go to the other side of a split + CMD_SPLIT_SWITCH, // switch to the other side of a split + CMD_SPLIT_SWAP, // swap which side is which in a split. CMD_ESCAPE, // by default this is the escape key. closes menus, etc. @@ -166,6 +167,7 @@ static CommandName const command_names[] = { {"split-horizontal", CMD_SPLIT_HORIZONTAL}, {"split-vertical", CMD_SPLIT_VERTICAL}, {"split-join", CMD_SPLIT_JOIN}, + {"split-switch", CMD_SPLIT_SWITCH}, {"split-swap", CMD_SPLIT_SWAP}, {"escape", CMD_ESCAPE}, }; diff --git a/main.c b/main.c index 356a2fa..de8f3ce 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,3 @@ -// @TODO: -// - test windows 7 - #include "base.h" no_warn_start #if _WIN32 diff --git a/node.c b/node.c index 5ae0ea7..7898c3c 100644 --- a/node.c +++ b/node.c @@ -417,11 +417,12 @@ static void node_split(Ted *ted, Node *node, bool vertical) { } } -// swap to the other side of a split -static void node_split_swap(Ted *ted) { +static void node_split_switch(Ted *ted) { assert(ted->active_node); u16 active_node_idx = (u16)(ted->active_node - ted->nodes); - Node *parent = &ted->nodes[node_parent(ted, active_node_idx)]; + i32 parent_idx = node_parent(ted, active_node_idx); + if (parent_idx < 0) return; + Node *parent = &ted->nodes[parent_idx]; if (parent) { if (parent->split_a == active_node_idx) { ted_node_switch(ted, &ted->nodes[parent->split_b]); @@ -430,3 +431,14 @@ static void node_split_swap(Ted *ted) { } } } + +static void node_split_swap(Ted *ted) { + assert(ted->active_node); + u16 active_node_idx = (u16)(ted->active_node - ted->nodes); + i32 parent_idx = node_parent(ted, active_node_idx); + if (parent_idx < 0) return; + Node *parent = &ted->nodes[parent_idx]; + u16 temp = parent->split_a; + parent->split_a = parent->split_b; + parent->split_b = temp; +} diff --git a/ted.c b/ted.c index 3150458..e3c6f47 100644 --- a/ted.c +++ b/ted.c @@ -233,7 +233,7 @@ static bool ted_open_file(Ted *ted, char const *filename) { TextBuffer *buffers = ted->buffers; for (u16 i = 0; i < TED_MAX_BUFFERS; ++i) { if (buffers_used[i]) { - if (buffers[i].filename && streq(path, buffers[i].filename)) { + if (buffers[i].filename && paths_eq(path, buffers[i].filename)) { buffer_reload(&buffers[i]); // make sure buffer is up to date with the file ted_switch_to_buffer(ted, &buffers[i]); return true; diff --git a/ted.cfg b/ted.cfg index 1b2d7fc..0ac455c 100644 --- a/ted.cfg +++ b/ted.cfg @@ -137,7 +137,9 @@ Ctrl+Shift+/ = :split-vertical # unsplit Ctrl+j = :split-join # switch to the other side of a split -Ctrl+tab = :split-swap +Ctrl+tab = :split-switch +# swap sides of a split +Ctrl+Shift+tab = :split-swap Escape = :escape diff --git a/ui.c b/ui.c index 4d825d1..58fd94e 100644 --- a/ui.c +++ b/ui.c @@ -201,10 +201,10 @@ static int qsort_file_entry_cmp(void *search_termv, void const *av, void const * return strcmp_case_insensitive(a->name, b->name); } -static Status file_selector_cd_(Ted const *ted, FileSelector *fs, char const *path, int symlink_depth); +static Status file_selector_cd_(Ted *ted, FileSelector *fs, char const *path, int symlink_depth); // cd to the directory `name`. `name` cannot include any path separators. -static Status file_selector_cd1(Ted const *ted, FileSelector *fs, char const *name, size_t name_len, int symlink_depth) { +static Status file_selector_cd1(Ted *ted, FileSelector *fs, char const *name, size_t name_len, int symlink_depth) { char *const cwd = fs->cwd; if (name_len == 0 || (name_len == 1 && name[0] == '.')) { @@ -274,20 +274,23 @@ static Status file_selector_cd1(Ted const *ted, FileSelector *fs, char const *na } -static Status file_selector_cd_(Ted const *ted, FileSelector *fs, char const *path, int symlink_depth) { +static Status file_selector_cd_(Ted *ted, FileSelector *fs, char const *path, int symlink_depth) { char *const cwd = fs->cwd; if (path[0] == '\0') return true; if (path_is_absolute(path)) { // absolute path (e.g. /foo, c:\foo) // start out by replacing cwd with the start of the absolute path - cwd[0] = '\0'; if (path[0] == PATH_SEPARATOR) { - str_cat(cwd, sizeof fs->cwd, PATH_SEPARATOR_STR); + char new_cwd[TED_PATH_MAX]; + // necessary because the full path of \ on windows isn't just \, it's c:\ or something + ted_full_path(ted, PATH_SEPARATOR_STR, new_cwd, sizeof new_cwd); + strcpy(cwd, new_cwd); path += 1; } #if _WIN32 else { + cwd[0] = '\0'; strn_cat(cwd, sizeof fs->cwd, path, 3); path += 3; } @@ -303,6 +306,7 @@ static Status file_selector_cd_(Ted const *ted, FileSelector *fs, char const *pa p += len; p += strspn(p, PATH_SEPARATOR_STR); } + return true; } @@ -312,7 +316,6 @@ static Status file_selector_cd_(Ted const *ted, FileSelector *fs, char const *pa static bool file_selector_cd(Ted *ted, FileSelector *fs, char const *path) { fs->sel.cursor = 0; fs->sel.scroll = 0; - buffer_clear(&ted->line_buffer); return file_selector_cd_(ted, fs, path, 0); } @@ -354,8 +357,9 @@ static char *file_selector_update(Ted *ted, FileSelector *fs) { if (file_selector_cd(ted, fs, dir_name)) { buffer_delete_chars_at_pos(line_buffer, buffer_start_of_file(line_buffer), last_path_sep + 1); // delete up to and including the last path separator - buffer_clear_undo_redo(line_buffer); + buffer_clear_undo_redo(line_buffer); } else { + // delete up to first path separator in line buffer BufferPos pos = {.line = 0, .index = first_path_sep}; size_t nchars = search_term32.len - first_path_sep; buffer_delete_chars_at_pos(line_buffer, pos, (i64)nchars); @@ -386,6 +390,7 @@ static char *file_selector_update(Ted *ted, FileSelector *fs) { case FS_DIRECTORY: // cd there file_selector_cd(ted, fs, option_chosen); + buffer_clear(line_buffer); break; } } diff --git a/util.c b/util.c index 7d0064d..a0e6651 100644 --- a/util.c +++ b/util.c @@ -257,15 +257,23 @@ static char const *path_filename(char const *path) { static bool path_is_absolute(char const *path) { return path[0] == PATH_SEPARATOR #if _WIN32 - || path[1] == ':' && path[2] == PATH_SEPARATOR + || path[1] == ':' #endif ; } // assuming `dir` is an absolute path, returns the absolute path of `relpath`, relative to `dir`. static void path_full(char const *dir, char const *relpath, char *abspath, size_t abspath_size) { + assert(abspath_size); if (path_is_absolute(relpath)) { - str_cpy(abspath, abspath_size, relpath); + if (strchr(ALL_PATH_SEPARATORS, relpath[0])) { + // make sure that on windows, if dir's drive is C: the absolute path of \a is c:\a + abspath[0] = '\0'; + strn_cat(abspath, abspath_size, dir, strcspn(dir, ALL_PATH_SEPARATORS)); + str_cat(abspath, abspath_size, relpath); + } else { + str_cpy(abspath, abspath_size, relpath); + } return; } str_cpy(abspath, abspath_size, dir); @@ -296,6 +304,17 @@ static void path_full(char const *dir, char const *relpath, char *abspath, size_ } } +// returns true if the paths are the same. +// handles the fact that paths are case insensitive on windows. +// treats links as different from the files they point to. +static bool paths_eq(char const *path1, char const *path2) { +#if _WIN32 + return _stricmp(path1, path2) == 0; +#else + return streq(path1, path2); +#endif +} + static void change_directory(char const *path) { #if _WIN32 _chdir(path); diff --git a/windows_installer/ted/ted/ted.vdproj b/windows_installer/ted/ted/ted.vdproj index 2a27cf6..b52b18c 100644 --- a/windows_installer/ted/ted/ted.vdproj +++ b/windows_installer/ted/ted/ted.vdproj @@ -505,15 +505,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:ted" - "ProductCode" = "8:{B825B9D0-799C-4DE6-AB13-078CEADBABB0}" - "PackageCode" = "8:{B266C9B0-1928-45AF-8BE1-F2EC7A3F0FC4}" + "ProductCode" = "8:{CD90D1DE-A5D9-4A80-8598-783741445D25}" + "PackageCode" = "8:{E8F328D3-9601-4CDD-86E6-7EC6881B966B}" "UpgradeCode" = "8:{844F6C2B-DF3B-4A81-9BD5-603401BBA651}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:FALSE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:21.03.1457" + "ProductVersion" = "8:21.03.1605" "Manufacturer" = "8:ted" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" -- cgit v1.2.3