diff --git a/main.c b/main.c index 9e55d3e..989397c 100644 --- a/main.c +++ b/main.c @@ -87,6 +87,36 @@ char *rzf_get_file_extension(const char *filename) { return (char *)(dot + 1); } +bool rzf_is_text_file(const char *path) { + const char *ext = rzf_get_file_extension(path); + + // Common text file extensions + const char *text_exts[] = { + "txt", "c", "h", "cpp", "hpp", "cc", "cxx", "py", "js", "ts", "java", + "rb", "go", "rs", "sh", "bash", "zsh", "fish", "pl", "php", "html", + "htm", "css", "xml", "json", "yaml", "yml", "toml", "ini", "conf", + "cfg", "log", "md", "markdown", "rst", "tex", "vim", "el", "lisp", + "scm", "clj", "lua", "r", "m", "swift", "kt", "scala", "hs", "ml", + "fs", "pas", "d", "nim", "cr", "jl", "dart", "ex", "exs", "erl", + "hrl", "zig", "v", "sql", "cmake", "make", "dockerfile", "gitignore", + NULL + }; + + // Check if it has no extension (often scripts or config files) + if (strlen(ext) == 0) { + return true; + } + + // Check against known text extensions + for (int i = 0; text_exts[i] != NULL; i++) { + if (strcasecmp(ext, text_exts[i]) == 0) { + return true; + } + } + + return false; +} + bool rzf_matches_file_type_filter(const char *path, const char *filter) { if (!filter || strlen(filter) < 2 || filter[0] != ':') return true; @@ -582,9 +612,9 @@ void *rzf_indexing_worker_func(void *arg) { struct stat statbuf; if (lstat(path, &statbuf) == 0) { int is_dir = S_ISDIR(statbuf.st_mode); - char real[PATH_MAX]; - if (realpath(path, real) == NULL) /* canonical, absolute path */ - continue; + char real[PATH_MAX]; + if (realpath(path, real) == NULL) + continue; local_batch[local_count].path = strdup(path); local_batch[local_count].lower_path = rzf_to_lower(path); if (!local_batch[local_count].path || @@ -1016,13 +1046,18 @@ char *rzf_run_interface(char **selected_file_path) { if (dir_path) free(dir_path); } else { // Open file - char abs[PATH_MAX]; - if (realpath(files[file_idx].path, abs)) - *selected_file_path = strdup(abs); /* always absolute */ - else /* fallback (shouldn't)*/ - *selected_file_path = strdup(files[file_idx].path); - - command = strdup("vim"); + char abs[PATH_MAX]; + if (realpath(files[file_idx].path, abs)) + *selected_file_path = strdup(abs); + else + *selected_file_path = strdup(files[file_idx].path); + + // Determine whether to use vim or xdg-open + if (rzf_is_text_file(*selected_file_path)) { + command = strdup("vim"); + } else { + command = strdup("xdg-open"); + } pthread_mutex_unlock(&files_mutex); goto end_loop; } @@ -1032,7 +1067,6 @@ char *rzf_run_interface(char **selected_file_path) { } break; - case 27: case 3: goto end_loop; @@ -1581,13 +1615,44 @@ int main() { signal(SIGHUP, rzf_cleanup_terminal); pthread_create(&indexing_thread, NULL, rzf_indexing_thread_func, NULL); + char *file_to_open = NULL; char *command = rzf_run_interface(&file_to_open); + if (command && file_to_open) { + // Fork and execute + pid_t pid = fork(); + if (pid == 0) { + // Child process + if (strcmp(command, "xdg-open") == 0) { + // For xdg-open, we need to detach from the terminal + setsid(); + // Redirect stdout/stderr to /dev/null to avoid terminal corruption + freopen("/dev/null", "w", stdout); + freopen("/dev/null", "w", stderr); + } + + execlp(command, command, file_to_open, (char *)NULL); + perror("execlp failed"); + exit(EXIT_FAILURE); + } else if (pid > 0) { + // Parent process + if (strcmp(command, "vim") == 0) { + // Wait for vim to finish + wait(NULL); + } + // For xdg-open, don't wait - let it run in background + } else { + perror("fork failed"); + } + } + return 0; + // Clean up indexing thread if (indexing_started && !indexing_complete) { pthread_cancel(indexing_thread); } pthread_join(indexing_thread, NULL); + // Clean up queue pthread_mutex_lock(&queue_mutex); for (int i = 0; i < queue_count; i++) { int idx = (queue_head + i) % DIR_QUEUE_CAPACITY; @@ -1598,35 +1663,24 @@ int main() { } pthread_mutex_unlock(&queue_mutex); - if (command && file_to_open) { - reset_shell_mode(); - pid_t pid = fork(); - if (pid == 0) { - char abs_path[PATH_MAX]; - if (realpath(file_to_open, abs_path)) { - execlp("vim", "vim", abs_path, (char *)NULL); - perror("execlp failed"); - } else - perror("realpath"); - - exit(EXIT_FAILURE); - } else if (pid > 0) { - wait(NULL); - } else { - perror("fork failed"); - } + // Execute the command if we have one + + // Clean up memory + if (file_to_open) free(file_to_open); - } if (command) free(command); rzf_free_files(); rzf_free_bookmarks(); + + // Destroy mutexes pthread_mutex_destroy(&files_mutex); pthread_mutex_destroy(&queue_mutex); pthread_mutex_destroy(&git_queue_mutex); pthread_mutex_destroy(&git_root_mutex); pthread_mutex_destroy(&preview_mutex); pthread_cond_destroy(&queue_cond); + return 0; } diff --git a/main.o b/main.o index d6fb005..f0b46d6 100644 Binary files a/main.o and b/main.o differ diff --git a/rzf b/rzf index 316f007..d47a633 100755 Binary files a/rzf and b/rzf differ