diff --git a/README.md b/README.md index b056a6e..918e6a5 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ of small previews is displayed, making it easy to choose an image to open. -i Read file list from stdin -n NUM Start at picture NUM -N NAME Set X window resource name to NAME - -o Write file list to stdout when quitting + -o Write list of marked/all files to stdout when quitting -p Pixelize, i.e. turn off image anti-aliasing -q Be quiet, disable warnings -r Search given directories recursively for images @@ -108,6 +108,10 @@ of small previews is displayed, making it easy to choose an image to open. R Reload all thumbnails D Remove image from file list and go to next image + m Mark/unmark current image + N Go [count] marked images forward + P Go [count] marked images backward + *Thumbnail mode:* h,j,k,l Move selection left/down/up/right [count] times diff --git a/commands.c b/commands.c index 36da023..c1792a5 100644 --- a/commands.c +++ b/commands.c @@ -48,6 +48,7 @@ extern win_t win; extern fileinfo_t *files; extern int filecnt, fileidx; +extern int markcnt; extern int alternate; extern int prefix; @@ -61,8 +62,10 @@ bool it_quit(arg_t a) unsigned int i; if (options->to_stdout) { - for (i = 0; i < filecnt; i++) - printf("%s\n", files[i].name); + for (i = 0; i < filecnt; i++) { + if (!markcnt || files[i].marked) + printf("%s\n", files[i].name); + } } cleanup(); exit(EXIT_SUCCESS); @@ -237,6 +240,46 @@ bool i_toggle_animation(arg_t a) return true; } +bool it_toggle_image_mark(arg_t a) +{ + int sel = mode == MODE_IMAGE ? fileidx : tns.sel; + + files[sel].marked = !files[sel].marked; + markcnt += files[sel].marked ? 1 : -1; + return true; +} + +bool it_navigate_marked(arg_t a) +{ + long n = (long) a; + int d, i, cnt, sel, new; + + if (mode == MODE_IMAGE) + cnt = filecnt, sel = new = fileidx; + else + cnt = tns.cnt, sel = new = tns.sel; + if (prefix > 0) + n *= prefix; + d = n > 0 ? 1 : -1; + for (i = sel + d; n != 0 && i >= 0 && i < cnt; i += d) { + if (files[i].marked) { + n -= d; + new = i; + } + } + if (new != sel) { + if (mode == MODE_IMAGE) { + load_image(new); + } else { + tns.sel = new; + tns.dirty = true; + } + return true; + } else { + return false; + } +} + bool it_scroll_move(arg_t a) { direction_t dir = (direction_t) a; diff --git a/commands.h b/commands.h index 7a6752f..118c89a 100644 --- a/commands.h +++ b/commands.h @@ -54,6 +54,8 @@ bool it_first(arg_t); bool it_n_or_last(arg_t); bool i_navigate_frame(arg_t); bool i_toggle_animation(arg_t); +bool it_toggle_image_mark(arg_t); +bool it_navigate_marked(arg_t); bool it_scroll_move(arg_t); bool it_scroll_screen(arg_t); bool i_scroll_to_edge(arg_t); diff --git a/config.def.h b/config.def.h index e0e1460..d24723d 100644 --- a/config.def.h +++ b/config.def.h @@ -81,6 +81,10 @@ static const keymap_t keys[] = { { true, XK_p, i_navigate_frame, (arg_t) -1 }, { true, XK_space, i_toggle_animation, (arg_t) None }, + { false, XK_m, it_toggle_image_mark, (arg_t) None }, + { false, XK_N, it_navigate_marked, (arg_t) +1 }, + { false, XK_P, it_navigate_marked, (arg_t) -1 }, + { false, XK_h, it_scroll_move, (arg_t) DIR_LEFT }, { false, XK_Left, it_scroll_move, (arg_t) DIR_LEFT }, { false, XK_j, it_scroll_move, (arg_t) DIR_DOWN }, diff --git a/main.c b/main.c index 4962782..fb8b8b6 100644 --- a/main.c +++ b/main.c @@ -65,6 +65,7 @@ win_t win; fileinfo_t *files; int filecnt, fileidx; +int markcnt; int alternate; int prefix; @@ -312,6 +313,7 @@ void update_info(void) unsigned int i, fn, fw, n; unsigned int llen = sizeof(win.bar.l), rlen = sizeof(win.bar.r); char *lt = win.bar.l, *rt = win.bar.r, title[TITLE_LEN]; + const char * mark; bool ow_info; for (fw = 0, i = filecnt; i > 0; fw++, i /= 10); @@ -328,9 +330,10 @@ void update_info(void) /* update bar contents */ if (win.bar.h == 0) return; + mark = files[sel].marked ? "* " : ""; if (mode == MODE_THUMB) { if (tns.cnt == filecnt) { - n = snprintf(rt, rlen, "%0*d/%d", fw, sel + 1, filecnt); + n = snprintf(rt, rlen, "%s%0*d/%d", mark, fw, sel + 1, filecnt); ow_info = true; } else { snprintf(lt, llen, "Loading... %0*d/%d", fw, tns.cnt, filecnt); @@ -338,7 +341,7 @@ void update_info(void) ow_info = false; } } else { - n = snprintf(rt, rlen, "%3d%% | ", (int) (img.zoom * 100.0)); + n = snprintf(rt, rlen, "%s%3d%% | ", mark, (int) (img.zoom * 100.0)); if (img.multi.cnt > 0) { for (fn = 0, i = img.multi.cnt; i > 0; fn++, i /= 10); n += snprintf(rt + n, rlen - n, "%0*d/%d | ", diff --git a/sxiv.1 b/sxiv.1 index 7d06004..02593b1 100644 --- a/sxiv.1 +++ b/sxiv.1 @@ -62,7 +62,8 @@ Print brief usage information to standard output and exit. Read names of files to open from standard input. .TP .B \-o -Write list of opened files to standard output when quitting. If combined with +Write list of all marked files, or all opened files if no files are marked, to +standard output when quitting. If combined with .IR \-i , then sxiv acts as a visual filter/pipe. .TP @@ -128,6 +129,19 @@ Reload all thumbnails. .TP .B D Remove current image from file list and go to next image. +.TP +.B m +Mark/unmark the current image. +.TP +.B N +Go +.I count +marked images forward. +.TP +.B P +Go +.I count +marked images backward. .SH THUMBNAIL KEYBOARD COMMANDS The following keyboard commands are only available in thumbnail mode: .TP diff --git a/types.h b/types.h index 49aa0fd..2cd305e 100644 --- a/types.h +++ b/types.h @@ -69,6 +69,7 @@ typedef struct { const char *path; /* always absolute */ const char *base; bool loaded; + bool marked; } fileinfo_t; /* timeouts in milliseconds: */