xaizek / vifm (License: GPLv2+) (since 2018-12-07)
Vifm is a file manager with curses interface, which provides Vi[m]-like environment for managing objects within file systems, extended with some useful ideas from mutt.
Commit 1bc90a22a6c0040758f9be57f61a301a1c8675d7

Show current file position of background operation
When processing multiple files in background, prepend current position
in the list and list's length to job's description.
Author: xaizek
Author date (UTC): 2024-04-08 08:43
Committer name: xaizek
Committer date (UTC): 2024-04-14 12:13
Parent(s): c54e0dd1b1a20fe39e25e0fdcc7a3b57b8a57f2d
Signing key: 99DC5E4DB05F6BE2
Tree: e79ef6f91399ac478a169135204f1ca434edabd7
File Lines added Lines deleted
ChangeLog 3 0
src/fops_cpmv.c 31 1
tests/fileops/cpmv_files.c 38 2
File ChangeLog changed (mode: 100644) (index 900a6e562..1d18667a2)
98 98 Document how use of different preview macros affect classification of the Document how use of different preview macros affect classification of the
99 99 previewer. Thanks to iambumblehead. previewer. Thanks to iambumblehead.
100 100
101 When processing multiple files in background, show current position in the
102 list on the job bar.
103
101 104 Fixed line number column not including padding to the left of it. Fixed line number column not including padding to the left of it.
102 105
103 106 Fixed local options not being loaded on Ctrl-W x. Fixed local options not being loaded on Ctrl-W x.
File src/fops_cpmv.c changed (mode: 100644) (index 5168d7038..5b56e719c)
... ... static int check_for_clashes(verify_args_t *args, char *list[], char *marked[],
62 62 int nlines, char **error); int nlines, char **error);
63 63 static const char * cmlo_to_str(CopyMoveLikeOp op); static const char * cmlo_to_str(CopyMoveLikeOp op);
64 64 static void cpmv_files_in_bg(bg_op_t *bg_op, void *arg); static void cpmv_files_in_bg(bg_op_t *bg_op, void *arg);
65 static void set_cpmv_bg_descr(bg_op_t *bg_op, bg_args_t *args, size_t i);
65 66 static void cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], static void cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[],
66 67 int move, int force, int skip, int from_trash, const char dst_dir[]); int move, int force, int skip, int from_trash, const char dst_dir[]);
67 68 static int cp_file_f(const char src[], const char dst[], CopyMoveLikeOp op, static int cp_file_f(const char src[], const char dst[], CopyMoveLikeOp op,
 
... ... cpmv_files_in_bg(bg_op_t *bg_op, void *arg)
607 608 { {
608 609 const char *const src = args->sel_list[i]; const char *const src = args->sel_list[i];
609 610 const char *const dst = args->list[i]; const char *const dst = args->list[i];
610 bg_op_set_descr(bg_op, src);
611
612 set_cpmv_bg_descr(bg_op, args, i);
613
611 614 cpmv_file_in_bg(ops, src, dst, args->move, args->force, args->skip, cpmv_file_in_bg(ops, src, dst, args->move, args->force, args->skip,
612 615 args->is_in_trash[i], args->path); args->is_in_trash[i], args->path);
613 616 ++bg_op->done; ++bg_op->done;
 
... ... cpmv_files_in_bg(bg_op_t *bg_op, void *arg)
616 619 fops_free_bg_args(args); fops_free_bg_args(args);
617 620 } }
618 621
622 /* Sets nice title for the background job. */
623 static void
624 set_cpmv_bg_descr(bg_op_t *bg_op, bg_args_t *args, size_t i)
625 {
626 const char *src = args->sel_list[i];
627
628 /* Start with the source path. */
629 const char *descr = src;
630
631 /* In case there are multiple files to process, prepend current position. */
632 char *stats = NULL;
633 if(args->sel_list_len > 1)
634 {
635 /* The space is doubled for the symmetry with progress appended by the job
636 * bar. */
637 stats = format_str("%d/%d %s", (int)i + 1, (int)args->sel_list_len, descr);
638 }
639 if(stats != NULL)
640 {
641 descr = stats;
642 }
643
644 bg_op_set_descr(bg_op, descr);
645
646 free(stats);
647 }
648
619 649 /* Actual implementation of background file copying/moving. */ /* Actual implementation of background file copying/moving. */
620 650 static void static void
621 651 cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], int move, cpmv_file_in_bg(ops_t *ops, const char src[], const char dst[], int move,
File tests/fileops/cpmv_files.c changed (mode: 100644) (index b50fc698a..9a5466a2c)
17 17 #include "../../src/utils/macros.h" #include "../../src/utils/macros.h"
18 18 #include "../../src/utils/path.h" #include "../../src/utils/path.h"
19 19 #include "../../src/utils/str.h" #include "../../src/utils/str.h"
20 #include "../../src/background.h"
20 21 #include "../../src/filelist.h" #include "../../src/filelist.h"
21 22 #include "../../src/fops_cpmv.h" #include "../../src/fops_cpmv.h"
22 23 #include "../../src/trash.h" #include "../../src/trash.h"
 
... ... SETUP()
36 37 saved_cwd); saved_cwd);
37 38 lwin.list_rows = 1; lwin.list_rows = 1;
38 39 lwin.list_pos = 0; lwin.list_pos = 0;
39 lwin.dir_entry = dynarray_cextend(NULL,
40 lwin.list_rows*sizeof(*lwin.dir_entry));
40 /* An extra item is to simplify test that needs two files. */
41 lwin.dir_entry = dynarray_cextend(NULL, 2*sizeof(*lwin.dir_entry));
41 42 lwin.dir_entry[0].name = strdup("file"); lwin.dir_entry[0].name = strdup("file");
42 43 lwin.dir_entry[0].origin = &lwin.curr_dir[0]; lwin.dir_entry[0].origin = &lwin.curr_dir[0];
43 44
 
... ... TEST(can_skip_existing_files)
499 500 } }
500 501 } }
501 502
503 TEST(bg_jog_has_correct_title)
504 {
505 make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), SANDBOX_PATH, "dir",
506 saved_cwd);
507
508 create_dir("dir");
509 create_file("dir/file");
510 create_file("dir/file2");
511
512 lwin.dir_entry[0].marked = 1;
513
514 lwin.list_rows = 2;
515 lwin.dir_entry[1].name = strdup("file2");
516 lwin.dir_entry[1].origin = &lwin.curr_dir[0];
517 lwin.dir_entry[1].marked = 1;
518
519 char last_src_file[PATH_MAX + 1];
520 make_abs_path(last_src_file, sizeof(last_src_file), SANDBOX_PATH, "dir/file2",
521 saved_cwd);
522
523 char descr[PATH_MAX + 1];
524 snprintf(descr, sizeof(descr), "2/2 %s", last_src_file);
525
526 wait_for_all_bg();
527 (void)fops_cpmv_bg(&lwin, NULL, 0, CMLO_COPY, CMLF_SKIP);
528 wait_for_bg();
529 assert_string_equal(descr, bg_jobs->bg_op.descr);
530
531 remove_file("file");
532 remove_file("file2");
533 remove_file("dir/file");
534 remove_file("dir/file2");
535 remove_dir("dir");
536 }
537
502 538 TEST(broken_link_behaves_like_a_regular_file_on_conflict, IF(not_windows)) TEST(broken_link_behaves_like_a_regular_file_on_conflict, IF(not_windows))
503 539 { {
504 540 make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), SANDBOX_PATH, "src", make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), SANDBOX_PATH, "src",
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master