emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] trunk r114849: Add pre-redisplay-function and rectangular


From: Stefan Monnier
Subject: [Emacs-diffs] trunk r114849: Add pre-redisplay-function and rectangular region
Date: Tue, 29 Oct 2013 16:12:20 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 114849
revision-id: address@hidden
parent: address@hidden
committer: Stefan Monnier <address@hidden>
branch nick: trunk
timestamp: Tue 2013-10-29 12:11:50 -0400
message:
  Add pre-redisplay-function and rectangular region
  * lisp/rect.el: Use lexical-binding.  Add new rectangular region support.
  (rectangle-mark): New command.
  (rectangle--region): New var.
  (deactivate-mark-hook): Reset rectangle--region.
  (rectangle--extract-region, rectangle--insert-for-yank)
  (rectangle--highlight-for-redisplay)
  (rectangle--unhighlight-for-redisplay): New functions.
  (region-extract-function, redisplay-unhighlight-region-function)
  (redisplay-highlight-region-function): Use them to handle
  rectangular region.
  * lisp/simple.el (region-extract-function): New var.
  (delete-backward-char, delete-forward-char, deactivate-mark): Use it.
  (kill-new, kill-append): Remove obsolete `yank-handler' argument.
  (kill-region): Replace obsolete `yank-handler' arg with `region'.
  (copy-region-as-kill, kill-ring-save): Add `region' argument.
  (redisplay-unhighlight-region-function)
  (redisplay-highlight-region-function): New vars.
  (redisplay--update-region-highlight): New function.
  (pre-redisplay-function): Use it.
  (exchange-point-and-mark): Don't deactivate the mark before
  reactivate-it anyway.
  * lisp/comint.el (comint-kill-region): Remove yank-handler argument.
  * lisp/delsel.el (delete-backward-char, backward-delete-char-untabify)
  (delete-char): Remove property, since it's now part of their
  default behavior.
  (self-insert-iso): Remove property since this command doesn't exist.
  
  * src/xdisp.c (prepare_menu_bars): Call Vpre_redisplay_function.
  (syms_of_xdisp): Declare pre-redisplay-function.
  (markpos_of_region): Remove function.
  (init_iterator, compute_stop_pos, handle_face_prop)
  (face_before_or_after_it_pos, reseat_to_string)
  (get_next_display_element, window_buffer_changed)
  (redisplay_internal, try_cursor_movement, redisplay_window)
  (try_window_reusing_current_matrix, try_window_id, display_line)
  (note_mode_line_or_margin_highlight, note_mouse_highlight)
  (display_string, mouse_face_from_buffer_pos): Remove region handling.
  * src/window.h (struct window): Remove field `region_showing'.
  * src/dispextern.h (struct it): Remove region_beg/end_charpos.
  (face_at_buffer_position, face_for_overlay_string)
  (face_at_string_position): Update prototypes.
  * src/xfaces.c (face_at_buffer_position, face_for_overlay_string)
  (face_at_string_position): Remove `region_beg' and `region_end' args.
  * src/fontset.c (Finternal_char_font):
  * src/font.c (font_at, font_range): Adjust calls accordingly.
  * src/insdel.c (Qregion_extract_function): New var.
  (syms_of_insdel): Initialize it.
  (prepare_to_modify_buffer_1): Use it.
modified:
  etc/NEWS                       news-20100311060928-aoit31wvzf25yr1z-1
  lisp/ChangeLog                 changelog-20091113204419-o5vbwnq5f7feedwu-1432
  lisp/comint.el                 comint.el-20091113204419-o5vbwnq5f7feedwu-149
  lisp/delsel.el                 delsel.el-20091113204419-o5vbwnq5f7feedwu-540
  lisp/rect.el                   rect.el-20091113204419-o5vbwnq5f7feedwu-83
  lisp/simple.el                 simple.el-20091113204419-o5vbwnq5f7feedwu-403
  lisp/subr.el                   subr.el-20091113204419-o5vbwnq5f7feedwu-151
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/dispextern.h               
dispextern.h-20091113204419-o5vbwnq5f7feedwu-218
  src/font.c                     font.c-20091113204419-o5vbwnq5f7feedwu-8540
  src/fontset.c                  fontset.c-20091113204419-o5vbwnq5f7feedwu-1079
  src/insdel.c                   insdel.c-20091113204419-o5vbwnq5f7feedwu-175
  src/window.h                   window.h-20091113204419-o5vbwnq5f7feedwu-271
  src/xdisp.c                    xdisp.c-20091113204419-o5vbwnq5f7feedwu-240
  src/xfaces.c                   xfaces.c-20091113204419-o5vbwnq5f7feedwu-560
=== modified file 'etc/NEWS'
--- a/etc/NEWS  2013-10-27 04:18:28 +0000
+++ b/etc/NEWS  2013-10-29 16:11:50 +0000
@@ -179,6 +179,9 @@
 
 * Editing Changes in Emacs 24.4
 
+** New command `rectangle-mark' makes a rectangular region.
+Most commands are still unaware of it, but kill/yank do work on the rectangle.
+
 ** C-x TAB enters a transient interactive mode.
 You can then use the left/right cursor keys to move the block of text.
 
@@ -631,6 +634,8 @@
 
 * Incompatible Lisp Changes in Emacs 24.4
 
+** `kill-region' lost its `yank-handler' optional argument.
+
 ** `(input-pending-p)' no longer runs other timers which are ready to
 run.  The new optional CHECK-TIMERS param allows for the prior behavior.
 
@@ -692,6 +697,8 @@
 
 * Lisp Changes in Emacs 24.4
 
+** New hook `pre-redisplay-function'.
+
 +++
 ** Functions that pop up menus and dialogs now work on all terminal types,
 including TTYs.

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2013-10-29 14:48:08 +0000
+++ b/lisp/ChangeLog    2013-10-29 16:11:50 +0000
@@ -1,5 +1,32 @@
 2013-10-29  Stefan Monnier  <address@hidden>
 
