示例#1
0
文件: bookmarks.c 项目: lyuts/vifm
/* Navigates the view to given mark if it's valid.  Returns new value for
 * save_msg flag. */
static int
navigate_to_bookmark(FileView *view, char mark)
{
	const bookmark_t *const bmark = get_bookmark(mark);

	if(is_bmark_valid(bmark))
	{
		if(change_directory(view, bmark->directory) >= 0)
		{
			load_dir_list(view, 1);
			(void)ensure_file_is_selected(view, bmark->file);
		}
	}
	else
	{
		if(!char_is_one_of(valid_bookmarks, mark))
			status_bar_message("Invalid mark name");
		else if(is_bmark_empty(bmark))
			status_bar_message("Mark is not set");
		else
			status_bar_message("Mark is invalid");

		move_to_list_pos(view, view->list_pos);
		return 1;
	}
	return 0;
}
示例#2
0
/* Navigates the view to given mark if it's valid.  Returns new value for
 * save_msg flag. */
static int
navigate_to_mark(FileView *view, char m)
{
	const mark_t *const mark = get_mark_by_name(m);

	if(is_mark_valid(mark))
	{
		navigate_to_file(view, mark->directory, mark->file);
		return 0;
	}

	if(!char_is_one_of(valid_marks, m))
	{
		status_bar_message("Invalid mark name");
	}
	else if(is_empty(mark))
	{
		status_bar_message("Mark is not set");
	}
	else
	{
		status_bar_message("Mark is invalid");
	}

	fview_cursor_redraw(view);
	return 1;
}
示例#3
0
文件: main_menu.c 项目: xaizek/vide
static void
goto_bookmark (GtkWidget * menu_item, gchar *value)
{
	GList *tmp;
	gint i;
	gchar *file;

	for(tmp = cfg.bookmarks; tmp != NULL; tmp = tmp->next)
	{
		Bookmarks *bk = tmp->data;
		if(!strcmp(value, bk->mark))
		{
			change_dir(curr_view, bk->dir);
			gtk_clist_freeze(GTK_CLIST(curr_view->clist));
			for(i = 0; i < GTK_CLIST(curr_view->clist)->rows; i++)
			{
				gtk_clist_get_text(GTK_CLIST(curr_view->clist), i, 0, &file);

				if(!strcmp(bk->file, file))
				{
					focus_on_row(curr_view, i);
					gtk_clist_thaw(GTK_CLIST(curr_view->clist));
					return;
				}
			}
			focus_on_row(curr_view, 0);
			gtk_clist_thaw(GTK_CLIST(curr_view->clist));
			return;
		}
	}
	status_bar_message("Mark not found");
	return;
}
示例#4
0
/* Ensures that terminal is in proper state for a loop iteration.  Returns
 * non-zero if so, otherwise zero is returned. */
