I can't take it anymore.

This commit is contained in:
retoor 2025-08-02 23:53:08 +02:00
parent e80e835939
commit cada002cbf
3 changed files with 83 additions and 29 deletions

108
main.c
View File

@ -87,6 +87,36 @@ char *rzf_get_file_extension(const char *filename) {
return (char *)(dot + 1); 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) { bool rzf_matches_file_type_filter(const char *path, const char *filter) {
if (!filter || strlen(filter) < 2 || filter[0] != ':') if (!filter || strlen(filter) < 2 || filter[0] != ':')
return true; return true;
@ -582,9 +612,9 @@ void *rzf_indexing_worker_func(void *arg) {
struct stat statbuf; struct stat statbuf;
if (lstat(path, &statbuf) == 0) { if (lstat(path, &statbuf) == 0) {
int is_dir = S_ISDIR(statbuf.st_mode); int is_dir = S_ISDIR(statbuf.st_mode);
char real[PATH_MAX]; char real[PATH_MAX];
if (realpath(path, real) == NULL) /* canonical, absolute path */ if (realpath(path, real) == NULL)
continue; continue;
local_batch[local_count].path = strdup(path); local_batch[local_count].path = strdup(path);
local_batch[local_count].lower_path = rzf_to_lower(path); local_batch[local_count].lower_path = rzf_to_lower(path);
if (!local_batch[local_count].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); if (dir_path) free(dir_path);
} else { } else {
// Open file // Open file
char abs[PATH_MAX]; char abs[PATH_MAX];
if (realpath(files[file_idx].path, abs)) if (realpath(files[file_idx].path, abs))
*selected_file_path = strdup(abs); /* always absolute */ *selected_file_path = strdup(abs);
else /* fallback (shouldn't)*/ else
*selected_file_path = strdup(files[file_idx].path); *selected_file_path = strdup(files[file_idx].path);
command = strdup("vim"); // 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); pthread_mutex_unlock(&files_mutex);
goto end_loop; goto end_loop;
} }
@ -1032,7 +1067,6 @@ char *rzf_run_interface(char **selected_file_path) {
} }
break; break;
case 27: case 27:
case 3: case 3:
goto end_loop; goto end_loop;
@ -1581,13 +1615,44 @@ int main() {
signal(SIGHUP, rzf_cleanup_terminal); signal(SIGHUP, rzf_cleanup_terminal);
pthread_create(&indexing_thread, NULL, rzf_indexing_thread_func, NULL); pthread_create(&indexing_thread, NULL, rzf_indexing_thread_func, NULL);
char *file_to_open = NULL; char *file_to_open = NULL;
char *command = rzf_run_interface(&file_to_open); 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) { if (indexing_started && !indexing_complete) {
pthread_cancel(indexing_thread); pthread_cancel(indexing_thread);
} }
pthread_join(indexing_thread, NULL); pthread_join(indexing_thread, NULL);
// Clean up queue
pthread_mutex_lock(&queue_mutex); pthread_mutex_lock(&queue_mutex);
for (int i = 0; i < queue_count; i++) { for (int i = 0; i < queue_count; i++) {
int idx = (queue_head + i) % DIR_QUEUE_CAPACITY; int idx = (queue_head + i) % DIR_QUEUE_CAPACITY;
@ -1598,35 +1663,24 @@ int main() {
} }
pthread_mutex_unlock(&queue_mutex); pthread_mutex_unlock(&queue_mutex);
if (command && file_to_open) { // Execute the command if we have one
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); // Clean up memory
} else if (pid > 0) { if (file_to_open)
wait(NULL);
} else {
perror("fork failed");
}
free(file_to_open); free(file_to_open);
}
if (command) if (command)
free(command); free(command);
rzf_free_files(); rzf_free_files();
rzf_free_bookmarks(); rzf_free_bookmarks();
// Destroy mutexes
pthread_mutex_destroy(&files_mutex); pthread_mutex_destroy(&files_mutex);
pthread_mutex_destroy(&queue_mutex); pthread_mutex_destroy(&queue_mutex);
pthread_mutex_destroy(&git_queue_mutex); pthread_mutex_destroy(&git_queue_mutex);
pthread_mutex_destroy(&git_root_mutex); pthread_mutex_destroy(&git_root_mutex);
pthread_mutex_destroy(&preview_mutex); pthread_mutex_destroy(&preview_mutex);
pthread_cond_destroy(&queue_cond); pthread_cond_destroy(&queue_cond);
return 0; return 0;
} }

BIN
main.o

Binary file not shown.

BIN
rzf

Binary file not shown.