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 775e904bbd5d937ad970caae0b51101dc5d8d8d4

Introduce and use utils/str:psuffix(int count)
Retrieves a suffix for a plural depending on the number of something.
Returns either "" or "s" (so only the trivial case).
Author: xaizek
Author date (UTC): 2025-07-22 17:59
Committer name: xaizek
Committer date (UTC): 2025-07-22 17:59
Parent(s): d9e492e70b6046104696d81336353bc6665299a0
Signing key: 99DC5E4DB05F6BE2
Tree: 9e110db02f2349c43fd2df66b34fe68b8d98908d
File Lines added Lines deleted
src/fops_cpmv.c 1 1
src/fops_misc.c 7 8
src/fops_put.c 1 1
src/fops_rename.c 4 4
src/search.c 1 1
src/ui/quickview.c 1 1
src/utils/str.c 6 0
src/utils/str.h 4 0
File src/fops_cpmv.c changed (mode: 100644) (index c6b609981..ec0ada4e3)
... ... fops_cpmv(view_t *view, char *list[], int nlines, CopyMoveLikeOp op, int flags)
208 208 } }
209 209
210 210 ui_sb_msgf("%d item%s successfully processed%s", ops->succeeded, ui_sb_msgf("%d item%s successfully processed%s", ops->succeeded,
211 (ops->succeeded == 1) ? "" : "s", fops_get_cancellation_suffix());
211 psuffix(ops->succeeded), fops_get_cancellation_suffix());
212 212
213 213 fops_free_ops(ops); fops_free_ops(ops);
214 214
File src/fops_misc.c changed (mode: 100644) (index 234c38f86..73db1a73d)
... ... fops_yank(view_t *view, int reg)
472 472
473 473 regs_update_unnamed(reg); regs_update_unnamed(reg);
474 474
475 ui_sb_msgf("%d item%s yanked", nyanked_files,
476 (nyanked_files == 1) ? "" : "s");
475 ui_sb_msgf("%d item%s yanked", nyanked_files, psuffix(nyanked_files));
477 476
478 477 regs_sync_to_shared_memory(); regs_sync_to_shared_memory();
479 478
 
... ... retarget_many(view_t *view, char *files[], int nfiles)
712 711
713 712 un_group_close(); un_group_close();
714 713
715 ui_sb_msgf("%d link%s retargeted%s", ops->succeeded,
716 (ops->succeeded == 1) ? "" : "s", fops_get_cancellation_suffix());
714 ui_sb_msgf("%d link%s retargeted%s", ops->succeeded, psuffix(ops->succeeded),
715 fops_get_cancellation_suffix());
717 716
718 717 fops_free_ops(ops); fops_free_ops(ops);
719 718
 
... ... fops_clone(view_t *view, char *list[], int nlines, int force, int copies)
892 891 free_string_array(list, nlines); free_string_array(list, nlines);
893 892 } }
894 893
895 ui_sb_msgf("%d item%s cloned%s", ops->succeeded,
896 (ops->succeeded == 1) ? "" : "s", fops_get_cancellation_suffix());
894 ui_sb_msgf("%d item%s cloned%s", ops->succeeded, psuffix(ops->succeeded),
895 fops_get_cancellation_suffix());
897 896
898 897 fops_free_ops(ops); fops_free_ops(ops);
899 898 return 1; return 1;
 
... ... fops_mkfiles(view_t *view, int at, char *names[], int count)
1129 1128 go_to_first_file(view, names, count); go_to_first_file(view, names, count);
1130 1129 } }
1131 1130
1132 ui_sb_msgf("%d item%s created%s", n, (n == 1) ? "" : "s",
1131 ui_sb_msgf("%d item%s created%s", n, psuffix(n),
1133 1132 fops_get_cancellation_suffix()); fops_get_cancellation_suffix());
1134 1133
1135 1134 fops_free_ops(ops); fops_free_ops(ops);
 
... ... fops_chown(int u, int g, uid_t uid, gid_t gid)
1445 1444 un_group_close(); un_group_close();
1446 1445
1447 1446 ui_sb_msgf("%d item%s fully processed%s", ops->succeeded, ui_sb_msgf("%d item%s fully processed%s", ops->succeeded,
1448 (ops->succeeded == 1) ? "" : "s", fops_get_cancellation_suffix());
1447 psuffix(ops->succeeded), fops_get_cancellation_suffix());
1449 1448 fops_free_ops(ops); fops_free_ops(ops);
1450 1449
1451 1450 ui_view_reset_selection_and_reload(view); ui_view_reset_selection_and_reload(view);
File src/fops_put.c changed (mode: 100644) (index 182fe3ded..5e854f5ab)
... ... put_files_i(view_t *view, int start)
495 495 regs_pack(put_confirm.reg->name); regs_pack(put_confirm.reg->name);
496 496 update_cursor_position(view); update_cursor_position(view);
497 497 ui_sb_msgf("%d item%s inserted%s", put_confirm.processed, ui_sb_msgf("%d item%s inserted%s", put_confirm.processed,
498 (put_confirm.processed == 1) ? "" : "s", fops_get_cancellation_suffix());
498 psuffix(put_confirm.processed), fops_get_cancellation_suffix());
499 499
500 500 return 1; return 1;
501 501 } }
File src/fops_rename.c changed (mode: 100644) (index f141710a6..3ef03e8b3)
... ... fops_rename(view_t *view, char *list[], int nlines, int recursive)
216 216 const int renamed = perform_renaming(view, files, is_dup, nfiles, list); const int renamed = perform_renaming(view, files, is_dup, nfiles, list);
217 217 if(renamed >= 0) if(renamed >= 0)
218 218 { {
219 ui_sb_msgf("%d item%s renamed", renamed, (renamed == 1) ? "" : "s");
219 ui_sb_msgf("%d item%s renamed", renamed, psuffix(renamed));
220 220 } }
221 221
222 222 flist_sel_stash(view); flist_sel_stash(view);
 
