Optional space and unit in `file-size-human-readable' (bug#35756)
To improve readability of strings produced by `file-size-human-readable', add two optional arguments: - SPACE, to provide a string (typically a space or non-breaking space) to put between the number and unit. For compatibility, the default is an empty string. - UNIT, a string to use as unit. For compatibility, the default is "B" in `iec' mode and the empty string otherwise. Also fix a glitch with small numbers in `iec' mode which caused a stray "i" in the result. * lisp/files.el (file-size-human-readable): Add optional SPACE and UNIT arguments and handle small numbers correctly. (files--ask-user-about-large-file, warn-maybe-out-of-memory): Call with `iec' and space. * test/lisp/files-tests.el (files-test-file-size-human-readable): New test. * lisp/url/url-http.el (url-http-simple-after-change-function) (url-http-content-length-after-change-function): Call with `iec' and space. * etc/NEWS (Lisp Changes): Mention the change.
This commit is contained in:
parent
b439b3bb5a
commit
866f527ddf
4 changed files with 69 additions and 23 deletions
9
etc/NEWS
9
etc/NEWS
|
@ -2163,6 +2163,15 @@ The functions 'base64-decode-string' and 'base64-decode-region' now
|
|||
accept an optional argument to decode the URL variant of base-64
|
||||
encoding.
|
||||
|
||||
+++
|
||||
** The function 'file-size-human-readable' accepts more optional arguments.
|
||||
The new third argument is a string put between the number and unit; it
|
||||
defaults to the empty string. The new fourth argument is a string
|
||||
representing the unit to use; it defaults to "B" when the second
|
||||
argument is 'iec' and the empty string otherwise. We recomment a
|
||||
space or non-breaking space as third argument, and "B" as fourth
|
||||
argument, circumstances allowing.
|
||||
|
||||
|
||||
* Changes in Emacs 27.1 on Non-Free Operating Systems
|
||||
|
||||
|
|
|
@ -1358,7 +1358,7 @@ it means chase no more than that many links and then stop."
|
|||
|
||||
;; A handy function to display file sizes in human-readable form.
|
||||
;; See http://en.wikipedia.org/wiki/Kibibyte for the reference.
|
||||
(defun file-size-human-readable (file-size &optional flavor)
|
||||
(defun file-size-human-readable (file-size &optional flavor space unit)
|
||||
"Produce a string showing FILE-SIZE in human-readable form.
|
||||
|
||||
Optional second argument FLAVOR controls the units and the display format:
|
||||
|
@ -1368,24 +1368,36 @@ Optional second argument FLAVOR controls the units and the display format:
|
|||
If FLAVOR is `si', each kilobyte is 1000 bytes and the produced suffixes
|
||||
are \"k\", \"M\", \"G\", \"T\", etc.
|
||||
If FLAVOR is `iec', each kilobyte is 1024 bytes and the produced suffixes
|
||||
are \"KiB\", \"MiB\", \"GiB\", \"TiB\", etc."
|
||||
are \"KiB\", \"MiB\", \"GiB\", \"TiB\", etc.
|
||||
|
||||
Optional third argument SPACE is a string put between the number and unit.
|
||||
It defaults to the empty string. We recommend a single space or
|
||||
non-breaking space, unless other constraints prohibit a space in that
|
||||
position.
|
||||
|
||||
Optional fourth argument UNIT is the unit to use. It defaults to \"B\"
|
||||
when FLAVOR is `iec' and the empty string otherwise. We recommend \"B\"
|
||||
in all cases, since that is the standard symbol for byte."
|
||||
(let ((power (if (or (null flavor) (eq flavor 'iec))
|
||||
1024.0
|
||||
1000.0))
|
||||
(post-fixes
|
||||
;; none, kilo, mega, giga, tera, peta, exa, zetta, yotta
|
||||
(list "" "k" "M" "G" "T" "P" "E" "Z" "Y")))
|
||||
(while (and (>= file-size power) (cdr post-fixes))
|
||||
(prefixes '("" "k" "M" "G" "T" "P" "E" "Z" "Y")))
|
||||
(while (and (>= file-size power) (cdr prefixes))
|
||||
(setq file-size (/ file-size power)
|
||||
post-fixes (cdr post-fixes)))
|
||||
(format (if (> (mod file-size 1.0) 0.05)
|
||||
"%.1f%s%s"
|
||||
"%.0f%s%s")
|
||||
file-size
|
||||
(if (and (eq flavor 'iec) (string= (car post-fixes) "k"))
|
||||
"K"
|
||||
(car post-fixes))
|
||||
(if (eq flavor 'iec) "iB" ""))))
|
||||
prefixes (cdr prefixes)))
|
||||
(let* ((prefix (car prefixes))
|
||||
(prefixed-unit (if (eq flavor 'iec)
|
||||
(concat
|
||||
(if (string= prefix "k") "K" prefix)
|
||||
(if (string= prefix "") "" "i")
|
||||
(or unit "B"))
|
||||
(concat prefix unit))))
|
||||
(format (if (> (mod file-size 1.0) 0.05)
|
||||
"%.1f%s%s"
|
||||
"%.0f%s%s")
|
||||
file-size
|
||||
(if (string-empty-p prefixed-unit) "" (or space ""))
|
||||
prefixed-unit))))
|
||||
|
||||
(defcustom mounted-file-systems
|
||||
(if (memq system-type '(windows-nt cygwin))
|
||||
|
@ -2054,7 +2066,7 @@ think it does, because \"free\" is pretty hard to define in practice."
|
|||
(defun files--ask-user-about-large-file (size op-type filename offer-raw)
|
||||
(let ((prompt (format "File %s is large (%s), really %s?"
|
||||
(file-name-nondirectory filename)
|
||||
(file-size-human-readable size) op-type)))
|
||||
(file-size-human-readable size 'iec " ") op-type)))
|
||||
(if (not offer-raw)
|
||||
(if (y-or-n-p prompt) nil 'abort)
|
||||
(let* ((use-dialog (and (display-popup-menus-p)
|
||||
|
@ -2106,9 +2118,10 @@ returns nil or exits non-locally."
|
|||
exceeds the %S%% of currently available free memory (%s).
|
||||
If that fails, try to open it with `find-file-literally'
|
||||
\(but note that some characters might be displayed incorrectly)."
|
||||
(file-size-human-readable size)
|
||||
(file-size-human-readable size 'iec " ")
|
||||
out-of-memory-warning-percentage
|
||||
(file-size-human-readable (* total-free-memory 1024)))))))))
|
||||
(file-size-human-readable (* total-free-memory 1024)
|
||||
'iec " "))))))))
|
||||
|
||||
(defun files--message (format &rest args)
|
||||
"Like `message', except sometimes don't print to minibuffer.
|
||||
|
|
|
@ -1016,7 +1016,8 @@ should be shown to the user."
|
|||
(defun url-http-simple-after-change-function (_st _nd _length)
|
||||
;; Function used when we do NOT know how long the document is going to be
|
||||
;; Just _very_ simple 'downloaded %d' type of info.
|
||||
(url-lazy-message "Reading %s..." (file-size-human-readable (buffer-size))))
|
||||
(url-lazy-message "Reading %s..."
|
||||
(file-size-human-readable (buffer-size) 'iec " ")))
|
||||
|
||||
(defun url-http-content-length-after-change-function (_st nd _length)
|
||||
"Function used when we DO know how long the document is going to be.
|
||||
|
@ -1029,16 +1030,16 @@ the callback to be triggered."
|
|||
(url-percentage (- nd url-http-end-of-headers)
|
||||
url-http-content-length)
|
||||
url-http-content-type
|
||||
(file-size-human-readable (- nd url-http-end-of-headers))
|
||||
(file-size-human-readable url-http-content-length)
|
||||
(file-size-human-readable (- nd url-http-end-of-headers) 'iec " ")
|
||||
(file-size-human-readable url-http-content-length 'iec " ")
|
||||
(url-percentage (- nd url-http-end-of-headers)
|
||||
url-http-content-length))
|
||||
(url-display-percentage
|
||||
"Reading... %s of %s (%d%%)"
|
||||
(url-percentage (- nd url-http-end-of-headers)
|
||||
url-http-content-length)
|
||||
(file-size-human-readable (- nd url-http-end-of-headers))
|
||||
(file-size-human-readable url-http-content-length)
|
||||
(file-size-human-readable (- nd url-http-end-of-headers) 'iec " ")
|
||||
(file-size-human-readable url-http-content-length 'iec " ")
|
||||
(url-percentage (- nd url-http-end-of-headers)
|
||||
url-http-content-length)))
|
||||
|
||||
|
|
|
@ -1259,5 +1259,28 @@ renaming only, rather than modified in-place."
|
|||
(ignore-errors (advice-remove #'write-region advice))
|
||||
(ignore-errors (delete-file temp-file-name)))))
|
||||
|
||||
(ert-deftest files-test-file-size-human-readable ()
|
||||
(should (equal (file-size-human-readable 13) "13"))
|
||||
(should (equal (file-size-human-readable 13 'si) "13"))
|
||||
(should (equal (file-size-human-readable 13 'iec) "13B"))
|
||||
(should (equal (file-size-human-readable 10000) "9.8k"))
|
||||
(should (equal (file-size-human-readable 10000 'si) "10k"))
|
||||
(should (equal (file-size-human-readable 10000 'iec) "9.8KiB"))
|
||||
(should (equal (file-size-human-readable 4294967296 nil) "4G"))
|
||||
(should (equal (file-size-human-readable 4294967296 'si) "4.3G"))
|
||||
(should (equal (file-size-human-readable 4294967296 'iec) "4GiB"))
|
||||
(should (equal (file-size-human-readable 13 nil " ") "13"))
|
||||
(should (equal (file-size-human-readable 13 'si " ") "13"))
|
||||
(should (equal (file-size-human-readable 13 'iec " ") "13 B"))
|
||||
(should (equal (file-size-human-readable 10000 nil " ") "9.8 k"))
|
||||
(should (equal (file-size-human-readable 10000 'si " ") "10 k"))
|
||||
(should (equal (file-size-human-readable 10000 'iec " ") "9.8 KiB"))
|
||||
(should (equal (file-size-human-readable 4294967296 nil " ") "4 G"))
|
||||
(should (equal (file-size-human-readable 4294967296 'si " ") "4.3 G"))
|
||||
(should (equal (file-size-human-readable 4294967296 'iec " ") "4 GiB"))
|
||||
(should (equal (file-size-human-readable 10000 nil " " "bit") "9.8 kbit"))
|
||||
(should (equal (file-size-human-readable 10000 'si " " "bit") "10 kbit"))
|
||||
(should (equal (file-size-human-readable 10000 'iec " " "bit") "9.8 Kibit")))
|
||||
|
||||
(provide 'files-tests)
|
||||
;;; files-tests.el ends here
|
||||
|
|
Loading…
Add table
Reference in a new issue