Форматирование целого числа с использованием префиксов ISO для кБ, МБ, ГБ, ... и КБ, MiB, GiB, - PullRequest
2 голосов
/ 07 апреля 2011

Я ищу функцию, которая печатает размер файла в строке состояния в режиме индикации размера. Я искал режим индикации размера в источнике, но не могу найти ссылки на код. Так, где функция, которая печатает, например, 22k

когда размер файла составляет около 22 килобайт?

Как насчет разницы между - килобайт (кБ), 1000 байтов и - кибибайт (КиБ), 1024 байта, как определено в

Разве Emacs не должен поддерживать оба?

Это, конечно, не так сложно написать, но зачем изобретать велосипед?

http://en.wikipedia.org/wiki/Kibibyte

Ответы [ 4 ]

3 голосов
/ 07 апреля 2011

См. Ch f format-mode-line RET и Ch v mode-line-format RET .

Включение size-indication-mode просто приводит к добавлению of %I в строку локального формата строки режима буфера, а функция C позаботится об остальном.

Вместо этого вы можете использовать %i, чтобы увидеть размер буфера в байтах.

Если вы хотите что-то, для чего вы можете указать произвольное значение, то по крайней мере одна функция elisp вдоль этих строк предоставляется Emacs (в ls-lisp модуль):

Ch f ls-lisp-format-file-size RET

2 голосов
/ 13 апреля 2011

Вот функция, которую я использую.

(defconst number-to-string-approx-suffixes
  '("k" "M" "G" "T" "P" "E" "Z" "Y"))
(defun number-to-string-approx-suffix (n &optional binary)
  "Return an approximate decimal representation of NUMBER as a string,
followed by a multiplier suffix (k, M, G, T, P, E, Z, Y). The representation
is at most 5 characters long for numbers between 0 and 10^19-5*10^16.
Uses a minus sign if negative.
NUMBER may be an integer or a floating point number.
If the optional argument BINARY is non-nil, use 1024 instead of 1000 as
the base multiplier."
  (if (zerop n)
      "0"
    (let ((sign "")
          (b (if binary 1024 1000))
          (suffix "")
          (bigger-suffixes number-to-string-approx-suffixes))
      (if (< n 0)
          (setq n (- n)
                sign "-"))
      (while (and (>= n 9999.5) (consp bigger-suffixes))
        (setq n (/ n b) ; TODO: this is rounding down; nearest would be better
              suffix (car bigger-suffixes)
              bigger-suffixes (cdr bigger-suffixes)))
      (concat sign
                  (if (integerp n)
                  (int-to-string n)
                (number-to-string (floor n)))
              suffix))))

Я использую ее в столбце размера меню буфера.

(defvar Buffer-menu-buffer+size-shorten 'binary)
(defadvice Buffer-menu-buffer+size (before Buffer-menu-shorten-size
                                    compile activate)
  "Shorten the size column in a buffer menu by using multiplier suffixes
\(k, M, G, T\).
This is done only if `Buffer-menu-buffer+size-shorten' is non-nil.
If `Buffer-menu-buffer+size-shorten' is the symbol `binary', use binary
multipliers (powers of 1024). Otherwise use decimal (powers of 1000)
multipliers."
  (if Buffer-menu-buffer+size-shorten
      (let ((binary (eq Buffer-menu-buffer+size-shorten 'binary)))
        (save-match-data
          (if (string-match "^[0-9]+$" size)
              (setq size (number-to-string-approx-suffix (string-to-number size)
                                                         binary)))))))
2 голосов
/ 12 апреля 2011

Я заметил, что emacs dev (bzr) просто переходит в новую функцию, определенную file-size-human-readable(). Это именно то, что я просил.

Некоторые разработчики emacs, должно быть, услышали мой звонок:)

0 голосов
/ 07 апреля 2011

Хорошо, я сам взломал решение. Должно быть близко к тому, что size-indication-mode обеспечивает

(defun number-to-iso-postfixed-string (number &optional binary)
  "Convert NUMBER to ISO-postfixed string.
If BINARY is non-nil use bibytes prefixes KiB, MiB, GiB instead of
kB, MB, GB etc."
  (let ((scale (if binary 1024.0 1000.0))
        (postfix nil))
    (concat (if (< number scale)
                (if (zerop number) "0" (number-to-string number))
                (format "%.1f"
                        (cond ((< number (expt scale 2)) (setq postfix "k") (/ number (expt scale 1)))
                              ((< number (expt scale 3)) (setq postfix "M") (/ number (expt scale 2)))
                              ((< number (expt scale 4)) (setq postfix "G") (/ number (expt scale 3)))
                              ((< number (expt scale 5)) (setq postfix "T") (/ number (expt scale 4)))
                              ((< number (expt scale 6)) (setq postfix "P") (/ number (expt scale 5)))
                              ((< number (expt scale 7)) (setq postfix "E") (/ number (expt scale 6)))
                              (t
                               number)
                              )))
            postfix
            (when (and postfix binary) "i"))))
;; Use: (number-to-iso-postfixed-string 999 nil)
;; Use: (number-to-iso-postfixed-string 1001 nil)
;; Use: (number-to-iso-postfixed-string 1024)
;; Use: (number-to-iso-postfixed-string 1024 t)
;; Use: (number-to-iso-postfixed-string (* 1024 1024) t)
;; Use: (number-to-iso-postfixed-string (* 1024 1023) t)
;; Use: (number-to-iso-postfixed-string (* 1024 1025) t)
;; Use: (number-to-iso-postfixed-string (* 1024.0 1024 1025) t)
...