emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Buffer size indicator on the mode line.


From: Lute Kamstra
Subject: Re: Buffer size indicator on the mode line.
Date: Fri, 29 Aug 2003 12:19:09 +0200
User-agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3.50 (gnu/linux)

Richard Stallman <address@hidden> writes:

>     To show the size, I added `(size-indication-mode " %i")' to
>     `mode-line-position' and implemented the `%i'-construct for
>     `mode-line-format'.
>
>     Do you people think this is a nice feature?
>
> I think it is a nice feature, thought it would be better to say
> "19% of 46673" to make it clear what the number means.

Good idea.

> However, given the shortage of mode line space, I think we should not
> turn this on by default.

That's what I had in mind.

I now implemented a human readable version as well (see patch below).
The size indicator now says "19% of 47k" instead.  I stole the
algorithm from gnulib's human.c, written by Paul Eggert and Larry
McVoy.  Is it customary to document such origins?  If yes, how?

I'd appreciate any nit-picking comments on the patch as it's the first
C-thingy I wrote for Emacs.

I'll also document the changes in the Emacs Manual and the Emacs Lisp
Reference Manual.

Regards,

  Lute.


Index: lisp/bindings.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/bindings.el,v
retrieving revision 1.121
diff -c -r1.121 bindings.el
*** lisp/bindings.el    10 Jun 2003 04:06:10 -0000      1.121
--- lisp/bindings.el    29 Aug 2003 09:37:14 -0000
***************
*** 312,317 ****
--- 312,319 ----
  
    (setq-default mode-line-position
      `((-3 . ,(propertize "%p" 'help-echo help-echo))
+       (size-indication-mode 
+        (8 ,(propertize " of %I" 'help-echo help-echo)))
        (line-number-mode
         ((column-number-mode
         (10 ,(propertize " (%l,%c)" 'help-echo help-echo))
Index: lisp/simple.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/simple.el,v
retrieving revision 1.617
diff -c -r1.617 simple.el
*** lisp/simple.el      17 Aug 2003 00:15:53 -0000      1.617
--- lisp/simple.el      29 Aug 2003 09:37:15 -0000
***************
*** 3454,3459 ****
--- 3454,3466 ----
  When Column Number mode is enabled, the column number appears
  in the mode line."
    :global t :group 'editing-basics :require nil)
+ 
+ (define-minor-mode size-indication-mode
+   "Toggle Size Indication mode.
+ With arg, turn Size Indication mode on iff arg is positive.  When
+ Size Indication mode is enabled, the size of the buffer appears
+ in the mode line."
+   :global t :group 'editing-basics :require nil)
  
  (defgroup paren-blinking nil
    "Blinking matching of parens and expressions."
Index: src/buffer.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/buffer.c,v
retrieving revision 1.436
diff -c -r1.436 buffer.c
*** src/buffer.c        19 Aug 2003 12:38:36 -0000      1.436
--- src/buffer.c        29 Aug 2003 09:37:17 -0000
***************
*** 5372,5377 ****
--- 5372,5379 ----
    %c -- print the current column number (this makes editing slower).
          To make the column number update correctly in all cases,
        `column-number-mode' must be non-nil.
+   %i -- print the size of the buffer.
+   %I -- like %i, but use k, M, G, etc., to abbreviate.
    %p -- print percent of buffer above top of window, or Top, Bot or All.
    %P -- print percent of buffer above bottom of window, perhaps plus Top,
          or print Bottom or All.
Index: src/xdisp.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xdisp.c,v
retrieving revision 1.843
diff -c -r1.843 xdisp.c
*** src/xdisp.c 9 Jul 2003 14:51:29 -0000       1.843
--- src/xdisp.c 29 Aug 2003 09:37:23 -0000
***************
*** 772,777 ****
--- 772,778 ----
  
  static int next_element_from_ellipsis P_ ((struct it *));
  static void pint2str P_ ((char *, int, int));
+ static void pint2hrstr P_ ((char *, int, int));
  static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
                                                        struct text_pos));
  static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
***************
*** 15583,15588 ****
--- 15584,15698 ----
      }
  }
  
+ /* Write a null-terminated, right justified decimal and "human
+    readable" representation of the positive integer D to BUF using a
+    minimal field width WIDTH.  */
+ 
+ static const char power_letter[] =
+   {
+     0,         /* not used */
+     'k', /* kilo */
+     'M', /* mega */
+     'G', /* giga */
+     'T', /* tera */
+     'P', /* peta */
+     'E', /* exa */
+     'Z', /* zetta */
+     'Y'        /* yotta */
+   };
+ 
+ static void
+ pint2hrstr (buf, width, d)
+      register char *buf;
+      register int width;
+      register int d;
+ {
+   int base = 1000;
+   int amt = d;
+   int tenths = 0;
+   int exponent = 0;
+   int exponent_max = sizeof power_letter - 1;
+ 
+   char * psuffix = buf + max (width, 4);
+   char * p = psuffix;
+ 
+   /* 0 means D == AMT.TENTHS;
+      1 means AMT.TENTHS < D < AMT.TENTHS + 0.05;
+      2 means D == AMT.TENTHS + 0.05;
+      3 means AMT.TENTHS + 0.05 < D < AMT.TENTHS + 0.1.        */
+   int rounding = 0;
+ 
+   if (base <= amt)
+     {
+       do
+       {
+         int r10 = (amt % base) * 10 + tenths;
+         int r2 = (r10 % base) * 2 + (rounding >> 1);
+         amt /= base;
+         tenths = r10 / base;
+         rounding = (r2 < base
+                     ? (r2 + rounding) != 0
+                     : 2 + (base < r2 + rounding));
+         exponent++;
+       }
+       while (base <= amt && exponent < exponent_max);
+ 
+       if (amt < 10)
+       {
+         if (2 < rounding + (tenths & 1))
+           {
+             tenths++;
+             rounding = 0;
+ 
+             if (tenths == 10)
+               {
+                 amt++;
+                 tenths = 0;
+               }
+           }
+ 
+         if (amt < 10)
+           {
+             *--p = '0' + tenths;
+             *--p = '.';
+             tenths = rounding = 0;
+           }
+       }
+ 
+       if (5 < tenths + (2 < rounding + (amt & 1)))
+       {
+         amt++;
+ 
+         if (amt == base && exponent < exponent_max)
+           {
+             exponent++;
+             *--p = '0';
+             *--p = '.';
+             amt = 1;
+           }
+       }
+     }
+ 
+   do
+     {
+       int digit = amt % 10;
+       *--p =  '0' + digit;
+     }
+   while ((amt /= 10) != 0);
+ 
+   if (exponent)
+     *psuffix++ = power_letter[exponent];
+ 
+   *psuffix++ = '\0';
+ 
+   for (width -= (int) (psuffix - p); width > 0; --width)
+     *--p = ' ';
+ 
+   if (p > buf)
+     while (p < psuffix)
+       *buf++ = *p++;
+ }
+ 
  /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
     If EOL_FLAG is 1, set also a mnemonic character for end-of-line
     type of CODING_SYSTEM.  Return updated pointer into BUF.  */
***************
*** 15784,15789 ****
--- 15894,15913 ----
      case 'f':
        obj = b->filename;
        break;
+ 
+     case 'i':
+       {
+       int size = ZV - BEGV;
+       pint2str (decode_mode_spec_buf, field_width, size);
+       return decode_mode_spec_buf;
+       }
+       
+     case 'I':
+       {
+       int size = ZV - BEGV;
+       pint2hrstr (decode_mode_spec_buf, field_width, size);
+       return decode_mode_spec_buf;
+       }
  
      case 'l':
        {






reply via email to

[Prev in Thread] Current Thread [Next in Thread]