comparison lisp/windmove.el @ 57092:5f904f95d7fd

(windmove-frame-edges): Report coordinates of outside edges of frame, not inside edges. (windmove-coordinates-of-position): Convert into wrapper to new function `windmove-coordinates-of-window-position'; `compute-motion' always applies to selected window. (windmove-coordinates-of-position): Update documentation to refer to Emacs 21 Lisp Reference Manual. (windmove-find-other-window): Fix off-by-one errors for max x,y.
author Eli Zaretskii <eliz@gnu.org>
date Mon, 13 Sep 2004 20:07:43 +0000
parents c3fcca92bfd9
children 6fb026ad601f 566253900690
comparison
equal deleted inserted replaced
57091:a02f327b4165 57092:5f904f95d7fd
322 For example, if a frame has 76 rows and 181 columns, the return value 322 For example, if a frame has 76 rows and 181 columns, the return value
323 from `windmove-frame-edges' will be the list (0 0 180 75)." 323 from `windmove-frame-edges' will be the list (0 0 180 75)."
324 (let* ((frame (if window 324 (let* ((frame (if window
325 (window-frame window) 325 (window-frame window)
326 (selected-frame))) 326 (selected-frame)))
327 (top-left (window-inside-edges (frame-first-window frame))) 327 (top-left (window-edges (frame-first-window frame)))
328 (x-min (nth 0 top-left)) 328 (x-min (nth 0 top-left))
329 (y-min (nth 1 top-left)) 329 (y-min (nth 1 top-left))
330 (x-max (+ x-min (frame-width frame) -1)) ; 1- for last row & col 330 (x-max (1- (frame-width frame))) ; 1- for last row & col
331 (y-max (+ x-max (frame-height frame) -1))) 331 (y-max (1- (frame-height frame))))
332 (list x-min y-min x-max y-max))) 332 (list x-min y-min x-max y-max)))
333 333
334 ;; it turns out that constraining is always a good thing, even when 334 ;; it turns out that constraining is always a good thing, even when
335 ;; wrapping is going to happen. this is because: 335 ;; wrapping is going to happen. this is because:
336 ;; first, since we disallow exotic diagonal-around-a-corner type 336 ;; first, since we disallow exotic diagonal-around-a-corner type
404 (windmove-constrain-around-range (cdr coord) min-y max-y))))) 404 (windmove-constrain-around-range (cdr coord) min-y max-y)))))
405 405
406 406
407 407
408 ;; `windmove-coordinates-of-position' is stolen and modified from the 408 ;; `windmove-coordinates-of-position' is stolen and modified from the
409 ;; Emacs Lisp Reference Manual, section 27.2.5. It seems to work 409 ;; Emacs 20 Lisp Reference Manual, section 27.2.5. It seems to work
410 ;; okay, although I am bothered by the fact that tab-offset (the cdr 410 ;; okay, although I am bothered by the fact that tab-offset (the cdr
411 ;; of the next-to- last argument) is set to 0. On the other hand, I 411 ;; of the next-to- last argument) is set to 0. On the other hand, I
412 ;; can't find a single usage of `compute-motion' anywhere that doesn't 412 ;; can't find a single usage of `compute-motion' anywhere that doesn't
413 ;; set this component to zero, and I'm too lazy to grovel through the 413 ;; set this component to zero, and I'm too lazy to grovel through the
414 ;; C source to figure out what's happening in the background. there 414 ;; C source to figure out what's happening in the background. there
416 ;; width of lines for telling `compute-motion' about; in particular, 416 ;; width of lines for telling `compute-motion' about; in particular,
417 ;; it seems we need to subtract 1 (for the continuation column) from 417 ;; it seems we need to subtract 1 (for the continuation column) from
418 ;; the number that `window-width' gives, or continuation lines aren't 418 ;; the number that `window-width' gives, or continuation lines aren't
419 ;; counted correctly. I haven't seen anyone doing this before, 419 ;; counted correctly. I haven't seen anyone doing this before,
420 ;; though. 420 ;; though.
421 (defun windmove-coordinates-of-position (pos &optional window) 421 ;;
422 "Return the coordinates of position POS in window WINDOW. 422 ;; Now updated for Emacs 21, based on the Emacs 21 Lisp Reference
423 ;; Manual, section 30.2.5. It is no longer necessary to subtract
424 ;; 1 for the usable width of the window.
425 ;; TODO: also handle minibuffer case, w/ `minibuffer-prompt-width'.
426 (defun windmove-coordinates-of-position (pos)
427 "Return the coordinates of position POS in the current window.
423 Return the window-based coodinates in a cons pair: (HPOS . VPOS), 428 Return the window-based coodinates in a cons pair: (HPOS . VPOS),
424 where HPOS and VPOS are the zero-based x and y components of the 429 where HPOS and VPOS are the zero-based x and y components of the
425 screen location of POS. If WINDOW is nil, return the coordinates in 430 screen location of POS.
426 the currently selected window.
427 As an example, if point is in the top left corner of a window, then 431 As an example, if point is in the top left corner of a window, then
428 the return value from `windmove-coordinates-of-position' is (0 . 0) 432 the return value from `windmove-coordinates-of-position' is (0 . 0)
429 regardless of the where point is in the buffer and where the window 433 regardless of the where point is in the buffer and where the window
430 is placed in the frame." 434 is placed in the frame."
431 (let* ((wind (if (null window) (selected-window) window)) 435 (let ((big-hairy-result (compute-motion
432 (big-hairy-result (compute-motion 436 (window-start)
433 (window-start) 437 '(0 . 0)
434 '(0 . 0) 438 pos
435 pos 439 nil ; (window-width window-height)
436 nil ; (window-width window-height) 440 nil ; window-width
437 nil ; window-width 441 (cons (window-hscroll)
438 (cons (window-hscroll) 442 0) ; why zero?
439 0) ; why zero? 443 (selected-window))))
440 wind))) 444 (cons (nth 1 big-hairy-result) ; hpos, not vpos as documented
441 (cons (nth 1 big-hairy-result) ; hpos, not vpos as documented 445 (nth 2 big-hairy-result)))) ; vpos, not hpos as documented
442 (nth 2 big-hairy-result)))) ; vpos, not hpos as documented 446
447 (defun windmove-coordinates-of-window-position (pos &optional window)
448 "Return the coordinates of position POS in WINDOW.
449 Return the window-based coodinates in a cons pair: (HPOS . VPOS),
450 where HPOS and VPOS are the zero-based x and y components of the
451 screen location of POS. If WINDOW is nil, return the coordinates in
452 the currently selected window."
453 (if (null window)
454 (windmove-coordinates-of-position pos)
455 (save-selected-window
456 (select-window window)
457 (windmove-coordinates-of-position pos))))
443 458
444 ;; This calculates the reference location in the current window: the 459 ;; This calculates the reference location in the current window: the
445 ;; frame-based (x . y) of either point, the top-left, or the 460 ;; frame-based (x . y) of either point, the top-left, or the
446 ;; bottom-right of the window, depending on ARG. 461 ;; bottom-right of the window, depending on ARG.
447 (defun windmove-reference-loc (&optional arg window) 462 (defun windmove-reference-loc (&optional arg window)
465 ((< effective-arg 0) 480 ((< effective-arg 0)
466 bottom-right) 481 bottom-right)
467 ((= effective-arg 0) 482 ((= effective-arg 0)
468 (windmove-coord-add 483 (windmove-coord-add
469 top-left 484 top-left
470 (windmove-coordinates-of-position (window-point window) 485 (windmove-coordinates-of-window-position
471 window))))))) 486 (window-point window)
487 window)))))))
472 488
473 ;; This uses the reference location in the current window (calculated 489 ;; This uses the reference location in the current window (calculated
474 ;; by `windmove-reference-loc' above) to find a reference location 490 ;; by `windmove-reference-loc' above) to find a reference location
475 ;; that will hopefully be in the window we want to move to. 491 ;; that will hopefully be in the window we want to move to.
476 (defun windmove-other-window-loc (dir &optional arg window) 492 (defun windmove-other-window-loc (dir &optional arg window)
489 ((eq dir 'up) 505 ((eq dir 'up)
490 (cons (car refpoint) 506 (cons (car refpoint)
491 (- (nth 1 edges) 507 (- (nth 1 edges)
492 windmove-window-distance-delta))) ; (x, y0-d) 508 windmove-window-distance-delta))) ; (x, y0-d)
493 ((eq dir 'right) 509 ((eq dir 'right)
494 (cons (+ (nth 2 edges) 510 (cons (+ (1- (nth 2 edges)) ; -1 to get actual max x
495 windmove-window-distance-delta) 511 windmove-window-distance-delta)
496 (cdr refpoint))) ; (x1+d, y) 512 (cdr refpoint))) ; (x1+d-1, y)
497 ((eq dir 'down) 513 ((eq dir 'down) ; -1 to get actual max y
498 (cons (car refpoint) 514 (cons (car refpoint)
499 (+ (nth 3 edges) 515 (+ (1- (nth 3 edges))
500 windmove-window-distance-delta))) ; (x, y1+d) 516 windmove-window-distance-delta))) ; (x, y1+d-1)
501 (t (error "Invalid direction of movement: %s" dir))))) 517 (t (error "Invalid direction of movement: %s" dir)))))
502 518
503 (defun windmove-find-other-window (dir &optional arg window) 519 (defun windmove-find-other-window (dir &optional arg window)
504 "Return the window object in direction DIR. 520 "Return the window object in direction DIR.
505 DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'." 521 DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'."