annotate lisp/windmove.el @ 110410:f2e111723c3a

Merge changes made in Gnus trunk. Reimplement nnimap, and do tweaks to the rest of the code to support that. * gnus-int.el (gnus-finish-retrieve-group-infos) (gnus-retrieve-group-data-early): New functions. * gnus-range.el (gnus-range-nconcat): New function. * gnus-start.el (gnus-get-unread-articles): Support early retrieval of data. (gnus-read-active-for-groups): Support finishing the early retrieval of data. * gnus-sum.el (gnus-summary-move-article): Pass the move-to group name if the move is internal, so that nnimap can do fast internal moves. * gnus.el (gnus-article-special-mark-lists): Add uid/active tuples, for nnimap usage. * nnimap.el: Rewritten. * nnmail.el (nnmail-inhibit-default-split-group): New internal variable to allow the mail splitting to not return a default group. This is useful for nnimap, which will leave unmatched mail in the inbox. * utf7.el (utf7-encode): Autoload. Implement shell connection. * nnimap.el (nnimap-open-shell-stream): New function. (nnimap-open-connection): Use it. Get the number of lines by using BODYSTRUCTURE. (nnimap-transform-headers): Get the number of lines in each message. (nnimap-retrieve-headers): Query for BODYSTRUCTURE so that we get the number of lines. Not all servers return UIDNEXT. Work past this problem. Remove junk from end of file. Fix typo in "bogus" section. Make capabilties be case-insensitive. Require cl when compiling. Don't bug out if the LIST command doesn't have any parameters. 2010-09-17 Knut Anders Hatlen <kahatlen@gmail.com> (tiny change) * nnimap.el (nnimap-get-groups): Don't bug out if the LIST command doesn't have any parameters. (mm-text-html-renderer): Document gnus-article-html. 2010-09-17 Julien Danjou <julien@danjou.info> (tiny fix) * mm-decode.el (mm-text-html-renderer): Document gnus-article-html. * dgnushack.el: Define netrc-credentials. If the user doesn't have a /etc/services, supply some sensible port defaults. Have `unseen-or-unread' select an unread unseen article first. (nntp-open-server): Return whether the open was successful or not. Throughout all files, replace (save-excursion (set-buffer ...)) with (with-current-buffer ... ). Save result so that it doesn't say "failed" all the time. Add ~/.authinfo to the default, since that's probably most useful for users. Don't use the "finish" method when we're reading from the agent. Add some more nnimap-relevant agent stuff to nnagent.el. * nnimap.el (nnimap-with-process-buffer): Removed. Revert one line that was changed by mistake in the last checkin. (nnimap-open-connection): Don't error out when we can't make a connection nnimap-related changes to avoid bugging out if we can't contact a server. * gnus-start.el (gnus-get-unread-articles): Don't try to scan groups from methods that are denied. * nnimap.el (nnimap-possibly-change-group): Return nil if we can't log in. (nnimap-finish-retrieve-group-infos): Make sure we're not waiting for nothing. * gnus-sum.el (gnus-select-newsgroup): Indent.
author Katsumi Yamaoka <yamaoka@jpl.org>
date Sat, 18 Sep 2010 10:02:19 +0000
parents 1d1d5d9bd884
children 376148b31b5e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
38436
b174db545cfd Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents: 30892
diff changeset
1 ;;; windmove.el --- directional window-selection routines
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
2 ;;
74442
b2e5081b9320 Update copyright years.
Glenn Morris <rgm@gnu.org>
parents: 68651
diff changeset
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
106815
1d1d5d9bd884 Add 2010 to copyright years.
Glenn Morris <rgm@gnu.org>
parents: 100908
diff changeset
4 ;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
5 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
6 ;; Author: Hovav Shacham (hovav@cs.stanford.edu)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
7 ;; Created: 17 October 1998
30892
495502641770 (windmove) <defgroup>: Add :version.
Dave Love <fx@gnu.org>
parents: 27545
diff changeset
8 ;; Keywords: window, movement, convenience
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
9 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
10 ;; This file is part of GNU Emacs.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
11 ;;
94678
ee5932bf781d Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 93975
diff changeset
12 ;; GNU Emacs is free software: you can redistribute it and/or modify
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
13 ;; it under the terms of the GNU General Public License as published by
94678
ee5932bf781d Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 93975
diff changeset
14 ;; the Free Software Foundation, either version 3 of the License, or
ee5932bf781d Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 93975
diff changeset
15 ;; (at your option) any later version.
ee5932bf781d Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 93975
diff changeset
16
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
17 ;; GNU Emacs is distributed in the hope that it will be useful,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
20 ;; GNU General Public License for more details.
94678
ee5932bf781d Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 93975
diff changeset
21
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
22 ;; You should have received a copy of the GNU General Public License
94678
ee5932bf781d Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents: 93975
diff changeset
23 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
24 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
25 ;; --------------------------------------------------------------------
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
26
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
27 ;;; Commentary:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
28 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
29 ;; This package defines a set of routines, windmove-{left,up,right,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
30 ;; down}, for selection of windows in a frame geometrically. For
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
31 ;; example, `windmove-right' selects the window immediately to the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
32 ;; right of the currently-selected one. This functionality is similar
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
33 ;; to the window-selection controls of the BRIEF editor of yore.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
34 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
35 ;; One subtle point is what happens when the window to the right has
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
36 ;; been split vertically; for example, consider a call to
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
37 ;; `windmove-right' in this setup:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
38 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
39 ;; -------------
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
40 ;; | | A |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
41 ;; | | |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
42 ;; | |-----
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
43 ;; | * | | (* is point in the currently
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
44 ;; | | B | selected window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
45 ;; | | |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
46 ;; -------------
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
47 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
48 ;; There are (at least) three reasonable things to do:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
49 ;; (1) Always move to the window to the right of the top edge of the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
50 ;; selected window; in this case, this policy selects A.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
51 ;; (2) Always move to the window to the right of the bottom edge of
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
52 ;; the selected window; in this case, this policy selects B.
30892
495502641770 (windmove) <defgroup>: Add :version.
Dave Love <fx@gnu.org>
parents: 27545
diff changeset
53 ;; (3) Move to the window to the right of point in the selected
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
54 ;; window. This may select either A or B, depending on the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
55 ;; position of point; in the illustrated example, it would select
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
56 ;; B.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
57 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
58 ;; Similar issues arise for all the movement functions. Windmove
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
59 ;; resolves this problem by allowing the user to specify behavior
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
60 ;; through a prefix argument. The cases are thus:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
61 ;; * if no argument is given to the movement functions, or the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
62 ;; argument given is zero, movement is relative to point;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
63 ;; * if a positive argument is given, movement is relative to the top
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
64 ;; or left edge of the selected window, depending on whether the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
65 ;; movement is to be horizontal or vertical;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
66 ;; * if a negative argument is given, movement is relative to the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
67 ;; bottom or right edge of the selected window, depending on whether
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
68 ;; the movement is to be horizontal or vertical.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
69 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
70 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
71 ;; Another feature enables wrap-around mode when the variable
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
72 ;; `windmove-wrap-around' is set to a non-nil value. In this mode,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
73 ;; movement that falls off the edge of the frame will wrap around to
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
74 ;; find the window on the opposite side of the frame. Windmove does
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
75 ;; the Right Thing about the minibuffer; for example, consider:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
76 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
77 ;; -------------
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
78 ;; | * |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
79 ;; |-----------|
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
80 ;; | A |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
81 ;; |-----------| (* is point in the currently
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
82 ;; | B | C | selected window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
83 ;; | | |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
84 ;; -------------
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
85 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
86 ;; With wraparound enabled, windmove-down will move to A, while
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
87 ;; windmove-up will move to the minibuffer if it is active, or to
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
88 ;; either B or C depending on the prefix argument.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
89 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
90 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
91 ;; A set of default keybindings is supplied: shift-{left,up,right,down}
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
92 ;; invoke the corresponding Windmove function. See the installation
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
93 ;; section if you wish to use these keybindings.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
94
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
95
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
96 ;; Installation:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
97 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
98 ;; Put the following line in your `.emacs' file:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
99 ;;
45166
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
100 ;; (windmove-default-keybindings) ; shifted arrow keys
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
101 ;;
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
102 ;; or
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
103 ;;
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
104 ;; (windmove-default-keybindings 'hyper) ; etc.
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
105 ;;
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
106 ;; to use another modifier key.
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
107 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
108 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
109 ;; If you wish to enable wrap-around, also add a line like:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
110 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
111 ;; (setq windmove-wrap-around t)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
112 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
113 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
114 ;; Note: If you have an Emacs that manifests a bug that sometimes
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
115 ;; causes the occasional creation of a "lost column" between windows,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
116 ;; so that two adjacent windows do not actually touch, you may want to
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
117 ;; increase the value of `windmove-window-distance-delta' to 2 or 3:
45166
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
118 ;;
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
119 ;; (setq windmove-window-distance-delta 2)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
120 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
121
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
122 ;; Acknowledgements:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
123 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
124 ;; Special thanks to Julian Assange (proff@iq.org), whose
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
125 ;; change-windows-intuitively.el predates Windmove, and provided the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
126 ;; inspiration for it. Kin Cho (kin@symmetrycomm.com) was the first
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
127 ;; to suggest wrap-around behavior. Thanks also to Gerd Moellmann
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
128 ;; (gerd@gnu.org) for his comments and suggestions.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
129
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
130 ;;; Code:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
131
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
132
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
133 ;; User configurable variables:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
134
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
135 ;; For customize ...
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
136 (defgroup windmove nil
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
137 "Directional selection of windows in a frame."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
138 :prefix "windmove-"
30892
495502641770 (windmove) <defgroup>: Add :version.
Dave Love <fx@gnu.org>
parents: 27545
diff changeset
139 :version "21.1"
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
140 :group 'windows
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
141 :group 'convenience)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
142
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
143
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
144 (defcustom windmove-wrap-around nil
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
145 "Whether movement off the edge of the frame wraps around.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
146 If this variable is set to t, moving left from the leftmost window in
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
147 a frame will find the rightmost one, and similarly for the other
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
148 directions. The minibuffer is skipped over in up/down movements if it
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
149 is inactive."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
150 :type 'boolean
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
151 :group 'windmove)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
152
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
153 ;; If your Emacs sometimes places an empty column between two adjacent
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
154 ;; windows, you may wish to set this delta to 2.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
155 (defcustom windmove-window-distance-delta 1
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
156 "How far away from the current window to look for an adjacent window.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
157 Measured in characters either horizontally or vertically; setting this
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
158 to a value larger than 1 may be useful in getting around window-
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
159 placement bugs in old versions of Emacs."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
160 :type 'number
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
161 :group 'windmove)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
162
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
163
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
164
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
165 ;; Implementation overview:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
166 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
167 ;; The conceptual framework behind this code is all fairly simple. We
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
168 ;; are on one window; we wish to move to another. The correct window
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
169 ;; to move to is determined by the position of point in the current
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
170 ;; window as well as the overall window setup.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
171 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
172 ;; Early on, I made the decision to base my implementation around the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
173 ;; built-in function `window-at'. This function takes a frame-based
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
174 ;; coordinate, and returns the window that contains it. Using this
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
175 ;; function, the job of the various top-level windmove functions can
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
176 ;; be decomposed: first, find the current frame-based location of
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
177 ;; point; second, manipulate it in some way to give a new location,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
178 ;; that hopefully falls in the window immediately at left (or right,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
179 ;; etc.); third, use `window-at' and `select-window' to select the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
180 ;; window at that new location.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
181 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
182 ;; This is probably not the only possible architecture, and it turns
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
183 ;; out to have some inherent cruftiness. (Well, okay, the third step
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
184 ;; is pretty clean....) We will consider each step in turn.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
185 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
186 ;; A quick digression about coordinate frames: most of the functions
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
187 ;; in the windmove package deal with screen coordinates in one way or
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
188 ;; another. These coordinates are always relative to some reference
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
189 ;; points. Window-based coordinates have their reference point in the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
190 ;; upper-left-hand corner of whatever window is being talked about;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
191 ;; frame-based coordinates have their reference point in the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
192 ;; upper-left-hand corner of the entire frame (of which the current
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
193 ;; window is a component).
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
194 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
195 ;; All coordinates are zero-based, which simply means that the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
196 ;; reference point (whatever it is) is assigned the value (x=0, y=0).
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
197 ;; X-coordinates grow down the screen, and Y-coordinates grow towards
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
198 ;; the right of the screen.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
199 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
200 ;; Okay, back to work. The first step is to gather information about
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
201 ;; the frame-based coordinates of point, or rather, the reference
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
202 ;; location. The reference location can be point, or the upper-left,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
203 ;; or the lower-right corner of the window; the particular one used is
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
204 ;; controlled by the prefix argument to `windmove-left' and all the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
205 ;; rest.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
206 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
207 ;; This work is done by `windmove-reference-loc'. It can figure out
65018
6c1c6712bea9 (windmove-coordinates-of-position): Remove.
Kim F. Storm <storm@cua.dk>
parents: 64762
diff changeset
208 ;; the locations of the corners by calling `window-edges' combined
6c1c6712bea9 (windmove-coordinates-of-position): Remove.
Kim F. Storm <storm@cua.dk>
parents: 64762
diff changeset
209 ;; with the result of `posn-at-point'.
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
210 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
211 ;; The second step is more messy. Conceptually, it is fairly simple:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
212 ;; if we know the reference location, and the coordinates of the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
213 ;; current window, we can "throw" our reference point just over the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
214 ;; appropriate edge of the window, and see what other window is
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
215 ;; there. More explicitly, consider this example from the user
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
216 ;; documentation above.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
217 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
218 ;; -------------
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
219 ;; | | A |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
220 ;; | | |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
221 ;; | |-----
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
222 ;; | * | | (* is point in the currently
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
223 ;; | | B | selected window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
224 ;; | | |
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
225 ;; -------------
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
226 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
227 ;; The asterisk marks the reference point; we wish to move right.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
228 ;; Since we are moving horizontally, the Y coordinate of the new
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
229 ;; location will be the same. The X coordinate can be such that it is
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
230 ;; just past the edge of the present window. Obviously, the new point
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
231 ;; will be inside window B. This in itself is fairly simple: using
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
232 ;; the result of `windmove-reference-loc' and `window-edges', all the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
233 ;; necessary math can be performed. (Having said that, there is a
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
234 ;; good deal of room for off-by-one errors, and Emacs 19.34, at least,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
235 ;; sometimes manifests a bug where two windows don't actually touch,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
236 ;; so a larger skip is required.) The actual math here is done by
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
237 ;; `windmove-other-window-loc'.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
238 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
239 ;; But we can't just pass the result of `windmove-other-window-loc' to
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
240 ;; `window-at' directly. Why not? Suppose a move would take us off
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
241 ;; the edge of the screen, say to the left. We want to give a
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
242 ;; descriptive error message to the user. Or, suppose that a move
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
243 ;; would place us in the minibuffer. What if the minibuffer is
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
244 ;; inactive?
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
245 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
246 ;; Actually, the whole subject of the minibuffer edge of the frame is
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
247 ;; rather messy. It turns out that with a sufficiently large delta,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
248 ;; we can fly off the bottom edge of the frame and miss the minibuffer
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
249 ;; altogther. This, I think, is never right: if there's a minibuffer
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
250 ;; and you're not in it, and you move down, the minibuffer should be
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
251 ;; in your way.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
252 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
253 ;; (By the way, I'm not totally sure that the code does the right
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
254 ;; thing in really weird cases, like a frame with no minibuffer.)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
255 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
256 ;; So, what we need is some ways to do constraining and such. The
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
257 ;; early versions of windmove took a fairly simplistic approach to all
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
258 ;; this. When I added the wrap-around option, those internals had to
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
259 ;; be rewritten. After a *lot* of futzing around, I came up with a
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
260 ;; two-step process that I think is general enough to cover the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
261 ;; relevant cases. (I'm not totally happy with having to pass the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
262 ;; window variable as deep as I do, but we can't have everything.)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
263 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
264 ;; In the first phase, we make sure that the new location is sane.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
265 ;; "Sane" means that we can only fall of the edge of the frame in the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
266 ;; direction we're moving in, and that we don't miss the minibuffer if
30892
495502641770 (windmove) <defgroup>: Add :version.
Dave Love <fx@gnu.org>
parents: 27545
diff changeset
267 ;; we're moving down and not already in the minibuffer. The function
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
268 ;; `windmove-constrain-loc-for-movement' takes care of all this.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
269 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
270 ;; Then, we handle the wraparound, if it's enabled. The function
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
271 ;; `windmove-wrap-loc-for-movement' takes coordinate values (both X
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
272 ;; and Y) that fall off the edge of the frame, and replaces them with
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
273 ;; values on the other side of the frame. It also has special
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
274 ;; minibuffer-handling code again, because we want to wrap through the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
275 ;; minibuffer if it's not enabled.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
276 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
277 ;; So, that's it. Seems to work. All of this work is done by the fun
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
278 ;; function `windmove-find-other-window'.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
279 ;;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
280 ;; So, now we have a window to move to (or nil if something's gone
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
281 ;; wrong). The function `windmove-do-window-select' is the main
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
282 ;; driver function: it actually does the `select-window'. It is
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
283 ;; called by four little convenience wrappers, `windmove-left',
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
284 ;; `windmove-up', `windmove-right', and `windmove-down', which make
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
285 ;; for convenient keybinding.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
286
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
287
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
288 ;; Quick & dirty utility function to add two (x . y) coords.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
289 (defun windmove-coord-add (coord1 coord2)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
290 "Add the two coordinates.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
291 Both COORD1 and COORD2 are coordinate cons pairs, (HPOS . VPOS). The
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
292 result is another coordinate cons pair."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
293 (cons (+ (car coord1) (car coord2))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
294 (+ (cdr coord1) (cdr coord2))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
295
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
296
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
297 (defun windmove-constrain-to-range (n min-n max-n)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
298 "Ensure that N is between MIN-N and MAX-N inclusive by constraining.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
299 If N is less than MIN-N, return MIN-N; if greater than MAX-N, return
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
300 MAX-N."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
301 (max min-n (min n max-n)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
302
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
303 (defun windmove-constrain-around-range (n min-n max-n)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
304 "Ensure that N is between MIN-N and MAX-N inclusive by wrapping.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
305 If N is less than MIN-N, return MAX-N; if greater than MAX-N, return
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
306 MIN-N."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
307 (cond
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
308 ((< n min-n) max-n)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
309 ((> n max-n) min-n)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
310 (t n)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
311
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
312 (defun windmove-frame-edges (window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
313 "Return (X-MIN Y-MIN X-MAX Y-MAX) for the frame containing WINDOW.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
314 If WINDOW is nil, return the edges for the selected frame.
39588
62d7faafb853 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents: 38436
diff changeset
315 \(X-MIN, Y-MIN) is the zero-based coordinate of the top-left corner
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
316 of the frame; (X-MAX, Y-MAX) is the zero-based coordinate of the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
317 bottom-right corner of the frame.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
318 For example, if a frame has 76 rows and 181 columns, the return value
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
319 from `windmove-frame-edges' will be the list (0 0 180 75)."
51424
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
320 (let* ((frame (if window
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
321 (window-frame window)
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
322 (selected-frame)))
57092
5f904f95d7fd (windmove-frame-edges): Report coordinates of
Eli Zaretskii <eliz@gnu.org>
parents: 56587
diff changeset
323 (top-left (window-edges (frame-first-window frame)))
51424
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
324 (x-min (nth 0 top-left))
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
325 (y-min (nth 1 top-left))
57092
5f904f95d7fd (windmove-frame-edges): Report coordinates of
Eli Zaretskii <eliz@gnu.org>
parents: 56587
diff changeset
326 (x-max (1- (frame-width frame))) ; 1- for last row & col
5f904f95d7fd (windmove-frame-edges): Report coordinates of
Eli Zaretskii <eliz@gnu.org>
parents: 56587
diff changeset
327 (y-max (1- (frame-height frame))))
51424
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
328 (list x-min y-min x-max y-max)))
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
329
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
330 ;; it turns out that constraining is always a good thing, even when
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
331 ;; wrapping is going to happen. this is because:
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
332 ;; first, since we disallow exotic diagonal-around-a-corner type
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
333 ;; movements, so we can always fix the unimportant direction (the one
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
334 ;; we're not moving in).
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
335 ;; second, if we're moving down and we're not in the minibuffer, then
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
336 ;; constraining the y coordinate to max-y is okay, because if that
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
337 ;; falls in the minibuffer and the minibuffer isn't active, that y
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
338 ;; coordinate will still be off the bottom of the frame as the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
339 ;; wrapping function sees it and so will get wrapped around anyway.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
340 (defun windmove-constrain-loc-for-movement (coord window dir)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
341 "Constrain COORD so that it is reasonable for the given movement.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
342 This involves two things: first, make sure that the \"off\" coordinate
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
343 -- the one not being moved on, e.g., y for horizontal movement -- is
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
344 within frame boundaries; second, if the movement is down and we're not
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
345 moving from the minibuffer, make sure that the y coordinate does not
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
346 exceed the frame max-y, so that we don't overshoot the minibuffer
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
347 accidentally. WINDOW is the window that movement is relative to; DIR
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
348 is the direction of the movement, one of `left', `up', `right',
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
349 or `down'.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
350 Returns the constrained coordinate."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
351 (let ((frame-edges (windmove-frame-edges window))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
352 (in-minibuffer (window-minibuffer-p window)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
353 (let ((min-x (nth 0 frame-edges))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
354 (min-y (nth 1 frame-edges))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
355 (max-x (nth 2 frame-edges))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
356 (max-y (nth 3 frame-edges)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
357 (let ((new-x
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
358 (if (memq dir '(up down)) ; vertical movement
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
359 (windmove-constrain-to-range (car coord) min-x max-x)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
360 (car coord)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
361 (new-y
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
362 (if (or (memq dir '(left right)) ; horizontal movement
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
363 (and (eq dir 'down)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
364 (not in-minibuffer))) ; don't miss minibuffer
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
365 ;; (technically, we shouldn't constrain on min-y in the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
366 ;; second case, but this shouldn't do any harm on a
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
367 ;; down movement.)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
368 (windmove-constrain-to-range (cdr coord) min-y max-y)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
369 (cdr coord))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
370 (cons new-x new-y)))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
371
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
372 ;; having constrained in the limited sense of windmove-constrain-loc-
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
373 ;; for-movement, the wrapping code is actually much simpler than it
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
374 ;; otherwise would be. the only complication is that we need to check
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
375 ;; if the minibuffer is active, and, if not, pretend that it's not
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
376 ;; even part of the frame.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
377 (defun windmove-wrap-loc-for-movement (coord window dir)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
378 "Takes the constrained COORD and wraps it around for the movement.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
379 This makes an out-of-range x or y coordinate and wraps it around the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
380 frame, giving a coordinate (hopefully) in the window on the other edge
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
381 of the frame. WINDOW is the window that movement is relative to (nil
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
382 means the currently selected window); DIR is the direction of the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
383 movement, one of `left', `up', `right',or `down'.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
384 Returns the wrapped coordinate."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
385 (let* ((frame-edges (windmove-frame-edges window))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
386 (frame-minibuffer (minibuffer-window (if window
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
387 (window-frame window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
388 (selected-frame))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
389 (minibuffer-active (minibuffer-window-active-p
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
390 frame-minibuffer)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
391 (let ((min-x (nth 0 frame-edges))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
392 (min-y (nth 1 frame-edges))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
393 (max-x (nth 2 frame-edges))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
394 (max-y (if (not minibuffer-active)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
395 (- (nth 3 frame-edges)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
396 (window-height frame-minibuffer))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
397 (nth 3 frame-edges))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
398 (cons
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
399 (windmove-constrain-around-range (car coord) min-x max-x)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
400 (windmove-constrain-around-range (cdr coord) min-y max-y)))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
401
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
402
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
403 ;; This calculates the reference location in the current window: the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
404 ;; frame-based (x . y) of either point, the top-left, or the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
405 ;; bottom-right of the window, depending on ARG.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
406 (defun windmove-reference-loc (&optional arg window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
407 "Return the reference location for directional window selection.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
408 Return a coordinate (HPOS . VPOS) that is frame-based. If ARG is nil
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
409 or not supplied, the reference point is the buffer's point in the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
410 currently-selected window, or WINDOW if supplied; otherwise, it is the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
411 top-left or bottom-right corner of the selected window, or WINDOW if
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
412 supplied, if ARG is greater or smaller than zero, respectively."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
413 (let ((effective-arg (if (null arg) 0 (prefix-numeric-value arg)))
51424
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
414 (edges (window-inside-edges window)))
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
415 (let ((top-left (cons (nth 0 edges)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
416 (nth 1 edges)))
51424
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
417 ;; Subtracting 1 converts the edge to the last column or line
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
418 ;; within the window.
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
419 (bottom-right (cons (- (nth 2 edges) 1)
51424
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
420 (- (nth 3 edges) 1))))
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
421 (cond
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
422 ((> effective-arg 0)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
423 top-left)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
424 ((< effective-arg 0)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
425 bottom-right)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
426 ((= effective-arg 0)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
427 (windmove-coord-add
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
428 top-left
65018
6c1c6712bea9 (windmove-coordinates-of-position): Remove.
Kim F. Storm <storm@cua.dk>
parents: 64762
diff changeset
429 (let ((col-row
6c1c6712bea9 (windmove-coordinates-of-position): Remove.
Kim F. Storm <storm@cua.dk>
parents: 64762
diff changeset
430 (posn-col-row
6c1c6712bea9 (windmove-coordinates-of-position): Remove.
Kim F. Storm <storm@cua.dk>
parents: 64762
diff changeset
431 (posn-at-point (window-point window) window))))
6c1c6712bea9 (windmove-coordinates-of-position): Remove.
Kim F. Storm <storm@cua.dk>
parents: 64762
diff changeset
432 (cons (- (car col-row) (window-hscroll window))
6c1c6712bea9 (windmove-coordinates-of-position): Remove.
Kim F. Storm <storm@cua.dk>
parents: 64762
diff changeset
433 (cdr col-row)))))))))
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
434
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
435 ;; This uses the reference location in the current window (calculated
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
436 ;; by `windmove-reference-loc' above) to find a reference location
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
437 ;; that will hopefully be in the window we want to move to.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
438 (defun windmove-other-window-loc (dir &optional arg window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
439 "Return a location in the window to be moved to.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
440 Return value is a frame-based (HPOS . VPOS) value that should be moved
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
441 to. DIR is one of `left', `up', `right', or `down'; an optional ARG
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
442 is handled as by `windmove-reference-loc'; WINDOW is the window that
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
443 movement is relative to."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
444 (let ((edges (window-edges window)) ; edges: (x0, y0, x1, y1)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
445 (refpoint (windmove-reference-loc arg window))) ; (x . y)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
446 (cond
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
447 ((eq dir 'left)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
448 (cons (- (nth 0 edges)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
449 windmove-window-distance-delta)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
450 (cdr refpoint))) ; (x0-d, y)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
451 ((eq dir 'up)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
452 (cons (car refpoint)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
453 (- (nth 1 edges)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
454 windmove-window-distance-delta))) ; (x, y0-d)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
455 ((eq dir 'right)
57092
5f904f95d7fd (windmove-frame-edges): Report coordinates of
Eli Zaretskii <eliz@gnu.org>
parents: 56587
diff changeset
456 (cons (+ (1- (nth 2 edges)) ; -1 to get actual max x
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
457 windmove-window-distance-delta)
57092
5f904f95d7fd (windmove-frame-edges): Report coordinates of
Eli Zaretskii <eliz@gnu.org>
parents: 56587
diff changeset
458 (cdr refpoint))) ; (x1+d-1, y)
5f904f95d7fd (windmove-frame-edges): Report coordinates of
Eli Zaretskii <eliz@gnu.org>
parents: 56587
diff changeset
459 ((eq dir 'down) ; -1 to get actual max y
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
460 (cons (car refpoint)
57092
5f904f95d7fd (windmove-frame-edges): Report coordinates of
Eli Zaretskii <eliz@gnu.org>
parents: 56587
diff changeset
461 (+ (1- (nth 3 edges))
5f904f95d7fd (windmove-frame-edges): Report coordinates of
Eli Zaretskii <eliz@gnu.org>
parents: 56587
diff changeset
462 windmove-window-distance-delta))) ; (x, y1+d-1)
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
463 (t (error "Invalid direction of movement: %s" dir)))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
464
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
465 (defun windmove-find-other-window (dir &optional arg window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
466 "Return the window object in direction DIR.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
467 DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
468 (let* ((actual-current-window (or window (selected-window)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
469 (raw-other-window-loc
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
470 (windmove-other-window-loc dir arg actual-current-window))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
471 (constrained-other-window-loc
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
472 (windmove-constrain-loc-for-movement raw-other-window-loc
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
473 actual-current-window
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
474 dir))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
475 (other-window-loc
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
476 (if windmove-wrap-around
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
477 (windmove-wrap-loc-for-movement constrained-other-window-loc
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
478 actual-current-window
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
479 dir)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
480 constrained-other-window-loc)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
481 (window-at (car other-window-loc)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
482 (cdr other-window-loc))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
483
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
484
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
485 ;; Selects the window that's hopefully at the location returned by
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
486 ;; `windmove-other-window-loc', or screams if there's no window there.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
487 (defun windmove-do-window-select (dir &optional arg window)
30892
495502641770 (windmove) <defgroup>: Add :version.
Dave Love <fx@gnu.org>
parents: 27545
diff changeset
488 "Move to the window at direction DIR.
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
489 DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
490 If no window is at direction DIR, an error is signaled."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
491 (let ((other-window (windmove-find-other-window dir arg window)))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
492 (cond ((null other-window)
51424
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
493 (error "No window %s from selected window" dir))
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
494 ((and (window-minibuffer-p other-window)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
495 (not (minibuffer-window-active-p other-window)))
51424
26d468be5b3c (windmove-reference-loc, windmove-frame-edges): Use window-inside-edges.
Richard M. Stallman <rms@gnu.org>
parents: 45166
diff changeset
496 (error "Minibuffer is inactive"))
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
497 (t
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
498 (select-window other-window)))))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
499
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
500
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
501 ;;; end-user functions
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
502 ;; these are all simple interactive wrappers to `windmove-do-
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
503 ;; window-select', meant to be bound to keys.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
504
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
505 ;;;###autoload
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
506 (defun windmove-left (&optional arg)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
507 "Select the window to the left of the current one.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
508 With no prefix argument, or with prefix argument equal to zero,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
509 \"left\" is relative to the position of point in the window; otherwise
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
510 it is relative to the top edge (for positive ARG) or the bottom edge
39588
62d7faafb853 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents: 38436
diff changeset
511 \(for negative ARG) of the current window.
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
512 If no window is at the desired location, an error is signaled."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
513 (interactive "P")
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
514 (windmove-do-window-select 'left arg))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
515
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
516 ;;;###autoload
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
517 (defun windmove-up (&optional arg)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
518 "Select the window above the current one.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
519 With no prefix argument, or with prefix argument equal to zero, \"up\"
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
520 is relative to the position of point in the window; otherwise it is
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
521 relative to the left edge (for positive ARG) or the right edge (for
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
522 negative ARG) of the current window.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
523 If no window is at the desired location, an error is signaled."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
524 (interactive "P")
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
525 (windmove-do-window-select 'up arg))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
526
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
527 ;;;###autoload
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
528 (defun windmove-right (&optional arg)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
529 "Select the window to the right of the current one.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
530 With no prefix argument, or with prefix argument equal to zero,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
531 \"right\" is relative to the position of point in the window;
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
532 otherwise it is relative to the top edge (for positive ARG) or the
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
533 bottom edge (for negative ARG) of the current window.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
534 If no window is at the desired location, an error is signaled."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
535 (interactive "P")
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
536 (windmove-do-window-select 'right arg))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
537
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
538 ;;;###autoload
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
539 (defun windmove-down (&optional arg)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
540 "Select the window below the current one.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
541 With no prefix argument, or with prefix argument equal to zero,
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
542 \"down\" is relative to the position of point in the window; otherwise
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
543 it is relative to the left edge (for positive ARG) or the right edge
39588
62d7faafb853 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents: 38436
diff changeset
544 \(for negative ARG) of the current window.
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
545 If no window is at the desired location, an error is signaled."
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
546 (interactive "P")
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
547 (windmove-do-window-select 'down arg))
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
548
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
549
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
550 ;;; set up keybindings
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
551 ;; Idea for this function is from iswitchb.el, by Stephen Eglen
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
552 ;; (stephen@cns.ed.ac.uk).
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
553 ;; I don't think these bindings will work on non-X terminals; you
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
554 ;; probably want to use different bindings in that case.
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
555
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
556 ;;;###autoload
45166
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
557 (defun windmove-default-keybindings (&optional modifier)
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
558 "Set up keybindings for `windmove'.
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
559 Keybindings are of the form MODIFIER-{left,right,up,down}.
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
560 Default MODIFIER is 'shift."
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
561 (interactive)
45166
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
562 (unless modifier (setq modifier 'shift))
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
563 (global-set-key (vector (list modifier 'left)) 'windmove-left)
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
564 (global-set-key (vector (list modifier 'right)) 'windmove-right)
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
565 (global-set-key (vector (list modifier 'up)) 'windmove-up)
8de5fa67b6cb (windmove-default-keybindings): Add optional parameter to allow using a
Juanma Barranquero <lekktu@gmail.com>
parents: 39588
diff changeset
566 (global-set-key (vector (list modifier 'down)) 'windmove-down))
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
567
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
568
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
569 (provide 'windmove)
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
570
93975
1e3a407766b9 Fix up comment convention on the arch-tag lines.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 79721
diff changeset
571 ;; arch-tag: 56267432-bf1a-4296-a9a0-85c6bd9f2375
27545
ea6b156518f2 *** empty log message ***
Gerd Moellmann <gerd@gnu.org>
parents:
diff changeset
572 ;;; windmove.el ends here