liberte@B.CS.UIUC.EDU.UUCP (06/15/87)
Questions about how to do highlighting and proposed solutions on usenet comp.emacs prompted me to try to repair my highlight-region hack. This used to work with previous versions of GNU Emacs, but sometime before 18.41 the update mechanism was changed so that (sit-for 0) really does not do an update if there is pending input. Since there is now no way to force and update, I tried to clear the pending input status, but now it appears difficult to clear the pending-input status. The following works in some limited cases and may be useful for someone. It is interesting nevertheless. (BTW, I learned that if you execute a null command while defining a keyboard macro, you are thrown out of defining-keyboard-macro mode *without notice*!! Why even terminate the mode? - just ignore the command and continue.) Dan LaLiberte liberte@a.cs.uiuc.edu uiucdcs!liberte p.s. I may be working on "true" highlighting for emacs this summer. Here is highlight.el: ---------------------------------------------------- ; highlight.el - fack highlighting with inverse-video ; Contains highlight-region, temporarily-highlight-region, ; and utilities wait-for-key, gobble-input, and interp-string (global-set-key "\eT" 'temp-highlight) (global-set-key "\eH" 'highlight-region) (defun temporarily-highlight-region (start end) "Temporarily highlight region from START to END until a keystroke is hit. Then it unhighlights and tries to execute the input with interp-string. Doesn't always catch multi-keystroke input if input is too slow. Doesn't always work if START or END is off the window. Doesn't always work with selective display. Probably has a lot of other problems too." (interactive "r") (highlight-region start end) ; (message "highlight on") ; (sit-for 1) ; debug (wait-for-key (point)) (sit-for 1) ; wait for all the input to come in - ha! ; If we dont gobble-input, sit-for 0 will not update the screen. ; Even if we do gobble-input, it still appears input is pending sometimes. ; We really need an update function to force update even with pending input. ; Then we wouldnt need gobble-input and interp-string. ; Alternatively, a stuff-input function would suffice. (let ((keys (gobble-input))) (setq keys (concat keys (gobble-input))) ; gobble more input (setq keys (concat keys (gobble-input))) ; (message "about to turn highlight off with pending: %s" keys) ; debug ; (sit-for 2) ; debug (highlight-region start end) ; (message "highlight off") ; debug ; (sit-for 2) ; debug (setq keys (concat keys (gobble-input))) (interp-string keys) ) ) (defun wait-for-key (where) "Wait at WHERE until input is pending." (let ((old-pnt (point))) (sit-for 1) (while (not (input-pending-p)) ; wait for input ; (message "waiting ...") (goto-char where) (sit-for 1) ; (message "...") ) (goto-char old-pnt) ) ) (defun gobble-input () "Return all pending input chars in a string" (let ((keys "")) (while (input-pending-p) (setq keys (concat keys (char-to-string (read-char)))) ) keys ) ) (defun interp-string (str) "Interpret the STRING as if it were from input using execute-kbd-macro. Doesn't execute a prefix sequence correctly since it ignores keys if not a complete key sequence." (let (tempfunc) (fset tempfunc str) (execute-kbd-macro tempfunc) ) ) (defun highlight-region (start end) "Temporarily highlight region by using inverse-video. It leaves inverse-video toggled. Use temporarily-highlight-region instead." (interactive "r") (let ((text (buffer-substring start end)) (old-pnt (point))) ; white out the region line by line (if (< start end) ; anything in region? (let ((i start) j k start-col end-col) (setq j i) (goto-char i) (while (< i end) (setq start-col (current-column)) ; (forward-char 1) (end-of-line) (if (> (point) end) (goto-char end) ) (setq j (point)) (setq end-col (current-column)) ; to end of line or text ; (message "insert from %d to %d" i j) ; debug ; (sit-for 2) ; debug (goto-char i) (delete-region i j) (setq k (- end-col start-col)) ; number of spaces ; (message "insert %d spaces" k) ; debug ; (sit-for 1) ; debug (insert-char ?\ k) (forward-char 1) ; move to start of next line (setq end (+ end (- k (- j i)))) ; adjust for extra spaces (setq i (point)) ; start of next line ; (message "i=%d j=%d k=%d" i j k) ; debug ; (sit-for 1) ; debug ) ; while ) ; let ) ; if (goto-char old-pnt) ; make sure point is back to initial position (sit-for 0) ; force update to erase text ; delete white space and reinsert text with inverse-video on ; (message "about to delete spaces") ; debug (delete-region start end) ; (message "about to reinsert %s" text) ; debug ; (sit-for 1) ; debug (goto-char start) (setq inverse-video (not inverse-video)) (insert text) (goto-char old-pnt) (sit-for 0) ; force update to show inverted text ) ; let ) ; The following version of highlight-region does not work because ; narrow-to-region works very strangely with large buffers. (defun highlight-region-bad (start end) "Temporarily highlight region by using inverse-video." (interactive "r") (let ((text (buffer-substring start end)) (old-pnt (point)) ) (narrow-to-region start end) (goto-char start) (replace-regexp "[^ \t\n]" " ") ; this is slow and not even complete (widen) (goto-char old-pnt) (sit-for 0) ; delete white space and reinsert text inverted (delete-region start end) ; (message "about to reinsert %s" text) ; (sit-for 0) (goto-char start) (setq inverse-video (not inverse-video)) (insert text) (goto-char old-pnt) (sit-for 0) ) )