unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: Reducing mouse-dependency In Emacs.
@ 2003-08-13  5:36 Luc Teirlinck
  2003-08-13  7:47 ` Miles Bader
  0 siblings, 1 reply; 26+ messages in thread
From: Luc Teirlinck @ 2003-08-13  5:36 UTC (permalink / raw)


The current version of `print-local-help' only works with `help-echo'
properties that are strings.  The fact that it does not work with
help-echo's that evaluate to strings was just an omission on my part
and is trivial to fix (I forgot some eval's).  I knew I still had to
take care of the rarer case of help-echo's that are functions.  I also
want `short-help' to have the same legal values as `help-echo',
including functions.

To take care of functional values, I need not only the value of the
property but also need to know whether it was found in an overlay (and
if so which overlay) or as a text property.
`get_char_property_and_overlay' provides that information, but in a
form that I do not know how to use from Lisp.  (I am not very familiar
at all with the Emacs C code.)  Assuming there is no better way, would
it be OK to define the following new primitive (the documentation
string would have to get a much shorter first line and maybe the name
is not right, but I could worry about such things later):

DEFUN ("find-char-property", Ffind_char_property, Sfind_char_property, 2, 3, 0,
       doc: /* Return a cons whose car is the value of POSITION's
property PROP, in OBJECT and whose cdr is the overlay in which the
property was found, or nil if it was found as a text property.  OBJECT
is optional and defaults to the current buffer.  If POSITION is at the
end of OBJECT, the value is nil.  If OBJECT is a buffer, then overlay
properties are considered as well as text properties.  If OBJECT is a
window, then that window's buffer is used, but window-specific
overlays are considered only if they are associated with OBJECT.  */)
     (position, prop, object)
     Lisp_Object position, object;
     register Lisp_Object prop;
{
  Lisp_Object *overlay = (Lisp_Object *) alloca (sizeof (Lisp_Object));
  Lisp_Object val=
    get_char_property_and_overlay (position, prop, object, overlay);
  return Fcons(val, *overlay);
}

I also put in a "defsubr (&Sadd_text_properties);" and a "EXFUN
(Ffind_char_property, 3);" in intervals.h.

(All of this in my own Emacs, not in the CVS, of course.)

The new primitive would take the same arguments as `get-char-property'
and return a cons with car the return value of `get-char-property' and
as cdr the overlay in which it was found, or nil if none.

I am really unfamiliar with the Emacs source code, but my Emacs
version still bootstraps, my Emacs has not crashed yet after some use
and everything seems to return the correct values, even in some
reasonably complex situations.

Is here a better way to access the information I need from Lisp or is
the above OK?  I know how to access the information I need completely
from Lisp, without any new primitives, but in a somewhat inelegant
way.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: Reducing mouse-dependency In Emacs.
@ 2003-08-12  2:49 Luc Teirlinck
  0 siblings, 0 replies; 26+ messages in thread
From: Luc Teirlinck @ 2003-08-12  2:49 UTC (permalink / raw)


The following (still strictly experimental) version of automatic
help-echo display eliminates the main obnoxiousness of the original
version.  In the original version, you could be asked a question in
the minibuffer, have to think about the answer, and suddenly the
question disappears for some useless help-echo.  The following version
prevents that.  It will only display the help-echo if the minibuffer
is empty or contains "Quit".  So, if you have "Mark set" in the echo
area, you have to do C-g or otherwise clear the echo area (say by
moving point) to get the help-echo.  Seems better than to miss an
important message, if not paying attention, by having it overridden by
help-echo.  Anyway, I wound up finding the original version unbearable
in actual use.  I found the one below much better.

===File ~/newhelp-timer.el==================================
(defun print-local-help (&optional timer)
  "Display help related text or overlay properties.
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.

The timer argument is meant for use in `run-with-idle-timer' and
prevents display of a message in case there is no help."
  (interactive)
  (let ((short (get-char-property (point) 'short-help))
	(echo (get-char-property (point) 'help-echo)))
    (cond (short (message "%s" short))
	  ((stringp echo) (message "%s" echo))
	  ((not timer) (message "No local help at point")))))

(defvar delay 1)

(defvar local-help-timer nil)

(unless local-help-timer
  (setq local-help-timer
	(run-with-idle-timer delay t #'maybe-display-help)))
   
(defun maybe-display-help ()
  (unless (and (current-message)
	       (not (string= (current-message) "Quit")))
    (print-local-help t)))

(defun cancel-echo ()
  (interactive)
  (cancel-timer local-help-timer)
  (setq local-help-timer nil))

(global-set-key "\C-h\C-l" 'print-local-help)
============================================================

^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: Reducing mouse-dependency In Emacs.
@ 2003-08-12  1:29 Luc Teirlinck
  2003-08-12  1:43 ` Luc Teirlinck
  0 siblings, 1 reply; 26+ messages in thread
From: Luc Teirlinck @ 2003-08-12  1:29 UTC (permalink / raw)


Here are my highlighting functions for text-properties.

You can do C-h C-k to highlight help-echo regions and C-u C-h C-k to
remove the highlight.  To make things more interesting, you should
have adjacent regions with different non-nil help-echo properties.

More generally, M-x highlight-text-property-regions will prompt for a
property and two faces.  Specifying nil for the first face will remove
any highlight associated with the property.

These functions are more meant to get an idea of "what is in the
buffer" than for permanent highlighting.  They do _not_ automatically
set a timer to update.

===File ~/highlightprops.el=================================
(defun highlight-text-property-regions (prop &optional face1 face2)
  "Highlight regions with non-nil text or overlay property PROP.
Regions get highlighted using face1, except that adjacent regions
with non-nil but different PROP properties get highlighted
alternatively with face1 and face2.
If face1 is nil, remove all highlighting.
If face2 is nil, highlight all regions with face1."
  (interactive "SProperty to highlight: \nSMain face: \nSBackup face: ")
  (unless prop (error "PROP must be non-nil"))
  (let ((overlay-list (overlays-in (point-min) (point-max))))
    (dolist (overlay overlay-list)
      (when (eq (overlay-get overlay 'highlight-text-property-regions) prop)
	(delete-overlay overlay))))
  (if face1
      (let ((pos (point-min))
	    (oldpos)
	    (current-face face1)
	    (change-face nil)
	    (current-overlay))
	(overlay-recenter (point-max))
	(unless face2 (setq face2 face1))
	(while (/= pos (point-max))
	  (if (get-char-property pos prop)
	      (progn
		(setq oldpos pos)
		(setq pos (next-single-char-property-change pos prop))
		(if change-face
		    (setq current-face (if (eq current-face face1)
					   face2 face1)))
		(setq current-overlay
		      (make-overlay oldpos pos (current-buffer) t)) 
		(overlay-put current-overlay 'face current-face)
		(overlay-put current-overlay
			     'highlight-text-property-regions prop)
		(setq change-face t))
	    (setq pos (next-single-char-property-change pos prop))
	    (setq change-face nil))))))

(defface help-echo-primary-face
  '((t (:background "yellow")))
  "Used by `highlight-help-echo-regions' as its main face."
  :group 'faces)

(defface help-echo-secondary-face
  '((t (:background "orange")))
  "Used by `highlight-help-echo-regions' as its secondary face."
  :group 'faces)

(defun highlight-help-echo-regions (&optional arg)
  "Highlight regions with non-nil help-echo-property.
With a numeric argumenr, remove all such highlighting.
Regions are normally highlighted with `help-echo-primary-face'.
However, regions are highlighted with'help-echo-secondary-face',
if necessary to distinguish them from adjacent regions.  This is
mainly useful for temporary highlighting, as it might override
other highlighting. No automatic updating takes place."
  (interactive "P")
  (if arg (highlight-text-property-regions 'help-echo)
    (highlight-text-property-regions
     'help-echo 'help-echo-primary-face 'help-echo-secondary-face)))

(global-set-key "\C-h\C-k" 'highlight-help-echo-regions)	
	  
  
				 
============================================================

^ permalink raw reply	[flat|nested] 26+ messages in thread
* Reducing mouse-dependency In Emacs.
@ 2003-08-10  3:42 Luc Teirlinck
  2003-08-10  6:08 ` Eli Zaretskii
  2003-08-10 16:50 ` Stefan Monnier
  0 siblings, 2 replies; 26+ messages in thread
From: Luc Teirlinck @ 2003-08-10  3:42 UTC (permalink / raw)


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
customizable.)

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 ()
  (help-setup-xref
   (list #'(lambda ()
	     (print-local-help-setup-xref)
	     (with-output-to-temp-buffer (help-buffer)
	       (princ (substitute-command-keys print-local-help-long)))))
   (interactive-p)))

(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
string."
  (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))
    (print-local-help-setup-xref)
    (cond ((and arg print-local-help-long)
	   (with-output-to-temp-buffer (help-buffer)
	     (princ (substitute-command-keys print-local-help-long))
	     (print-help-return-message)))
	  (short (message short))
	  ((stringp echo) (message echo))
	  (print-local-help-long
	   (message
	    (substitute-command-keys
	     "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."
  (interactive)
  (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."
  (interactive)
  (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)
============================================================

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2003-08-14  1:42 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-08-13  5:36 Reducing mouse-dependency In Emacs Luc Teirlinck
2003-08-13  7:47 ` Miles Bader
2003-08-13 12:59   ` Luc Teirlinck
2003-08-13 22:56     ` Nick Roberts
2003-08-14  0:35       ` Luc Teirlinck
2003-08-14  1:42         ` Miles Bader
2003-08-14  1:04       ` Luc Teirlinck
2003-08-13 14:32   ` Luc Teirlinck
  -- strict thread matches above, loose matches on Subject: below --
2003-08-12  2:49 Luc Teirlinck
2003-08-12  1:29 Luc Teirlinck
2003-08-12  1:43 ` Luc Teirlinck
2003-08-10  3:42 Luc Teirlinck
2003-08-10  6:08 ` Eli Zaretskii
2003-08-10 14:53   ` Luc Teirlinck
2003-08-11 12:53   ` Richard Stallman
2003-08-10 16:50 ` Stefan Monnier
2003-08-10 23:09   ` Luc Teirlinck
2003-08-11  4:05     ` Luc Teirlinck
2003-08-11 23:16       ` Richard Stallman
2003-08-11  6:04     ` Eli Zaretskii
2003-08-11 15:52       ` Luc Teirlinck
2003-08-11 17:52         ` Eli Zaretskii
2003-08-11 14:54     ` Stefan Monnier
2003-08-12  2:30       ` Luc Teirlinck
2003-08-12  6:28         ` Eli Zaretskii
2003-08-12 16:08           ` Luc Teirlinck

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).