... ... verify_list(char *files[], int nfiles, char *names[], int nnames, char **error,
287 287 } }
288 288 else if(moves > 0) else if(moves > 0)
289 289 { {
290 const char *suffix = (moves == 1 ? "" : "s");
290 const char *suffix = psuffix(moves);
291 291 /* Stray space prevents removal of the line. */ /* Stray space prevents removal of the line. */
292 292 if(!prompt_msgf("Rename", if(!prompt_msgf("Rename",
293 293 "It appears that the rename list has %d move%s, which could have " "It appears that the rename list has %d move%s, which could have "
 
... ... fops_incdec(view_t *view, int k)
586 586 } }
587 587 else if(err == 0) else if(err == 0)
588 588 { {
589 ui_sb_msgf("%d item%s renamed", nrenamed, (nrenamed == 1) ? "" : "s");
589 ui_sb_msgf("%d item%s renamed", nrenamed, psuffix(nrenamed));
590 590 } }
591 591
592 592 return 1; return 1;
 
... ... rename_marked(view_t *view, const char desc[], const char lhs[],
944 944 ui_view_schedule_redraw(view); ui_view_schedule_redraw(view);
945 945 } }
946 946
947 ui_sb_msgf("%d item%s renamed", nrenamed, (nrenamed == 1) ? "" : "s");
947 ui_sb_msgf("%d item%s renamed", nrenamed, psuffix(nrenamed));
948 948 return 1; return 1;
949 949 } }
950 950
File src/search.c changed (mode: 100644) (index 22cc44ccf..ae19438a7)
... ... print_search_msg(const view_t *view, int backward)
318 318 { {
319 319 ui_sb_msgf("%d of %d matching item%s for: %s", ui_sb_msgf("%d of %d matching item%s for: %s",
320 320 get_current_entry(view)->search_match, view->matches, get_current_entry(view)->search_match, view->matches,
321 (view->matches == 1) ? "" : "s", hists_search_last());
321 psuffix(view->matches), hists_search_last());
322 322 } }
323 323 } }
324 324
File src/ui/quickview.c changed (mode: 100644) (index 05fc982a7..6bb8e8f40)
... ... print_tree_stats(tree_print_state_t *s)
512 512 fprintf(s->fp, "%s%d director%s, %d file%s\n", fprintf(s->fp, "%s%d director%s, %d file%s\n",
513 513 ui_cancellation_requested() ? "(cancelled)\n" : "", ui_cancellation_requested() ? "(cancelled)\n" : "",
514 514 s->ndirs, (s->ndirs == 1) ? "y" : "ies", s->ndirs, (s->ndirs == 1) ? "y" : "ies",
515 s->nfiles, (s->nfiles == 1) ? "" : "s");
515 s->nfiles, psuffix(s->nfiles));
516 516 } }
517 517
518 518 /* Produces tree preview of the path. Returns non-zero to request stopping of /* Produces tree preview of the path. Returns non-zero to request stopping of
File src/utils/str.c changed (mode: 100644) (index 264899790..a3bf7b1e3)
... ... str_is_ascii(const char str[])
1275 1275 return 1; return 1;
1276 1276 } }
1277 1277
1278 const char *
1279 psuffix(int count)
1280 {
1281 return (count == 1 ? "" : "s");
1282 }
1283
1278 1284 #ifndef HAVE_STRCASESTR #ifndef HAVE_STRCASESTR
1279 1285
1280 1286 char * char *
File src/utils/str.h changed (mode: 100644) (index 8a54b84b6..3312b1b09)
... ... char * double_char(const char str[], char c);
367 367 * so. */ * so. */
368 368 int str_is_ascii(const char str[]); int str_is_ascii(const char str[]);
369 369
370 /* Retrieves a suffix for a plural depending on the number of something.
371 * Returns either "" or "s". */
372 const char * psuffix(int count);
373
370 374 #ifndef HAVE_STRCASESTR #ifndef HAVE_STRCASESTR
371 375
372 376 /* Same as strstr(), but in case insensitive way. */ /* Same as strstr(), but in case insensitive way. */
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