summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/bindings.c1
-rw-r--r--src/main/cmds.c81
2 files changed, 64 insertions, 18 deletions
diff --git a/src/main/bindings.c b/src/main/bindings.c
index 32dcbdb..ad63974 100644
--- a/src/main/bindings.c
+++ b/src/main/bindings.c
@@ -98,6 +98,7 @@ void init_bindings() {
BINDING(Ctrl, 'C', "exit"),
BINDING(Ctrl, 'S', "buffer-write-to-file"),
BINDING(Ctrl, 'F', "find-file"),
+ BINDING(Ctrl, 'G', "find-file-relative"),
BINDING(Ctrl, 'W', "write-file"),
BINDING(None, 'b', "switch-buffer"),
BINDING(Ctrl, 'B', "buffer-list"),
diff --git a/src/main/cmds.c b/src/main/cmds.c
index bf465ed..506054b 100644
--- a/src/main/cmds.c
+++ b/src/main/cmds.c
@@ -1,4 +1,5 @@
#include <errno.h>
+#include <libgen.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -226,20 +227,8 @@ int32_t buffer_list(struct command_ctx ctx, int argc, const char *argv[]) {
static void find_file_comp_inserted() { minibuffer_execute(); }
-int32_t find_file(struct command_ctx ctx, int argc, const char *argv[]) {
- const char *pth = NULL;
- if (argc == 0) {
- struct completion_provider providers[] = {path_provider()};
- enable_completion(minibuffer_buffer(),
- ((struct completion_trigger){
- .kind = CompletionTrigger_Input, .nchars = 0}),
- providers, 1, find_file_comp_inserted);
- return minibuffer_prompt(ctx, "find file: ");
- }
-
- disable_completion(minibuffer_buffer());
-
- pth = argv[0];
+static int32_t open_file(struct buffers *buffers, struct window *active_window,
+ const char *pth) {
struct stat sb = {0};
if (stat(pth, &sb) < 0 && errno != ENOENT) {
minibuffer_echo("stat on %s failed: %s", pth, strerror(errno));
@@ -252,19 +241,74 @@ int32_t find_file(struct command_ctx ctx, int argc, const char *argv[]) {
}
const char *filename = to_abspath(pth);
- struct buffer *b = buffers_find_by_filename(ctx.buffers, filename);
+ struct buffer *b = buffers_find_by_filename(buffers, filename);
free((char *)filename);
if (b == NULL) {
- b = buffers_add(ctx.buffers, buffer_from_file((char *)pth));
+ b = buffers_add(buffers, buffer_from_file((char *)pth));
} else {
buffer_reload(b);
}
- window_set_buffer(ctx.active_window, b);
+ window_set_buffer(active_window, b);
minibuffer_echo_timeout(4, "buffer \"%s\" loaded",
- window_buffer(ctx.active_window)->name);
+ window_buffer(active_window)->name);
+
+ return 0;
+}
+
+int32_t find_file(struct command_ctx ctx, int argc, const char *argv[]) {
+ const char *pth = NULL;
+ if (argc == 0) {
+ struct completion_provider providers[] = {path_provider()};
+ enable_completion(minibuffer_buffer(),
+ ((struct completion_trigger){
+ .kind = CompletionTrigger_Input, .nchars = 0}),
+ providers, 1, find_file_comp_inserted);
+ return minibuffer_prompt(ctx, "find file: ");
+ }
+
+ disable_completion(minibuffer_buffer());
+
+ open_file(ctx.buffers, ctx.active_window, argv[0]);
+ return 0;
+}
+
+COMMAND_FN("find-file-internal", find_file, find_file, NULL);
+int32_t find_file_relative(struct command_ctx ctx, int argc,
+ const char *argv[]) {
+ struct buffer *b = window_buffer(ctx.active_window);
+ if (b->filename == NULL) {
+ minibuffer_echo_timeout(4, "buffer %s is not backed by a file", b->name);
+ return 1;
+ }
+
+ char *filename = strdup(b->filename);
+ char *dir = dirname(filename);
+ if (argc == 0) {
+ struct completion_provider providers[] = {path_provider()};
+ enable_completion(minibuffer_buffer(),
+ ((struct completion_trigger){
+ .kind = CompletionTrigger_Input, .nchars = 0}),
+ providers, 1, find_file_comp_inserted);
+
+ ctx.self = &find_file_command;
+ minibuffer_prompt_initial(ctx, dir, "find file: ");
+ free(filename);
+ return 0;
+ }
+ disable_completion(minibuffer_buffer());
+ size_t dirlen = strlen(dir);
+ size_t plen = strlen(argv[0]);
+ char *pth = (char *)malloc(dirlen + plen + 2);
+ memcpy(pth, dir, dirlen);
+ pth[dirlen] = '/';
+ memcpy(pth + dirlen + 1, argv[0], plen);
+ pth[dirlen + plen + 1] = '\0';
+ open_file(ctx.buffers, ctx.active_window, pth);
+
+ free(filename);
return 0;
}
@@ -272,6 +316,7 @@ void register_global_commands(struct commands *commands,
void (*terminate_cb)()) {
struct command global_commands[] = {
{.name = "find-file", .fn = find_file},
+ {.name = "find-file-relative", .fn = find_file_relative},
{.name = "write-file", .fn = write_file},
{.name = "run-command-interactive", .fn = run_interactive},
{.name = "switch-buffer", .fn = switch_buffer},