static int
ensure_term_is_ready(void)
{
	ui_update_term_state();

	update_terminal_settings();

	if(curr_stats.term_state == TS_TOO_SMALL)
	{
		ui_display_too_small_term_msg();
		wait_for_signal();
		return 0;
	}

	if(curr_stats.term_state == TS_BACK_TO_NORMAL)
	{
		wint_t c;

		wtimeout(status_bar, 0);
		while(compat_wget_wch(status_bar, &c) != ERR);
		curr_stats.term_state = TS_NORMAL;
		modes_redraw();
		wtimeout(status_bar, cfg.timeout_len);

		curr_stats.save_msg = 0;
		status_bar_message("");
	}

	return 1;
}
示例#5
0
文件: view.c 项目: lyuts/vifm
void
view_pre(void)
{
	if(curr_stats.save_msg == 0)
	{
		status_bar_message("-- VIEW -- ");
		curr_stats.save_msg = 2;
	}
}
示例#6
0
文件: menu.c 项目: cfillion/vifm
void
menu_post(void)
{
	if(curr_stats.need_update != UT_NONE)
	{
		menu_redraw();
		curr_stats.need_update = UT_NONE;
	}
	status_bar_message(curr_stats.save_msg ? NULL : "");
}
示例#7
0
文件: bookmarks.c 项目: lyuts/vifm
int
set_user_bookmark(const char mark, const char directory[], const char file[])
{
	if(!is_user_bookmark(mark))
	{
		status_bar_message("Invalid mark name");
		return 1;
	}

	set_mark(mark, directory, file, time(NULL), 0);
	return 0;
}
示例#8
0
文件: search.c 项目: ksteen/vifm-w32
int
find_pattern(FileView *view, char *pattern)
{
	int found = 0;
	regex_t re;
	int x;
	int first_match = 0;
	int first_match_pos = 0;

	view->selected_files = 0;

	for(x = 0; x < view->list_rows; x++)
	{
		if(regcomp(&re, pattern, REG_EXTENDED) == 0)
		{
			if(regexec(&re, view->dir_entry[x].name, 0, NULL, 0) == 0)
			{
				if(!first_match)
				{
					first_match++;
					first_match_pos = x;
				}
				view->dir_entry[x].selected = 1;
				view->selected_files++;
				found++;
			}
			else
				view->dir_entry[x].selected = 0;
		}
		regfree(&re);
	}


	/* Need to redraw the list so that the matching files are highlighted */
	draw_dir_list(view, view->top_line, view->curr_line);

	if(found)
	{
		draw_dir_list(view, view->top_line, view->curr_line);
		moveto_list_pos(view, first_match_pos);
		return 0;
	}
	else
	{
		char buf[48];
		moveto_list_pos(view, view->list_pos);
		snprintf(buf, sizeof(buf), "No matching files for %s", view->regexp);
		status_bar_message(buf);
		return 1;
	}
}
示例#9
0
文件: callbacks.c 项目: xaizek/vide
void
toggle_tag_cb ()
{
  FileInfo *info = gtk_clist_get_row_data (GTK_CLIST (curr_view->clist),
					   curr_view->row);
  gint row = curr_view->row;

  if (g_list_find (curr_view->tagged, info) != NULL)
    {
      curr_view->tagged = g_list_remove (curr_view->tagged, info);
      gtk_clist_set_background (GTK_CLIST (curr_view->clist), row,
				&CLIST_COLOR);
			status_bar_message("File removed from tag list");
    }
  else
    {
      curr_view->tagged = g_list_append (curr_view->tagged, info);
			gtk_clist_unselect_all(GTK_CLIST(curr_view->clist));
      gtk_clist_set_background (GTK_CLIST (curr_view->clist), row,
				&TAG_COLOR);
			status_bar_message("File is tagged");
    }
}
示例#10
0
int
unstash_menu(FileView *view)
{
	static menu_data_t menu_data_storage;

	if(!menu_data_stash.initialized)
	{
		status_bar_message("No saved menu to display");
		return 1;
	}

	reset_menu_data(&menu_data_storage);
	menu_data_storage = menu_data_stash;
	menu_data_stash.initialized = 0;
	menu_state.d = &menu_data_storage;

	return display_menu(menu_data_storage.state, view);
}
示例#11
0
int
display_menu(menu_state_t *m, FileView *view)
{
	if(m->d->len < 1)
	{
		status_bar_message(m->d->empty_msg);
		reset_menu_data(m->d);
		return 1;
	}

	init_menu_state(m, view);

	setup_menu();
	draw_menu(m);
	move_to_menu_pos(m->d->pos, m);
	enter_menu_mode(m->d, view);
	return 0;
}
示例#12
0
文件: menus.c 项目: lyuts/vifm
int
display_menu(menu_info *m, FileView *view)
{
	if(m->len < 1)
	{
		status_bar_message(m->empty_msg);
		reset_popup_menu(m);
		return 1;
	}
	else
	{
		setup_menu();
		draw_menu(m);
		move_to_menu_pos(m->pos, m);
		enter_menu_mode(m, view);
		return 0;
	}
}
示例#13
0
文件: menus.c 项目: lyuts/vifm
/* Navigates the view to a given dir/file combination specified by the path. */
static void
navigate_to_selected_file(FileView *view, const char path[])
{
	/* Check whether target path is directory while we don't change current
	 * working directory by invoking change_directory() function below. */
	const int dst_is_dir = is_dir(path);

	char name[NAME_MAX];
	char *dir = strdup(path);
	char *const last_slash = find_slashr(dir);

	if(last_slash == NULL)
	{
		copy_str(name, sizeof(name), dir);
	}
	else
	{
		*last_slash = '\0';
		copy_str(name, sizeof(name), last_slash + 1);
	}

	if(change_directory(view, dir) >= 0)
	{
		status_bar_message("Finding the correct directory...");
		wrefresh(status_bar);

		load_dir_list(view, 0);

		if(dst_is_dir)
		{
			strcat(name, "/");
		}
		(void)ensure_file_is_selected(view, name);
	}
	else
	{
		show_error_msgf("Invalid path", "Cannot change dir to \"%s\"", dir);
	}

	free(dir);
}
示例#14
0
文件: search.c 项目: lowtalker/vifm
void
print_search_fail_msg(const FileView *view, int backward)
{
    const char *const regexp = cfg_get_last_search_pattern();

    int cflags;
    regex_t re;
    int err;

    if(regexp[0] == '\0')
    {
        status_bar_message("");
        return;
    }

    cflags = get_regexp_cflags(regexp);
    err = regcomp(&re, regexp, cflags);

    if(err != 0)
    {
        status_bar_errorf("Regexp (%s) error: %s", regexp,
                          get_regexp_error(err, &re));
        regfree(&re);
        return;
    }

    regfree(&re);

    if(cfg.wrap_scan)
    {
        status_bar_errorf("No matching files for: %s", regexp);
    }
    else if(backward)
    {
        status_bar_errorf("Search hit TOP without match for: %s", regexp);
    }
    else
    {
        status_bar_errorf("Search hit BOTTOM without match for: %s", regexp);
    }
}
示例#15
0
文件: running.c 项目: cfillion/vifm
/* Executes the cmd and displays its output on the status bar. */
static void
output_to_statusbar(const char cmd[])
{
	FILE *file, *err;
	char buf[2048];
	char *lines;
	size_t len;
	int error;

	setup_shellout_env();
	error = (background_and_capture((char *)cmd, 1, &file, &err) == (pid_t)-1);
	cleanup_shellout_env();
	if(error)
	{
		show_error_msgf("Trouble running command", "Unable to run: %s", cmd);
		return;
	}

	lines = NULL;
	len = 0;
	while(fgets(buf, sizeof(buf), file) == buf)
	{
		char *p;

		chomp(buf);
		p = realloc(lines, len + 1 + strlen(buf) + 1);
		if(p != NULL)
		{
			lines = p;
			len += sprintf(lines + len, "%s%s", (len == 0) ? "": "\n", buf);
		}
	}

	fclose(file);
	fclose(err);

	status_bar_message((lines == NULL) ? "" : lines);
	free(lines);
}
示例#16
0
void
modes_post(void)
{
	if(ANY(vle_mode_is, CMDLINE_MODE, SORT_MODE, CHANGE_MODE, ATTR_MODE))
	{
		return;
	}
	else if(vle_mode_is(VIEW_MODE))
	{
		view_post();
		return;
	}
	else if(is_in_menu_like_mode())
	{
		menu_post();
		return;
	}

	update_screen(curr_stats.need_update);

	if(curr_stats.save_msg)
	{
		status_bar_message(NULL);
	}

	if(!vle_mode_is(FILE_INFO_MODE) && curr_view->list_rows > 0)
	{
		if(!is_status_bar_multiline())
		{
			update_stat_window(curr_view);
			ui_ruler_update(curr_view);
		}
	}

	modes_statusbar_update();
}
示例#17
0
void
modes_redraw(void)
{
	LOG_FUNC_ENTER;

	static int in_here;

	if(curr_stats.load_stage < 2)
	{
		return;
	}

	if(in_here++ > 0)
	{
		/* TODO: is this still needed?  Update scheduling might have solved issues
		 * caused by asynchronous execution of this function in the past. */
		return;
	}

	if(curr_stats.term_state != TS_NORMAL)
	{
		update_screen(UT_REDRAW);
		goto finish;
	}

	if(vle_mode_is(CMDLINE_MODE))
	{
		redraw_cmdline();
		goto finish;
	}
	else if(vle_primary_mode_is(MENU_MODE))
	{
		menu_redraw();
		if(vle_mode_is(MSG_MODE))
		{
			redraw_msg_dialog(0);
		}
		goto finish;
	}
	else if(vle_mode_is(FILE_INFO_MODE))
	{
		redraw_file_info_dialog();
		goto finish;
	}

	update_screen(UT_REDRAW);

	if(curr_stats.save_msg)
	{
		status_bar_message(NULL);
	}

	if(vle_mode_is(SORT_MODE))
	{
		redraw_sort_dialog();
	}
	else if(vle_mode_is(CHANGE_MODE))
	{
		redraw_change_dialog();
	}
	else if(vle_mode_is(ATTR_MODE))
	{
		redraw_attr_dialog();
	}
	else if(vle_mode_is(VIEW_MODE))
	{
		view_redraw();
	}
	else if(vle_mode_is(MSG_MODE))
	{
		redraw_msg_dialog(0);
	}

finish:
	if(--in_here > 0)
	{
		modes_redraw();
	}
}
示例#18
0
文件: fuse.c 项目: jubalh/vifm
int
fuse_try_unmount(FileView *view)
{
	char buf[14 + PATH_MAX + 1];
	fuse_mount_t *runner, *trailer;
	int status;
	fuse_mount_t *sniffer;
	char *escaped_mount_point;

	runner = fuse_mounts;
	trailer = NULL;
	while(runner)
	{
		if(paths_are_equal(runner->mount_point, view->curr_dir))
		{
			break;
		}

		trailer = runner;
		runner = runner->next;
	}

	if(runner == NULL)
	{
		return 0;
	}

	/* we are exiting a top level dir */
	escaped_mount_point = escape_filename(runner->mount_point, 0);
	snprintf(buf, sizeof(buf), "%s %s 2> /dev/null", curr_stats.fuse_umount_cmd,
			escaped_mount_point);
	LOG_INFO_MSG("FUSE unmount command: `%s`", buf);
	free(escaped_mount_point);

	/* Have to chdir to parent temporarily, so that this DIR can be unmounted. */
	if(vifm_chdir(cfg.fuse_home) != 0)
	{
		show_error_msg("FUSE UMOUNT ERROR", "Can't chdir to FUSE home");
		return -1;
	}

	status_bar_message("FUSE unmounting selected file, please stand by..");
	status = background_and_wait_for_status(buf, 0, NULL);
	clean_status_bar();
	/* check child status */
	if(!WIFEXITED(status) || WEXITSTATUS(status))
	{
		werase(status_bar);
		show_error_msgf("FUSE UMOUNT ERROR", "Can't unmount %s.  It may be busy.",
				runner->source_file_name);
		(void)vifm_chdir(flist_get_dir(view));
		return -1;
	}

	/* remove the directory we created for the mount */
	if(path_exists(runner->mount_point, DEREF))
		rmdir(runner->mount_point);

	/* remove mount point from fuse_mount_t */
	sniffer = runner->next;
	if(trailer)
		trailer->next = sniffer ? sniffer : NULL;
	else
		fuse_mounts = sniffer;

	updir_from_mount(view, runner);
	free(runner);
	return 1;
}
示例#19
0
文件: ui.c 项目: kotobot/vifm
void
redraw_window(void)
{
    int screen_x, screen_y;
    int x, y;
    struct winsize ws;

    curr_stats.freeze = 1;

    ioctl(0, TIOCGWINSZ, &ws);

    // changed for pdcurses
    resize_term(ws.ws_row, ws.ws_col);

    getmaxyx(stdscr, screen_y, screen_x);

    if (screen_y < 10)
        finish("Terminal is too small to run vifm\n");
    if (screen_x < 30)
        finish("Terminal is too small to run vifm\n");

    wclear(stdscr);
    wclear(lwin.title);
    wclear(lwin.win);
    wclear(rwin.title);
    wclear(rwin.win);
    wclear(stat_win);
    wclear(status_bar);
    wclear(pos_win);
    wclear(num_win);
    wclear(rborder);
    wclear(mborder);
    wclear(lborder);

    wclear(change_win);
    wclear(sort_win);

    wresize(stdscr, screen_y, screen_x);
    mvwin(sort_win, (screen_y - 14)/2, (screen_x -30)/2);
    mvwin(change_win, (screen_y - 10)/2, (screen_x -30)/2);
    wresize(menu_win, screen_y - 1, screen_x);
    wresize(error_win, (screen_y -10)/2, screen_x -2);
    mvwin(error_win, (screen_y -10)/2, 1);
    wresize(lborder, screen_y -2, 1);

    if (curr_stats.number_of_windows == 1)
    {
        wresize(lwin.title, 1, screen_x -1);
        wresize(lwin.win, screen_y -3, screen_x -2);
        getmaxyx(lwin.win, y, x);
        lwin.window_width = x -1;
        lwin.window_rows = y -1;

        wresize(rwin.title, 1, screen_x -1);
        mvwin(rwin.title, 0, 1);
        wresize(rwin.win, screen_y -3, screen_x -2);
        mvwin(rwin.win, 1, 1);
        getmaxyx(rwin.win, y, x);
        rwin.window_width = x -1;
        rwin.window_rows = y -1;
    }
    else
    {
        wresize(lwin.title, 1, screen_x/2 -2);
        wresize(lwin.win, screen_y -3, screen_x/2 -2);
        getmaxyx(lwin.win, y, x);
        lwin.window_width = x -1;
        lwin.window_rows = y -1;

        mvwin(mborder, 0, screen_x/2 -1);
        wresize(mborder, screen_y, 2);

        wresize(rwin.title, 1, screen_x/2 -2);
        mvwin(rwin.title, 0, screen_x/2 +1);

        wresize(rwin.win, screen_y -3, screen_x/2 -2);
        mvwin(rwin.win, 1, screen_x/2 +1);
        getmaxyx(rwin.win, y, x);
        rwin.window_width = x -1;
        rwin.window_rows = y -1;
    }



    /* For FreeBSD */
    keypad(lwin.win, TRUE);
    keypad(rwin.win, TRUE);

    if (screen_x % 2)
    {
        wresize(rborder, screen_y -2, 2);
        mvwin(rborder, 0, screen_x -2);
    }
    else
    {
        wresize(rborder, screen_y -2, 1);
        mvwin(rborder, 0, screen_x -1);
    }

    wresize(stat_win, 1, screen_x);
    mvwin(stat_win, screen_y -2, 0);
    wresize(status_bar, 1, screen_x -19);

    /* For FreeBSD */
    keypad(status_bar, TRUE);

    mvwin(status_bar, screen_y -1, 0);
    wresize(pos_win, 1, 13);
    mvwin(pos_win, screen_y -1, screen_x -13);

    wresize(num_win, 1, 6);
    mvwin(num_win, screen_y -1, screen_x -19);

    curs_set(0);

    change_directory(&rwin, rwin.curr_dir);
    load_dir_list(&rwin, 0);
    change_directory(&lwin, lwin.curr_dir);
    load_dir_list(&lwin, 0);

    if(curr_stats.view)
    {
        wclear(other_view->win);

        change_directory(curr_view, curr_view->curr_dir);
        load_dir_list(curr_view, 0);

        quick_view_file(curr_view);
    }
    else
        change_directory(curr_view, curr_view->curr_dir);

    update_stat_window(curr_view);

    if (curr_view->selected_files)
    {
        char status_buf[24];
        snprintf(status_buf, sizeof(status_buf), "%d %s Selected",
                 curr_view->selected_files,
                 curr_view->selected_files == 1 ? "File" : "Files");
        status_bar_message(status_buf);
    }
    else
        status_bar_message(" ");


    update_pos_window(curr_view);

    update_all_windows();

    moveto_list_pos(curr_view, curr_view->list_pos);
    wrefresh(curr_view->win);

    curr_stats.freeze = 0;
    curr_stats.need_redraw = 0;


}
示例#20
0
文件: fuse.c 项目: jubalh/vifm
/* mount_point should be an array of at least PATH_MAX characters
 * Returns non-zero on error. */
