/* Goes one directory up from current location. Returns zero unless it won't * make sense to continue going up (like on error or reaching root). */ static int cd_to_parent_dir(FileView *view) { char dir_name[strlen(view->curr_dir) + 1]; int ret; /* Return to original directory from custom view. */ if(flist_custom_active(view)) { navigate_to(view, view->custom.orig_dir); return 0; } /* Do nothing in root. */ if(is_root_dir(view->curr_dir)) { return 1; } dir_name[0] = '\0'; extract_last_path_component(view->curr_dir, dir_name); ret = change_directory(view, "../"); if(ret == -1) { return 1; } if(ret == 0) { load_dir_list(view, 0); flist_set_pos(view, find_file_pos_in_list(view, dir_name)); } return 0; }
void flist_set_pos(FileView *view, int pos) { if(pos < 1) { pos = 0; } if(pos > view->list_rows - 1) { pos = view->list_rows - 1; } if(pos != -1) { FileView *const other = (view == curr_view) ? other_view : curr_view; view->list_pos = pos; fview_position_updated(view); /* Synchronize cursor with the other pane. */ if(view->custom.type == CV_DIFF && other->list_pos != pos) { flist_set_pos(other, pos); } } }
/* Resolve link target and either navigate inside directory link points to or * navigate to directory where target is located pointing cursor on * it (the follow_dirs flag controls behaviour). */ static void follow_link(FileView *view, int follow_dirs) { char *dir, *file; char full_path[PATH_MAX]; char linkto[PATH_MAX + NAME_MAX]; dir_entry_t *const entry = &curr_view->dir_entry[curr_view->list_pos]; get_full_path_of(entry, sizeof(full_path), full_path); if(get_link_target_abs(full_path, entry->origin, linkto, sizeof(linkto)) != 0) { show_error_msg("Error", "Can't read link."); return; } if(!path_exists(linkto, DEREF)) { show_error_msg("Broken Link", "Can't access link destination. It might be broken."); return; } chosp(linkto); if(is_dir(linkto) && !follow_dirs) { dir = strdup(entry->name); file = NULL; } else { dir = strdup(linkto); remove_last_path_component(dir); file = get_last_path_component(linkto); } if(dir[0] != '\0') { navigate_to(view, dir); } if(file != NULL) { const int pos = find_file_pos_in_list(view, file); if(pos >= 0) { flist_set_pos(view, pos); } } free(dir); }
static void updir_from_mount(FileView *view, fuse_mount_t *runner) { char *file; int pos; if(change_directory(view, runner->source_file_dir) < 0) return; load_dir_list(view, 0); file = runner->source_file_name; file += strlen(runner->source_file_dir) + 1; pos = find_file_pos_in_list(view, file); flist_set_pos(view, pos); }
int ensure_file_is_selected(FileView *view, const char name[]) { int file_pos; char nm[NAME_MAX]; /* Don't reset filters to find "file with empty name". */ if(name[0] == '\0') { return 0; } /* This is for compatibility with paths loaded from vifminfo that have * trailing slash. */ copy_str(nm, sizeof(nm), name); chosp(nm); file_pos = find_file_pos_in_list(view, nm); if(file_pos < 0 && file_can_be_displayed(view->curr_dir, nm)) { if(nm[0] == '.') { set_dot_files_visible(view, 1); file_pos = find_file_pos_in_list(view, nm); } if(file_pos < 0) { remove_filename_filter(view); /* remove_filename_filter() postpones list of files reloading. */ populate_dir_list(view, 1); file_pos = find_file_pos_in_list(view, nm); } } flist_set_pos(view, (file_pos < 0) ? 0 : file_pos); return file_pos >= 0; }