Skip to content

Commit

Permalink
Add prev_dir and next_dir navigation actions
Browse files Browse the repository at this point in the history
Many image collections are organized by directory, so it is nice to have
jump-to-adjacent-directory navigation.

e.g. Given the following file hierarchy:

    .
    ├── A
    │   ├── 1.jpg
    │   ├── 2.jpg
    │   └── C
    │       ├── 1.jpg
    │       ├── 2.jpg
    │       └── 3.jpg
    └── B
        ├── 1.jpg
        ├── 2.jpg
        └── 3.jpg

`feh --recursive` creates the following filelist:

    A/1.jpg <---- current_file
    A/2.jpg
    A/C/1.jpg
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg
    B/2.jpg
    B/3.jpg

If we press [next_dir], we move the current_file pointer to:

    A/1.jpg
    A/2.jpg
    A/C/1.jpg <-- current_file
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg
    B/2.jpg
    B/3.jpg

Pressing [next_dir] again moves the pointer to:

    A/1.jpg
    A/2.jpg
    A/C/1.jpg
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg <---- current_file
    B/2.jpg
    B/3.jpg

[next_dir] now moves the pointer back to the top of the list:

    A/1.jpg <---- current_file
    A/2.jpg
    A/C/1.jpg
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg
    B/2.jpg
    B/3.jpg

Pressing [prev_dir] from here moves backwards to the first image of the
previous directory:

    A/1.jpg
    A/2.jpg
    A/C/1.jpg
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg <---- current_file
    B/2.jpg
    B/3.jpg

When starting from an position that is not the first image of a
directory, [prev_dir] moves the pointer to the first image of the
current directory.

These actions combine well with `--sort dirname` since all regular files
in a directory will be sorted before any subdirectories, avoiding a
filelist like the following:

    A/1.jpg
    A/SUBDIR/2.jpg
    A/SUBDIR/3.jpg
    A/4.jpg

With `--sort dirname` that filelist becomes:

    A/1.jpg
    A/4.jpg
    A/SUBDIR/2.jpg
    A/SUBDIR/3.jpg
  • Loading branch information
guns committed May 28, 2016
1 parent 7db8895 commit 36b09fa
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 1 deletion.
6 changes: 6 additions & 0 deletions man/feh.pre
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,12 @@ Close current window
.
Jump to a random position in the current filelist
.
.It \&[, \&] Bq prev_dir, next_dir
.
Jump to the first image of the previous or next sequence of images sharing
a directory name in the current filelist. Use --sort dirname if you would
like to ensure that all images in a directory are grouped together.
.
.It < , > Bq orient_3 , orient_1
.
In place editing - rotate the images 90 degrees (counter)clockwise.
Expand Down
4 changes: 3 additions & 1 deletion src/feh.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ enum text_bg { TEXT_BG_CLEAR = 0, TEXT_BG_TINTED };

enum slide_change { SLIDE_NEXT, SLIDE_PREV, SLIDE_RAND, SLIDE_FIRST, SLIDE_LAST,
SLIDE_JUMP_FWD,
SLIDE_JUMP_BACK
SLIDE_JUMP_BACK,
SLIDE_JUMP_NEXT_DIR,
SLIDE_JUMP_PREV_DIR
};

enum image_bg { IMAGE_BG_CHECKS = 1, IMAGE_BG_BLACK, IMAGE_BG_WHITE };
Expand Down
14 changes: 14 additions & 0 deletions src/keyevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ void init_keyevents(void) {
feh_set_kb(&keys.next_img , 0, XK_Right , 0, XK_n , 0, XK_space);
feh_set_kb(&keys.jump_back , 0, XK_Page_Up , 0, XK_KP_Page_Up, 0, 0);
feh_set_kb(&keys.jump_fwd , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0);
feh_set_kb(&keys.prev_dir , 0, XK_bracketleft, 0, 0 , 0, 0);
feh_set_kb(&keys.next_dir , 0, XK_bracketright, 0, 0 , 0, 0);
feh_set_kb(&keys.jump_random,0, XK_z , 0, 0 , 0, 0);
feh_set_kb(&keys.quit , 0, XK_Escape , 0, XK_q , 0, 0);
feh_set_kb(&keys.close , 0, XK_x , 0, 0 , 0, 0);
Expand Down Expand Up @@ -222,6 +224,10 @@ void init_keyevents(void) {
cur_kb = &keys.jump_back;
else if (!strcmp(action, "jump_fwd"))
cur_kb = &keys.jump_fwd;
else if (!strcmp(action, "prev_dir"))
cur_kb = &keys.prev_dir;
else if (!strcmp(action, "next_dir"))
cur_kb = &keys.next_dir;
else if (!strcmp(action, "jump_random"))
cur_kb = &keys.jump_random;
else if (!strcmp(action, "quit"))
Expand Down Expand Up @@ -532,6 +538,14 @@ void feh_event_handle_keypress(XEvent * ev)
else if (winwid->type == WIN_TYPE_THUMBNAIL)
feh_thumbnail_select_next(winwid, 10);
}
else if (feh_is_kp(&keys.next_dir, keysym, state)) {
if (opt.slideshow)
slideshow_change_image(winwid, SLIDE_JUMP_NEXT_DIR, 1);
}
else if (feh_is_kp(&keys.prev_dir, keysym, state)) {
if (opt.slideshow)
slideshow_change_image(winwid, SLIDE_JUMP_PREV_DIR, 1);
}
else if (feh_is_kp(&keys.quit, keysym, state)) {
winwidget_destroy_all();
}
Expand Down
2 changes: 2 additions & 0 deletions src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ struct __fehkb {
struct __fehkey jump_back;
struct __fehkey quit;
struct __fehkey jump_fwd;
struct __fehkey prev_dir;
struct __fehkey next_dir;
struct __fehkey remove;
struct __fehkey delete;
struct __fehkey jump_first;
Expand Down
38 changes: 38 additions & 0 deletions src/slideshow.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,44 @@ void slideshow_change_image(winwidget winwid, int change, int render)
try the previous file, not another jmp */
change = SLIDE_NEXT;
break;
case SLIDE_JUMP_NEXT_DIR:
{
char old_dir[FEH_MAX_DIRNAME_LEN], new_dir[FEH_MAX_DIRNAME_LEN];
int j;

feh_file_dirname(old_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN);

for (j = 0; j < our_filelist_len; j++) {
current_file = feh_list_jump(filelist, current_file, FORWARD, 1);
feh_file_dirname(new_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN);
if (strcmp(old_dir, new_dir) != 0)
break;
}
}
change = SLIDE_NEXT;
break;
case SLIDE_JUMP_PREV_DIR:
{
char old_dir[FEH_MAX_DIRNAME_LEN], new_dir[FEH_MAX_DIRNAME_LEN];
int j;

/* Start the search from the previous file in case we are on
the first file of a directory */
current_file = feh_list_jump(filelist, current_file, BACK, 1);
feh_file_dirname(old_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN);

for (j = 0; j < our_filelist_len; j++) {
current_file = feh_list_jump(filelist, current_file, BACK, 1);
feh_file_dirname(new_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN);
if (strcmp(old_dir, new_dir) != 0)
break;
}

/* Next file is the first entry of prev_dir */
current_file = feh_list_jump(filelist, current_file, FORWARD, 1);
}
change = SLIDE_NEXT;
break;
default:
eprintf("BUG!\n");
break;
Expand Down

0 comments on commit 36b09fa

Please sign in to comment.