diff options
| author | Joakim Verona | 2011-06-23 01:28:30 +0200 |
|---|---|---|
| committer | Joakim Verona | 2011-06-23 01:28:30 +0200 |
| commit | c5082a753011dacef505e91f1fc30a84fa75a2eb (patch) | |
| tree | 2c995eff276b6e9e68f54b4ebe76bf012231c86d /lisp | |
| parent | 787c27e81f046cfa1c457ed405551f8ca0ddb0e8 (diff) | |
| parent | 297dde5a97c0c5c8020db72213c7f84067f1ee21 (diff) | |
| download | emacs-c5082a753011dacef505e91f1fc30a84fa75a2eb.tar.gz emacs-c5082a753011dacef505e91f1fc30a84fa75a2eb.zip | |
merge upstream
Diffstat (limited to 'lisp')
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 @@ | |||
| 1 | 2011-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 | |||
| 11 | 2011-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 | |||
| 17 | 2011-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 | |||
| 22 | 2011-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 | |||
| 29 | 2011-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 | |||
| 40 | 2011-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 | |||
| 68 | 2011-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 | |||
| 73 | 2011-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 | |||
| 79 | 2011-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 | |||
| 84 | 2011-06-21 Leo Liu <sdl.web@gmail.com> | ||
| 85 | |||
| 86 | * subr.el (sha1): Implement sha1 using secure-hash. | ||
| 87 | |||
| 88 | 2011-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 | |||
| 107 | 2011-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 | |||
| 114 | 2011-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 | |||
| 119 | 2011-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 | |||
| 125 | 2011-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 | |||
| 130 | 2011-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 | |||
| 137 | 2011-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 | |||
| 180 | 2011-06-20 Deniz Dogan <deniz@dogan.se> | ||
| 181 | |||
| 182 | * net/rcirc.el: Delete trailing whitespaces once and for all. | ||
| 183 | |||
| 184 | 2011-06-20 Daniel Colascione <dan.colascione@gmail.com> | ||
| 185 | |||
| 186 | * emacs-lisp/syntax.el (syntax-ppss): Further improve docstring. | ||
| 187 | |||
| 188 | 2011-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 | |||
| 194 | 2011-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 | |||
| 222 | 2011-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 | |||
| 243 | 2011-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 | |||
| 256 | 2011-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 | |||
| 272 | 2011-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 | |||
| 289 | 2011-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 | |||
| 305 | 2011-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 | |||
| 1 | 2011-06-15 Stefan Monnier <monnier@iro.umontreal.ca> | 321 | 2011-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. |
| 549 | REGEXP is matched against the entire file name. | 549 | REGEXP is matched against the entire file name. When called |
| 550 | Does not re-mark files which already have a mark. | 550 | interactively, prompt for REGEXP. |
| 551 | With prefix argument, unflag all those files. | 551 | With prefix argument, unflag all those files. |
| 552 | Optional fourth argument LOCALP is as in `dired-get-filename'." | 552 | Optional 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. |
| 401 | The returned value is the same as `parse-partial-sexp' except that | 401 | The returned value is the same as that of `parse-partial-sexp' |
| 402 | values 2 and 6 values of the returned state cannot be relied upon. | 402 | run from point-min to POS except that values at positions 2 and 6 |
| 403 | in the returned list (counting from 0) cannot be relied upon. | ||
| 403 | Point is at POS when this function returns." | 404 | Point 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. | ||
| 100 | You can set this in your init file; for example, | ||
| 101 | |||
| 102 | (setq pop-up-frame-alist '((width . 80) (height . 20))) | ||
| 103 | |||
| 104 | If non-nil, the value you specify here is used by the default | ||
| 105 | `pop-up-frame-function' for the creation of new frames. | ||
| 106 | |||
| 107 | Since `pop-up-frame-function' is used by `display-buffer' for | ||
| 108 | making new frames, any value specified here by default affects | ||
| 109 | the automatic generation of new frames via `display-buffer' and | ||
| 110 | all functions based on it. The behavior of `make-frame' is not | ||
| 111 | affected 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. | ||
| 120 | This function is called with no arguments and should return a new | ||
| 121 | frame. 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. | ||
| 129 | Special frames are used for buffers whose names are listed in | ||
| 130 | `special-display-buffer-names' and for buffers whose names match | ||
| 131 | one of the regular expressions in `special-display-regexps'. | ||
| 132 | |||
| 133 | This variable can be set in your init file, like this: | ||
| 134 | |||
| 135 | (setq special-display-frame-alist '((width . 80) (height . 20))) | ||
| 136 | |||
| 137 | These 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. | ||
| 145 | If BUFFER is already displayed in a visible or iconified frame, | ||
| 146 | raise that frame. Otherwise, display BUFFER in a new frame. | ||
| 147 | |||
| 148 | Optional argument ARGS is a list specifying additional | ||
| 149 | information. | ||
| 150 | |||
| 151 | If ARGS is an alist, use it as a list of frame parameters. If | ||
| 152 | these parameters contain \(same-window . t), display BUFFER in | ||
| 153 | the selected window. If they contain \(same-frame . t), display | ||
| 154 | BUFFER in a window of the selected frame. | ||
| 155 | |||
| 156 | If ARGS is a list whose car is a symbol, use (car ARGS) as a | ||
| 157 | function to do the work. Pass it BUFFER as first argument, | ||
| 158 | and (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 @@ | |||
| 1 | 2011-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 | |||
| 8 | 2011-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 | |||
| 13 | 2011-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 | |||
| 22 | 2011-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 | |||
| 1 | 2011-06-10 Katsumi Yamaoka <yamaoka@jpl.org> | 36 | 2011-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 | ||
| 162 | tokens 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 | ||
| 189 | The default will get login and password information from | 214 | The 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', | |||
| 3230 | MATCHES is a list of index matches found by `Info-apropos-matches'.") | 3230 | MATCHES 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. |
| 90 | This only has effect if you specify it before loading the smtpmail library." | 76 | This 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. | ||
| 99 | This may be either nil (plain connection) or `starttls' (use the | ||
| 100 | starttls mechanism to turn on TLS security after opening the | ||
| 101 | stream)." | ||
| 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. |
| 115 | This is appended (with an @-sign) to any specified recipients which do | 109 | This 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 | ||
| 119 | Don't bother to set this unless you have get an error like: | 113 | Don'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." |
| 121 | when sending mail, and the *trace of SMTP session to <somewhere>* | ||
| 122 | buffer 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. | ||
| 162 | This variable can either be a filename pointing to a file in netrc(5) | ||
| 163 | format, 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 | ||
| 166 | need to enter a `realm' too, add it to the user string, so that it | ||
| 167 | looks 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. | ||
| 179 | This is a list of four-element list with `servername' (a string), | ||
| 180 | `port' (an integer), `key' (a filename) and `certificate' (a | ||
| 181 | filename). | ||
| 182 | If you do not have a certificate/key pair, leave the `key' and | ||
| 183 | `certificate' fields as `nil'. A key/certificate pair is only | ||
| 184 | needed if you want to use X.509 client authenticated | ||
| 185 | connections." | ||
| 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. |
| 195 | This is mainly useful for development purposes, to learn about | 152 | This 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. | ||
| 1982 | It 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. |
| 518 | Only the elements of table that satisfy predicate PRED are considered. | 519 | Only the elements of table that satisfy predicate PRED are considered. |
| 519 | POINT is the position of point within STRING. | 520 | POINT 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. |
| 531 | Only the elements of table that satisfy predicate PRED are considered. | 535 | Only the elements of table that satisfy predicate PRED are considered. |
| 532 | POINT is the position of point within STRING. | 536 | POINT 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 |
| 113 | capabilities, 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 | |||
| 123 | If :use-starttls-if-possible is non-nil, do opportunistic | ||
| 124 | STARTTLS upgrades even if Emacs doesn't have built-in TLS | ||
| 125 | functionality. | ||
| 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 |
| 116 | asynchronously, 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, | |||
| 780 | this is `comint-dynamic-complete-functions'." | 780 | this 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). |
| 906 | If no directory information can be extracted from the completed | 939 | If no directory information can be extracted from the completed |
| 907 | component, `default-directory' is used as the basis for completion." | 940 | component, `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. | ||
| 1348 | Test is done using `equal'. | ||
| 1349 | If PRED is non-nil, it is a function used for further removal. | ||
| 1350 | Returns 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 | ||
| 208 | 5x5 keyboard bindings are: | 213 | 5x5 keyboard bindings are: |
| 209 | \\<5x5-mode-map> | 214 | \\<5x5-mode-map> |
| 210 | Flip \\[5x5-flip-current] | 215 | Flip \\[5x5-flip-current] |
| 211 | Move up \\[5x5-up] | 216 | Move up \\[5x5-up] |
| 212 | Move down \\[5x5-down] | 217 | Move down \\[5x5-down] |
| 213 | Move left \\[5x5-left] | 218 | Move left \\[5x5-left] |
| 214 | Move right \\[5x5-right] | 219 | Move right \\[5x5-right] |
| 215 | Start new game \\[5x5-new-game] | 220 | Start new game \\[5x5-new-game] |
| 216 | New game with random grid \\[5x5-randomize] | 221 | New game with random grid \\[5x5-randomize] |
| 217 | Random cracker \\[5x5-crack-randomly] | 222 | Random cracker \\[5x5-crack-randomly] |
| 218 | Mutate current cracker \\[5x5-crack-mutating-current] | 223 | Mutate current cracker \\[5x5-crack-mutating-current] |
| 219 | Mutate best cracker \\[5x5-crack-mutating-best] | 224 | Mutate best cracker \\[5x5-crack-mutating-best] |
| 220 | Mutate xor cracker \\[5x5-crack-xor-mutate] | 225 | Mutate xor cracker \\[5x5-crack-xor-mutate] |
| 221 | Quit current game \\[5x5-quit-game]" | 226 | Solve with Calc \\[5x5-solve-suggest] |
| 227 | Rotate left Calc Solutions \\[5x5-solve-rotate-left] | ||
| 228 | Rotate right Calc Solutions \\[5x5-solve-rotate-right] | ||
| 229 | Quit 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 | |||
| 809 | If N is not supplied rotate by 1, that is to say put the last | ||
| 810 | element first in the list. | ||
| 811 | |||
| 812 | The 5x5 game has in general several solutions. For grid size=5, | ||
| 813 | there are 4 possible solutions. When function | ||
| 814 | `5x5-solve-suggest' (press `\\[5x5-solve-suggest]') is called the | ||
| 815 | solution that is presented is the one that needs least number of | ||
| 816 | strokes --- other solutions can be viewed by rotating through the | ||
| 817 | list. The list of solution is ordered by number of strokes, so | ||
| 818 | rotating left just after calling `5x5-solve-suggest' will show | ||
| 819 | the the solution with second least number of strokes, while | ||
| 820 | rotating right will show the solution with greatest number of | ||
| 821 | strokes." | ||
| 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. | ||
| 853 | If N is not supplied, rotate by 1. Similar to function | ||
| 854 | `5x5-solve-rotate-left' except that rotation is right instead of | ||
| 855 | lest." | ||
| 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. |
| 1964 | This is ok since we do our own keyword/comment/string face coloring.") | 1964 | This 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 | ||
| 2008 | Turning on Delphi mode calls the value of the variable `delphi-mode-hook' | 2008 | Turning on Delphi mode calls the value of the variable `delphi-mode-hook' |
| 2009 | with no args, if that value is non-nil." | 2009 | with 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. | ||
| 1152 | Can complete variable and target names. | ||
| 1153 | The 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") |
| 284 | This is implemented using the Octave command `completion_matches' which | ||
| 285 | is 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") |
| 988 | Compare that symbol against Octave's reserved words and builtin | ||
| 989 | variables." | ||
| 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. |
| 237 | Repeated use of \\[pascal-complete-word] will show you all of them. | 236 | Repeated use of \\[pascal-complete-word] would show you all of them. |
| 238 | Normally, when there is more than one possible completion, | 237 | Normally, when there is more than one possible completion, |
| 239 | it displays a list of all possible completions." | 238 | it 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> |
| 304 | TAB indents for Pascal code. Delete converts tabs to spaces as it moves back. | 303 | TAB 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 \ |
| 307 | to position in code | 306 | to 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 | ||
| 310 | Other useful functions are: | 309 | Other 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. | ||
| 2605 | OBJECT is either a string or a buffer. Optional arguments START and | ||
| 2606 | END are character positions specifying which portion of OBJECT for | ||
| 2607 | computing the hash. If BINARY is non-nil, return a string in binary | ||
| 2608 | form." | ||
| 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. |
| 1162 | When not inside a field, signal an error." | 1162 | When 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." |
| 1466 | If that does not exist, call the value of `widget-complete-field'. | 1485 | (let ((completions (widget-get widget :completions))) |
| 1467 | During 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. | ||
| 3023 | Completions are taken from the :completion-alist property of the | ||
| 3024 | widget. 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. |
| 3061 | It reads a file name from an editable text field." | 3073 | It 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. |
| 1171 | More precisely, cycle through all windows calling the function | 1170 | More precisely, cycle through all windows calling the function |
| 1172 | PREDICATE on each one of them with the window as its sole | 1171 | PREDICATE on each one of them with the window as its sole |
| 1173 | argument. Return the first window for which PREDICATE returns | 1172 | argument. Return the first window for which PREDICATE returns |
| 1174 | non-nil. If no window satisfies PREDICATE, return DEFAULT. | 1173 | non-nil. Windows are scanned starting with the window following |
| 1174 | the selcted window. If no window satisfies PREDICATE, return | ||
| 1175 | DEFAULT. | ||
| 1176 | |||
| 1177 | MINIBUF t means include the minibuffer window even if the | ||
| 1178 | minibuffer is not active. MINIBUF nil or omitted means include | ||
| 1179 | the minibuffer window only if the minibuffer is active. Any | ||
| 1180 | other value means do not include the minibuffer window even if | ||
| 1181 | the minibuffer is active. | ||
| 1175 | 1182 | ||
| 1176 | ALL-FRAMES nil or omitted means consider all windows on the selected | 1183 | ALL-FRAMES nil or omitted means consider all windows on the selected |
| 1177 | frame, plus the minibuffer window if specified by the MINIBUF | 1184 | frame, plus the minibuffer window if specified by the MINIBUF |
| @@ -1192,7 +1199,9 @@ values of ALL-FRAMES have special meanings: | |||
| 1192 | Anything else means consider all windows on the selected frame | 1199 | Anything else means consider all windows on the selected frame |
| 1193 | and no others." | 1200 | and 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. |
| 1299 | BUFFER-OR-NAME may be a buffer or the name of an existing buffer | 1308 | BUFFER-OR-NAME may be a buffer or the name of an existing buffer |
| 1300 | and defaults to the current buffer. | 1309 | and defaults to the current buffer. Windows are scanned starting |
| 1301 | 1310 | with the selected window. | |
| 1302 | Any windows showing BUFFER-OR-NAME on the selected frame are listed | ||
| 1303 | first. | ||
| 1304 | 1311 | ||
| 1305 | MINIBUF t means include the minibuffer window even if the | 1312 | MINIBUF t means include the minibuffer window even if the |
| 1306 | minibuffer is not active. MINIBUF nil or omitted means include | 1313 | minibuffer is not active. MINIBUF nil or omitted means include |
| @@ -1328,7 +1335,7 @@ Anything else means consider all windows on the selected frame | |||
| 1328 | and no others." | 1335 | and 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 | |||
| 2044 | negative, shrink selected window by -DELTA lines or columns. | 2051 | negative, shrink selected window by -DELTA lines or columns. |
| 2045 | Return nil." | 2052 | Return 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 | |||
| 2054 | negative, enlarge selected window by -DELTA lines or columns. | 2072 | negative, enlarge selected window by -DELTA lines or columns. |
| 2055 | Return nil." | 2073 | Return 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. | ||
| 2256 | If this variable is nil, functions that quit a window never | ||
| 2257 | delete the associated frame. If this variable equals the symbol | ||
| 2258 | `automatic', a frame is deleted only if it the window is | ||
| 2259 | dedicated or was created by `display-buffer'. If this variable | ||
| 2260 | is t, a frame can be always deleted, even if it was created by | ||
| 2261 | `make-frame-command'. Other values should not be used. | ||
| 2262 | |||
| 2263 | Note that a frame will be effectively deleted if and only if | ||
| 2264 | another frame still exists. | ||
| 2265 | |||
| 2266 | Functions quitting a window and consequently affected by this | ||
| 2267 | variable 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. |
| 2227 | Return `frame' if deleting WINDOW should delete its frame | 2278 | Return `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 | |||
| 2960 | frame. The selected window is not changed by this function." | 3014 | frame. 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. | ||
| 3583 | WINDOW can be any window and defaults to the root window of the | ||
| 3584 | selected frame. | ||
| 3585 | |||
| 3586 | Optional argument MARKERS non-nil means use markers for sampling | ||
| 3587 | positions like `window-point' or `window-start'. MARKERS should | ||
| 3588 | be non-nil only if the value is used for putting the state back | ||
| 3589 | in the same session (note that markers slow down processing). | ||
| 3590 | |||
| 3591 | The return value can be used as argument for `window-state-put' | ||
| 3592 | to put the state recorded here into an arbitrary window. The | ||
| 3593 | value 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. | ||
| 3761 | STATE should be the state of a window returned by an earlier | ||
| 3762 | invocation of `window-state-get'. Optional argument WINDOW must | ||
| 3763 | specify a live window and defaults to the selected one. | ||
| 3764 | |||
| 3765 | Optional argument IGNORE non-nil means ignore minimum window | ||
| 3766 | sizes and fixed size restrictions. IGNORE equal `safe' means | ||
| 3767 | subwindows 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. |
| 3468 | The value specified here is used when no other specifiers have | 3831 | The 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. |
| 3511 | The car of each element of this list is built from a set of cons | 3879 | The 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 | ||
| 4137 | A cons cell whose car is `other-window-means-other-frame' and | ||
| 4138 | whose 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 | ||
| 4141 | means, for example, that you prefer functions like | ||
| 4142 | `find-file-other-window' or `switch-to-buffer-other-window' to | ||
| 4143 | make a new frame instead of a new window on the selected frame. | ||
| 4144 | |||
| 3769 | Usually, applications are free to override the specifiers of | 4145 | Usually, 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 |
| 3771 | argument of `display-buffer'. For every `display-buffer-alist' | 4147 | argument 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. |
| 4361 | WINDOW must be a live window and defaults to the selected one. | 4728 | WINDOW 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 | ||
| 4706 | SPECIFIERS must be a list of buffer display specifiers, see the | 5081 | SPECIFIERS must be a list of buffer display specifiers, see the |
| 4707 | documentation of `display-buffer-alist' for a description." | 5082 | documentation 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. |
| 4911 | SPECIFIERS is the SPECIFIERS argument of `display-buffer'." | 5287 | BUFFER must be a live buffer or the name of a live buffer. |
| 4912 | (let (normalized) | 5288 | |
| 5289 | Return nil if BUFFER shall be preferably displayed in another | ||
| 5290 | window on the selected frame. Return non-nil if BUFFER shall be | ||
| 5291 | preferably displayed in a window on any but the selected frame. | ||
| 5292 | |||
| 5293 | Optional argument LABEL is like the same argument of | ||
| 5294 | `display-buffer'. | ||
| 5295 | |||
| 5296 | The calculation of the return value is exclusively based on the | ||
| 5297 | user 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'. | ||
| 5306 | BUFFER-NAME is the name of the buffer that shall be displayed, | ||
| 5307 | SPECIFIERS is the second argument of `display-buffer'. LABEL the | ||
| 5308 | same argument of `display-buffer'. OTHER-FRAME non-nil means use | ||
| 5309 | other-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'. |
| 4945 | BUFFER-OR-NAME is the buffer to display. This routine provides a | 5349 | BUFFER-OR-NAME is the buffer to display. This routine provides a |
| 4946 | compatibility layer for the now obsolete Emacs 23 buffer display | 5350 | compatibility layer for the now obsolete Emacs 23 buffer display |
| 4947 | options." | 5351 | options." |
| 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. | ||
| 5137 | BUFFER-NAME must be a string specifying a valid buffer name. | ||
| 5138 | SPECIFIERS and LABEL are the homonymous arguments of | ||
| 5139 | `display-buffer'. | ||
| 5140 | |||
| 5141 | The method for displaying the buffer specified by BUFFER-NAME or | ||
| 5142 | LABEL is established by appending the following four lists of | ||
| 5143 | specifiers: | ||
| 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'. | ||
| 5470 | SPECIFIERS is a list of buffer display specfiers. LABEL is the | ||
| 5471 | same 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'. | ||
| 5497 | BUFFER-NAME must be the name of the buffer that shall be displayed. | ||
| 5498 | LABEL 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. | ||
| 5533 | BUFFER-NAME must be a string specifying a valid buffer name. | ||
| 5534 | SPECIFIERS and LABEL are the homonymous arguments of | ||
| 5535 | `display-buffer'. | ||
| 5536 | |||
| 5537 | The method for displaying the buffer specified by BUFFER-NAME or | ||
| 5538 | LABEL is established by appending the following four lists of | ||
| 5539 | specifiers: | ||
| 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 | |||
| 5388 | additional information." | 5763 | additional 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. |
| 5515 | Another frame will be used only if there is no other choice. | 5900 | Another frame will be used only if there is no other choice. |
| 5516 | Optional arguments BUFFER-OR-NAME and NORECORD have the same | 5901 | Arguments BUFFER-OR-NAME and NORECORD have the same meaning as |
| 5517 | meaning as for `switch-to-buffer'. | 5902 | for `switch-to-buffer'. |
| 5518 | 5903 | ||
| 5519 | This function is intended for interactive use only. Lisp | 5904 | This function is intended for interactive use only. Lisp |
| 5520 | functions should call `pop-to-buffer-same-frame' instead." | 5905 | functions 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. |
| 5528 | The selected window will be used only if there is no other | 5913 | The selected window will be used only if there is no other |
| 5529 | choice. Windows on the selected frame are preferred to windows | 5914 | choice. Windows on the selected frame are preferred to windows |
| 5530 | on other frames. Optional arguments BUFFER-OR-NAME and NORECORD | 5915 | on other frames. Arguments BUFFER-OR-NAME and NORECORD have the |
| 5531 | have the same meaning as for `switch-to-buffer'. | 5916 | same meaning as for `switch-to-buffer'. |
| 5532 | 5917 | ||
| 5533 | This function is intended for interactive use only. Lisp | 5918 | This function is intended for interactive use only. Lisp |
| 5534 | functions should call `pop-to-buffer-other-window' instead." | 5919 | functions 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. |
| 5542 | The selected window or another frame will be used only if there | 5927 | The selected window or another frame will be used only if there |
| 5543 | is no other choice. Optional arguments BUFFER-OR-NAME and | 5928 | is no other choice. Arguments BUFFER-OR-NAME and NORECORD have |
| 5544 | NORECORD have the same meaning as for `switch-to-buffer'. | 5929 | the same meaning as for `switch-to-buffer'. |
| 5545 | 5930 | ||
| 5546 | This function is intended for interactive use only. Lisp | 5931 | This function is intended for interactive use only. Lisp |
| 5547 | functions should call `pop-to-buffer-other-window-same-frame' | 5932 | functions 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. |
| 5556 | The same frame will be used only if there is no other choice. | 5941 | The same frame will be used only if there is no other choice. |
| 5557 | Optional arguments BUFFER-OR-NAME and NORECORD have the same | 5942 | Arguments BUFFER-OR-NAME and NORECORD have the same meaning |
| 5558 | meaning as for `switch-to-buffer'. | 5943 | as for `switch-to-buffer'. |
| 5559 | 5944 | ||
| 5560 | This function is intended for interactive use only. Lisp | 5945 | This function is intended for interactive use only. Lisp |
| 5561 | functions should call `pop-to-buffer-other-frame' instead." | 5946 | functions 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 |
| 5608 | selected rather than \(as usual\) some other window. See | 5993 | selected 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. |
| 5921 | If nil, never make a separate frame. | 6306 | If nil, never make a separate frame. |
| 5922 | If the value is `graphic-only', make a separate frame | 6307 | If the value is `graphic-only', make a separate frame |
| 5923 | on graphic displays only. | 6308 | on graphic displays only. |
| 5924 | If this is the symbol unset, the option was not set and is | ||
| 5925 | ignored. | ||
| 5926 | Any other non-nil value means always make a separate frame." | 6309 | Any 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. |
| 5941 | If the buffer in question is already displayed in a frame, raise | 6322 | If the buffer in question is already displayed in a frame, raise |
| 5942 | that frame." | 6323 | that 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. |
| 6017 | Otherwise `display-buffer' will leave the window configuration | 6398 | Otherwise `display-buffer' will leave the window configuration |
| 6018 | alone. Heights are evened only when `display-buffer' reuses a | 6399 | alone. Heights are evened only when `display-buffer' reuses a |
| 6019 | window that appears above or below the selected window." | 6400 | window 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. |
| 6029 | The actual non-nil value of this variable will be copied to the | 6410 | The 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. |
| 438 | EVENT is the client message. FRAME is where the mouse is now. | 450 | EVENT 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. | |||
| 440 | FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent." | 452 | FORMAT 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 |