aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorJoakim Verona2011-06-23 01:28:30 +0200
committerJoakim Verona2011-06-23 01:28:30 +0200
commitc5082a753011dacef505e91f1fc30a84fa75a2eb (patch)
tree2c995eff276b6e9e68f54b4ebe76bf012231c86d /lisp
parent787c27e81f046cfa1c457ed405551f8ca0ddb0e8 (diff)
parent297dde5a97c0c5c8020db72213c7f84067f1ee21 (diff)
downloademacs-c5082a753011dacef505e91f1fc30a84fa75a2eb.tar.gz
emacs-c5082a753011dacef505e91f1fc30a84fa75a2eb.zip
merge upstream
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog320
-rw-r--r--lisp/cus-edit.el5
-rw-r--r--lisp/cus-face.el51
-rw-r--r--lisp/dired-x.el9
-rw-r--r--lisp/dired.el2
-rw-r--r--lisp/emacs-lisp/bytecomp.el19
-rw-r--r--lisp/emacs-lisp/rx.el17
-rw-r--r--lisp/emacs-lisp/syntax.el5
-rw-r--r--lisp/files.el1
-rw-r--r--lisp/frame.el90
-rw-r--r--lisp/gnus/ChangeLog35
-rw-r--r--lisp/gnus/auth-source.el205
-rw-r--r--lisp/gnus/nnimap.el2
-rw-r--r--lisp/info.el2
-rw-r--r--lisp/international/mule-cmds.el30
-rw-r--r--lisp/mail/mailabbrev.el1
-rw-r--r--lisp/mail/smtpmail.el646
-rw-r--r--lisp/menu-bar.el6
-rw-r--r--lisp/minibuffer.el17
-rw-r--r--lisp/misc.el2
-rw-r--r--lisp/net/browse-url.el2
-rw-r--r--lisp/net/network-stream.el53
-rw-r--r--lisp/net/rcirc.el16
-rw-r--r--lisp/net/tramp-cache.el78
-rw-r--r--lisp/pcomplete.el203
-rw-r--r--lisp/play/5x5.el97
-rw-r--r--lisp/progmodes/compile.el4
-rw-r--r--lisp/progmodes/delphi.el24
-rw-r--r--lisp/progmodes/make-mode.el44
-rw-r--r--lisp/progmodes/meta-mode.el52
-rw-r--r--lisp/progmodes/octave-inf.el23
-rw-r--r--lisp/progmodes/octave-mod.el8
-rw-r--r--lisp/progmodes/pascal.el75
-rw-r--r--lisp/shell.el6
-rw-r--r--lisp/subr.el8
-rw-r--r--lisp/term/ns-win.el5
-rw-r--r--lisp/textmodes/bibtex.el70
-rw-r--r--lisp/textmodes/fill.el1
-rw-r--r--lisp/wid-edit.el103
-rw-r--r--lisp/window.el922
-rw-r--r--lisp/x-dnd.el17
41 files changed, 2083 insertions, 1193 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index d2d44793366..66336413e27 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,323 @@
12011-06-22 Roland Winkler <winkler@gnu.org>
2
3 * textmodes/bibtex.el (bibtex-entry-update): Use mapc.
4 (bibtex-clean-entry): First delete the old key so that a
5 customized algorithm for generating the new key does not get
6 confused by the old key.
7 (bibtex-url): Obey regexp of first step.
8 (bibtex-search-entries): Do not use add-to-list with local
9 list-var.
10
112011-06-22 Lars Magne Ingebrigtsen <larsi@gnus.org>
12
13 * mail/smtpmail.el (smtpmail-try-auth-methods): If the user has
14 stored a user name, then query for the password first, instead of
15 waiting for SMTP to give an error message and the trying again.
16
172011-06-22 Lawrence Mitchell <wence@gmx.li>
18
19 * net/browse-url.el (browse-url-xdg-open): Use 0, rather than nil
20 BUFFER in call-process.
21
222011-06-22 Lars Magne Ingebrigtsen <larsi@gnus.org>
23
24 * mail/smtpmail.el (smtpmail-via-smtp): Make sure we don't send
25 QUIT twice.
26 (smtpmail-try-auth-methods): Require user name and password from
27 auth-source.
28
292011-06-22 Martin Rudalics <rudalics@gmx.at>
30
31 * window.el (display-buffer-default-specifiers)
32 (display-buffer-alist): Remove entries for pop-up-frame-alist.
33 Suggested by Katsumi Yamaoka <yamaoka@jpl.org>.
34 (split-window): Normalize SIDE argument (Bug#8916).
35
36 * frame.el (pop-up-frame-alist, pop-up-frame-function)
37 (special-display-frame-alist, special-display-popup-frame):
38 Remove duplicate declarations. These are now in window.el.
39
402011-06-21 Lars Magne Ingebrigtsen <larsi@gnus.org>
41
42 * mail/smtpmail.el (smtpmail-via-smtp): Set
43 :use-starttls-if-possible so that we always use STARTTLS if the
44 server supports it. SMTP servers that support STARTTLS commonly
45 require it.
46
47 * net/network-stream.el (network-stream-open-starttls): Support
48 upgrading to STARTTLS always, even if we don't have built-in support.
49 (open-network-stream): Add the :always-query-capabilies keyword.
50
51 * mail/smtpmail.el: Rewritten to do opportunistic STARTTLS
52 upgrades with `open-network-stream', and rely solely on
53 auth-source for all credentials. Big changes throughout the file,
54 but in particular:
55 (smtpmail-auth-credentials): Removed.
56 (smtpmail-starttls-credentials): Removed.
57 (smtpmail-via-smtp): Check for servers saying they want AUTH after
58 MAIL FROM, too.
59
60 * net/network-stream.el (network-stream-open-starttls): Provide
61 support for client certificates both for external and built-in
62 STARTTLS.
63 (auth-source): Require.
64 (open-network-stream): Document the :client-certificate keyword.
65 (network-stream-certificate): Change cert-cert to cert and
66 cert-key to key.
67
682011-06-21 Michael Albinus <michael.albinus@gmx.de>
69
70 * net/tramp-cache.el (top): Don't load the persistency file when
71 "emacs -Q" has been called.
72
732011-06-21 Tim Harper <timcharper@gmail.com>
74
75 * term/ns-win.el (ns-initialize-window-system): set
76 application-specific `ApplePressAndHoldEnabled' system
77 resource to NO as it is not yet supported by the NS port.
78
792011-06-21 Juanma Barranquero <lekktu@gmail.com>
80
81 * misc.el (list-dynamic-libraries--refresh): Compute header here...
82 (list-dynamic-libraries): ...not here.
83
842011-06-21 Leo Liu <sdl.web@gmail.com>
85
86 * subr.el (sha1): Implement sha1 using secure-hash.
87
882011-06-21 Martin Rudalics <rudalics@gmx.at>
89
90 * window.el (display-buffer-alist): In default value do not
91 enforce searching a window on any but the selected frame.
92 Reported by Katsumi Yamaoka <yamaoka@jpl.org>.
93 (display-buffer-select-window): Remove function.
94 (display-buffer-in-window): When a window on another frame gets
95 reused, do not select it any more but just raise its frame if
96 necessary (Bug#8851) and (Bug#8856).
97 (display-buffer-normalize-options): Handle pop-up-frames related
98 options more faithfully.
99 (pop-to-buffer): Don't rely on `display-buffer' selecting the
100 window if it is on another frame.
101 (display-buffer-alist, display-buffer-default-specifiers): Don't
102 make new frame unsplittable by default.
103 (display-buffer-normalize-argument): Fix doc-string typo and use
104 'same-frame-other-window instead of 'other-window when associating
105 with display-buffer-macro-specifiers.
106
1072011-06-21 Vincent Belaïche <vincent.b.1@hotmail.fr>
108
109 * play/5x5.el (5x5-solve-rotate-left, 5x5-solve-rotate-right):
110 New functions.
111 (5x5-mode-map, 5x5-mode-menu): Bind them.
112 (5x5-draw-grid): Tweak the solver's rendering.
113
1142011-06-21 Stefan Monnier <monnier@iro.umontreal.ca>
115
116 * progmodes/compile.el (compilation-error-regexp-alist-alist): Rename
117 `caml' to `python-tracebacks-and-caml'; allow leading tabs (bug#8585).
118
1192011-06-21 Drew Adams <drew.adams@oracle.com>
120
121 * menu-bar.el: Use function variable instead of switch-to-buffer.
122 (menu-bar-select-buffer-function): New variable.
123 (menu-bar-update-buffers): Use it (bug#8876).
124
1252011-06-21 Stefan Monnier <monnier@iro.umontreal.ca>
126
127 * emacs-lisp/bytecomp.el (add-to-list): Add handler to check the
128 variable's status.
129
1302011-06-20 Jan Djärv <jan.h.d@swipnet.se>
131
132 * x-dnd.el (x-dnd-version-from-flags)
133 (x-dnd-more-than-3-from-flags): New functions that handle long-as-cons
134 and long as number (Bug#8899).
135 (x-dnd-handle-xdnd): Call functions above (Bug#8899).
136
1372011-06-20 Stefan Monnier <monnier@iro.umontreal.ca>
138
139 * minibuffer.el (completion-metadata): Add `metadata' to the alist.
140 (completion-try-completion, completion-all-completions): Compute the
141 metadata argument if it's missing; make it optional (bug#8795).
142
143 * wid-edit.el: Use lex-bind and move towards completion-at-point.
144 (widget-complete): Use new :completion-function property.
145 (widget-completions-at-point): New function.
146 (default): Use :completion-function instead of :complete.
147 (widget-default-completions): Rename from widget-default-complete;
148 Rewrite.
149 (widget-string-complete, widget-file-complete, widget-color-complete):
150 Remove functions.
151 (file, symbol, function, variable, coding-system, color):
152 * international/mule-cmds.el (default-input-method, charset)
153 (language-info-custom-alist):
154 * cus-edit.el (face): Use new property :completions.
155
156 * progmodes/pascal.el (pascal-completions-at-point): New function.
157 (pascal-mode): Use it.
158 (pascal-mode-map): Use completion-at-point.
159 (pascal-toggle-completions): Make obsolete.
160 (pascal-complete-word, pascal-show-completions):
161 * progmodes/octave-mod.el (octave-complete-symbol):
162 Redefine as obsolete alias.
163 * progmodes/octave-inf.el (inferior-octave-completion-at-point):
164 Signal absence of completion info for old Octave,
165 (inferior-octave-complete): Redefine as obsolete alias.
166 * progmodes/meta-mode.el: Use lexical-binding and completion-at-point.
167 (meta-completions-at-point): Rename from meta-complete-symbol and
168 adapt it for use on completion-at-point-functions.
169 (meta-common-mode): Use it.
170 (meta-looking-at-backward, meta-match-buffer): Remove.
171 (meta-complete-symbol): Redefine as obsolete alias.
172 (meta-common-mode-map): Use completion-at-point.
173 * progmodes/make-mode.el: Use lexical-binding and completion-at-point.
174 (makefile-mode-map): Use completion-at-point.
175 (makefile-completions-at-point): Rename from makefile-complete and
176 adapt it for use on completion-at-point-functions.
177 (makefile-mode): Use it.
178 (makefile-complete): Redefine as obsolete alias.
179
1802011-06-20 Deniz Dogan <deniz@dogan.se>
181
182 * net/rcirc.el: Delete trailing whitespaces once and for all.
183
1842011-06-20 Daniel Colascione <dan.colascione@gmail.com>
185
186 * emacs-lisp/syntax.el (syntax-ppss): Further improve docstring.
187
1882011-06-19 Chong Yidong <cyd@stupidchicken.com>
189
190 * files.el (auto-mode-alist): Entry for m2-mode (Bug#8852).
191
192 * info.el (Info-apropos-toc-nodes): Minor doc fix (Bug#8833).
193
1942011-06-19 Martin Rudalics <rudalics@gmx.at>
195
196 * window.el (display-buffer-other-window-means-other-frame):
197 Call display-buffer-normalize-alist.
198 (display-buffer-normalize-specifiers-1): Rename to
199 display-buffer-normalize-argument. New argument other-frame.
200 Rewrite.
201 (display-buffer-normalize-specifiers-2): Rename to
202 display-buffer-normalize-options.
203 (display-buffer-normalize-alist-1): New function.
204 (display-buffer-normalize-specifiers-3): Rename to
205 display-buffer-normalize-alist.
206 Call display-buffer-normalize-alist-1.
207 (display-buffer-normalize-options-inhibit): New variable.
208 (display-buffer-normalize-specifiers): Rewrite calling
209 display-buffer-normalize-alist,
210 display-buffer-normalize-argument, and
211 display-buffer-normalize-options. Don't call the latter if
212 display-buffer-normalize-options-inhibit is non-nil.
213 (frame-auto-delete): New option.
214 (window-deletable-p): Use frame-auto-delete.
215 (window-list-no-nils, window-state-ignored-parameters)
216 (window-state-get-1, window-state-get, window-state-put-list)
217 (window-state-put-1, window-state-put-2, window-state-put):
218 New functions.
219 (display-buffer-normalize-options): Move special-display-p group
220 after pop-up-frame group (Bug#8851) and (Bug#8856).
221
2222011-06-18 Chong Yidong <cyd@stupidchicken.com>
223
224 * emacs-lisp/rx.el (rx-constituents): Add support for numbered
225 groups (Bug#8776).
226 (rx-submatch-n): New function.
227 (rx): Document it.
228
229 * dired-x.el (dired-mark-unmarked-files): Fix interactive spec
230 (Bug#8768).
231
232 * replace.el (occur-mode-map): Set occur-edit-mode binding to "e".
233
234 * textmodes/fill.el (default-justification): Add :safe (Bug#8879).
235
236 * cus-face.el (custom-declare-face): Call custom-theme-recalc face
237 anytime existing face settings are present (Bug#8889).
238
239 * progmodes/delphi.el (delphi-mode-syntax-table): Use defvar.
240 (delphi-mode): Use define-derived-mode to inherit from prog-mode.
241 Remove unused argument.
242
2432011-06-18 Martin Rudalics <rudalics@gmx.at>
244
245 * window.el (display-buffer-default-specifiers):
246 Remove pop-up-frame. Add pop-up-window-min-height,
247 pop-up-window-min-width, and another reuse-window specifier
248 (Bug#8882). Reported by Dan Nicolaescu <dann@gnu.org>.
249 (display-buffer-normalize-specifiers-2):
250 Handle split-height-threshold and split-width-threshold also when
251 pop-up-windows is unset. Add a reuse-window specifier for the
252 case popping up a new window fails.
253 (special-display-popup-frame): Remove double quoting.
254 (display-buffer-normalize-specifiers-1): Fix thinko.
255
2562011-06-17 Stefan Monnier <monnier@iro.umontreal.ca>
257
258 * shell.el (shell-completion-vars): Set pcomplete-termination-string
259 according to comint-completion-addsuffix.
260
261 * pcomplete.el: Convert to lexical binding and fix bug#8819.
262 (pcomplete-suffix-list): Mark as obsolete.
263 (pcomplete-completions-at-point): Capture pcomplete-norm-func and
264 pcomplete-seen in the closure.
265 (pcomplete-comint-setup): Setup completion-at-point as well.
266 (pcomplete--entries): New function.
267 (pcomplete--env-regexp): New var.
268 (pcomplete-entries): Rewrite to work with partial-completion and
269 without relying on pcomplete-suffix-list.
270 (pcomplete-pare-list): Remove, unused.
271
2722011-06-17 Martin Rudalics <rudalics@gmx.at>
273
274 * window.el (display-buffer-alist): Set pop-up-window-min-height
275 and pop-up-window-min-width in default value. Reported by
276 Thierry Volpiatto <thierry.volpiatto@gmail.com>. New specifier
277 other-window-means-other-frame.
278 (display-buffer-macro-specifiers): Comment out entry for
279 other-window specifier.
280 (display-buffer-other-window-means-other-frame): New function.
281 (display-buffer-normalize-specifiers-1): New arguments
282 buffer-name and label. Treat other-window case specially.
283 (display-buffer-normalize-specifiers-2): Treat other-window case
284 specially.
285 (display-buffer-normalize-specifiers-3): New function.
286 (display-buffer-normalize-specifiers):
287 Call display-buffer-normalize-specifiers-3.
288
2892011-06-17 Martin Rudalics <rudalics@gmx.at>
290
291 * window.el (same-window-p): Fix two typos introduced when
292 adding with-no-warnings.
293 (display-buffer-normalize-specifiers-1): Don't check
294 pop-up-frames for 'unset initialization.
295 (display-buffer-normalize-specifiers-2): Major rewrite using
296 special-display-p and same-window-p (Bug#8851) and (Bug#8856).
297 (pop-up-frames, display-buffer-reuse-frames)
298 (display-buffer-mark-dedicated): Don't initialize to 'unset.
299 Suggested by David Engster <deng@randomsample.de>.
300 (even-window-heights): Initialize to 'unset.
301 (display-buffer-alist-set): Handle new 'unset initializations.
302 (display-buffer-macro-specifiers): Don't pop up a new frame in the
303 other window case.
304
3052011-06-16 Martin Rudalics <rudalics@gmx.at>
306
307 * window.el (display-buffer-normalize-specifiers-1):
308 Respect current value of pop-up-frames for most reasonable values of
309 second argument of display-buffer (Bug#8865).
310 (switch-to-buffer-same-frame, switch-to-buffer-other-window)
311 (switch-to-buffer-other-window-same-frame)
312 (switch-to-buffer-other-frame): Fix doc-strings. Reported by Drew
313 Adams (Bug#8875).
314 (display-buffer): Don't check noninteractive when calling
315 display-buffer-pop-up-frame.
316 (display-buffer-pop-up-frame): Never pop up a frame in
317 noninteractive mode (Bug#8857).
318 (enlarge-window, shrink-window): Don't report an error when the
319 window can't be resized as requested (Bug#8862).
320
12011-06-15 Stefan Monnier <monnier@iro.umontreal.ca> 3212011-06-15 Stefan Monnier <monnier@iro.umontreal.ca>
2 322
3 * pcmpl-rpm.el (pcomplete/rpm): Minor simplification. 323 * pcmpl-rpm.el (pcomplete/rpm): Minor simplification.
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index f14c055d7a8..7c96b526f41 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -3830,9 +3830,8 @@ restoring it to the state of a face that has never been customized."
3830 :sample-face-get 'widget-face-sample-face-get 3830 :sample-face-get 'widget-face-sample-face-get
3831 :notify 'widget-face-notify 3831 :notify 'widget-face-notify
3832 :match (lambda (_widget value) (facep value)) 3832 :match (lambda (_widget value) (facep value))
3833 :complete-function (lambda () 3833 :completions (apply-partially #'completion-table-with-predicate
3834 (interactive) 3834 obarray #'facep 'strict)
3835 (lisp-complete-symbol 'facep))
3836 :prompt-match 'facep 3835 :prompt-match 'facep
3837 :prompt-history 'widget-face-prompt-value-history 3836 :prompt-history 'widget-face-prompt-value-history
3838 :validate (lambda (widget) 3837 :validate (lambda (widget)
diff --git a/lisp/cus-face.el b/lisp/cus-face.el
index 90f21f32149..c23632ab885 100644
--- a/lisp/cus-face.el
+++ b/lisp/cus-face.el
@@ -34,30 +34,33 @@
34(defun custom-declare-face (face spec doc &rest args) 34(defun custom-declare-face (face spec doc &rest args)
35 "Like `defface', but FACE is evaluated as a normal argument." 35 "Like `defface', but FACE is evaluated as a normal argument."
36 (unless (get face 'face-defface-spec) 36 (unless (get face 'face-defface-spec)
37 (unless (facep face) 37 (let ((facep (facep face)))
38 ;; If the user has already created the face, respect that. 38 (unless facep
39 (let ((value (or (get face 'saved-face) spec)) 39 ;; If the user has already created the face, respect that.
40 (have-window-system (memq initial-window-system '(x w32)))) 40 (let ((value (or (get face 'saved-face) spec))
41 ;; Create global face. 41 (have-window-system (memq initial-window-system '(x w32))))
42 (make-empty-face face) 42 ;; Create global face.
43 ;; Create frame-local faces 43 (make-empty-face face)
44 (dolist (frame (frame-list)) 44 ;; Create frame-local faces
45 (face-spec-set-2 face frame value) 45 (dolist (frame (frame-list))
46 (when (memq (window-system frame) '(x w32 ns)) 46 (face-spec-set-2 face frame value)
47 (setq have-window-system t))) 47 (when (memq (window-system frame) '(x w32 ns))
48 ;; When making a face after frames already exist 48 (setq have-window-system t)))
49 (if have-window-system 49 ;; When making a face after frames already exist
50 (make-face-x-resource-internal face)))) 50 (if have-window-system
51 ;; Don't record SPEC until we see it causes no errors. 51 (make-face-x-resource-internal face))))
52 (put face 'face-defface-spec (purecopy spec)) 52 ;; Don't record SPEC until we see it causes no errors.
53 (push (cons 'defface face) current-load-list) 53 (put face 'face-defface-spec (purecopy spec))
54 (when (and doc (null (face-documentation face))) 54 (push (cons 'defface face) current-load-list)
55 (set-face-documentation face (purecopy doc))) 55 (when (and doc (null (face-documentation face)))
56 (custom-handle-all-keywords face args 'custom-face) 56 (set-face-documentation face (purecopy doc)))
57 (run-hooks 'custom-define-hook) 57 (custom-handle-all-keywords face args 'custom-face)
58 ;; If the face has an existing theme setting, recalculate it. 58 (run-hooks 'custom-define-hook)
59 (if (get face 'theme-face) 59 ;; If the face had existing settings, recalculate it. For
60 (custom-theme-recalc-face face))) 60 ;; example, the user might load a theme with a face setting, and
61 ;; later load a library defining that face.
62 (if facep
63 (custom-theme-recalc-face face))))
61 face) 64 face)
62 65
63;;; Face attributes. 66;;; Face attributes.
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 548728cf28d..ca89d07ea7f 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -546,11 +546,14 @@ This functions works by temporarily binding `dired-marker-char' to
546;; Returns t if any work was done, nil otherwise. 546;; Returns t if any work was done, nil otherwise.
547(defun dired-mark-unmarked-files (regexp msg &optional unflag-p localp) 547(defun dired-mark-unmarked-files (regexp msg &optional unflag-p localp)
548 "Mark unmarked files matching REGEXP, displaying MSG. 548 "Mark unmarked files matching REGEXP, displaying MSG.
549REGEXP is matched against the entire file name. 549REGEXP is matched against the entire file name. When called
550Does not re-mark files which already have a mark. 550interactively, prompt for REGEXP.
551With prefix argument, unflag all those files. 551With prefix argument, unflag all those files.
552Optional fourth argument LOCALP is as in `dired-get-filename'." 552Optional fourth argument LOCALP is as in `dired-get-filename'."
553 (interactive "P") 553 (interactive
554 (list (dired-read-regexp
555 "Mark unmarked files matching regexp (default all): ")
556 nil current-prefix-arg nil))
554 (let ((dired-marker-char (if unflag-p ?\s dired-marker-char))) 557 (let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
555 (dired-mark-if 558 (dired-mark-if
556 (and 559 (and
diff --git a/lisp/dired.el b/lisp/dired.el
index 48cdc2a2e26..43b2170d13a 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -4089,7 +4089,7 @@ true then the type of the file linked to by FILE is printed instead.
4089;;;*** 4089;;;***
4090 4090
4091;;;### (autoloads (dired-do-relsymlink dired-jump-other-window dired-jump) 4091;;;### (autoloads (dired-do-relsymlink dired-jump-other-window dired-jump)
4092;;;;;; "dired-x" "dired-x.el" "94bd5ca0bd260e43402e3cd9f114970c") 4092;;;;;; "dired-x" "dired-x.el" "cdeb2935dc1d33819b12981ba5272073")
4093;;; Generated autoloads from dired-x.el 4093;;; Generated autoloads from dired-x.el
4094 4094
4095(autoload 'dired-jump "dired-x" "\ 4095(autoload 'dired-jump "dired-x" "\
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 1e7ee315942..127f93c6858 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -4244,6 +4244,25 @@ binding slots have been popped."
4244(defun byte-compile-form-make-variable-buffer-local (form) 4244(defun byte-compile-form-make-variable-buffer-local (form)
4245 (byte-compile-keep-pending form 'byte-compile-normal-call)) 4245 (byte-compile-keep-pending form 'byte-compile-normal-call))
4246 4246
4247(byte-defop-compiler-1 add-to-list byte-compile-add-to-list)
4248(defun byte-compile-add-to-list (form)
4249 ;; FIXME: This could be used for `set' as well, except that it's got
4250 ;; its own opcode, so the final `byte-compile-normal-call' needs to
4251 ;; be replaced with something else.
4252 (pcase form
4253 (`(,fun ',var . ,_)
4254 (byte-compile-check-variable var 'assign)
4255 (if (assq var byte-compile--lexical-environment)
4256 (byte-compile-log-warning
4257 (format "%s cannot use lexical var `%s'" fun var)
4258 nil :error)
4259 (unless (or (not (byte-compile-warning-enabled-p 'free-vars))
4260 (boundp var)
4261 (memq var byte-compile-bound-variables)
4262 (memq var byte-compile-free-references))
4263 (byte-compile-warn "assignment to free variable `%S'" var)
4264 (push var byte-compile-free-references)))))
4265 (byte-compile-normal-call form))
4247 4266
4248;;; tags 4267;;; tags
4249 4268
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 7122de4789c..56efd142198 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -130,6 +130,8 @@
130 (** . (rx-** 2 nil)) ; SRE 130 (** . (rx-** 2 nil)) ; SRE
131 (submatch . (rx-submatch 1 nil)) ; SRE 131 (submatch . (rx-submatch 1 nil)) ; SRE
132 (group . submatch) ; sregex 132 (group . submatch) ; sregex
133 (submatch-n . (rx-submatch-n 2 nil))
134 (group-n . submatch-n)
133 (zero-or-more . (rx-kleene 1 nil)) 135 (zero-or-more . (rx-kleene 1 nil))
134 (one-or-more . (rx-kleene 1 nil)) 136 (one-or-more . (rx-kleene 1 nil))
135 (zero-or-one . (rx-kleene 1 nil)) 137 (zero-or-one . (rx-kleene 1 nil))
@@ -690,6 +692,16 @@ FORM is either `(repeat N FORM1)' or `(repeat N M FORMS...)'."
690 (mapconcat (lambda (re) (rx-form re ':)) (cdr form) nil)) 692 (mapconcat (lambda (re) (rx-form re ':)) (cdr form) nil))
691 "\\)")) 693 "\\)"))
692 694
695(defun rx-submatch-n (form)
696 "Parse and produce code from FORM, which is `(submatch-n N ...)'."
697 (let ((n (nth 1 form)))
698 (concat "\\(?" (number-to-string n) ":"
699 (if (= 3 (length form))
700 ;; Only one sub-form.
701 (rx-form (nth 2 form))
702 ;; Several sub-forms implicitly concatenated.
703 (mapconcat (lambda (re) (rx-form re ':)) (cddr form) nil))
704 "\\)")))
693 705
694(defun rx-backref (form) 706(defun rx-backref (form)
695 "Parse and produce code from FORM, which is `(backref N)'." 707 "Parse and produce code from FORM, which is `(backref N)'."
@@ -1072,6 +1084,11 @@ CHAR
1072 like `and', but makes the match accessible with `match-end', 1084 like `and', but makes the match accessible with `match-end',
1073 `match-beginning', and `match-string'. 1085 `match-beginning', and `match-string'.
1074 1086
1087`(submatch-n N SEXP1 SEXP2 ...)'
1088`(group-n N SEXP1 SEXP2 ...)'
1089 like `group', but make it an explicitly-numbered group with
1090 group number N.
1091
1075`(or SEXP1 SEXP2 ...)' 1092`(or SEXP1 SEXP2 ...)'
1076`(| SEXP1 SEXP2 ...)' 1093`(| SEXP1 SEXP2 ...)'
1077 matches anything that matches SEXP1 or SEXP2, etc. If all 1094 matches anything that matches SEXP1 or SEXP2, etc. If all
diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el
index 7ba7b13af44..200b3a6389b 100644
--- a/lisp/emacs-lisp/syntax.el
+++ b/lisp/emacs-lisp/syntax.el
@@ -398,8 +398,9 @@ point (where the PPSS is equivalent to nil).")
398 398
399(defun syntax-ppss (&optional pos) 399(defun syntax-ppss (&optional pos)
400 "Parse-Partial-Sexp State at POS, defaulting to point. 400 "Parse-Partial-Sexp State at POS, defaulting to point.
401The returned value is the same as `parse-partial-sexp' except that 401The returned value is the same as that of `parse-partial-sexp'
402values 2 and 6 values of the returned state cannot be relied upon. 402run from point-min to POS except that values at positions 2 and 6
403in the returned list (counting from 0) cannot be relied upon.
403Point is at POS when this function returns." 404Point is at POS when this function returns."
404 ;; Default values. 405 ;; Default values.
405 (unless pos (setq pos (point))) 406 (unless pos (setq pos (point)))
diff --git a/lisp/files.el b/lisp/files.el
index aafc6f92906..7b97b730111 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2333,6 +2333,7 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'" . archive-mode)
2333 ("\\.ebrowse\\'" . ebrowse-tree-mode) 2333 ("\\.ebrowse\\'" . ebrowse-tree-mode)
2334 ("#\\*mail\\*" . mail-mode) 2334 ("#\\*mail\\*" . mail-mode)
2335 ("\\.g\\'" . antlr-mode) 2335 ("\\.g\\'" . antlr-mode)
2336 ("\\.mod\\'" . m2-mode)
2336 ("\\.ses\\'" . ses-mode) 2337 ("\\.ses\\'" . ses-mode)
2337 ("\\.docbook\\'" . sgml-mode) 2338 ("\\.docbook\\'" . sgml-mode)
2338 ("\\.com\\'" . dcl-mode) 2339 ("\\.com\\'" . dcl-mode)
diff --git a/lisp/frame.el b/lisp/frame.el
index a95e91c8eeb..3ceec2657e7 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -95,96 +95,6 @@ appended when the minibuffer frame is created."
95 (sexp :tag "Value"))) 95 (sexp :tag "Value")))
96 :group 'frames) 96 :group 'frames)
97 97
98(defcustom pop-up-frame-alist nil
99 "Alist of parameters for automatically generated new frames.
100You can set this in your init file; for example,
101
102 (setq pop-up-frame-alist '((width . 80) (height . 20)))
103
104If non-nil, the value you specify here is used by the default
105`pop-up-frame-function' for the creation of new frames.
106
107Since `pop-up-frame-function' is used by `display-buffer' for
108making new frames, any value specified here by default affects
109the automatic generation of new frames via `display-buffer' and
110all functions based on it. The behavior of `make-frame' is not
111affected by this variable."
112 :type '(repeat (cons :format "%v"
113 (symbol :tag "Parameter")
114 (sexp :tag "Value")))
115 :group 'frames)
116
117(defcustom pop-up-frame-function
118 (lambda () (make-frame pop-up-frame-alist))
119 "Function used by `display-buffer' for creating a new frame.
120This function is called with no arguments and should return a new
121frame. The default value calls `make-frame' with the argument
122`pop-up-frame-alist'."
123 :type 'function
124 :group 'frames)
125
126(defcustom special-display-frame-alist
127 '((height . 14) (width . 80) (unsplittable . t))
128 "Alist of parameters for special frames.
129Special frames are used for buffers whose names are listed in
130`special-display-buffer-names' and for buffers whose names match
131one of the regular expressions in `special-display-regexps'.
132
133This variable can be set in your init file, like this:
134
135 (setq special-display-frame-alist '((width . 80) (height . 20)))
136
137These supersede the values given in `default-frame-alist'."
138 :type '(repeat (cons :format "%v"
139 (symbol :tag "Parameter")
140 (sexp :tag "Value")))
141 :group 'frames)
142
143(defun special-display-popup-frame (buffer &optional args)
144 "Display BUFFER and return the window chosen.
145If BUFFER is already displayed in a visible or iconified frame,
146raise that frame. Otherwise, display BUFFER in a new frame.
147
148Optional argument ARGS is a list specifying additional
149information.
150
151If ARGS is an alist, use it as a list of frame parameters. If
152these parameters contain \(same-window . t), display BUFFER in
153the selected window. If they contain \(same-frame . t), display
154BUFFER in a window of the selected frame.
155
156If ARGS is a list whose car is a symbol, use (car ARGS) as a
157function to do the work. Pass it BUFFER as first argument,
158and (cdr ARGS) as second."
159 (if (and args (symbolp (car args)))
160 (apply (car args) buffer (cdr args))
161 (let ((window (get-buffer-window buffer 0)))
162 (or
163 ;; If we have a window already, make it visible.
164 (when window
165 (let ((frame (window-frame window)))
166 (make-frame-visible frame)
167 (raise-frame frame)
168 window))
169 ;; Reuse the current window if the user requested it.
170 (when (cdr (assq 'same-window args))
171 (condition-case nil
172 (progn (switch-to-buffer buffer) (selected-window))
173 (error nil)))
174 ;; Stay on the same frame if requested.
175 (when (or (cdr (assq 'same-frame args)) (cdr (assq 'same-window args)))
176 (let* ((pop-up-windows t)
177 pop-up-frames
178 special-display-buffer-names special-display-regexps)
179 (display-buffer buffer)))
180 ;; If no window yet, make one in a new frame.
181 (let ((frame
182 (with-current-buffer buffer
183 (make-frame (append args special-display-frame-alist)))))
184 (set-window-buffer (frame-selected-window frame) buffer)
185 (set-window-dedicated-p (frame-selected-window frame) t)
186 (frame-selected-window frame))))))
187
188(defun handle-delete-frame (event) 98(defun handle-delete-frame (event)
189 "Handle delete-frame events from the X server." 99 "Handle delete-frame events from the X server."
190 (interactive "e") 100 (interactive "e")
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 2bfaf32f958..5a6ad584438 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,38 @@
12011-06-21 Lars Magne Ingebrigtsen <larsi@gnus.org>
2
3 * auth-source.el (auth-source-netrc-create): Don't print all tokens in
4 %S format, since that looks odd.
5 (auth-sources): Prefer the ~/.authinfo file over the ~/.authinfo.gpg
6 file, especially when saving.
7
82011-06-21 Andrew Cohen <cohen@andy.bu.edu>
9
10 * nnimap.el (nnimap-find-article-by-message-id): return nil when no
11 article found.
12
132011-06-18 Teodor Zlatanov <tzz@lifelogs.com>
14
15 * auth-source.el (auth-source-netrc-use-gpg-tokens): Replace
16 `auth-source-save-secrets' with a more sensitive alist that can be
17 configured per file. Experimental, so defaults to 'never.
18 (auth-source-netrc-create): Use it. Still experimental code.
19 (with-auth-source-epa-overrides): Use `find-file-hooks' if
20 `find-file-hook' is unbound (XEmacs fix). Fix backquoting bug.
21
222011-06-16 Teodor Zlatanov <tzz@lifelogs.com>
23
24 * auth-source.el (auth-source-save-secrets): New variable to control if
25 secret tokens should be saved encrypted.
26 (auth-source-netrc-parse, auth-source-netrc-search): Pass the file name
27 to `auth-source-netrc-normalize'.
28 (with-auth-source-epa-overrides): Add convenience macro. Don't depend
29 on the EPA variables being defined.
30 (auth-source-epa-make-gpg-token): Convert text to a "gpg:" token.
31 (auth-source-netrc-normalize): Convert "gpg:" tokens back to text in
32 the lexical-let closure.
33 (auth-source-netrc-create): Create "gpg:" tokens according to
34 `auth-source-save-secrets'.
35
12011-06-10 Katsumi Yamaoka <yamaoka@jpl.org> 362011-06-10 Katsumi Yamaoka <yamaoka@jpl.org>
2 37
3 * gnus-group.el (gnus-group-update-group): Add new argument 38 * gnus-group.el (gnus-group-update-group): Add new argument
diff --git a/lisp/gnus/auth-source.el b/lisp/gnus/auth-source.el
index e0bea324a25..6fe033fea79 100644
--- a/lisp/gnus/auth-source.el
+++ b/lisp/gnus/auth-source.el
@@ -154,6 +154,31 @@ let-binding."
154 (const :tag "Never save" nil) 154 (const :tag "Never save" nil)
155 (const :tag "Ask" ask))) 155 (const :tag "Ask" ask)))
156 156
157;; TODO: make the default (setq auth-source-netrc-use-gpg-tokens `((,(if (boundp 'epa-file-auto-mode-alist-entry) (car (symbol-value 'epa-file-auto-mode-alist-entry)) "\\.gpg\\'") never) (t gpg)))
158;; TODO: or maybe leave as (setq auth-source-netrc-use-gpg-tokens 'never)
159
160(defcustom auth-source-netrc-use-gpg-tokens 'never
161 "Set this to tell auth-source when to create GPG password
162tokens in netrc files. It's either an alist or `never'."
163 :group 'auth-source
164 :version "23.2" ;; No Gnus
165 :type `(choice
166 (const :tag "Always use GPG password tokens" (t gpg))
167 (const :tag "Never use GPG password tokens" never)
168 (repeat :tag "Use a lookup list"
169 (list
170 (choice :tag "Matcher"
171 (const :tag "Match anything" t)
172 (const :tag "The EPA encrypted file extensions"
173 ,(if (boundp 'epa-file-auto-mode-alist-entry)
174 (car (symbol-value
175 'epa-file-auto-mode-alist-entry))
176 "\\.gpg\\'"))
177 (regexp :tag "Regular expression"))
178 (choice :tag "What to do"
179 (const :tag "Save GPG-encrypted password tokens" gpg)
180 (const :tag "Don't encrypt tokens" never))))))
181
157(defvar auth-source-magic "auth-source-magic ") 182(defvar auth-source-magic "auth-source-magic ")
158 183
159(defcustom auth-source-do-cache t 184(defcustom auth-source-do-cache t
@@ -183,7 +208,7 @@ If the value is a function, debug messages are logged by calling
183 (function :tag "Function that takes arguments like `message'") 208 (function :tag "Function that takes arguments like `message'")
184 (const :tag "Don't log anything" nil))) 209 (const :tag "Don't log anything" nil)))
185 210
186(defcustom auth-sources '("~/.authinfo.gpg" "~/.authinfo" "~/.netrc") 211(defcustom auth-sources '("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")
187 "List of authentication sources. 212 "List of authentication sources.
188 213
189The default will get login and password information from 214The default will get login and password information from
@@ -237,9 +262,11 @@ can get pretty complex."
237 ,@auth-source-protocols-customize)) 262 ,@auth-source-protocols-customize))
238 (list :tag "User" :inline t 263 (list :tag "User" :inline t
239 (const :format "" :value :user) 264 (const :format "" :value :user)
240 (choice :tag "Personality/Username" 265 (choice
266 :tag "Personality/Username"
241 (const :tag "Any" t) 267 (const :tag "Any" t)
242 (string :tag "Name"))))))))) 268 (string
269 :tag "Name")))))))))
243 270
244(defcustom auth-source-gpg-encrypt-to t 271(defcustom auth-source-gpg-encrypt-to t
245 "List of recipient keys that `authinfo.gpg' encrypted to. 272 "List of recipient keys that `authinfo.gpg' encrypted to.
@@ -686,7 +713,8 @@ Returns the deleted entries."
686 when (string-match (concat "^" auth-source-magic) 713 when (string-match (concat "^" auth-source-magic)
687 (symbol-name sym)) 714 (symbol-name sym))
688 ;; remove that key 715 ;; remove that key
689 do (password-cache-remove (symbol-name sym)))) 716 do (password-cache-remove (symbol-name sym)))
717 (setq auth-source-netrc-cache nil))
690 718
691(defun auth-source-remember (spec found) 719(defun auth-source-remember (spec found)
692 "Remember FOUND search results for SPEC." 720 "Remember FOUND search results for SPEC."
@@ -898,7 +926,7 @@ Note that the MAX parameter is used so we can exit the parse early."
898 (null require) 926 (null require)
899 ;; every element of require is in the normalized list 927 ;; every element of require is in the normalized list
900 (let ((normalized (nth 0 (auth-source-netrc-normalize 928 (let ((normalized (nth 0 (auth-source-netrc-normalize
901 (list alist))))) 929 (list alist) file))))
902 (loop for req in require 930 (loop for req in require
903 always (plist-get normalized req))))) 931 always (plist-get normalized req)))))
904 (decf max) 932 (decf max)
@@ -934,7 +962,56 @@ Note that the MAX parameter is used so we can exit the parse early."
934 962
935 (nreverse result)))))) 963 (nreverse result))))))
936 964
937(defun auth-source-netrc-normalize (alist) 965(defmacro with-auth-source-epa-overrides (&rest body)
966 `(let ((file-name-handler-alist
967 ',(if (boundp 'epa-file-handler)
968 (remove (symbol-value 'epa-file-handler)
969 file-name-handler-alist)
970 file-name-handler-alist))
971 (,(if (boundp 'find-file-hook) 'find-file-hook 'find-file-hooks)
972 ',(remove
973 'epa-file-find-file-hook
974 (if (boundp 'find-file-hook) 'find-file-hook 'find-file-hooks)))
975 (auto-mode-alist
976 ',(if (boundp 'epa-file-auto-mode-alist-entry)
977 (remove (symbol-value 'epa-file-auto-mode-alist-entry)
978 auto-mode-alist)
979 auto-mode-alist)))
980 ,@body))
981
982(defun auth-source-epa-make-gpg-token (secret file)
983 (require 'epa nil t)
984 (unless (featurep 'epa)
985 (error "EPA could not be loaded."))
986 (let* ((base (file-name-sans-extension file))
987 (passkey (format "gpg:-%s" base))
988 (stash (concat base ".gpg"))
989 ;; temporarily disable EPA
990 (stashfile
991 (with-auth-source-epa-overrides
992 (make-temp-file "gpg-token" nil
993 stash)))
994 (epa-file-passphrase-alist
995 `((,stashfile
996 . ,(password-read
997 (format
998 "token pass for %s? "
999 file)
1000 passkey)))))
1001 (write-region secret nil stashfile)
1002 ;; temporarily disable EPA
1003 (unwind-protect
1004 (with-auth-source-epa-overrides
1005 (with-temp-buffer
1006 (insert-file-contents stashfile)
1007 (base64-encode-region (point-min) (point-max) t)
1008 (concat "gpg:"
1009 (buffer-substring-no-properties
1010 (point-min)
1011 (point-max)))))
1012 (delete-file stashfile))))
1013
1014(defun auth-source-netrc-normalize (alist filename)
938 (mapcar (lambda (entry) 1015 (mapcar (lambda (entry)
939 (let (ret item) 1016 (let (ret item)
940 (while (setq item (pop entry)) 1017 (while (setq item (pop entry))
@@ -950,15 +1027,65 @@ Note that the MAX parameter is used so we can exit the parse early."
950 1027
951 ;; send back the secret in a function (lexical binding) 1028 ;; send back the secret in a function (lexical binding)
952 (when (equal k "secret") 1029 (when (equal k "secret")
953 (setq v (lexical-let ((v v)) 1030 (setq v (lexical-let ((v v)
954 (lambda () v)))) 1031 (filename filename)
955 1032 (base (file-name-nondirectory
956 (setq ret (plist-put ret 1033 filename))
957 (intern (concat ":" k)) 1034 (token-decoder nil)
958 v)) 1035 (gpgdata nil)
959 )) 1036 (stash nil))
960 ret)) 1037 (setq stash (concat base ".gpg"))
961 alist)) 1038 (when (string-match "gpg:\\(.+\\)" v)
1039 (require 'epa nil t)
1040 (unless (featurep 'epa)
1041 (error "EPA could not be loaded."))
1042 (setq gpgdata (base64-decode-string
1043 (match-string 1 v)))
1044 ;; it's a GPG token
1045 (setq
1046 token-decoder
1047 (lambda (gpgdata)
1048;;; FIXME: this relies on .gpg files being handled by EPA/EPG
1049 (let* ((passkey (format "gpg:-%s" base))
1050 ;; temporarily disable EPA
1051 (stashfile
1052 (with-auth-source-epa-overrides
1053 (make-temp-file "gpg-token" nil
1054 stash)))
1055 (epa-file-passphrase-alist
1056 `((,stashfile
1057 . ,(password-read
1058 (format
1059 "token pass for %s? "
1060 filename)
1061 passkey)))))
1062 (unwind-protect
1063 (progn
1064 ;; temporarily disable EPA
1065 (with-auth-source-epa-overrides
1066 (write-region gpgdata
1067 nil
1068 stashfile))
1069 (setq
1070 v
1071 (with-temp-buffer
1072 (insert-file-contents stashfile)
1073 (buffer-substring-no-properties
1074 (point-min)
1075 (point-max)))))
1076 (delete-file stashfile)))
1077 ;; clear out the decoder at end
1078 (setq token-decoder nil
1079 gpgdata nil))))
1080 (lambda ()
1081 (when token-decoder
1082 (funcall token-decoder gpgdata))
1083 v))))
1084 (setq ret (plist-put ret
1085 (intern (concat ":" k))
1086 v))))
1087 ret))
1088 alist))
962 1089
963;;; (setq secret (plist-get (nth 0 (auth-source-search :host t :type 'netrc :K 1 :max 1)) :secret)) 1090;;; (setq secret (plist-get (nth 0 (auth-source-search :host t :type 'netrc :K 1 :max 1)) :secret))
964;;; (funcall secret) 1091;;; (funcall secret)
@@ -982,7 +1109,8 @@ See `auth-source-search' for details on SPEC."
982 :file (oref backend source) 1109 :file (oref backend source)
983 :host (or host t) 1110 :host (or host t)
984 :user (or user t) 1111 :user (or user t)
985 :port (or port t))))) 1112 :port (or port t))
1113 (oref backend source))))
986 1114
987 ;; if we need to create an entry AND none were found to match 1115 ;; if we need to create an entry AND none were found to match
988 (when (and create 1116 (when (and create
@@ -1017,6 +1145,9 @@ See `auth-source-search' for details on SPEC."
1017 ;; we know (because of an assertion in auth-source-search) that the 1145 ;; we know (because of an assertion in auth-source-search) that the
1018 ;; :create parameter is either t or a list (which includes nil) 1146 ;; :create parameter is either t or a list (which includes nil)
1019 (create-extra (if (eq t create) nil create)) 1147 (create-extra (if (eq t create) nil create))
1148 (current-data (car (auth-source-search :max 1
1149 :host host
1150 :port port)))
1020 (required (append base-required create-extra)) 1151 (required (append base-required create-extra))
1021 (file (oref backend source)) 1152 (file (oref backend source))
1022 (add "") 1153 (add "")
@@ -1051,7 +1182,9 @@ See `auth-source-search' for details on SPEC."
1051 (dolist (r required) 1182 (dolist (r required)
1052 (let* ((data (aget valist r)) 1183 (let* ((data (aget valist r))
1053 ;; take the first element if the data is a list 1184 ;; take the first element if the data is a list
1054 (data (auth-source-netrc-element-or-first data)) 1185 (data (or (auth-source-netrc-element-or-first data)
1186 (plist-get current-data
1187 (intern (format ":%s" r) obarray))))
1055 ;; this is the default to be offered 1188 ;; this is the default to be offered
1056 (given-default (aget auth-source-creation-defaults r)) 1189 (given-default (aget auth-source-creation-defaults r))
1057 ;; the default supplementals are simple: 1190 ;; the default supplementals are simple:
@@ -1098,7 +1231,36 @@ See `auth-source-search' for details on SPEC."
1098 (cond 1231 (cond
1099 ((and (null data) (eq r 'secret)) 1232 ((and (null data) (eq r 'secret))
1100 ;; Special case prompt for passwords. 1233 ;; Special case prompt for passwords.
1101 (read-passwd prompt)) 1234;; TODO: make the default (setq auth-source-netrc-use-gpg-tokens `((,(if (boundp 'epa-file-auto-mode-alist-entry) (car (symbol-value 'epa-file-auto-mode-alist-entry)) "\\.gpg\\'") nil) (t gpg)))
1235;; TODO: or maybe leave as (setq auth-source-netrc-use-gpg-tokens 'never)
1236 (let* ((ep (format "Use GPG password tokens in %s?" file))
1237 (gpg-encrypt
1238 (cond
1239 ((eq auth-source-netrc-use-gpg-tokens 'never)
1240 'never)
1241 ((listp auth-source-netrc-use-gpg-tokens)
1242 (let ((check (copy-sequence
1243 auth-source-netrc-use-gpg-tokens))
1244 item ret)
1245 (while check
1246 (setq item (pop check))
1247 (when (or (eq (car item) t)
1248 (string-match (car item) file))
1249 (setq ret (cdr item))
1250 (setq check nil)))))
1251 (t 'never)))
1252 (plain (read-passwd prompt)))
1253 ;; ask if we don't know what to do (in which case
1254 ;; auth-source-netrc-use-gpg-tokens must be a list)
1255 (unless gpg-encrypt
1256 (setq gpg-encrypt (if (y-or-n-p ep) 'gpg 'never))
1257 ;; TODO: save the defcustom now? or ask?
1258 (setq auth-source-netrc-use-gpg-tokens
1259 (cons `(,file ,gpg-encrypt)
1260 auth-source-netrc-use-gpg-tokens)))
1261 (if (eq gpg-encrypt 'gpg)
1262 (auth-source-epa-make-gpg-token plain file)
1263 plain)))
1102 ((null data) 1264 ((null data)
1103 (when default 1265 (when default
1104 (setq prompt 1266 (setq prompt
@@ -1125,7 +1287,7 @@ See `auth-source-search' for details on SPEC."
1125 (let ((printer (lambda () 1287 (let ((printer (lambda ()
1126 ;; append the key (the symbol name of r) 1288 ;; append the key (the symbol name of r)
1127 ;; and the value in r 1289 ;; and the value in r
1128 (format "%s%s %S" 1290 (format "%s%s %s"
1129 ;; prepend a space 1291 ;; prepend a space
1130 (if (zerop (length add)) "" " ") 1292 (if (zerop (length add)) "" " ")
1131 ;; remap auth-source tokens to netrc 1293 ;; remap auth-source tokens to netrc
@@ -1135,8 +1297,9 @@ See `auth-source-search' for details on SPEC."
1135 (secret "password") 1297 (secret "password")
1136 (port "port") ; redundant but clearer 1298 (port "port") ; redundant but clearer
1137 (t (symbol-name r))) 1299 (t (symbol-name r)))
1138 ;; the value will be printed in %S format 1300 (if (string-match "[\" ]" data)
1139 data)))) 1301 (format "%S" data)
1302 data)))))
1140 (setq add (concat add (funcall printer))))))) 1303 (setq add (concat add (funcall printer)))))))
1141 1304
1142 (plist-put 1305 (plist-put
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index dc8b38b8f9a..1bbd76f345e 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -929,7 +929,7 @@ textual parts.")
929 (car (setq result (nnimap-parse-response)))) 929 (car (setq result (nnimap-parse-response))))
930 ;; Select the last instance of the message in the group. 930 ;; Select the last instance of the message in the group.
931 (and (setq article 931 (and (setq article
932 (car (last (assoc "SEARCH" (cdr result))))) 932 (car (last (cdr (assoc "SEARCH" (cdr result))))))
933 (string-to-number article)))))) 933 (string-to-number article))))))
934 934
935(defun nnimap-delete-article (articles) 935(defun nnimap-delete-article (articles)
diff --git a/lisp/info.el b/lisp/info.el
index 796fd7e2256..bca41c29d0f 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -3230,7 +3230,7 @@ STRING is the search string given as an argument to `info-apropos',
3230MATCHES is a list of index matches found by `Info-apropos-matches'.") 3230MATCHES is a list of index matches found by `Info-apropos-matches'.")
3231 3231
3232(defun Info-apropos-toc-nodes (filename) 3232(defun Info-apropos-toc-nodes (filename)
3233 "Apropos-specific implementation of `Info-apropos-toc-nodes'." 3233 "Apropos-specific implementation of `Info-toc-nodes'."
3234 (let ((nodes (mapcar 'car (reverse Info-apropos-nodes)))) 3234 (let ((nodes (mapcar 'car (reverse Info-apropos-nodes))))
3235 `(,filename 3235 `(,filename
3236 ("Top" nil nil ,nodes) 3236 ("Top" nil nil ,nodes)
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index 5f4d3ea849e..b3f17bb3fcf 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -1308,11 +1308,11 @@ This is the input method activated automatically by the command
1308`toggle-input-method' (\\[toggle-input-method])." 1308`toggle-input-method' (\\[toggle-input-method])."
1309 :link '(custom-manual "(emacs)Input Methods") 1309 :link '(custom-manual "(emacs)Input Methods")
1310 :group 'mule 1310 :group 'mule
1311 :type '(choice (const nil) (string 1311 :type '(choice (const nil)
1312 :completion-ignore-case t 1312 (string
1313 :complete-function widget-string-complete 1313 :completions (apply-partially
1314 :completion-alist input-method-alist 1314 #'completion-table-case-fold input-method-alist)
1315 :prompt-history input-method-history)) 1315 :prompt-history input-method-history))
1316 :set-after '(current-language-environment)) 1316 :set-after '(current-language-environment))
1317 1317
1318(put 'input-method-function 'permanent-local t) 1318(put 'input-method-function 'permanent-local t)
@@ -1875,10 +1875,10 @@ specifies the character set for the major languages of Western Europe."
1875(define-widget 'charset 'symbol 1875(define-widget 'charset 'symbol
1876 "An Emacs charset." 1876 "An Emacs charset."
1877 :tag "Charset" 1877 :tag "Charset"
1878 :complete-function (lambda () 1878 :completions (apply-partially #'completion-table-with-predicate
1879 (interactive) 1879 (apply-partially #'completion-table-case-fold
1880 (lisp-complete-symbol 'charsetp)) 1880 obarray)
1881 :completion-ignore-case t 1881 #'charsetp 'strict)
1882 :value 'ascii 1882 :value 'ascii
1883 :validate (lambda (widget) 1883 :validate (lambda (widget)
1884 (unless (charsetp (widget-value widget)) 1884 (unless (charsetp (widget-value widget))
@@ -1912,9 +1912,9 @@ See `set-language-info-alist' for use in programs."
1912 (set-language-environment current-language-environment))) 1912 (set-language-environment current-language-environment)))
1913 :type `(alist 1913 :type `(alist
1914 :key-type (string :tag "Language environment" 1914 :key-type (string :tag "Language environment"
1915 :completion-ignore-case t 1915 :completions
1916 :complete-function widget-string-complete 1916 (apply-partially #'completion-table-case-fold
1917 :completion-alist language-info-alist) 1917 language-info-alist))
1918 :value-type 1918 :value-type
1919 (alist :key-type symbol 1919 (alist :key-type symbol
1920 :options ((documentation string) 1920 :options ((documentation string)
@@ -1927,9 +1927,9 @@ See `set-language-info-alist' for use in programs."
1927 (nonascii-translation charset) 1927 (nonascii-translation charset)
1928 (input-method 1928 (input-method
1929 (string 1929 (string
1930 :completion-ignore-case t 1930 :completions
1931 :complete-function widget-string-complete 1931 (apply-partially #'completion-table-case-fold
1932 :completion-alist input-method-alist 1932 input-method-alist)
1933 :prompt-history input-method-history)) 1933 :prompt-history input-method-history))
1934 (features (repeat symbol)) 1934 (features (repeat symbol))
1935 (unibyte-display coding-system))))) 1935 (unibyte-display coding-system)))))
diff --git a/lisp/mail/mailabbrev.el b/lisp/mail/mailabbrev.el
index b4827cf10ba..901eb002dc1 100644
--- a/lisp/mail/mailabbrev.el
+++ b/lisp/mail/mailabbrev.el
@@ -565,7 +565,6 @@ of a mail alias. The value is set up, buffer-local, when first needed.")
565 565
566(defun mail-abbrev-complete-alias () 566(defun mail-abbrev-complete-alias ()
567 "Perform completion on alias preceding point." 567 "Perform completion on alias preceding point."
568 ;; Based on lisp.el:lisp-complete-symbol
569 (interactive) 568 (interactive)
570 (mail-abbrev-make-syntax-table) 569 (mail-abbrev-make-syntax-table)
571 (let ((end (point)) 570 (let ((end (point))
diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el
index bc1ca77d24a..3c9ea9de573 100644
--- a/lisp/mail/smtpmail.el
+++ b/lisp/mail/smtpmail.el
@@ -34,16 +34,10 @@
34;; 34;;
35;;(setq send-mail-function 'smtpmail-send-it) ; if you use `mail' 35;;(setq send-mail-function 'smtpmail-send-it) ; if you use `mail'
36;;(setq message-send-mail-function 'smtpmail-send-it) ; if you use message/Gnus 36;;(setq message-send-mail-function 'smtpmail-send-it) ; if you use message/Gnus
37;;(setq smtpmail-default-smtp-server "YOUR SMTP HOST") 37;;(setq smtpmail-smtp-server "YOUR SMTP HOST")
38;;(setq smtpmail-local-domain "YOUR DOMAIN NAME") 38;;(setq smtpmail-local-domain "YOUR DOMAIN NAME")
39;;(setq smtpmail-sendto-domain "YOUR DOMAIN NAME") 39;;(setq smtpmail-sendto-domain "YOUR DOMAIN NAME")
40;;(setq smtpmail-debug-info t) ; only to debug problems 40;;(setq smtpmail-debug-info t) ; only to debug problems
41;;(setq smtpmail-auth-credentials ; or use ~/.authinfo
42;; '(("YOUR SMTP HOST" 25 "username" "password")))
43;;(setq smtpmail-starttls-credentials
44;; '(("YOUR SMTP HOST" 25 "~/.my_smtp_tls.key" "~/.my_smtp_tls.cert")))
45;; Where the 25 equals the value of `smtpmail-smtp-service', it can be an
46;; integer or a string, just as long as they match (eq).
47 41
48;; To queue mail, set `smtpmail-queue-mail' to t and use 42;; To queue mail, set `smtpmail-queue-mail' to t and use
49;; `smtpmail-send-queued-mail' to send. 43;; `smtpmail-send-queued-mail' to send.
@@ -58,17 +52,9 @@
58;; Authentication by the AUTH mechanism. 52;; Authentication by the AUTH mechanism.
59;; See http://www.ietf.org/rfc/rfc2554.txt 53;; See http://www.ietf.org/rfc/rfc2554.txt
60 54
61;; Modified by Simon Josefsson <simon@josefsson.org>, 2000-10-07, to support
62;; STARTTLS. Requires external program
63;; ftp://ftp.opaopa.org/pub/elisp/starttls-*.tar.gz.
64;; See http://www.ietf.org/rfc/rfc2246.txt, http://www.ietf.org/rfc/rfc2487.txt
65
66;;; Code: 55;;; Code:
67 56
68(require 'sendmail) 57(require 'sendmail)
69(autoload 'starttls-any-program-available "starttls")
70(autoload 'starttls-open-stream "starttls")
71(autoload 'starttls-negotiate "starttls")
72(autoload 'mail-strip-quoted-names "mail-utils") 58(autoload 'mail-strip-quoted-names "mail-utils")
73(autoload 'message-make-date "message") 59(autoload 'message-make-date "message")
74(autoload 'message-make-message-id "message") 60(autoload 'message-make-message-id "message")
@@ -85,11 +71,9 @@
85 :group 'mail) 71 :group 'mail)
86 72
87 73
88(defcustom smtpmail-default-smtp-server nil 74(defvar smtpmail-default-smtp-server nil
89 "Specify default SMTP server. 75 "Specify default SMTP server.
90This only has effect if you specify it before loading the smtpmail library." 76This only has effect if you specify it before loading the smtpmail library.")
91 :type '(choice (const nil) string)
92 :group 'smtpmail)
93 77
94(defcustom smtpmail-smtp-server 78(defcustom smtpmail-smtp-server
95 (or (getenv "SMTPSERVER") smtpmail-default-smtp-server) 79 (or (getenv "SMTPSERVER") smtpmail-default-smtp-server)
@@ -110,6 +94,16 @@ don't define this value."
110 :type '(choice (const nil) string) 94 :type '(choice (const nil) string)
111 :group 'smtpmail) 95 :group 'smtpmail)
112 96
97(defcustom smtpmail-stream-type nil
98 "Connection type SMTP connections.
99This may be either nil (plain connection) or `starttls' (use the
100starttls mechanism to turn on TLS security after opening the
101stream)."
102 :version "24.1"
103 :group 'smtpmail
104 :type '(choice (const :tag "Plain" nil)
105 (const starttls)))
106
113(defcustom smtpmail-sendto-domain nil 107(defcustom smtpmail-sendto-domain nil
114 "Local domain name without a host name. 108 "Local domain name without a host name.
115This is appended (with an @-sign) to any specified recipients which do 109This is appended (with an @-sign) to any specified recipients which do
@@ -117,11 +111,7 @@ not include an @-sign, so that each RCPT TO address is fully qualified.
117\(Some configurations of sendmail require this.) 111\(Some configurations of sendmail require this.)
118 112
119Don't bother to set this unless you have get an error like: 113Don't bother to set this unless you have get an error like:
120 Sending failed; SMTP protocol error 114 Sending failed; 501 <someone>: recipient address must contain a domain."
121when sending mail, and the *trace of SMTP session to <somewhere>*
122buffer includes an exchange like:
123 RCPT TO: <someone>
124 501 <someone>: recipient address must contain a domain."
125 :type '(choice (const nil) string) 115 :type '(choice (const nil) string)
126 :group 'smtpmail) 116 :group 'smtpmail)
127 117
@@ -157,39 +147,6 @@ and sent with `smtpmail-send-queued-mail'."
157 :type 'directory 147 :type 'directory
158 :group 'smtpmail) 148 :group 'smtpmail)
159 149
160(defcustom smtpmail-auth-credentials "~/.authinfo"
161 "Specify username and password for servers, directly or via .netrc file.
162This variable can either be a filename pointing to a file in netrc(5)
163format, or list of four-element lists that contain, in order,
164`servername' (a string), `port' (an integer), `user' (a string) and
165`password' (a string, or nil to query the user when needed). If you
166need to enter a `realm' too, add it to the user string, so that it
167looks like `user@realm'."
168 :type '(choice file
169 (repeat (list (string :tag "Server")
170 (integer :tag "Port")
171 (string :tag "Username")
172 (choice (const :tag "Query when needed" nil)
173 (string :tag "Password")))))
174 :version "22.1"
175 :group 'smtpmail)
176
177(defcustom smtpmail-starttls-credentials '(("" 25 "" ""))
178 "Specify STARTTLS keys and certificates for servers.
179This is a list of four-element list with `servername' (a string),
180`port' (an integer), `key' (a filename) and `certificate' (a
181filename).
182If you do not have a certificate/key pair, leave the `key' and
183`certificate' fields as `nil'. A key/certificate pair is only
184needed if you want to use X.509 client authenticated
185connections."
186 :type '(repeat (list (string :tag "Server")
187 (integer :tag "Port")
188 (file :tag "Key")
189 (file :tag "Certificate")))
190 :version "21.1"
191 :group 'smtpmail)
192
193(defcustom smtpmail-warn-about-unknown-extensions nil 150(defcustom smtpmail-warn-about-unknown-extensions nil
194 "If set, print warnings about unknown SMTP extensions. 151 "If set, print warnings about unknown SMTP extensions.
195This is mainly useful for development purposes, to learn about 152This is mainly useful for development purposes, to learn about
@@ -230,6 +187,7 @@ The list is in preference order.")
230 (tembuf (generate-new-buffer " smtpmail temp")) 187 (tembuf (generate-new-buffer " smtpmail temp"))
231 (case-fold-search nil) 188 (case-fold-search nil)
232 delimline 189 delimline
190 result
233 (mailbuf (current-buffer)) 191 (mailbuf (current-buffer))
234 ;; Examine this variable now, so that 192 ;; Examine this variable now, so that
235 ;; local binding in the mail buffer will take effect. 193 ;; local binding in the mail buffer will take effect.
@@ -373,9 +331,10 @@ The list is in preference order.")
373 ;; Send or queue 331 ;; Send or queue
374 (if (not smtpmail-queue-mail) 332 (if (not smtpmail-queue-mail)
375 (if (not (null smtpmail-recipient-address-list)) 333 (if (not (null smtpmail-recipient-address-list))
376 (if (not (smtpmail-via-smtp 334 (when (setq result
377 smtpmail-recipient-address-list tembuf)) 335 (smtpmail-via-smtp
378 (error "Sending failed; SMTP protocol error")) 336 smtpmail-recipient-address-list tembuf))
337 (error "Sending failed: %s" result))
379 (error "Sending failed; no recipients")) 338 (error "Sending failed; no recipients"))
380 (let* ((file-data 339 (let* ((file-data
381 (expand-file-name 340 (expand-file-name
@@ -432,7 +391,8 @@ The list is in preference order.")
432 ;; mail, send it, etc... 391 ;; mail, send it, etc...
433 (let ((file-msg "") 392 (let ((file-msg "")
434 (qfile (expand-file-name smtpmail-queue-index-file 393 (qfile (expand-file-name smtpmail-queue-index-file
435 smtpmail-queue-dir))) 394 smtpmail-queue-dir))
395 result)
436 (insert-file-contents qfile) 396 (insert-file-contents qfile)
437 (goto-char (point-min)) 397 (goto-char (point-min))
438 (while (not (eobp)) 398 (while (not (eobp))
@@ -448,17 +408,16 @@ The list is in preference order.")
448 (or (and mail-specify-envelope-from (mail-envelope-from)) 408 (or (and mail-specify-envelope-from (mail-envelope-from))
449 user-mail-address))) 409 user-mail-address)))
450 (if (not (null smtpmail-recipient-address-list)) 410 (if (not (null smtpmail-recipient-address-list))
451 (if (not (smtpmail-via-smtp smtpmail-recipient-address-list 411 (when (setq result (smtpmail-via-smtp
452 (current-buffer))) 412 smtpmail-recipient-address-list
453 (error "Sending failed; SMTP protocol error")) 413 (current-buffer)))
414 (error "Sending failed: %s" result))
454 (error "Sending failed; no recipients")))) 415 (error "Sending failed; no recipients"))))
455 (delete-file file-msg) 416 (delete-file file-msg)
456 (delete-file (concat file-msg ".el")) 417 (delete-file (concat file-msg ".el"))
457 (delete-region (point-at-bol) (point-at-bol 2))) 418 (delete-region (point-at-bol) (point-at-bol 2)))
458 (write-region (point-min) (point-max) qfile)))) 419 (write-region (point-min) (point-max) qfile))))
459 420
460;; (defun smtpmail-via-smtp (host,port,sender,destination,smtpmail-text-buffer)
461
462(defun smtpmail-fqdn () 421(defun smtpmail-fqdn ()
463 (if smtpmail-local-domain 422 (if smtpmail-local-domain
464 (concat (system-name) "." smtpmail-local-domain) 423 (concat (system-name) "." smtpmail-local-domain)
@@ -503,146 +462,149 @@ The list is in preference order.")
503 (push el2 result))) 462 (push el2 result)))
504 (nreverse result))) 463 (nreverse result)))
505 464
506(defvar starttls-extra-args)
507(defvar starttls-extra-arguments)
508
509(defun smtpmail-open-stream (process-buffer host port)
510 (let ((cred (smtpmail-find-credentials
511 smtpmail-starttls-credentials host port)))
512 (if (null (and cred (starttls-any-program-available)))
513 ;; The normal case.
514 (open-network-stream "SMTP" process-buffer host port)
515 (let* ((cred-key (smtpmail-cred-key cred))
516 (cred-cert (smtpmail-cred-cert cred))
517 (starttls-extra-args
518 (append
519 starttls-extra-args
520 (when (and (stringp cred-key) (stringp cred-cert)
521 (file-regular-p
522 (setq cred-key (expand-file-name cred-key)))
523 (file-regular-p
524 (setq cred-cert (expand-file-name cred-cert))))
525 (list "--key-file" cred-key "--cert-file" cred-cert))))
526 (starttls-extra-arguments
527 (append
528 starttls-extra-arguments
529 (when (and (stringp cred-key) (stringp cred-cert)
530 (file-regular-p
531 (setq cred-key (expand-file-name cred-key)))
532 (file-regular-p
533 (setq cred-cert (expand-file-name cred-cert))))
534 (list "--x509keyfile" cred-key "--x509certfile" cred-cert)))))
535 (starttls-open-stream "SMTP" process-buffer host port)))))
536
537;; `password-read' autoloads password-cache. 465;; `password-read' autoloads password-cache.
538(declare-function password-cache-add "password-cache" (key password)) 466(declare-function password-cache-add "password-cache" (key password))
539 467
540(defun smtpmail-try-auth-methods (process supported-extensions host port) 468(defun smtpmail-command-or-throw (process string &optional code)
469 (let (ret)
470 (smtpmail-send-command process string)
471 (unless (smtpmail-ok-p (setq ret (smtpmail-read-response process))
472 code)
473 (throw 'done (format "%s in response to %s"
474 (smtpmail-response-text ret)
475 string)))
476 ret))
477
478(defun smtpmail-try-auth-methods (process supported-extensions host port
479 &optional ask-for-password)
480 (setq port
481 (if port
482 (format "%s" port)
483 "smtp"))
541 (let* ((mechs (cdr-safe (assoc 'auth supported-extensions))) 484 (let* ((mechs (cdr-safe (assoc 'auth supported-extensions)))
542 (mech (car (smtpmail-intersection mechs smtpmail-auth-supported))) 485 (mech (car (smtpmail-intersection mechs smtpmail-auth-supported)))
543 (auth-info (auth-source-search :max 1 486 (auth-source-creation-prompts
544 :host host 487 '((user . "SMTP user at %h: ")
545 :port (or port "smtp"))) 488 (secret . "SMTP password for %u@%h: ")))
546 (auth-user (plist-get (nth 0 auth-info) :user)) 489 (auth-info (car
547 (auth-pass (plist-get (nth 0 auth-info) :secret)) 490 (auth-source-search
548 (auth-pass (if (functionp auth-pass) 491 :max 1
549 (funcall auth-pass) 492 :host host
550 auth-pass)) 493 :port port
551 (cred (if (and auth-user auth-pass) ; try user-auth-* before netrc-* 494 :require (and ask-for-password
552 (list host port auth-user auth-pass) 495 '(:user :secret))
553 ;; else, if auth-source didn't return them... 496 :create ask-for-password)))
554 (if (stringp smtpmail-auth-credentials) 497 (user (plist-get auth-info :user))
555 (let* ((netrc (netrc-parse smtpmail-auth-credentials)) 498 (password (plist-get auth-info :secret))
556 (port-name (format "%s" (or port "smtp"))) 499 (save-function (and ask-for-password
557 (hostentry (netrc-machine netrc host port-name 500 (plist-get auth-info :save-function)))
558 port-name)))
559 (when hostentry
560 (list host port
561 (netrc-get hostentry "login")
562 (netrc-get hostentry "password"))))
563 ;; else, try `smtpmail-find-credentials' since
564 ;; `smtpmail-auth-credentials' is not a string
565 (smtpmail-find-credentials
566 smtpmail-auth-credentials host port))))
567 (prompt (when cred (format "SMTP password for %s:%s: "
568 (smtpmail-cred-server cred)
569 (smtpmail-cred-port cred))))
570 (passwd (when cred
571 (or (smtpmail-cred-passwd cred)
572 (password-read prompt prompt))))
573 ret) 501 ret)
574 (when (and cred mech) 502 (when (and user
575 (cond 503 (not password))
576 ((eq mech 'cram-md5) 504 ;; The user has stored the user name, but not the password, so
577 (smtpmail-send-command process (upcase (format "AUTH %s" mech))) 505 ;; ask for the password, even if we're not forcing that through
578 (if (or (null (car (setq ret (smtpmail-read-response process)))) 506 ;; `ask-for-password'.
579 (not (integerp (car ret))) 507 (setq auth-info
580 (>= (car ret) 400)) 508 (car
581 (throw 'done nil)) 509 (auth-source-search
582 (when (eq (car ret) 334) 510 :max 1
583 (let* ((challenge (substring (cadr ret) 4)) 511 :host host
584 (decoded (base64-decode-string challenge)) 512 :port port
585 (hash (rfc2104-hash 'md5 64 16 passwd decoded)) 513 :require '(:user :secret)
586 (response (concat (smtpmail-cred-user cred) " " hash)) 514 :create t))
587 ;; Osamu Yamane <yamane@green.ocn.ne.jp>: 515 password (plist-get auth-info :secret)))
588 ;; SMTP auth fails because the SMTP server identifies 516 (when (functionp password)
589 ;; only the first part of the string (delimited by 517 (setq password (funcall password)))
590 ;; new line characters) as a response from the 518 (cond
591 ;; client, and the rest as distinct commands. 519 ((or (not mech)
592 520 (not user)
593 ;; In my case, the response string is 80 characters 521 (not password))
594 ;; long. Without the no-line-break option for 522 ;; No mechanism, or no credentials.
595 ;; `base64-encode-string', only the first 76 characters 523 mech)
596 ;; are taken as a response to the server, and the 524 ((eq mech 'cram-md5)
597 ;; authentication fails. 525 (setq ret (smtpmail-command-or-throw process "AUTH CRAM-MD5"))
598 (encoded (base64-encode-string response t))) 526 (when (eq (car ret) 334)
599 (smtpmail-send-command process (format "%s" encoded)) 527 (let* ((challenge (substring (cadr ret) 4))
600 (if (or (null (car (setq ret (smtpmail-read-response process)))) 528 (decoded (base64-decode-string challenge))
601 (not (integerp (car ret))) 529 (hash (rfc2104-hash 'md5 64 16 password decoded))
602 (>= (car ret) 400)) 530 (response (concat user " " hash))
603 (throw 'done nil))))) 531 ;; Osamu Yamane <yamane@green.ocn.ne.jp>:
604 ((eq mech 'login) 532 ;; SMTP auth fails because the SMTP server identifies
605 (smtpmail-send-command process "AUTH LOGIN") 533 ;; only the first part of the string (delimited by
606 (if (or (null (car (setq ret (smtpmail-read-response process)))) 534 ;; new line characters) as a response from the
607 (not (integerp (car ret))) 535 ;; client, and the rest as distinct commands.
608 (>= (car ret) 400)) 536
609 (throw 'done nil)) 537 ;; In my case, the response string is 80 characters
610 (smtpmail-send-command 538 ;; long. Without the no-line-break option for
611 process (base64-encode-string (smtpmail-cred-user cred) t)) 539 ;; `base64-encode-string', only the first 76 characters
612 (if (or (null (car (setq ret (smtpmail-read-response process)))) 540 ;; are taken as a response to the server, and the
613 (not (integerp (car ret))) 541 ;; authentication fails.
614 (>= (car ret) 400)) 542 (encoded (base64-encode-string response t)))
615 (throw 'done nil)) 543 (smtpmail-command-or-throw process encoded)
616 (smtpmail-send-command process (base64-encode-string passwd t)) 544 (when save-function
617 (if (or (null (car (setq ret (smtpmail-read-response process)))) 545 (funcall save-function)))))
618 (not (integerp (car ret))) 546 ((eq mech 'login)
619 (>= (car ret) 400)) 547 (smtpmail-command-or-throw process "AUTH LOGIN")
620 (throw 'done nil))) 548 (smtpmail-command-or-throw
621 ((eq mech 'plain) 549 process (base64-encode-string user t))
622 ;; We used to send an empty initial request, and wait for an 550 (smtpmail-command-or-throw process (base64-encode-string password t))
623 ;; empty response, and then send the password, but this 551 (when save-function
624 ;; violate a SHOULD in RFC 2222 paragraph 5.1. Note that this 552 (funcall save-function)))
625 ;; is not sent if the server did not advertise AUTH PLAIN in 553 ((eq mech 'plain)
626 ;; the EHLO response. See RFC 2554 for more info. 554 ;; We used to send an empty initial request, and wait for an
627 (smtpmail-send-command process 555 ;; empty response, and then send the password, but this
628 (concat "AUTH PLAIN " 556 ;; violate a SHOULD in RFC 2222 paragraph 5.1. Note that this
629 (base64-encode-string 557 ;; is not sent if the server did not advertise AUTH PLAIN in
630 (concat "\0" 558 ;; the EHLO response. See RFC 2554 for more info.
631 (smtpmail-cred-user cred) 559 (smtpmail-command-or-throw
632 "\0" 560 process
633 passwd) t))) 561 (concat "AUTH PLAIN "
634 (if (or (null (car (setq ret (smtpmail-read-response process)))) 562 (base64-encode-string (concat "\0" user "\0" password) t))
635 (not (integerp (car ret))) 563 235)
636 (not (equal (car ret) 235))) 564 (when save-function
637 (throw 'done nil))) 565 (funcall save-function)))
638 566 (t
639 (t 567 (error "Mechanism %s not implemented" mech)))))
640 (error "Mechanism %s not implemented" mech))) 568
641 ;; Remember the password. 569(defun smtpmail-response-code (string)
642 (when (null (smtpmail-cred-passwd cred)) 570 (when string
643 (password-cache-add prompt passwd))))) 571 (with-temp-buffer
644 572 (insert string)
645(defun smtpmail-via-smtp (recipient smtpmail-text-buffer) 573 (goto-char (point-min))
574 (and (re-search-forward "^\\([0-9]+\\) " nil t)
575 (string-to-number (match-string 1))))))
576
577(defun smtpmail-ok-p (response &optional code)
578 (and (car response)
579 (integerp (car response))
580 (< (car response) 400)
581 (or (null code)
582 (= code (car response)))))
583
584(defun smtpmail-response-text (response)
585 (mapconcat 'identity (cdr response) "\n"))
586
587(defun smtpmail-query-smtp-server ()
588 (let ((server (read-string "Outgoing SMTP mail server: "))
589 (ports '(587 "smtp"))
590 stream port)
591 (when (and smtpmail-smtp-server
592 (not (member smtpmail-smtp-server ports)))
593 (push smtpmail-smtp-server ports))
594 (while (and (not smtpmail-smtp-server)
595 (setq port (pop ports)))
596 (when (setq stream (ignore-errors
597 (open-network-stream "smtp" nil server port)))
598 (customize-save-variable 'smtpmail-smtp-server server)
599 (customize-save-variable 'smtpmail-smtp-service port)
600 (delete-process stream)))
601 (unless smtpmail-smtp-server
602 (error "Couldn't contact an SMTP server"))))
603
604(defun smtpmail-via-smtp (recipient smtpmail-text-buffer
605 &optional ask-for-password)
606 (unless smtpmail-smtp-server
607 (smtpmail-query-smtp-server))
646 (let ((process nil) 608 (let ((process nil)
647 (host (or smtpmail-smtp-server 609 (host (or smtpmail-smtp-server
648 (error "`smtpmail-smtp-server' not defined"))) 610 (error "`smtpmail-smtp-server' not defined")))
@@ -654,14 +616,16 @@ The list is in preference order.")
654 (mail-envelope-from)) 616 (mail-envelope-from))
655 user-mail-address)) 617 user-mail-address))
656 response-code 618 response-code
657 greeting
658 process-buffer 619 process-buffer
620 result
621 auth-mechanisms
659 (supported-extensions '())) 622 (supported-extensions '()))
660 (unwind-protect 623 (unwind-protect
661 (catch 'done 624 (catch 'done
662 ;; get or create the trace buffer 625 ;; get or create the trace buffer
663 (setq process-buffer 626 (setq process-buffer
664 (get-buffer-create (format "*trace of SMTP session to %s*" host))) 627 (get-buffer-create
628 (format "*trace of SMTP session to %s*" host)))
665 629
666 ;; clear the trace buffer of old output 630 ;; clear the trace buffer of old output
667 (with-current-buffer process-buffer 631 (with-current-buffer process-buffer
@@ -669,105 +633,89 @@ The list is in preference order.")
669 (erase-buffer)) 633 (erase-buffer))
670 634
671 ;; open the connection to the server 635 ;; open the connection to the server
672 (setq process (smtpmail-open-stream process-buffer host port)) 636 (setq result
673 (and (null process) (throw 'done nil)) 637 (open-network-stream
638 "smtpmail" process-buffer host port
639 :type smtpmail-stream-type
640 :return-list t
641 :capability-command (format "EHLO %s\r\n" (smtpmail-fqdn))
642 :end-of-command "^[0-9]+ .*\r\n"
643 :success "^2.*\n"
644 :always-query-capabilities t
645 :starttls-function
646 (lambda (capabilities)
647 (and (string-match "-STARTTLS" capabilities)
648 "STARTTLS\r\n"))
649 :client-certificate t
650 :use-starttls-if-possible t))
651
652 ;; If we couldn't access the server at all, we give up.
653 (unless (setq process (car result))
654 (throw 'done "Unable to contact server"))
674 655
675 ;; set the send-filter 656 ;; set the send-filter
676 (set-process-filter process 'smtpmail-process-filter) 657 (set-process-filter process 'smtpmail-process-filter)
677 658
659 (let* ((greeting (plist-get (cdr result) :greeting))
660 (code (smtpmail-response-code greeting)))
661 (unless code
662 (throw 'done (format "No greeting: %s" greeting)))
663 (when (>= code 400)
664 (throw 'done (format "Connection not allowed: %s" greeting))))
665
678 (with-current-buffer process-buffer 666 (with-current-buffer process-buffer
679 (set-buffer-process-coding-system 'raw-text-unix 'raw-text-unix) 667 (set-buffer-process-coding-system 'raw-text-unix 'raw-text-unix)
680 (make-local-variable 'smtpmail-read-point) 668 (make-local-variable 'smtpmail-read-point)
681 (setq smtpmail-read-point (point-min)) 669 (setq smtpmail-read-point (point-min))
682 670
683 671 (let* ((capabilities (plist-get (cdr result) :capabilities))
684 (if (or (null (car (setq greeting (smtpmail-read-response process)))) 672 (code (smtpmail-response-code capabilities)))
685 (not (integerp (car greeting))) 673 (if (or (null code)
686 (>= (car greeting) 400)) 674 (>= code 400))
687 (throw 'done nil)) 675 ;; The server didn't accept EHLO, so we fall back on HELO.
688 676 (smtpmail-command-or-throw
689 (let ((do-ehlo t) 677 process (format "HELO %s" (smtpmail-fqdn)))
690 (do-starttls t)) 678 ;; EHLO was successful, so we parse the extensions.
691 (while do-ehlo 679 (dolist (line (delete
692 ;; EHLO 680 ""
693 (smtpmail-send-command process (format "EHLO %s" (smtpmail-fqdn))) 681 (split-string
694 682 (plist-get (cdr result) :capabilities)
695 (if (or (null (car (setq response-code 683 "\r\n")))
696 (smtpmail-read-response process)))) 684 (let ((name
697 (not (integerp (car response-code))) 685 (with-case-table ascii-case-table
698 (>= (car response-code) 400)) 686 (mapcar (lambda (s) (intern (downcase s)))
699 (progn 687 (split-string (substring line 4) "[ ]")))))
700 ;; HELO 688 (when (= (length name) 1)
701 (smtpmail-send-command 689 (setq name (car name)))
702 process (format "HELO %s" (smtpmail-fqdn))) 690 (when name
703 691 (cond ((memq (if (consp name) (car name) name)
704 (if (or (null (car (setq response-code 692 '(verb xvrb 8bitmime onex xone
705 (smtpmail-read-response process)))) 693 expn size dsn etrn
706 (not (integerp (car response-code))) 694 enhancedstatuscodes
707 (>= (car response-code) 400)) 695 help xusr
708 (throw 'done nil))) 696 auth=login auth starttls))
709 (dolist (line (cdr (cdr response-code))) 697 (setq supported-extensions
710 (let ((name 698 (cons name supported-extensions)))
711 (with-case-table ascii-case-table 699 (smtpmail-warn-about-unknown-extensions
712 (mapcar (lambda (s) (intern (downcase s))) 700 (message "Unknown extension %s" name))))))))
713 (split-string (substring line 4) "[ ]"))))) 701
714 (and (eq (length name) 1) 702 (setq auth-mechanisms
715 (setq name (car name))) 703 (smtpmail-try-auth-methods
716 (and name 704 process supported-extensions host port
717 (cond ((memq (if (consp name) (car name) name) 705 ask-for-password))
718 '(verb xvrb 8bitmime onex xone 706
719 expn size dsn etrn 707 (when (or (member 'onex supported-extensions)
720 enhancedstatuscodes 708 (member 'xone supported-extensions))
721 help xusr 709 (smtpmail-command-or-throw process (format "ONEX")))
722 auth=login auth starttls)) 710
723 (setq supported-extensions 711 (when (and smtpmail-debug-verb
724 (cons name supported-extensions))) 712 (or (member 'verb supported-extensions)
725 (smtpmail-warn-about-unknown-extensions 713 (member 'xvrb supported-extensions)))
726 (message "Unknown extension %s" name))))))) 714 (smtpmail-command-or-throw process (format "VERB")))
727 715
728 (if (and do-starttls 716 (when (member 'xusr supported-extensions)
729 (smtpmail-find-credentials smtpmail-starttls-credentials host port) 717 (smtpmail-command-or-throw process (format "XUSR")))
730 (member 'starttls supported-extensions) 718
731 (numberp (process-id process)))
732 (progn
733 (smtpmail-send-command process (format "STARTTLS"))
734 (if (or (null (car (setq response-code (smtpmail-read-response process))))
735 (not (integerp (car response-code)))
736 (>= (car response-code) 400))
737 (throw 'done nil))
738 (starttls-negotiate process)
739 (setq do-starttls nil))
740 (setq do-ehlo nil))))
741
742 (smtpmail-try-auth-methods process supported-extensions host port)
743
744 (if (or (member 'onex supported-extensions)
745 (member 'xone supported-extensions))
746 (progn
747 (smtpmail-send-command process (format "ONEX"))
748 (if (or (null (car (setq response-code (smtpmail-read-response process))))
749 (not (integerp (car response-code)))
750 (>= (car response-code) 400))
751 (throw 'done nil))))
752
753 (if (and smtpmail-debug-verb
754 (or (member 'verb supported-extensions)
755 (member 'xvrb supported-extensions)))
756 (progn
757 (smtpmail-send-command process (format "VERB"))
758 (if (or (null (car (setq response-code (smtpmail-read-response process))))
759 (not (integerp (car response-code)))
760 (>= (car response-code) 400))
761 (throw 'done nil))))
762
763 (if (member 'xusr supported-extensions)
764 (progn
765 (smtpmail-send-command process (format "XUSR"))
766 (if (or (null (car (setq response-code (smtpmail-read-response process))))
767 (not (integerp (car response-code)))
768 (>= (car response-code) 400))
769 (throw 'done nil))))
770
771 ;; MAIL FROM:<sender> 719 ;; MAIL FROM:<sender>
772 (let ((size-part 720 (let ((size-part
773 (if (or (member 'size supported-extensions) 721 (if (or (member 'size supported-extensions)
@@ -797,65 +745,73 @@ The list is in preference order.")
797 " BODY=8BITMIME" 745 " BODY=8BITMIME"
798 "") 746 "")
799 ""))) 747 "")))
800 ;; (smtpmail-send-command process (format "MAIL FROM:%s@%s" (user-login-name) (smtpmail-fqdn))) 748 (smtpmail-send-command
801 (smtpmail-send-command process (format "MAIL FROM:<%s>%s%s" 749 process (format "MAIL FROM:<%s>%s%s"
802 envelope-from 750 envelope-from size-part body-part))
803 size-part 751 (cond
804 body-part)) 752 ((smtpmail-ok-p (setq result (smtpmail-read-response process)))
805 753 ;; Success.
806 (if (or (null (car (setq response-code (smtpmail-read-response process)))) 754 )
807 (not (integerp (car response-code))) 755 ((and auth-mechanisms
808 (>= (car response-code) 400)) 756 (not ask-for-password)
809 (throw 'done nil))) 757 (= (car result) 530))
758 ;; We got a "530 auth required", so we close and try
759 ;; again, this time asking the user for a password.
760 (smtpmail-send-command process "QUIT")
761 (smtpmail-read-response process)
762 (delete-process process)
763 (setq process nil)
764 (throw 'done
765 (smtpmail-via-smtp recipient smtpmail-text-buffer t)))
766 (t
767 ;; Return the error code.
768 (throw 'done
769 (smtpmail-response-text result)))))
810 770
811 ;; RCPT TO:<recipient> 771 ;; RCPT TO:<recipient>
812 (let ((n 0)) 772 (let ((n 0))
813 (while (not (null (nth n recipient))) 773 (while (not (null (nth n recipient)))
814 (smtpmail-send-command process (format "RCPT TO:<%s>" (smtpmail-maybe-append-domain (nth n recipient)))) 774 (smtpmail-send-command
815 (setq n (1+ n)) 775 process (format "RCPT TO:<%s>"
816 776 (smtpmail-maybe-append-domain
817 (setq response-code (smtpmail-read-response process)) 777 (nth n recipient))))
818 (if (or (null (car response-code)) 778 (cond
819 (not (integerp (car response-code))) 779 ((smtpmail-ok-p (setq result (smtpmail-read-response process)))
820 (>= (car response-code) 400)) 780 ;; Success.
821 (throw 'done nil)))) 781 nil)
822 782 ((and auth-mechanisms
823 ;; DATA 783 (not ask-for-password)
824 (smtpmail-send-command process "DATA") 784 (= (car result) 550))
825 785 ;; We got a "550 relay not permitted", and the server
826 (if (or (null (car (setq response-code (smtpmail-read-response process)))) 786 ;; accepts credentials, so we try again, but ask for a
827 (not (integerp (car response-code))) 787 ;; password first.
828 (>= (car response-code) 400)) 788 (smtpmail-send-command process "QUIT")
829 (throw 'done nil)) 789 (smtpmail-read-response process)
830 790 (delete-process process)
831 ;; Mail contents 791 (setq process nil)
792 (throw 'done
793 (smtpmail-via-smtp recipient smtpmail-text-buffer t)))
794 (t
795 ;; Return the error code.
796 (throw 'done
797 (smtpmail-response-text result))))
798 (setq n (1+ n))))
799
800 ;; Send the contents.
801 (smtpmail-command-or-throw process "DATA")
832 (smtpmail-send-data process smtpmail-text-buffer) 802 (smtpmail-send-data process smtpmail-text-buffer)
833
834 ;; DATA end "." 803 ;; DATA end "."
835 (smtpmail-send-command process ".") 804 (smtpmail-command-or-throw process ".")
836 805 ;; Return success.
837 (if (or (null (car (setq response-code (smtpmail-read-response process)))) 806 nil))
838 (not (integerp (car response-code))) 807 (when (and process
839 (>= (car response-code) 400)) 808 (buffer-live-p process-buffer))
840 (throw 'done nil)) 809 (with-current-buffer (process-buffer process)
841 810 (smtpmail-send-command process "QUIT")
842 ;; QUIT 811 (smtpmail-read-response process)
843 ;; (smtpmail-send-command process "QUIT") 812 (delete-process process)
844 ;; (and (null (car (smtpmail-read-response process))) 813 (unless smtpmail-debug-info
845 ;; (throw 'done nil)) 814 (kill-buffer process-buffer)))))))
846 t))
847 (if process
848 (with-current-buffer (process-buffer process)
849 (smtpmail-send-command process "QUIT")
850 (smtpmail-read-response process)
851
852 ;; (if (or (null (car (setq response-code (smtpmail-read-response process))))
853 ;; (not (integerp (car response-code)))
854 ;; (>= (car response-code) 400))
855 ;; (throw 'done nil))
856 (delete-process process)
857 (unless smtpmail-debug-info
858 (kill-buffer process-buffer)))))))
859 815
860 816
861(defun smtpmail-process-filter (process output) 817(defun smtpmail-process-filter (process output)
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 343a9c6dd0c..437bd523841 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -1977,6 +1977,10 @@ Buffers menu is regenerated."
1977;; Used to cache the menu entries for commands in the Buffers menu 1977;; Used to cache the menu entries for commands in the Buffers menu
1978(defvar menu-bar-buffers-menu-command-entries nil) 1978(defvar menu-bar-buffers-menu-command-entries nil)
1979 1979
1980(defvar menu-bar-select-buffer-function 'switch-to-buffer
1981 "Function to select the buffer chosen from the `Buffers' menu-bar menu.
1982It must accept a buffer as its only required argument.")
1983
1980(defun menu-bar-update-buffers (&optional force) 1984(defun menu-bar-update-buffers (&optional force)
1981 ;; If user discards the Buffers item, play along. 1985 ;; If user discards the Buffers item, play along.
1982 (and (lookup-key (current-global-map) [menu-bar buffer]) 1986 (and (lookup-key (current-global-map) [menu-bar buffer])
@@ -2022,7 +2026,7 @@ Buffers menu is regenerated."
2022 (cons nil nil)) 2026 (cons nil nil))
2023 `(lambda () 2027 `(lambda ()
2024 (interactive) 2028 (interactive)
2025 (switch-to-buffer ,(cdr pair)))))) 2029 (funcall menu-bar-select-buffer-function ,(cdr pair))))))
2026 (list buffers-vec)))) 2030 (list buffers-vec))))
2027 2031
2028 ;; Make a Frames menu if we have more than one frame. 2032 ;; Make a Frames menu if we have more than one frame.
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 03e8225f0c5..a7ffc8d061a 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -135,7 +135,8 @@ The metadata of a completion table should be constant between two boundaries."
135 (let ((metadata (if (functionp table) 135 (let ((metadata (if (functionp table)
136 (funcall table string pred 'metadata)))) 136 (funcall table string pred 'metadata))))
137 (if (eq (car-safe metadata) 'metadata) 137 (if (eq (car-safe metadata) 'metadata)
138 (cdr metadata)))) 138 metadata
139 '(metadata))))
139 140
140(defun completion--field-metadata (field-start) 141(defun completion--field-metadata (field-start)
141 (completion-metadata (buffer-substring-no-properties field-start (point)) 142 (completion-metadata (buffer-substring-no-properties field-start (point))
@@ -513,7 +514,7 @@ an association list that can specify properties such as:
513 (delete-dups (append (cdr over) (copy-sequence completion-styles))) 514 (delete-dups (append (cdr over) (copy-sequence completion-styles)))
514 completion-styles))) 515 completion-styles)))
515 516
516(defun completion-try-completion (string table pred point metadata) 517(defun completion-try-completion (string table pred point &optional metadata)
517 "Try to complete STRING using completion table TABLE. 518 "Try to complete STRING using completion table TABLE.
518Only the elements of table that satisfy predicate PRED are considered. 519Only the elements of table that satisfy predicate PRED are considered.
519POINT is the position of point within STRING. 520POINT is the position of point within STRING.
@@ -524,9 +525,12 @@ a new position for point."
524 (completion--some (lambda (style) 525 (completion--some (lambda (style)
525 (funcall (nth 1 (assq style completion-styles-alist)) 526 (funcall (nth 1 (assq style completion-styles-alist))
526 string table pred point)) 527 string table pred point))
527 (completion--styles metadata))) 528 (completion--styles (or metadata
529 (completion-metadata
530 (substring string 0 point)
531 table pred)))))
528 532
529(defun completion-all-completions (string table pred point metadata) 533(defun completion-all-completions (string table pred point &optional metadata)
530 "List the possible completions of STRING in completion table TABLE. 534 "List the possible completions of STRING in completion table TABLE.
531Only the elements of table that satisfy predicate PRED are considered. 535Only the elements of table that satisfy predicate PRED are considered.
532POINT is the position of point within STRING. 536POINT is the position of point within STRING.
@@ -537,7 +541,10 @@ in the last `cdr'."
537 (completion--some (lambda (style) 541 (completion--some (lambda (style)
538 (funcall (nth 2 (assq style completion-styles-alist)) 542 (funcall (nth 2 (assq style completion-styles-alist))
539 string table pred point)) 543 string table pred point))
540 (completion--styles metadata))) 544 (completion--styles (or metadata
545 (completion-metadata
546 (substring string 0 point)
547 table pred)))))
541 548
542(defun minibuffer--bitset (modified completions exact) 549(defun minibuffer--bitset (modified completions exact)
543 (logior (if modified 4 0) 550 (logior (if modified 4 0)
diff --git a/lisp/misc.el b/lisp/misc.el
index e50b5b38c75..8087c7f5259 100644
--- a/lisp/misc.el
+++ b/lisp/misc.el
@@ -151,6 +151,7 @@ Internal use only."
151 (vector (list "Library" (1+ max-id-len) t) 151 (vector (list "Library" (1+ max-id-len) t)
152 (list "Loaded from" (1+ max-name-len) t) 152 (list "Loaded from" (1+ max-name-len) t)
153 (list "Candidate names" 0 t)))) 153 (list "Candidate names" 0 t))))
154 (tabulated-list-init-header)
154 (setq tabulated-list-entries nil) 155 (setq tabulated-list-entries nil)
155 (dolist (lib dynamic-library-alist) 156 (dolist (lib dynamic-library-alist)
156 (let* ((id (car lib)) 157 (let* ((id (car lib))
@@ -178,7 +179,6 @@ The return value is always nil."
178 (tabulated-list-mode) 179 (tabulated-list-mode)
179 (setq tabulated-list-sort-key (cons "Library" nil)) 180 (setq tabulated-list-sort-key (cons "Library" nil))
180 (add-hook 'tabulated-list-revert-hook 'list-dynamic-libraries--refresh nil t) 181 (add-hook 'tabulated-list-revert-hook 'list-dynamic-libraries--refresh nil t)
181 (tabulated-list-init-header)
182 (setq list-dynamic-libraries--loaded-only-p loaded-only-p) 182 (setq list-dynamic-libraries--loaded-only-p loaded-only-p)
183 (list-dynamic-libraries--refresh) 183 (list-dynamic-libraries--refresh)
184 (tabulated-list-print)) 184 (tabulated-list-print))
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index c1ec3f0ed13..d9e6827d2df 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -958,7 +958,7 @@ Galeon, Konqueror, Netscape, Mosaic, Lynx in an xterm, and then W3."
958;;;###autoload 958;;;###autoload
959(defun browse-url-xdg-open (url &optional new-window) 959(defun browse-url-xdg-open (url &optional new-window)
960 (interactive (browse-url-interactive-arg "URL: ")) 960 (interactive (browse-url-interactive-arg "URL: "))
961 (call-process "nohup" nil nil nil "xdg-open" url)) 961 (call-process "xdg-open" nil 0 nil url))
962 962
963;;;###autoload 963;;;###autoload
964(defun browse-url-netscape (url &optional new-window) 964(defun browse-url-netscape (url &optional new-window)
diff --git a/lisp/net/network-stream.el b/lisp/net/network-stream.el
index b17b9ae805c..161d7252d6e 100644
--- a/lisp/net/network-stream.el
+++ b/lisp/net/network-stream.el
@@ -44,6 +44,7 @@
44 44
45(require 'tls) 45(require 'tls)
46(require 'starttls) 46(require 'starttls)
47(require 'auth-source)
47 48
48(declare-function gnutls-negotiate "gnutls" t t) ; defun* 49(declare-function gnutls-negotiate "gnutls" t t) ; defun*
49 50
@@ -110,10 +111,21 @@ values:
110 STARTTLS if the server supports STARTTLS, and nil otherwise. 111 STARTTLS if the server supports STARTTLS, and nil otherwise.
111 112
112:always-query-capabilies says whether to query the server for 113:always-query-capabilies says whether to query the server for
113capabilities, even if we're doing a `plain' network connection. 114 capabilities, even if we're doing a `plain' network connection.
115
116:client-certificate should either be a list where the first
117 element is the certificate key file name, and the second
118 element is the certificate file name itself, or `t', which
119 means that `auth-source' will be queried for the key and the
120 certificate. This parameter will only be used when doing TLS
121 or STARTTLS connections.
122
123If :use-starttls-if-possible is non-nil, do opportunistic
124STARTTLS upgrades even if Emacs doesn't have built-in TLS
125functionality.
114 126
115:nowait is a boolean that says the connection should be made 127:nowait is a boolean that says the connection should be made
116asynchronously, if possible." 128 asynchronously, if possible."
117 (unless (featurep 'make-network-process) 129 (unless (featurep 'make-network-process)
118 (error "Emacs was compiled without networking support")) 130 (error "Emacs was compiled without networking support"))
119 (let ((type (plist-get parameters :type)) 131 (let ((type (plist-get parameters :type))
@@ -152,6 +164,22 @@ asynchronously, if possible."
152 :type (nth 3 result)) 164 :type (nth 3 result))
153 (car result)))))) 165 (car result))))))
154 166
167(defun network-stream-certificate (host service parameters)
168 (let ((spec (plist-get :client-certificate parameters)))
169 (cond
170 ((listp spec)
171 ;; Either nil or a list with a key/certificate pair.
172 spec)
173 ((eq spec t)
174 (let* ((auth-info
175 (car (auth-source-search :max 1
176 :host host
177 :port service)))
178 (key (plist-get auth-info :key))
179 (cert (plist-get auth-info :cert)))
180 (and key cert
181 (list key cert)))))))
182
155;;;###autoload 183;;;###autoload
156(defalias 'open-protocol-stream 'open-network-stream) 184(defalias 'open-protocol-stream 'open-network-stream)
157 185
@@ -184,7 +212,8 @@ asynchronously, if possible."
184 ;; If we have built-in STARTTLS support, try to upgrade the 212 ;; If we have built-in STARTTLS support, try to upgrade the
185 ;; connection. 213 ;; connection.
186 (when (and (or (fboundp 'open-gnutls-stream) 214 (when (and (or (fboundp 'open-gnutls-stream)
187 (and require-tls 215 (and (or require-tls
216 (plist-get parameters :use-starttls-if-possible))
188 (executable-find "gnutls-cli"))) 217 (executable-find "gnutls-cli")))
189 capabilities success-string starttls-function 218 capabilities success-string starttls-function
190 (setq starttls-command 219 (setq starttls-command
@@ -201,14 +230,28 @@ asynchronously, if possible."
201 starttls-extra-arguments 230 starttls-extra-arguments
202 ;; For opportunistic TLS upgrades, we don't really 231 ;; For opportunistic TLS upgrades, we don't really
203 ;; care about the identity of the peer. 232 ;; care about the identity of the peer.
204 (cons "--insecure" starttls-extra-arguments)))) 233 (cons "--insecure" starttls-extra-arguments)))
234 (cert (network-stream-certificate host service parameters)))
235 ;; There are client certificates requested, so add them to
236 ;; the command line.
237 (when cert
238 (setq starttls-extra-arguments
239 (nconc (list "--x509keyfile" (expand-file-name (nth 0 cert))
240 "--x509certfile" (expand-file-name (nth 1 cert)))
241 starttls-extra-arguments)))
205 (setq stream (starttls-open-stream name buffer host service))) 242 (setq stream (starttls-open-stream name buffer host service)))
206 (network-stream-get-response stream start eoc)) 243 (network-stream-get-response stream start eoc))
244 ;; Requery capabilities for protocols that require it; i.e.,
245 ;; EHLO for SMTP.
246 (when (plist-get parameters :always-query-capabilities)
247 (network-stream-command stream capability-command eoc))
207 (when (string-match success-string 248 (when (string-match success-string
208 (network-stream-command stream starttls-command eoc)) 249 (network-stream-command stream starttls-command eoc))
209 ;; The server said it was OK to begin STARTTLS negotiations. 250 ;; The server said it was OK to begin STARTTLS negotiations.
210 (if (fboundp 'open-gnutls-stream) 251 (if (fboundp 'open-gnutls-stream)
211 (gnutls-negotiate :process stream :hostname host) 252 (let ((cert (network-stream-certificate host service parameters)))
253 (gnutls-negotiate :process stream :hostname host
254 :keylist (and cert (list cert))))
212 (unless (starttls-negotiate stream) 255 (unless (starttls-negotiate stream)
213 (delete-process stream))) 256 (delete-process stream)))
214 (if (memq (process-status stream) '(open run)) 257 (if (memq (process-status stream) '(open run))
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 70190867e89..f7f5f61fafe 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -987,7 +987,7 @@ This number is independent of the number of lines in the buffer.")
987 (setq buffer-invisibility-spec '()) 987 (setq buffer-invisibility-spec '())
988 (setq buffer-display-table (make-display-table)) 988 (setq buffer-display-table (make-display-table))
989 (set-display-table-slot buffer-display-table 4 989 (set-display-table-slot buffer-display-table 4
990 (let ((glyph (make-glyph-code 990 (let ((glyph (make-glyph-code
991 ?. 'font-lock-keyword-face))) 991 ?. 'font-lock-keyword-face)))
992 (make-vector 3 glyph))) 992 (make-vector 3 glyph)))
993 993
@@ -1151,7 +1151,7 @@ Create the buffer if it doesn't exist."
1151 (rcirc-generate-new-buffer-name process target)))) 1151 (rcirc-generate-new-buffer-name process target))))
1152 (with-current-buffer new-buffer 1152 (with-current-buffer new-buffer
1153 (rcirc-mode process target) 1153 (rcirc-mode process target)
1154 (rcirc-put-nick-channel process (rcirc-nick process) target 1154 (rcirc-put-nick-channel process (rcirc-nick process) target
1155 rcirc-current-line)) 1155 rcirc-current-line))
1156 new-buffer))))) 1156 new-buffer)))))
1157 1157
@@ -1238,7 +1238,7 @@ Create the buffer if it doesn't exist."
1238 (interactive) 1238 (interactive)
1239 (let ((pos (1+ (- (point) rcirc-prompt-end-marker)))) 1239 (let ((pos (1+ (- (point) rcirc-prompt-end-marker))))
1240 (goto-char (point-max)) 1240 (goto-char (point-max))
1241 (let ((text (buffer-substring-no-properties rcirc-prompt-end-marker 1241 (let ((text (buffer-substring-no-properties rcirc-prompt-end-marker
1242 (point))) 1242 (point)))
1243 (parent (buffer-name))) 1243 (parent (buffer-name)))
1244 (delete-region rcirc-prompt-end-marker (point)) 1244 (delete-region rcirc-prompt-end-marker (point))
@@ -1477,7 +1477,7 @@ record activity."
1477 (match-string 1 text))) 1477 (match-string 1 text)))
1478 rcirc-ignore-list)) 1478 rcirc-ignore-list))
1479 ;; do not ignore if we sent the message 1479 ;; do not ignore if we sent the message
1480 (not (string= sender (rcirc-nick process)))) 1480 (not (string= sender (rcirc-nick process))))
1481 (let* ((buffer (rcirc-target-buffer process sender response target text)) 1481 (let* ((buffer (rcirc-target-buffer process sender response target text))
1482 (inhibit-read-only t)) 1482 (inhibit-read-only t))
1483 (with-current-buffer buffer 1483 (with-current-buffer buffer
@@ -1655,8 +1655,8 @@ log-files with absolute names (see `rcirc-log-filename-function')."
1655(defun rcirc-view-log-file () 1655(defun rcirc-view-log-file ()
1656 "View logfile corresponding to the current buffer." 1656 "View logfile corresponding to the current buffer."
1657 (interactive) 1657 (interactive)
1658 (find-file-other-window 1658 (find-file-other-window
1659 (expand-file-name (funcall rcirc-log-filename-function 1659 (expand-file-name (funcall rcirc-log-filename-function
1660 (rcirc-buffer-process) rcirc-target) 1660 (rcirc-buffer-process) rcirc-target)
1661 rcirc-log-directory))) 1661 rcirc-log-directory)))
1662 1662
@@ -2446,7 +2446,7 @@ keywords when no KEYWORD is given."
2446 rcirc-fill-column) 2446 rcirc-fill-column)
2447 (t fill-column)) 2447 (t fill-column))
2448 ;; make sure ... doesn't cause line wrapping 2448 ;; make sure ... doesn't cause line wrapping
2449 3))) 2449 3)))
2450 (fill-region (point) (point-max) nil t)))) 2450 (fill-region (point) (point-max) nil t))))
2451 2451
2452;;; handlers 2452;;; handlers
@@ -2813,7 +2813,7 @@ Passwords are stored in `rcirc-authinfo' (which see)."
2813 ;; quakenet authentication doesn't rely on the user's nickname. 2813 ;; quakenet authentication doesn't rely on the user's nickname.
2814 ;; the variable `nick' here represents the Q account name. 2814 ;; the variable `nick' here represents the Q account name.
2815 (when (eq method 'quakenet) 2815 (when (eq method 'quakenet)
2816 (rcirc-send-privmsg 2816 (rcirc-send-privmsg
2817 process 2817 process
2818 "Q@CServe.quakenet.org" 2818 "Q@CServe.quakenet.org"
2819 (format "AUTH %s %s" nick (car args)))))))))) 2819 (format "AUTH %s %s" nick (car args))))))))))
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index e3e6264b28f..9397025cb60 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -177,9 +177,9 @@ Remove also properties of all files in subdirectories."
177 (tramp-message vec 8 "%s" directory) 177 (tramp-message vec 8 "%s" directory)
178 (maphash 178 (maphash
179 (lambda (key value) 179 (lambda (key value)
180 (when (and (stringp (tramp-file-name-localname key)) 180 (when (and (stringp (tramp-file-name-localname key))
181 (string-match directory (tramp-file-name-localname key))) 181 (string-match directory (tramp-file-name-localname key)))
182 (remhash key tramp-cache-data))) 182 (remhash key tramp-cache-data)))
183 tramp-cache-data))) 183 tramp-cache-data)))
184 184
185;; Reverting or killing a buffer should also flush file properties. 185;; Reverting or killing a buffer should also flush file properties.
@@ -200,12 +200,12 @@ Remove also properties of all files in subdirectories."
200(add-hook 'kill-buffer-hook 'tramp-flush-file-function) 200(add-hook 'kill-buffer-hook 'tramp-flush-file-function)
201(add-hook 'tramp-cache-unload-hook 201(add-hook 'tramp-cache-unload-hook
202 (lambda () 202 (lambda ()
203 (remove-hook 'before-revert-hook 203 (remove-hook 'before-revert-hook
204 'tramp-flush-file-function) 204 'tramp-flush-file-function)
205 (remove-hook 'eshell-pre-command-hook 205 (remove-hook 'eshell-pre-command-hook
206 'tramp-flush-file-function) 206 'tramp-flush-file-function)
207 (remove-hook 'kill-buffer-hook 207 (remove-hook 'kill-buffer-hook
208 'tramp-flush-file-function))) 208 'tramp-flush-file-function)))
209 209
210;;; -- Properties -- 210;;; -- Properties --
211 211
@@ -290,17 +290,17 @@ KEY identifies the connection, it is either a process or a vector."
290 (let (result) 290 (let (result)
291 (maphash 291 (maphash
292 (lambda (key value) 292 (lambda (key value)
293 (let ((tmp (format 293 (let ((tmp (format
294 "(%s %s)" 294 "(%s %s)"
295 (if (processp key) 295 (if (processp key)
296 (prin1-to-string (prin1-to-string key)) 296 (prin1-to-string (prin1-to-string key))
297 (prin1-to-string key)) 297 (prin1-to-string key))
298 (if (hash-table-p value) 298 (if (hash-table-p value)
299 (tramp-cache-print value) 299 (tramp-cache-print value)
300 (if (bufferp value) 300 (if (bufferp value)
301 (prin1-to-string (prin1-to-string value)) 301 (prin1-to-string (prin1-to-string value))
302 (prin1-to-string value)))))) 302 (prin1-to-string value))))))
303 (setq result (if result (concat result " " tmp) tmp)))) 303 (setq result (if result (concat result " " tmp) tmp))))
304 table) 304 table)
305 result))) 305 result)))
306 306
@@ -310,8 +310,8 @@ KEY identifies the connection, it is either a process or a vector."
310 (let (result) 310 (let (result)
311 (maphash 311 (maphash
312 (lambda (key value) 312 (lambda (key value)
313 (when (and (vectorp key) (null (aref key 3))) 313 (when (and (vectorp key) (null (aref key 3)))
314 (add-to-list 'result key))) 314 (add-to-list 'result key)))
315 tramp-cache-data) 315 tramp-cache-data)
316 result)) 316 result))
317 317
@@ -327,12 +327,12 @@ KEY identifies the connection, it is either a process or a vector."
327 ;; Remove temporary data. 327 ;; Remove temporary data.
328 (maphash 328 (maphash
329 (lambda (key value) 329 (lambda (key value)
330 (if (and (vectorp key) (not (tramp-file-name-localname key))) 330 (if (and (vectorp key) (not (tramp-file-name-localname key)))
331 (progn 331 (progn
332 (remhash "process-name" value) 332 (remhash "process-name" value)
333 (remhash "process-buffer" value) 333 (remhash "process-buffer" value)
334 (remhash "first-password-request" value)) 334 (remhash "first-password-request" value))
335 (remhash key cache))) 335 (remhash key cache)))
336 cache) 336 cache)
337 ;; Dump it. 337 ;; Dump it.
338 (with-temp-buffer 338 (with-temp-buffer
@@ -357,8 +357,8 @@ KEY identifies the connection, it is either a process or a vector."
357 (add-hook 'kill-emacs-hook 'tramp-dump-connection-properties)) 357 (add-hook 'kill-emacs-hook 'tramp-dump-connection-properties))
358(add-hook 'tramp-cache-unload-hook 358(add-hook 'tramp-cache-unload-hook
359 (lambda () 359 (lambda ()
360 (remove-hook 'kill-emacs-hook 360 (remove-hook 'kill-emacs-hook
361 'tramp-dump-connection-properties))) 361 'tramp-dump-connection-properties)))
362 362
363;;;###tramp-autoload 363;;;###tramp-autoload
364(defun tramp-parse-connection-properties (method) 364(defun tramp-parse-connection-properties (method)
@@ -368,18 +368,22 @@ for all methods. Resulting data are derived from connection history."
368 (let (res) 368 (let (res)
369 (maphash 369 (maphash
370 (lambda (key value) 370 (lambda (key value)
371 (if (and (vectorp key) 371 (if (and (vectorp key)
372 (string-equal method (tramp-file-name-method key)) 372 (string-equal method (tramp-file-name-method key))
373 (not (tramp-file-name-localname key))) 373 (not (tramp-file-name-localname key)))
374 (push (list (tramp-file-name-user key) 374 (push (list (tramp-file-name-user key)
375 (tramp-file-name-host key)) 375 (tramp-file-name-host key))
376 res))) 376 res)))
377 tramp-cache-data) 377 tramp-cache-data)
378 res)) 378 res))
379 379
380;; Read persistent connection history. 380;; Read persistent connection history.
381(when (and (stringp tramp-persistency-file-name) 381(when (and (stringp tramp-persistency-file-name)
382 (zerop (hash-table-count tramp-cache-data))) 382 (zerop (hash-table-count tramp-cache-data))
383 ;; When "emacs -Q" has been called, both variables are nil.
384 ;; We do not load the persistency file then, in order to
385 ;; have a clean test environment.
386 (or init-file-user site-run-file))
383 (condition-case err 387 (condition-case err
384 (with-temp-buffer 388 (with-temp-buffer
385 (insert-file-contents tramp-persistency-file-name) 389 (insert-file-contents tramp-persistency-file-name)
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 932436df8c9..46a82e3720d 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -1,4 +1,4 @@
1;;; pcomplete.el --- programmable completion 1;;; pcomplete.el --- programmable completion -*- lexical-binding: t -*-
2 2
3;; Copyright (C) 1999-2011 Free Software Foundation, Inc. 3;; Copyright (C) 1999-2011 Free Software Foundation, Inc.
4 4
@@ -154,6 +154,7 @@ This mirrors the optional behavior of tcsh."
154 "A list of characters which constitute a proper suffix." 154 "A list of characters which constitute a proper suffix."
155 :type '(repeat character) 155 :type '(repeat character)
156 :group 'pcomplete) 156 :group 'pcomplete)
157(make-obsolete-variable 'pcomplete-suffix-list nil "24.1")
157 158
158(defcustom pcomplete-recexact nil 159(defcustom pcomplete-recexact nil
159 "If non-nil, use shortest completion if characters cannot be added. 160 "If non-nil, use shortest completion if characters cannot be added.
@@ -501,18 +502,16 @@ Same as `pcomplete' but using the standard completion UI."
501 ;; practice it should work just fine (fingers crossed). 502 ;; practice it should work just fine (fingers crossed).
502 (let ((prefixes (pcomplete--common-quoted-suffix 503 (let ((prefixes (pcomplete--common-quoted-suffix
503 pcomplete-stub buftext))) 504 pcomplete-stub buftext)))
504 (apply-partially 505 (apply-partially #'pcomplete--table-subvert
505 'pcomplete--table-subvert 506 completions
506 completions 507 (cdr prefixes) (car prefixes))))
507 (cdr prefixes) (car prefixes))))
508 (t 508 (t
509 (lexical-let ((completions completions)) 509 (lambda (string pred action)
510 (lambda (string pred action) 510 (let ((res (complete-with-action
511 (let ((res (complete-with-action 511 action completions string pred)))
512 action completions string pred))) 512 (if (stringp res)
513 (if (stringp res) 513 (pcomplete-quote-argument res)
514 (pcomplete-quote-argument res) 514 res))))))
515 res)))))))
516 (pred 515 (pred
517 ;; Pare it down, if applicable. 516 ;; Pare it down, if applicable.
518 (when (and pcomplete-use-paring pcomplete-seen) 517 (when (and pcomplete-use-paring pcomplete-seen)
@@ -521,12 +520,13 @@ Same as `pcomplete' but using the standard completion UI."
521 (funcall pcomplete-norm-func 520 (funcall pcomplete-norm-func
522 (directory-file-name f))) 521 (directory-file-name f)))
523 pcomplete-seen)) 522 pcomplete-seen))
524 (lambda (f) 523 ;; Capture the dynbound values for later use.
525 (not (when pcomplete-seen 524 (let ((norm-func pcomplete-norm-func)
526 (member 525 (seen pcomplete-seen))
527 (funcall pcomplete-norm-func 526 (lambda (f)
528 (directory-file-name f)) 527 (not (member
529 pcomplete-seen))))))) 528 (funcall norm-func (directory-file-name f))
529 seen)))))))
530 (when pcomplete-ignore-case 530 (when pcomplete-ignore-case
531 (setq table 531 (setq table
532 (apply-partially #'completion-table-case-fold table))) 532 (apply-partially #'completion-table-case-fold table)))
@@ -780,6 +780,8 @@ dynamic-complete-functions are kept. For comint mode itself,
780this is `comint-dynamic-complete-functions'." 780this is `comint-dynamic-complete-functions'."
781 (set (make-local-variable 'pcomplete-parse-arguments-function) 781 (set (make-local-variable 'pcomplete-parse-arguments-function)
782 'pcomplete-parse-comint-arguments) 782 'pcomplete-parse-comint-arguments)
783 (add-hook 'completion-at-point-functions
784 'pcomplete-completions-at-point nil 'local)
783 (set (make-local-variable completef-sym) 785 (set (make-local-variable completef-sym)
784 (copy-sequence (symbol-value completef-sym))) 786 (copy-sequence (symbol-value completef-sym)))
785 (let* ((funs (symbol-value completef-sym)) 787 (let* ((funs (symbol-value completef-sym))
@@ -887,15 +889,46 @@ Magic characters are those in `pcomplete-arg-quote-list'."
887 889
888(defsubst pcomplete-dirs-or-entries (&optional regexp predicate) 890(defsubst pcomplete-dirs-or-entries (&optional regexp predicate)
889 "Return either directories, or qualified entries." 891 "Return either directories, or qualified entries."
890 ;; FIXME: pcomplete-entries doesn't return a list any more.
891 (pcomplete-entries 892 (pcomplete-entries
892 nil 893 nil
893 (lexical-let ((re regexp) 894 (lambda (f)
894 (pred predicate)) 895 (or (file-directory-p f)
895 (lambda (f) 896 (and (or (null regexp) (string-match regexp f))
896 (or (file-directory-p f) 897 (or (null predicate) (funcall predicate f)))))))
897 (and (if (not re) t (string-match re f)) 898
898 (if (not pred) t (funcall pred f)))))))) 899(defun pcomplete--entries (&optional regexp predicate)
900 "Like `pcomplete-entries' but without env-var handling."
901 (let* ((ign-pred
902 (when (or pcomplete-file-ignore pcomplete-dir-ignore)
903 ;; Capture the dynbound value for later use.
904 (let ((file-ignore pcomplete-file-ignore)
905 (dir-ignore pcomplete-dir-ignore))
906 (lambda (file)
907 (not
908 (if (eq (aref file (1- (length file))) ?/)
909 (and dir-ignore (string-match dir-ignore file))
910 (and file-ignore (string-match file-ignore file))))))))
911 (reg-pred (if regexp (lambda (file) (string-match regexp file))))
912 (pred (cond
913 ((null (or ign-pred reg-pred)) predicate)
914 ((null (or ign-pred predicate)) reg-pred)
915 ((null (or reg-pred predicate)) ign-pred)
916 (t (lambda (f)
917 (and (or (null reg-pred) (funcall reg-pred f))
918 (or (null ign-pred) (funcall ign-pred f))
919 (or (null predicate) (funcall predicate f))))))))
920 (lambda (s p a)
921 (if (and (eq a 'metadata) pcomplete-compare-entry-function)
922 `(metadata (cycle-sort-function
923 . ,(lambda (comps)
924 (sort comps pcomplete-compare-entry-function)))
925 ,@(cdr (completion-file-name-table s p a)))
926 (let ((completion-ignored-extensions nil))
927 (completion-table-with-predicate
928 'completion-file-name-table pred 'strict s p a))))))
929
930(defconst pcomplete--env-regexp
931 "\\(?:\\`\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(\\$\\(?:{\\([^}]+\\)}\\|\\(?2:[[:alnum:]_]+\\)\\)\\)")
899 932
900(defun pcomplete-entries (&optional regexp predicate) 933(defun pcomplete-entries (&optional regexp predicate)
901 "Complete against a list of directory candidates. 934 "Complete against a list of directory candidates.
@@ -905,65 +938,48 @@ If PREDICATE is non-nil, it will also be used to refine the match
905\(files for which the PREDICATE returns nil will be excluded). 938\(files for which the PREDICATE returns nil will be excluded).
906If no directory information can be extracted from the completed 939If no directory information can be extracted from the completed
907component, `default-directory' is used as the basis for completion." 940component, `default-directory' is used as the basis for completion."
908 (let* ((name (substitute-env-vars pcomplete-stub)) 941 ;; FIXME: The old code did env-var expansion here, so we reproduce this
909 (completion-ignore-case pcomplete-ignore-case) 942 ;; behavior for now, but really env-var handling should be performed globally
910 (default-directory (expand-file-name 943 ;; rather than here since it also applies to non-file arguments.
911 (or (file-name-directory name) 944 (let ((table (pcomplete--entries regexp predicate)))
912 default-directory))) 945 (lambda (string pred action)
913 above-cutoff) 946 (let ((strings nil)
914 (setq name (file-name-nondirectory name) 947 (orig-length (length string)))
915 pcomplete-stub name) 948 ;; Perform env-var expansion.
916 (let ((completions 949 (while (string-match pcomplete--env-regexp string)
917 (file-name-all-completions name default-directory))) 950 (push (substring string 0 (match-beginning 1)) strings)
918 (if regexp 951 (push (getenv (match-string 2 string)) strings)
919 (setq completions 952 (setq string (substring string (match-end 1))))
920 (pcomplete-pare-list 953 (if (not (and strings
921 completions nil 954 (or (eq action t)
922 (function 955 (eq (car-safe action) 'boundaries))))
923 (lambda (file) 956 (let ((newstring
924 (not (string-match regexp file))))))) 957 (mapconcat 'identity (nreverse (cons string strings)) "")))
925 (if predicate 958 ;; FIXME: We could also try to return unexpanded envvars.
926 (setq completions 959 (complete-with-action action table newstring pred))
927 (pcomplete-pare-list 960 (let* ((envpos (apply #'+ (mapcar #' length strings)))
928 completions nil 961 (newstring
929 (function 962 (mapconcat 'identity (nreverse (cons string strings)) ""))
930 (lambda (file) 963 (bounds (completion-boundaries newstring table pred
931 (not (funcall predicate file))))))) 964 (or (cdr-safe action) ""))))
932 (if (or pcomplete-file-ignore pcomplete-dir-ignore) 965 (if (>= (car bounds) envpos)
933 (setq completions 966 ;; The env-var is "out of bounds".
934 (pcomplete-pare-list 967 (if (eq action t)
935 completions nil 968 (complete-with-action action table newstring pred)
936 (function 969 (list* 'boundaries
937 (lambda (file) 970 (+ (car bounds) (- orig-length (length newstring)))
938 (if (eq (aref file (1- (length file))) 971 (cdr bounds)))
939 ?/) 972 ;; The env-var is in the file bounds.
940 (and pcomplete-dir-ignore 973 (if (eq action t)
941 (string-match pcomplete-dir-ignore file)) 974 (let ((comps (complete-with-action
942 (and pcomplete-file-ignore 975 action table newstring pred))
943 (string-match pcomplete-file-ignore file)))))))) 976 (len (- envpos (car bounds))))
944 (setq above-cutoff (and pcomplete-cycle-cutoff-length 977 ;; Strip the part of each completion that's actually
945 (> (length completions) 978 ;; coming from the env-var.
946 pcomplete-cycle-cutoff-length))) 979 (mapcar (lambda (s) (substring s len)) comps))
947 (sort completions 980 (list* 'boundaries
948 (function 981 (+ envpos (- orig-length (length newstring)))
949 (lambda (l r) 982 (cdr bounds))))))))))
950 ;; for the purposes of comparison, remove the
951 ;; trailing slash from directory names.
952 ;; Otherwise, "foo.old/" will come before "foo/",
953 ;; since . is earlier in the ASCII alphabet than
954 ;; /
955 (let ((left (if (eq (aref l (1- (length l)))
956 ?/)
957 (substring l 0 (1- (length l)))
958 l))
959 (right (if (eq (aref r (1- (length r)))
960 ?/)
961 (substring r 0 (1- (length r)))
962 r)))
963 (if above-cutoff
964 (string-lessp left right)
965 (funcall pcomplete-compare-entry-function
966 left right)))))))))
967 983
968(defsubst pcomplete-all-entries (&optional regexp predicate) 984(defsubst pcomplete-all-entries (&optional regexp predicate)
969 "Like `pcomplete-entries', but doesn't ignore any entries." 985 "Like `pcomplete-entries', but doesn't ignore any entries."
@@ -1343,25 +1359,6 @@ If specific documentation can't be given, be generic."
1343 1359
1344;; general utilities 1360;; general utilities
1345 1361
1346(defun pcomplete-pare-list (l r &optional pred)
1347 "Destructively remove from list L all elements matching any in list R.
1348Test is done using `equal'.
1349If PRED is non-nil, it is a function used for further removal.
1350Returns the resultant list."
1351 (while (and l (or (and r (member (car l) r))
1352 (and pred
1353 (funcall pred (car l)))))
1354 (setq l (cdr l)))
1355 (let ((m l))
1356 (while m
1357 (while (and (cdr m)
1358 (or (and r (member (cadr m) r))
1359 (and pred
1360 (funcall pred (cadr m)))))
1361 (setcdr m (cddr m)))
1362 (setq m (cdr m))))
1363 l)
1364
1365(defun pcomplete-uniqify-list (l) 1362(defun pcomplete-uniqify-list (l)
1366 "Sort and remove multiples in L." 1363 "Sort and remove multiples in L."
1367 (setq l (sort l 'string-lessp)) 1364 (setq l (sort l 'string-lessp))
diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el
index 5a8ff9d0f32..86e6b4abb6c 100644
--- a/lisp/play/5x5.el
+++ b/lisp/play/5x5.el
@@ -144,6 +144,8 @@
144 (define-key map [(control c) (control x)] #'5x5-crack-xor-mutate) 144 (define-key map [(control c) (control x)] #'5x5-crack-xor-mutate)
145 (define-key map "n" #'5x5-new-game) 145 (define-key map "n" #'5x5-new-game)
146 (define-key map "s" #'5x5-solve-suggest) 146 (define-key map "s" #'5x5-solve-suggest)
147 (define-key map "<" #'5x5-solve-rotate-left)
148 (define-key map ">" #'5x5-solve-rotate-right)
147 (define-key map "q" #'5x5-quit-game) 149 (define-key map "q" #'5x5-quit-game)
148 map) 150 map)
149 "Local keymap for the 5x5 game.") 151 "Local keymap for the 5x5 game.")
@@ -174,6 +176,9 @@ GRID is the grid of positions to click.")
174 ["Quit game" 5x5-quit-game t] 176 ["Quit game" 5x5-quit-game t]
175 "---" 177 "---"
176 ["Use Calc solver" 5x5-solve-suggest t] 178 ["Use Calc solver" 5x5-solve-suggest t]
179 ["Rotate left list of Calc solutions" 5x5-solve-rotate-left t]
180 ["Rotate right list of Calc solutions" 5x5-solve-rotate-right t]
181 "---"
177 ["Crack randomly" 5x5-crack-randomly t] 182 ["Crack randomly" 5x5-crack-randomly t]
178 ["Crack mutating current" 5x5-crack-mutating-current t] 183 ["Crack mutating current" 5x5-crack-mutating-current t]
179 ["Crack mutating best" 5x5-crack-mutating-best t] 184 ["Crack mutating best" 5x5-crack-mutating-best t]
@@ -207,18 +212,21 @@ squares you must fill the grid.
207 212
2085x5 keyboard bindings are: 2135x5 keyboard bindings are:
209\\<5x5-mode-map> 214\\<5x5-mode-map>
210Flip \\[5x5-flip-current] 215Flip \\[5x5-flip-current]
211Move up \\[5x5-up] 216Move up \\[5x5-up]
212Move down \\[5x5-down] 217Move down \\[5x5-down]
213Move left \\[5x5-left] 218Move left \\[5x5-left]
214Move right \\[5x5-right] 219Move right \\[5x5-right]
215Start new game \\[5x5-new-game] 220Start new game \\[5x5-new-game]
216New game with random grid \\[5x5-randomize] 221New game with random grid \\[5x5-randomize]
217Random cracker \\[5x5-crack-randomly] 222Random cracker \\[5x5-crack-randomly]
218Mutate current cracker \\[5x5-crack-mutating-current] 223Mutate current cracker \\[5x5-crack-mutating-current]
219Mutate best cracker \\[5x5-crack-mutating-best] 224Mutate best cracker \\[5x5-crack-mutating-best]
220Mutate xor cracker \\[5x5-crack-xor-mutate] 225Mutate xor cracker \\[5x5-crack-xor-mutate]
221Quit current game \\[5x5-quit-game]" 226Solve with Calc \\[5x5-solve-suggest]
227Rotate left Calc Solutions \\[5x5-solve-rotate-left]
228Rotate right Calc Solutions \\[5x5-solve-rotate-right]
229Quit current game \\[5x5-quit-game]"
222 230
223 (interactive "P") 231 (interactive "P")
224 (setq 5x5-cracking nil) 232 (setq 5x5-cracking nil)
@@ -331,9 +339,14 @@ Quit current game \\[5x5-quit-game]"
331 (forward-char (+ 1 (/ (1+ 5x5-x-scale) 2))) 339 (forward-char (+ 1 (/ (1+ 5x5-x-scale) 2)))
332 (dotimes (x 5x5-grid-size) 340 (dotimes (x 5x5-grid-size)
333 (when (5x5-cell solution-grid y x) 341 (when (5x5-cell solution-grid y x)
342 (if (= 0 (mod 5x5-x-scale 2))
343 (progn
344 (insert "()")
345 (delete-region (point) (+ (point) 2))
346 (backward-char 2))
334 (insert-char ?O 1) 347 (insert-char ?O 1)
335 (delete-char 1) 348 (delete-char 1)
336 (backward-char)) 349 (backward-char)))
337 (forward-char (1+ 5x5-x-scale)))) 350 (forward-char (1+ 5x5-x-scale))))
338 (forward-line 5x5-y-scale)))) 351 (forward-line 5x5-y-scale))))
339 (setq 5x5-solver-output nil))) 352 (setq 5x5-solver-output nil)))
@@ -790,6 +803,64 @@ Argument N is ignored."
790 (5x5-draw-grid (list 5x5-grid)) 803 (5x5-draw-grid (list 5x5-grid))
791 (5x5-position-cursor)) 804 (5x5-position-cursor))
792 805
806(defun 5x5-solve-rotate-left (&optional n)
807 "Rotate left by N the list of solutions in 5x5-solver-output.
808
809If N is not supplied rotate by 1, that is to say put the last
810element first in the list.
811
812The 5x5 game has in general several solutions. For grid size=5,
813there are 4 possible solutions. When function
814`5x5-solve-suggest' (press `\\[5x5-solve-suggest]') is called the
815solution that is presented is the one that needs least number of
816strokes --- other solutions can be viewed by rotating through the
817list. The list of solution is ordered by number of strokes, so
818rotating left just after calling `5x5-solve-suggest' will show
819the the solution with second least number of strokes, while
820rotating right will show the solution with greatest number of
821strokes."
822 (interactive "P")
823 (let ((len (length 5x5-solver-output)))
824 (when (>= len 3)
825 (setq n (if (integerp n) n 1)
826 n (mod n (1- len)))
827 (unless (eq n 0)
828 (setq n (- len n 1))
829 (let* ((p-tail (last 5x5-solver-output (1+ n)))
830 (tail (cdr p-tail))
831 (l-tail (last tail)))
832 ;;
833 ;; For n = 2:
834 ;;
835 ;; +--+--+ +--+--+ +--+--+ +--+--+ +--+--+
836 ;; |M | ---->|S1| ---->|S2| ---->|S3| ---->|S4| ----> nil
837 ;; +--+--+ +--+--+ +--+--+ +--+--+ +--+--+
838 ;; ^ ^ ^ ^
839 ;; | | | |
840 ;; + 5x5-solver-output | | + l-tail
841 ;; + p-tail |
842 ;; + tail
843 ;;
844 (setcdr l-tail (cdr 5x5-solver-output))
845 (setcdr 5x5-solver-output tail)
846 (unless (eq p-tail 5x5-solver-output)
847 (setcdr p-tail nil)))
848 (5x5-draw-grid (list 5x5-grid))
849 (5x5-position-cursor)))))
850
851(defun 5x5-solve-rotate-right (&optional n)
852 "Rotate right by N the list of solutions in 5x5-solver-output.
853If N is not supplied, rotate by 1. Similar to function
854`5x5-solve-rotate-left' except that rotation is right instead of
855lest."
856 (interactive "P")
857 (setq n
858 (if (integerp n) (- n)
859 -1))
860 (5x5-solve-rotate-left n))
861
862
863
793;; Keyboard response functions. 864;; Keyboard response functions.
794 865
795(defun 5x5-flip-current () 866(defun 5x5-flip-current ()
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index b8cac2fd331..1a23cd112af 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -155,8 +155,8 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
155\\([a-zA-Z]?:?[^:( \t\n]+\\)\ 155\\([a-zA-Z]?:?[^:( \t\n]+\\)\
156 \\([0-9]+\\)\\(?:[) \t]\\|:[^0-9\n]\\)" 2 3 nil (1)) 156 \\([0-9]+\\)\\(?:[) \t]\\|:[^0-9\n]\\)" 2 3 nil (1))
157 157
158 (caml 158 (python-tracebacks-and-caml
159 "^ *File \\(\"?\\)\\([^,\" \n\t<>]+\\)\\1, lines? \\([0-9]+\\)-?\\([0-9]+\\)?\\(?:$\\|,\ 159 "^[ \t]*File \\(\"?\\)\\([^,\" \n\t<>]+\\)\\1, lines? \\([0-9]+\\)-?\\([0-9]+\\)?\\(?:$\\|,\
160\\(?: characters? \\([0-9]+\\)-?\\([0-9]+\\)?:\\)?\\([ \n]Warning:\\)?\\)" 160\\(?: characters? \\([0-9]+\\)-?\\([0-9]+\\)?:\\)?\\([ \n]Warning:\\)?\\)"
161 2 (3 . 4) (5 . 6) (7)) 161 2 (3 . 4) (5 . 6) (7))
162 162
diff --git a/lisp/progmodes/delphi.el b/lisp/progmodes/delphi.el
index c809079381f..e8e2f8ffbf0 100644
--- a/lisp/progmodes/delphi.el
+++ b/lisp/progmodes/delphi.el
@@ -1959,12 +1959,12 @@ comment block. If not in a // comment, just does a normal newline."
1959 kmap) 1959 kmap)
1960 "Keymap used in Delphi mode.") 1960 "Keymap used in Delphi mode.")
1961 1961
1962(defconst delphi-mode-syntax-table (make-syntax-table) 1962(defvar delphi-mode-syntax-table nil
1963 "Delphi mode's syntax table. It is just a standard syntax table. 1963 "Delphi mode's syntax table. It is just a standard syntax table.
1964This is ok since we do our own keyword/comment/string face coloring.") 1964This is ok since we do our own keyword/comment/string face coloring.")
1965 1965
1966;;;###autoload 1966;;;###autoload
1967(defun delphi-mode (&optional skip-initial-parsing) 1967(define-derived-mode delphi-mode prog-mode "Delphi"
1968 "Major mode for editing Delphi code. \\<delphi-mode-map> 1968 "Major mode for editing Delphi code. \\<delphi-mode-map>
1969\\[delphi-tab]\t- Indents the current line (or region, if Transient Mark mode 1969\\[delphi-tab]\t- Indents the current line (or region, if Transient Mark mode
1970\t is enabled and the region is active) of Delphi code. 1970\t is enabled and the region is active) of Delphi code.
@@ -2007,14 +2007,6 @@ Coloring:
2007 2007
2008Turning on Delphi mode calls the value of the variable `delphi-mode-hook' 2008Turning on Delphi mode calls the value of the variable `delphi-mode-hook'
2009with no args, if that value is non-nil." 2009with no args, if that value is non-nil."
2010 (interactive)
2011 (kill-all-local-variables)
2012 (use-local-map delphi-mode-map)
2013 (setq major-mode 'delphi-mode) ;FIXME: Use define-derived-mode.
2014 (setq mode-name "Delphi")
2015
2016 (setq local-abbrev-table delphi-mode-abbrev-table)
2017 (set-syntax-table delphi-mode-syntax-table)
2018 2010
2019 ;; Buffer locals: 2011 ;; Buffer locals:
2020 (mapc #'(lambda (var) 2012 (mapc #'(lambda (var)
@@ -2033,12 +2025,12 @@ with no args, if that value is non-nil."
2033 (add-hook 'after-change-functions 'delphi-after-change nil t) 2025 (add-hook 'after-change-functions 'delphi-after-change nil t)
2034 2026
2035 (widen) 2027 (widen)
2036 (unless skip-initial-parsing 2028
2037 (delphi-save-excursion 2029 (delphi-save-excursion
2038 (let ((delphi-verbose t)) 2030 (let ((delphi-verbose t))
2039 (delphi-progress-start) 2031 (delphi-progress-start)
2040 (delphi-parse-region (point-min) (point-max)) 2032 (delphi-parse-region (point-min) (point-max))
2041 (delphi-progress-done)))) 2033 (delphi-progress-done)))
2042 2034
2043 (run-mode-hooks 'delphi-mode-hook)) 2035 (run-mode-hooks 'delphi-mode-hook))
2044 2036
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el
index 22e5d2f7c5c..293ba49d4ae 100644
--- a/lisp/progmodes/make-mode.el
+++ b/lisp/progmodes/make-mode.el
@@ -1,4 +1,4 @@
1;;; make-mode.el --- makefile editing commands for Emacs 1;;; make-mode.el --- makefile editing commands for Emacs -*- lexical-binding:t -*-
2 2
3;; Copyright (C) 1992, 1994, 1999-2011 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 1994, 1999-2011 Free Software Foundation, Inc.
4 4
@@ -602,7 +602,7 @@ The function must satisfy this calling convention:
602 (define-key map "\C-c\C-m\C-p" 'makefile-makepp-mode) 602 (define-key map "\C-c\C-m\C-p" 'makefile-makepp-mode)
603 (define-key map "\M-p" 'makefile-previous-dependency) 603 (define-key map "\M-p" 'makefile-previous-dependency)
604 (define-key map "\M-n" 'makefile-next-dependency) 604 (define-key map "\M-n" 'makefile-next-dependency)
605 (define-key map "\e\t" 'makefile-complete) 605 (define-key map "\e\t" 'completion-at-point)
606 606
607 ;; Make menus. 607 ;; Make menus.
608 (define-key map [menu-bar makefile-mode] 608 (define-key map [menu-bar makefile-mode]
@@ -653,7 +653,7 @@ The function must satisfy this calling convention:
653 '(menu-item "Find Targets and Macros" makefile-pickup-everything 653 '(menu-item "Find Targets and Macros" makefile-pickup-everything
654 :help "Notice names of all macros and targets in Makefile")) 654 :help "Notice names of all macros and targets in Makefile"))
655 (define-key map [menu-bar makefile-mode complete] 655 (define-key map [menu-bar makefile-mode complete]
656 '(menu-item "Complete Target or Macro" makefile-complete 656 '(menu-item "Complete Target or Macro" completion-at-point
657 :help "Perform completion on Makefile construct preceding point")) 657 :help "Perform completion on Makefile construct preceding point"))
658 (define-key map [menu-bar makefile-mode backslash] 658 (define-key map [menu-bar makefile-mode backslash]
659 '(menu-item "Backslash Region" makefile-backslash-region 659 '(menu-item "Backslash Region" makefile-backslash-region
@@ -852,6 +852,8 @@ Makefile mode can be configured by modifying the following variables:
852 List of special targets. You will be offered to complete 852 List of special targets. You will be offered to complete
853 on one of those in the minibuffer whenever you enter a `.'. 853 on one of those in the minibuffer whenever you enter a `.'.
854 at the beginning of a line in Makefile mode." 854 at the beginning of a line in Makefile mode."
855 (add-hook 'completion-at-point-functions
856 #'makefile-completions-at-point nil t)
855 (add-hook 'write-file-functions 857 (add-hook 'write-file-functions
856 'makefile-warn-suspicious-lines nil t) 858 'makefile-warn-suspicious-lines nil t)
857 (add-hook 'write-file-functions 859 (add-hook 'write-file-functions
@@ -1147,11 +1149,7 @@ and adds all qualifying names to the list of known targets."
1147 1149
1148;;; Completion. 1150;;; Completion.
1149 1151
1150(defun makefile-complete () 1152(defun makefile-completions-at-point ()
1151 "Perform completion on Makefile construct preceding point.
1152Can complete variable and target names.
1153The context determines which are considered."
1154 (interactive)
1155 (let* ((beg (save-excursion 1153 (let* ((beg (save-excursion
1156 (skip-chars-backward "^$(){}:#= \t\n") 1154 (skip-chars-backward "^$(){}:#= \t\n")
1157 (point))) 1155 (point)))
@@ -1168,22 +1166,26 @@ The context determines which are considered."
1168 ;; Preceding "$(" or "${" means macros only. 1166 ;; Preceding "$(" or "${" means macros only.
1169 ((and (memq pc '(?\{ ?\()) 1167 ((and (memq pc '(?\{ ?\())
1170 (progn 1168 (progn
1171 (setq paren (if (eq paren ?\{) ?\} ?\))) 1169 (setq paren (if (eq pc ?\{) ?\} ?\)))
1172 (backward-char) 1170 (backward-char)
1173 (= (preceding-char) ?$))) 1171 (= (preceding-char) ?$)))
1174 t))))) 1172 t)))))
1175 1173 (suffix (cond
1176 (table (apply-partially 'completion-table-with-terminator 1174 (do-macros (if paren (string paren)))
1177 (cond 1175 ((save-excursion (goto-char beg) (bolp)) ":")
1178 (do-macros (or paren "")) 1176 (t " "))))
1179 ((save-excursion (goto-char beg) (bolp)) ":") 1177 (list beg (point)
1180 (t " ")) 1178 (append (if do-macros '() makefile-target-table)
1181 (append (if do-macros 1179 makefile-macro-table)
1182 '() 1180 :exit-function
1183 makefile-target-table) 1181 (if suffix
1184 makefile-macro-table)))) 1182 (lambda (_s finished)
1185 (completion-in-region beg (point) table))) 1183 (when (memq finished '(sole finished))
1186 1184 (if (looking-at (regexp-quote suffix))
1185 (goto-char (match-end 0))
1186 (insert suffix))))))))
1187
1188(define-obsolete-function-alias 'makefile-complete 'completion-at-point "24.1")
1187 1189
1188 1190
1189;; Backslashification. Stolen from cc-mode.el. 1191;; Backslashification. Stolen from cc-mode.el.
diff --git a/lisp/progmodes/meta-mode.el b/lisp/progmodes/meta-mode.el
index b36104bf49b..ab640c0e270 100644
--- a/lisp/progmodes/meta-mode.el
+++ b/lisp/progmodes/meta-mode.el
@@ -1,4 +1,4 @@
1;;; meta-mode.el --- major mode for editing Metafont or MetaPost sources 1;;; meta-mode.el --- major mode for editing Metafont or MetaPost sources -*- lexical-binding:t -*-
2 2
3;; Copyright (C) 1997, 2001-2011 Free Software Foundation, Inc. 3;; Copyright (C) 1997, 2001-2011 Free Software Foundation, Inc.
4 4
@@ -471,16 +471,13 @@ If the list was changed, sort the list and remove duplicates first."
471 (string-lessp (car a) (car b))) 471 (string-lessp (car a) (car b)))
472 472
473 473
474(defun meta-complete-symbol () 474(defun meta-completions-at-point ()
475 "Perform completion on Metafont or MetaPost symbol preceding point."
476 ;; FIXME: Use completion-at-point-functions.
477 (interactive "*")
478 (let ((list meta-complete-list) 475 (let ((list meta-complete-list)
479 entry) 476 entry)
480 (while list 477 (while list
481 (setq entry (car list) 478 (setq entry (car list)
482 list (cdr list)) 479 list (cdr list))
483 (if (meta-looking-at-backward (car entry) 200) 480 (if (looking-back (car entry) (max (point-min) (- (point) 200)))
484 (setq list nil))) 481 (setq list nil)))
485 (if (numberp (nth 1 entry)) 482 (if (numberp (nth 1 entry))
486 (let* ((sub (nth 1 entry)) 483 (let* ((sub (nth 1 entry))
@@ -488,31 +485,19 @@ If the list was changed, sort the list and remove duplicates first."
488 (begin (match-beginning sub)) 485 (begin (match-beginning sub))
489 (end (match-end sub)) 486 (end (match-end sub))
490 (list (funcall (nth 2 entry)))) 487 (list (funcall (nth 2 entry))))
491 (completion-in-region 488 (list
492 begin end 489 begin end list
493 (if (zerop (length close)) list 490 :exit-function
494 (apply-partially 'completion-table-with-terminator 491 (unless (zerop (length close))
495 close list)))) 492 (lambda (_s finished)
496 (funcall (nth 1 entry))))) 493 (when (memq finished '(sole finished))
497 494 (if (looking-at (regexp-quote close))
498 495 (goto-char (match-end 0))
499(defun meta-looking-at-backward (regexp &optional limit) 496 (insert close)))))))
500 ;; utility function used in `meta-complete-symbol' 497 (nth 1 entry))))
501 (let ((pos (point))) 498
502 (save-excursion 499(define-obsolete-function-alias 'meta-complete-symbol
503 (and (re-search-backward 500 'completion-at-point "24.1")
504 regexp (if limit (max (point-min) (- (point) limit))) t)
505 (eq (match-end 0) pos)))))
506
507(defun meta-match-buffer (n)
508 ;; utility function used in `meta-complete-symbol'
509 (if (match-beginning n)
510 (let ((str (buffer-substring (match-beginning n) (match-end n))))
511 (set-text-properties 0 (length str) nil str)
512 (copy-sequence str))
513 ""))
514
515
516 501
517;;; Indentation. 502;;; Indentation.
518 503
@@ -906,7 +891,7 @@ The environment marked is the one that contains point or follows point."
906 (define-key map "\C-c;" 'meta-comment-region) 891 (define-key map "\C-c;" 'meta-comment-region)
907 (define-key map "\C-c:" 'meta-uncomment-region) 892 (define-key map "\C-c:" 'meta-uncomment-region)
908 ;; Symbol Completion: 893 ;; Symbol Completion:
909 (define-key map "\M-\t" 'meta-complete-symbol) 894 (define-key map "\M-\t" 'completion-at-point)
910 ;; Shell Commands: 895 ;; Shell Commands:
911 ;; (define-key map "\C-c\C-c" 'meta-command-file) 896 ;; (define-key map "\C-c\C-c" 'meta-command-file)
912 ;; (define-key map "\C-c\C-k" 'meta-kill-job) 897 ;; (define-key map "\C-c\C-k" 'meta-kill-job)
@@ -935,7 +920,7 @@ The environment marked is the one that contains point or follows point."
935 ["Uncomment Region" meta-uncomment-region 920 ["Uncomment Region" meta-uncomment-region
936 :active (meta-mark-active)] 921 :active (meta-mark-active)]
937 "--" 922 "--"
938 ["Complete Symbol" meta-complete-symbol t] 923 ["Complete Symbol" completion-at-point t]
939; "--" 924; "--"
940; ["Command on Buffer" meta-command-file t] 925; ["Command on Buffer" meta-command-file t]
941; ["Kill Job" meta-kill-job t] 926; ["Kill Job" meta-kill-job t]
@@ -994,6 +979,7 @@ The environment marked is the one that contains point or follows point."
994 979
995 (set (make-local-variable 'parse-sexp-ignore-comments) t) 980 (set (make-local-variable 'parse-sexp-ignore-comments) t)
996 981
982 (add-hook 'completion-at-point-functions #'meta-completions-at-point nil t)
997 (set (make-local-variable 'comment-indent-function) #'meta-comment-indent) 983 (set (make-local-variable 'comment-indent-function) #'meta-comment-indent)
998 (set (make-local-variable 'indent-line-function) #'meta-indent-line) 984 (set (make-local-variable 'indent-line-function) #'meta-indent-line)
999 ;; No need to define a mode-specific 'indent-region-function. 985 ;; No need to define a mode-specific 'indent-region-function.
diff --git a/lisp/progmodes/octave-inf.el b/lisp/progmodes/octave-inf.el
index 803a542563c..cb64b2436c6 100644
--- a/lisp/progmodes/octave-inf.el
+++ b/lisp/progmodes/octave-inf.el
@@ -267,8 +267,12 @@ startup file, `~/.emacs-octave'."
267 (save-excursion 267 (save-excursion
268 (skip-syntax-backward "w_" (comint-line-beginning-position)) 268 (skip-syntax-backward "w_" (comint-line-beginning-position))
269 (point)))) 269 (point))))
270 (cond (inferior-octave-complete-impossible nil) 270 (cond ((eq start end) nil)
271 ((eq start end) nil) 271 (inferior-octave-complete-impossible
272 (message (concat
273 "Your Octave does not have `completion_matches'. "
274 "Please upgrade to version 2.X."))
275 nil)
272 (t 276 (t
273 (list 277 (list
274 start end 278 start end
@@ -279,19 +283,8 @@ startup file, `~/.emacs-octave'."
279 (sort (delete-dups inferior-octave-output-list) 283 (sort (delete-dups inferior-octave-output-list)
280 'string-lessp)))))))) 284 'string-lessp))))))))
281 285
282(defun inferior-octave-complete () 286(define-obsolete-function-alias 'inferior-octave-complete
283 "Perform completion on the Octave symbol preceding point. 287 'completion-at-point "24.1")
284This is implemented using the Octave command `completion_matches' which
285is NOT available with versions of Octave prior to 2.0."
286 (interactive)
287 (if inferior-octave-complete-impossible
288 (error (concat
289 "Your Octave does not have `completion_matches'. "
290 "Please upgrade to version 2.X."))
291 (let ((data (inferior-octave-completion-at-point)))
292 (if (null data)
293 (message "Cannot complete an empty string")
294 (apply #'completion-in-region data)))))
295 288
296(defun inferior-octave-dynamic-list-input-ring () 289(defun inferior-octave-dynamic-list-input-ring ()
297 "List the buffer's input history in a help buffer." 290 "List the buffer's input history in a help buffer."
diff --git a/lisp/progmodes/octave-mod.el b/lisp/progmodes/octave-mod.el
index 39d997e1d5e..183347cdeca 100644
--- a/lisp/progmodes/octave-mod.el
+++ b/lisp/progmodes/octave-mod.el
@@ -983,12 +983,8 @@ otherwise."
983 (setq end (point)))) 983 (setq end (point))))
984 (list beg end octave-completion-alist))) 984 (list beg end octave-completion-alist)))
985 985
986(defun octave-complete-symbol () 986(define-obsolete-function-alias 'octave-complete-symbol
987 "Perform completion on Octave symbol preceding point. 987 'completion-at-point "24.1")
988Compare that symbol against Octave's reserved words and builtin
989variables."
990 (interactive)
991 (apply 'completion-in-region (octave-completion-at-point-function)))
992 988
993;;; Electric characters && friends 989;;; Electric characters && friends
994 990
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el
index e28bb14bb9a..57ed13969b4 100644
--- a/lisp/progmodes/pascal.el
+++ b/lisp/progmodes/pascal.el
@@ -40,7 +40,6 @@
40;; pascal-tab-always-indent t 40;; pascal-tab-always-indent t
41;; pascal-auto-endcomments t 41;; pascal-auto-endcomments t
42;; pascal-auto-lineup '(all) 42;; pascal-auto-lineup '(all)
43;; pascal-toggle-completions nil
44;; pascal-type-keywords '("array" "file" "packed" "char" 43;; pascal-type-keywords '("array" "file" "packed" "char"
45;; "integer" "real" "string" "record") 44;; "integer" "real" "string" "record")
46;; pascal-start-keywords '("begin" "end" "function" "procedure" 45;; pascal-start-keywords '("begin" "end" "function" "procedure"
@@ -79,8 +78,8 @@
79 ;; These are user preferences, so not to set by default. 78 ;; These are user preferences, so not to set by default.
80 ;;(define-key map "\r" 'electric-pascal-terminate-line) 79 ;;(define-key map "\r" 'electric-pascal-terminate-line)
81 ;;(define-key map "\t" 'electric-pascal-tab) 80 ;;(define-key map "\t" 'electric-pascal-tab)
82 (define-key map "\M-\t" 'pascal-complete-word) 81 (define-key map "\M-\t" 'completion-at-point)
83 (define-key map "\M-?" 'pascal-show-completions) 82 (define-key map "\M-?" 'completion-help-at-point)
84 (define-key map "\177" 'backward-delete-char-untabify) 83 (define-key map "\177" 'backward-delete-char-untabify)
85 (define-key map "\M-\C-h" 'pascal-mark-defun) 84 (define-key map "\M-\C-h" 'pascal-mark-defun)
86 (define-key map "\C-c\C-b" 'pascal-insert-block) 85 (define-key map "\C-c\C-b" 'pascal-insert-block)
@@ -232,13 +231,13 @@ will do all lineups."
232 (const :tag "Case statements" case)) 231 (const :tag "Case statements" case))
233 :group 'pascal) 232 :group 'pascal)
234 233
235(defcustom pascal-toggle-completions nil 234(defvar pascal-toggle-completions nil
236 "*Non-nil means \\<pascal-mode-map>\\[pascal-complete-word] should try all possible completions one by one. 235 "*Non-nil meant \\<pascal-mode-map>\\[pascal-complete-word] would try all possible completions one by one.
237Repeated use of \\[pascal-complete-word] will show you all of them. 236Repeated use of \\[pascal-complete-word] would show you all of them.
238Normally, when there is more than one possible completion, 237Normally, when there is more than one possible completion,
239it displays a list of all possible completions." 238it displays a list of all possible completions.")
240 :type 'boolean 239(make-obsolete-variable 'pascal-toggle-completions
241 :group 'pascal) 240 'completion-cycle-threshold "24.1")
242 241
243(defcustom pascal-type-keywords 242(defcustom pascal-type-keywords
244 '("array" "file" "packed" "char" "integer" "real" "string" "record") 243 '("array" "file" "packed" "char" "integer" "real" "string" "record")
@@ -303,9 +302,9 @@ are handled in another way, and should not be added to this list."
303 "Major mode for editing Pascal code. \\<pascal-mode-map> 302 "Major mode for editing Pascal code. \\<pascal-mode-map>
304TAB indents for Pascal code. Delete converts tabs to spaces as it moves back. 303TAB indents for Pascal code. Delete converts tabs to spaces as it moves back.
305 304
306\\[pascal-complete-word] completes the word around current point with respect \ 305\\[completion-at-point] completes the word around current point with respect \
307to position in code 306to position in code
308\\[pascal-show-completions] shows all possible completions at this point. 307\\[completion-help-at-point] shows all possible completions at this point.
309 308
310Other useful functions are: 309Other useful functions are:
311 310
@@ -354,6 +353,7 @@ no args, if that value is non-nil."
354 (set (make-local-variable 'comment-start) "{") 353 (set (make-local-variable 'comment-start) "{")
355 (set (make-local-variable 'comment-start-skip) "(\\*+ *\\|{ *") 354 (set (make-local-variable 'comment-start-skip) "(\\*+ *\\|{ *")
356 (set (make-local-variable 'comment-end) "}") 355 (set (make-local-variable 'comment-end) "}")
356 (add-hook 'completion-at-point-functions 'pascal-completions-at-point nil t)
357 ;; Font lock support 357 ;; Font lock support
358 (set (make-local-variable 'font-lock-defaults) 358 (set (make-local-variable 'font-lock-defaults)
359 '(pascal-font-lock-keywords nil t)) 359 '(pascal-font-lock-keywords nil t))
@@ -1287,54 +1287,17 @@ indent of the current line in parameterlist."
1287(defvar pascal-last-word-shown nil) 1287(defvar pascal-last-word-shown nil)
1288(defvar pascal-last-completions nil) 1288(defvar pascal-last-completions nil)
1289 1289
1290(defun pascal-complete-word () 1290(defun pascal-completions-at-point ()
1291 "Complete word at current point.
1292\(See also `pascal-toggle-completions', `pascal-type-keywords',
1293`pascal-start-keywords' and `pascal-separator-keywords'.)"
1294 (interactive)
1295 (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point))) 1291 (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
1296 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))) 1292 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point))))
1293 (when (> e b)
1294 (list b e #'pascal-completion))))
1297 1295
1298 ;; Toggle-completions inserts whole labels 1296(define-obsolete-function-alias 'pascal-complete-word
1299 (if pascal-toggle-completions 1297 'completion-at-point "24.1")
1300 (let* ((pascal-str (buffer-substring b e)) 1298
1301 (allcomp (if (and pascal-toggle-completions 1299(define-obsolete-function-alias 'pascal-show-completions
1302 (string= pascal-last-word-shown pascal-str)) 1300 'completion-help-at-point "24.1")
1303 pascal-last-completions
1304 (all-completions pascal-str 'pascal-completion))))
1305 ;; Update entry number in list
1306 (setq pascal-last-completions allcomp
1307 pascal-last-word-numb
1308 (if (>= pascal-last-word-numb (1- (length allcomp)))
1309 0
1310 (1+ pascal-last-word-numb)))
1311 (setq pascal-last-word-shown (elt allcomp pascal-last-word-numb))
1312 ;; Display next match or same string if no match was found
1313 (if allcomp
1314 (progn
1315 (goto-char e)
1316 (insert-before-markers pascal-last-word-shown)
1317 (delete-region b e))
1318 (message "(No match)")))
1319 ;; The other form of completion does not necessarily do that.
1320 (completion-in-region b e 'pascal-completion))))
1321
1322(defun pascal-show-completions ()
1323 "Show all possible completions at current point."
1324 (interactive)
1325 (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
1326 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
1327 (pascal-str (buffer-substring b e))
1328 (allcomp (if (and pascal-toggle-completions
1329 (string= pascal-last-word-shown pascal-str))
1330 pascal-last-completions
1331 (all-completions pascal-str 'pascal-completion))))
1332 ;; Show possible completions in a temporary buffer.
1333 (with-output-to-temp-buffer "*Completions*"
1334 (display-completion-list allcomp pascal-str))
1335 ;; Wait for a keypress. Then delete *Completion* window
1336 (momentary-string-display "" (point))
1337 (delete-window (get-buffer-window (get-buffer "*Completions*")))))
1338 1301
1339 1302
1340(defun pascal-get-default-symbol () 1303(defun pascal-get-default-symbol ()
diff --git a/lisp/shell.el b/lisp/shell.el
index 8a282e94160..de811543ba0 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -398,6 +398,12 @@ to `dirtrack-mode'."
398 (set (make-local-variable 'pcomplete-parse-arguments-function) 398 (set (make-local-variable 'pcomplete-parse-arguments-function)
399 ;; FIXME: This function should be moved to shell.el. 399 ;; FIXME: This function should be moved to shell.el.
400 #'pcomplete-parse-comint-arguments) 400 #'pcomplete-parse-comint-arguments)
401 (set (make-local-variable 'pcomplete-termination-string)
402 (cond ((not comint-completion-addsuffix) "")
403 ((stringp comint-completion-addsuffix)
404 comint-completion-addsuffix)
405 ((not (consp comint-completion-addsuffix)) " ")
406 (t (cdr comint-completion-addsuffix))))
401 ;; Don't use pcomplete's defaulting mechanism, rely on 407 ;; Don't use pcomplete's defaulting mechanism, rely on
402 ;; shell-dynamic-complete-functions instead. 408 ;; shell-dynamic-complete-functions instead.
403 (set (make-local-variable 'pcomplete-default-completion-function) #'ignore) 409 (set (make-local-variable 'pcomplete-default-completion-function) #'ignore)
diff --git a/lisp/subr.el b/lisp/subr.el
index b328b7e17b7..4d2f3b1808c 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2600,6 +2600,14 @@ Otherwise, return nil."
2600 (get-char-property (1- (field-end pos)) 'field) 2600 (get-char-property (1- (field-end pos)) 'field)
2601 raw-field))) 2601 raw-field)))
2602 2602
2603(defun sha1 (object &optional start end binary)
2604 "Return the SHA1 (Secure Hash Algorithm) of an OBJECT.
2605OBJECT is either a string or a buffer. Optional arguments START and
2606END are character positions specifying which portion of OBJECT for
2607computing the hash. If BINARY is non-nil, return a string in binary
2608form."
2609 (secure-hash 'sha1 object start end binary))
2610
2603 2611
2604;;;; Support for yanking and text properties. 2612;;;; Support for yanking and text properties.
2605 2613
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index 712929ecec0..fbf3e91d3d9 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -916,6 +916,11 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
916 ;; FIXME: This will surely lead to "MODIFIED OUTSIDE CUSTOM" warnings. 916 ;; FIXME: This will surely lead to "MODIFIED OUTSIDE CUSTOM" warnings.
917 (menu-bar-mode (if (get-lisp-resource nil "Menus") 1 -1)) 917 (menu-bar-mode (if (get-lisp-resource nil "Menus") 1 -1))
918 918
919 ;; OS X Lion introduces PressAndHold, which is unsupported by this port.
920 ;; See this thread for more details:
921 ;; http://lists.gnu.org/archive/html/emacs-devel/2011-06/msg00505.html
922 (ns-set-resource nil "ApplePressAndHoldEnabled" "NO")
923
919 (setq ns-initialized t)) 924 (setq ns-initialized t))
920 925
921(add-to-list 'handle-args-function-alist '(ns . x-handle-args)) 926(add-to-list 'handle-args-function-alist '(ns . x-handle-args))
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 12094887f38..107a0728bae 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -3154,8 +3154,8 @@ When called interactively with a prefix arg, query for a value of ENTRY-TYPE."
3154 (insert (bibtex-field-left-delimiter))) 3154 (insert (bibtex-field-left-delimiter)))
3155 (goto-char end))) 3155 (goto-char end)))
3156 (skip-chars-backward " \t\n") 3156 (skip-chars-backward " \t\n")
3157 (dolist (field required) (bibtex-make-field field)) 3157 (mapc 'bibtex-make-field required)
3158 (dolist (field optional) (bibtex-make-optional-field field)))))) 3158 (mapc 'bibtex-make-optional-field optional)))))
3159 3159
3160(defun bibtex-parse-entry (&optional content) 3160(defun bibtex-parse-entry (&optional content)
3161 "Parse entry at point, return an alist. 3161 "Parse entry at point, return an alist.
@@ -4247,21 +4247,24 @@ At end of the cleaning process, the functions in
4247 ;; (bibtex-format-string) 4247 ;; (bibtex-format-string)
4248 (t (bibtex-format-entry))) 4248 (t (bibtex-format-entry)))
4249 ;; set key 4249 ;; set key
4250 (when (or new-key (not key)) 4250 (if (or new-key (not key))
4251 (setq key (bibtex-generate-autokey)) 4251 (save-excursion
4252 ;; Sometimes `bibtex-generate-autokey' returns an empty string 4252 ;; First delete the old key so that a customized algorithm
4253 (if (or bibtex-autokey-edit-before-use (string= "" key)) 4253 ;; for generating the new key does not get confused by the
4254 (setq key (if (eq entry-type 'string) 4254 ;; old key.
4255 (bibtex-read-string-key key) 4255 (re-search-forward (if (eq entry-type 'string)
4256 (bibtex-read-key "Key to use: " key)))) 4256 bibtex-string-maybe-empty-head
4257 (save-excursion 4257 bibtex-entry-maybe-empty-head))
4258 (re-search-forward (if (eq entry-type 'string) 4258 (if (match-beginning bibtex-key-in-head)
4259 bibtex-string-maybe-empty-head 4259 (delete-region (match-beginning bibtex-key-in-head)
4260 bibtex-entry-maybe-empty-head)) 4260 (match-end bibtex-key-in-head)))
4261 (if (match-beginning bibtex-key-in-head) 4261 (setq key (bibtex-generate-autokey))
4262 (delete-region (match-beginning bibtex-key-in-head) 4262 ;; Sometimes `bibtex-generate-autokey' returns an empty string
4263 (match-end bibtex-key-in-head))) 4263 (if (or bibtex-autokey-edit-before-use (string= "" key))
4264 (insert key))) 4264 (setq key (if (eq entry-type 'string)
4265 (bibtex-read-string-key key)
4266 (bibtex-read-key "Key to use: " key))))
4267 (insert key)))
4265 4268
4266 (unless called-by-reformat 4269 (unless called-by-reformat
4267 (let* ((end (save-excursion 4270 (let* ((end (save-excursion
@@ -4718,7 +4721,7 @@ Return the URL or nil if none can be generated."
4718 (fields-alist (save-excursion (bibtex-parse-entry t))) 4721 (fields-alist (save-excursion (bibtex-parse-entry t)))
4719 ;; Always ignore case, 4722 ;; Always ignore case,
4720 (case-fold-search t) 4723 (case-fold-search t)
4721 text url scheme obj fmt fl-match step) 4724 text url scheme obj fmt fl-match)
4722 ;; The return value of `bibtex-parse-entry' (i.e., FIELDS-ALIST) 4725 ;; The return value of `bibtex-parse-entry' (i.e., FIELDS-ALIST)
4723 ;; is always used to generate the URL. However, if the BibTeX 4726 ;; is always used to generate the URL. However, if the BibTeX
4724 ;; entry contains more than one URL, we have multiple matches 4727 ;; entry contains more than one URL, we have multiple matches
@@ -4773,11 +4776,8 @@ Return the URL or nil if none can be generated."
4773 (setq url (if (null scheme) (match-string 0 text) 4776 (setq url (if (null scheme) (match-string 0 text)
4774 (if (stringp (car scheme)) 4777 (if (stringp (car scheme))
4775 (setq fmt (pop scheme))) 4778 (setq fmt (pop scheme)))
4776 (dotimes (i (length scheme)) 4779 (dolist (step scheme)
4777 (setq step (nth i scheme)) 4780 (setq text (cdr (assoc-string (car step) fields-alist t)))
4778 ;; The first step shall use TEXT as obtained earlier.
4779 (unless (= i 0)
4780 (setq text (cdr (assoc-string (car step) fields-alist t))))
4781 (if (string-match (nth 1 step) text) 4781 (if (string-match (nth 1 step) text)
4782 (push (cond ((functionp (nth 2 step)) 4782 (push (cond ((functionp (nth 2 step))
4783 (funcall (nth 2 step) text)) 4783 (funcall (nth 2 step) text))
@@ -4857,24 +4857,24 @@ where FILE is the BibTeX file of ENTRY."
4857 (save-excursion 4857 (save-excursion
4858 (goto-char beg) 4858 (goto-char beg)
4859 (and (looking-at bibtex-entry-head) 4859 (and (looking-at bibtex-entry-head)
4860 (setq key (bibtex-key-in-head))))) 4860 (setq key (bibtex-key-in-head))))
4861 (add-to-list 'entries 4861 (not (assoc key entries)))
4862 (list key file 4862 (push (list key file
4863 (buffer-substring-no-properties 4863 (buffer-substring-no-properties beg end))
4864 beg end)))))) 4864 entries))))
4865 ;; The following is slow. But it works reliably even in more 4865 ;; The following is slow. But it works reliably even in more
4866 ;; complicated cases with BibTeX string constants and crossrefed 4866 ;; complicated cases with BibTeX string constants and crossrefed
4867 ;; entries. If you prefer speed over reliability, perform an 4867 ;; entries. If you prefer speed over reliability, perform an
4868 ;; unrestricted search. 4868 ;; unrestricted search.
4869 (bibtex-map-entries 4869 (bibtex-map-entries
4870 (lambda (key beg end) 4870 (lambda (key beg end)
4871 (if (cond (funp (funcall regexp beg end)) 4871 (if (and (cond (funp (funcall regexp beg end))
4872 ((and (setq text (bibtex-text-in-field field t)) 4872 ((and (setq text (bibtex-text-in-field field t))
4873 (string-match regexp text)))) 4873 (string-match regexp text))))
4874 (add-to-list 'entries 4874 (not (assoc key entries)))
4875 (list key file 4875 (push (list key file
4876 (buffer-substring-no-properties 4876 (buffer-substring-no-properties beg end))
4877 beg end)))))))))) 4877 entries))))))))
4878 (if display 4878 (if display
4879 (if entries 4879 (if entries
4880 (bibtex-display-entries entries) 4880 (bibtex-display-entries entries)
diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el
index 2b7e9a19baa..a85ed982ab0 100644
--- a/lisp/textmodes/fill.el
+++ b/lisp/textmodes/fill.el
@@ -1054,6 +1054,7 @@ The `justification' text-property can locally override this variable."
1054 (const full) 1054 (const full)
1055 (const center) 1055 (const center)
1056 (const none)) 1056 (const none))
1057 :safe 'symbolp
1057 :group 'fill) 1058 :group 'fill)
1058(make-variable-buffer-local 'default-justification) 1059(make-variable-buffer-local 'default-justification)
1059 1060
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 7b7813db94b..b0d00242f2a 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -1,4 +1,4 @@
1;;; wid-edit.el --- Functions for creating and using widgets -*-byte-compile-dynamic: t;-*- 1;;; wid-edit.el --- Functions for creating and using widgets -*-byte-compile-dynamic: t; lexical-binding:t -*-
2;; 2;;
3;; Copyright (C) 1996-1997, 1999-2011 Free Software Foundation, Inc. 3;; Copyright (C) 1996-1997, 1999-2011 Free Software Foundation, Inc.
4;; 4;;
@@ -1161,10 +1161,29 @@ the field."
1161 "Complete content of editable field from point. 1161 "Complete content of editable field from point.
1162When not inside a field, signal an error." 1162When not inside a field, signal an error."
1163 (interactive) 1163 (interactive)
1164 (let ((data (widget-completions-at-point)))
1165 (cond
1166 ((functionp data) (funcall data))
1167 ((consp data)
1168 (let ((completion-extra-properties (nth 3 data)))
1169 (completion-in-region (nth 0 data) (nth 1 data) (nth 2 data)
1170 (plist-get completion-extra-properties
1171 :predicate))))
1172 ((widget-field-find (point))
1173 ;; This defaulting used to be performed in widget-default-complete, but
1174 ;; it seems more appropriate here than in widget-default-completions.
1175 (call-interactively 'widget-complete-field))
1176 (t
1177 (error "Not in an editable field")))))
1178;; We may want to use widget completion in buffers where the major mode
1179;; hasn't added widget-completions-at-point to completion-at-point-functions,
1180;; so it's not really obsolete (yet).
1181;; (make-obsolete 'widget-complete 'completion-at-point "24.1")
1182
1183(defun widget-completions-at-point ()
1164 (let ((field (widget-field-find (point)))) 1184 (let ((field (widget-field-find (point))))
1165 (if field 1185 (when field
1166 (widget-apply field :complete) 1186 (widget-apply field :completions-function))))
1167 (error "Not in an editable field"))))
1168 1187
1169;;; Setting up the buffer. 1188;;; Setting up the buffer.
1170 1189
@@ -1435,7 +1454,7 @@ The value of the :type attribute should be an unconverted widget type."
1435 :value-to-external (lambda (_widget value) value) 1454 :value-to-external (lambda (_widget value) value)
1436 :button-prefix 'widget-button-prefix 1455 :button-prefix 'widget-button-prefix
1437 :button-suffix 'widget-button-suffix 1456 :button-suffix 'widget-button-suffix
1438 :complete 'widget-default-complete 1457 :completions-function #'widget-default-completions
1439 :create 'widget-default-create 1458 :create 'widget-default-create
1440 :indent nil 1459 :indent nil
1441 :offset 0 1460 :offset 0
@@ -1461,13 +1480,20 @@ The value of the :type attribute should be an unconverted widget type."
1461 1480
1462(defvar widget--completing-widget) 1481(defvar widget--completing-widget)
1463 1482
1464(defun widget-default-complete (widget) 1483(defun widget-default-completions (widget)
1465 "Call the value of the :complete-function property of WIDGET. 1484 "Return completion data, like `completion-at-point-functions' would."
1466If that does not exist, call the value of `widget-complete-field'. 1485 (let ((completions (widget-get widget :completions)))
1467During this call, `widget--completing-widget' is bound to WIDGET." 1486 (if completions
1468 (let ((widget--completing-widget widget)) 1487 (list (widget-field-start widget)
1469 (call-interactively (or (widget-get widget :complete-function) 1488 (max (point) (widget-field-text-end widget))
1470 widget-complete-field)))) 1489 completions)
1490 (if (widget-get widget :complete)
1491 (lambda () (widget-apply widget :complete))
1492 (if (widget-get widget :complete-function)
1493 (lambda ()
1494 (let ((widget--completing-widget widget))
1495 (call-interactively
1496 (widget-get widget :complete-function)))))))))
1471 1497
1472(defun widget-default-create (widget) 1498(defun widget-default-create (widget)
1473 "Create WIDGET at point in the current buffer." 1499 "Create WIDGET at point in the current buffer."
@@ -3018,20 +3044,6 @@ as the value."
3018 :complete-function 'ispell-complete-word 3044 :complete-function 'ispell-complete-word
3019 :prompt-history 'widget-string-prompt-value-history) 3045 :prompt-history 'widget-string-prompt-value-history)
3020 3046
3021(defun widget-string-complete ()
3022 "Complete contents of string field.
3023Completions are taken from the :completion-alist property of the
3024widget. If that isn't a list, it's evalled and expected to yield a list."
3025 (interactive)
3026 (let* ((widget widget--completing-widget)
3027 (completion-ignore-case (widget-get widget :completion-ignore-case))
3028 (alist (widget-get widget :completion-alist))
3029 (_ (unless (listp alist)
3030 (setq alist (eval alist)))))
3031 (completion-in-region (widget-field-start widget)
3032 (max (point) (widget-field-text-end widget))
3033 alist)))
3034
3035(define-widget 'regexp 'string 3047(define-widget 'regexp 'string
3036 "A regular expression." 3048 "A regular expression."
3037 :match 'widget-regexp-match 3049 :match 'widget-regexp-match
@@ -3059,21 +3071,13 @@ widget. If that isn't a list, it's evalled and expected to yield a list."
3059(define-widget 'file 'string 3071(define-widget 'file 'string
3060 "A file widget. 3072 "A file widget.
3061It reads a file name from an editable text field." 3073It reads a file name from an editable text field."
3062 :complete-function 'widget-file-complete 3074 :completions #'completion-file-name-table
3063 :prompt-value 'widget-file-prompt-value 3075 :prompt-value 'widget-file-prompt-value
3064 :format "%{%t%}: %v" 3076 :format "%{%t%}: %v"
3065 ;; Doesn't work well with terminating newline. 3077 ;; Doesn't work well with terminating newline.
3066 ;; :value-face 'widget-single-line-field 3078 ;; :value-face 'widget-single-line-field
3067 :tag "File") 3079 :tag "File")
3068 3080
3069(defun widget-file-complete ()
3070 "Perform completion on file name preceding point."
3071 (interactive)
3072 (let ((widget widget--completing-widget))
3073 (completion-in-region (widget-field-start widget)
3074 (max (point) (widget-field-text-end widget))
3075 'completion-file-name-table)))
3076
3077(defun widget-file-prompt-value (widget prompt value unbound) 3081(defun widget-file-prompt-value (widget prompt value unbound)
3078 ;; Read file from minibuffer. 3082 ;; Read file from minibuffer.
3079 (abbreviate-file-name 3083 (abbreviate-file-name
@@ -3113,7 +3117,7 @@ It reads a directory name from an editable text field."
3113 :tag "Symbol" 3117 :tag "Symbol"
3114 :format "%{%t%}: %v" 3118 :format "%{%t%}: %v"
3115 :match (lambda (_widget value) (symbolp value)) 3119 :match (lambda (_widget value) (symbolp value))
3116 :complete-function 'lisp-complete-symbol 3120 :completions obarray
3117 :prompt-internal 'widget-symbol-prompt-internal 3121 :prompt-internal 'widget-symbol-prompt-internal
3118 :prompt-match 'symbolp 3122 :prompt-match 'symbolp
3119 :prompt-history 'widget-symbol-prompt-value-history 3123 :prompt-history 'widget-symbol-prompt-value-history
@@ -3141,9 +3145,8 @@ It reads a directory name from an editable text field."
3141 3145
3142(define-widget 'function 'restricted-sexp 3146(define-widget 'function 'restricted-sexp
3143 "A Lisp function." 3147 "A Lisp function."
3144 :complete-function (lambda () 3148 :completions (apply-partially #'completion-table-with-predicate
3145 (interactive) 3149 obarray #'fboundp 'strict)
3146 (lisp-complete-symbol 'fboundp))
3147 :prompt-value 'widget-field-prompt-value 3150 :prompt-value 'widget-field-prompt-value
3148 :prompt-internal 'widget-symbol-prompt-internal 3151 :prompt-internal 'widget-symbol-prompt-internal
3149 :prompt-match 'fboundp 3152 :prompt-match 'fboundp
@@ -3165,9 +3168,8 @@ It reads a directory name from an editable text field."
3165 "A Lisp variable." 3168 "A Lisp variable."
3166 :prompt-match 'boundp 3169 :prompt-match 'boundp
3167 :prompt-history 'widget-variable-prompt-value-history 3170 :prompt-history 'widget-variable-prompt-value-history
3168 :complete-function (lambda () 3171 :completions (apply-partially #'completion-table-with-predicate
3169 (interactive) 3172 obarray #'boundp 'strict)
3170 (lisp-complete-symbol 'boundp))
3171 :tag "Variable") 3173 :tag "Variable")
3172 3174
3173(define-widget 'coding-system 'symbol 3175(define-widget 'coding-system 'symbol
@@ -3178,9 +3180,8 @@ It reads a directory name from an editable text field."
3178 :prompt-history 'coding-system-value-history 3180 :prompt-history 'coding-system-value-history
3179 :prompt-value 'widget-coding-system-prompt-value 3181 :prompt-value 'widget-coding-system-prompt-value
3180 :action 'widget-coding-system-action 3182 :action 'widget-coding-system-action
3181 :complete-function (lambda () 3183 :completions (apply-partially #'completion-table-with-predicate
3182 (interactive) 3184 obarray #'coding-system-p 'strict)
3183 (lisp-complete-symbol 'coding-system-p))
3184 :validate (lambda (widget) 3185 :validate (lambda (widget)
3185 (unless (coding-system-p (widget-value widget)) 3186 (unless (coding-system-p (widget-value widget))
3186 (widget-put widget :error (format "Invalid coding system: %S" 3187 (widget-put widget :error (format "Invalid coding system: %S"
@@ -3317,7 +3318,7 @@ It reads a directory name from an editable text field."
3317 (insert (widget-apply widget :value-get)) 3318 (insert (widget-apply widget :value-get))
3318 (goto-char (point-min)) 3319 (goto-char (point-min))
3319 (let (err) 3320 (let (err)
3320 (condition-case data 3321 (condition-case data ;Note: We get a spurious byte-compile warning here.
3321 (progn 3322 (progn
3322 ;; Avoid a confusing end-of-file error. 3323 ;; Avoid a confusing end-of-file error.
3323 (skip-syntax-forward "\\s-") 3324 (skip-syntax-forward "\\s-")
@@ -3685,7 +3686,7 @@ example:
3685 :size 10 3686 :size 10
3686 :tag "Color" 3687 :tag "Color"
3687 :value "black" 3688 :value "black"
3688 :complete 'widget-color-complete 3689 :completions (or facemenu-color-alist (defined-colors))
3689 :sample-face-get 'widget-color-sample-face-get 3690 :sample-face-get 'widget-color-sample-face-get
3690 :notify 'widget-color-notify 3691 :notify 'widget-color-notify
3691 :action 'widget-color-action) 3692 :action 'widget-color-action)
@@ -3711,14 +3712,6 @@ example:
3711 (delete-window win))) 3712 (delete-window win)))
3712 (pop-to-buffer ,(current-buffer)))))) 3713 (pop-to-buffer ,(current-buffer))))))
3713 3714
3714(defun widget-color-complete (widget)
3715 "Complete the color in WIDGET."
3716 (require 'facemenu) ; for facemenu-color-alist
3717 (completion-in-region (widget-field-start widget)
3718 (max (point) (widget-field-text-end widget))
3719 (or facemenu-color-alist
3720 (sort (defined-colors) 'string-lessp))))
3721
3722(defun widget-color-sample-face-get (widget) 3715(defun widget-color-sample-face-get (widget)
3723 (let* ((value (condition-case nil 3716 (let* ((value (condition-case nil
3724 (widget-value widget) 3717 (widget-value widget)
diff --git a/lisp/window.el b/lisp/window.el
index 5493893d4c1..ac43fe7703c 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -1165,13 +1165,20 @@ IGNORE, when non-nil means a window can be returned even if its
1165 (window-frame window)) 1165 (window-frame window))
1166 (or best best-2))) 1166 (or best best-2)))
1167 1167
1168(defun get-window-with-predicate (predicate &optional minibuf 1168(defun get-window-with-predicate (predicate &optional minibuf all-frames default)
1169 all-frames default)
1170 "Return a live window satisfying PREDICATE. 1169 "Return a live window satisfying PREDICATE.
1171More precisely, cycle through all windows calling the function 1170More precisely, cycle through all windows calling the function
1172PREDICATE on each one of them with the window as its sole 1171PREDICATE on each one of them with the window as its sole
1173argument. Return the first window for which PREDICATE returns 1172argument. Return the first window for which PREDICATE returns
1174non-nil. If no window satisfies PREDICATE, return DEFAULT. 1173non-nil. Windows are scanned starting with the window following
1174the selcted window. If no window satisfies PREDICATE, return
1175DEFAULT.
1176
1177MINIBUF t means include the minibuffer window even if the
1178minibuffer is not active. MINIBUF nil or omitted means include
1179the minibuffer window only if the minibuffer is active. Any
1180other value means do not include the minibuffer window even if
1181the minibuffer is active.
1175 1182
1176ALL-FRAMES nil or omitted means consider all windows on the selected 1183ALL-FRAMES nil or omitted means consider all windows on the selected
1177frame, plus the minibuffer window if specified by the MINIBUF 1184frame, plus the minibuffer window if specified by the MINIBUF
@@ -1192,7 +1199,9 @@ values of ALL-FRAMES have special meanings:
1192Anything else means consider all windows on the selected frame 1199Anything else means consider all windows on the selected frame
1193and no others." 1200and no others."
1194 (catch 'found 1201 (catch 'found
1195 (dolist (window (window-list-1 nil minibuf all-frames)) 1202 (dolist (window (window-list-1
1203 (next-window nil minibuf all-frames)
1204 minibuf all-frames))
1196 (when (funcall predicate window) 1205 (when (funcall predicate window)
1197 (throw 'found window))) 1206 (throw 'found window)))
1198 default)) 1207 default))
@@ -1297,10 +1306,8 @@ selected frame and no others."
1297(defun get-buffer-window-list (&optional buffer-or-name minibuf all-frames) 1306(defun get-buffer-window-list (&optional buffer-or-name minibuf all-frames)
1298 "Return list of all windows displaying BUFFER-OR-NAME, or nil if none. 1307 "Return list of all windows displaying BUFFER-OR-NAME, or nil if none.
1299BUFFER-OR-NAME may be a buffer or the name of an existing buffer 1308BUFFER-OR-NAME may be a buffer or the name of an existing buffer
1300and defaults to the current buffer. 1309and defaults to the current buffer. Windows are scanned starting
1301 1310with the selected window.
1302Any windows showing BUFFER-OR-NAME on the selected frame are listed
1303first.
1304 1311
1305MINIBUF t means include the minibuffer window even if the 1312MINIBUF t means include the minibuffer window even if the
1306minibuffer is not active. MINIBUF nil or omitted means include 1313minibuffer is not active. MINIBUF nil or omitted means include
@@ -1328,7 +1335,7 @@ Anything else means consider all windows on the selected frame
1328and no others." 1335and no others."
1329 (let ((buffer (normalize-live-buffer buffer-or-name)) 1336 (let ((buffer (normalize-live-buffer buffer-or-name))
1330 windows) 1337 windows)
1331 (dolist (window (window-list-1 (frame-first-window) minibuf all-frames)) 1338 (dolist (window (window-list-1 (selected-window) minibuf all-frames))
1332 (when (eq (window-buffer window) buffer) 1339 (when (eq (window-buffer window) buffer)
1333 (setq windows (cons window windows)))) 1340 (setq windows (cons window windows))))
1334 (nreverse windows))) 1341 (nreverse windows)))
@@ -2044,7 +2051,18 @@ make selected window wider by DELTA columns. If DELTA is
2044negative, shrink selected window by -DELTA lines or columns. 2051negative, shrink selected window by -DELTA lines or columns.
2045Return nil." 2052Return nil."
2046 (interactive "p") 2053 (interactive "p")
2047 (resize-window (selected-window) delta horizontal)) 2054 (cond
2055 ((zerop delta))
2056 ((window-size-fixed-p nil horizontal)
2057 (error "Selected window has fixed size"))
2058 ((window-resizable-p nil delta horizontal)
2059 (resize-window nil delta horizontal))
2060 (t
2061 (resize-window
2062 nil (if (> delta 0)
2063 (window-max-delta nil horizontal)
2064 (- (window-min-delta nil horizontal)))
2065 horizontal))))
2048 2066
2049(defun shrink-window (delta &optional horizontal) 2067(defun shrink-window (delta &optional horizontal)
2050 "Make selected window DELTA lines smaller. 2068 "Make selected window DELTA lines smaller.
@@ -2054,7 +2072,18 @@ make selected window narrower by DELTA columns. If DELTA is
2054negative, enlarge selected window by -DELTA lines or columns. 2072negative, enlarge selected window by -DELTA lines or columns.
2055Return nil." 2073Return nil."
2056 (interactive "p") 2074 (interactive "p")
2057 (resize-window (selected-window) (- delta) horizontal)) 2075 (cond
2076 ((zerop delta))
2077 ((window-size-fixed-p nil horizontal)
2078 (error "Selected window has fixed size"))
2079 ((window-resizable-p nil (- delta) horizontal)
2080 (resize-window nil (- delta) horizontal))
2081 (t
2082 (resize-window
2083 nil (if (> delta 0)
2084 (- (window-min-delta nil horizontal))
2085 (window-max-delta nil horizontal))
2086 horizontal))))
2058 2087
2059(defun maximize-window (&optional window) 2088(defun maximize-window (&optional window)
2060 "Maximize WINDOW. 2089 "Maximize WINDOW.
@@ -2222,6 +2251,28 @@ and no others."
2222 (next-window base-window (if nomini 'arg) all-frames)))) 2251 (next-window base-window (if nomini 'arg) all-frames))))
2223 2252
2224;;; Deleting windows. 2253;;; Deleting windows.
2254(defcustom frame-auto-delete 'automatic
2255 "If non-nil, quitting a window can delete it's frame.
2256If this variable is nil, functions that quit a window never
2257delete the associated frame. If this variable equals the symbol
2258`automatic', a frame is deleted only if it the window is
2259dedicated or was created by `display-buffer'. If this variable
2260is t, a frame can be always deleted, even if it was created by
2261`make-frame-command'. Other values should not be used.
2262
2263Note that a frame will be effectively deleted if and only if
2264another frame still exists.
2265
2266Functions quitting a window and consequently affected by this
2267variable are `switch-to-prev-buffer', `delete-windows-on',
2268`replace-buffer-in-windows' and `quit-restore-window'."
2269 :type '(choice
2270 (const :tag "Never" nil)
2271 (const :tag "Automatic" automatic)
2272 (const :tag "Always" t))
2273 :group 'windows
2274 :group 'frames)
2275
2225(defun window-deletable-p (&optional window) 2276(defun window-deletable-p (&optional window)
2226 "Return t if WINDOW can be safely deleted from its frame. 2277 "Return t if WINDOW can be safely deleted from its frame.
2227Return `frame' if deleting WINDOW should delete its frame 2278Return `frame' if deleting WINDOW should delete its frame
@@ -2237,9 +2288,12 @@ instead."
2237 (quit-restore (window-parameter window 'quit-restore))) 2288 (quit-restore (window-parameter window 'quit-restore)))
2238 (cond 2289 (cond
2239 ((frame-root-window-p window) 2290 ((frame-root-window-p window)
2240 (when (and (or dedicated 2291 (when (and (or (eq frame-auto-delete t)
2241 (and (eq (car-safe quit-restore) 'new-frame) 2292 (and (eq frame-auto-delete 'automatic)
2242 (eq (nth 1 quit-restore) (window-buffer window)))) 2293 (or dedicated
2294 (and (eq (car-safe quit-restore) 'new-frame)
2295 (eq (nth 1 quit-restore)
2296 (window-buffer window))))))
2243 (other-visible-frames-p frame)) 2297 (other-visible-frames-p frame))
2244 ;; WINDOW is the root window of its frame. Return `frame' but 2298 ;; WINDOW is the root window of its frame. Return `frame' but
2245 ;; only if WINDOW is (1) either dedicated or quit-restore's car 2299 ;; only if WINDOW is (1) either dedicated or quit-restore's car
@@ -2960,7 +3014,11 @@ new window are inherited from the window selected on WINDOW's
2960frame. The selected window is not changed by this function." 3014frame. The selected window is not changed by this function."
2961 (interactive "i") 3015 (interactive "i")
2962 (setq window (normalize-any-window window)) 3016 (setq window (normalize-any-window window))
2963 (let* ((horizontal (not (memq side '(nil below above)))) 3017 (let* ((side (cond
3018 ((not side) 'below)
3019 ((memq side '(below above right left)) side)
3020 (t 'right)))
3021 (horizontal (not (memq side '(nil below above))))
2964 (frame (window-frame window)) 3022 (frame (window-frame window))
2965 (parent (window-parent window)) 3023 (parent (window-parent window))
2966 (function (window-parameter window 'split-window)) 3024 (function (window-parameter window 'split-window))
@@ -3454,15 +3512,320 @@ specific buffers."
3454 ;; (message "Done in %d rounds" round) 3512 ;; (message "Done in %d rounds" round)
3455 )) 3513 ))
3456 3514
3515;;; Window states, how to get them and how to put them in a window.
3516(defsubst window-list-no-nils (&rest args)
3517 "Like LIST but do not add nil elements of ARGS."
3518 (delq nil (apply 'list args)))
3519
3520(defvar window-state-ignored-parameters '(quit-restore)
3521 "List of window parameters ignored by `window-state-get'.")
3522
3523(defun window-state-get-1 (window &optional markers)
3524 "Helper function for `window-state-get'."
3525 (let* ((type
3526 (cond
3527 ((window-vchild window) 'vc)
3528 ((window-hchild window) 'hc)
3529 (t 'leaf)))
3530 (buffer (window-buffer window))
3531 (selected (eq window (selected-window)))
3532 (head
3533 (window-list-no-nils
3534 type
3535 (unless (window-next window) (cons 'last t))
3536 (cons 'clone-number (window-clone-number window))
3537 (cons 'total-height (window-total-size window))
3538 (cons 'total-width (window-total-size window t))
3539 (cons 'normal-height (window-normal-size window))
3540 (cons 'normal-width (window-normal-size window t))
3541 (cons 'splits (window-splits window))
3542 (cons 'nest (window-nest window))
3543 (let (list)
3544 (dolist (parameter (window-parameters window))
3545 (unless (memq (car parameter)
3546 window-state-ignored-parameters)
3547 (setq list (cons parameter list))))
3548 (when list
3549 (cons 'parameters list)))
3550 (when buffer
3551 ;; All buffer related things go in here - make the buffer
3552 ;; current when retrieving `point' and `mark'.
3553 (with-current-buffer (window-buffer window)
3554 (let ((point (if selected (point) (window-point window)))
3555 (start (window-start window))
3556 (mark (mark)))
3557 (window-list-no-nils
3558 'buffer (buffer-name buffer)
3559 (cons 'selected selected)
3560 (when window-size-fixed (cons 'size-fixed window-size-fixed))
3561 (cons 'hscroll (window-hscroll window))
3562 (cons 'fringes (window-fringes window))
3563 (cons 'margins (window-margins window))
3564 (cons 'scroll-bars (window-scroll-bars window))
3565 (cons 'vscroll (window-vscroll window))
3566 (cons 'dedicated (window-dedicated-p window))
3567 (cons 'point (if markers (copy-marker point) point))
3568 (cons 'start (if markers (copy-marker start) start))
3569 (when mark
3570 (cons 'mark (if markers (copy-marker mark) mark)))))))))
3571 (tail
3572 (when (memq type '(vc hc))
3573 (let (list)
3574 (setq window (window-child window))
3575 (while window
3576 (setq list (cons (window-state-get-1 window markers) list))
3577 (setq window (window-right window)))
3578 (nreverse list)))))
3579 (append head tail)))
3580
3581(defun window-state-get (&optional window markers)
3582 "Return state of WINDOW as a Lisp object.
3583WINDOW can be any window and defaults to the root window of the
3584selected frame.
3585
3586Optional argument MARKERS non-nil means use markers for sampling
3587positions like `window-point' or `window-start'. MARKERS should
3588be non-nil only if the value is used for putting the state back
3589in the same session (note that markers slow down processing).
3590
3591The return value can be used as argument for `window-state-put'
3592to put the state recorded here into an arbitrary window. The
3593value can be also stored on disk and read back in a new session."
3594 (setq window
3595 (if window
3596 (if (window-any-p window)
3597 window
3598 (error "%s is not a live or internal window" window))
3599 (frame-root-window)))
3600 ;; The return value is a cons whose car specifies some constraints on
3601 ;; the size of WINDOW. The cdr lists the states of the subwindows of
3602 ;; WINDOW.
3603 (cons
3604 ;; Frame related things would go into a function, say `frame-state',
3605 ;; calling `window-state-get' to insert the frame's root window.
3606 (window-list-no-nils
3607 (cons 'min-height (window-min-size window))
3608 (cons 'min-width (window-min-size window t))
3609 (cons 'min-height-ignore (window-min-size window nil t))
3610 (cons 'min-width-ignore (window-min-size window t t))
3611 (cons 'min-height-safe (window-min-size window nil 'safe))
3612 (cons 'min-width-safe (window-min-size window t 'safe))
3613 ;; These are probably not needed.
3614 (when (window-size-fixed-p window) (cons 'fixed-height t))
3615 (when (window-size-fixed-p window t) (cons 'fixed-width t)))
3616 (window-state-get-1 window markers)))
3617
3618(defvar window-state-put-list nil
3619 "Helper variable for `window-state-put'.")
3620
3621(defun window-state-put-1 (state &optional window ignore totals)
3622 "Helper function for `window-state-put'."
3623 (let ((type (car state)))
3624 (setq state (cdr state))
3625 (cond
3626 ((eq type 'leaf)
3627 ;; For a leaf window just add unprocessed entries to
3628 ;; `window-state-put-list'.
3629 (setq window-state-put-list
3630 (cons (cons window state) window-state-put-list)))
3631 ((memq type '(vc hc))
3632 (let* ((horizontal (eq type 'hc))
3633 (total (window-total-size window horizontal))
3634 (first t)
3635 size new)
3636 (dolist (item state)
3637 ;; Find the next child window. WINDOW always points to the
3638 ;; real window that we want to fill with what we find here.
3639 (when (memq (car item) '(leaf vc hc))
3640 (if (assq 'last item)
3641 ;; The last child window. Below `window-state-put-1'
3642 ;; will put into it whatever ITEM has in store.
3643 (setq new nil)
3644 ;; Not the last child window, prepare for splitting
3645 ;; WINDOW. SIZE is the new (and final) size of the old
3646 ;; window.
3647 (setq size
3648 (if totals
3649 ;; Use total size.
3650 (cdr (assq (if horizontal 'total-width 'total-height) item))
3651 ;; Use normalized size and round.
3652 (round (* total
3653 (cdr (assq
3654 (if horizontal 'normal-width 'normal-height)
3655 item))))))
3656
3657 ;; Use safe sizes, we try to resize later.
3658 (setq size (max size (if horizontal
3659 window-safe-min-height
3660 window-safe-min-width)))
3661
3662 (if (window-sizable-p window (- size) horizontal 'safe)
3663 (let* ((window-nest (assq 'nest item)))
3664 ;; We must inherit the nesting, otherwise we might mess
3665 ;; up handling of atomic and side window.
3666 (setq new (split-window window size horizontal)))
3667 ;; Give up if we can't resize window down to safe sizes.
3668 (error "Cannot resize window %s" window))
3669
3670 (when first
3671 (setq first nil)
3672 ;; When creating the first child window add for parent
3673 ;; unprocessed entries to `window-state-put-list'.
3674 (setq window-state-put-list
3675 (cons (cons (window-parent window) state)
3676 window-state-put-list))))
3677
3678 ;; Now process the current window (either the one we've just
3679 ;; split or the last child of its parent).
3680 (window-state-put-1 item window ignore totals)
3681 ;; Continue with the last window split off.
3682 (setq window new))))))))
3683
3684(defun window-state-put-2 (ignore)
3685 "Helper function for `window-state-put'."
3686 (dolist (item window-state-put-list)
3687 (let ((window (car item))
3688 (clone-number (cdr (assq 'clone-number item)))
3689 (splits (cdr (assq 'splits item)))
3690 (nest (cdr (assq 'nest item)))
3691 (parameters (cdr (assq 'parameters item)))
3692 (state (cdr (assq 'buffer item))))
3693 ;; Put in clone-number.
3694 (when clone-number (set-window-clone-number window clone-number))
3695 (when splits (set-window-splits window splits))
3696 (when nest (set-window-nest window nest))
3697 ;; Process parameters.
3698 (when parameters
3699 (dolist (parameter parameters)
3700 (set-window-parameter window (car parameter) (cdr parameter))))
3701 ;; Process buffer related state.
3702 (when state
3703 ;; We don't want to raise an error here so we create a buffer if
3704 ;; there's none.
3705 (set-window-buffer window (get-buffer-create (car state)))
3706 (with-current-buffer (window-buffer window)
3707 (set-window-hscroll window (cdr (assq 'hscroll state)))
3708 (apply 'set-window-fringes
3709 (cons window (cdr (assq 'fringes state))))
3710 (let ((margins (cdr (assq 'margins state))))
3711 (set-window-margins window (car margins) (cdr margins)))
3712 (let ((scroll-bars (cdr (assq 'scroll-bars state))))
3713 (set-window-scroll-bars
3714 window (car scroll-bars) (nth 2 scroll-bars) (nth 3 scroll-bars)))
3715 (set-window-vscroll window (cdr (assq 'vscroll state)))
3716 ;; Adjust vertically.
3717 (if (memq window-size-fixed '(t height))
3718 ;; A fixed height window, try to restore the original size.
3719 (let ((delta (- (cdr (assq 'total-height item))
3720 (window-total-height window)))
3721 window-size-fixed)
3722 (when (window-resizable-p window delta)
3723 (resize-window window delta)))
3724 ;; Else check whether the window is not high enough.
3725 (let* ((min-size (window-min-size window nil ignore))
3726 (delta (- min-size (window-total-size window))))
3727 (when (and (> delta 0)
3728 (window-resizable-p window delta nil ignore))
3729 (resize-window window delta nil ignore))))
3730 ;; Adjust horizontally.
3731 (if (memq window-size-fixed '(t width))
3732 ;; A fixed width window, try to restore the original size.
3733 (let ((delta (- (cdr (assq 'total-width item))
3734 (window-total-width window)))
3735 window-size-fixed)
3736 (when (window-resizable-p window delta)
3737 (resize-window window delta)))
3738 ;; Else check whether the window is not wide enough.
3739 (let* ((min-size (window-min-size window t ignore))
3740 (delta (- min-size (window-total-size window t))))
3741 (when (and (> delta 0)
3742 (window-resizable-p window delta t ignore))
3743 (resize-window window delta t ignore))))
3744 ;; Set dedicated status.
3745 (set-window-dedicated-p window (cdr (assq 'dedicated state)))
3746 ;; Install positions (maybe we should do this after all windows
3747 ;; have been created and sized).
3748 (ignore-errors
3749 (set-window-start window (cdr (assq 'start state)))
3750 (set-window-point window (cdr (assq 'point state)))
3751 ;; I'm not sure whether we should set the mark here, but maybe
3752 ;; it can be used.
3753 (let ((mark (cdr (assq 'mark state))))
3754 (when mark (set-mark mark))))
3755 ;; Select window if it's the selected one.
3756 (when (cdr (assq 'selected state))
3757 (select-window window)))))))
3758
3759(defun window-state-put (state &optional window ignore)
3760 "Put window state STATE into WINDOW.
3761STATE should be the state of a window returned by an earlier
3762invocation of `window-state-get'. Optional argument WINDOW must
3763specify a live window and defaults to the selected one.
3764
3765Optional argument IGNORE non-nil means ignore minimum window
3766sizes and fixed size restrictions. IGNORE equal `safe' means
3767subwindows can get as small as `window-safe-min-height' and
3768`window-safe-min-width'."
3769 (setq window (normalize-live-window window))
3770 (let* ((frame (window-frame window))
3771 (head (car state))
3772 ;; We check here (1) whether the total sizes of root window of
3773 ;; STATE and that of WINDOW are equal so we can avoid
3774 ;; calculating new sizes, and (2) if we do have to resize
3775 ;; whether we can do so without violating size restrictions.
3776 (totals
3777 (and (= (window-total-size window)
3778 (cdr (assq 'total-height state)))
3779 (= (window-total-size window t)
3780 (cdr (assq 'total-width state)))))
3781 (min-height (cdr (assq 'min-height head)))
3782 (min-width (cdr (assq 'min-width head)))
3783 window-splits selected)
3784 (if (and (not totals)
3785 (or (> min-height (window-total-size window))
3786 (> min-width (window-total-size window t)))
3787 (or (not ignore)
3788 (and (setq min-height
3789 (cdr (assq 'min-height-ignore head)))
3790 (setq min-width
3791 (cdr (assq 'min-width-ignore head)))
3792 (or (> min-height (window-total-size window))
3793 (> min-width (window-total-size window t)))
3794 (or (not (eq ignore 'safe))
3795 (and (setq min-height
3796 (cdr (assq 'min-height-safe head)))
3797 (setq min-width
3798 (cdr (assq 'min-width-safe head)))
3799 (or (> min-height
3800 (window-total-size window))
3801 (> min-width
3802 (window-total-size window t))))))))
3803 ;; The check above might not catch all errors due to rounding
3804 ;; issues - so IGNORE equal 'safe might not always produce the
3805 ;; minimum possible state. But such configurations hardly make
3806 ;; sense anyway.
3807 (error "Window %s too small to accomodate state" window)
3808 (setq state (cdr state))
3809 (setq window-state-put-list nil)
3810 ;; Work on the windows of a temporary buffer to make sure that
3811 ;; splitting proceeds regardless of any buffer local values of
3812 ;; `window-size-fixed'. Release that buffer after the buffers of
3813 ;; all live windows have been set by `window-state-put-2'.
3814 (with-temp-buffer
3815 (set-window-buffer window (current-buffer))
3816 (window-state-put-1 state window nil totals)
3817 (window-state-put-2 ignore))
3818 (window-check frame))))
3457 3819
3458 3820;;; Displaying buffers.
3459(defconst display-buffer-default-specifiers 3821(defconst display-buffer-default-specifiers
3460 '((reuse-window nil same visible) 3822 '((reuse-window nil same visible)
3461 (pop-up-window (largest . nil) (lru . nil)) 3823 (pop-up-window (largest . nil) (lru . nil))
3462 (pop-up-frame) 3824 (pop-up-window-min-height . 40)
3463 (pop-up-frame-alist 3825 (pop-up-window-min-width . 80)
3464 (height . 24) (width . 80) (unsplittable . t)) 3826 (reuse-window other nil nil)
3465 (reuse-window nil other visible) 3827 (reuse-window nil other visible)
3828 (reuse-window nil nil t)
3466 (reuse-window-even-sizes . t)) 3829 (reuse-window-even-sizes . t))
3467 "Buffer display default specifiers. 3830 "Buffer display default specifiers.
3468The value specified here is used when no other specifiers have 3831The value specified here is used when no other specifiers have
@@ -3479,12 +3842,11 @@ buffer display specifiers.")
3479 (reuse-window nil same nil) 3842 (reuse-window nil same nil)
3480 (pop-up-window (largest . nil) (lru . nil)) 3843 (pop-up-window (largest . nil) (lru . nil))
3481 (reuse-window nil other nil)) 3844 (reuse-window nil other nil))
3482 (other-window 3845 ;; (other-window
3483 ;; Avoid selected window. 3846 ;; ;; Avoid selected window.
3484 (reuse-window other same visible) 3847 ;; (reuse-window other same visible)
3485 (pop-up-window (largest . nil) (lru . nil)) 3848 ;; (pop-up-window (largest . nil) (lru . nil))
3486 (pop-up-frame) 3849 ;; (reuse-window other other visible))
3487 (reuse-window other other visible))
3488 (same-frame-other-window 3850 (same-frame-other-window
3489 ;; Avoid other frames and selected window. 3851 ;; Avoid other frames and selected window.
3490 (reuse-window other same nil) 3852 (reuse-window other same nil)
@@ -3502,10 +3864,16 @@ buffer display specifiers.")
3502 3864
3503(defcustom display-buffer-alist 3865(defcustom display-buffer-alist
3504 '((((regexp . ".*")) 3866 '((((regexp . ".*"))
3505 reuse-window (reuse-window nil same visible) 3867 ;; Reuse window showing same buffer on same frame.
3868 reuse-window (reuse-window nil same nil)
3869 ;; Pop up window.
3506 pop-up-window 3870 pop-up-window
3871 ;; Split largest or lru window.
3507 (pop-up-window (largest . nil) (lru . nil)) 3872 (pop-up-window (largest . nil) (lru . nil))
3508 reuse-window (reuse-window other other nil) 3873 (pop-up-window-min-height . 40) ; split-height-threshold / 2
3874 (pop-up-window-min-width . 80) ; split-width-threshold / 2
3875 ;; Reuse any but selected window on same frame.
3876 reuse-window (reuse-window other nil nil)
3509 (reuse-window-even-sizes . t))) 3877 (reuse-window-even-sizes . t)))
3510 "List associating buffer identifiers with display specifiers. 3878 "List associating buffer identifiers with display specifiers.
3511The car of each element of this list is built from a set of cons 3879The car of each element of this list is built from a set of cons
@@ -3766,6 +4134,14 @@ supported:
3766 4134
3767- t to strongly dedicate the window to the buffer. 4135- t to strongly dedicate the window to the buffer.
3768 4136
4137A cons cell whose car is `other-window-means-other-frame' and
4138whose cdr is non-nil means that you want calls of
4139`display-buffer' with the second argument t or the symbol
4140`other-window' to display the buffer in another frame. This
4141means, for example, that you prefer functions like
4142`find-file-other-window' or `switch-to-buffer-other-window' to
4143make a new frame instead of a new window on the selected frame.
4144
3769Usually, applications are free to override the specifiers of 4145Usually, applications are free to override the specifiers of
3770`display-buffer-alist' by passing their own specifiers as second 4146`display-buffer-alist' by passing their own specifiers as second
3771argument of `display-buffer'. For every `display-buffer-alist' 4147argument of `display-buffer'. For every `display-buffer-alist'
@@ -3997,9 +4373,7 @@ using the location specifiers `same-window' or `other-frame'."
3997 (list 4373 (list
3998 :tag "Pop-up frame" 4374 :tag "Pop-up frame"
3999 :value (pop-up-frame 4375 :value (pop-up-frame
4000 (pop-up-frame) 4376 (pop-up-frame))
4001 (pop-up-frame-alist
4002 (height . 24) (width . 80) (unsplittable . t)))
4003 :format "%t\n%v" 4377 :format "%t\n%v"
4004 :inline t 4378 :inline t
4005 (const :format "" pop-up-frame) 4379 (const :format "" pop-up-frame)
@@ -4210,6 +4584,15 @@ using the location specifiers `same-window' or `other-frame'."
4210 :format "%[No other window%] %v\n" :size 15 4584 :format "%[No other window%] %v\n" :size 15
4211 (const :tag "Off" :format "%t" nil) 4585 (const :tag "Off" :format "%t" nil)
4212 (const :tag "Ignore" :format "%t" t))) 4586 (const :tag "Ignore" :format "%t" t)))
4587 ;; Other window means other frame.
4588 (cons
4589 :format "%v"
4590 (const :format "" other-window-means-other-frame)
4591 (choice
4592 :help-echo "Whether other window means same or other frame."
4593 :format "%[Same or other frame%] %v\n" :size 15
4594 (const :tag "Same frame" :format "%t" nil)
4595 (const :tag "Other frame" :format "%t" t)))
4213 ;; Overriding. 4596 ;; Overriding.
4214 (cons 4597 (cons
4215 :format "%v\n" 4598 :format "%v\n"
@@ -4340,22 +4723,6 @@ documentation of `display-buffer-alist' for a description."
4340 ((functionp set-width) 4723 ((functionp set-width)
4341 (ignore-errors (funcall set-width window)))))) 4724 (ignore-errors (funcall set-width window))))))
4342 4725
4343;; We have to work around the deficiency that the command loop does not
4344;; preserve the selected window when it is on a frame that hasn't been
4345;; raised or given input focus. So we have to (1) select the window
4346;; used for displaying a buffer and (2) raise its frame if necessary,
4347;; thus defeating one primary principle of `display-buffer' namely to
4348;; _not_ select the window chosen for displaying the buffer :-(
4349(defun display-buffer-select-window (window &optional norecord)
4350 "Select WINDOW and raise its frame if necessary."
4351 (let ((old-frame (selected-frame))
4352 (new-frame (window-frame window)))
4353 ;; Select WINDOW _before_ raising the frame to assure that the mouse
4354 ;; cursor moves into the correct window.
4355 (select-window window norecord)
4356 (unless (eq old-frame new-frame)
4357 (select-frame-set-input-focus new-frame))))
4358
4359(defun display-buffer-in-window (buffer window specifiers) 4726(defun display-buffer-in-window (buffer window specifiers)
4360 "Display BUFFER in WINDOW and raise its frame if needed. 4727 "Display BUFFER in WINDOW and raise its frame if needed.
4361WINDOW must be a live window and defaults to the selected one. 4728WINDOW must be a live window and defaults to the selected one.
@@ -4376,8 +4743,16 @@ documentation of `display-buffer-alist' for a description."
4376 (set-window-dedicated-p window dedicated)) 4743 (set-window-dedicated-p window dedicated))
4377 (when no-other-window 4744 (when no-other-window
4378 (set-window-parameter window 'no-other-window t)) 4745 (set-window-parameter window 'no-other-window t))
4379 (unless (eq old-frame new-frame) 4746 (unless (or (eq old-frame new-frame)
4380 (display-buffer-select-window window)) 4747 (not (frame-visible-p new-frame))
4748 ;; Assume the selected frame is already visible enough.
4749 (eq new-frame (selected-frame))
4750 ;; Assume the frame from which we invoked the minibuffer
4751 ;; is visible.
4752 (and (minibuffer-window-active-p (selected-window))
4753 (eq new-frame
4754 (window-frame (minibuffer-selected-window)))))
4755 (raise-frame new-frame))
4381 ;; Return window. 4756 ;; Return window.
4382 window)) 4757 window))
4383 4758
@@ -4705,7 +5080,8 @@ non-nil means to make a new frame on graphic displays only.
4705 5080
4706SPECIFIERS must be a list of buffer display specifiers, see the 5081SPECIFIERS must be a list of buffer display specifiers, see the
4707documentation of `display-buffer-alist' for a description." 5082documentation of `display-buffer-alist' for a description."
4708 (unless (and graphic-only (not (display-graphic-p))) 5083 (unless (or (and graphic-only (not (display-graphic-p)))
5084 noninteractive)
4709 (let* ((selected-window (selected-window)) 5085 (let* ((selected-window (selected-window))
4710 (function (or (cdr (assq 'pop-up-frame-function specifiers)) 5086 (function (or (cdr (assq 'pop-up-frame-function specifiers))
4711 'make-frame)) 5087 'make-frame))
@@ -4906,16 +5282,49 @@ BUFFER-OR-NAME and return that buffer."
4906 buffer)) 5282 buffer))
4907 (current-buffer))) 5283 (current-buffer)))
4908 5284
4909(defun display-buffer-normalize-specifiers-1 (specifiers) 5285(defun display-buffer-other-window-means-other-frame (buffer-or-name &optional label)
4910 "Subroutine of `display-buffer-normalize-specifiers'. 5286 "Return non-nil if BUFFER shall be preferably displayed in another frame.
4911SPECIFIERS is the SPECIFIERS argument of `display-buffer'." 5287BUFFER must be a live buffer or the name of a live buffer.
4912 (let (normalized) 5288
5289Return nil if BUFFER shall be preferably displayed in another
5290window on the selected frame. Return non-nil if BUFFER shall be
5291preferably displayed in a window on any but the selected frame.
5292
5293Optional argument LABEL is like the same argument of
5294`display-buffer'.
5295
5296The calculation of the return value is exclusively based on the
5297user preferences expressed in `display-buffer-alist'."
5298 (let* ((buffer (normalize-live-buffer buffer-or-name))
5299 (list (display-buffer-normalize-alist (buffer-name buffer) label))
5300 (value (assq 'other-window-means-other-frame
5301 (or (car list) (cdr list)))))
5302 (when value (cdr value))))
5303
5304(defun display-buffer-normalize-argument (buffer-name specifiers label other-frame)
5305 "Normalize second argument of `display-buffer'.
5306BUFFER-NAME is the name of the buffer that shall be displayed,
5307SPECIFIERS is the second argument of `display-buffer'. LABEL the
5308same argument of `display-buffer'. OTHER-FRAME non-nil means use
5309other-frame for other-window."
5310 (let (normalized entry)
4913 (cond 5311 (cond
5312 ((not specifiers)
5313 nil)
4914 ((listp specifiers) 5314 ((listp specifiers)
5315 ;; If SPECIFIERS is a list, we assume it is a list of specifiers.
4915 (dolist (specifier specifiers) 5316 (dolist (specifier specifiers)
4916 (cond 5317 (cond
4917 ((consp specifier) 5318 ((consp specifier)
4918 (setq normalized (cons specifier normalized))) 5319 (setq normalized (cons specifier normalized)))
5320 ((eq specifier 'other-window)
5321 ;; `other-window' must be treated separately.
5322 (let ((entry (assq (if other-frame
5323 'other-frame
5324 'same-frame-other-window)
5325 display-buffer-macro-specifiers)))
5326 (dolist (item (cdr entry))
5327 (setq normalized (cons item normalized)))))
4919 ((symbolp specifier) 5328 ((symbolp specifier)
4920 ;; Might be a macro specifier, try to expand it (the cdr is a 5329 ;; Might be a macro specifier, try to expand it (the cdr is a
4921 ;; list and we have to reverse it later, so do it one at a 5330 ;; list and we have to reverse it later, so do it one at a
@@ -4924,34 +5333,37 @@ SPECIFIERS is the SPECIFIERS argument of `display-buffer'."
4924 (dolist (item (cdr entry)) 5333 (dolist (item (cdr entry))
4925 (setq normalized (cons item normalized))))))) 5334 (setq normalized (cons item normalized)))))))
4926 ;; Reverse list. 5335 ;; Reverse list.
4927 (setq normalized (nreverse normalized))) 5336 (nreverse normalized))
4928 ;; The two cases below must come from the SPECIFIERS argument of 5337 ((setq entry (assq specifiers display-buffer-macro-specifiers))
4929 ;; `display-buffer'. 5338 ;; A macro specifier.
4930 ((eq specifiers 't) 5339 (cdr entry))
4931 ;; Historically t means "other window". Eventually we should get 5340 ((or other-frame (with-no-warnings pop-up-frames))
4932 ;; rid of this. 5341 ;; Pop up another frame.
4933 (setq normalized 5342 (cdr (assq 'other-frame display-buffer-macro-specifiers)))
4934 (cdr (assq 'other-window display-buffer-macro-specifiers)) 5343 (t
4935 normalized)) 5344 ;; In any other case pop up a new window.
4936 ((symbolp specifiers) 5345 (cdr (assq 'same-frame-other-window display-buffer-macro-specifiers))))))
4937 ;; We allow scalar specifiers in calls of `display-buffer'. 5346
4938 (let ((entry (assq specifiers display-buffer-macro-specifiers))) 5347(defun display-buffer-normalize-options (buffer-or-name)
4939 (when entry (setq normalized (cdr entry))))))
4940
4941 normalized))
4942
4943(defun display-buffer-normalize-specifiers-2 (&optional buffer-or-name)
4944 "Subroutine of `display-buffer-normalize-specifiers'. 5348 "Subroutine of `display-buffer-normalize-specifiers'.
4945BUFFER-OR-NAME is the buffer to display. This routine provides a 5349BUFFER-OR-NAME is the buffer to display. This routine provides a
4946compatibility layer for the now obsolete Emacs 23 buffer display 5350compatibility layer for the now obsolete Emacs 23 buffer display
4947options." 5351options."
4948 (let* ((buffer (normalize-live-buffer buffer-or-name)) 5352 (with-no-warnings
4949 (buffer-name (buffer-name buffer)) 5353 (let* ((buffer (normalize-live-buffer buffer-or-name))
4950 specifiers) 5354 (buffer-name (buffer-name buffer))
4951 ;; Disable warnings, there are too many obsolete options here. 5355 (use-pop-up-frames
4952 (with-no-warnings 5356 (or (and (eq pop-up-frames 'graphic-only)
5357 (display-graphic-p))
5358 pop-up-frames))
5359 specifiers)
5360 ;; `even-window-heights', unless nil or unset.
5361 (unless (memq even-window-heights '(nil unset))
5362 (setq specifiers
5363 (cons (cons 'reuse-window-even-sizes t) specifiers)))
5364
4953 ;; `display-buffer-mark-dedicated' 5365 ;; `display-buffer-mark-dedicated'
4954 (unless (memq display-buffer-mark-dedicated '(nil unset)) 5366 (when display-buffer-mark-dedicated
4955 (setq specifiers 5367 (setq specifiers
4956 (cons (cons 'dedicate display-buffer-mark-dedicated) 5368 (cons (cons 'dedicate display-buffer-mark-dedicated)
4957 specifiers))) 5369 specifiers)))
@@ -4968,25 +5380,31 @@ options."
4968 (min-width (if (numberp split-width-threshold) 5380 (min-width (if (numberp split-width-threshold)
4969 (/ split-width-threshold 2) 5381 (/ split-width-threshold 2)
4970 1.0))) 5382 1.0)))
4971 (when pop-up-window 5383 ;; Create an entry only if a default value was changed.
4972 ;; `split-height-threshold' 5384 (when (or pop-up-window
5385 (not (equal split-height-threshold 80))
5386 (not (equal split-width-threshold 160)))
5387 ;; `reuse-window' (needed as fallback when popping up the new
5388 ;; window fails).
4973 (setq specifiers 5389 (setq specifiers
4974 (cons (cons 'pop-up-window-min-height min-height) 5390 (cons (list 'reuse-window 'other nil nil)
4975 specifiers)) 5391 specifiers))
4976 ;; `split-width-threshold' 5392 ;; `split-width-threshold'
4977 (setq specifiers 5393 (setq specifiers
4978 (cons (cons 'pop-up-window-min-width min-width) 5394 (cons (cons 'pop-up-window-min-width min-width)
4979 specifiers)) 5395 specifiers))
5396 ;; `split-height-threshold'
5397 (setq specifiers
5398 (cons (cons 'pop-up-window-min-height min-height)
5399 specifiers))
4980 ;; `pop-up-window' 5400 ;; `pop-up-window'
4981 (setq specifiers 5401 (setq specifiers
4982 (cons (list 'pop-up-window 5402 (cons (list 'pop-up-window
4983 (cons 'largest fun) (cons 'lru fun)) 5403 (cons 'largest fun) (cons 'lru fun))
4984 specifiers)))) 5404 specifiers))))
4985 5405
4986 ;; `pop-up-frame' group. Anything is added here iff 5406 ;; `pop-up-frame' group.
4987 ;; `pop-up-frames' is neither nil nor unset (we ignore the problem 5407 (when use-pop-up-frames
4988 ;; that callers usually don't care about graphic-only).
4989 (unless (memq pop-up-frames '(nil unset))
4990 ;; `pop-up-frame-function'. If `pop-up-frame-function' uses the 5408 ;; `pop-up-frame-function'. If `pop-up-frame-function' uses the
4991 ;; now obsolete `pop-up-frame-alist' it will continue to do so. 5409 ;; now obsolete `pop-up-frame-alist' it will continue to do so.
4992 (setq specifiers 5410 (setq specifiers
@@ -4994,165 +5412,90 @@ options."
4994 specifiers)) 5412 specifiers))
4995 ;; `pop-up-frame' 5413 ;; `pop-up-frame'
4996 (setq specifiers 5414 (setq specifiers
4997 (cons (list 'pop-up-frame pop-up-frames) specifiers))) 5415 (cons (list 'pop-up-frame t) specifiers)))
4998
4999 ;; `special-display-regexps'
5000 (dolist (entry special-display-regexps)
5001 (cond
5002 ((stringp entry)
5003 ;; Plain string.
5004 (when (string-match-p entry buffer-name)
5005 (setq specifiers
5006 (cons
5007 (list 'fun-with-args special-display-function
5008 special-display-frame-alist)
5009 specifiers))))
5010 ((consp entry)
5011 (let ((name (car entry))
5012 (rest (cdr entry)))
5013 (cond
5014 ((not (string-match-p name buffer-name)))
5015 ((functionp (car rest))
5016 ;; A function.
5017 (setq specifiers
5018 (cons (list 'fun-with-args (car rest) (cadr rest))
5019 specifiers)))
5020 ((listp rest)
5021 ;; A list of parameters.
5022 (cond
5023 ((assq 'same-window rest)
5024 (setq specifiers
5025 (cons (list 'reuse-window 'same) specifiers))
5026 (setq specifiers
5027 (cons (list 'reuse-window-dedicated 'weak)
5028 specifiers)))
5029 ((assq 'same-frame rest)
5030 (setq specifiers
5031 (setq specifiers
5032 (cons (list 'same-frame) specifiers))))
5033 (t
5034 (setq specifiers
5035 (cons (list 'fun-with-args special-display-function
5036 special-display-frame-alist)
5037 specifiers))))))))))
5038
5039 ;; `special-display-buffer-names'
5040 (dolist (entry special-display-buffer-names)
5041 (cond
5042 ((stringp entry)
5043 ;; Plain string.
5044 (when (string-equal entry buffer-name)
5045 (setq specifiers
5046 (cons
5047 (list 'fun-with-args special-display-function
5048 special-display-frame-alist)
5049 specifiers))))
5050 ((consp entry)
5051 (let ((name (car entry))
5052 (rest (cdr entry)))
5053 (cond
5054 ((not (string-equal name buffer-name)))
5055 ((functionp (car rest))
5056 ;; A function.
5057 (setq specifiers
5058 (cons (list 'fun-with-args (car rest) (cadr rest))
5059 specifiers)))
5060 ((listp rest)
5061 ;; A list of parameters.
5062 (cond
5063 ((assq 'same-window rest)
5064 (setq specifiers
5065 (cons (list 'reuse-window 'same) specifiers))
5066 (setq specifiers
5067 (cons (list 'reuse-window-dedicated 'weak)
5068 specifiers)))
5069 ((assq 'same-frame rest)
5070 (setq specifiers
5071 (setq specifiers
5072 (cons (list 'same-frame) specifiers))))
5073 (t
5074 (setq specifiers
5075 (cons (list 'fun-with-args special-display-function
5076 special-display-frame-alist)
5077 specifiers))))))))))
5078
5079 ;; `same-window-regexps'
5080 (dolist (entry same-window-regexps)
5081 (cond
5082 ((stringp entry)
5083 (when (string-match-p entry buffer-name)
5084 (setq specifiers
5085 (cons (list 'reuse-window 'same) specifiers))))
5086 ((consp entry)
5087 (when (string-match-p (car entry) buffer-name)
5088 (setq specifiers
5089 (cons (list 'reuse-window 'same) specifiers))))))
5090 5416
5091 ;; `same-window-buffer-names' 5417 ;; `pop-up-windows' and `use-pop-up-frames' both nil means means
5092 (dolist (entry same-window-buffer-names) 5418 ;; we are supposed to reuse any window on the same frame (unless
5093 (cond 5419 ;; we find one showing the same buffer already).
5094 ((stringp entry) 5420 (unless (or pop-up-windows use-pop-up-frames)
5095 (when (string-equal entry buffer-name)
5096 (setq specifiers
5097 (cons (list 'reuse-window 'same) specifiers))))
5098 ((consp entry)
5099 (when (string-equal (car entry) buffer-name)
5100 (setq specifiers
5101 (cons (list 'reuse-window 'same) specifiers))))))
5102
5103 ;; `pop-up-windows' and `pop-up-frames' nil means means we
5104 ;; are supposed to reuse any window (unless we find one showing
5105 ;; the same buffer already).
5106
5107 ;; This clause is needed because Emacs 23 options can be used to
5108 ;; suppress a certain behavior while `display-buffer-alist' can be
5109 ;; only used to enforce some behavior.
5110 (when (and (not pop-up-windows) (memq pop-up-frames '(nil unset)))
5111 ;; `even-window-heights'
5112 (when even-window-heights
5113 (setq specifiers
5114 (cons (cons 'reuse-window-even-sizes t) specifiers)))
5115 ;; `reuse-window' showing any buffer on same frame. 5421 ;; `reuse-window' showing any buffer on same frame.
5116 (setq specifiers 5422 (setq specifiers
5117 (cons (list 'reuse-window nil nil nil) 5423 (cons (list 'reuse-window nil nil nil)
5118 specifiers))) 5424 specifiers)))
5119 5425
5120 ;; `display-buffer-reuse-frames' or `pop-up-frames' set means we 5426 ;; `special-display-p' group.
5121 ;; are supposed to reuse a window showing the same buffer. 5427 (when special-display-function
5122 (unless (and (memq display-buffer-reuse-frames '(nil unset)) 5428 ;; `special-display-p' returns either t or a list of frame
5123 (memq pop-up-frames '(nil unset))) 5429 ;; parameters to pass to `special-display-function'.
5124 ;; `even-window-heights' 5430 (let ((pars (special-display-p buffer-name)))
5125 (when even-window-heights 5431 (when pars
5432 (setq specifiers
5433 (cons (list 'fun-with-args special-display-function
5434 (when (listp pars) pars))
5435 specifiers)))))
5436
5437 ;; `pop-up-frames', `display-buffer-reuse-frames' means search for
5438 ;; a window showing the buffer on some visible or iconfied frame.
5439 ;; `last-nonminibuffer-frame' set and not the same frame means
5440 ;; search that frame.
5441 (let ((frames (or (and (or use-pop-up-frames
5442 display-buffer-reuse-frames
5443 (not (last-nonminibuffer-frame)))
5444 ;; All visible or iconfied frames.
5445 0)
5446 ;; Same frame.
5447 (last-nonminibuffer-frame))))
5448 (when frames
5126 (setq specifiers 5449 (setq specifiers
5127 (cons (cons 'reuse-window-even-sizes t) specifiers))) 5450 (cons (list 'reuse-window 'other 'same frames)
5128 ;; `reuse-window' showing same buffer on visible frame. 5451 specifiers))))
5452
5453 ;; `same-window-p' group.
5454 (when (same-window-p buffer-name)
5455 ;; Try to reuse the same (selected) window.
5129 (setq specifiers 5456 (setq specifiers
5130 (cons (list 'reuse-window nil 'same 0) 5457 (cons (list 'reuse-window 'same nil nil)
5131 specifiers))) 5458 specifiers)))
5132 5459
5133 specifiers))) 5460 ;; Prepend "reuse window on same frame if showing the buffer
5461 ;; already" specifier. It will be overriden by the application
5462 ;; supplied 'other-window specifier.
5463 (setq specifiers (cons (list 'reuse-window nil 'same nil)
5464 specifiers))
5134 5465
5135(defun display-buffer-normalize-specifiers (buffer-name specifiers label) 5466 specifiers)))
5136 "Return normalized specifiers for a buffer matching BUFFER-NAME or LABEL.
5137BUFFER-NAME must be a string specifying a valid buffer name.
5138SPECIFIERS and LABEL are the homonymous arguments of
5139`display-buffer'.
5140
5141The method for displaying the buffer specified by BUFFER-NAME or
5142LABEL is established by appending the following four lists of
5143specifiers:
5144
5145- The specifiers in `display-buffer-alist' whose buffer
5146 identifier matches BUFFER-NAME or LABEL and whose 'override
5147 component is set.
5148
5149- SPECIFIERS.
5150
5151- The specifiers in `display-buffer-alist' whose buffer
5152 identifier matches BUFFER-NAME or LABEL and whose 'override
5153 component is not set.
5154 5467
5155- `display-buffer-default-specifiers'." 5468(defun display-buffer-normalize-alist-1 (specifiers label)
5469 "Subroutine of `display-buffer-normalize-alist'.
5470SPECIFIERS is a list of buffer display specfiers. LABEL is the
5471same argument of `display-buffer'."
5472 (let (normalized entry)
5473 (cond
5474 ((not specifiers)
5475 nil)
5476 ((listp specifiers)
5477 ;; If SPECIFIERS is a list, we assume it is a list of specifiers.
5478 (dolist (specifier specifiers)
5479 (cond
5480 ((consp specifier)
5481 (setq normalized (cons specifier normalized)))
5482 ((symbolp specifier)
5483 ;; Might be a macro specifier, try to expand it (the cdr is a
5484 ;; list and we have to reverse it later, so do it one at a
5485 ;; time).
5486 (let ((entry (assq specifier display-buffer-macro-specifiers)))
5487 (dolist (item (cdr entry))
5488 (setq normalized (cons item normalized)))))))
5489 ;; Reverse list.
5490 (nreverse normalized))
5491 ((setq entry (assq specifiers display-buffer-macro-specifiers))
5492 ;; A macro specifier.
5493 (cdr entry)))))
5494
5495(defun display-buffer-normalize-alist (buffer-name label)
5496 "Normalize `display-buffer-alist'.
5497BUFFER-NAME must be the name of the buffer that shall be displayed.
5498LABEL the corresponding argument of `display-buffer'."
5156 (let (list-1 list-2) 5499 (let (list-1 list-2)
5157 (dolist (entry display-buffer-alist) 5500 (dolist (entry display-buffer-alist)
5158 (when (and (listp entry) 5501 (when (and (listp entry)
@@ -5167,9 +5510,10 @@ specifiers:
5167 (string-match-p value buffer-name)) 5510 (string-match-p value buffer-name))
5168 (and (eq type 'label) (eq value label))) 5511 (and (eq type 'label) (eq value label)))
5169 (throw 'match t))))))) 5512 (throw 'match t)))))))
5170 (let* ((raw (cdr entry)) 5513 (let* ((specifiers (cdr entry))
5171 (normalized (display-buffer-normalize-specifiers-1 raw))) 5514 (normalized
5172 (if (assq 'override raw) 5515 (display-buffer-normalize-alist-1 specifiers label)))
5516 (if (assq 'override specifiers)
5173 (setq list-1 5517 (setq list-1
5174 (if list-1 5518 (if list-1
5175 (append list-1 normalized) 5519 (append list-1 normalized)
@@ -5179,15 +5523,46 @@ specifiers:
5179 (append list-2 normalized) 5523 (append list-2 normalized)
5180 normalized)))))) 5524 normalized))))))
5181 5525
5526 (cons list-1 list-2)))
5527
5528(defvar display-buffer-normalize-options-inhibit nil
5529 "If non-nil, `display-buffer' doesn't process obsolete options.")
5530
5531(defun display-buffer-normalize-specifiers (buffer-name specifiers label)
5532 "Return normalized specifiers for a buffer matching BUFFER-NAME or LABEL.
5533BUFFER-NAME must be a string specifying a valid buffer name.
5534SPECIFIERS and LABEL are the homonymous arguments of
5535`display-buffer'.
5536
5537The method for displaying the buffer specified by BUFFER-NAME or
5538LABEL is established by appending the following four lists of
5539specifiers:
5540
5541- The specifiers in `display-buffer-alist' whose buffer
5542 identifier matches BUFFER-NAME or LABEL and whose 'override
5543 component is set.
5544
5545- SPECIFIERS.
5546
5547- The specifiers in `display-buffer-alist' whose buffer
5548 identifier matches BUFFER-NAME or LABEL and whose 'override
5549 component is not set.
5550
5551- `display-buffer-default-specifiers'."
5552 (let* ((list (display-buffer-normalize-alist buffer-name label))
5553 (other-frame (assq 'other-window-means-other-frame
5554 (or (car list) (cdr list)))))
5182 (append 5555 (append
5183 ;; Overriding user specifiers. 5556 ;; Overriding user specifiers.
5184 list-1 5557 (car list)
5185 ;; Application specifiers. 5558 ;; Application specifiers.
5186 (display-buffer-normalize-specifiers-1 specifiers) 5559 (display-buffer-normalize-argument
5560 buffer-name specifiers label other-frame)
5187 ;; Emacs 23 compatibility specifiers. 5561 ;; Emacs 23 compatibility specifiers.
5188 (display-buffer-normalize-specifiers-2 buffer-name) 5562 (unless display-buffer-normalize-options-inhibit
5563 (display-buffer-normalize-options buffer-name))
5189 ;; Non-overriding user specifiers. 5564 ;; Non-overriding user specifiers.
5190 list-2 5565 (cdr list)
5191 ;; Default specifiers. 5566 ;; Default specifiers.
5192 display-buffer-default-specifiers))) 5567 display-buffer-default-specifiers)))
5193 5568
@@ -5301,8 +5676,8 @@ this list as arguments."
5301 ;; Try reusing a window not showing BUFFER on any visible or 5676 ;; Try reusing a window not showing BUFFER on any visible or
5302 ;; iconified frame. 5677 ;; iconified frame.
5303 (display-buffer-reuse-window buffer '(nil other 0)) 5678 (display-buffer-reuse-window buffer '(nil other 0))
5304 ;; Try making a new frame (but not in batch mode). 5679 ;; Try making a new frame.
5305 (and (not noninteractive) (display-buffer-pop-up-frame buffer)) 5680 (display-buffer-pop-up-frame buffer)
5306 ;; Try using a weakly dedicated window. 5681 ;; Try using a weakly dedicated window.
5307 (display-buffer-reuse-window 5682 (display-buffer-reuse-window
5308 buffer '(nil nil t) '((reuse-window-dedicated . weak))) 5683 buffer '(nil nil t) '((reuse-window-dedicated . weak)))
@@ -5388,11 +5763,21 @@ documentations of `display-buffer' and `display-buffer-alist' for
5388additional information." 5763additional information."
5389 (interactive "BPop to buffer:\nP") 5764 (interactive "BPop to buffer:\nP")
5390 (let ((buffer (normalize-buffer-to-display buffer-or-name)) 5765 (let ((buffer (normalize-buffer-to-display buffer-or-name))
5391 window) 5766 (old-window (selected-window))
5767 (old-frame (selected-frame))
5768 new-window new-frame)
5392 (set-buffer buffer) 5769 (set-buffer buffer)
5393 (when (setq window (display-buffer buffer specifiers label)) 5770 (setq new-window (display-buffer buffer specifiers label))
5394 (select-window window norecord) 5771 (unless (eq new-window old-window)
5395 buffer))) 5772 ;; `display-buffer' has chosen another window, select it.
5773 (select-window new-window norecord)
5774 (setq new-frame (window-frame new-window))
5775 (unless (eq new-frame old-frame)
5776 ;; `display-buffer' has chosen another frame, make sure it gets
5777 ;; input focus and is risen.
5778 (select-frame-set-input-focus new-frame)))
5779
5780 buffer))
5396 5781
5397(defsubst pop-to-buffer-same-window (&optional buffer-or-name norecord label) 5782(defsubst pop-to-buffer-same-window (&optional buffer-or-name norecord label)
5398 "Pop to buffer specified by BUFFER-OR-NAME in the selected window. 5783 "Pop to buffer specified by BUFFER-OR-NAME in the selected window.
@@ -5513,8 +5898,8 @@ functions should call `pop-to-buffer-same-window' instead."
5513(defun switch-to-buffer-same-frame (buffer-or-name &optional norecord) 5898(defun switch-to-buffer-same-frame (buffer-or-name &optional norecord)
5514 "Switch to buffer BUFFER-OR-NAME in a window on the selected frame. 5899 "Switch to buffer BUFFER-OR-NAME in a window on the selected frame.
5515Another frame will be used only if there is no other choice. 5900Another frame will be used only if there is no other choice.
5516Optional arguments BUFFER-OR-NAME and NORECORD have the same 5901Arguments BUFFER-OR-NAME and NORECORD have the same meaning as
5517meaning as for `switch-to-buffer'. 5902for `switch-to-buffer'.
5518 5903
5519This function is intended for interactive use only. Lisp 5904This function is intended for interactive use only. Lisp
5520functions should call `pop-to-buffer-same-frame' instead." 5905functions should call `pop-to-buffer-same-frame' instead."
@@ -5527,8 +5912,8 @@ functions should call `pop-to-buffer-same-frame' instead."
5527 "Switch to buffer BUFFER-OR-NAME in another window. 5912 "Switch to buffer BUFFER-OR-NAME in another window.
5528The selected window will be used only if there is no other 5913The selected window will be used only if there is no other
5529choice. Windows on the selected frame are preferred to windows 5914choice. Windows on the selected frame are preferred to windows
5530on other frames. Optional arguments BUFFER-OR-NAME and NORECORD 5915on other frames. Arguments BUFFER-OR-NAME and NORECORD have the
5531have the same meaning as for `switch-to-buffer'. 5916same meaning as for `switch-to-buffer'.
5532 5917
5533This function is intended for interactive use only. Lisp 5918This function is intended for interactive use only. Lisp
5534functions should call `pop-to-buffer-other-window' instead." 5919functions should call `pop-to-buffer-other-window' instead."
@@ -5540,8 +5925,8 @@ functions should call `pop-to-buffer-other-window' instead."
5540(defun switch-to-buffer-other-window-same-frame (buffer-or-name &optional norecord) 5925(defun switch-to-buffer-other-window-same-frame (buffer-or-name &optional norecord)
5541 "Switch to buffer BUFFER-OR-NAME in another window on the selected frame. 5926 "Switch to buffer BUFFER-OR-NAME in another window on the selected frame.
5542The selected window or another frame will be used only if there 5927The selected window or another frame will be used only if there
5543is no other choice. Optional arguments BUFFER-OR-NAME and 5928is no other choice. Arguments BUFFER-OR-NAME and NORECORD have
5544NORECORD have the same meaning as for `switch-to-buffer'. 5929the same meaning as for `switch-to-buffer'.
5545 5930
5546This function is intended for interactive use only. Lisp 5931This function is intended for interactive use only. Lisp
5547functions should call `pop-to-buffer-other-window-same-frame' 5932functions should call `pop-to-buffer-other-window-same-frame'
@@ -5554,8 +5939,8 @@ instead."
5554(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord) 5939(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
5555 "Switch to buffer BUFFER-OR-NAME on another frame. 5940 "Switch to buffer BUFFER-OR-NAME on another frame.
5556The same frame will be used only if there is no other choice. 5941The same frame will be used only if there is no other choice.
5557Optional arguments BUFFER-OR-NAME and NORECORD have the same 5942Arguments BUFFER-OR-NAME and NORECORD have the same meaning
5558meaning as for `switch-to-buffer'. 5943as for `switch-to-buffer'.
5559 5944
5560This function is intended for interactive use only. Lisp 5945This function is intended for interactive use only. Lisp
5561functions should call `pop-to-buffer-other-frame' instead." 5946functions should call `pop-to-buffer-other-frame' instead."
@@ -5607,8 +5992,8 @@ This function returns non-nil if `display-buffer' or
5607`pop-to-buffer' would show a buffer named BUFFER-NAME in the 5992`pop-to-buffer' would show a buffer named BUFFER-NAME in the
5608selected rather than \(as usual\) some other window. See 5993selected rather than \(as usual\) some other window. See
5609`same-window-buffer-names' and `same-window-regexps'." 5994`same-window-buffer-names' and `same-window-regexps'."
5610 (let ((buffer-names (with-no-warnings special-display-buffer-names)) 5995 (let ((buffer-names (with-no-warnings same-window-buffer-names))
5611 (regexps (with-no-warnings special-display-regexps))) 5996 (regexps (with-no-warnings same-window-regexps)))
5612 (cond 5997 (cond
5613 ((not (stringp buffer-name))) 5998 ((not (stringp buffer-name)))
5614 ;; The elements of `same-window-buffer-names' can be buffer 5999 ;; The elements of `same-window-buffer-names' can be buffer
@@ -5674,7 +6059,7 @@ and (cdr ARGS) as second."
5674 ;; Reuse the current window if the user requested it. 6059 ;; Reuse the current window if the user requested it.
5675 (when (cdr (assq 'same-window args)) 6060 (when (cdr (assq 'same-window args))
5676 (display-buffer-reuse-window 6061 (display-buffer-reuse-window
5677 buffer '(same nil nil) '((reuse-dedicated . 'weak)))) 6062 buffer '(same nil nil) '((reuse-dedicated . weak))))
5678 ;; Stay on the same frame if requested. 6063 ;; Stay on the same frame if requested.
5679 (when (or (cdr (assq 'same-frame args)) 6064 (when (or (cdr (assq 'same-frame args))
5680 (cdr (assq 'same-window args))) 6065 (cdr (assq 'same-window args)))
@@ -5916,32 +6301,28 @@ frame. The default value calls `make-frame' with the argument
5916 'pop-up-frame-function 6301 'pop-up-frame-function
5917 "use 2nd arg of `display-buffer' instead." "24.1") 6302 "use 2nd arg of `display-buffer' instead." "24.1")
5918 6303
5919(defcustom pop-up-frames 'unset ; nil 6304(defcustom pop-up-frames nil
5920 "Whether `display-buffer' should make a separate frame. 6305 "Whether `display-buffer' should make a separate frame.
5921If nil, never make a separate frame. 6306If nil, never make a separate frame.
5922If the value is `graphic-only', make a separate frame 6307If the value is `graphic-only', make a separate frame
5923on graphic displays only. 6308on graphic displays only.
5924If this is the symbol unset, the option was not set and is
5925ignored.
5926Any other non-nil value means always make a separate frame." 6309Any other non-nil value means always make a separate frame."
5927 :type '(choice 6310 :type '(choice
5928 (const :tag "Unset" unset)
5929 (const :tag "Never" nil) 6311 (const :tag "Never" nil)
5930 (const :tag "On graphic displays only" graphic-only) 6312 (const :tag "On graphic displays only" graphic-only)
5931 (const :tag "Always" t)) 6313 (const :tag "Always" t))
5932 :version "24.1"
5933 :group 'windows 6314 :group 'windows
5934 :group 'frames) 6315 :group 'frames)
5935(make-obsolete-variable 6316(make-obsolete-variable
5936 'pop-up-frames 6317 'pop-up-frames
5937 "use 2nd arg of `display-buffer' instead." "24.1") 6318 "use 2nd arg of `display-buffer' instead." "24.1")
5938 6319
5939(defcustom display-buffer-reuse-frames 'unset ; nil 6320(defcustom display-buffer-reuse-frames nil
5940 "Set and non-nil means `display-buffer' should reuse frames. 6321 "Set and non-nil means `display-buffer' should reuse frames.
5941If the buffer in question is already displayed in a frame, raise 6322If the buffer in question is already displayed in a frame, raise
5942that frame." 6323that frame."
5943 :type 'boolean 6324 :type 'boolean
5944 :version "24.1" 6325 :version "21.1"
5945 :group 'windows 6326 :group 'windows
5946 :group 'frames) 6327 :group 'frames)
5947(make-obsolete-variable 6328(make-obsolete-variable
@@ -6012,20 +6393,20 @@ is nil, `display-buffer' cannot split windows horizontally."
6012 'split-width-threshold 6393 'split-width-threshold
6013 "use 2nd arg of `display-buffer' instead." "24.1") 6394 "use 2nd arg of `display-buffer' instead." "24.1")
6014 6395
6015(defcustom even-window-heights t 6396(defcustom even-window-heights 'unset ; t
6016 "If non-nil `display-buffer' will try to even window heights. 6397 "If set and non-nil `display-buffer' will try to even window heights.
6017Otherwise `display-buffer' will leave the window configuration 6398Otherwise `display-buffer' will leave the window configuration
6018alone. Heights are evened only when `display-buffer' reuses a 6399alone. Heights are evened only when `display-buffer' reuses a
6019window that appears above or below the selected window." 6400window that appears above or below the selected window."
6020 :type 'boolean 6401 :type 'boolean
6021 :version "23.1" 6402 :version "24.1"
6022 :group 'windows) 6403 :group 'windows)
6023(make-obsolete-variable 6404(make-obsolete-variable
6024 'even-window-heights 6405 'even-window-heights
6025 "use 2nd arg of `display-buffer' instead." "24.1") 6406 "use 2nd arg of `display-buffer' instead." "24.1")
6026 6407
6027(defvar display-buffer-mark-dedicated 'unset ; nil 6408(defvar display-buffer-mark-dedicated nil
6028 "Set and non-nil means `display-buffer' marks the windows it creates as dedicated. 6409 "Non-nil means `display-buffer' marks the windows it creates as dedicated.
6029The actual non-nil value of this variable will be copied to the 6410The actual non-nil value of this variable will be copied to the
6030`window-dedicated-p' flag.") 6411`window-dedicated-p' flag.")
6031(make-obsolete-variable 6412(make-obsolete-variable
@@ -6202,7 +6583,7 @@ value of `display-buffer-alist'."
6202 nil 6583 nil
6203 (list 6584 (list
6204 'pop-up-frame 6585 'pop-up-frame
6205 (unless (memq pop-up-frames '(nil unset)) 6586 (when pop-up-frames
6206 (list 'pop-up-frame pop-up-frames)) 6587 (list 'pop-up-frame pop-up-frames))
6207 (when pop-up-frame-function 6588 (when pop-up-frame-function
6208 (cons 'pop-up-frame-function pop-up-frame-function)) 6589 (cons 'pop-up-frame-function pop-up-frame-function))
@@ -6338,17 +6719,16 @@ value of `display-buffer-alist'."
6338 (list 6719 (list
6339 'reuse-window 6720 'reuse-window
6340 (list 'reuse-window nil 'same 6721 (list 'reuse-window nil 'same
6341 (unless (and (memq display-buffer-reuse-frames '(nil unset)) 6722 (when (or display-buffer-reuse-frames pop-up-frames)
6342 (memq pop-up-frames '(nil unset)))
6343 ;; "0" (all visible and iconified frames) is hardcoded in 6723 ;; "0" (all visible and iconified frames) is hardcoded in
6344 ;; Emacs 23. 6724 ;; Emacs 23.
6345 0)) 6725 0))
6346 (when even-window-heights 6726 (unless (memq even-window-heights '(nil unset))
6347 (cons 'reuse-window-even-sizes t))) 6727 (cons 'reuse-window-even-sizes t)))
6348 no-custom) 6728 no-custom)
6349 6729
6350 ;; `display-buffer-mark-dedicated' 6730 ;; `display-buffer-mark-dedicated'
6351 (unless (memq display-buffer-mark-dedicated '(nil unset)) 6731 (when display-buffer-mark-dedicated
6352 (display-buffer-alist-add 6732 (display-buffer-alist-add
6353 nil 6733 nil
6354 (list 6734 (list
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el
index 1c6af1f45f2..04b759a8116 100644
--- a/lisp/x-dnd.el
+++ b/lisp/x-dnd.el
@@ -433,6 +433,18 @@ otherwise return the frame coordinates."
433(declare-function x-get-selection-internal "xselect.c" 433(declare-function x-get-selection-internal "xselect.c"
434 (selection-symbol target-type &optional time-stamp)) 434 (selection-symbol target-type &optional time-stamp))
435 435
436(defun x-dnd-version-from-flags (flags)
437 "Return the version byte from the 32 bit FLAGS in an XDndEnter message"
438 (if (consp flags) ;; Long as cons
439 (ash (car flags) -8)
440 (ash flags -24))) ;; Ordinary number
441
442(defun x-dnd-more-than-3-from-flags (flags)
443 "Return the nmore-than3 bit from the 32 bit FLAGS in an XDndEnter message"
444 (if (consp flags)
445 (logand (cdr flags) 1)
446 (logand flags 1)))
447
436(defun x-dnd-handle-xdnd (event frame window message _format data) 448(defun x-dnd-handle-xdnd (event frame window message _format data)
437 "Receive one XDND event (client message) and send the appropriate reply. 449 "Receive one XDND event (client message) and send the appropriate reply.
438EVENT is the client message. FRAME is where the mouse is now. 450EVENT is the client message. FRAME is where the mouse is now.
@@ -440,9 +452,10 @@ WINDOW is the window within FRAME where the mouse is now.
440FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent." 452FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent."
441 (cond ((equal "XdndEnter" message) 453 (cond ((equal "XdndEnter" message)
442 (let* ((flags (aref data 1)) 454 (let* ((flags (aref data 1))
443 (version (and (consp flags) (ash (car flags) -8))) 455 (version (x-dnd-version-from-flags flags))
444 (more-than-3 (and (consp flags) (cdr flags))) 456 (more-than-3 (x-dnd-more-than-3-from-flags flags))
445 (dnd-source (aref data 0))) 457 (dnd-source (aref data 0)))
458 (message "%s %s" version more-than-3)
446 (if version ;; If flags is bad, version will be nil. 459 (if version ;; If flags is bad, version will be nil.
447 (x-dnd-save-state 460 (x-dnd-save-state
448 window nil nil 461 window nil nil