]> code.delx.au - gnu-emacs/blobdiff - lisp/windmove.el
From Ulf Jasper <ulf.jasper@web.de>:
[gnu-emacs] / lisp / windmove.el
index fc5e864391c40d7f9f8ebccdfd0bcf18bd3ba004..986280c0bb1aebe55fd66690edf848d71bea7b98 100644 (file)
@@ -321,14 +321,15 @@ of the frame; (X-MAX, Y-MAX) is the zero-based coordinate of the
 bottom-right corner of the frame.
 For example, if a frame has 76 rows and 181 columns, the return value
 from `windmove-frame-edges' will be the list (0 0 180 75)."
-  (let ((frame (if window
-                   (window-frame window)
-                 (selected-frame))))
-    (let ((x-min 0)
-          (y-min 0)
-          (x-max (1- (frame-width frame))) ; 1- for last row & col here
-          (y-max (1- (frame-height frame))))
-      (list x-min y-min x-max y-max))))
+  (let* ((frame (if window
+                   (window-frame window)
+                 (selected-frame)))
+        (top-left (window-edges (frame-first-window frame)))
+        (x-min (nth 0 top-left))
+        (y-min (nth 1 top-left))
+        (x-max (1- (frame-width frame))) ; 1- for last row & col
+        (y-max (1- (frame-height frame))))
+    (list x-min y-min x-max y-max)))
 
 ;; it turns out that constraining is always a good thing, even when
 ;; wrapping is going to happen.  this is because:
@@ -405,7 +406,7 @@ Returns the wrapped coordinate."
 
 
 ;; `windmove-coordinates-of-position' is stolen and modified from the
-;; Emacs Lisp Reference Manual, section 27.2.5.  It seems to work
+;; Emacs 20 Lisp Reference Manual, section 27.2.5.  It seems to work
 ;; okay, although I am bothered by the fact that tab-offset (the cdr
 ;; of the next-to- last argument) is set to 0.  On the other hand, I
 ;; can't find a single usage of `compute-motion' anywhere that doesn't
