diff --git a/bview.c b/bview.c index 46c8df2..825d9d7 100644 --- a/bview.c +++ b/bview.c @@ -45,7 +45,6 @@ bview_t *bview_new(editor_t *editor, int type, char *opt_path, int opt_path_len, self->viewport_scope_x = editor->viewport_scope_x; self->viewport_scope_y = editor->viewport_scope_y; self->id = (id++); - getcwd(self->init_cwd, PATH_MAX + 1); // Open buffer if (opt_buffer) { diff --git a/cmd.c b/cmd.c index 6dc5e28..ed007eb 100644 --- a/cmd.c +++ b/cmd.c @@ -705,13 +705,21 @@ int cmd_browse(cmd_context_t *ctx) { bview_t *menu; aproc_t *aproc; char *cmd; - asprintf(&cmd, "tree --charset C -n -f -L 2 %s 2>/dev/null", ctx->static_param ? ctx->static_param : ""); + char *browse_path; + browse_path = ctx->static_param ? ctx->static_param : "./"; + asprintf(&cmd, "cd %s && tree --charset C -n -f -L 2 2>/dev/null", browse_path); aproc = aproc_new(ctx->editor, ctx->bview, &(ctx->bview->aproc), cmd, 0, _cmd_aproc_bview_passthru_cb); free(cmd); if (!aproc) return MLE_ERR; - editor_menu(ctx->editor, _cmd_menu_browse_cb, "..\n", 3, aproc, &menu); + editor_menu(ctx->editor, _cmd_menu_browse_cb, ".", 1, aproc, &menu); mark_move_beginning(menu->active_cursor->mark); bview_zero_viewport_y(menu); + if (strncmp(browse_path, "./", 2) == 0) { + browse_path += 2; + } else if (strcmp(browse_path, ".") == 0) { + browse_path = ""; + } + snprintf(menu->browse_path, sizeof(menu->browse_path), "%s", browse_path); return MLE_OK; } @@ -1728,51 +1736,62 @@ static int _cmd_menu_ctag_cb(cmd_context_t *ctx) { // Callback from cmd_browse static int _cmd_menu_browse_cb(cmd_context_t *ctx) { char *line; - char *path; - char cwd[PATH_MAX]; - char *corrected_path; - bview_t *new_bview; + char *path, *tmp; + char apath[PATH_MAX + 1]; + bview_t *new_bview, *self_bview; // Get path from tree output line = strndup(ctx->bview->active_cursor->mark->bline->data, ctx->bview->active_cursor->mark->bline->data_len); - if ((path = strstr(line, "- ")) != NULL) { - path += 2; + if ((path = strstr(line, "-- ")) != NULL) { + path += 3; + if (strncmp(path, "./", 2) == 0) { + path += 2; + } + if ((tmp = strstr(path, " -> ")) != NULL) { + *tmp = '\0'; + } } else if (strcmp(line, "..") == 0) { path = ".."; - } else if (util_is_dir(line)) { - path = line; + } else if (strlen(line) < 1) { + free(line); + return MLE_OK; } else { MLE_SET_ERR(ctx->editor, "browse: Cannot browse to: '%s'", line); free(line); return MLE_ERR; } - // Fix cwd if it changed - getcwd(cwd, PATH_MAX); - if (strcmp(cwd, ctx->bview->init_cwd) != 0) { - asprintf(&corrected_path, "%s/%s", ctx->bview->init_cwd, path); + // Derive apath + size_t browse_path_len = strlen(ctx->bview->browse_path); + if (browse_path_len > 0 && *path != '/') { + snprintf(apath, sizeof(apath), + "%s%s%s", + ctx->bview->browse_path, + ctx->bview->browse_path[browse_path_len - 1] != '/' ? "/" : "", + path + ); } else { - corrected_path = strdup(path); + snprintf(apath, sizeof(apath), "%s", path); } // Open file or browse dir + self_bview = ctx->bview; new_bview = NULL; - if (util_is_dir(corrected_path)) { - chdir(corrected_path); + if (util_is_dir(apath)) { ctx->bview = ctx->editor->active_edit; + ctx->static_param = apath; cmd_browse(ctx); } else { - editor_open_bview(ctx->editor, NULL, MLE_BVIEW_TYPE_EDIT, corrected_path, strlen(corrected_path), 0, 0, 0, NULL, &new_bview); + editor_open_bview(ctx->editor, NULL, MLE_BVIEW_TYPE_EDIT, apath, strlen(apath), 0, 0, 0, NULL, &new_bview); } - // Close menu - editor_close_bview(ctx->editor, ctx->bview, NULL); + // Close self + editor_close_bview(ctx->editor, self_bview, NULL); // Set new_bview to active if (new_bview) editor_set_active(ctx->editor, new_bview); free(line); - free(corrected_path); return MLE_OK; } diff --git a/editor.c b/editor.c index 26452ae..e8672c2 100644 --- a/editor.c +++ b/editor.c @@ -358,12 +358,10 @@ int editor_open_bview(editor_t *editor, bview_t *opt_parent, int type, char *opt cmd_context_t ctx; memset(&ctx, 0, sizeof(cmd_context_t)); ctx.editor = editor; - ctx.static_param = strndup(opt_path, opt_path_len); + ctx.static_param = opt_path; ctx.bview = bview; cmd_browse(&ctx); editor_close_bview(editor, bview, NULL); - free(ctx.static_param); - ctx.static_param = NULL; } return MLE_OK; } diff --git a/mle.h b/mle.h index 01f7535..9c212b3 100644 --- a/mle.h +++ b/mle.h @@ -203,7 +203,7 @@ struct bview_s { #ifndef PATH_MAX #define PATH_MAX 4096 #endif - char init_cwd[PATH_MAX + 1]; + char browse_path[PATH_MAX + 1]; int id; bview_listener_t *listeners; bview_t *top_next; diff --git a/tests/func/test_browse.sh b/tests/func/test_browse.sh index 5762cf6..3c74cce 100755 --- a/tests/func/test_browse.sh +++ b/tests/func/test_browse.sh @@ -8,23 +8,19 @@ if ! command -v tree &>/dev/null; then fi # make tmpdir and delete at exit +this_dir=$(pwd) tmpdir=$(mktemp -d) -pushed=0 -finish() { [ $pushed -eq 1 ] && popd &>/dev/null; rm -rf $tmpdir; } +cd $tmpdir +finish() { cd $this_dir; rm -rf $tmpdir; } trap finish EXIT -# make adir/bdir/hello -this_dir=$(pwd) -pushd $tmpdir &>/dev/null -pushed=1 +# setup tmpdir mkdir -p adir/bdir -touch adir/bdir/hello +touch adir/bdir/hi -# ensure that we can browse into adir, then bdir, then select hello -macro='C-b C-f a d i r enter enter C-f b d i r enter enter C-f h e l l o enter enter' +# ensure that we can browse into adir, bdir, then select hi +# ensure path is relative to where we started +macro='C-b C-f a d i r enter enter C-f b d i r enter enter C-f h i enter enter' declare -A expected -expected[hello]='^bview.[[:digit:]]+.buffer.path=./hello$' +expected[hi]='^bview.[[:digit:]]+.buffer.path=adir/bdir/hi$' source "$this_dir/test.sh" - -popd &>/dev/null -pushed=0