nsxiv7d878bd
Added file marks; fixes issue #94
- Command it_toggle_image_mark (bound to 'm') toggles mark of current image - Command it_navigate_marked (bound to 'N'/'P') can be used to go to the next/previous marked image - When option -o is given, all marked files get printed
+77 −6
7 files changed
- M README.md +5 −1
- M commands.c +45 −2
- M commands.h +2 −0
- M config.def.h +4 −0
- M main.c +5 −2
- M sxiv.1 +15 −1
- M types.h +1 −0
| @@ -79,7 +79,7 @@ of small previews is displayed, making it easy to choose an image to open. | |||
| 79 | 79 | -i Read file list from stdin | |
| 80 | 80 | -n NUM Start at picture NUM | |
| 81 | 81 | -N NAME Set X window resource name to NAME | |
| 82 | − | -o Write file list to stdout when quitting | |
| 82 | + | -o Write list of marked/all files to stdout when quitting | |
| 83 | 83 | -p Pixelize, i.e. turn off image anti-aliasing | |
| 84 | 84 | -q Be quiet, disable warnings | |
| 85 | 85 | -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. | |||
| 108 | 108 | R Reload all thumbnails | |
| 109 | 109 | D Remove image from file list and go to next image | |
| 110 | 110 | ||
| 111 | + | m Mark/unmark current image | |
| 112 | + | N Go [count] marked images forward | |
| 113 | + | P Go [count] marked images backward | |
| 114 | + | ||
| 111 | 115 | *Thumbnail mode:* | |
| 112 | 116 | ||
| 113 | 117 | h,j,k,l Move selection left/down/up/right [count] times | |
| @@ -48,6 +48,7 @@ extern win_t win; | |||
| 48 | 48 | ||
| 49 | 49 | extern fileinfo_t *files; | |
| 50 | 50 | extern int filecnt, fileidx; | |
| 51 | + | extern int markcnt; | |
| 51 | 52 | extern int alternate; | |
| 52 | 53 | ||
| 53 | 54 | extern int prefix; | |
| @@ -61,8 +62,10 @@ bool it_quit(arg_t a) | |||
| 61 | 62 | unsigned int i; | |
| 62 | 63 | ||
| 63 | 64 | if (options->to_stdout) { | |
| 64 | − | for (i = 0; i < filecnt; i++) | |
| 65 | − | printf("%s\n", files[i].name); | |
| 65 | + | for (i = 0; i < filecnt; i++) { | |
| 66 | + | if (!markcnt || files[i].marked) | |
| 67 | + | printf("%s\n", files[i].name); | |
| 68 | + | } | |
| 66 | 69 | } | |
| 67 | 70 | cleanup(); | |
| 68 | 71 | exit(EXIT_SUCCESS); | |
| @@ -237,6 +240,46 @@ bool i_toggle_animation(arg_t a) | |||
| 237 | 240 | return true; | |
| 238 | 241 | } | |
| 239 | 242 | ||
| 243 | + | bool it_toggle_image_mark(arg_t a) | |
| 244 | + | { | |
| 245 | + | int sel = mode == MODE_IMAGE ? fileidx : tns.sel; | |
| 246 | + | ||
| 247 | + | files[sel].marked = !files[sel].marked; | |
| 248 | + | markcnt += files[sel].marked ? 1 : -1; | |
| 249 | + | return true; | |
| 250 | + | } | |
| 251 | + | ||
| 252 | + | bool it_navigate_marked(arg_t a) | |
| 253 | + | { | |
| 254 | + | long n = (long) a; | |
| 255 | + | int d, i, cnt, sel, new; | |
| 256 | + | ||
| 257 | + | if (mode == MODE_IMAGE) | |
| 258 | + | cnt = filecnt, sel = new = fileidx; | |
| 259 | + | else | |
| 260 | + | cnt = tns.cnt, sel = new = tns.sel; | |
| 261 | + | if (prefix > 0) | |
| 262 | + | n *= prefix; | |
| 263 | + | d = n > 0 ? 1 : -1; | |
| 264 | + | for (i = sel + d; n != 0 && i >= 0 && i < cnt; i += d) { | |
| 265 | + | if (files[i].marked) { | |
| 266 | + | n -= d; | |
| 267 | + | new = i; | |
| 268 | + | } | |
| 269 | + | } | |
| 270 | + | if (new != sel) { | |
| 271 | + | if (mode == MODE_IMAGE) { | |
| 272 | + | load_image(new); | |
| 273 | + | } else { | |
| 274 | + | tns.sel = new; | |
| 275 | + | tns.dirty = true; | |
| 276 | + | } | |
| 277 | + | return true; | |
| 278 | + | } else { | |
| 279 | + | return false; | |
| 280 | + | } | |
| 281 | + | } | |
| 282 | + | ||
| 240 | 283 | bool it_scroll_move(arg_t a) | |
| 241 | 284 | { | |
| 242 | 285 | direction_t dir = (direction_t) a; | |
| @@ -54,6 +54,8 @@ bool it_first(arg_t); | |||
| 54 | 54 | bool it_n_or_last(arg_t); | |
| 55 | 55 | bool i_navigate_frame(arg_t); | |
| 56 | 56 | bool i_toggle_animation(arg_t); | |
| 57 | + | bool it_toggle_image_mark(arg_t); | |
| 58 | + | bool it_navigate_marked(arg_t); | |
| 57 | 59 | bool it_scroll_move(arg_t); | |
| 58 | 60 | bool it_scroll_screen(arg_t); | |
| 59 | 61 | bool i_scroll_to_edge(arg_t); | |
| @@ -81,6 +81,10 @@ static const keymap_t keys[] = { | |||
| 81 | 81 | { true, XK_p, i_navigate_frame, (arg_t) -1 }, | |
| 82 | 82 | { true, XK_space, i_toggle_animation, (arg_t) None }, | |
| 83 | 83 | ||
| 84 | + | { false, XK_m, it_toggle_image_mark, (arg_t) None }, | |
| 85 | + | { false, XK_N, it_navigate_marked, (arg_t) +1 }, | |
| 86 | + | { false, XK_P, it_navigate_marked, (arg_t) -1 }, | |
| 87 | + | ||
| 84 | 88 | { false, XK_h, it_scroll_move, (arg_t) DIR_LEFT }, | |
| 85 | 89 | { false, XK_Left, it_scroll_move, (arg_t) DIR_LEFT }, | |
| 86 | 90 | { false, XK_j, it_scroll_move, (arg_t) DIR_DOWN }, | |
| @@ -65,6 +65,7 @@ win_t win; | |||
| 65 | 65 | ||
| 66 | 66 | fileinfo_t *files; | |
| 67 | 67 | int filecnt, fileidx; | |
| 68 | + | int markcnt; | |
| 68 | 69 | int alternate; | |
| 69 | 70 | ||
| 70 | 71 | int prefix; | |
| @@ -312,6 +313,7 @@ void update_info(void) | |||
| 312 | 313 | unsigned int i, fn, fw, n; | |
| 313 | 314 | unsigned int llen = sizeof(win.bar.l), rlen = sizeof(win.bar.r); | |
| 314 | 315 | char *lt = win.bar.l, *rt = win.bar.r, title[TITLE_LEN]; | |
| 316 | + | const char * mark; | |
| 315 | 317 | bool ow_info; | |
| 316 | 318 | ||
| 317 | 319 | for (fw = 0, i = filecnt; i > 0; fw++, i /= 10); | |
| @@ -328,9 +330,10 @@ void update_info(void) | |||
| 328 | 330 | /* update bar contents */ | |
| 329 | 331 | if (win.bar.h == 0) | |
| 330 | 332 | return; | |
| 333 | + | mark = files[sel].marked ? "* " : ""; | |
| 331 | 334 | if (mode == MODE_THUMB) { | |
| 332 | 335 | if (tns.cnt == filecnt) { | |
| 333 | − | n = snprintf(rt, rlen, "%0*d/%d", fw, sel + 1, filecnt); | |
| 336 | + | n = snprintf(rt, rlen, "%s%0*d/%d", mark, fw, sel + 1, filecnt); | |
| 334 | 337 | ow_info = true; | |
| 335 | 338 | } else { | |
| 336 | 339 | snprintf(lt, llen, "Loading... %0*d/%d", fw, tns.cnt, filecnt); | |
| @@ -338,7 +341,7 @@ void update_info(void) | |||
| 338 | 341 | ow_info = false; | |
| 339 | 342 | } | |
| 340 | 343 | } else { | |
| 341 | − | n = snprintf(rt, rlen, "%3d%% | ", (int) (img.zoom * 100.0)); | |
| 344 | + | n = snprintf(rt, rlen, "%s%3d%% | ", mark, (int) (img.zoom * 100.0)); | |
| 342 | 345 | if (img.multi.cnt > 0) { | |
| 343 | 346 | for (fn = 0, i = img.multi.cnt; i > 0; fn++, i /= 10); | |
| 344 | 347 | n += snprintf(rt + n, rlen - n, "%0*d/%d | ", | |
| @@ -62,7 +62,8 @@ Print brief usage information to standard output and exit. | |||
| 62 | 62 | Read names of files to open from standard input. | |
| 63 | 63 | .TP | |
| 64 | 64 | .B \-o | |
| 65 | − | Write list of opened files to standard output when quitting. If combined with | |
| 65 | + | Write list of all marked files, or all opened files if no files are marked, to | |
| 66 | + | standard output when quitting. If combined with | |
| 66 | 67 | .IR \-i , | |
| 67 | 68 | then sxiv acts as a visual filter/pipe. | |
| 68 | 69 | .TP | |
| @@ -128,6 +129,19 @@ Reload all thumbnails. | |||
| 128 | 129 | .TP | |
| 129 | 130 | .B D | |
| 130 | 131 | Remove current image from file list and go to next image. | |
| 132 | + | .TP | |
| 133 | + | .B m | |
| 134 | + | Mark/unmark the current image. | |
| 135 | + | .TP | |
| 136 | + | .B N | |
| 137 | + | Go | |
| 138 | + | .I count | |
| 139 | + | marked images forward. | |
| 140 | + | .TP | |
| 141 | + | .B P | |
| 142 | + | Go | |
| 143 | + | .I count | |
| 144 | + | marked images backward. | |
| 131 | 145 | .SH THUMBNAIL KEYBOARD COMMANDS | |
| 132 | 146 | The following keyboard commands are only available in thumbnail mode: | |
| 133 | 147 | .TP | |
| @@ -69,6 +69,7 @@ typedef struct { | |||
| 69 | 69 | const char *path; /* always absolute */ | |
| 70 | 70 | const char *base; | |
| 71 | 71 | bool loaded; | |
| 72 | + | bool marked; | |
| 72 | 73 | } fileinfo_t; | |
| 73 | 74 | ||
| 74 | 75 | /* timeouts in milliseconds: */ | |