static int
fuse_mount(FileView *view, char file_full_path[], const char param[],
		const char program[], char mount_point[])
{
	/* TODO: refactor this function fuse_mount(). */

	int mount_point_id;
	char buf[2*PATH_MAX];
	char *escaped_filename;
	int foreground;
	char errors_file[PATH_MAX];
	int status;
	int cancelled;

	escaped_filename = escape_filename(get_current_file_name(view), 0);

	mount_point_id = get_last_mount_point_id(fuse_mounts);
	do
	{
		snprintf(mount_point, PATH_MAX, "%s/%03d_%s", cfg.fuse_home,
				++mount_point_id, get_current_file_name(view));
	}
	while(path_exists(mount_point, DEREF));
	if(os_mkdir(mount_point, S_IRWXU) != 0)
	{
		free(escaped_filename);
		show_error_msg("Unable to create FUSE mount directory", mount_point);
		return -1;
	}
	free(escaped_filename);

	/* Just before running the mount,
		 I need to chdir out temporarily from any FUSE mounted
		 paths, Otherwise the fuse-zip command fails with
		 "fusermount: failed to open current directory: permission denied"
		 (this happens when mounting JARs from mounted JARs) */
	if(vifm_chdir(cfg.fuse_home) != 0)
	{
		show_error_msg("FUSE MOUNT ERROR", "Can't chdir() to FUSE home");
		return -1;
	}

	format_mount_command(mount_point, file_full_path, param, program, sizeof(buf),
			buf, &foreground);

	status_bar_message("FUSE mounting selected file, please stand by..");

	if(foreground)
	{
		def_prog_mode();
		endwin();
	}

	generate_tmp_file_name("vifm.errors", errors_file, sizeof(errors_file));

	strcat(buf, " 2> ");
	strcat(buf, errors_file);
	LOG_INFO_MSG("FUSE mount command: `%s`", buf);
	status = background_and_wait_for_status(buf, !foreground, &cancelled);

	clean_status_bar();

	/* Check child process exit status. */
	if(!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS)
	{
		FILE *ef;

		if(!WIFEXITED(status))
		{
			LOG_ERROR_MSG("FUSE mounter didn't exit!");
		}
		else
		{
			LOG_ERROR_MSG("FUSE mount command exit status: %d", WEXITSTATUS(status));
		}

		ef = os_fopen(errors_file, "r");
		if(ef == NULL)
		{
			LOG_SERROR_MSG(errno, "Failed to open temporary stderr file: %s",
					errors_file);
		}
		show_errors_from_file(ef, "FUSE mounter error");

		werase(status_bar);

		if(cancelled)
		{
			status_bar_message("FUSE mount cancelled");
			curr_stats.save_msg = 1;
		}
		else
		{
			show_error_msg("FUSE MOUNT ERROR", file_full_path);
		}

		if(unlink(errors_file) != 0)
		{
			LOG_SERROR_MSG(errno, "Error file deletion failure: %d", errors_file);
		}

		/* Remove the directory we created for the mount. */
		(void)rmdir(mount_point);

		(void)vifm_chdir(flist_get_dir(view));
		return -1;
	}
	unlink(errors_file);
	status_bar_message("FUSE mount success");

	register_mount(&fuse_mounts, file_full_path, mount_point, mount_point_id);

	return 0;
}
示例#21
0
int
compare_two_panes(CompareType ct, ListType lt, int group_paths, int skip_empty)
{
	int next_id = 1;
	entries_t curr, other;

	trie_t *const trie = trie_create();
	ui_cancellation_reset();
	ui_cancellation_enable();

	curr = make_diff_list(trie, curr_view, &next_id, ct, skip_empty, 0);
	other = make_diff_list(trie, other_view, &next_id, ct, skip_empty,
			lt == LT_DUPS);

	ui_cancellation_disable();
	trie_free_with_data(trie, &free_compare_records);

	/* Clear progress message displayed by make_diff_list(). */
	ui_sb_quick_msg_clear();

	if(ui_cancellation_requested())
	{
		free_dir_entries(curr_view, &curr.entries, &curr.nentries);
		free_dir_entries(other_view, &other.entries, &other.nentries);
		status_bar_message("Comparison has been cancelled");
		return 1;
	}

	if(!group_paths || lt != LT_ALL)
	{
		/* Sort both lists according to unique file numbers to group identical files
		 * (sorting is stable, tags are set in make_diff_list()). */
		qsort(curr.entries, curr.nentries, sizeof(*curr.entries), &id_sorter);
		qsort(other.entries, other.nentries, sizeof(*other.entries), &id_sorter);
	}

	if(lt == LT_UNIQUE)
	{
		make_unique_lists(curr, other);
		return 0;
	}

	if(lt == LT_DUPS)
	{
		leave_only_dups(&curr, &other);
	}

	flist_custom_start(curr_view, lt == LT_ALL ? "diff" : "dups diff");
	flist_custom_start(other_view, lt == LT_ALL ? "diff" : "dups diff");

	fill_side_by_side(curr, other, group_paths);

	if(flist_custom_finish(curr_view, CV_DIFF, 0) != 0)
	{
		show_error_msg("Comparison", "No results to display");
		return 0;
	}
	if(flist_custom_finish(other_view, CV_DIFF, 0) != 0)
	{
		assert(0 && "The error shouldn't be happening here.");
	}

	curr_view->list_pos = 0;
	other_view->list_pos = 0;
	curr_view->custom.diff_cmp_type = ct;
	other_view->custom.diff_cmp_type = ct;
	curr_view->custom.diff_path_group = group_paths;
	other_view->custom.diff_path_group = group_paths;

	assert(curr_view->list_rows == other_view->list_rows &&
			"Diff views must be in sync!");

	ui_view_schedule_redraw(curr_view);
	ui_view_schedule_redraw(other_view);
	return 0;
}
示例#22
0
int
compare_one_pane(FileView *view, CompareType ct, ListType lt, int skip_empty)
{
	int i, dup_id;
	FileView *other = (view == curr_view) ? other_view : curr_view;
	const char *const title = (lt == LT_ALL)  ? "compare"
	                        : (lt == LT_DUPS) ? "dups" : "nondups";

	int next_id = 1;
	entries_t curr;

	trie_t *trie = trie_create();
	ui_cancellation_reset();
	ui_cancellation_enable();

	curr = make_diff_list(trie, view, &next_id, ct, skip_empty, 0);

	ui_cancellation_disable();
	trie_free_with_data(trie, &free_compare_records);

	/* Clear progress message displayed by make_diff_list(). */
	ui_sb_quick_msg_clear();

	if(ui_cancellation_requested())
	{
		free_dir_entries(view, &curr.entries, &curr.nentries);
		status_bar_message("Comparison has been cancelled");
		return 1;
	}

	qsort(curr.entries, curr.nentries, sizeof(*curr.entries), &id_sorter);

	flist_custom_start(view, title);

	dup_id = -1;
	next_id = 0;
	for(i = 0; i < curr.nentries; ++i)
	{
		dir_entry_t *entry = &curr.entries[i];

		if(lt == LT_ALL)
		{
			flist_custom_put(view, entry);
			continue;
		}

		if(entry->id == dup_id)
		{
			put_or_free(view, entry, next_id, lt == LT_DUPS);
			continue;
		}

		dup_id = (i < curr.nentries - 1 && entry[0].id == entry[1].id)
		       ? entry->id
		       : -1;

		if(entry->id == dup_id)
		{
			put_or_free(view, entry, ++next_id, lt == LT_DUPS);
			continue;
		}

		put_or_free(view, entry, next_id, lt == LT_UNIQUE);
	}

	/* Entries' data has been moved out of them or freed, so need to free only the
	 * list. */
	dynarray_free(curr.entries);

	if(flist_custom_finish(view, lt == LT_UNIQUE ? CV_REGULAR : CV_COMPARE,
				0) != 0)
	{
		show_error_msg("Comparison", "No results to display");
		return 0;
	}

	/* Leave the other pane, if it's in the CV_DIFF mode, two panes are needed for
	 * this. */
	if(other->custom.type == CV_DIFF)
	{
		cd_updir(other, 1);
	}

	view->list_pos = 0;
	ui_view_schedule_redraw(view);
	return 0;
}
示例#23
0
void
screen_status_message(const char *msg)
{
	status_bar_message(&screen.status_bar, msg);
}
示例#24
0
文件: main_loop.c 项目: ychaim/vifm
/*
 * Main Loop
 * Everything is driven from this function with the exception of
 * signals which are handled in signals.c
 */
