[comp.emacs] Inverse videoing a region of text in GNU emacs

ranga@topaz.rutgers.edu (Rangarajan) (06/07/87)

Is there a command to highlight (reverse video) a region of text? I
know that the variable "inverse-video" controls this feature, but it
does not seem to work properly in a lisp function. I tried the
following (in vain):
	(defun hilite (from to)
	  ;; Highlight the segment from FROM to TO
		(kill-region from to)
		(setq inverse-video t)
		(goto-char from)
		(yank)
		(setq inverse-video nil)
	)

	Any insights? Thanks.
		--ranga

address: rangarajan@ru-aim, ranga@topaz.rutgers.edu		

gudeman@arizona.edu (David Gudeman) (06/11/87)

Posting-Front-End: GNU Emacs 18.41.1 of Fri Apr  3 1987 on megaron.arizona.edu (berkeley-unix)


In article <12497@topaz.rutgers.edu> ranga@topaz.rutgers.edu writes:

   From: ranga@topaz.rutgers.edu (Rangarajan)
   Organization: Rutgers Univ., New Brunswick, N.J.

   Is there a command to highlight (reverse video) a region of text? I
   know that the variable "inverse-video" controls this feature, but it
   does not seem to work properly in a lisp function. I tried the
   following (in vain):
	   (defun hilite (from to)
	     ;; Highlight the segment from FROM to TO
		   (kill-region from to)
		   (setq inverse-video t)
		   (goto-char from)
		   (yank)
		   (setq inverse-video nil)
	   )
   ...
The answer to your first question is "no".  There is no way to control
reverse video beyond on/off.  The variable inverse-video is supposed
to be used to control the entire screen at once, not individual parts.
When the sreen refreshes, everything is written according to the
current value of the variable, not the value when the text was
origianally written.  Your intended use of the variable is interesting
though.

The reason it doesn't work is that Emacs uses an algorithm to
update the screen as efficiently as possible.  Since the you kill a
region and immediately yank it back, the screen doesn't change, so it
is not updated (Emacs doesn't keep track of reverse-video attribute so
that is not recorded as a change).  To make it work, you have to
refresh the screen (with '(sit-for 0)') after the text is deleted and
after it is re-inserted, skip either one and it won't work.  Another
comment, kill-region should not generally be called from elisp
functions, unless you specifically want a side-affect on the kill
ring.  It is better to assign the string to a variable, delete the
region, then insert the string.  Also, to temporarily assign to a
variable in a function, use 'let':

	(defun hilite (p1 p2)
	  "Hilight the current region."
	  (interactive "r")
	  (let ((s (buffer-substring p1 p2))
		(inverse-video t))
	    (delete-region p1 p2)
	    (sit-for 0)
	    (insert s)
	    (sit-for 0)))

If you don't have the second '(sit-for 0)', the screen will not be
refreshed until _after_ the function exits, and the value of
inverse-video will be back to nil by then.  Also, remember that any
number of screen operations may rewrite some or all of the
inverse-video text, and if so, will write it normal mode.