--- a/src/xdisp.c 2016-10-07 15:47:28.000000000 +1300 +++ b/src/xdisp.c 2016-10-07 15:54:31.000000000 +1300 @@ -23810,6 +23813,45 @@ Add %-spec for a mode-line size and position indicator. } } + /* Indicate the relative size and position of the current window. */ + case '~': + { + ptrdiff_t toppos = marker_position (w->start); + ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos; + ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b) + 1; + ptrdiff_t open; + ptrdiff_t close; + int i; + char *p = decode_mode_spec_buf; + + /* It makes little sense to pad with spaces, so use WIDTH to + enable the user to specify the size of the indicator. */ + + if (width < 3) width = 3; /* Set a minimum indicator size. */ + width -= 2; /* Reserve space for open and close marks. */ + + if (total >= 1000000) + /* Do it differently for a large value, to avoid overflow. */ + { + open = ((toppos - BUF_BEGV (b)) + (total / width) - 1) / (total / width); + close = ((botpos - BUF_BEGV (b) + 1) + (total / width) - 1) / (total / width); + } + else + { + open = ((toppos - BUF_BEGV (b)) * width + total - 1) / total; + close = ((botpos - BUF_BEGV (b) + 1) * width + total - 1) / total; + } + + /* Build the indicator string. */ + for (i = 0; i < open; i++) *p++ = '-'; + *p++ = '+'; + for (i = 0; i < (close - open); i++) *p++ = '~'; + *p++ = '+'; + for (i = 0; i < (width - close); i++) *p++ = '-'; + *p = 0; + return decode_mode_spec_buf; + } + case 's': /* status of process */ obj = Fget_buffer_process (Fcurrent_buffer ());