void
main_loop(void)
{
	LOG_FUNC_ENTER;

	int last_result = 0;
	int wait_enter = 0;
	int timeout = cfg.timeout_len;

	buf[0] = L'\0';
	while(1)
	{
		wchar_t c;
		size_t counter;
		int ret;

		is_term_working();

#ifdef _WIN32
		update_win_console();
#endif

		lwin.user_selection = 1;
		rwin.user_selection = 1;

		if(curr_stats.too_small_term > 0)
		{
			touchwin(stdscr);
			wrefresh(stdscr);

			mvwin(status_bar, 0, 0);
			wresize(status_bar, getmaxy(stdscr), getmaxx(stdscr));
			werase(status_bar);
			waddstr(status_bar, "Terminal is too small for vifm");
			touchwin(status_bar);
			wrefresh(status_bar);

#ifndef _WIN32
			pause();
#endif
			continue;
		}
		else if(curr_stats.too_small_term < 0)
		{
			wtimeout(status_bar, 0);
			while(wget_wch(status_bar, (wint_t*)&c) != ERR);
			curr_stats.too_small_term = 0;
			modes_redraw();
			wtimeout(status_bar, cfg.timeout_len);

			wait_enter = 0;
			curr_stats.save_msg = 0;
			status_bar_message("");
		}

		modes_pre();

		/* This waits for timeout then skips if no keypress. */
		ret = read_char(status_bar, (wint_t*)&c, timeout);

		/* Ensure that current working directory is set correctly (some pieces of
		 * code rely on this). */
		(void)vifm_chdir(curr_view->curr_dir);

		if(ret != ERR && pos != ARRAY_LEN(buf) - 2)
		{
			if(c == L'\x1a') /* Ctrl-Z */
			{
				def_prog_mode();
				endwin();
#ifndef _WIN32
				{
					void (*saved_stp_sig_handler)(int) = signal(SIGTSTP, SIG_DFL);
					kill(0, SIGTSTP);
					signal(SIGTSTP, saved_stp_sig_handler);
				}
#endif
				continue;
			}

			if(wait_enter)
			{
				wait_enter = 0;
				curr_stats.save_msg = 0;
				clean_status_bar();
				if(c == L'\x0d')
					continue;
			}

			buf[pos++] = c;
			buf[pos] = L'\0';
		}

		if(wait_enter && ret == ERR)
			continue;

		counter = get_key_counter();
		if(ret == ERR && last_result == KEYS_WAIT_SHORT)
		{
			last_result = execute_keys_timed_out(buf);
			counter = get_key_counter() - counter;
			assert(counter <= pos);
			if(counter > 0)
			{
				memmove(buf, buf + counter,
						(wcslen(buf) - counter + 1)*sizeof(wchar_t));
			}
		}
		else
		{
			if(ret != ERR)
				curr_stats.save_msg = 0;
			last_result = execute_keys(buf);
			counter = get_key_counter() - counter;
			assert(counter <= pos);
			if(counter > 0)
			{
				pos -= counter;
				memmove(buf, buf + counter,
						(wcslen(buf) - counter + 1)*sizeof(wchar_t));
			}
			if(last_result == KEYS_WAIT || last_result == KEYS_WAIT_SHORT)
			{
				if(ret != ERR)
					modupd_input_bar(buf);
				if(last_result == KEYS_WAIT_SHORT && wcscmp(buf, L"\033") == 0)
					timeout = 1;
				if(counter > 0)
					clear_input_bar();

				if(!curr_stats.save_msg && curr_view->selected_files &&
						get_mode() != CMDLINE_MODE)
					print_selected_msg();
				continue;
			}
		}

		timeout = cfg.timeout_len;

		process_scheduled_updates();

		pos = 0;
		buf[0] = L'\0';
		clear_input_bar();

		if(is_status_bar_multiline())
		{
			wait_enter = 1;
			update_all_windows();
			continue;
		}

		/* Ensure that current working directory is set correctly (some pieces of
		 * code rely on this).  PWD could be changed during command execution, but
		 * it should be correct for modes_post() in case of preview modes. */
		(void)vifm_chdir(curr_view->curr_dir);
		modes_post();
	}
}
示例#25
0
文件: fuse.c 项目: lyuts/vifm
/*
 * mount_point should be an array of at least PATH_MAX characters
 * Returns non-zero on error.
 */
