https://midnight-commander.org/ticket/3165
Интересно, почему этот патч не приняли?
Я его адаптировал для современной версии mc:
diff -rU 3 a/lib/util.c b/lib/util.c
--- a/lib/util.c 2019-10-13 18:40:47.000000000 +0000
+++ b/lib/util.c 2019-11-08 14:56:06.000000000 +0000
@@ -415,7 +415,8 @@
*/
void
-size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si)
+size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si,
+ gboolean human_readable)
{
/* Avoid taking power for every file. */
/* *INDENT-OFF* */
@@ -456,6 +457,8 @@
static const char *const suffix_lc[] = { "", "k", "m", "g", "t", "p", "e", "z", "y", NULL };
const char *const *sfx = use_si ? suffix_lc : suffix;
+ unsigned base = use_si ? 1000 : 1024;
+ unsigned human_digits;
int j = 0;
if (len == 0)
@@ -486,6 +489,9 @@
size += size_remain; /* Re-add remainder lost by division/multiplication */
}
+ if (human_readable && len < 5)
+ human_readable = FALSE; /* Human readable form needs 5 characters */
+
for (j = units; sfx[j] != NULL; j++)
{
if (size == 0)
@@ -503,11 +509,28 @@
break;
}
- if (size < power10[len - (j > 0 ? 1 : 0)])
+#define DIV_ROUND(a, b) (((a) + ((b)/2))/(b))
+ if ((!human_readable && size < power10[len - (j > 0 ? 1 : 0)]) ||
+ (human_readable && size < 1000))
+ {
+ g_snprintf (buffer, len + 1, "%" PRIuMAX "%s", size, sfx[j]);
+ break;
+ }
+ else if (human_readable && DIV_ROUND (size, 10) < base && sfx[j + 1])
+ {
+ human_digits = DIV_ROUND (size, 10) * 1000 / base; /* 0 - 999 */
+ g_snprintf (buffer, len + 1, "%u.%02u%s",
+ human_digits / 100, human_digits % 100, sfx[j + 1]);
+ break;
+ }
+ else if (human_readable && DIV_ROUND (size, 100) < base && sfx[j + 1])
{
- g_snprintf (buffer, len + 1, "%" PRIuMAX "%s", size, sfx[j]);
+ human_digits = DIV_ROUND (size, 100) * 1000 / base; /* 0 - 999 */
+ g_snprintf (buffer, len + 1, "%u.%01u%s",
+ human_digits / 10, human_digits % 10, sfx[j + 1]);
break;
}
+#undef DIV_ROUND
/* Powers of 1000 or 1024, with rounding. */
if (use_si)
diff -rU 3 a/lib/util.h b/lib/util.h
--- a/lib/util.h 2019-10-13 18:40:47.000000000 +0000
+++ b/lib/util.h 2019-11-08 14:57:06.000000000 +0000
@@ -154,7 +154,7 @@
* not including trailing 0. BUFFER should be at least LEN+1 long.
*
* Units: size units (0=bytes, 1=Kbytes, 2=Mbytes, etc.) */
-void size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si);
+void size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si, gboolean human_readable);
const char *string_perm (mode_t mode_bits);
const char *extension (const char *);
diff -rU 3 a/src/filemanager/boxes.c b/src/filemanager/boxes.c
--- a/src/filemanager/boxes.c 2019-10-13 18:40:47.000000000 +0000
+++ b/src/filemanager/boxes.c 2019-11-08 14:57:59.000000000 +0000
@@ -646,6 +646,7 @@
QUICK_START_GROUPBOX (N_("Main options")),
QUICK_CHECKBOX (N_("Show mi&ni-status"), &panels_options.show_mini_info, NULL),
QUICK_CHECKBOX (N_("Use SI si&ze units"), &panels_options.kilobyte_si, NULL),
+ QUICK_CHECKBOX (N_("Human readable &size"), &panels_options.human_readable, NULL),
QUICK_CHECKBOX (N_("Mi&x all files"), &panels_options.mix_all_files, NULL),
QUICK_CHECKBOX (N_("Show &backup files"), &panels_options.show_backups, NULL),
QUICK_CHECKBOX (N_("Show &hidden files"), &panels_options.show_dot_files, NULL),
diff -rU 3 a/src/filemanager/chown.c b/src/filemanager/chown.c
--- a/src/filemanager/chown.c 2019-10-13 18:40:47.000000000 +0000
+++ b/src/filemanager/chown.c 2019-11-08 14:58:34.000000000 +0000
@@ -438,7 +438,7 @@
chown_label (0, str_trunc (fname, GW - 4));
chown_label (1, str_trunc (get_owner (sf_stat.st_uid), GW - 4));
chown_label (2, str_trunc (get_group (sf_stat.st_gid), GW - 4));
- size_trunc_len (buffer, GW - 4, sf_stat.st_size, 0, panels_options.kilobyte_si);
+ size_trunc_len (buffer, GW - 4, sf_stat.st_size, 0, panels_options.kilobyte_si, panels_options.human_readable);
chown_label (3, buffer);
chown_label (4, string_perm (sf_stat.st_mode));
diff -rU 3 a/src/filemanager/filegui.c b/src/filemanager/filegui.c
--- a/src/filemanager/filegui.c 2019-10-13 18:40:47.000000000 +0000
+++ b/src/filemanager/filegui.c 2019-11-08 15:03:18.000000000 +0000
@@ -524,7 +524,7 @@
vfs_path_free (p);
g_free (s1);
/* new file size */
- size_trunc_len (s2, sizeof (s2), ui->src_stat->st_size, 0, panels_options.kilobyte_si);
+ size_trunc_len (s2, sizeof (s2), ui->src_stat->st_size, 0, panels_options.kilobyte_si, panels_options.human_readable);
NEW_LABEL (2, s2);
/* new file modification date & time */
s1 = (char *) file_date (ui->src_stat->st_mtime);
@@ -539,7 +539,7 @@
vfs_path_free (p);
g_free (s1);
/* existing file size */
- size_trunc_len (s2, sizeof (s2), ui->dst_stat->st_size, 0, panels_options.kilobyte_si);
+ size_trunc_len (s2, sizeof (s2), ui->dst_stat->st_size, 0, panels_options.kilobyte_si, panels_options.human_readable);
NEW_LABEL (6, s2);
/* existing file modification date & time */
s1 = (char *) file_date (ui->dst_stat->st_mtime);
@@ -1090,13 +1090,13 @@
if (ui->total_bytes_label != NULL)
{
- size_trunc_len (buffer2, 5, tctx->copied_bytes, 0, panels_options.kilobyte_si);
+ size_trunc_len (buffer2, 5, tctx->copied_bytes, 0, panels_options.kilobyte_si, panels_options.human_readable);
if (!ctx->progress_totals_computed)
g_snprintf (buffer, sizeof (buffer), _(" Total: %s "), buffer2);
else
{
- size_trunc_len (buffer3, 5, ctx->progress_bytes, 0, panels_options.kilobyte_si);
+ size_trunc_len (buffer3, 5, ctx->progress_bytes, 0, panels_options.kilobyte_si, panels_options.human_readable);
g_snprintf (buffer, sizeof (buffer), _(" Total: %s/%s "), buffer2, buffer3);
}
diff -rU 3 a/src/filemanager/info.c b/src/filemanager/info.c
--- a/src/filemanager/info.c 2019-10-13 18:40:47.000000000 +0000
+++ b/src/filemanager/info.c 2019-11-08 15:03:49.000000000 +0000
@@ -178,8 +178,8 @@
{
char buffer1[6], buffer2[6];
- size_trunc_len (buffer1, 5, myfs_stats.avail, 1, panels_options.kilobyte_si);
- size_trunc_len (buffer2, 5, myfs_stats.total, 1, panels_options.kilobyte_si);
+ size_trunc_len (buffer1, 5, myfs_stats.avail, 1, panels_options.kilobyte_si, panels_options.human_readable);
+ size_trunc_len (buffer2, 5, myfs_stats.total, 1, panels_options.kilobyte_si, panels_options.human_readable);
tty_printf (_("Free space: %s/%s (%d%%)"), buffer1, buffer2,
myfs_stats.total == 0 ? 0 :
(int) (100 * (long double) myfs_stats.avail / myfs_stats.total));
@@ -237,7 +237,7 @@
#endif
{
char buffer[10];
- size_trunc_len (buffer, 9, st.st_size, 0, panels_options.kilobyte_si);
+ size_trunc_len (buffer, 9, st.st_size, 0, panels_options.kilobyte_si, panels_options.human_readable);
tty_printf (_("Size: %s"), buffer);
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
tty_printf (ngettext (" (%lu block)", " (%lu blocks)",
diff -rU 3 a/src/filemanager/panel.c b/src/filemanager/panel.c
--- a/src/filemanager/panel.c 2019-10-13 18:40:47.000000000 +0000
+++ b/src/filemanager/panel.c 2019-11-08 15:04:16.000000000 +0000
@@ -515,7 +515,7 @@
format_device_number (buffer, len + 1, fe->st.st_rdev);
else
#endif
- size_trunc_len (buffer, (unsigned int) len, fe->st.st_size, 0, panels_options.kilobyte_si);
+ size_trunc_len (buffer, (unsigned int) len, fe->st.st_size, 0, panels_options.kilobyte_si, panels_options.human_readable);
return buffer;
}
@@ -1157,9 +1157,9 @@
char buffer1[6], buffer2[6], tmp[BUF_SMALL];
size_trunc_len (buffer1, sizeof (buffer1) - 1, myfs_stats.avail, 1,
- panels_options.kilobyte_si);
+ panels_options.kilobyte_si, panels_options.human_readable);
size_trunc_len (buffer2, sizeof (buffer2) - 1, myfs_stats.total, 1,
- panels_options.kilobyte_si);
+ panels_options.kilobyte_si, panels_options.human_readable);
g_snprintf (tmp, sizeof (tmp), " %s/%s (%d%%) ", buffer1, buffer2,
myfs_stats.total == 0 ? 0 :
(int) (100 * (long double) myfs_stats.avail / myfs_stats.total));
diff -rU 3 a/src/setup.c b/src/setup.c
--- a/src/setup.c 2019-10-13 18:40:47.000000000 +0000
+++ b/src/setup.c 2019-11-08 18:25:32.000000000 +0000
@@ -131,6 +131,7 @@
panels_options_t panels_options = {
.show_mini_info = TRUE,
.kilobyte_si = FALSE,
+ .human_readable = FALSE,
.mix_all_files = FALSE,
.show_backups = TRUE,
.show_dot_files = TRUE,
@@ -410,6 +411,7 @@
} panels_ini_options[] = {
{ "show_mini_info", &panels_options.show_mini_info },
{ "kilobyte_si", &panels_options.kilobyte_si },
+ { "human_readable", &panels_options.human_readable },
{ "mix_all_files", &panels_options.mix_all_files },
{ "show_backups", &panels_options.show_backups },
{ "show_dot_files", &panels_options.show_dot_files },
diff -rU 3 a/src/setup.h b/src/setup.h
--- a/src/setup.h 2019-10-13 18:40:47.000000000 +0000
+++ b/src/setup.h 2019-11-08 15:05:51.000000000 +0000
@@ -37,6 +37,7 @@
gboolean show_mini_info; /* If true, show the mini-info on the panel */
gboolean kilobyte_si; /* If TRUE, SI units (1000 based) will be used for larger units
* (kilobyte, megabyte, ...). If FALSE, binary units (1024 based) will be used */
+ gboolean human_readable; /* If TRUE, at most three digits are used to display the size of the files. */
gboolean mix_all_files; /* If FALSE then directories are shown separately from files */
gboolean show_backups; /* If TRUE, show files ending in ~ */
gboolean show_dot_files; /* If TRUE, show files starting with a dot */
diff -rU 3 a/src/viewer/display.c b/src/viewer/display.c
--- a/src/viewer/display.c 2019-10-13 18:40:47.000000000 +0000
+++ b/src/viewer/display.c 2019-11-08 15:06:24.000000000 +0000
@@ -172,7 +172,7 @@
char buffer[BUF_TRUNC_LEN + 1];
size_trunc_len (buffer, BUF_TRUNC_LEN, mcview_get_filesize (view), 0,
- panels_options.kilobyte_si);
+ panels_options.kilobyte_si, panels_options.human_readable);
tty_printf ("%9" PRIuMAX "/%s%s %s", (uintmax_t) view->dpy_end,
buffer, mcview_may_still_grow (view) ? "+" : " ",
#ifdef HAVE_CHARSET
В настройках панели выбираешь опцию «human readable size», работает, на первый взгляд, нормально: https://i.imgur.com/WwthIt7.png