* mode-line size and position indicator
@ 2017-08-23 3:20 Nick Helm
2017-08-24 16:55 ` Eli Zaretskii
0 siblings, 1 reply; 9+ messages in thread
From: Nick Helm @ 2017-08-23 3:20 UTC (permalink / raw)
To: Emacs developers
[-- Attachment #1: Type: text/plain, Size: 942 bytes --]
Hi all,
I've been trying to improve my C skills lately, so I thought I'd take a
crack at adding a small feature to xdisp.c.
I've written a simple mode-line indicator to visually show the relative
size and position of the window view on the current buffer. It works by
adding a new %-spec construct to decode_mode_spec.
The result is akin to a vertical scroll-bar, but it appears as a
horizontal mark on the mode-line. It may be useful to terminal users or
those who prefer to run with traditional scroll-bars turned off. I've
attached a screen-grab of what it looks like on my system.
The indicator is activated by adding %N~ to mode-line-format, where N is
a positive integer that sets the desired width of the indicator in char.
I'm under no illusions that this should be included in Emacs, and
admittedly, it is a very simple feature, but I'd appreciate any
comments or suggestions to improve the code. Patch attached.
Thanks,
Nick
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: xdisp.c.patch --]
[-- Type: text/x-patch, Size: 1584 bytes --]
--- 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 ());
[-- Attachment #3: indicator.png --]
[-- Type: image/png, Size: 23067 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mode-line size and position indicator
2017-08-23 3:20 Nick Helm
@ 2017-08-24 16:55 ` Eli Zaretskii
2017-08-24 19:26 ` John Yates
2017-08-25 9:57 ` Nick Helm
0 siblings, 2 replies; 9+ messages in thread
From: Eli Zaretskii @ 2017-08-24 16:55 UTC (permalink / raw)
To: Nick Helm; +Cc: emacs-devel
> From: Nick Helm <nick@tenpoint.co.nz>
> Date: Wed, 23 Aug 2017 15:20:27 +1200
>
> I've been trying to improve my C skills lately, so I thought I'd take a
> crack at adding a small feature to xdisp.c.
>
> I've written a simple mode-line indicator to visually show the relative
> size and position of the window view on the current buffer. It works by
> adding a new %-spec construct to decode_mode_spec.
>
> The result is akin to a vertical scroll-bar, but it appears as a
> horizontal mark on the mode-line. It may be useful to terminal users or
> those who prefer to run with traditional scroll-bars turned off. I've
> attached a screen-grab of what it looks like on my system.
>
> The indicator is activated by adding %N~ to mode-line-format, where N is
> a positive integer that sets the desired width of the indicator in char.
>
> I'm under no illusions that this should be included in Emacs, and
> admittedly, it is a very simple feature, but I'd appreciate any
> comments or suggestions to improve the code. Patch attached.
Looks good, although there's a fundamental problem with putting on the
mode line an indicator that must use a significant part of the screen
estate to be useful: the mode line is pretty crowded these days, even
in the default configuration.
> + /* 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;
> + }
I wonder whether it would have made sense to reuse the code we have
for computing the scroll-bar thumb.
Also, why two different code fragments? why not use the former for
both small and large values of 'total'?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mode-line size and position indicator
2017-08-24 16:55 ` Eli Zaretskii
@ 2017-08-24 19:26 ` John Yates
2017-08-25 2:47 ` Richard Stallman
2017-08-25 9:57 ` Nick Helm
1 sibling, 1 reply; 9+ messages in thread
From: John Yates @ 2017-08-24 19:26 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Nick Helm, Emacs developers
On Thu, Aug 24, 2017 at 12:55 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>
> Looks good, although there's a fundamental problem with putting on the
> mode line an indicator that must use a significant part of the screen
> estate to be useful: the mode line is pretty crowded these days, even
> in the default configuration.
After a futile effort at IBM to obtain an FSF copyright assignment I have
given up and been too lazy to restart the effort with my new employer.
Hence my .emacs (https://github.com/jsyjr/MyConfiguration.git ) is in
the public domain.
A couple months back I posted a mode-line widget that I have been
using for some number of years. The relevant code is appended at
the end of this message. Notable behavior:
* Overlays proportional view of window in buffer onto line/column widget
* Supports the same mouse menu behavior as the original widget
* Highlights left edge square bracket if BOB is visible
* Highlights right edge square bracket if EOB is visible
* Hysteresis to minimize mode-line jitter
This solution does not use any more mode-line real estate than the
current line/column widget.
. . .
> I wonder whether it would have made sense to reuse the code we have
> for computing the scroll-bar thumb.
I am an inexperienced elisp hacker so I doubt that there is anything
particularly useful or novel in my code. As the comments mention I
was much inspired by past email discussions. The hardest part I found
was the logic corresponding to Eli's scroll-bar thumb logic.
I would love it if emacs offered essentially this functionality OOTB.
/john
;;{{{ mode-line position-widget
;; Use a fancy widget to display buffer position on the mode line.
;; -------------------------------------------------------------------
;;
;; Initial inspiration from an email thread between David Engster's and
;; Drew Adams:
;;
;; http://lists.gnu.org/archive/html/emacs-devel/2010-03/msg00523.html
;; http://permalink.gmane.org/gmane.emacs.devel/122038
;;
;; Further learnings from Lennart Borgman's sml-modeline.el
;; https://www.emacswiki.org/emacs/sml-modeline.el
;;
;; TODO: Change color if cursor exceeds limit column
(defvar buffer-max-column-visited 1
"Accumulate max column visited to prevent mode-line jitter.")
(make-variable-buffer-local 'buffer-max-column-visited)
(defun my/position-widget ()
(let*
((c-n-m column-number-mode)
(l-n-m line-number-mode)
(wbeg (window-start))
(wend (window-end)))
(save-restriction
(widen)
(let*
((eob-line (line-number-at-pos (point-max)))
(wbeg-line (line-number-at-pos wbeg))
(wend-line (line-number-at-pos wend))
(widget
(concat
;; Leading [
(if (= wbeg-line 1)
#("[" 0 1 (face mode-line-highlight-bold))
"[")
;; Body
(if (not (or l-n-m c-n-m))
(replace-regexp-in-string "%" "%%" (format-mode-line
'(-3 "%P")))
(let*
((wlines (1+ (- wend-line wbeg-line)))
(expanded
(format-mode-line
(concat
(cond
((not l-n-m) "")
((> 10 eob-line) "%1l")
((> 100 eob-line) "%2l")
((> 1000 eob-line) "%3l")
((> 10000 eob-line) "%4l")
((> 100000 eob-line) "%5l")
((> 1000000 eob-line) "%6l")
(t "%7l"))
(if (and l-n-m c-n-m) #("," 0 1 (face bold)) "")
(cond
((not c-n-m) "")
(t (let*
((max-col (max (current-column)
buffer-max-column-visited))
(field (cond
((> 10 max-col) 3)
((> 100 max-col) 4)
((> 1000 max-col) 5)
(t 6)))
(cur-col (current-column))
(digits (cond
((> 10 cur-col) 1)
((> 100 cur-col) 2)
((> 1000 cur-col) 3)
(t 4))))
(setq buffer-max-column-visited max-col)
(substring "%c " 0 (- field digits))))))))
(len (length expanded))
(hilen (max 1 ; at least one column
(min len ; no more than full string
(round (/ (* wlines len)
(float eob-line))))))
(lpad (round (/ (* wbeg-line (- len hilen))
(float (- eob-line wlines -2)))))
(rpad (+ lpad hilen)))
(put-text-property lpad rpad 'face
'mode-line-highlight expanded)
expanded))
;; Trailing ]
(if (= wend-line eob-line)
#("]" 0 1 (face mode-line-highlight-bold))
"]"))))
(propertize
widget
'help-echo "Buffer position widget\nmouse-1: Line and Column Mode Menu"
'mouse-face 'mode-line-highlight
'local-map '(keymap
(mode-line
keymap
(down-mouse-1
keymap
(line-number-mode
menu-item "Global Line Number Mode" line-number-mode
:help "Toggle line number display"
:button (:toggle . line-number-mode))
(column-number-mode
menu-item "Global Column Number Mode"
column-number-mode
:help "Toggle column number display"
:button (:toggle . column-number-mode))
"Control Line and Column Display Globally"))))))))
(my/custom-set-variables
'(mode-line-position '(:eval (my/position-widget)) t)
)
;;}}}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mode-line size and position indicator
@ 2017-08-24 21:02 mark M
2017-08-25 6:27 ` Eli Zaretskii
0 siblings, 1 reply; 9+ messages in thread
From: mark M @ 2017-08-24 21:02 UTC (permalink / raw)
To: John Yates; +Cc: Eli Zaretskii, Nick Helm, Emacs developers
[-- Attachment #1: Type: text/plain, Size: 4801 bytes --]
Both Aquamacs and Emacs The latest version have started flickering quite a bit on opening any latex document with color or tables or formatting
>
> On Aug 24, 2017 at 12:26 PM, <John Yates (mailto:john@yates-sheets.org)> wrote:
>
>
>
> On Thu, Aug 24, 2017 at 12:55 PM, Eli Zaretskii wrote: > > Looks good, although there's a fundamental problem with putting on the > mode line an indicator that must use a significant part of the screen > estate to be useful: the mode line is pretty crowded these days, even > in the default configuration. After a futile effort at IBM to obtain an FSF copyright assignment I have given up and been too lazy to restart the effort with my new employer. Hence my .emacs (https://github.com/jsyjr/MyConfiguration.git ) is in the public domain. A couple months back I posted a mode-line widget that I have been using for some number of years. The relevant code is appended at the end of this message. Notable behavior: * Overlays proportional view of window in buffer onto line/column widget
* Supports the same mouse menu behavior as the original widget * Highlights left edge square bracket if BOB is visible * Highlights right edge square bracket if EOB is visible * Hysteresis to minimi
ze mode-line jitter This solution does not use any more mode-line real estate than the current line/column widget. . . . > I wonder whether it would have made sense to reuse the code we have > for computing the scroll-bar thumb. I am an inexperienced elisp hacker so I doubt that there is anything particularly useful or novel in my code. As the comments mention I was much inspired by past email discussions. The hardest part I found was the logic corresponding to Eli's scroll-bar thumb logic. I would love it if emacs offered essentially this functionality OOTB. /john ;;{{{ mode-line position-widget ;; Use a fancy widget to display buffer position on the mode line. ;; ------------------------------------------------------------------- ;; ;; Initial inspiration from an email thread between
David Engster's and ;; Drew Adams: ;; ;; http://lists.gnu.org/archive/html/emacs-devel/2010-03/msg00523.html ;; http://permalink.gmane.org/gmane.emacs.devel/122038 ;; ;; Further learnings from Lenn
art Borgman's sml-modeline.el ;; https://www.emacswiki.org/emacs/sml-modeline.el ;; ;; TODO: Change color if cursor exceeds limit column (defvar buffer-max-column-visited 1 "Accumulate max column visited to prevent mode-line jitter.") (make-variable-buffer-local 'buffer-max-column-visited) (defun my/position-widget () (let* ((c-n-m column-number-mode) (l-n-m line-number-mode) (wbeg (window-start)) (wend (window-end))) (save-restriction (widen) (let* ((eob-line (line-number-at-pos (point-max))) (wbeg-line (line-number-at-pos wbeg)) (wend-line (line-number-at-pos wend)) (widget (concat ;; Leading [ (if (= wbeg-line 1) #("[" 0 1 (face mode-line-highlight-bold)) "[") ;; Body (if (not (or l-n-m c-n-m)) (replace-regexp-in-string "%" "%%" (format-mode-line '(-3 "%P"))) (let* ((wlines (1+ (- wend-
line wbeg-line))) (expanded (format-mode-line (concat (cond ((not l-n-m) "") ((> 10 eob-line) "%1l") ((> 100 eob-line) "%2l") ((> 1000 eob-line) "%3l") ((> 10000 eob-line) "%4l") ((> 100000 e
ob-line) "%5l") ((> 1000000 eob-line) "%6l") (t "%7l")) (if (and l-n-m c-n-m) #("," 0 1 (face bold)) "") (cond ((not c-n-m) "") (t (let* ((max-col (max (current-column) buffer-max-column-visited)) (field (cond ((> 10 max-col) 3) ((> 100 max-col) 4) ((> 1000 max-col) 5) (t 6))) (cur-col (current-column)) (digits (cond ((> 10 cur-col) 1) ((> 100 cur-col) 2) ((> 1000 cur-col) 3) (t 4)))) (setq buffer-max-column-visited max-col) (substring "%c " 0 (- field digits)))))))) (len (length expanded)) (hilen (max 1 ; at least one column (min len ; no more than full string (round (/ (* wlines len) (float eob-line)))))) (lpad (round (/ (* wbeg-line (- len hilen)) (float (- eob-line wlines -2))))) (rpad (+ lpad hilen))) (put-text-property lpad rpad 'face 'mode-line-highlight expanded) expanded))
;; Trailing ] (if (= wend-line eob-line) #("]" 0 1 (face mode-line-highlight-bold)) "]")))) (propertize widget 'help-echo "Buffer position widget\nmouse-1: Line and Column Mode Menu" 'mouse-face 'mo
de-line-highlight 'local-map '(keymap (mode-line keymap (down-mouse-1 keymap (line-number-mode menu-item "Global Line Number Mode" line-number-mode :help "Toggle line number display" :button (:toggle . line-number-mode)) (column-number-mode menu-item "Global Column Number Mode" column-number-mode :help "Toggle column number display" :button (:toggle . column-number-mode)) "Control Line and Column Display Globally")))))))) (my/custom-set-variables '(mode-line-position '(:eval (my/position-widget)) t) ) ;;}}}
>
>
[-- Attachment #2: Type: text/html, Size: 7243 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mode-line size and position indicator
2017-08-24 19:26 ` John Yates
@ 2017-08-25 2:47 ` Richard Stallman
0 siblings, 0 replies; 9+ messages in thread
From: Richard Stallman @ 2017-08-25 2:47 UTC (permalink / raw)
To: John Yates; +Cc: eliz, nick, emacs-devel
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
> After a futile effort at IBM to obtain an FSF copyright assignment I have
> given up and been too lazy to restart the effort with my new employer.
> Hence my .emacs (https://github.com/jsyjr/MyConfiguration.git ) is in
> the public domain.
If the copyright belongs to you, then you can either assign it to the
FSF or put the work in the public domain. You can do either one on
your own.
However, if the copyright belngs to IBM, then you don't have legal
authority to do either of these things. Only the copyright holder can
do them.
This is why we ask a contributor who is employed by software
companies, or works in the software field, to get a copyright
_disclaimer_ from per employer. Not an _assignment_, but a
_disclaimer_. The disclaimer is a lot simpler and generally easier to
get.
I don't know the facts of the situation, such as whether IBM claims
copyright on this work. But I suspect that if you asked for an assignment
from IBM that there was a misunderstanding at work.
Would you please talk with our copyright clerks to help get this
situation straightened out?
--
Dr Richard Stallman
President, Free Software Foundation (gnu.org, fsf.org)
Internet Hall-of-Famer (internethalloffame.org)
Skype: No way! See stallman.org/skype.html.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mode-line size and position indicator
2017-08-24 21:02 mode-line size and position indicator mark M
@ 2017-08-25 6:27 ` Eli Zaretskii
0 siblings, 0 replies; 9+ messages in thread
From: Eli Zaretskii @ 2017-08-25 6:27 UTC (permalink / raw)
To: mark M; +Cc: nick, emacs-devel, john
> Date: Thu, 24 Aug 2017 14:02:06 -0700
> From: mark M <write2mark1@gmail.com>
> Cc: Eli Zaretskii <eliz@gnu.org>, Nick Helm <nick@tenpoint.co.nz>,
> Emacs developers <emacs-devel@gnu.org>
>
> Both Aquamacs and Emacs The latest version have started flickering quite a bit on opening any latex
> document with color or tables or formatting
You mean, after installing these patches? Or regardless?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mode-line size and position indicator
2017-08-24 16:55 ` Eli Zaretskii
2017-08-24 19:26 ` John Yates
@ 2017-08-25 9:57 ` Nick Helm
2017-08-25 12:36 ` Eli Zaretskii
1 sibling, 1 reply; 9+ messages in thread
From: Nick Helm @ 2017-08-25 9:57 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: emacs-devel
Thanks for your comments Eli.
On Fri 25 Aug 2017 at 4.55 am, Eli Zaretskii wrote:
> ...there's a fundamental problem with putting on the mode line an
> indicator that must use a significant part of the screen estate to be
> useful: the mode line is pretty crowded these days, even in the
> default configuration.
Agreed, especially when we already have scroll-bars. Still, something
like this might be useful in a few corner cases – users do seem to keep
reinventing it in one form or another over and over again. See John
Yate's comment down thread for one recent example. Even nyan-mode
qualifies, I guess. :)
> I wonder whether it would have made sense to reuse the code we have
> for computing the scroll-bar thumb.
Almost certainly. I'll check it out.
> Also, why two different code fragments? why not use the former for
> both small and large values of 'total'?
Other parts of xdisp.c seem to warn against overflow when dealing with
large buffers ('total' more than 1000000). Although I couldn't
reproduce any problems when I was playing around with the code, I
thought it was prudent to follow the same kinds of precautions.
In the other case, I wanted the code to run quickly during rapid
scrolling manoeuvres, so I tried to condense the math as much as
possible at the cost of dealing with larger variables. That was the idea
anyway.
Thanks again,
Nick
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mode-line size and position indicator
2017-08-25 9:57 ` Nick Helm
@ 2017-08-25 12:36 ` Eli Zaretskii
2017-08-26 7:50 ` Nick Helm
0 siblings, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2017-08-25 12:36 UTC (permalink / raw)
To: Nick Helm; +Cc: emacs-devel
> From: Nick Helm <nick@tenpoint.co.nz>
> CC: emacs-devel@gnu.org
> Date: Fri, 25 Aug 2017 21:57:35 +1200
>
> In the other case, I wanted the code to run quickly during rapid
> scrolling manoeuvres, so I tried to condense the math as much as
> possible at the cost of dealing with larger variables. That was the idea
> anyway.
Did you actually see any tangible slowdown in using the "slower" code?
I very much doubt that you'd see any effect, whereas complicating the
code has an immediate clear effect on its readability.
IME, such micro-optimizations are almost never needed, and shouldn't
be done without measurements.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mode-line size and position indicator
2017-08-25 12:36 ` Eli Zaretskii
@ 2017-08-26 7:50 ` Nick Helm
0 siblings, 0 replies; 9+ messages in thread
From: Nick Helm @ 2017-08-26 7:50 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: emacs-devel
On Sat 26 Aug 2017 at 12.36 am, Eli Zaretskii wrote:
>> In the other case, I wanted the code to run quickly during rapid
>> scrolling manoeuvres, so I tried to condense the math as much as
>> possible at the cost of dealing with larger variables. That was the idea
>> anyway.
>
> Did you actually see any tangible slowdown in using the "slower" code?
> I very much doubt that you'd see any effect, whereas complicating the
> code has an immediate clear effect on its readability.
No, none that I could detect with just basic compile-and-use testing.
I get your point about the readability of the code too. I'll have a go
at improving it.
Thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-08-26 7:50 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-24 21:02 mode-line size and position indicator mark M
2017-08-25 6:27 ` Eli Zaretskii
-- strict thread matches above, loose matches on Subject: below --
2017-08-23 3:20 Nick Helm
2017-08-24 16:55 ` Eli Zaretskii
2017-08-24 19:26 ` John Yates
2017-08-25 2:47 ` Richard Stallman
2017-08-25 9:57 ` Nick Helm
2017-08-25 12:36 ` Eli Zaretskii
2017-08-26 7:50 ` Nick Helm
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).