@@ -417,30 +418,43 @@ Returns the wrapped coordinate."
 ;; the number that `window-width' gives, or continuation lines aren't
 ;; counted correctly.  I haven't seen anyone doing this before,
 ;; though.
-(defun windmove-coordinates-of-position (pos &optional window)
-  "Return the coordinates of position POS in window WINDOW.
+;;
+;; Now updated for Emacs 21, based on the Emacs 21 Lisp Reference
+;; Manual, section 30.2.5.  It is no longer necessary to subtract
+;; 1 for the usable width of the window.
+;; TODO: also handle minibuffer case, w/ `minibuffer-prompt-width'.
+(defun windmove-coordinates-of-position (pos)
+  "Return the coordinates of position POS in the current window.
 Return the window-based coodinates in a cons pair: (HPOS . VPOS),
 where HPOS and VPOS are the zero-based x and y components of the
-screen location of POS.  If WINDOW is nil, return the coordinates in
-the currently selected window.
+screen location of POS.
 As an example, if point is in the top left corner of a window, then
 the return value from `windmove-coordinates-of-position' is (0 . 0)
 regardless of the where point is in the buffer and where the window
 is placed in the frame."
-  (let* ((wind (if (null window) (selected-window) window))
-         (usable-width (1- (window-width wind))) ; 1- for cont. column
-         (usable-height (1- (window-height wind))) ; 1- for mode line
-         (big-hairy-result (compute-motion
-                            (window-start)
-                            '(0 . 0)
-                            pos
-                            (cons usable-width usable-height)
-                            usable-width
-                            (cons (window-hscroll)
-                                  0)    ; why zero?
-                            wind)))
-    (cons (nth 1 big-hairy-result)      ; hpos, not vpos as documented
-          (nth 2 big-hairy-result))))   ; vpos, not hpos as documented
+  (let ((big-hairy-result (compute-motion
+                           (window-start)
+                           '(0 . 0)
+                           pos
+                           nil ; (window-width window-height)
+                           nil ; window-width
+                           (cons (window-hscroll)
+                                 0)  ; why zero?
+                           (selected-window))))
+  (cons (nth 1 big-hairy-result)        ; hpos, not vpos as documented
+        (nth 2 big-hairy-result))))     ; vpos, not hpos as documented
+
+(defun windmove-coordinates-of-window-position (pos &optional window)
+  "Return the coordinates of position POS in WINDOW.
+Return the window-based coodinates in a cons pair: (HPOS . VPOS),
+where HPOS and VPOS are the zero-based x and y components of the
+screen location of POS.  If WINDOW is nil, return the coordinates in
+the currently selected window."
+  (if (null window)
+      (windmove-coordinates-of-position pos)
+    (save-selected-window
+      (select-window window)
+      (windmove-coordinates-of-position pos))))
 
 ;; This calculates the reference location in the current window: the
 ;; frame-based (x . y) of either point, the top-left, or the
@@ -453,15 +467,13 @@ currently-selected window, or WINDOW if supplied; otherwise, it is the
 top-left or bottom-right corner of the selected window, or WINDOW if
 supplied, if ARG is greater or smaller than zero, respectively."
   (let ((effective-arg (if (null arg) 0 (prefix-numeric-value arg)))
-        (edges (window-edges window)))
+        (edges (window-inside-edges window)))
     (let ((top-left (cons (nth 0 edges)
                           (nth 1 edges)))
-          ;; if 1-'s are not there, windows actually extend too far.
-          ;; actually, -2 is necessary for bottom: (nth 3 edges) is
-          ;; the height of the window; -1 because we want 0-based max,
-          ;; -1 to get rid of mode line
+         ;; Subtracting 1 converts the edge to the last column or line
+         ;; within the window.
           (bottom-right (cons (- (nth 2 edges) 1)
-                              (- (nth 3 edges) 2))))
+                              (- (nth 3 edges) 1))))
       (cond
        ((> effective-arg 0)
           top-left)
@@ -470,8 +482,9 @@ supplied, if ARG is greater or smaller than zero, respectively."
        ((= effective-arg 0)
           (windmove-coord-add
              top-left
-             (windmove-coordinates-of-position (window-point window)
-                                               window)))))))
+             (windmove-coordinates-of-window-position
+              (window-point window)
+              window)))))))
 
 ;; This uses the reference location in the current window (calculated
 ;; by `windmove-reference-loc' above) to find a reference location
@@ -494,13 +507,13 @@ movement is relative to."
             (- (nth 1 edges)
                windmove-window-distance-delta))) ; (x, y0-d)
      ((eq dir 'right)
-      (cons (+ (nth 2 edges)
+      (cons (+ (1- (nth 2 edges))      ; -1 to get actual max x
                windmove-window-distance-delta)
-            (cdr refpoint)))            ; (x1+d, y)
-     ((eq dir 'down)
+            (cdr refpoint)))            ; (x1+d-1, y)
+     ((eq dir 'down)                   ; -1 to get actual max y
       (cons (car refpoint)
-            (+ (nth 3 edges)
-               windmove-window-distance-delta))) ; (x, y1+d)
+            (+ (1- (nth 3 edges))
+               windmove-window-distance-delta))) ; (x, y1+d-1)
      (t (error "Invalid direction of movement: %s" dir)))))
 
 (defun windmove-find-other-window (dir &optional arg window)
@@ -531,10 +544,10 @@ DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'.
 If no window is at direction DIR, an error is signaled."
   (let ((other-window (windmove-find-other-window dir arg window)))
     (cond ((null other-window)
-           (error "No window at %s" dir))
+           (error "No window %s from selected window" dir))
           ((and (window-minibuffer-p other-window)
                 (not (minibuffer-window-active-p other-window)))
-           (error "Can't move to inactive minibuffer"))
+           (error "Minibuffer is inactive"))
           (t
            (select-window other-window)))))
 
@@ -609,4 +622,5 @@ Default MODIFIER is 'shift."
 
 (provide 'windmove)
 
+;;; arch-tag: 56267432-bf1a-4296-a9a0-85c6bd9f2375
 ;;; windmove.el ends here