+       * rect.el: Use lexical-binding.  Add new rectangular region support.
+       (rectangle-mark): New command.
+       (rectangle--region): New var.
+       (deactivate-mark-hook): Reset rectangle--region.
+       (rectangle--extract-region, rectangle--insert-for-yank)
+       (rectangle--highlight-for-redisplay)
+       (rectangle--unhighlight-for-redisplay): New functions.
+       (region-extract-function, redisplay-unhighlight-region-function)
+       (redisplay-highlight-region-function): Use them to handle
+       rectangular region.
+       * simple.el (region-extract-function): New var.
+       (delete-backward-char, delete-forward-char, deactivate-mark): Use it.
+       (kill-new, kill-append): Remove obsolete `yank-handler' argument.
+       (kill-region): Replace obsolete `yank-handler' arg with `region'.
+       (copy-region-as-kill, kill-ring-save): Add `region' argument.
+       (redisplay-unhighlight-region-function)
+       (redisplay-highlight-region-function): New vars.
+       (redisplay--update-region-highlight): New function.
+       (pre-redisplay-function): Use it.
+       (exchange-point-and-mark): Don't deactivate the mark before
+       reactivate-it anyway.
+       * comint.el (comint-kill-region): Remove yank-handler argument.
+       * delsel.el (delete-backward-char, backward-delete-char-untabify)
+       (delete-char): Remove property, since it's now part of their
+       default behavior.
+       (self-insert-iso): Remove property since this command doesn't exist.
+
        * emacs-lisp/package.el (package--download-one-archive)
        (describe-package-1): Don't query the user about final newline.
 

=== modified file 'lisp/comint.el'
--- a/lisp/comint.el    2013-09-11 03:31:56 +0000
+++ b/lisp/comint.el    2013-10-29 16:11:50 +0000
@@ -2679,7 +2679,7 @@
     (kill-whole-line count)
     (when (>= count 0) (comint-update-fence))))
 
-(defun comint-kill-region (beg end &optional yank-handler)
+(defun comint-kill-region (beg end)
   "Like `kill-region', but ignores read-only properties, if safe.
 This command assumes that the buffer contains read-only
 \"prompts\" which are regions with front-sticky read-only
@@ -2693,7 +2693,6 @@
 the case, this command just calls `kill-region' with all
 read-only properties intact.  The read-only status of newlines is
 updated using `comint-update-fence', if necessary."