static int
fuse_mount(FileView *view, char *file_full_path, const char *param,
		const char *program, char *mount_point)
{
	/* TODO: refactor this function fuse_mount() */

	fuse_mount_t *runner = NULL;
	int mount_point_id = 0;
	fuse_mount_t *fuse_item = NULL;
	char buf[2*PATH_MAX];
	char *escaped_filename;
	int clear_before_mount = 0;
	char errors_file[PATH_MAX];
	int status;

	escaped_filename = escape_filename(get_current_file_name(view), 0);

	/* get mount_point_id + mount_point and set runner pointing to the list's
	 * tail */
	if(fuse_mounts != NULL)
	{
		runner = fuse_mounts;
		while(runner->next != NULL)
			runner = runner->next;
		mount_point_id = runner->mount_point_id;
	}
	do
	{
		snprintf(mount_point, PATH_MAX, "%s/%03d_%s", cfg.fuse_home,
				++mount_point_id, get_current_file_name(view));
	}
	while(path_exists(mount_point));
	if(make_dir(mount_point, S_IRWXU) != 0)
	{
		free(escaped_filename);
		show_error_msg("Unable to create FUSE mount directory", mount_point);
		return -1;
	}
	free(escaped_filename);

	/* Just before running the mount,
		 I need to chdir out temporarily from any FUSE mounted
		 paths, Otherwise the fuse-zip command fails with
		 "fusermount: failed to open current directory: permission denied"
		 (this happens when mounting JARs from mounted JARs) */
	if(vifm_chdir(cfg.fuse_home) != 0)
	{
		show_error_msg("FUSE MOUNT ERROR", "Can't chdir() to FUSE home");
		return -1;
	}

	clear_before_mount = format_mount_command(mount_point, file_full_path, param,
			program, sizeof(buf), buf);

	status_bar_message("FUSE mounting selected file, please stand by..");

	if(clear_before_mount)
	{
		def_prog_mode();
		endwin();
	}

	generate_tmp_file_name("vifm.errors", errors_file, sizeof(errors_file));

	strcat(buf, " 2> ");
	strcat(buf, errors_file);
	LOG_INFO_MSG("FUSE mount command: `%s`", buf);
	status = background_and_wait_for_status(buf);

	clean_status_bar();

	/* check child status */
	if(!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status)))
	{
		FILE *ef = fopen(errors_file, "r");
		print_errors(ef);
		unlink(errors_file);

		werase(status_bar);
		/* remove the directory we created for the mount */
		if(path_exists(mount_point))
			rmdir(mount_point);
		show_error_msg("FUSE MOUNT ERROR", file_full_path);
		(void)vifm_chdir(view->curr_dir);
		return -1;
	}
	unlink(errors_file);
	status_bar_message("FUSE mount success");

	fuse_item = malloc(sizeof(*fuse_item));
	copy_str(fuse_item->source_file_name, sizeof(fuse_item->source_file_name),
			file_full_path);
	strcpy(fuse_item->source_file_dir, view->curr_dir);
	canonicalize_path(mount_point, fuse_item->mount_point,
			sizeof(fuse_item->mount_point));
	fuse_item->mount_point_id = mount_point_id;
	fuse_item->next = NULL;
	if(fuse_mounts == NULL)
		fuse_mounts = fuse_item;
	else
		runner->next = fuse_item;

	return 0;
}