207 |
;; rest. |
;; rest. |
208 |
;; |
;; |
209 |
;; This work is done by `windmove-reference-loc'. It can figure out |
;; This work is done by `windmove-reference-loc'. It can figure out |
210 |
;; the locations of the corners by calling `window-edges', but to |
;; the locations of the corners by calling `window-edges' combined |
211 |
;; calculate the frame-based location of point, it calls the workhorse |
;; with the result of `posn-at-point'. |
|
;; function `windmove-coordinates-of-position', which itself calls the |
|
|
;; incredibly hairy builtin `compute-motion'. There is a good deal of |
|
|
;; black magic in getting all the arguments to this function just right. |
|
212 |
;; |
;; |
213 |
;; The second step is more messy. Conceptually, it is fairly simple: |
;; The second step is more messy. Conceptually, it is fairly simple: |
214 |
;; if we know the reference location, and the coordinates of the |
;; if we know the reference location, and the coordinates of the |
402 |
(windmove-constrain-around-range (cdr coord) min-y max-y))))) |
(windmove-constrain-around-range (cdr coord) min-y max-y))))) |
403 |
|
|
404 |
|
|
|
|
|
|
;; `windmove-coordinates-of-position' is stolen and modified from the |
|
|
;; 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 |
|
|
;; set this component to zero, and I'm too lazy to grovel through the |
|
|
;; C source to figure out what's happening in the background. there |
|
|
;; also seems to be a good deal of fun in calculating the correct |
|
|
;; width of lines for telling `compute-motion' about; in particular, |
|
|
;; it seems we need to subtract 1 (for the continuation column) from |
|
|
;; the number that `window-width' gives, or continuation lines aren't |
|
|
;; counted correctly. I haven't seen anyone doing this before, |
|
|
;; though. |
|
|
;; |
|
|
;; 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. |
|
|
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 ((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)))) |
|
|
|
|
405 |
;; This calculates the reference location in the current window: the |
;; This calculates the reference location in the current window: the |
406 |
;; frame-based (x . y) of either point, the top-left, or the |
;; frame-based (x . y) of either point, the top-left, or the |
407 |
;; bottom-right of the window, depending on ARG. |
;; bottom-right of the window, depending on ARG. |
428 |
((= effective-arg 0) |
((= effective-arg 0) |
429 |
(windmove-coord-add |
(windmove-coord-add |
430 |
top-left |
top-left |
431 |
(windmove-coordinates-of-window-position |
(let ((col-row |
432 |
(window-point window) |
(posn-col-row |
433 |
window))))))) |
(posn-at-point (window-point window) window)))) |
434 |
|
(cons (- (car col-row) (window-hscroll window)) |
435 |
|
(cdr col-row))))))))) |
436 |
|
|
437 |
;; This uses the reference location in the current window (calculated |
;; This uses the reference location in the current window (calculated |
438 |
;; by `windmove-reference-loc' above) to find a reference location |
;; by `windmove-reference-loc' above) to find a reference location |