-  (declare (advertised-calling-convention (beg end) "23.3"))
   (interactive "r")
   (save-excursion
     (let* ((true-beg (min beg end))
@@ -2708,9 +2707,9 @@
                         (if (listp end-lst) (memq 'read-only end-lst) t))))
       (if (or (and (not beg-bolp) (or beg-bad end-bad))
              (and (not end-bolp) end-bad))
-         (kill-region beg end yank-handler)
+         (kill-region beg end)
        (let ((inhibit-read-only t))
-         (kill-region beg end yank-handler)
+         (kill-region beg end)
          (comint-update-fence))))))
 
 ;; Support for source-file processing commands.

=== modified file 'lisp/delsel.el'
--- a/lisp/delsel.el    2013-01-01 09:11:05 +0000
+++ b/lisp/delsel.el    2013-10-29 16:11:50 +0000
@@ -165,16 +165,10 @@
        (not (run-hook-with-args-until-success
              'self-insert-uses-region-functions))))
 
-(put 'self-insert-iso 'delete-selection t)
-
 (put 'yank 'delete-selection 'yank)
 (put 'clipboard-yank 'delete-selection 'yank)
 (put 'insert-register 'delete-selection t)
 
-(put 'delete-backward-char 'delete-selection 'supersede)
-(put 'backward-delete-char-untabify 'delete-selection 'supersede)
-(put 'delete-char 'delete-selection 'supersede)
-
 (put 'newline-and-indent 'delete-selection t)
 (put 'newline 'delete-selection t)
 (put 'open-line 'delete-selection 'kill)

=== modified file 'lisp/rect.el'
--- a/lisp/rect.el      2013-01-01 09:11:05 +0000
+++ b/lisp/rect.el      2013-10-29 16:11:50 +0000
@@ -1,4 +1,4 @@
-;;; rect.el --- rectangle functions for GNU Emacs
+;;; rect.el --- rectangle functions for GNU Emacs  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 1985, 1999-2013 Free Software Foundation, Inc.
 
@@ -412,6 +412,152 @@
     (apply-on-rectangle 'rectangle-number-line-callback
                        start end format)))
 
+;;; New rectangle integration with kill-ring.
+
+;; FIXME: lots of known problems with the new rectangle support:
+;; - no key binding for mark-rectangle.
+;; - no access to the `string-rectangle' functionality.
+;; - lots of commands handle the region without paying attention to its
+;;   rectangular shape.
+
+(defvar-local rectangle--region nil
+  "If non-nil, the region is meant to delimit a rectangle.")
+
+(add-hook 'deactivate-mark-hook
+          (lambda () (kill-local-variable 'rectangle--region)))
+
+(add-function :around redisplay-highlight-region-function
+              #'rectangle--highlight-for-redisplay)
+(add-function :around redisplay-unhighlight-region-function
+              #'rectangle--unhighlight-for-redisplay)
+(add-function :around region-extract-function
+              #'rectangle--extract-region)
+
+;;;###autoload
+(defun rectangle-mark ()
+  "Toggle the region as rectangular."
+  (interactive)
+  (if rectangle--region
+      (kill-local-variable 'rectangle--region)
+    (unless (region-active-p) (push-mark-command t))
+    (setq rectangle--region t)))
+
+(defun rectangle--extract-region (orig &optional delete)
+  (if (not rectangle--region)
+      (funcall orig delete)
+    (let* ((strs (funcall (if delete
+                              #'delete-extract-rectangle
+                            #'extract-rectangle)
+                          (region-beginning) (region-end)))
+           (str (mapconcat #'identity strs "\n")))
+      (when (eq last-command 'kill-region)
+        ;; Try to prevent kill-region from appending this to some
+        ;; earlier element.
+        (setq last-command 'kill-region-dont-append))
+      (when strs
+        (put-text-property 0 (length str) 'yank-handler
+                           `(rectangle--insert-for-yank ,strs t)
+                           str)
+        str))))
+
+(defun rectangle--insert-for-yank (strs)
+  (push (point) buffer-undo-list)
+  (let ((undo-at-start buffer-undo-list))
+    (insert-rectangle strs)
+    (setq yank-undo-function
+          (lambda (_start _end)
+            (undo-start)
+            (setcar undo-at-start nil)  ;Turn it into a boundary.
+            (while (not (eq pending-undo-list (cdr undo-at-start)))
+              (undo-more 1))))))
+
+(defun rectangle--highlight-for-redisplay (orig start end window rol)
+  (cond
+   ((not rectangle--region)
+    (funcall orig start end window rol))
+   ((and (eq 'rectangle (car-safe rol))
+         (eq (nth 1 rol) (buffer-modified-tick))
+         (eq start (nth 2 rol))
+         (eq end (nth 3 rol)))
+    rol)
+   (t
+    (save-excursion
+      (let* ((nrol nil)
+             (old (if (eq 'rectangle (car-safe rol))
+                      (nthcdr 4 rol)
+                    (funcall redisplay-unhighlight-region-function rol)
+                    nil))
+             (ptcol (progn (goto-char start) (current-column)))
+             (markcol (progn (goto-char end) (current-column)))
+             (leftcol  (min ptcol markcol))
+             (rightcol (max ptcol markcol)))
+        (goto-char start)
+        (while (< (point) end)
+          (let* ((mleft (move-to-column leftcol))
+                 (left (point))
+                 (mright (move-to-column rightcol))
+                 (right (point))
+                 (ol
+                  (if (not old)
+                      (let ((ol (make-overlay left right)))
+                        (overlay-put ol 'window window)
+                        (overlay-put ol 'face 'region)
+                        ol)
+                    (let ((ol (pop old)))
+                      (move-overlay ol left right (current-buffer))
+                      ol))))
+            ;; `move-to-column' may stop before the column (if bumping into
+            ;; EOL) or overshoot it a little, when column is in the middle
+            ;; of a char.
+            (cond
+             ((< mleft leftcol)         ;`leftcol' is past EOL.
+              (overlay-put ol 'before-string
+                           (spaces-string (- leftcol mleft)))
+              (setq mright (max mright leftcol)))
+             ((and (> mleft leftcol)    ;`leftcol' is in the middle of a char.
+                   (eq (char-before left) ?\t))
+              (setq left (1- left))
+              (move-overlay ol left right)
+              (goto-char left)
+              (overlay-put ol 'before-string
+                           (spaces-string (- leftcol (current-column)))))
+             ((overlay-get ol 'before-string)
+              (overlay-put ol 'before-string nil)))
+            (cond
+             ((< mright rightcol)       ;`rightcol' is past EOL.
+              (let ((str (make-string (- rightcol mright) ?\s)))
+                (put-text-property 0 (length str) 'face 'region str)
+                ;; If cursor happens to be here, draw it *before* rather than
+                ;; after this highlighted pseudo-text.
+                (put-text-property 0 1 'cursor t str)
+                (overlay-put ol 'after-string str)))
+             ((and (> mright rightcol)  ;`rightcol' is in the middle of a char.
+                   (eq (char-before right) ?\t))
+              (setq right (1- right))
+              (move-overlay ol left right)
+              (goto-char right)
+              (let ((str (make-string (- rightcol (current-column)) ?\s)))
+                (put-text-property 0 (length str) 'face 'region str)
+                (overlay-put ol 'after-string str)))
+             ((overlay-get ol 'after-string)
+              (overlay-put ol 'after-string nil)))
+            (when (= leftcol rightcol)
+              ;; Make zero-width rectangles visible!
+              (overlay-put ol 'after-string
+                           (concat (propertize " "
+                                               'face '(region (:height 0.2)))
+                                   (overlay-get ol 'after-string))))
+            (push ol nrol))
+          (forward-line 1))
+        (mapc #'delete-overlay old)
+        `(rectangle ,(buffer-modified-tick) ,start ,end ,@nrol))))))
+
+(defun rectangle--unhighlight-for-redisplay (orig rol)
+  (if (not (eq 'rectangle (car-safe rol)))
+      (funcall orig rol)
+    (mapc #'delete-overlay (nthcdr 4 rol))
+    (setcar (cdr rol) nil)))
+
 (provide 'rect)
 
 ;;; rect.el ends here

=== modified file 'lisp/simple.el'
--- a/lisp/simple.el    2013-10-25 09:45:51 +0000
+++ b/lisp/simple.el    2013-10-29 16:11:50 +0000
@@ -874,6 +874,18 @@
   :group 'killing
   :version "24.1")
 
+(defvar region-extract-function
+  (lambda (delete)
+    (when (region-beginning)
+      (if (eq delete 'delete-only)
+          (delete-region (region-beginning) (region-end))
+        (filter-buffer-substring (region-beginning) (region-end) delete))))
+  "Function to get the region's content.
+Called with one argument DELETE.
+If DELETE is `delete-only', then only delete the region and the return value
+is undefined.  If DELETE is nil, just return the content as a string.
+If anything else, delete the region and return its content as a string.")
+
 (defun delete-backward-char (n &optional killflag)
   "Delete the previous N characters (following if N is negative).
 If Transient Mark mode is enabled, the mark is active, and N is 1,
@@ -895,8 +907,8 @@
              (= n 1))
         ;; If a region is active, kill or delete it.
         (if (eq delete-active-region 'kill)
-            (kill-region (region-beginning) (region-end))
-          (delete-region (region-beginning) (region-end))))
+            (kill-region (region-beginning) (region-end) 'region)
+           (funcall region-extract-function 'delete-only)))
        ;; In Overwrite mode, maybe untabify while deleting
        ((null (or (null overwrite-mode)
                   (<= n 0)
@@ -927,8 +939,9 @@
              (= n 1))
         ;; If a region is active, kill or delete it.
         (if (eq delete-active-region 'kill)
-            (kill-region (region-beginning) (region-end))
-          (delete-region (region-beginning) (region-end))))
+            (kill-region (region-beginning) (region-end) 'region)
+          (funcall region-extract-function 'delete-only)))
+
        ;; Otherwise, do simple deletion.
        (t (delete-char n killflag))))
 
@@ -3417,7 +3430,7 @@
   :group 'killing
   :version "23.2")
 
-(defun kill-new (string &optional replace yank-handler)
+(defun kill-new (string &optional replace)
   "Make STRING the latest kill in the kill ring.
 Set `kill-ring-yank-pointer' to point to it.
 If `interprogram-cut-function' is non-nil, apply it to STRING.
@@ -3432,13 +3445,6 @@
 argument is not used by `insert-for-yank'.  However, since Lisp code
 may access and use elements from the kill ring directly, the STRING
 argument should still be a \"useful\" string for such uses."
-  (if (> (length string) 0)
-      (if yank-handler
-         (put-text-property 0 (length string)
-                            'yank-handler yank-handler string))
-    (if yank-handler
-       (signal 'args-out-of-range
-               (list string "yank-handler specified for empty string"))))
   (unless (and kill-do-not-save-duplicates
               ;; Due to text properties such as 'yank-handler that
               ;; can alter the contents to yank, comparison using
@@ -3466,19 +3472,15 @@
   (setq kill-ring-yank-pointer kill-ring)
   (if interprogram-cut-function
       (funcall interprogram-cut-function string)))
-(set-advertised-calling-convention
- 'kill-new '(string &optional replace) "23.3")
 
-(defun kill-append (string before-p &optional yank-handler)
+(defun kill-append (string before-p)
   "Append STRING to the end of the latest kill in the kill ring.
 If BEFORE-P is non-nil, prepend STRING to the kill.
 If `interprogram-cut-function' is set, pass the resulting kill to it."
   (let* ((cur (car kill-ring)))
     (kill-new (if before-p (concat string cur) (concat cur string))
              (or (= (length cur) 0)
-                 (equal yank-handler (get-text-property 0 'yank-handler cur)))
-             yank-handler)))
-(set-advertised-calling-convention 'kill-append '(string before-p) "23.3")
+                 (equal nil (get-text-property 0 'yank-handler cur))))))
 
 (defcustom yank-pop-change-selection nil
   "Whether rotating the kill ring changes the window system selection.
@@ -3539,7 +3541,7 @@
   :type 'boolean
   :group 'killing)
 
-(defun kill-region (beg end &optional yank-handler)
+(defun kill-region (beg end &optional region)
   "Kill (\"cut\") text between point and mark.
 This deletes the text from the buffer and saves it in the kill ring.
 The command \\[yank] can retrieve it from there.
@@ -3559,19 +3561,24 @@
 Any command that calls this function is a \"kill command\".
 If the previous command was also a kill command,
 the text killed this time appends to the text killed last time
-to make one entry in the kill ring."
+to make one entry in the kill ring.
+
+The optional argument REGION if non-nil, indicates that we're not just killing
+some text between BEG and END, but we're killing the region."
   ;; Pass point first, then mark, because the order matters
   ;; when calling kill-append.
-  (interactive (list (point) (mark)))
+  (interactive (list (point) (mark) 'region))
   (unless (and beg end)
     (error "The mark is not set now, so there is no region"))
   (condition-case nil
-      (let ((string (filter-buffer-substring beg end t)))
+      (let ((string (if region
+                        (funcall region-extract-function 'delete)
+                      (filter-buffer-substring beg end 'delete))))
        (when string                    ;STRING is nil if BEG = END
          ;; Add that string to the kill ring, one way or another.
          (if (eq last-command 'kill-region)
-             (kill-append string (< end beg) yank-handler)
-           (kill-new string nil yank-handler)))
+             (kill-append string (< end beg))
+           (kill-new string nil)))
        (when (or string (eq last-command 'kill-region))
          (setq this-command 'kill-region))
        (setq deactivate-mark t)
@@ -3582,7 +3589,7 @@
      ;; We should beep, in case the user just isn't aware of this.
      ;; However, there's no harm in putting
      ;; the region's text in the kill ring, anyway.
-     (copy-region-as-kill beg end)
+     (copy-region-as-kill beg end region)
      ;; Set this-command now, so it will be set even if we get an error.
      (setq this-command 'kill-region)
      ;; This should barf, if appropriate, and give us the correct error.
@@ -3592,26 +3599,31 @@
        (barf-if-buffer-read-only)
        ;; If the buffer isn't read-only, the text is.
        (signal 'text-read-only (list (current-buffer)))))))
-(set-advertised-calling-convention 'kill-region '(beg end) "23.3")
 
 ;; copy-region-as-kill no longer sets this-command, because it's confusing
 ;; to get two copies of the text when the user accidentally types M-w and
 ;; then corrects it with the intended C-w.
-(defun copy-region-as-kill (beg end)
+(defun copy-region-as-kill (beg end &optional region)
   "Save the region as if killed, but don't kill it.
 In Transient Mark mode, deactivate the mark.
 If `interprogram-cut-function' is non-nil, also save the text for a window
 system cut and paste.
 
+The optional argument REGION if non-nil, indicates that we're not just copying
+some text between BEG and END, but we're copying the region.
+
 This command's old key binding has been given to `kill-ring-save'."
-  (interactive "r")
+  (interactive "r\np")
+  (let ((str (if region
+                 (funcall region-extract-function)
+               (filter-buffer-substring beg end))))
   (if (eq last-command 'kill-region)
-      (kill-append (filter-buffer-substring beg end) (< end beg))
-    (kill-new (filter-buffer-substring beg end)))
+        (kill-append str (< end beg))
+      (kill-new str)))
   (setq deactivate-mark t)
   nil)
 
-(defun kill-ring-save (beg end)
+(defun kill-ring-save (beg end &optional region)
   "Save the region as if killed, but don't kill it.
 In Transient Mark mode, deactivate the mark.
 If `interprogram-cut-function' is non-nil, also save the text for a window
@@ -3620,10 +3632,13 @@
 If you want to append the killed line to the last killed text,
 use \\[append-next-kill] before \\[kill-ring-save].
 
+The optional argument REGION if non-nil, indicates that we're not just copying
+some text between BEG and END, but we're copying the region.
+
 This command is similar to `copy-region-as-kill', except that it gives
 visual feedback indicating the extent of the region being copied."
-  (interactive "r")
-  (copy-region-as-kill beg end)
+  (interactive "r\np")
+  (copy-region-as-kill beg end region)
   ;; This use of called-interactively-p is correct because the code it
   ;; controls just gives the user visual feedback.
   (if (called-interactively-p 'interactive)
@@ -4203,8 +4218,7 @@
                  (or (x-selection-owner-p 'PRIMARY)
                      (null (x-selection-exists-p 'PRIMARY))))
             (x-set-selection 'PRIMARY
-                             (buffer-substring (region-beginning)
-                                               (region-end))))))
+                              (funcall region-extract-function nil)))))
     (if (and (null force)
             (or (eq transient-mark-mode 'lambda)
                 (and (eq (car-safe transient-mark-mode) 'only)
@@ -4289,9 +4303,60 @@
 also checks the value of `use-empty-active-region'."
   (and transient-mark-mode mark-active))
 
-(defvar mark-ring nil
+
+(defvar redisplay-unhighlight-region-function
+  (lambda (rol) (when (overlayp rol) (delete-overlay rol))))
+
+(defvar redisplay-highlight-region-function
+  (lambda (start end window rol)
+    (if (not (overlayp rol))
+        (let ((nrol (make-overlay start end)))
+          (funcall redisplay-unhighlight-region-function rol)
+          (overlay-put nrol 'window window)
+          (overlay-put nrol 'face 'region)
+          nrol)
+      (unless (and (eq (overlay-buffer rol) (current-buffer))
+                   (eq (overlay-start rol) start)
+                   (eq (overlay-end rol) end))
+        (move-overlay rol start end (current-buffer)))
+      rol)))
+
+(defun redisplay--update-region-highlight (window)
+  (with-current-buffer (window-buffer window)
+    (let ((rol (window-parameter window 'internal-region-overlay)))
+      (if (not (region-active-p))
+          (funcall redisplay-unhighlight-region-function rol)
+        (let* ((pt (window-point window))
+               (mark (mark))
+               (start (min pt mark))
+               (end   (max pt mark))
+               (new
+                (funcall redisplay-highlight-region-function
+                         start end window rol)))
+          (unless (equal new rol)
+            (set-window-parameter window 'internal-region-overlay
+                                  new)))))))
+
+(defun redisplay--update-region-highlights (windows)
+  (with-demoted-errors "redisplay--update-region-highlights: %S"
+    (if (null windows)
+        (redisplay--update-region-highlight (selected-window))
+      (unless (listp windows) (setq windows (window-list-1 nil nil t)))
+      (if highlight-nonselected-windows
+          (mapc #'redisplay--update-region-highlight windows)
+        (let ((msw (and (window-minibuffer-p) (minibuffer-selected-window))))
+          (dolist (w windows)
+            (if (or (eq w (selected-window)) (eq w msw))
+                (redisplay--update-region-highlight w)
+              (funcall redisplay-unhighlight-region-function
+                       (window-parameter w 'internal-region-overlay)))))))))
+
+(add-function :before pre-redisplay-function
+              #'redisplay--update-region-highlights)
+
+
+(defvar-local mark-ring nil
   "The list of former marks of the current buffer, most recent first.")
-(make-variable-buffer-local 'mark-ring)
 (put 'mark-ring 'permanent-local t)
 
 (defcustom mark-ring-max 16
@@ -4466,7 +4531,6 @@
        (temp-highlight (eq (car-safe transient-mark-mode) 'only)))
     (if (null omark)
         (error "No mark set in this buffer"))
-    (deactivate-mark)
     (set-mark (point))
     (goto-char omark)
     (cond (temp-highlight

=== modified file 'lisp/subr.el'
--- a/lisp/subr.el      2013-10-25 01:10:27 +0000
+++ b/lisp/subr.el      2013-10-29 16:11:50 +0000
@@ -2818,6 +2818,7 @@
     val))
 
 ;;;; Support for yanking and text properties.
+;; Why here in subr.el rather than in simple.el?  --Stef
 
 (defvar yank-handled-properties)
 (defvar yank-excluded-properties)

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-10-29 16:08:08 +0000
+++ b/src/ChangeLog     2013-10-29 16:11:50 +0000
@@ -1,3 +1,27 @@
+2013-10-29  Stefan Monnier  <address@hidden>
+
+       * xdisp.c (prepare_menu_bars): Call Vpre_redisplay_function.
+       (syms_of_xdisp): Declare pre-redisplay-function.
+       (markpos_of_region): Remove function.
+       (init_iterator, compute_stop_pos, handle_face_prop)
+       (face_before_or_after_it_pos, reseat_to_string)
+       (get_next_display_element, window_buffer_changed)
+       (redisplay_internal, try_cursor_movement, redisplay_window)
+       (try_window_reusing_current_matrix, try_window_id, display_line)
+       (note_mode_line_or_margin_highlight, note_mouse_highlight)
+       (display_string, mouse_face_from_buffer_pos): Remove region handling.
+       * window.h (struct window): Remove field `region_showing'.
+       * dispextern.h (struct it): Remove region_beg/end_charpos.
+       (face_at_buffer_position, face_for_overlay_string)
+       (face_at_string_position): Update prototypes.
+       * xfaces.c (face_at_buffer_position, face_for_overlay_string)
+       (face_at_string_position): Remove `region_beg' and `region_end' args.
+       * fontset.c (Finternal_char_font):
+       * font.c (font_at, font_range): Adjust calls accordingly.
+       * insdel.c (Qregion_extract_function): New var.
+       (syms_of_insdel): Initialize it.
+       (prepare_to_modify_buffer_1): Use it.
+
 2013-10-29  Dmitry Antipov  <address@hidden>
 
        Prefer 'unsigned long' to 'long unsigned int' and 'unsigned long int'.

=== modified file 'src/dispextern.h'
--- a/src/dispextern.h  2013-10-29 05:55:25 +0000
+++ b/src/dispextern.h  2013-10-29 16:11:50 +0000
@@ -2214,10 +2214,6 @@
      used for overlay strings and strings from display properties.  */
   ptrdiff_t string_nchars;
 
-  /* Start and end of a visible region; -1 if the region is not
-     visible in the window.  */
-  ptrdiff_t region_beg_charpos, region_end_charpos;
-
   /* Position at which redisplay end trigger functions should be run.  */
   ptrdiff_t redisplay_end_trigger_charpos;
 
@@ -3325,7 +3321,7 @@
 void init_sigio (int);
 void ignore_sigio (void);
 
-/* Defined in xfaces.c */
+/* Defined in xfaces.c.  */
 
 #ifdef HAVE_X_WINDOWS
 void unload_color (struct frame *, unsigned long);
@@ -3352,16 +3348,13 @@
 void free_frame_faces (struct frame *);
 void recompute_basic_faces (struct frame *);
 int face_at_buffer_position (struct window *w, ptrdiff_t pos,
-                             ptrdiff_t region_beg, ptrdiff_t region_end,
                              ptrdiff_t *endptr, ptrdiff_t limit,
                              int mouse, int base_face_id);
 int face_for_overlay_string (struct window *w, ptrdiff_t pos,
-                             ptrdiff_t region_beg, ptrdiff_t region_end,
                              ptrdiff_t *endptr, ptrdiff_t limit,
                              int mouse, Lisp_Object overlay);
 int face_at_string_position (struct window *w, Lisp_Object string,
                              ptrdiff_t pos, ptrdiff_t bufpos,
-                             ptrdiff_t region_beg, ptrdiff_t region_end,
                              ptrdiff_t *endptr, enum face_id, int mouse);
 int merge_faces (struct frame *, Lisp_Object, int, int);
 int compute_char_face (struct frame *, int, Lisp_Object);
@@ -3369,7 +3362,7 @@
 extern Lisp_Object Qforeground_color, Qbackground_color;
 extern char unspecified_fg[], unspecified_bg[];
 
-/* Defined in xfns.c  */
+/* Defined in xfns.c.  */
 
 #ifdef HAVE_X_WINDOWS
 void gamma_correct (struct frame *, XColor *);

=== modified file 'src/font.c'
--- a/src/font.c        2013-10-25 06:55:36 +0000
+++ b/src/font.c        2013-10-29 16:11:50 +0000
@@ -3669,10 +3669,10 @@
       ptrdiff_t endptr;
 
       if (STRINGP (string))
-       face_id = face_at_string_position (w, string, pos, 0, -1, -1, &endptr,
+       face_id = face_at_string_position (w, string, pos, 0, &endptr,
                                           DEFAULT_FACE_ID, 0);
       else
-       face_id = face_at_buffer_position (w, pos, -1, -1, &endptr,
+       face_id = face_at_buffer_position (w, pos, &endptr,
                                           pos + 100, 0, -1);
       face = FACE_FROM_ID (f, face_id);
     }
@@ -3716,7 +3716,7 @@
        {
          int face_id;
 
-         face_id = face_at_buffer_position (w, pos, 0, 0, &ignore,
+         face_id = face_at_buffer_position (w, pos, &ignore,
                                             *limit, 0, -1);
          face = FACE_FROM_ID (XFRAME (w->frame), face_id);
        }

=== modified file 'src/fontset.c'
--- a/src/fontset.c     2013-09-24 06:43:20 +0000
+++ b/src/fontset.c     2013-10-29 16:11:50 +0000
@@ -1875,7 +1875,7 @@
        return Qnil;
       w = XWINDOW (window);
       f = XFRAME (w->frame);
-      face_id = face_at_buffer_position (w, pos, -1, -1, &dummy,
+      face_id = face_at_buffer_position (w, pos, &dummy,
                                         pos + 100, 0, -1);
     }
   if (! CHAR_VALID_P (c))

=== modified file 'src/insdel.c'
--- a/src/insdel.c      2013-10-07 15:03:33 +0000
+++ b/src/insdel.c      2013-10-29 16:11:50 +0000
@@ -1778,6 +1778,8 @@
   bset_point_before_scroll (current_buffer, Qnil);
 }
 
+Lisp_Object Qregion_extract_function;
+
 /* Check that it is okay to modify the buffer between START and END,
    which are char positions.
 
@@ -1843,6 +1845,7 @@
 #endif /* not CLASH_DETECTION */
 
   /* If `select-active-regions' is non-nil, save the region text.  */
+  /* FIXME: Move this to Elisp (via before-change-functions).  */
   if (!NILP (BVAR (current_buffer, mark_active))
       && !inhibit_modification_hooks
       && XMARKER (BVAR (current_buffer, mark))->buffer
@@ -1854,10 +1857,8 @@
     {
       ptrdiff_t b = marker_position (BVAR (current_buffer, mark));
       ptrdiff_t e = PT;
-      if (b < e)
-       Vsaved_region_selection = make_buffer_string (b, e, 0);
-      else if (b > e)
-       Vsaved_region_selection = make_buffer_string (e, b, 0);
+      Vsaved_region_selection
+       = call1 (Fsymbol_value (Qregion_extract_function), Qnil);
     }
 
   signal_before_change (start, end, preserve_ptr);
@@ -2202,5 +2203,7 @@
   inhibit_modification_hooks = 0;
   DEFSYM (Qinhibit_modification_hooks, "inhibit-modification-hooks");
 
+  DEFSYM (Qregion_extract_function, "region-extract-function");
+
   defsubr (&Scombine_after_change_execute);
 }

=== modified file 'src/window.h'
--- a/src/window.h      2013-10-02 12:08:27 +0000
+++ b/src/window.h      2013-10-29 16:11:50 +0000
@@ -341,10 +341,6 @@
        y-direction (smooth scrolling).  */
     int vscroll;
 
-    /* If we have highlighted the region (or any part of it), the mark
-       (region start) position; otherwise zero.  */
-    ptrdiff_t region_showing;
-
     /* Z_BYTE - buffer position of the last glyph in the current matrix of W.
        Should be nonnegative, and only valid if window_end_valid is nonzero.  
*/
     ptrdiff_t window_end_bytepos;

=== modified file 'src/xdisp.c'
--- a/src/xdisp.c       2013-10-28 10:58:01 +0000
+++ b/src/xdisp.c       2013-10-29 16:11:50 +0000
@@ -2601,24 +2601,6 @@
 
 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
 
-/* Return mark position if current buffer has the region of non-zero length,
-   or -1 otherwise.  */
-
-static ptrdiff_t
-markpos_of_region (void)
-{
-  if (!NILP (Vtransient_mark_mode)
-      && !NILP (BVAR (current_buffer, mark_active))
-      && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
-    {
-      ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
-
-      if (markpos != PT)
-       return markpos;
-    }
-  return -1;
-}
-
 /***********************************************************************
                       Iterator initialization
  ***********************************************************************/
@@ -2647,7 +2629,6 @@
               ptrdiff_t charpos, ptrdiff_t bytepos,
               struct glyph_row *row, enum face_id base_face_id)
 {
-  ptrdiff_t markpos;
   enum face_id remapped_base_face_id = base_face_id;
 
   /* Some precondition checks.  */
@@ -2751,28 +2732,6 @@
   /* Are multibyte characters enabled in current_buffer?  */
   it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
 
-  /* If visible region is of non-zero length, set IT->region_beg_charpos
-     and IT->region_end_charpos to the start and end of a visible region
-     in window IT->w.  Set both to -1 to indicate no region.  */
-  markpos = markpos_of_region ();
-  if (markpos >= 0
-      /* Maybe highlight only in selected window.  */
-      && (/* Either show region everywhere.  */
-         highlight_nonselected_windows
-         /* Or show region in the selected window.  */
-         || w == XWINDOW (selected_window)
-         /* Or show the region if we are in the mini-buffer and W is
-            the window the mini-buffer refers to.  */
-         || (MINI_WINDOW_P (XWINDOW (selected_window))
-             && WINDOWP (minibuf_selected_window)
-             && w == XWINDOW (minibuf_selected_window))))
-    {
-      it->region_beg_charpos = min (PT, markpos);
-      it->region_end_charpos = max (PT, markpos);
-    }
-  else
-    it->region_beg_charpos = it->region_end_charpos = -1;
-
   /* Get the position at which the redisplay_end_trigger hook should
      be run, if it is to be run at all.  */
   if (MARKERP (w->redisplay_end_trigger)
@@ -3406,16 +3365,6 @@
       if (pos < it->stop_charpos)
        it->stop_charpos = pos;
 
-      /* If showing the region, we have to stop at the region
-        start or end because the face might change there.  */
-      if (it->region_beg_charpos > 0)
-       {
-         if (IT_CHARPOS (*it) < it->region_beg_charpos)
-           it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
-         else if (IT_CHARPOS (*it) < it->region_end_charpos)
-           it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
-       }
-
       /* Set up variables for computing the stop position from text
          property changes.  */
       XSETBUFFER (object, current_buffer);
@@ -3799,8 +3748,6 @@
       new_face_id
        = face_at_buffer_position (it->w,
                                   IT_CHARPOS (*it),
-                                  it->region_beg_charpos,
-                                  it->region_end_charpos,
                                   &next_stop,
                                   (IT_CHARPOS (*it)
                                    + TEXT_PROP_DISTANCE_LIMIT),
@@ -3877,8 +3824,6 @@
          base_face_id
            = face_for_overlay_string (it->w,
                                       IT_CHARPOS (*it),
-                                      it->region_beg_charpos,
-                                      it->region_end_charpos,
                                       &next_stop,
                                       (IT_CHARPOS (*it)
                                        + TEXT_PROP_DISTANCE_LIMIT),
@@ -3907,8 +3852,6 @@
                                             it->string,
                                             IT_STRING_CHARPOS (*it),
                                             bufpos,
-                                            it->region_beg_charpos,
-                                            it->region_end_charpos,
                                             &next_stop,
                                             base_face_id, 0);
 
@@ -4051,8 +3994,6 @@
                                         it->string,
                                         charpos,
                                         bufpos,
-                                        it->region_beg_charpos,
-                                        it->region_end_charpos,
                                         &next_check_charpos,
                                         base_face_id, 0);
 
@@ -4142,8 +4083,6 @@
       /* Determine face for CHARSET_ASCII, or unibyte.  */
       face_id = face_at_buffer_position (it->w,
                                         CHARPOS (pos),
-                                        it->region_beg_charpos,
-                                        it->region_end_charpos,
                                         &next_check_charpos,
                                         limit, 0, -1);
 
@@ -6441,9 +6380,6 @@
                  ptrdiff_t charpos, ptrdiff_t precision, int field_width,
                  int multibyte)
 {
-  /* No region in strings.  */
-  it->region_beg_charpos = it->region_end_charpos = -1;
-
   /* No text property checks performed by default, but see below.  */
   it->stop_charpos = -1;
 
@@ -7033,8 +6969,7 @@
                  INC_TEXT_POS (pos, it->multibyte_p);
 
                  next_face_id = face_at_buffer_position
-                   (it->w, CHARPOS (pos), it->region_beg_charpos,
-                    it->region_end_charpos, &ignore,
+                   (it->w, CHARPOS (pos), &ignore,
                     (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
                     -1);
                  it->end_of_box_run_p
@@ -10906,8 +10841,7 @@
          && UNCHANGED_MODIFIED < MODIFF);
 }
 
-/* Nonzero if W's buffer was changed but not saved or Transient Mark mode
-   is enabled and mark of W's buffer was changed since last W's update.  */
+/* Nonzero if W's buffer was changed but not saved.  */
 
 static int
 window_buffer_changed (struct window *w)
@@ -10916,9 +10850,7 @@
 
   eassert (BUFFER_LIVE_P (b));
 
-  return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
-         || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
-             != (w->region_showing != 0)));
+  return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
 }
 
 /* Nonzero if W has %c in its mode line and mode line should be updated.  */
@@ -11273,6 +11205,10 @@
   all_windows = (update_mode_lines
                 || buffer_shared_and_changed ()
                 || windows_or_buffers_changed);
+
+  if (FUNCTIONP (Vpre_redisplay_function))
+    safe_call1 (Vpre_redisplay_function, all_windows ? Qt : Qnil);
+
   if (all_windows)
     {
       Lisp_Object tail, frame;
@@ -13147,17 +13083,6 @@
       clear_garbaged_frames ();
     }
 
-  /* If showing the region, and mark has changed, we must redisplay
-     the whole window.  The assignment to this_line_start_pos prevents
-     the optimization directly below this if-statement.  */
-  if (((!NILP (Vtransient_mark_mode)
-       && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
-       != (w->region_showing > 0))
-      || (w->region_showing
-         && w->region_showing
-         != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
-    CHARPOS (this_line_start_pos) = 0;
-
   /* Optimize the case that only the line containing the cursor in the
      selected window has changed.  Variables starting with this_ are
      set in display_line and record information about the line
@@ -13317,13 +13242,7 @@
        }
       /* If highlighting the region, or if the cursor is in the echo area,
         then we can't just move the cursor.  */
-      else if (! (!NILP (Vtransient_mark_mode)
-                 && !NILP (BVAR (current_buffer, mark_active)))
-              && (EQ (selected_window,
-                      BVAR (current_buffer, last_selected_window))
-                  || highlight_nonselected_windows)
-              && !w->region_showing
-              && NILP (Vshow_trailing_whitespace)
+      else if (NILP (Vshow_trailing_whitespace)
               && !cursor_in_echo_area)
        {
          struct it it;
@@ -15003,11 +14922,6 @@
       && !update_mode_lines
       && !windows_or_buffers_changed
       && !f->cursor_type_changed
-      /* Can't use this case if highlighting a region.  When a
-         region exists, cursor movement has to do more than just
-         set the cursor.  */
-      && markpos_of_region () < 0
-      && !w->region_showing
       && NILP (Vshow_trailing_whitespace)
       /* This code is not used for mini-buffer for the sake of the case
         of redisplaying to replace an echo area message; since in
@@ -15622,7 +15536,7 @@
             Move it back to a fully-visible line.  */
          new_vpos = window_box_height (w);
        }
-      else if (w->cursor.vpos >=0)
+      else if (w->cursor.vpos >= 0)
        {
          /* Some people insist on not letting point enter the scroll
             margin, even though this part handles windows that didn't
@@ -15680,12 +15594,14 @@
 
          /* If we are highlighting the region, then we just changed
             the region, so redisplay to show it.  */
-         if (markpos_of_region () >= 0)
+         /* FIXME: We need to (re)run pre-redisplay-function!  */
+         /* if (markpos_of_region () >= 0)
            {
              clear_glyph_matrix (w->desired_matrix);
              if (!try_window (window, startp, 0))
                goto need_larger_matrices;
            }
+         */
        }
 
 #ifdef GLYPH_DEBUG
@@ -16380,10 +16296,8 @@
       || f->cursor_type_changed)
     return 0;
 
-  /* Can't do this if region may have changed.  */
-  if (markpos_of_region () >= 0
-      || w->region_showing
-      || !NILP (Vshow_trailing_whitespace))
+  /* Can't do this if showing trailing whitespace.  */
+  if (!NILP (Vshow_trailing_whitespace))
     return 0;
 
   /* If top-line visibility has changed, give up.  */
@@ -17181,19 +17095,10 @@
   if (!w->window_end_valid)
     GIVE_UP (8);
 
-  /* Can't use this if highlighting a region because a cursor movement
-     will do more than just set the cursor.  */
-  if (markpos_of_region () >= 0)
-    GIVE_UP (9);
-
   /* Likewise if highlighting trailing whitespace.  */
   if (!NILP (Vshow_trailing_whitespace))
     GIVE_UP (11);
 
-  /* Likewise if showing a region.  */
-  if (w->region_showing)
-    GIVE_UP (10);
-
   /* Can't use this if overlay arrow position and/or string have
      changed.  */
   if (overlay_arrows_changed_p ())
@@ -19277,9 +19182,6 @@
       return 0;
     }
 
-  /* Is IT->w showing the region?  */
-  it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos 
: 0;
-
   /* Clear the result glyph row and enable it.  */
   prepare_desired_row (row);
 
@@ -22413,9 +22315,7 @@
 
       it->face_id
        = face_at_string_position (it->w, face_string, face_string_pos,
-                                  0, it->region_beg_charpos,
-                                  it->region_end_charpos,
-                                  &endptr, it->base_face_id, 0);
+                                  0, &endptr, it->base_face_id, 0);
       face = FACE_FROM_ID (it->f, it->face_id);
       it->face_box_p = face->box != FACE_NO_BOX;
     }
@@ -27419,7 +27319,7 @@
 
   hlinfo->mouse_face_window = window;
   hlinfo->mouse_face_face_id
-    = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
+    = face_at_buffer_position (w, mouse_charpos, &ignore,
                               mouse_charpos + 1,
                               !hlinfo->mouse_face_hidden, -1);
   show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
@@ -28100,8 +28000,7 @@
 
          hlinfo->mouse_face_face_id = face_at_string_position (w, string,
                                                                charpos,
-                                                               0, 0, 0,
-                                                               &ignore,
+                                                               0, &ignore,
                                                                glyph->face_id,
                                                                1);
          show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
@@ -28402,7 +28301,7 @@
              hlinfo->mouse_face_past_end = 0;
              hlinfo->mouse_face_window = window;
              hlinfo->mouse_face_face_id
-               = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
+               = face_at_string_position (w, object, pos, 0, &ignore,
                                           glyph->face_id, 1);
              show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
              cursor = No_Cursor;
@@ -28449,13 +28348,14 @@
                     the first row visible in a window does not
                     necessarily display the character whose position
                     is the smallest.  */
-                 Lisp_Object lim1 =
-                   NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
+                 Lisp_Object lim1
+                   = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
                    ? Fmarker_position (w->start)
                    : Qnil;
-                 Lisp_Object lim2 =
-                   NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
-                   ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos)
+                 Lisp_Object lim2
+                   = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
+                   ? make_number (BUF_Z (XBUFFER (buffer))
+                                  - w->window_end_pos)
                    : Qnil;
 
                  if (NILP (overlay))
@@ -29788,6 +29688,13 @@
   DEFSYM (Qthin_space, "thin-space");
   DEFSYM (Qzero_width, "zero-width");
 
+  DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
+              doc: /* Function run just before redisplay.
+It is called with one argument, which is the set of windows that are to
+be redisplayed.  This set can be nil (meaning, only the selected window),
+or t (meaning all windows).  */);
+  Vpre_redisplay_function = intern ("ignore");
+
   DEFSYM (Qglyphless_char_display, "glyphless-char-display");
   Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
 

=== modified file 'src/xfaces.c'
--- a/src/xfaces.c      2013-10-29 16:08:08 +0000
+++ b/src/xfaces.c      2013-10-29 16:11:50 +0000
@@ -5916,7 +5916,6 @@
 
 int
 face_at_buffer_position (struct window *w, ptrdiff_t pos,
-                        ptrdiff_t region_beg, ptrdiff_t region_end,
                         ptrdiff_t *endptr, ptrdiff_t limit,
                         int mouse, int base_face_id)
 {
@@ -5937,8 +5936,6 @@
   XSETFASTINT (position, pos);
 
   endpos = ZV;
-  if (pos < region_beg && region_beg < endpos)
-    endpos = region_beg;
 
   /* Get the `face' or `mouse_face' text property at POS, and
      determine the next position at which the property changes.  */
@@ -5974,8 +5971,7 @@
 
   /* Optimize common cases where we can use the default face.  */
   if (noverlays == 0
-      && NILP (prop)
-      && !(pos >= region_beg && pos < region_end))
+      && NILP (prop))
     return default_face->id;
 
   /* Begin with attributes from the default face.  */
@@ -6002,15 +5998,6 @@
        endpos = oendpos;
     }
 
-  /* If in the region, merge in the region face.  */
-  if (pos >= region_beg && pos < region_end)
-    {
-      merge_named_face (f, Qregion, attrs, 0);
-
-      if (region_end < endpos)
-       endpos = region_end;
-    }
-
   *endptr = endpos;
 
   /* Look up a realized face with the given face attributes,
@@ -6026,7 +6013,6 @@
 
 int
 face_for_overlay_string (struct window *w, ptrdiff_t pos,
-                        ptrdiff_t region_beg, ptrdiff_t region_end,
                         ptrdiff_t *endptr, ptrdiff_t limit,
                         int mouse, Lisp_Object overlay)
 {
@@ -6045,8 +6031,6 @@
   XSETFASTINT (position, pos);
 
   endpos = ZV;
-  if (pos < region_beg && region_beg < endpos)
-    endpos = region_beg;
 
   /* Get the `face' or `mouse_face' text property at POS, and
      determine the next position at which the property changes.  */
@@ -6060,7 +6044,6 @@
 
   /* Optimize common case where we can use the default face.  */
   if (NILP (prop)
-      && !(pos >= region_beg && pos < region_end)
       && NILP (Vface_remapping_alist))
     return DEFAULT_FACE_ID;
 
@@ -6072,15 +6055,6 @@
   if (!NILP (prop))
     merge_face_ref (f, prop, attrs, 1, 0);
 
-  /* If in the region, merge in the region face.  */
-  if (pos >= region_beg && pos < region_end)
-    {
-      merge_named_face (f, Qregion, attrs, 0);
-
-      if (region_end < endpos)
-       endpos = region_end;
-    }
-
   *endptr = endpos;
 
   /* Look up a realized face with the given face attributes,
@@ -6113,7 +6087,6 @@
 int
 face_at_string_position (struct window *w, Lisp_Object string,
                         ptrdiff_t pos, ptrdiff_t bufpos,
-                        ptrdiff_t region_beg, ptrdiff_t region_end,
                         ptrdiff_t *endptr, enum face_id base_face_id,
                         int mouse_p)
 {
@@ -6145,15 +6118,8 @@
   base_face = FACE_FROM_ID (f, base_face_id);
   eassert (base_face);
 
-  /* Optimize the default case that there is no face property and we
-     are not in the region.  */
+  /* Optimize the default case that there is no face property.  */
   if (NILP (prop)
-      && (base_face_id != DEFAULT_FACE_ID
-         /* BUFPOS <= 0 means STRING is not an overlay string, so
-            that the region doesn't have to be taken into account.  */
-         || bufpos <= 0
-         || bufpos < region_beg
-         || bufpos >= region_end)
       && (multibyte_p
          /* We can't realize faces for different charsets differently
             if we don't have fonts, so we can stop here if not working
@@ -6169,12 +6135,6 @@
   if (!NILP (prop))
     merge_face_ref (f, prop, attrs, 1, 0);
 
-  /* If in the region, merge in the region face.  */
-  if (bufpos
-      && bufpos >= region_beg
-      && bufpos < region_end)
-    merge_named_face (f, Qregion, attrs, 0);
-
   /* Look up a realized face with the given face attributes,
      or realize a new one for ASCII characters.  */
   return lookup_face (f, attrs);


reply via email to

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