Exemplo n.º 1
0
static int
search_menu_backwards(menu_info *m, int start_pos)
{
	int match_up = -1;
	int match_down = -1;
	int x;

	for(x = m->len - 1; x > -1; x--)
	{
		if(!m->matches[x])
			continue;

		if(match_up < 0)
		{
			if(x <= start_pos)
				match_up = x;
		}
		if(match_down < 0)
		{
			if(x > start_pos)
				match_down = x;
		}
	}

	if(match_up > -1 || match_down > -1)
	{
		int pos;

		if(!cfg.wrap_scan && match_up <= -1)
		{
			status_bar_errorf("Search hit TOP without match for: %s", m->regexp);
			return 1;
		}

		pos = (match_up > -1) ? match_up : match_down;

		clean_menu_position(m);
		move_to_menu_pos(pos, m);
		status_bar_messagef("%d %s", m->matching_entries,
				(m->matching_entries == 1) ? "match" : "matches");
	}
	else
	{
		move_to_menu_pos(m->pos, m);
		if(!cfg.wrap_scan)
			status_bar_errorf("Search hit TOP without match for: %s", m->regexp);
		else
			status_bar_errorf("No matches for: %s", m->regexp);
		return 1;
	}
	return 0;
}
Exemplo n.º 2
0
/* Restores current item from the trash. */
static KHandlerResponse
restore_current(menu_data_t *m)
{
	char *trash_path;
	int err;

	cmd_group_begin("restore: ");
	cmd_group_end();

	/* The string is freed in restore_from_trash(), thus must be cloned. */
	trash_path = strdup(trash_list[m->pos].trash_name);
	err = restore_from_trash(trash_path);
	free(trash_path);

	if(err != 0)
	{
		const char *const orig_path = m->items[m->pos];
		status_bar_errorf("Failed to restore %s", orig_path);
		curr_stats.save_msg = 1;
		return KHR_UNHANDLED;
	}

	remove_current_item(m->state);
	return KHR_REFRESH_WINDOW;
}
Exemplo n.º 3
0
int
find_vwpattern(const char *pattern, int backward)
{
	int err;

	if(pattern == NULL)
		return 0;

	if(vi->last_search_backward != -1)
		regfree(&vi->re);
	vi->last_search_backward = -1;
	if((err = regcomp(&vi->re, pattern, get_regexp_cflags(pattern))) != 0)
	{
		status_bar_errorf("Invalid pattern: %s", get_regexp_error(err, &vi->re));
		regfree(&vi->re);
		draw();
		return 1;
	}

	vi->last_search_backward = backward;

	search(vi->search_repeat, backward);

	return curr_stats.save_msg;
}
Exemplo n.º 4
0
/* Looks for next matching element in backward direction from current position.
 * Returns new value for save_msg flag. */
static int
search_menu_backwards(menu_state_t *m, int start_pos)
{
	int match_up = -1;
	int match_down = -1;
	int i;

	for(i = m->d->len - 1; i > -1; --i)
	{
		if(m->matches[i][0] < 0)
		{
			continue;
		}

		if(match_up < 0 && i <= start_pos)
		{
			match_up = i;
		}
		if(match_down < 0 && i > start_pos)
		{
			match_down = i;
		}
	}

	if(!cfg.wrap_scan && match_up <= -1)
	{
		status_bar_errorf("Search hit TOP without match for: %s", m->regexp);
		return 1;
	}

	return navigate_to_match(m, (match_up > -1) ? match_up : match_down);
}
Exemplo n.º 5
0
/* Looks for next matching element in forward direction from current position.
 * Returns new value for save_msg flag. */
static int
search_menu_forwards(menu_state_t *m, int start_pos)
{
	int match_up = -1;
	int match_down = -1;
	int i;

	for(i = 0; i < m->d->len; ++i)
	{
		if(m->matches[i][0] < 0)
		{
			continue;
		}

		if(match_up < 0 && i < start_pos)
		{
			match_up = i;
		}
		if(match_down < 0 && i >= start_pos)
		{
			match_down = i;
		}
	}

	if(!cfg.wrap_scan && match_down <= -1)
	{
		status_bar_errorf("Search hit BOTTOM without match for: %s", m->regexp);
		return 1;
	}

	return navigate_to_match(m, (match_down > -1) ? match_down : match_up);
}
Exemplo n.º 6
0
static int
resolve_mark(char mark)
{
	int result;

	result = check_mark_directory(curr_view, mark);
	if(result < 0)
		status_bar_errorf("Trying to use an invalid mark: '%c", mark);
	return result;
}
Exemplo n.º 7
0
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);
    }
}
Exemplo n.º 8
0
void
setup_user_bookmark(const char mark, const char directory[], const char file[],
		time_t timestamp)
{
	if(is_user_bookmark(mark))
	{
		set_mark(mark, directory, file, timestamp, 1);
	}
	else
	{
		status_bar_errorf("Only user's bookmarks can be loaded, but got: %c", mark);
	}
}
Exemplo n.º 9
0
void
menu_print_search_msg(const menu_state_t *m)
{
	int cflags;
	regex_t re;
	int err;

	/* Can be NULL after regex compilation failure. */
	if(m->regexp == NULL)
	{
		return;
	}

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

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

	regfree(&re);

	if(m->matching_entries > 0)
	{
		status_bar_messagef("%d of %d %s", get_match_index(m), m->matching_entries,
				(m->matching_entries == 1) ? "match" : "matches");
	}
	else
	{
		status_bar_errorf("No matches for: %s", m->regexp);
	}
}
Exemplo n.º 10
0
/* Goes through all menu items and marks those that match search pattern.
 * Returns non-zero on error. */
