summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog105
-rw-r--r--lisp/comint.el6
-rw-r--r--lisp/doc-view.el5
-rw-r--r--lisp/emacs-lisp/timer.el40
-rw-r--r--lisp/iswitchb.el7
-rw-r--r--lisp/net/rcirc.el21
-rw-r--r--lisp/net/tramp-ftp.el8
-rw-r--r--lisp/net/tramp-sh.el79
-rw-r--r--lisp/net/tramp-smb.el8
-rw-r--r--lisp/net/tramp.el9
-rw-r--r--lisp/shell.el7
-rw-r--r--lisp/textmodes/bibtex.el227
-rw-r--r--lisp/url/ChangeLog4
-rw-r--r--lisp/url/url-future.el6
-rw-r--r--lisp/window.el437
15 files changed, 846 insertions, 123 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 101384cee7d..8cc1c3f1e26 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,108 @@
+2011-06-06 Martin Rudalics <rudalics@gmx.at>
+
+ * window.el (window-right, window-left, window-child)
+ (window-child-count, window-last-child, window-any-p)
+ (normalize-live-buffer, normalize-live-frame)
+ (normalize-any-window, normalize-live-window)
+ (window-iso-combination-p, window-iso-combined-p)
+ (window-iso-combinations)
+ (walk-window-tree-1, walk-window-tree, walk-window-subtree)
+ (windows-with-parameter, window-with-parameter)
+ (window-atom-root, make-window-atom, window-atom-check-1)
+ (window-atom-check, window-side-check, window-check): New
+ functions.
+ (ignore-window-parameters, window-sides, window-sides-vertical)
+ (window-sides-slots): New variables.
+ (window-size-fixed): Move down in code. Minor doc-string fix.
+
+2011-06-05 Andreas Schwab <schwab@linux-m68k.org>
+
+ * comint.el (comint-dynamic-complete-as-filename)
+ (comint-dynamic-complete-filename): Correctly call
+ completion-in-region.
+
+2011-06-05 Deniz Dogan <deniz@dogan.se>
+
+ * net/rcirc.el (rcirc-prompt-for-encryption): Fix bug introduced
+ in last change.
+
+2011-06-05 Deniz Dogan <deniz@dogan.se>
+
+ * net/rcirc.el (rcirc-prompt-for-encryption): New function.
+ (rcirc): Use it to prompt for encryption.
+
+2011-06-05 Roland Winkler <winkler@gnu.org>
+
+ * textmodes/bibtex.el (bibtex-search-buffer): New variable.
+ (bibtex-search-entries): New command bound to C-c C-a.
+ (bibtex-display-entries): New function.
+
+2011-06-05 Roland Winkler <winkler@gnu.org>
+
+ * textmodes/bibtex.el (bibtex-generate-url-list): Fix docstring.
+ (bibtex-insert-kill): After yanking insert newline if necessary.
+ (bibtex-initialize): Call bibtex-string-files-init only once.
+ (bibtex-mode): Do not call easy-menu-add.
+ (bibtex-validate-globally): Use save-excursion in bibtex buffers.
+ (bibtex-yank): Set arg properly if nil.
+
+2011-06-05 Roland Winkler <winkler@gnu.org>
+
+ * textmodes/bibtex.el (bibtex-search-entry-globally): New
+ variable.
+ (bibtex-search-entry): Use it.
+
+2011-06-05 Roland Winkler <winkler@gnu.org>
+
+ * textmodes/bibtex.el (bibtex-entry-format): New option
+ sort-fields.
+ (bibtex-format-entry, bibtex-reformat): Honor this option.
+ (bibtex-parse-entry): Return fields in proper order.
+
+2011-06-05 Juanma Barranquero <lekktu@gmail.com>
+
+ * doc-view.el (doc-view-remove-if): Move computation of result out
+ of `dolist' to silence misleading lexical-binding warning.
+
+2011-06-04 Chong Yidong <cyd@stupidchicken.com>
+
+ * emacs-lisp/timer.el (timer-activate): Remove unused arg.
+ (timer-activate, timer-activate-when-idle): Doc fix (Bug#8793).
+
+2011-06-04 Michael Albinus <michael.albinus@gmx.de>
+
+ * net/tramp-sh.el (tramp-find-shell): Apply workaround also for
+ "SunOS 5.10".
+
+2011-06-04 Michael Albinus <michael.albinus@gmx.de>
+
+ * net/tramp.el (tramp-set-completion-function, tramp-parse-rhosts)
+ (tramp-parse-shosts, tramp-parse-sconfig, tramp-parse-shostkeys)
+ (tramp-parse-hosts, tramp-parse-passwd, tramp-parse-netrc)
+ (tramp-parse-putty):
+ * net/tramp-sh.el (tramp-completion-function-alist-rsh)
+ (tramp-completion-function-alist-ssh)
+ (tramp-completion-function-alist-telnet)
+ (tramp-completion-function-alist-su)
+ (tramp-completion-function-alist-putty): Set `tramp-autoload'
+ cookie.
+
+ * net/tramp-ftp.el:
+ * net/tramp-sh.el:
+ * net/tramp-smb.el: Set `tramp-autoload' cookie, and eval after
+ load "tramp.el" `tramp-set-completion-function'.
+
+2011-06-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * shell.el: Require and use pcomplete.
+ (shell-dynamic-complete-functions): Add pcomplete-completions-at-point.
+ (shell-completion-vars): Set pcomplete-default-completion-function.
+
+2011-06-04 Deniz Dogan <deniz@dogan.se>
+
+ * iswitchb.el (iswitchb-window-buffer-p): Use `member' instead of
+ `memq' (Bug#8799).
+
2011-06-02 Stefan Monnier <monnier@iro.umontreal.ca>
* subr.el (make-progress-reporter): Add "..." by default (bug#8785).
diff --git a/lisp/comint.el b/lisp/comint.el
index e4bc530f361..5548d19ad30 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -3035,7 +3035,8 @@ Returns t if successful."
(when (comint--match-partial-filename)
(unless (window-minibuffer-p (selected-window))
(message "Completing file name..."))
- (apply #'completion-in-region (comint--complete-file-name-data))))
+ (let ((data (comint--complete-file-name-data)))
+ (completion-in-region (nth 0 data) (nth 1 data) (nth 2 data)))))
(defun comint-filename-completion ()
"Return completion data for filename at point, if any."
@@ -3152,7 +3153,8 @@ in the same way as TABLE completes strings of the form (concat S2 S)."
(defun comint-dynamic-complete-as-filename ()
"Dynamically complete at point as a filename.
See `comint-dynamic-complete-filename'. Returns t if successful."
- (apply #'completion-in-region (comint--complete-file-name-data)))
+ (let ((data (comint--complete-file-name-data)))
+ (completion-in-region (nth 0 data) (nth 1 data) (nth 2 data))))
(make-obsolete 'comint-dynamic-complete-as-filename
'comint-filename-completion "24.1")
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 7bd1a55011e..06c3b70a3a6 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -614,9 +614,10 @@ It's a subdirectory of `doc-view-cache-directory'."
(defun doc-view-remove-if (predicate list)
"Return LIST with all items removed that satisfy PREDICATE."
(let (new-list)
- (dolist (item list (nreverse new-list))
+ (dolist (item list)
(when (not (funcall predicate item))
- (setq new-list (cons item new-list))))))
+ (setq new-list (cons item new-list))))
+ (nreverse new-list)))
;;;###autoload
(defun doc-view-mode-p (type)
diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el
index 5f069226aa9..0a035175041 100644
--- a/lisp/emacs-lisp/timer.el
+++ b/lisp/emacs-lisp/timer.el
@@ -189,35 +189,35 @@ fire repeatedly that many seconds apart."
(setcdr reuse-cell timers))
(setq reuse-cell (cons timer timers)))
;; Insert new timer after last which possibly means in front of queue.
- (if last
- (setcdr last reuse-cell)
- (if idle
- (setq timer-idle-list reuse-cell)
- (setq timer-list reuse-cell)))
+ (cond (last (setcdr last reuse-cell))
+ (idle (setq timer-idle-list reuse-cell))
+ (t (setq timer-list reuse-cell)))
(setf (timer--triggered timer) triggered-p)
(setf (timer--idle-delay timer) idle)
nil)
(error "Invalid or uninitialized timer")))
-(defun timer-activate (timer &optional triggered-p reuse-cell idle)
- "Put TIMER on the list of active timers.
+(defun timer-activate (timer &optional triggered-p reuse-cell)
+ "Insert TIMER into `timer-list'.
+If TRIGGERED-P is t, make TIMER inactive (put it on the list, but
+mark it as already triggered). To remove it, use `cancel-timer'.
-If TRIGGERED-P is t, that means to make the timer inactive
-\(put it on the list, but mark it as already triggered).
-To remove from the list, use `cancel-timer'.
-
-REUSE-CELL, if non-nil, is a cons cell to reuse instead
-of allocating a new one."
+REUSE-CELL, if non-nil, is a cons cell to reuse when inserting
+TIMER into `timer-list' (usually a cell removed from that list by
+`cancel-timer-internal'; using this reduces consing for repeat
+timers). If nil, allocate a new cell."
(timer--activate timer triggered-p reuse-cell nil))
(defun timer-activate-when-idle (timer &optional dont-wait reuse-cell)
- "Arrange to activate TIMER whenever Emacs is next idle.
-If optional argument DONT-WAIT is non-nil, then enable the
-timer to activate immediately, or at the right time, if Emacs
-is already idle.
-
-REUSE-CELL, if non-nil, is a cons cell to reuse instead
-of allocating a new one."
+ "Insert TIMER into `timer-idle-list'.
+This arranges to activate TIMER whenever Emacs is next idle.
+If optional argument DONT-WAIT is non-nil, set TIMER to activate
+immediately, or at the right time, if Emacs is already idle.
+
+REUSE-CELL, if non-nil, is a cons cell to reuse when inserting
+TIMER into `timer-idle-list' (usually a cell removed from that
+list by `cancel-timer-internal'; using this reduces consing for
+repeat timers). If nil, allocate a new cell."
(timer--activate timer (not dont-wait) reuse-cell 'idle))
(defalias 'disable-timeout 'cancel-timer)
diff --git a/lisp/iswitchb.el b/lisp/iswitchb.el
index e0da2563c1a..70dda5442d5 100644
--- a/lisp/iswitchb.el
+++ b/lisp/iswitchb.el
@@ -1118,10 +1118,9 @@ Return the modified list with the last element prepended to it."
If BUFFER is visible in the current frame, return nil."
(interactive)
(let ((blist (iswitchb-get-buffers-in-frames 'current)))
- ;;If the buffer is visible in current frame, return nil
- (if (memq buffer blist)
- nil
- ;; maybe in other frame or icon
+ ;; If the buffer is visible in current frame, return nil
+ (unless (member buffer blist)
+ ;; maybe in other frame or icon
(get-buffer-window buffer 0) ; better than 'visible
)))
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index bd9d6846a4b..70190867e89 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -455,15 +455,7 @@ If ARG is non-nil, instead prompt for connection parameters."
:channels)
" "))
"[, ]+" t))
- (encryption
- (intern (completing-read "Encryption (default plain): "
- '("plain" "tls")
- nil t
- (let ((choice (plist-get server-plist
- :encryption)))
- (when choice
- (symbol-name choice)))
- nil "plain"))))
+ (encryption (rcirc-prompt-for-encryption server-plist)))
(rcirc-connect server port nick user-name
rcirc-default-full-name
channels password encryption))
@@ -596,6 +588,17 @@ If ARG is non-nil, instead prompt for connection parameters."
(time-to-seconds (current-time))
(float-time)))
+(defun rcirc-prompt-for-encryption (server-plist)
+ "Prompt the user for the encryption method to use.
+SERVER-PLIST is the property list for the server."
+ (let ((msg "Encryption (default %s): ")
+ (choices '("plain" "tls"))
+ (default (or (plist-get server-plist :encryption)
+ 'plain)))
+ (intern
+ (completing-read (format msg default)
+ choices nil t nil nil (symbol-name default)))))
+
(defun rcirc-keepalive ()
"Send keep alive pings to active rcirc processes.
Kill processes that have not received a server message since the
diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el
index d42a6f57ea9..71b3eacccea 100644
--- a/lisp/net/tramp-ftp.el
+++ b/lisp/net/tramp-ftp.el
@@ -113,9 +113,11 @@ present for backward compatibility."
(list nil "\\`\\(anonymous\\|ftp\\)\\'" tramp-ftp-method)))
;; Add completion function for FTP method.
-(tramp-set-completion-function
- tramp-ftp-method
- '((tramp-parse-netrc "~/.netrc")))
+;;;###tramp-autoload
+(eval-after-load 'tramp
+ '(tramp-set-completion-function
+ tramp-ftp-method
+ '((tramp-parse-netrc "~/.netrc"))))
;; If there is URL syntax, `substitute-in-file-name' needs special
;; handling.
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index a25877abe90..025b4ab6cf3 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -400,11 +400,13 @@ detected as prompt when being sent on echoing hosts, therefore.")
"\\'")
nil ,(user-login-name)))
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-rsh
'((tramp-parse-rhosts "/etc/hosts.equiv")
(tramp-parse-rhosts "~/.rhosts"))
"Default list of (FUNCTION FILE) pairs to be examined for rsh methods.")
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-ssh
'((tramp-parse-rhosts "/etc/hosts.equiv")
(tramp-parse-rhosts "/etc/shosts.equiv")
@@ -420,47 +422,60 @@ detected as prompt when being sent on echoing hosts, therefore.")
(tramp-parse-sknownhosts "~/.ssh2/knownhosts"))
"Default list of (FUNCTION FILE) pairs to be examined for ssh methods.")
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-telnet
'((tramp-parse-hosts "/etc/hosts"))
"Default list of (FUNCTION FILE) pairs to be examined for telnet methods.")
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-su
'((tramp-parse-passwd "/etc/passwd"))
"Default list of (FUNCTION FILE) pairs to be examined for su methods.")
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-putty
'((tramp-parse-putty
"HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"))
"Default list of (FUNCTION REGISTRY) pairs to be examined for putty methods.")
-(tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scp1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scp2" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scpc" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scpx" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "sftp" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "rsync" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "rsyncc" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "rsh" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "remsh" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh2" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh1_old" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh2_old" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "telnet" tramp-completion-function-alist-telnet)
-(tramp-set-completion-function "su" tramp-completion-function-alist-su)
-(tramp-set-completion-function "sudo" tramp-completion-function-alist-su)
-(tramp-set-completion-function "ksu" tramp-completion-function-alist-su)
-(tramp-set-completion-function "krlogin" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "plink1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "plinkx" tramp-completion-function-alist-putty)
-(tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh)
+;;;###tramp-autoload
+(eval-after-load 'tramp
+ '(progn
+ (tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
+ (tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
+ (tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "scp1" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "scp2" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "scpc" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "scpx" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "sftp" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "rsync" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "rsyncc" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "rsh" tramp-completion-function-alist-rsh)
+ (tramp-set-completion-function "remsh" tramp-completion-function-alist-rsh)
+ (tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "ssh1" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "ssh2" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "ssh1_old" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "ssh2_old" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "telnet" tramp-completion-function-alist-telnet)
+ (tramp-set-completion-function "su" tramp-completion-function-alist-su)
+ (tramp-set-completion-function "sudo" tramp-completion-function-alist-su)
+ (tramp-set-completion-function "ksu" tramp-completion-function-alist-su)
+ (tramp-set-completion-function
+ "krlogin" tramp-completion-function-alist-rsh)
+ (tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "plink1" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "plinkx" tramp-completion-function-alist-putty)
+ (tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh)))
;; "getconf PATH" yields:
;; HP-UX: /usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin
@@ -3626,9 +3641,11 @@ file exists and nonzero exit status otherwise."
(tramp-send-command vec "echo ~root" t)
(cond
((or (string-match "^~root$" (buffer-string))
- ;; The default shell (ksh93) of OpenSolaris is buggy.
- (string-equal (tramp-get-connection-property vec "uname" "")
- "SunOS 5.11"))
+ ;; The default shell (ksh93) of OpenSolaris and Solaris
+ ;; is buggy. We've got reports for "SunOS 5.10" and
+ ;; "SunOS 5.11" so far.
+ (string-match (regexp-opt '("SunOS 5.10" "SunOS 5.11"))
+ (tramp-get-connection-property vec "uname" "")))
(setq shell
(or (tramp-find-executable
vec "bash" (tramp-get-remote-path vec) t t)
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index a43e99c1206..eb456298c1a 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -53,9 +53,11 @@
`(,(concat "\\`" tramp-smb-method "\\'") nil nil))
;; Add completion function for SMB method.
-(tramp-set-completion-function
- tramp-smb-method
- '((tramp-parse-netrc "~/.netrc")))
+;;;###tramp-autoload
+(eval-after-load 'tramp
+ '(tramp-set-completion-function
+ tramp-smb-method
+ '((tramp-parse-netrc "~/.netrc"))))
(defcustom tramp-smb-program "smbclient"
"*Name of SMB client to run."
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 178f057a66c..8f1095a0486 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1500,6 +1500,7 @@ letter into the file name. This function removes it."
;;; Config Manipulation Functions:
+;;;###tramp-autoload
(defun tramp-set-completion-function (method function-list)
"Sets the list of completion functions for METHOD.
FUNCTION-LIST is a list of entries of the form (FUNCTION FILE).
@@ -2366,6 +2367,7 @@ PARTIAL-USER must match USER, PARTIAL-HOST must match HOST."
(unless (zerop (+ (length user) (length host)))
(tramp-completion-make-tramp-file-name method user host nil)))
+;;;###tramp-autoload
(defun tramp-parse-rhosts (filename)
"Return a list of (user host) tuples allowed to access.
Either user or host may be nil."
@@ -2396,6 +2398,7 @@ Either user or host may be nil."
(forward-line 1)
result))
+;;;###tramp-autoload
(defun tramp-parse-shosts (filename)
"Return a list of (user host) tuples allowed to access.
User is always nil."
@@ -2425,6 +2428,7 @@ User is always nil."
(forward-line 1))
result))
+;;;###tramp-autoload
(defun tramp-parse-sconfig (filename)
"Return a list of (user host) tuples allowed to access.
User is always nil."
@@ -2454,6 +2458,7 @@ User is always nil."
(forward-line 1))
result))
+;;;###tramp-autoload
(defun tramp-parse-shostkeys (dirname)
"Return a list of (user host) tuples allowed to access.
User is always nil."
@@ -2485,6 +2490,7 @@ User is always nil."
(setq files (cdr files)))
result))
+;;;###tramp-autoload
(defun tramp-parse-hosts (filename)
"Return a list of (user host) tuples allowed to access.
User is always nil."
@@ -2519,6 +2525,7 @@ User is always nil."
;; as default. Unfortunately, we have no information whether any user name
;; has been typed already. So we use `tramp-current-user' as indication,
;; assuming it is set in `tramp-completion-handle-file-name-all-completions'.
+;;;###tramp-autoload
(defun tramp-parse-passwd (filename)
"Return a list of (user host) tuples allowed to access.
Host is always \"localhost\"."
@@ -2548,6 +2555,7 @@ Host is always \"localhost\"."
(forward-line 1)
result))
+;;;###tramp-autoload
(defun tramp-parse-netrc (filename)
"Return a list of (user host) tuples allowed to access.
User may be nil."
@@ -2578,6 +2586,7 @@ User may be nil."
(forward-line 1)
result))
+;;;###tramp-autoload
(defun tramp-parse-putty (registry)
"Return a list of (user host) tuples allowed to access.
User is always nil."
diff --git a/lisp/shell.el b/lisp/shell.el
index e07f996823e..8a282e94160 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -98,6 +98,7 @@
(eval-when-compile (require 'cl))
(require 'comint)
+(require 'pcomplete)
;;; Customization and Buffer Variables
@@ -186,7 +187,9 @@ This is a fine thing to set in your `.emacs' file.")
shell-environment-variable-completion
shell-command-completion
shell-c-a-p-replace-by-expanded-directory
+ pcomplete-completions-at-point
shell-filename-completion
+ ;; Not sure when this one would still be useful. --Stef
comint-filename-completion)
"List of functions called to perform completion.
This variable is used to initialize `comint-dynamic-complete-functions' in the
@@ -380,7 +383,6 @@ to `dirtrack-mode'."
:group 'shell
:type '(choice (const nil) regexp))
-(defvar pcomplete-parse-arguments-function)
(defun shell-completion-vars ()
"Setup completion vars for `shell-mode' and `read-shell-command'."
@@ -396,6 +398,9 @@ to `dirtrack-mode'."
(set (make-local-variable 'pcomplete-parse-arguments-function)
;; FIXME: This function should be moved to shell.el.
#'pcomplete-parse-comint-arguments)
+ ;; Don't use pcomplete's defaulting mechanism, rely on
+ ;; shell-dynamic-complete-functions instead.
+ (set (make-local-variable 'pcomplete-default-completion-function) #'ignore)
(setq comint-input-autoexpand shell-input-autoexpand)
;; Not needed in shell-mode because it's inherited from comint-mode, but
;; placed here for read-shell-command.
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 9d05728ffad..12094887f38 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -126,6 +126,8 @@ braces Enclose parts of field entries by braces according to
`bibtex-field-braces-alist'.
strings Replace parts of field entries by string constants
according to `bibtex-field-strings-alist'.
+sort-fields Sort fields to match the field order in
+ `bibtex-entry-field-alist'.
The value t means do all of the above formatting actions.
The value nil means do no formatting at all."
@@ -144,7 +146,8 @@ The value nil means do no formatting at all."
(const delimiters)
(const unify-case)
(const braces)
- (const strings))))
+ (const strings)
+ (const sort-fields))))
(put 'bibtex-entry-format 'safe-local-variable
(lambda (x)
(or (eq x t)
@@ -153,7 +156,8 @@ The value nil means do no formatting at all."
(unless (memq (pop x)
'(opts-or-alts required-fields numerical-fields
page-dashes whitespace inherit-booktitle realign
- last-comma delimiters unify-case braces strings))
+ last-comma delimiters unify-case braces strings
+ sort-fields))
(setq OK nil)))
(unless (null x) (setq OK nil))
OK))))
@@ -593,7 +597,8 @@ to the directories specified in `bibtex-string-file-path'."
List elements can be absolute file names or file names relative to the
directories specified in `bibtex-file-path'. If an element is a directory,
check all BibTeX files in this directory. If an element is the symbol
-`bibtex-file-path', check all BibTeX files in `bibtex-file-path'."
+`bibtex-file-path', check all BibTeX files in `bibtex-file-path'.
+See also `bibtex-search-entry-globally'."
:group 'bibtex
:type '(repeat (choice (const :tag "bibtex-file-path" bibtex-file-path)
directory file)))
@@ -601,6 +606,12 @@ check all BibTeX files in this directory. If an element is the symbol
(defvar bibtex-file-path (getenv "BIBINPUTS")
"*Colon separated list of paths to search for `bibtex-files'.")
+(defcustom bibtex-search-entry-globally nil
+ "If non-nil, interactive calls of `bibtex-search-entry' search globally.
+A global search includes all files in `bibtex-files'."
+ :group 'bibtex
+ :type 'boolean)
+
(defcustom bibtex-help-message t
"If non-nil print help messages in the echo area on entering a new field."
:group 'bibtex
@@ -912,7 +923,7 @@ The following is a complex example, see URL `http://link.aps.org/'.
(((\"journal\" . \"\\\\=<\\(PR[ABCDEL]?\\|RMP\\)\\\\=>\")
\"http://link.aps.org/abstract/%s/v%s/p%s\"
- (\"journal\" \".*\" downcase)
+ (\"journal\" \".*\" upcase)
(\"volume\" \".*\" 0)
(\"pages\" \"\\`[A-Z]?[0-9]+\" 0)))"
:group 'bibtex
@@ -957,6 +968,11 @@ Set this variable before loading BibTeX mode."
:group 'bibtex
:type 'boolean)
+(defcustom bibtex-search-buffer "*BibTeX Search*"
+ "Buffer for BibTeX search results."
+ :group 'bibtex
+ :type 'string)
+
;; `bibtex-font-lock-keywords' is a user option, too. But since the
;; patterns used to define this variable are defined in a later
;; section of this file, it is defined later.
@@ -1014,6 +1030,7 @@ Set this variable before loading BibTeX mode."
(define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
(define-key km "\C-c\C-rw" 'widen)
(define-key km "\C-c\C-l" 'bibtex-url)
+ (define-key km "\C-c\C-a" 'bibtex-search-entries)
(define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
(define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
(define-key km "\C-c\C-ei" 'bibtex-InCollection)
@@ -1091,6 +1108,8 @@ Set this variable before loading BibTeX mode."
["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
(fboundp 'reftex-view-crossref-from-bibtex)])
("Operating on Buffer or Region"
+ ["Search Entries" bibtex-search-entries t]
+ "--"
["Validate Entries" bibtex-validate t]
["Sort Entries" bibtex-sort-buffer t]
["Reformat Entries" bibtex-reformat t]
@@ -1881,6 +1900,9 @@ Optional arg COMMA is as in `bibtex-enclosing-field'."
(push-mark)
(insert (funcall fun 'bibtex-entry-kill-ring-yank-pointer
bibtex-entry-kill-ring))
+ ;; If we copied an entry from a buffer containing only this one entry,
+ ;; it can be missing the second "\n".
+ (unless (looking-back "\n\n") (insert "\n"))
(unless (functionp bibtex-reference-keys)
;; update `bibtex-reference-keys'
(save-excursion
@@ -1906,7 +1928,7 @@ Formats current entry according to variable `bibtex-entry-format'."
'(realign opts-or-alts required-fields numerical-fields
page-dashes whitespace inherit-booktitle
last-comma delimiters unify-case braces
- strings)
+ strings sort-fields)
bibtex-entry-format))
(left-delim-re (regexp-quote (bibtex-field-left-delimiter)))
bounds crossref-key req-field-list default-field-list field-list
@@ -1962,7 +1984,21 @@ Formats current entry according to variable `bibtex-entry-format'."
;; default list of fields that may appear in this entry
default-field-list (append (nth 0 (nth 1 entry-list))
(nth 1 (nth 1 entry-list))
- bibtex-user-optional-fields)))
+ bibtex-user-optional-fields))
+
+ (when (memq 'sort-fields format)
+ (goto-char (point-min))
+ (let ((beg-fields (save-excursion (bibtex-beginning-first-field)))
+ (fields-alist (bibtex-parse-entry))
+ bibtex-help-message elt)
+ (delete-region beg-fields (point))
+ (dolist (field default-field-list)
+ (when (setq elt (assoc-string (car field) fields-alist t))
+ (setq fields-alist (delete elt fields-alist))
+ (bibtex-make-field (list (car elt) "" (cdr elt)) nil nil t)))
+ (dolist (field fields-alist)
+ (unless (member (car field) '("=key=" "=type="))
+ (bibtex-make-field (list (car field) "" (cdr field)) nil nil t))))))
;; process all fields
(bibtex-beginning-first-field (point-min))
@@ -2698,12 +2734,14 @@ When called interactively, FORCE is t, CURRENT is t if current buffer uses
((and (not current) (memq (current-buffer) buffer-list))
(setq buffer-list (delq (current-buffer) buffer-list))))
;; parse keys
- (dolist (buffer buffer-list)
- (with-current-buffer buffer
- (if (or force (functionp bibtex-reference-keys))
- (bibtex-parse-keys))
- (unless (functionp bibtex-strings)
- (bibtex-parse-strings (bibtex-string-files-init)))))
+ (let (string-init)
+ (dolist (buffer buffer-list)
+ (with-current-buffer buffer
+ (if (or force (functionp bibtex-reference-keys))
+ (bibtex-parse-keys))
+ (when (or force (functionp bibtex-strings))
+ (unless string-init (setq string-init (bibtex-string-files-init)))
+ (bibtex-parse-strings string-init)))))
;; select BibTeX buffer
(if select
(if buffer-list
@@ -3018,10 +3056,7 @@ if that value is non-nil.
bibtex-font-lock-syntactic-keywords))
(setq imenu-generic-expression
(list (list nil bibtex-entry-head bibtex-key-in-head))
- imenu-case-fold-search t)
- ;; XEmacs needs `easy-menu-add', Emacs does not care
- (easy-menu-add bibtex-edit-menu)
- (easy-menu-add bibtex-entry-menu))
+ imenu-case-fold-search t))
(defun bibtex-field-list (entry-type)
"Return list of allowed fields for entry ENTRY-TYPE.
@@ -3139,7 +3174,7 @@ If optional arg CONTENT is non-nil extract content of text fields."
(bibtex-text-in-field-bounds bounds content))
alist)
(goto-char (bibtex-end-of-field bounds))))
- alist))
+ (nreverse alist)))
(defun bibtex-autofill-entry ()
"Try to fill fields of current BibTeX entry based on neighboring entries.
@@ -3567,10 +3602,15 @@ is limited to the current buffer. Optional arg START is buffer position
where the search starts. If it is nil, start search at beginning of buffer.
If DISPLAY is non-nil, display the buffer containing KEY.
Otherwise, use `set-buffer'.
-When called interactively, GLOBAL is t if there is a prefix arg or the current
-mode is not `bibtex-mode', START is nil, and DISPLAY is t."
+When called interactively, START is nil, DISPLAY is t.
+Also, GLOBAL is t if the current mode is not `bibtex-mode'
+or `bibtex-search-entry-globally' is non-nil.
+A prefix arg negates the value of `bibtex-search-entry-globally'."
(interactive
- (let ((global (or current-prefix-arg (not (eq major-mode 'bibtex-mode)))))
+ (let ((global (or (not (eq major-mode 'bibtex-mode))
+ (if bibtex-search-entry-globally
+ (not current-prefix-arg)
+ current-prefix-arg))))
(list (bibtex-read-key "Find key: " nil global) global nil t)))
(if (and global bibtex-files)
(let ((buffer-list (bibtex-initialize t))
@@ -3843,20 +3883,21 @@ Return t if test was successful, nil otherwise."
;; Check for duplicate keys within BibTeX buffer
(dolist (buffer buffer-list)
(with-current-buffer buffer
- (let (entry-type key key-list)
- (goto-char (point-min))
- (while (re-search-forward bibtex-entry-head nil t)
- (setq entry-type (bibtex-type-in-head)
- key (bibtex-key-in-head))
- (if (or (and strings (bibtex-string= entry-type "string"))
- (assoc-string entry-type bibtex-entry-field-alist t))
- (if (member key key-list)
- (push (format "%s:%d: Duplicate key `%s'\n"
- (buffer-file-name)
- (bibtex-current-line) key)
- error-list)
- (push key key-list))))
- (push (cons buffer key-list) buffer-key-list))))
+ (save-excursion
+ (let (entry-type key key-list)
+ (goto-char (point-min))
+ (while (re-search-forward bibtex-entry-head nil t)
+ (setq entry-type (bibtex-type-in-head)
+ key (bibtex-key-in-head))
+ (if (or (and strings (bibtex-string= entry-type "string"))
+ (assoc-string entry-type bibtex-entry-field-alist t))
+ (if (member key key-list)
+ (push (format "%s:%d: Duplicate key `%s'\n"
+ (buffer-file-name)
+ (bibtex-current-line) key)
+ error-list)
+ (push key key-list))))
+ (push (cons buffer key-list) buffer-key-list)))))
;; Check for duplicate keys among BibTeX buffers
(while (setq current-buf (pop buffer-list))
@@ -4118,6 +4159,7 @@ More precisely, reinsert the field or entry killed or yanked most recently.
With argument N, reinsert the Nth most recently killed BibTeX item.
See also the command \\[bibtex-yank-pop]."
(interactive "*p")
+ (unless n (setq n 1))
(bibtex-insert-kill (1- n) t)
(setq this-command 'bibtex-yank))
@@ -4397,14 +4439,15 @@ If mark is active reformat entries in region, if not in whole buffer."
("Force delimiters? " . 'delimiters)
("Unify case of entry types and field names? " . 'unify-case)
("Enclose parts of field entries by braces? " . 'braces)
- ("Replace parts of field entries by string constants? " . 'strings))))))
+ ("Replace parts of field entries by string constants? " . 'strings)
+ ("Sort fields? " . 'sort-fields))))))
;; Do not include required-fields because `bibtex-reformat'
;; cannot handle the error messages of `bibtex-format-entry'.
;; Use `bibtex-validate' to check for required fields.
((eq t bibtex-entry-format)
'(realign opts-or-alts numerical-fields delimiters
last-comma page-dashes unify-case inherit-booktitle
- whitespace braces strings))
+ whitespace braces strings sort-fields))
(t
(cons 'realign (remove 'required-fields bibtex-entry-format)))))
(reformat-reference-keys
@@ -4754,6 +4797,118 @@ Return the URL or nil if none can be generated."
(message "No URL known."))
url)))
+;; We could combine multiple seach results with set operations
+;; AND, OR, MINUS, and NOT. Would this be useful?
+;; How complicated are searches in real life?
+;; We could also have other searches such as "publication year newer than...".
+(defun bibtex-search-entries (field regexp &optional global display)
+ "Search BibTeX entries for FIELD matching REGEXP.
+REGEXP may be a regexp to search for.
+If REGEXP is a function, it is called for each entry with two args,
+the buffer positions of beginning and end of entry. Then an entry
+is accepted if this function returns non-nil.
+If FIELD is an empty string perform search for REGEXP in whole entry.
+With GLOBAL non-nil, search in `bibtex-files'. Otherwise the search
+is limited to the current buffer.
+If DISPLAY is non-nil, display search results in `bibtex-search-buffer'.
+When called interactively, DISPLAY is t.
+Also, GLOBAL is t if `bibtex-search-entry-globally' is non-nil.
+A prefix arg negates the value of `bibtex-search-entry-globally'.
+Return alist with elements (KEY FILE ENTRY),
+where FILE is the BibTeX file of ENTRY."
+ (interactive
+ (list (completing-read
+ "Field: "
+ (delete-dups
+ (apply 'append
+ bibtex-user-optional-fields
+ (mapcar (lambda (x)
+ (append (mapcar 'car (nth 0 (nth 1 x)))
+ (mapcar 'car (nth 1 (nth 1 x)))))
+ bibtex-entry-field-alist))) nil t)
+ (read-string "Regexp: ")
+ (if bibtex-search-entry-globally
+ (not current-prefix-arg)
+ current-prefix-arg)
+ t))
+ (let ((funp (functionp regexp))
+ entries text file)
+ ;; If REGEXP is a function, the value of FIELD is ignored anyway.
+ ;; Yet to ensure the code below does not fail, we make FIELD
+ ;; a non-empty string.
+ (if (and funp (string= "" field)) (setq field "unrestricted"))
+ (dolist (buffer (if (and global bibtex-files)
+ (bibtex-initialize t)
+ (list (current-buffer))))
+ (with-current-buffer buffer
+ (setq file (if buffer-file-name
+ (file-name-nondirectory buffer-file-name)
+ (buffer-name buffer)))
+ (save-excursion
+ (goto-char (point-min))
+ (if (string= "" field)
+ ;; Unrestricted search.
+ (while (re-search-forward regexp nil t)
+ (let ((beg (bibtex-beginning-of-entry))
+ (end (bibtex-end-of-entry))
+ key)
+ (if (and (<= beg (match-beginning 0))
+ (<= (match-end 0) end)
+ (save-excursion
+ (goto-char beg)
+ (and (looking-at bibtex-entry-head)
+ (setq key (bibtex-key-in-head)))))
+ (add-to-list 'entries
+ (list key file
+ (buffer-substring-no-properties
+ beg end))))))
+ ;; The following is slow. But it works reliably even in more
+ ;; complicated cases with BibTeX string constants and crossrefed
+ ;; entries. If you prefer speed over reliability, perform an
+ ;; unrestricted search.
+ (bibtex-map-entries
+ (lambda (key beg end)
+ (if (cond (funp (funcall regexp beg end))
+ ((and (setq text (bibtex-text-in-field field t))
+ (string-match regexp text))))
+ (add-to-list 'entries
+ (list key file
+ (buffer-substring-no-properties
+ beg end))))))))))
+ (if display
+ (if entries
+ (bibtex-display-entries entries)
+ (message "No BibTeX entries %smatching `%s'"
+ (if (string= "" field) ""
+ (format "with field `%s' " field))
+ regexp)))
+ entries))
+
+(defun bibtex-display-entries (entries &optional append)
+ "Display BibTeX ENTRIES in `bibtex-search-buffer'.
+ENTRIES is an alist with elements (KEY FILE ENTRY),
+where FILE is the BibTeX file of ENTRY.
+If APPEND is non-nil, append ENTRIES to those already displayed."
+ (pop-to-buffer (get-buffer-create bibtex-search-buffer))
+ ;; It would be nice if this buffer was editable, though editing
+ ;; can be meaningful only for individual existing entries
+ ;; (unlike reordering or creating new entries).
+ ;; Fancy workaround: Editing commands in the virtual buffer could
+ ;; jump to the real entry in the real buffer.
+ (let (buffer-read-only)
+ (if append (goto-char (point-max)) (erase-buffer))
+ (dolist (entry (sort entries (lambda (x y) (string< (car x) (car y)))))
+ (insert "% " (nth 1 entry) "\n" (nth 2 entry) "\n\n")))
+ ;; `bibtex-sort-buffer' fails with the file names associated with
+ ;; each entry. Prior to sorting we could make the file name
+ ;; a BibTeX field of each entry (using `bibtex-make-field').
+ ;; Or we could make it a text property that we unfold afterwards.
+ ;; (bibtex-sort-buffer)
+ (bibtex-mode)
+ (set-buffer-modified-p nil)
+ (setq buffer-read-only t)
+ (goto-char (point-min)))
+
;; Make BibTeX a Feature
diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog
index e5ab59e828f..9f7ad1c1ca5 100644
--- a/lisp/url/ChangeLog
+++ b/lisp/url/ChangeLog
@@ -1,3 +1,7 @@
+2011-06-04 Andreas Schwab <schwab@linux-m68k.org>
+
+ * url-future.el (url-future-test): Fix scope of `saver'.
+
2011-06-01 Glenn Morris <rgm@gnu.org>
* url-queue.el (url-queue-parallel-processes, url-queue-timeout):
diff --git a/lisp/url/url-future.el b/lisp/url/url-future.el
index 334c4fa9126..ac85a3cec47 100644
--- a/lisp/url/url-future.el
+++ b/lisp/url/url-future.el
@@ -96,7 +96,8 @@
(url-future-finish url-future 'cancel)))
(ert-deftest url-future-test ()
- (let* ((text "running future")
+ (let* (saver
+ (text "running future")
(good (make-url-future :value (lambda () (format text))
:callback (lambda (f) (set 'saver f))))
(bad (make-url-future :value (lambda () (/ 1 0))
@@ -104,8 +105,7 @@
(tocancel (make-url-future :value (lambda () (/ 1 0))
:callback (lambda (f) (set 'saver f))
:errorback (lambda (&rest d)
- (set 'saver d))))
- saver)
+ (set 'saver d)))))
(should (equal good (url-future-call good)))
(should (equal good saver))
(should (equal text (url-future-value good)))
diff --git a/lisp/window.el b/lisp/window.el
index 9ea00442628..0da3f5ae1de 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -30,15 +30,6 @@
(eval-when-compile (require 'cl))
-(defvar window-size-fixed nil
- "*Non-nil in a buffer means windows displaying the buffer are fixed-size.
-If the value is `height', then only the window's height is fixed.
-If the value is `width', then only the window's width is fixed.
-Any other non-nil value fixes both the width and the height.
-Emacs won't change the size of any window displaying that buffer,
-unless you explicitly change the size, or Emacs has no other choice.")
-(make-variable-buffer-local 'window-size-fixed)
-
(defmacro save-selected-window (&rest body)
"Execute BODY, then select the previously selected window.
The value returned is the value of the last form in BODY.
@@ -72,6 +63,434 @@ are not altered by this macro (unless they are altered in BODY)."
(when (window-live-p save-selected-window-window)
(select-window save-selected-window-window 'norecord))))))
+;; The following two functions are like `window-next' and `window-prev'
+;; but the WINDOW argument is _not_ optional (so they don't substitute
+;; the selected window for nil), and they return nil when WINDOW doesn't
+;; have a parent (like a frame's root window or a minibuffer window).
+(defsubst window-right (window)
+ "Return WINDOW's right sibling.
+Return nil if WINDOW is the root window of its frame. WINDOW can
+be any window."
+ (and window (window-parent window) (window-next window)))
+
+(defsubst window-left (window)
+ "Return WINDOW's left sibling.
+Return nil if WINDOW is the root window of its frame. WINDOW can
+be any window."
+ (and window (window-parent window) (window-prev window)))
+
+(defsubst window-child (window)
+ "Return WINDOW's first child window."
+ (or (window-vchild window) (window-hchild window)))
+
+(defun window-child-count (window)
+ "Return number of WINDOW's child windows."
+ (let ((count 0))
+ (when (and (windowp window) (setq window (window-child window)))
+ (while window
+ (setq count (1+ count))
+ (setq window (window-next window))))
+ count))
+
+(defun window-last-child (window)
+ "Return last child window of WINDOW."
+ (when (and (windowp window) (setq window (window-child window)))
+ (while (window-next window)
+ (setq window (window-next window))))
+ window)
+
+(defsubst window-any-p (object)
+ "Return t if OBJECT denotes a live or internal window."
+ (and (windowp object)
+ (or (window-buffer object) (window-child object))
+ t))
+
+;; The following four functions should probably go to subr.el.
+(defsubst normalize-live-buffer (buffer-or-name)
+ "Return buffer specified by BUFFER-OR-NAME.
+BUFFER-OR-NAME must be either a buffer or a string naming a live
+buffer and defaults to the current buffer."
+ (cond
+ ((not buffer-or-name)
+ (current-buffer))
+ ((bufferp buffer-or-name)
+ (if (buffer-live-p buffer-or-name)
+ buffer-or-name
+ (error "Buffer %s is not a live buffer" buffer-or-name)))
+ ((get-buffer buffer-or-name))
+ (t
+ (error "No such buffer %s" buffer-or-name))))
+
+(defsubst normalize-live-frame (frame)
+ "Return frame specified by FRAME.
+FRAME must be a live frame and defaults to the selected frame."
+ (if frame
+ (if (frame-live-p frame)
+ frame
+ (error "%s is not a live frame" frame))
+ (selected-frame)))
+
+(defsubst normalize-any-window (window)
+ "Return window specified by WINDOW.
+WINDOW must be a window that has not been deleted and defaults to
+the selected window."
+ (if window
+ (if (window-any-p window)
+ window
+ (error "%s is not a window" window))
+ (selected-window)))
+
+(defsubst normalize-live-window (window)
+ "Return live window specified by WINDOW.
+WINDOW must be a live window and defaults to the selected one."
+ (if window
+ (if (and (windowp window) (window-buffer window))
+ window
+ (error "%s is not a live window" window))
+ (selected-window)))
+
+(defvar ignore-window-parameters nil
+ "If non-nil, standard functions ignore window parameters.
+The functions currently affected by this are `split-window',
+`delete-window', `delete-other-windows' and `other-window'.
+
+An application may bind this to a non-nil value around calls to
+these functions to inhibit processing of window parameters.")
+
+(defun window-iso-combination-p (&optional window horizontal)
+ "If WINDOW is a vertical combination return WINDOW's first child.
+WINDOW can be any window and defaults to the selected one.
+Optional argument HORIZONTAL non-nil means return WINDOW's first
+child if WINDOW is a horizontal combination."
+ (setq window (normalize-any-window window))
+ (if horizontal
+ (window-hchild window)
+ (window-vchild window)))
+
+(defsubst window-iso-combined-p (&optional window horizontal)
+ "Return non-nil if and only if WINDOW is vertically combined.
+WINDOW can be any window and defaults to the selected one.
+Optional argument HORIZONTAL non-nil means return non-nil if and
+only if WINDOW is horizontally combined."
+ (setq window (normalize-any-window window))
+ (let ((parent (window-parent window)))
+ (and parent (window-iso-combination-p parent horizontal))))
+
+(defun window-iso-combinations (&optional window horizontal)
+ "Return largest number of vertically arranged subwindows of WINDOW.
+WINDOW can be any window and defaults to the selected one.
+Optional argument HORIZONTAL non-nil means to return the largest
+number of horizontally arranged subwindows of WINDOW."
+ (setq window (normalize-any-window window))
+ (cond
+ ((window-live-p window)
+ ;; If WINDOW is live, return 1.
+ 1)
+ ((window-iso-combination-p window horizontal)
+ ;; If WINDOW is iso-combined, return the sum of the values for all
+ ;; subwindows of WINDOW.
+ (let ((child (window-child window))
+ (count 0))
+ (while child
+ (setq count
+ (+ (window-iso-combinations child horizontal)
+ count))
+ (setq child (window-right child)))
+ count))
+ (t
+ ;; If WINDOW is not iso-combined, return the maximum value of any
+ ;; subwindow of WINDOW.
+ (let ((child (window-child window))
+ (count 1))
+ (while child
+ (setq count
+ (max (window-iso-combinations child horizontal)
+ count))
+ (setq child (window-right child)))
+ count))))
+
+(defun walk-window-tree-1 (proc walk-window-tree-window any &optional sub-only)
+ "Helper function for `walk-window-tree' and `walk-window-subtree'."
+ (let (walk-window-tree-buffer)
+ (while walk-window-tree-window
+ (setq walk-window-tree-buffer
+ (window-buffer walk-window-tree-window))
+ (when (or walk-window-tree-buffer any)
+ (funcall proc walk-window-tree-window))
+ (unless walk-window-tree-buffer
+ (walk-window-tree-1
+ proc (window-hchild walk-window-tree-window) any)
+ (walk-window-tree-1
+ proc (window-vchild walk-window-tree-window) any))
+ (if sub-only
+ (setq walk-window-tree-window nil)
+ (setq walk-window-tree-window
+ (window-right walk-window-tree-window))))))
+
+(defun walk-window-tree (proc &optional frame any)
+ "Run function PROC on each live window of FRAME.
+PROC must be a function with one argument - a window. FRAME must
+be a live frame and defaults to the selected one. ANY, if
+non-nil means to run PROC on all live and internal windows of
+FRAME.
+
+This function performs a pre-order, depth-first traversal of the
+window tree. If PROC changes the window tree, the result is
+unpredictable."
+ (let ((walk-window-tree-frame (normalize-live-frame frame)))
+ (walk-window-tree-1
+ proc (frame-root-window walk-window-tree-frame) any)))
+
+(defun walk-window-subtree (proc &optional window any)
+ "Run function PROC on each live subwindow of WINDOW.
+WINDOW defaults to the selected window. PROC must be a function
+with one argument - a window. ANY, if non-nil means to run PROC
+on all live and internal subwindows of WINDOW.
+
+This function performs a pre-order, depth-first traversal of the
+window tree rooted at WINDOW. If PROC changes that window tree,
+the result is unpredictable."
+ (setq window (normalize-any-window window))
+ (walk-window-tree-1 proc window any t))
+
+(defun windows-with-parameter (parameter &optional value frame any values)
+ "Return a list of all windows on FRAME with PARAMETER non-nil.
+FRAME defaults to the selected frame. Optional argument VALUE
+non-nil means only return windows whose window-parameter value of
+PARAMETER equals VALUE \(comparison is done using `equal').
+Optional argument ANY non-nil means consider internal windows
+too. Optional argument VALUES non-nil means return a list of cons
+cells whose car is the value of the parameter and whose cdr is
+the window."
+ (let (this-value windows)
+ (walk-window-tree
+ (lambda (window)
+ (when (and (setq this-value (window-parameter window parameter))
+ (or (not value) (or (equal value this-value))))
+ (setq windows
+ (if values
+ (cons (cons this-value window) windows)
+ (cons window windows)))))
+ frame any)
+
+ (nreverse windows)))
+
+(defun window-with-parameter (parameter &optional value frame any)
+ "Return first window on FRAME with PARAMETER non-nil.
+FRAME defaults to the selected frame. Optional argument VALUE
+non-nil means only return a window whose window-parameter value
+for PARAMETER equals VALUE \(comparison is done with `equal').
+Optional argument ANY non-nil means consider internal windows
+too."
+ (let (this-value windows)
+ (catch 'found
+ (walk-window-tree
+ (lambda (window)
+ (when (and (setq this-value (window-parameter window parameter))
+ (or (not value) (equal value this-value)))
+ (throw 'found window)))
+ frame any))))
+
+;;; Atomic windows.
+(defun window-atom-root (&optional window)
+ "Return root of atomic window WINDOW is a part of.
+WINDOW can be any window and defaults to the selected one.
+Return nil if WINDOW is not part of a atomic window."
+ (setq window (normalize-any-window window))
+ (let (root)
+ (while (and window (window-parameter window 'window-atom))
+ (setq root window)
+ (setq window (window-parent window)))
+ root))
+
+(defun make-window-atom (window)
+ "Make WINDOW an atomic window.
+WINDOW must be an internal window. Return WINDOW."
+ (if (not (window-child window))
+ (error "Window %s is not an internal window" window)
+ (walk-window-subtree
+ (lambda (window)
+ (set-window-parameter window 'window-atom t))
+ window t)
+ window))
+
+(defun window-atom-check-1 (window)
+ "Subroutine of `window-atom-check'."
+ (when window
+ (if (window-parameter window 'window-atom)
+ (let ((count 0))
+ (when (or (catch 'reset
+ (walk-window-subtree
+ (lambda (window)
+ (if (window-parameter window 'window-atom)
+ (setq count (1+ count))
+ (throw 'reset t)))
+ window t))
+ ;; count >= 1 must hold here. If there's no other
+ ;; window around dissolve this atomic window.
+ (= count 1))
+ ;; Dissolve atomic window.
+ (walk-window-subtree
+ (lambda (window)
+ (set-window-parameter window 'window-atom nil))
+ window t)))
+ ;; Check children.
+ (unless (window-buffer window)
+ (window-atom-check-1 (window-hchild window))
+ (window-atom-check-1 (window-vchild window))))
+ ;; Check right sibling
+ (window-atom-check-1 (window-right window))))
+
+(defun window-atom-check (&optional frame)
+ "Check atomicity of all windows on FRAME.
+FRAME defaults to the selected frame. If an atomic window is
+wrongly configured, reset the atomicity of all its subwindows to
+nil. An atomic window is wrongly configured if it has no
+subwindows or one of its subwindows is not atomic."
+ (window-atom-check-1 (frame-root-window frame)))
+
+;; Side windows.
+(defvar window-sides '(left top right bottom)
+ "Window sides.")
+
+(defcustom window-sides-vertical nil
+ "If non-nil, left and right side windows are full height.
+Otherwise, top and bottom side windows are full width."
+ :type 'boolean
+ :group 'windows
+ :version "24.1")
+
+(defcustom window-sides-slots '(nil nil nil nil)
+ "Maximum number of side window slots.
+The value is a list of four elements specifying the number of
+side window slots on \(in this order) the left, top, right and
+bottom side of each frame. If an element is a number, this means
+to display at most that many side windows on the corresponding
+side. If an element is nil, this means there's no bound on the
+number of slots on that side."
+ :risky t
+ :type
+ '(list
+ :value (nil nil nil nil)
+ (choice
+ :tag "Left"
+ :help-echo "Maximum slots of left side window."
+ :value nil
+ :format "%[Left%] %v\n"
+ (const :tag "Unlimited" :format "%t" nil)
+ (integer :tag "Number" :value 2 :size 5))
+ (choice
+ :tag "Top"
+ :help-echo "Maximum slots of top side window."
+ :value nil
+ :format "%[Top%] %v\n"
+ (const :tag "Unlimited" :format "%t" nil)
+ (integer :tag "Number" :value 3 :size 5))
+ (choice
+ :tag "Right"
+ :help-echo "Maximum slots of right side window."
+ :value nil
+ :format "%[Right%] %v\n"
+ (const :tag "Unlimited" :format "%t" nil)
+ (integer :tag "Number" :value 2 :size 5))
+ (choice
+ :tag "Bottom"
+ :help-echo "Maximum slots of bottom side window."
+ :value nil
+ :format "%[Bottom%] %v\n"
+ (const :tag "Unlimited" :format "%t" nil)
+ (integer :tag "Number" :value 3 :size 5)))
+ :group 'windows)
+
+(defun window-side-check (&optional frame)
+ "Check the window-side parameter of all windows on FRAME.
+FRAME defaults to the selected frame. If the configuration is
+invalid, reset all window-side parameters to nil.
+
+A valid configuration has to preserve the following invariant:
+
+- If a window has a non-nil window-side parameter, it must have a
+ parent window and the parent window's window-side parameter
+ must be either nil or the same as for window.
+
+- If windows with non-nil window-side parameters exist, there
+ must be at most one window of each side and non-side with a
+ parent whose window-side parameter is nil and there must be no
+ leaf window whose window-side parameter is nil."
+ (let (normal none left top right bottom
+ side parent parent-side code)
+ (when (or (catch 'reset
+ (walk-window-tree
+ (lambda (window)
+ (setq side (window-parameter window 'window-side))
+ (setq parent (window-parent window))
+ (setq parent-side
+ (and parent (window-parameter parent 'window-side)))
+ ;; The following `cond' seems a bit tedious, but I'd
+ ;; rather stick to using just the stack.
+ (cond
+ (parent-side
+ (when (not (eq parent-side side))
+ ;; A parent whose window-side is non-nil must
+ ;; have a child with the same window-side.
+ (throw 'reset t)))
+ ;; Now check that there's more than one main window
+ ;; for any of none, left, top, right and bottom.
+ ((eq side 'none)
+ (if none
+ (throw 'reset t)
+ (setq none t)))
+ ((eq side 'left)
+ (if left
+ (throw 'reset t)
+ (setq left t)))
+ ((eq side 'top)
+ (if top
+ (throw 'reset t)
+ (setq top t)))
+ ((eq side 'right)
+ (if right
+ (throw 'reset t)
+ (setq right t)))
+ ((eq side 'bottom)
+ (if bottom
+ (throw 'reset t)
+ (setq bottom t)))
+ ((window-buffer window)
+ ;; A leaf window without window-side parameter,
+ ;; record its existence.
+ (setq normal t))))
+ frame t))
+ (if none
+ ;; At least one non-side window exists, so there must
+ ;; be at least one side-window and no normal window.
+ (or (not (or left top right bottom)) normal)
+ ;; No non-side window exists, so there must be no side
+ ;; window either.
+ (or left top right bottom)))
+ (walk-window-tree
+ (lambda (window)
+ (set-window-parameter window 'window-side nil))
+ frame t))))
+
+(defun window-check (&optional frame)
+ "Check atomic and side windows on FRAME.
+FRAME defaults to the selected frame."
+ (window-side-check frame)
+ (window-atom-check frame))
+
+;;; Window sizes.
+(defvar window-size-fixed nil
+ "Non-nil in a buffer means windows displaying the buffer are fixed-size.
+If the value is `height', then only the window's height is fixed.
+If the value is `width', then only the window's width is fixed.
+Any other non-nil value fixes both the width and the height.
+
+Emacs won't change the size of any window displaying that buffer,
+unless it has no other choice \(like when deleting a neighboring
+window).")
+(make-variable-buffer-local 'window-size-fixed)
+
(defun window-body-height (&optional window)
"Return number of lines in WINDOW available for actual buffer text.
WINDOW defaults to the selected window.