[Top][All Lists]

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

Reducing mouse-dependency In Emacs.

From: Luc Teirlinck
Subject: Reducing mouse-dependency In Emacs.
Date: Sat, 9 Aug 2003 22:42:33 -0500 (CDT)

Text properties like `mouse-face' and `help-echo' are, as presently
conceived, not only completely useless to the blind, but to any
non mouse oriented user.  Unfortunately, quite a bit of documentation
relies exclusively on those type of features.  A disturbing recent
trend, already pointed out by others, is to rely more and more on
such mouse-exclusive features.

I propose to complement `mouse-face' and `help-echo' with two new text
properties, `short-help' and `long-help', which would be strings or
evaluate to strings.

The idea would be that `help-echo' could rely on the fact that the
user is busy using the mouse, `short-help' on the fact that he is
using the keyboard (if it makes a difference) and `long-help' would
provide more thorough documentation, in a more limited number of
situations.  `help-echo' would be the one that would always be
present if any one of the three is, with `short-help' defaulting to it.

Below is a function, `print-local-help' (which could be bound to some
help key sequence, say C-h C-l, as implemented below) that first looks
for a `short-help' property and, if none is found, for `help-echo' and
prints the resulting string in the echo area.  `long-help' would be
for documenting more elaborate and potentially confusing features like
keymap or local-map text-properties.  `long-help' would be accessed by
giving `print-local-help' a numeric argument.  This would display the
help in a help-buffer with all the usual features available, including
the ones provided by `substitute-command-keys' to print out keymaps,
the usual links and a completely functional "back" button. This could
be used for all kinds of information, including how to customize the
keymap provided by the text property.  (Hopefully, that would
encourage authors to make sure that such keymaps are easily

Two other functions `next-help-echo-region' and
`previous-help-echo-region' would carry one forward and backward to
the beginning of successive regions with non-nil `help-echo'
properties.  (They are bound to C-tab and C-M-tab in the
implementation below.)

I believe that this would allow for efficient use of local
documentation contained in text properties in a mouse-independent way.

If there is interest in the functionality below, then there is one
issue I still might need to address.  Below, I only handle `help-echo'
properties that are strings or evaluate to strings.  Strictly
speaking, the ((stringp echo) (message echo)) clause should be
replaced by an (echo (help-echo-string echo)) clause, where
`help-echo-string' would be a function computing the string
corresponding to the help-echo property if that property is a
function.  Is there already an Elisp function with that functionality?
If not are help-echo properties that are functions used in practice in
ordinary buffers?  (The only example I know of is used in the mode
line.)  If there is interest in the functionality, then I could, if
necessary, provide a function of this type myself.

I do not necessarily propose to put those functions in a separate
file.  (It would be too short.)  Maybe there is a natural place they
could go.

===File ~/local-help.el=====================================
;; The next variable and function are needed for xref info related to
;; print-local-help.

(defvar print-local-help-long "")

(defun print-local-help-setup-xref ()
   (list #'(lambda ()
             (with-output-to-temp-buffer (help-buffer)
               (princ (substitute-command-keys print-local-help-long)))))

(defun print-local-help (arg)
  "Display help related text or overlay properties.
Normally, this displays a short help message in the echo area,
namely the value of the `short-help' text or overlay property at
point.  If there is no `short-help' property at point, but there
is a `help-echo' property whose value is a string, then that is
printed instead.
If a numeric argument is given and there is a `long-help' text or
overlay property at point, then that is displayed in a temporary
help buffer, after `substitute-command-keys' is called on the
  (interactive "P")
  (let ((short (get-char-property (point) 'short-help))
        (echo (get-char-property (point) 'help-echo)))
    (setq print-local-help-long (get-char-property (point) 'long-help))
    (cond ((and arg print-local-help-long)
           (with-output-to-temp-buffer (help-buffer)
             (princ (substitute-command-keys print-local-help-long))
          (short (message short))
          ((stringp echo) (message echo))
             "Only long help is available. Type C-u \\[print-local-help]")))
          (t (message "No local help at point")))))

(defun next-help-echo-region ()
  "Go to the start of the next region with non-nil help-echo property.
Adjacent areas with different non-nil help-echo properties are
considered different regions."
  (let ((pos (next-single-char-property-change (point) 'help-echo)))
    (if (get-char-property pos 'help-echo)
        (goto-char pos)
      (setq pos (next-single-char-property-change pos 'help-echo))
      (if (= pos (point-max))
          (message "No further help-echo regions in this buffer")
        (goto-char pos)))))

(defun previous-help-echo-region ()
  "Move back to the start of a region with non-nil help-echo property.
Adjacent areas with different non-nil help-echo properties are
considered different regions."
  (let ((pos (previous-single-char-property-change (point) 'help-echo)))
    (if (get-char-property pos 'help-echo)
        (goto-char pos)
      (setq pos (previous-single-char-property-change pos 'help-echo))
      (if (get-char-property pos 'help-echo)
          (goto-char pos)
        (message "No prior help-echo regions in this buffer")))))

(global-set-key "\C-h\C-l" 'print-local-help)
(global-set-key [C-tab] 'next-help-echo-region)
(global-set-key [C-M-tab] 'previous-help-echo-region)

reply via email to

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