static int
search_menu(menu_state_t *ms, int start_pos, int print_errors)
{
	menu_data_t *const m = ms->d;
	int cflags;
	regex_t re;
	int err;
	int i;

	if(ms->matches == NULL)
	{
		ms->matches = reallocarray(NULL, m->len, sizeof(*ms->matches));
	}

	memset(ms->matches, -1, 2*sizeof(**ms->matches)*m->len);
	ms->matching_entries = 0;

	if(ms->regexp[0] == '\0')
	{
		return 0;
	}

	cflags = get_regexp_cflags(ms->regexp);
	err = regcomp(&re, ms->regexp, cflags);
	if(err != 0)
	{
		if(print_errors)
		{
			status_bar_errorf("Regexp error: %s", get_regexp_error(err, &re));
		}
		regfree(&re);
		return -1;
	}

	for(i = 0; i < m->len; ++i)
	{
		regmatch_t matches[1];
		if(regexec(&re, m->items[i], 1, matches, 0) == 0)
		{
			ms->matches[i][0] = matches[0].rm_so;
			ms->matches[i][1] = matches[0].rm_eo;

			++ms->matching_entries;
		}
	}
	regfree(&re);
	return 0;
}
Exemplo n.º 11
0
/* Returns non-zero on error */
static int
search_menu(menu_info *m, int start_pos)
{
	int cflags;
	regex_t re;
	int err;

	if(m->matches == NULL)
		m->matches = malloc(sizeof(int)*m->len);

	memset(m->matches, 0, sizeof(int)*m->len);

	if(m->regexp[0] == '\0')
		return 0;

	cflags = get_regexp_cflags(m->regexp);
	if((err = regcomp(&re, m->regexp, cflags)) == 0)
	{
		int x;
		m->matching_entries = 0;
		for(x = 0; x < m->len; x++)
		{
			if(regexec(&re, m->items[x], 0, NULL, 0) != 0)
				continue;
			m->matches[x] = 1;

			m->matching_entries++;
		}
		regfree(&re);
		return 0;
	}
	else
	{
		status_bar_errorf("Regexp error: %s", get_regexp_error(err, &re));
		regfree(&re);
		return -1;
	}
}
Exemplo n.º 12
0
int
run_ext_command(const char cmd[], MacroFlags flags, int bg, int *save_msg)
{
	if(bg && flags != MF_NONE && flags != MF_NO_TERM_MUX && flags != MF_IGNORE)
	{
		status_bar_errorf("\"%s\" macro can't be combined with \" &\"",
				macros_to_str(flags));
		*save_msg = 1;
		return -1;
	}

	if(flags == MF_STATUSBAR_OUTPUT)
	{
		output_to_statusbar(cmd);
		*save_msg = 1;
		return -1;
	}
	else if(flags == MF_IGNORE)
	{
		*save_msg = 0;
		if(bg)
		{
			int error;

			setup_shellout_env();
			error = (start_background_job(cmd, 1) != 0);
			cleanup_shellout_env();

			if(error)
			{
				status_bar_errorf("Failed to start in bg: %s", cmd);
				*save_msg = 1;
			}
		}
		else
		{
			output_to_nowhere(cmd);
		}
		return -1;
	}
	else if(flags == MF_MENU_OUTPUT || flags == MF_MENU_NAV_OUTPUT)
	{
		const int navigate = flags == MF_MENU_NAV_OUTPUT;
		setup_shellout_env();
		*save_msg = show_user_menu(curr_view, cmd, navigate) != 0;
		cleanup_shellout_env();
	}
	else if(flags == MF_SPLIT && curr_stats.term_multiplexer != TM_NONE)
	{
		run_in_split(curr_view, cmd);
	}
	else if(flags == MF_CUSTOMVIEW_OUTPUT || flags == MF_VERYCUSTOMVIEW_OUTPUT)
	{
		const int very = flags == MF_VERYCUSTOMVIEW_OUTPUT;
		output_to_custom_flist(curr_view, cmd, very);
	}
	else
	{
		return 0;
	}
	return 1;
}
Exemplo n.º 13
0
int
find_pattern(FileView *view, const char pattern[], int backward, int move,
             int *const found, int interactive)
{
    int cflags;
    int nmatches = 0;
    regex_t re;
    int err;
    FileView *other;

    if(move && cfg.hl_search)
    {
        clean_selected_files(view);
    }

    reset_search_results(view);

    if(pattern[0] == '\0')
    {
        *found = 1;
        return 0;
    }

    *found = 0;

    cflags = get_regexp_cflags(pattern);
    if((err = regcomp(&re, pattern, cflags)) == 0)
    {
        int i;
        for(i = 0; i < view->list_rows; ++i)
        {
            regmatch_t matches[1];
            dir_entry_t *const entry = &view->dir_entry[i];

            if(is_parent_dir(entry->name))
            {
                continue;
            }

            if(regexec(&re, entry->name, 1, matches, 0) != 0)
            {
                continue;
            }

            entry->search_match = nmatches + 1;
            entry->match_left = matches[0].rm_so;
            entry->match_right = matches[0].rm_eo;
            if(cfg.hl_search)
            {
                entry->selected = 1;
                ++view->selected_files;
            }
            ++nmatches;
        }
        regfree(&re);
    }
    else
    {
        if(interactive)
        {
            status_bar_errorf("Regexp error: %s", get_regexp_error(err, &re));
        }
        regfree(&re);
        return 1;
    }

    other = (view == &lwin) ? &rwin : &lwin;
    if(other->matches != 0 && strcmp(other->last_search, pattern) != 0)
    {
        other->last_search[0] = '\0';
        ui_view_reset_search_highlight(other);
    }
    view->matches = nmatches;
    copy_str(view->last_search, sizeof(view->last_search), pattern);

    /* Need to redraw the list so that the matching files are highlighted */
    draw_dir_list(view);

    view->matches = nmatches;
    if(nmatches > 0)
    {
        const int was_found = move ? goto_search_match(view, backward) : 1;
        *found = was_found;

        if(cfg.hl_search && !was_found)
        {
            /* Update the view.  It look might have changed, because of selection. */
            fview_cursor_redraw(view);
        }

        if(!cfg.hl_search)
        {
            if(interactive)
            {
                print_result(view, was_found, backward);
            }
            return 1;
        }
        return 0;
    }
    else
    {
        fview_cursor_redraw(view);
        if(interactive)
        {
            print_search_fail_msg(view, backward);
        }
        return 1;
    }
}
Exemplo n.º 14
0
int
find_pattern(FileView *view, const char pattern[], int backward, int move,
		int *const found, int print_errors)
{
	int cflags;
	int nmatches = 0;
	regex_t re;
	int err;
	FileView *other;

	if(move && cfg.hl_search)
	{
		flist_sel_stash(view);
	}

	reset_search_results(view);

	/* We at least could wipe out previous search results, so schedule a
	 * redraw. */
	ui_view_schedule_redraw(view);

	if(pattern[0] == '\0')
	{
		*found = 1;
		return 0;
	}

	*found = 0;

	cflags = get_regexp_cflags(pattern);
	if((err = regcomp(&re, pattern, cflags)) == 0)
	{
		int i;
		for(i = 0; i < view->list_rows; ++i)
		{
			regmatch_t matches[1];
			dir_entry_t *const entry = &view->dir_entry[i];
			const char *name = entry->name;
			char *free_this = NULL;

			if(is_parent_dir(name))
			{
				continue;
			}

			if(fentry_is_dir(entry))
			{
				free_this = format_str("%s/", name);
				name = free_this;
			}

			if(regexec(&re, name, 1, matches, 0) != 0)
			{
				free(free_this);
				continue;
			}
			free(free_this);

			entry->search_match = nmatches + 1;
			entry->match_left = matches[0].rm_so;
			entry->match_right = matches[0].rm_eo;
			if(cfg.hl_search)
			{
				entry->selected = 1;
				++view->selected_files;
			}
			++nmatches;
		}
		regfree(&re);
	}
	else
	{
		if(print_errors)
		{
			status_bar_errorf("Regexp error: %s", get_regexp_error(err, &re));
		}
		regfree(&re);
		return -1;
	}

	other = (view == &lwin) ? &rwin : &lwin;
	if(other->matches != 0 && strcmp(other->last_search, pattern) != 0)
	{
		other->last_search[0] = '\0';
		ui_view_reset_search_highlight(other);
	}
	view->matches = nmatches;
	copy_str(view->last_search, sizeof(view->last_search), pattern);

	view->matches = nmatches;
	if(nmatches > 0)
	{
		const int was_found = move ? goto_search_match(view, backward) : 1;
		*found = was_found;

		if(!cfg.hl_search)
		{
			if(print_errors)
			{
				print_result(view, was_found, backward);
			}
			return 1;
		}
		return 0;
	}
	else
	{
		if(print_errors)
		{
			print_search_fail_msg(view, backward);
		}
		return 1;
	}
}