aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorJoakim Verona2012-09-10 16:03:53 +0200
committerJoakim Verona2012-09-10 16:03:53 +0200
commitb035a30e5cd2f34fedc04c253eeb5a11afed8145 (patch)
treeb9350cce389602f4967bdc1beed745929155ad5d /lisp
parent4a37733c693d59a9b83a3fb2d0c7f9461d149f60 (diff)
parenta31a4cdacb196cc96dcb9bd229edb1d635e01344 (diff)
downloademacs-b035a30e5cd2f34fedc04c253eeb5a11afed8145.tar.gz
emacs-b035a30e5cd2f34fedc04c253eeb5a11afed8145.zip
upstream
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog310
-rw-r--r--lisp/calendar/holidays.el2
-rw-r--r--lisp/custom.el45
-rw-r--r--lisp/dired-aux.el53
-rw-r--r--lisp/dired.el10
-rw-r--r--lisp/emacs-lisp/benchmark.el6
-rw-r--r--lisp/emacs-lisp/byte-run.el7
-rw-r--r--lisp/emacs-lisp/cl-loaddefs.el28
-rw-r--r--lisp/emacs-lisp/cl-macs.el83
-rw-r--r--lisp/emacs-lisp/debug.el163
-rw-r--r--lisp/emacs-lisp/lisp-mode.el77
-rw-r--r--lisp/emacs-lisp/macroexp.el110
-rw-r--r--lisp/emacs-lisp/map-ynp.el10
-rw-r--r--lisp/emacs-lisp/pcase.el2
-rw-r--r--lisp/emulation/cua-rect.el2
-rw-r--r--lisp/eshell/em-unix.el2
-rw-r--r--lisp/files.el74
-rw-r--r--lisp/frame.el4
-rw-r--r--lisp/gnus/ChangeLog111
-rw-r--r--lisp/gnus/gnus-demon.el9
-rw-r--r--lisp/gnus/gnus-fun.el4
-rw-r--r--lisp/gnus/gnus-group.el7
-rw-r--r--lisp/gnus/gnus-logic.el73
-rw-r--r--lisp/gnus/gnus-notifications.el16
-rw-r--r--lisp/gnus/gnus-score.el231
-rw-r--r--lisp/gnus/gnus-srvr.el3
-rw-r--r--lisp/gnus/gnus-util.el12
-rw-r--r--lisp/gnus/gnus.el45
-rw-r--r--lisp/gnus/message.el32
-rw-r--r--lisp/gnus/nnmaildir.el286
-rw-r--r--lisp/gnus/qp.el16
-rw-r--r--lisp/help.el37
-rw-r--r--lisp/isearch.el19
-rw-r--r--lisp/loadup.el28
-rw-r--r--lisp/mail/smtpmail.el12
-rw-r--r--lisp/net/browse-url.el2
-rw-r--r--lisp/play/blackbox.el2
-rw-r--r--lisp/progmodes/cc-cmds.el17
-rw-r--r--lisp/progmodes/cc-engine.el8
-rw-r--r--lisp/progmodes/flymake.el5
-rw-r--r--lisp/progmodes/python.el16
-rw-r--r--lisp/progmodes/ruby-mode.el173
-rw-r--r--lisp/progmodes/sh-script.el31
-rw-r--r--lisp/progmodes/vhdl-mode.el15
-rw-r--r--lisp/register.el51
-rw-r--r--lisp/replace.el110
-rw-r--r--lisp/ses.el4
-rw-r--r--lisp/simple.el8
-rw-r--r--lisp/speedbar.el6
-rw-r--r--lisp/subr.el68
-rw-r--r--lisp/textmodes/picture.el8
-rw-r--r--lisp/userlock.el48
-rw-r--r--lisp/window.el170
53 files changed, 1894 insertions, 777 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 87904b8313b..8de59875674 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,13 +1,311 @@
12012-09-10 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * emacs-lisp/lisp-mode.el (emacs-list-byte-code-comment-re): New var.
4 (emacs-lisp-byte-code-comment)
5 (emacs-lisp-byte-code-syntax-propertize, emacs-lisp-byte-code-mode):
6 New functions.
7 (eval-sexp-add-defvars): Don't skip defvars in column >0.
8 (eval-defun-2): Remove bogus interactive spec.
9 (lisp-indent-line): Remove redundant whole-exp code, now done in
10 indent-according-to-mode.
11 (save-match-data): Remove redundant indent data.
12
13 * emacs-lisp/benchmark.el (benchmark-run, benchmark-run-compiled):
14 Use `declare'.
15
162012-09-09 Juri Linkov <juri@jurta.org>
17
18 * replace.el (replace-regexp-lax-whitespace): New defcustom.
19 (replace-lax-whitespace, query-replace-regexp)
20 (query-replace-regexp-eval, replace-regexp): Doc fix.
21 (perform-replace, replace-highlight): Let-bind
22 isearch-lax-whitespace to replace-lax-whitespace and
23 isearch-regexp-lax-whitespace to replace-regexp-lax-whitespace.
24
25 * isearch.el (isearch-query-replace): Let-bind
26 replace-lax-whitespace to isearch-lax-whitespace and
27 replace-regexp-lax-whitespace to
28 isearch-regexp-lax-whitespace. (Bug#10885)
29
302012-09-09 Stefan Monnier <monnier@iro.umontreal.ca>
31
32 * eshell/em-unix.el (eshell/sudo): Explicitly drop return value.
33
342012-09-09 Alan Mackenzie <acm@muc.de>
35
36 * progmodes/cc-engine.el (c-state-cache-init):
37 Initialise c-state-semi-nonlit-pos-cache\(-limit\)? properly.
38 (c-record-parse-state-state):
39 Record c-state-semi-nonlit-pos-cache\(-limit\)?.
40
412012-09-09 Andreas Schwab <schwab@linux-m68k.org>
42
43 * register.el (register-separator): Rename from
44 separator-register. All uses changed. Doc fix.
45 (register): Fix version.
46
472012-09-09 Chong Yidong <cyd@gnu.org>
48
49 * replace.el (query-replace-map): Bind four new symbols for
50 requesting window scrolling.
51
52 * subr.el (y-or-n-p): Handle the window-scrolling bindings in
53 query-replace-map (Bug#8948).
54
55 * custom.el (custom-theme-load-confirm): Use y-or-n-p.
56
57 * emacs-lisp/map-ynp.el (map-y-or-n-p): Don't bind scrolling keys
58 since they are now in query-replace-map.
59
60 * window.el (scroll-other-window-down): Make the arg optional.
61
622012-09-09 Chong Yidong <cyd@gnu.org>
63
64 * files.el (hack-local-variables-confirm): Use quit-window to kill
65 the *Local Variables* buffer.
66
672012-09-08 Dmitry Gutov <dgutov@yandex.ru>
68
69 * progmodes/ruby-mode.el (ruby-toggle-block): Guess the current block,
70 not just expect to be at its beginning. Adjust callees.
71 Succeed when do-end block has no space before the pipe character.
72 (ruby-brace-to-do-end): When the original block is one-liner,
73 convert to multiline. Reindent the result.
74
752012-09-08 Jambunathan K <kjambunathan@gmail.com>
76
77 * register.el (register): New group.
78 (register-separator): New user option.
79 (increment-register): Route it to `append-to-register', if
80 register contains text. Implication is that `C-x r +' can now be
81 used for appending to a text register (bug#12217).
82 (append-to-register, prepend-to-register): Add separator based on
83 `register-separator.
84
852012-09-08 Alan Mackenzie <acm@muc.de>
86
87 AWK Mode: make auto-newline work when there's "==" in the pattern.
88 * progmodes/cc-cmds.el (c-point-syntax): Handle virtual semicolons
89 correctly.
90 * progmodes/cc-engine.el (c-guess-basic-syntax CASE 5A.3):
91 Test more rigorously for "=" token.
92
932012-09-08 Dmitry Gutov <dgutov@yandex.ru>
94
95 * progmodes/ruby-mode.el (ruby-match-expression-expansion):
96 Only fail when reached LIMIT.
97
982012-09-08 Chong Yidong <cyd@gnu.org>
99
100 * dired.el (dired-mode-map): Don't bind M-=.
101
102 * dired-aux.el (dired-diff): Use backup file as default.
103
1042012-09-08 Drew Adams <drew.adams@oracle.com>
105
106 * subr.el (add-to-history): Fix delete usage (Bug#12314).
107
1082012-09-08 Chong Yidong <cyd@gnu.org>
109
110 * subr.el (syntax-after, syntax-class): Doc fix.
111
1122012-09-08 Martin Rudalics <rudalics@gmx.at>
113
114 * window.el (display-buffer-in-previous-window): New buffer
115 display action function.
116
117 * emacs-lisp/debug.el (debugger-bury-or-kill): New option.
118 (debugger-previous-window): New variable.
119 (debug): Rewrite using display-buffer-in-previous-window,
120 quit-restore-window and debugger-bury-or-kill. (Bug#8789)
121
1222012-09-07 Stefan Monnier <monnier@iro.umontreal.ca>
123
124 * emacs-lisp/byte-run.el (defun): Tweak message. Simplify code.
125
1262012-09-07 Matt McClure <mlm@aya.yale.edu> (tiny change)
127
128 * progmodes/python.el (python-shell-send-string):
129 When default-directory is remote, create temp file on remote
130 filesystem.
131 (python-shell-send-file): When file is remote, pass local view of
132 file paths to remote Python interpreter. (Bug#12340)
133
1342012-09-07 Chong Yidong <cyd@gnu.org>
135
136 * window.el (switch-to-buffer): Doc fix (Bug#12181).
137
138 * files.el (after-find-file): Don't fail on a read-only buffer if
139 require-final-newline is `visit' or `visit-save' (Bug#11156).
140
141 * subr.el (read-char-choice): Allow quitting via ESC ESC.
142
143 * userlock.el (ask-user-about-supersession-threat):
144 Use read-char-choice (Bug#12093).
145
1462012-09-07 Chong Yidong <cyd@gnu.org>
147
148 * subr.el (buffer-narrowed-p): New function.
149
150 * ses.el (ses-widen):
151 * simple.el (count-words--buffer-message):
152 * net/browse-url.el (browse-url-of-buffer): Use it
153
154 * simple.el (count-words-region): Don't signal an error if there
155 is a non-nil prefix arg and the mark is not set.
156
157 * help.el (describe-key-briefly): Allow the message to be seen
158 when invoked from the minibuffer (Bug#7014).
159
1602012-09-07 Dmitry Gutov <dgutov@yandex.ru>
161
162 * progmodes/ruby-mode.el (ruby-end-of-defun)
163 (ruby-beginning-of-defun): Simplify, allow indentation before
164 block beginning and end keywords.
165 (ruby-beginning-of-defun): Only consider 3 keywords defun beginners.
166 (ruby-end-of-defun): Expect that the point is at the beginning of
167 the defun.
168
1692012-09-06 Stefan Monnier <monnier@iro.umontreal.ca>
170
171 * emacs-lisp/cl-macs.el (cl--do-arglist): Understand _ on &key args
172 (bug#12367).
173 (cl--make-usage-args): Strip _ from argument names.
174
1752012-09-06 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
176
177 * progmodes/vhdl-mode.el (vhdl-speedbar-initialize): Don't use
178 obsolete alias speedbar-key-map.
179 (vhdl-doc-variable, vhdl-doc-mode): Use called-interactively-p.
180 (vhdl-index-menu-init): Don't use obsolete variable
181 font-lock-maximum-size.
182
1832012-09-06 Chong Yidong <cyd@gnu.org>
184
185 * frame.el (window-system-version): Mark as obsolete.
186
187 * speedbar.el (speedbar-update-flag, speedbar-mode): Remove uses
188 of obsolete variable speedbar-key-map.
189
1902012-09-06 Juri Linkov <juri@jurta.org>
191
192 * replace.el (replace-lax-whitespace): New defcustom.
193 (query-replace, query-replace-regexp, query-replace-regexp-eval)
194 (replace-string, replace-regexp): Mention it in docstrings.
195 (perform-replace, replace-highlight): Let-bind
196 isearch-lax-whitespace and isearch-regexp-lax-whitespace according
197 to the values of replace-lax-whitespace and regexp-flag.
198 Don't let-bind search-whitespace-regexp. (Bug#10885)
199
200 * isearch.el (isearch-query-replace): Let-bind
201 replace-lax-whitespace instead of let-binding
202 replace-search-function and replace-re-search-function.
203 (isearch-lazy-highlight-search): Let-bind isearch-lax-whitespace
204 and isearch-regexp-lax-whitespace to lazy-highlight variables.
205 (isearch-toggle-symbol): Set isearch-regexp to nil
206 in isearch-word mode (like in isearch-toggle-word).
207
2082012-09-06 Juri Linkov <juri@jurta.org>
209
210 * replace.el (replace-search-function)
211 (replace-re-search-function): Set default values to nil.
212 (perform-replace): Let-bind isearch-related variables based on
213 replace-related values, call `isearch-search-fun' and let-bind
214 the result to `search-function'. Remove code that sets
215 `search-function' and `search-string' separately for
216 `delimited-flag'.
217 (replace-highlight): Add new argument `delimited-flag' and
218 rename other arguments to the names used in `perform-replace'.
219 Let-bind `isearch-word' to the argument `delimited-flag'.
220 (Bug#10885, bug#10887)
221
2222012-09-07 Dmitry Gutov <dgutov@yandex.ru>
223
224 * progmodes/ruby-mode.el (ruby-indent-beg-re): Add pieces from
225 ruby-beginning-of-indent, simplify, allow all keywords to have
226 indentation before them.
227 (ruby-beginning-of-indent): Adjust for above. Search until the
228 found point is not inside a string or comment.
229 (ruby-font-lock-keywords): Allow symbols to start with "@"
230 character, give them higher priority than variables.
231 (ruby-syntax-propertize-function)
232 (ruby-font-lock-syntactic-keywords): Remove the "not comments"
233 matchers. Expression expansions are not comments when inside a
234 string, and there comment syntax status is irrelevant.
235 (ruby-match-expression-expansion): New function. Check that
236 expression expansion is inside a string, and it's not escaped.
237 (ruby-font-lock-keywords): Use it.
238
2392012-09-05 Martin Rudalics <rudalics@gmx.at>
240
241 * help.el (temp-buffer-max-height): New default value.
242 (temp-buffer-resize-frames): New option.
243 (resize-temp-buffer-window): Optionally resize frame.
244
245 * window.el (fit-frame-to-buffer-bottom-margin): New option.
246 (fit-frame-to-buffer): New function.
247
2482012-09-05 Glenn Morris <rgm@gnu.org>
249
250 * emulation/cua-rect.el (cua--init-rectangles):
251 * textmodes/picture.el (picture-mode-map):
252 * play/blackbox.el (blackbox-mode-map): Remap right-char and left-char
253 like forward-char and backward-char. (Bug#12317)
254
2552012-09-05 Leo Liu <sdl.web@gmail.com>
256
257 * progmodes/flymake.el (flymake-warning-re): New variable.
258 (flymake-parse-line): Use it.
259
2602012-09-05 Glenn Morris <rgm@gnu.org>
261
262 * calendar/holidays.el (holiday-christian-holidays):
263 Rename an entry. (Bug#12289)
264
2652012-09-05 Stefan Monnier <monnier@iro.umontreal.ca>
266
267 * progmodes/sh-script.el (sh-font-lock-paren): Don't burp at BOB
268 (bug#12222).
269
2702012-09-04 Stefan Monnier <monnier@iro.umontreal.ca>
271
272 * loadup.el: Load macroexp. Remove hack.
273 * emacs-lisp/macroexp.el (macroexp--eval-if-compile): New function.
274 (macroexp--expand-all): Use it to get better warnings.
275 (macroexp--backtrace, macroexp--trim-backtrace-frame)
276 (internal-macroexpand-for-load): New functions.
277 (macroexp--pending-eager-loads): New var.
278 (emacs-startup-hook): New hack to replace one in loadup.el.
279 * emacs-lisp/cl-macs.el (cl--compiler-macro-list*)
280 (cl--compiler-macro-cXXr): Move to top, before they can be used.
281 (cl-psetf): Simplify.
282 (cl-defstruct): Add indent rule.
283
2842012-09-04 Lars Ingebrigtsen <larsi@gnus.org>
285
286 * mail/smtpmail.el (smtpmail-send-it): Prefer the From: header
287 over `user-mail-address' for the SMTP MAIL FROM envelope.
288 (smtpmail-via-smtp): Ditto.
289
2902012-09-04 Dmitry Gutov <dgutov@yandex.ru>
291
292 * progmodes/ruby-mode.el: Clean up keybindings.
293 (ruby-mode-map): Don't bind ruby-electric-brace,
294 ruby-beginning-of-defun, ruby-end-of-defun, ruby-mark-defun,
295 backward-kill-word, reindent-then-newline-and-indent.
296 (ruby-mark-defun): Remove.
297 (ruby-electric-brace): Remove. Obsoleted by electric-indent-chars.
298 (ruby-mode): Set local beginning-of-defun-function and
299 end-of-defun-function values.
300
12012-09-03 Martin Rudalics <rudalics@gmx.at> 3012012-09-03 Martin Rudalics <rudalics@gmx.at>
2 302
3 * window.el (temp-buffer-window-setup-hook) 303 * window.el (temp-buffer-window-setup-hook)
4 (temp-buffer-window-show-hook): New hooks. 304 (temp-buffer-window-show-hook): New hooks.
5 (temp-buffer-window-setup, temp-buffer-window-show) 305 (temp-buffer-window-setup, temp-buffer-window-show)
6 (with-temp-buffer-window): New functions. 306 (with-temp-buffer-window): New functions.
7 (fit-window-to-buffer): Remove unused optional argument 307 (fit-window-to-buffer): Remove unused optional argument OVERRIDE.
8 OVERRIDE. 308 (special-display-popup-frame): Make sure the window used shows BUFFER.
9 (special-display-popup-frame): Make sure the window used shows
10 BUFFER.
11 309
12 * help.el (temp-buffer-resize-mode): Fix doc-string. 310 * help.el (temp-buffer-resize-mode): Fix doc-string.
13 (resize-temp-buffer-window): New optional argument WINDOW. 311 (resize-temp-buffer-window): New optional argument WINDOW.
@@ -149,8 +447,8 @@
1492012-08-29 Michael Albinus <michael.albinus@gmx.de> 4472012-08-29 Michael Albinus <michael.albinus@gmx.de>
150 448
151 * eshell/esh-ext.el (eshell-external-command): Do not examine 449 * eshell/esh-ext.el (eshell-external-command): Do not examine
152 remote shell scripts. See 450 remote shell scripts.
153 <https://bugs.launchpad.net/ubuntu/+source/emacs23/+bug/1035790>. 451 See <https://bugs.launchpad.net/ubuntu/+source/emacs23/+bug/1035790>.
154 452
155 * net/tramp-sh.el (tramp-remote-path): Add "/sbin" and 453 * net/tramp-sh.el (tramp-remote-path): Add "/sbin" and
156 "/usr/local/sbin". 454 "/usr/local/sbin".
diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el
index 043d402f612..9643a1e2905 100644
--- a/lisp/calendar/holidays.el
+++ b/lisp/calendar/holidays.el
@@ -250,7 +250,7 @@ See the documentation for `calendar-holidays' for details."
250 (if calendar-christian-all-holidays-flag 250 (if calendar-christian-all-holidays-flag
251 (append 251 (append
252 (holiday-fixed 1 6 "Epiphany") 252 (holiday-fixed 1 6 "Epiphany")
253 (holiday-julian 12 25 "Eastern Orthodox Christmas") 253 (holiday-julian 12 25 "Christmas (Julian calendar)")
254 (holiday-greek-orthodox-easter) 254 (holiday-greek-orthodox-easter)
255 (holiday-fixed 8 15 "Assumption") 255 (holiday-fixed 8 15 "Assumption")
256 (holiday-advent 0 "Advent"))))) 256 (holiday-advent 0 "Advent")))))
diff --git a/lisp/custom.el b/lisp/custom.el
index fb166dd35f7..3eb2895888d 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -1223,38 +1223,19 @@ Return t if THEME was successfully loaded, nil otherwise."
1223 "Query the user about loading a Custom theme that may not be safe. 1223 "Query the user about loading a Custom theme that may not be safe.
1224The theme should be in the current buffer. If the user agrees, 1224The theme should be in the current buffer. If the user agrees,
1225query also about adding HASH to `custom-safe-themes'." 1225query also about adding HASH to `custom-safe-themes'."
1226 (if noninteractive 1226 (unless noninteractive
1227 nil 1227 (save-window-excursion
1228 (let ((exit-chars '(?y ?n ?\s)) 1228 (rename-buffer "*Custom Theme*" t)
1229 window prompt char) 1229 (emacs-lisp-mode)
1230 (save-window-excursion 1230 (setq window (pop-to-buffer (current-buffer)))
1231 (rename-buffer "*Custom Theme*" t) 1231 (goto-char (point-min))
1232 (emacs-lisp-mode) 1232 (prog1 (when (y-or-n-p "Loading a theme can run Lisp code. Really load? ")
1233 (setq window (display-buffer (current-buffer))) 1233 ;; Offer to save to `custom-safe-themes'.
1234 (setq prompt 1234 (and (or custom-file user-init-file)
1235 (format "Loading a theme can run Lisp code. Really load?%s" 1235 (y-or-n-p "Treat this theme as safe in future sessions? ")
1236 (if (and window 1236 (customize-push-and-save 'custom-safe-themes (list hash)))
1237 (< (line-number-at-pos (point-max)) 1237 t)
1238 (window-body-height))) 1238 (quit-window)))))
1239 " (y or n) "
1240 (push ?\C-v exit-chars)
1241 "\nType y or n, or C-v to scroll: ")))
1242 (goto-char (point-min))
1243 (while (null char)
1244 (setq char (read-char-choice prompt exit-chars))
1245 (when (eq char ?\C-v)
1246 (if window
1247 (with-selected-window window
1248 (condition-case nil
1249 (scroll-up)
1250 (error (goto-char (point-min))))))
1251 (setq char nil)))
1252 (when (memq char '(?\s ?y))
1253 ;; Offer to save to `custom-safe-themes'.
1254 (and (or custom-file user-init-file)
1255 (y-or-n-p "Treat this theme as safe in future sessions? ")
1256 (customize-push-and-save 'custom-safe-themes (list hash)))
1257 t)))))
1258 1239
1259(defun custom-theme-name-valid-p (name) 1240(defun custom-theme-name-valid-p (name)
1260 "Return t if NAME is a valid name for a Custom theme, nil otherwise. 1241 "Return t if NAME is a valid name for a Custom theme, nil otherwise.
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 6186f762e0a..1f8e8068de3 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -54,43 +54,30 @@ into this list; they also should call `dired-log' to log the errors.")
54;;;###autoload 54;;;###autoload
55(defun dired-diff (file &optional switches) 55(defun dired-diff (file &optional switches)
56 "Compare file at point with file FILE using `diff'. 56 "Compare file at point with file FILE using `diff'.
57FILE defaults to the file at the mark. (That's the mark set by 57If called interactively, prompt for FILE; if the file at point
58\\[set-mark-command], not by Dired's \\[dired-mark] command.) 58has a backup file, use that as the default.
59The prompted-for FILE is the first file given to `diff'. 59
60FILE is the first file given to `diff'.
60With prefix arg, prompt for second argument SWITCHES, 61With prefix arg, prompt for second argument SWITCHES,
61which is the string of command switches for `diff'." 62which is the string of command switches for `diff'."
62 (interactive 63 (interactive
63 (let* ((current (dired-get-filename t)) 64 (let* ((current (dired-get-filename t))
64 ;; Get the file at the mark. 65 (oldf (file-newest-backup current))
65 (file-at-mark (if (mark t) 66 (dir (if oldf (file-name-directory oldf))))
66 (save-excursion (goto-char (mark t)) 67 (list (read-file-name
67 (dired-get-filename t t)))) 68 (format "Diff %s with%s: "
68 ;; Use it as default if it's not the same as the current file, 69 (file-name-nondirectory current)
69 ;; and the target dir is the current dir or the mark is active. 70 (if oldf
70 (default (if (and (not (equal file-at-mark current)) 71 (concat " (default "
71 (or (equal (dired-dwim-target-directory) 72 (file-name-nondirectory oldf)
72 (dired-current-directory)) 73 ")")
73 mark-active)) 74 ""))
74 file-at-mark)) 75 dir oldf t)
75 (target-dir (if default 76 (if current-prefix-arg
76 (dired-current-directory) 77 (read-string "Options for diff: "
77 (dired-dwim-target-directory))) 78 (if (stringp diff-switches)
78 (defaults (dired-dwim-target-defaults (list current) target-dir))) 79 diff-switches
79 (require 'diff) 80 (mapconcat 'identity diff-switches " ")))))))
80 (list
81 (minibuffer-with-setup-hook
82 (lambda ()
83 (set (make-local-variable 'minibuffer-default-add-function) nil)
84 (setq minibuffer-default defaults))
85 (read-file-name
86 (format "Diff %s with%s: " current
87 (if default (format " (default %s)" default) ""))
88 target-dir default t))
89 (if current-prefix-arg
90 (read-string "Options for diff: "
91 (if (stringp diff-switches)
92 diff-switches
93 (mapconcat 'identity diff-switches " ")))))))
94 (let ((current (dired-get-filename t))) 81 (let ((current (dired-get-filename t)))
95 (when (or (equal (expand-file-name file) 82 (when (or (equal (expand-file-name file)
96 (expand-file-name current)) 83 (expand-file-name current))
diff --git a/lisp/dired.el b/lisp/dired.el
index cd27b6b6404..f4ae027181a 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1410,7 +1410,6 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST."
1410 (define-key map "&" 'dired-do-async-shell-command) 1410 (define-key map "&" 'dired-do-async-shell-command)
1411 ;; Comparison commands 1411 ;; Comparison commands
1412 (define-key map "=" 'dired-diff) 1412 (define-key map "=" 'dired-diff)
1413 (define-key map "\M-=" 'dired-backup-diff)
1414 ;; Tree Dired commands 1413 ;; Tree Dired commands
1415 (define-key map "\M-\C-?" 'dired-unmark-all-files) 1414 (define-key map "\M-\C-?" 'dired-unmark-all-files)
1416 (define-key map "\M-\C-d" 'dired-tree-down) 1415 (define-key map "\M-\C-d" 'dired-tree-down)
@@ -3745,14 +3744,15 @@ Ask means pop up a menu for the user to select one of copy, move or link."
3745;;;;;; dired-run-shell-command dired-do-shell-command dired-do-async-shell-command 3744;;;;;; dired-run-shell-command dired-do-shell-command dired-do-async-shell-command
3746;;;;;; dired-clean-directory dired-do-print dired-do-touch dired-do-chown 3745;;;;;; dired-clean-directory dired-do-print dired-do-touch dired-do-chown
3747;;;;;; dired-do-chgrp dired-do-chmod dired-compare-directories dired-backup-diff 3746;;;;;; dired-do-chgrp dired-do-chmod dired-compare-directories dired-backup-diff
3748;;;;;; dired-diff) "dired-aux" "dired-aux.el" "9499f79f5853da0aa93d26465c7bf3a1") 3747;;;;;; dired-diff) "dired-aux" "dired-aux.el" "4b260eda371d319a6c8e8e5ec917e287")
3749;;; Generated autoloads from dired-aux.el 3748;;; Generated autoloads from dired-aux.el
3750 3749
3751(autoload 'dired-diff "dired-aux" "\ 3750(autoload 'dired-diff "dired-aux" "\
3752Compare file at point with file FILE using `diff'. 3751Compare file at point with file FILE using `diff'.
3753FILE defaults to the file at the mark. (That's the mark set by 3752If called interactively, prompt for FILE; if the file at point
3754\\[set-mark-command], not by Dired's \\[dired-mark] command.) 3753has a backup file, use that as the default.
3755The prompted-for FILE is the first file given to `diff'. 3754
3755FILE is the first file given to `diff'.
3756With prefix arg, prompt for second argument SWITCHES, 3756With prefix arg, prompt for second argument SWITCHES,
3757which is the string of command switches for `diff'. 3757which is the string of command switches for `diff'.
3758 3758
diff --git a/lisp/emacs-lisp/benchmark.el b/lisp/emacs-lisp/benchmark.el
index 646be3e1b71..9029c81f279 100644
--- a/lisp/emacs-lisp/benchmark.el
+++ b/lisp/emacs-lisp/benchmark.el
@@ -53,6 +53,7 @@ FORMS once.
53Return a list of the total elapsed time for execution, the number of 53Return a list of the total elapsed time for execution, the number of
54garbage collections that ran, and the time taken by garbage collection. 54garbage collections that ran, and the time taken by garbage collection.
55See also `benchmark-run-compiled'." 55See also `benchmark-run-compiled'."
56 (declare (indent 1) (debug t))
56 (unless (natnump repetitions) 57 (unless (natnump repetitions)
57 (setq forms (cons repetitions forms) 58 (setq forms (cons repetitions forms)
58 repetitions 1)) 59 repetitions 1))
@@ -69,8 +70,6 @@ See also `benchmark-run-compiled'."
69 `(benchmark-elapse ,@forms)) 70 `(benchmark-elapse ,@forms))
70 (- gcs-done ,gcs) 71 (- gcs-done ,gcs)
71 (- gc-elapsed ,gc))))) 72 (- gc-elapsed ,gc)))))
72(put 'benchmark-run 'edebug-form-spec t)
73(put 'benchmark-run 'lisp-indent-function 2)
74 73
75;;;###autoload 74;;;###autoload
76(defmacro benchmark-run-compiled (&optional repetitions &rest forms) 75(defmacro benchmark-run-compiled (&optional repetitions &rest forms)
@@ -78,6 +77,7 @@ See also `benchmark-run-compiled'."
78This is like `benchmark-run', but what is timed is a funcall of the 77This is like `benchmark-run', but what is timed is a funcall of the
79byte code obtained by wrapping FORMS in a `lambda' and compiling the 78byte code obtained by wrapping FORMS in a `lambda' and compiling the
80result. The overhead of the `lambda's is accounted for." 79result. The overhead of the `lambda's is accounted for."
80 (declare (indent 1) (debug t))
81 (unless (natnump repetitions) 81 (unless (natnump repetitions)
82 (setq forms (cons repetitions forms) 82 (setq forms (cons repetitions forms)
83 repetitions 1)) 83 repetitions 1))
@@ -96,8 +96,6 @@ result. The overhead of the `lambda's is accounted for."
96 (funcall ,lambda-code)))) 96 (funcall ,lambda-code))))
97 `(benchmark-elapse (funcall ,code))) 97 `(benchmark-elapse (funcall ,code)))
98 (- gcs-done ,gcs) (- gc-elapsed ,gc))))) 98 (- gcs-done ,gcs) (- gc-elapsed ,gc)))))
99(put 'benchmark-run-compiled 'edebug-form-spec t)
100(put 'benchmark-run-compiled 'lisp-indent-function 2)
101 99
102;;;###autoload 100;;;###autoload
103(defun benchmark (repetitions form) 101(defun benchmark (repetitions form)
diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el
index 9b66c8ffd60..d1382f42b19 100644
--- a/lisp/emacs-lisp/byte-run.el
+++ b/lisp/emacs-lisp/byte-run.el
@@ -185,11 +185,10 @@ The return value is undefined.
185 ((and (featurep 'cl) 185 ((and (featurep 'cl)
186 (memq (car x) ;C.f. cl-do-proclaim. 186 (memq (car x) ;C.f. cl-do-proclaim.
187 '(special inline notinline optimize warn))) 187 '(special inline notinline optimize warn)))
188 (if (null (stringp docstring)) 188 (push (list 'declare x)
189 (push (list 'declare x) body) 189 (if (stringp docstring) (cdr body) body))
190 (setcdr body (cons (list 'declare x) (cdr body))))
191 nil) 190 nil)
192 (t (message "Warning: Unknown defun property %S in %S" 191 (t (message "Warning: Unknown defun property `%S' in %S"
193 (car x) name))))) 192 (car x) name)))))
194 decls)) 193 decls))
195 (def (list 'defalias 194 (def (list 'defalias
diff --git a/lisp/emacs-lisp/cl-loaddefs.el b/lisp/emacs-lisp/cl-loaddefs.el
index d4da1f59a85..f2bc7cc9d3c 100644
--- a/lisp/emacs-lisp/cl-loaddefs.el
+++ b/lisp/emacs-lisp/cl-loaddefs.el
@@ -249,8 +249,7 @@ Remove from SYMBOL's plist the property PROPNAME and its value.
249 249
250;;;*** 250;;;***
251 251
252;;;### (autoloads (cl--compiler-macro-cXXr cl--compiler-macro-list* 252;;;### (autoloads (cl--compiler-macro-adjoin cl-defsubst cl-compiler-macroexpand
253;;;;;; cl--compiler-macro-adjoin cl-defsubst cl-compiler-macroexpand
254;;;;;; cl-define-compiler-macro cl-assert cl-check-type cl-typep 253;;;;;; cl-define-compiler-macro cl-assert cl-check-type cl-typep
255;;;;;; cl-deftype cl-defstruct cl-callf2 cl-callf cl-letf* cl-letf 254;;;;;; cl-deftype cl-defstruct cl-callf2 cl-callf cl-letf* cl-letf
256;;;;;; cl-rotatef cl-shiftf cl-remf cl-psetf cl-declare cl-the cl-locally 255;;;;;; cl-rotatef cl-shiftf cl-remf cl-psetf cl-declare cl-the cl-locally
@@ -260,9 +259,20 @@ Remove from SYMBOL's plist the property PROPNAME and its value.
260;;;;;; cl-do cl-loop cl-return-from cl-return cl-block cl-etypecase 259;;;;;; cl-do cl-loop cl-return-from cl-return cl-block cl-etypecase
261;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when 260;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when
262;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp 261;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp
263;;;;;; cl-gensym) "cl-macs" "cl-macs.el" "a1ca04b3f2acc7c9b06f45ef5486d443") 262;;;;;; cl-gensym cl--compiler-macro-cXXr cl--compiler-macro-list*)
263;;;;;; "cl-macs" "cl-macs.el" "00526d56a1062b9c308cf37b59374f2b")
264;;; Generated autoloads from cl-macs.el 264;;; Generated autoloads from cl-macs.el
265 265
266(autoload 'cl--compiler-macro-list* "cl-macs" "\
267
268
269\(fn FORM ARG &rest OTHERS)" nil nil)
270
271(autoload 'cl--compiler-macro-cXXr "cl-macs" "\
272
273
274\(fn FORM X)" nil nil)
275
266(autoload 'cl-gensym "cl-macs" "\ 276(autoload 'cl-gensym "cl-macs" "\
267Generate a new uninterned symbol. 277Generate a new uninterned symbol.
268The name is made by appending a number to PREFIX, default \"G\". 278The name is made by appending a number to PREFIX, default \"G\".
@@ -659,6 +669,8 @@ value, that slot cannot be set via `setf'.
659 669
660(put 'cl-defstruct 'doc-string-elt '2) 670(put 'cl-defstruct 'doc-string-elt '2)
661 671
672(put 'cl-defstruct 'lisp-indent-function '1)
673
662(autoload 'cl-deftype "cl-macs" "\ 674(autoload 'cl-deftype "cl-macs" "\
663Define NAME as a new data type. 675Define NAME as a new data type.
664The type name can then be used in `cl-typecase', `cl-check-type', etc. 676The type name can then be used in `cl-typecase', `cl-check-type', etc.
@@ -722,16 +734,6 @@ surrounded by (cl-block NAME ...).
722 734
723\(fn FORM A LIST &rest KEYS)" nil nil) 735\(fn FORM A LIST &rest KEYS)" nil nil)
724 736
725(autoload 'cl--compiler-macro-list* "cl-macs" "\
726
727
728\(fn FORM ARG &rest OTHERS)" nil nil)
729
730(autoload 'cl--compiler-macro-cXXr "cl-macs" "\
731
732
733\(fn FORM X)" nil nil)
734
735;;;*** 737;;;***
736 738
737;;;### (autoloads (cl-tree-equal cl-nsublis cl-sublis cl-nsubst-if-not 739;;;### (autoloads (cl-tree-equal cl-nsublis cl-sublis cl-nsubst-if-not
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 81a451dbbb4..e385a80c1f3 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -58,6 +58,33 @@
58 58
59;;; Initialization. 59;;; Initialization.
60 60
61;; Place compiler macros at the beginning, otherwise uses of the corresponding
62;; functions can lead to recursive-loads that prevent the calls from
63;; being optimized.
64
65;;;###autoload
66(defun cl--compiler-macro-list* (_form arg &rest others)
67 (let* ((args (reverse (cons arg others)))
68 (form (car args)))
69 (while (setq args (cdr args))
70 (setq form `(cons ,(car args) ,form)))
71 form))
72
73;;;###autoload
74(defun cl--compiler-macro-cXXr (form x)
75 (let* ((head (car form))
76 (n (symbol-name (car form)))
77 (i (- (length n) 2)))
78 (if (not (string-match "c[ad]+r\\'" n))
79 (if (and (fboundp head) (symbolp (symbol-function head)))
80 (cl--compiler-macro-cXXr (cons (symbol-function head) (cdr form))
81 x)
82 (error "Compiler macro for cXXr applied to non-cXXr form"))
83 (while (> i (match-beginning 0))
84 (setq x (list (if (eq (aref n i) ?a) 'car 'cdr) x))
85 (setq i (1- i)))
86 x)))
87
61;;; Some predicates for analyzing Lisp forms. 88;;; Some predicates for analyzing Lisp forms.
62;; These are used by various 89;; These are used by various
63;; macro expanders to optimize the results in certain common cases. 90;; macro expanders to optimize the results in certain common cases.
@@ -366,9 +393,14 @@ its argument list allows full Common Lisp conventions."
366 (mapcar (lambda (x) 393 (mapcar (lambda (x)
367 (cond 394 (cond
368 ((symbolp x) 395 ((symbolp x)
369 (if (eq ?\& (aref (symbol-name x) 0)) 396 (let ((first (aref (symbol-name x) 0)))
370 (setq state x) 397 (if (eq ?\& first)
371 (make-symbol (upcase (symbol-name x))))) 398 (setq state x)
399 ;; Strip a leading underscore, since it only
400 ;; means that this argument is unused.
401 (make-symbol (upcase (if (eq ?_ first)
402 (substring (symbol-name x) 1)
403 (symbol-name x)))))))
372 ((not (consp x)) x) 404 ((not (consp x)) x)
373 ((memq state '(nil &rest)) (cl--make-usage-args x)) 405 ((memq state '(nil &rest)) (cl--make-usage-args x))
374 (t ;(VAR INITFORM SVAR) or ((KEYWORD VAR) INITFORM SVAR). 406 (t ;(VAR INITFORM SVAR) or ((KEYWORD VAR) INITFORM SVAR).
@@ -452,7 +484,13 @@ its argument list allows full Common Lisp conventions."
452 (let ((arg (pop args))) 484 (let ((arg (pop args)))
453 (or (consp arg) (setq arg (list arg))) 485 (or (consp arg) (setq arg (list arg)))
454 (let* ((karg (if (consp (car arg)) (caar arg) 486 (let* ((karg (if (consp (car arg)) (caar arg)
455 (intern (format ":%s" (car arg))))) 487 (let ((name (symbol-name (car arg))))
488 ;; Strip a leading underscore, since it only
489 ;; means that this argument is unused, but
490 ;; shouldn't affect the key's name (bug#12367).
491 (if (eq ?_ (aref name 0))
492 (setq name (substring name 1)))
493 (intern (format ":%s" name)))))
456 (varg (if (consp (car arg)) (cl-cadar arg) (car arg))) 494 (varg (if (consp (car arg)) (cl-cadar arg) (car arg)))
457 (def (if (cdr arg) (cadr arg) 495 (def (if (cdr arg) (cadr arg)
458 (or (car cl--bind-defs) (cadr (assq varg cl--bind-defs))))) 496 (or (car cl--bind-defs) (cadr (assq varg cl--bind-defs)))))
@@ -1425,8 +1463,15 @@ Valid clauses are:
1425 cl--loop-accum-var)))) 1463 cl--loop-accum-var))))
1426 1464
1427(defun cl--loop-build-ands (clauses) 1465(defun cl--loop-build-ands (clauses)
1466 "Return various representations of (and . CLAUSES).
1467CLAUSES is a list of Elisp expressions, where clauses of the form
1468\(progn E1 E2 E3 .. t) are the focus of particular optimizations.
1469The return value has shape (COND BODY COMBO)
1470such that COMBO is equivalent to (and . CLAUSES)."
1428 (let ((ands nil) 1471 (let ((ands nil)
1429 (body nil)) 1472 (body nil))
1473 ;; Look through `clauses', trying to optimize (progn ,@A t) (progn ,@B) ,@C
1474 ;; into (progn ,@A ,@B) ,@C.
1430 (while clauses 1475 (while clauses
1431 (if (and (eq (car-safe (car clauses)) 'progn) 1476 (if (and (eq (car-safe (car clauses)) 'progn)
1432 (eq (car (last (car clauses))) t)) 1477 (eq (car (last (car clauses))) t))
@@ -1437,6 +1482,7 @@ Valid clauses are:
1437 (cl-cdadr clauses) 1482 (cl-cdadr clauses)
1438 (list (cadr clauses)))) 1483 (list (cadr clauses))))
1439 (cddr clauses))) 1484 (cddr clauses)))
1485 ;; A final (progn ,@A t) is moved outside of the `and'.
1440 (setq body (cdr (butlast (pop clauses))))) 1486 (setq body (cdr (butlast (pop clauses)))))
1441 (push (pop clauses) ands))) 1487 (push (pop clauses) ands)))
1442 (setq ands (or (nreverse ands) (list t))) 1488 (setq ands (or (nreverse ands) (list t)))
@@ -1905,8 +1951,6 @@ See Info node `(cl)Declarations' for details."
1905 (cl-do-proclaim (pop specs) nil))) 1951 (cl-do-proclaim (pop specs) nil)))
1906 nil) 1952 nil)
1907 1953
1908
1909
1910;;; The standard modify macros. 1954;;; The standard modify macros.
1911 1955
1912;; `setf' is now part of core Elisp, defined in gv.el. 1956;; `setf' is now part of core Elisp, defined in gv.el.
@@ -1929,7 +1973,7 @@ before assigning any PLACEs to the corresponding values.
1929 (or p (error "Odd number of arguments to cl-psetf")) 1973 (or p (error "Odd number of arguments to cl-psetf"))
1930 (pop p)) 1974 (pop p))
1931 (if simple 1975 (if simple
1932 `(progn (setf ,@args) nil) 1976 `(progn (setq ,@args) nil)
1933 (setq args (reverse args)) 1977 (setq args (reverse args))
1934 (let ((expr `(setf ,(cadr args) ,(car args)))) 1978 (let ((expr `(setf ,(cadr args) ,(car args))))
1935 (while (setq args (cddr args)) 1979 (while (setq args (cddr args))
@@ -2119,7 +2163,7 @@ one keyword is supported, `:read-only'. If this has a non-nil
2119value, that slot cannot be set via `setf'. 2163value, that slot cannot be set via `setf'.
2120 2164
2121\(fn NAME SLOTS...)" 2165\(fn NAME SLOTS...)"
2122 (declare (doc-string 2) 2166 (declare (doc-string 2) (indent 1)
2123 (debug 2167 (debug
2124 (&define ;Makes top-level form not be wrapped. 2168 (&define ;Makes top-level form not be wrapped.
2125 [&or symbolp 2169 [&or symbolp
@@ -2597,14 +2641,6 @@ surrounded by (cl-block NAME ...).
2597 `(if (cl-member ,a ,list ,@keys) ,list (cons ,a ,list)) 2641 `(if (cl-member ,a ,list ,@keys) ,list (cons ,a ,list))
2598 form)) 2642 form))
2599 2643
2600;;;###autoload
2601(defun cl--compiler-macro-list* (_form arg &rest others)
2602 (let* ((args (reverse (cons arg others)))
2603 (form (car args)))
2604 (while (setq args (cdr args))
2605 (setq form `(cons ,(car args) ,form)))
2606 form))
2607
2608(defun cl--compiler-macro-get (_form sym prop &optional def) 2644(defun cl--compiler-macro-get (_form sym prop &optional def)
2609 (if def 2645 (if def
2610 `(cl-getf (symbol-plist ,sym) ,prop ,def) 2646 `(cl-getf (symbol-plist ,sym) ,prop ,def)
@@ -2616,21 +2652,6 @@ surrounded by (cl-block NAME ...).
2616 (cl--make-type-test temp (cl--const-expr-val type))) 2652 (cl--make-type-test temp (cl--const-expr-val type)))
2617 form)) 2653 form))
2618 2654
2619;;;###autoload
2620(defun cl--compiler-macro-cXXr (form x)
2621 (let* ((head (car form))
2622 (n (symbol-name (car form)))
2623 (i (- (length n) 2)))
2624 (if (not (string-match "c[ad]+r\\'" n))
2625 (if (and (fboundp head) (symbolp (symbol-function head)))
2626 (cl--compiler-macro-cXXr (cons (symbol-function head) (cdr form))
2627 x)
2628 (error "Compiler macro for cXXr applied to non-cXXr form"))
2629 (while (> i (match-beginning 0))
2630 (setq x (list (if (eq (aref n i) ?a) 'car 'cdr) x))
2631 (setq i (1- i)))
2632 x)))
2633
2634(dolist (y '(cl-first cl-second cl-third cl-fourth 2655(dolist (y '(cl-first cl-second cl-third cl-fourth
2635 cl-fifth cl-sixth cl-seventh 2656 cl-fifth cl-sixth cl-seventh
2636 cl-eighth cl-ninth cl-tenth 2657 cl-eighth cl-ninth cl-tenth
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index 7bc93a19d1a..188c0800eb8 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -48,6 +48,39 @@ the middle is discarded, and just the beginning and end are displayed."
48 :group 'debugger 48 :group 'debugger
49 :version "21.1") 49 :version "21.1")
50 50
51(defcustom debugger-bury-or-kill 'bury
52 "How to proceed with the debugger buffer when exiting `debug'.
53The value used here affects the behavior of operations on any
54window previously showing the debugger buffer.
55
56`nil' means that if its window is not deleted when exiting the
57 debugger, invoking `switch-to-prev-buffer' will usually show
58 the debugger buffer again.
59
60`append' means that if the window is not deleted, the debugger
61 buffer moves to the end of the window's previous buffers so
62 it's less likely that a future invocation of
63 `switch-to-prev-buffer' will switch to it. Also, it moves the
64 buffer to the end of the frame's buffer list.
65
66`bury' means that if the window is not deleted, its buffer is
67 removed from the window's list of previous buffers. Also, it
68 moves the buffer to the end of the frame's buffer list. This
69 value provides the most reliable remedy to not have
70 `switch-to-prev-buffer' switch to the debugger buffer again
71 without killing the buffer.
72
73`kill' means to kill the debugger buffer.
74
75The value used here is passed to `quit-restore-window'."
76 :type '(choice
77 (const :tag "Keep alive" nil)
78 (const :tag "Append" 'append)
79 (const :tag "Bury" 'bury)
80 (const :tag "Kill" 'kill))
81 :group 'debugger
82 :version "24.2")
83
51(defvar debug-function-list nil 84(defvar debug-function-list nil
52 "List of functions currently set for debug on entry.") 85 "List of functions currently set for debug on entry.")
53 86
@@ -60,6 +93,9 @@ the middle is discarded, and just the beginning and end are displayed."
60(defvar debugger-old-buffer nil 93(defvar debugger-old-buffer nil
61 "This is the buffer that was current when the debugger was entered.") 94 "This is the buffer that was current when the debugger was entered.")
62 95
96(defvar debugger-previous-window nil
97 "This is the window last showing the debugger buffer.")
98
63(defvar debugger-previous-backtrace nil 99(defvar debugger-previous-backtrace nil
64 "The contents of the previous backtrace (including text properties). 100 "The contents of the previous backtrace (including text properties).
65This is to optimize `debugger-make-xrefs'.") 101This is to optimize `debugger-make-xrefs'.")
@@ -133,7 +169,7 @@ first will be printed into the backtrace buffer."
133 (with-current-buffer (get-buffer "*Backtrace*") 169 (with-current-buffer (get-buffer "*Backtrace*")
134 (list major-mode (buffer-string))))) 170 (list major-mode (buffer-string)))))
135 (debugger-buffer (get-buffer-create "*Backtrace*")) 171 (debugger-buffer (get-buffer-create "*Backtrace*"))
136 (debugger-old-buffer (current-buffer)) 172 (debugger-window nil)
137 (debugger-step-after-exit nil) 173 (debugger-step-after-exit nil)
138 (debugger-will-be-back nil) 174 (debugger-will-be-back nil)
139 ;; Don't keep reading from an executing kbd macro! 175 ;; Don't keep reading from an executing kbd macro!
@@ -184,78 +220,63 @@ first will be printed into the backtrace buffer."
184 (cursor-in-echo-area nil)) 220 (cursor-in-echo-area nil))
185 (unwind-protect 221 (unwind-protect
186 (save-excursion 222 (save-excursion
187 (save-window-excursion 223 (with-no-warnings
188 (with-no-warnings 224 (setq unread-command-char -1))
189 (setq unread-command-char -1)) 225 (when (eq (car debugger-args) 'debug)
190 (when (eq (car debugger-args) 'debug) 226 ;; Skip the frames for backtrace-debug, byte-code,
191 ;; Skip the frames for backtrace-debug, byte-code, 227 ;; and implement-debug-on-entry.
192 ;; and implement-debug-on-entry. 228 (backtrace-debug 4 t)
193 (backtrace-debug 4 t) 229 ;; Place an extra debug-on-exit for macro's.
194 ;; Place an extra debug-on-exit for macro's. 230 (when (eq 'lambda (car-safe (cadr (backtrace-frame 4))))
195 (when (eq 'lambda (car-safe (cadr (backtrace-frame 4)))) 231 (backtrace-debug 5 t)))
196 (backtrace-debug 5 t))) 232 (pop-to-buffer
197 (pop-to-buffer debugger-buffer) 233 debugger-buffer
198 (debugger-mode) 234 `((display-buffer-reuse-window
199 (debugger-setup-buffer debugger-args) 235 display-buffer-in-previous-window)
200 (when noninteractive 236 . (,(when debugger-previous-window
201 ;; If the backtrace is long, save the beginning 237 `(previous-window . ,debugger-previous-window)))))
202 ;; and the end, but discard the middle. 238 (setq debugger-window (selected-window))
203 (when (> (count-lines (point-min) (point-max)) 239 (setq debugger-previous-window debugger-window)
204 debugger-batch-max-lines) 240 (debugger-mode)
205 (goto-char (point-min)) 241 (debugger-setup-buffer debugger-args)
206 (forward-line (/ 2 debugger-batch-max-lines)) 242 (when noninteractive
207 (let ((middlestart (point))) 243 ;; If the backtrace is long, save the beginning
208 (goto-char (point-max)) 244 ;; and the end, but discard the middle.
209 (forward-line (- (/ 2 debugger-batch-max-lines) 245 (when (> (count-lines (point-min) (point-max))
210 debugger-batch-max-lines)) 246 debugger-batch-max-lines)
211 (delete-region middlestart (point)))
212 (insert "...\n"))
213 (goto-char (point-min)) 247 (goto-char (point-min))
214 (message "%s" (buffer-string)) 248 (forward-line (/ 2 debugger-batch-max-lines))
215 (kill-emacs -1)) 249 (let ((middlestart (point)))
250 (goto-char (point-max))
251 (forward-line (- (/ 2 debugger-batch-max-lines)
252 debugger-batch-max-lines))
253 (delete-region middlestart (point)))
254 (insert "...\n"))
255 (goto-char (point-min))
256 (message "%s" (buffer-string))
257 (kill-emacs -1))
258 (message "")
259 (let ((standard-output nil)
260 (buffer-read-only t))
216 (message "") 261 (message "")
217 (let ((standard-output nil) 262 ;; Make sure we unbind buffer-read-only in the right buffer.
218 (buffer-read-only t)) 263 (save-excursion
219 (message "") 264 (recursive-edit))))
220 ;; Make sure we unbind buffer-read-only in the right buffer. 265 (when (and (window-live-p debugger-window)
221 (save-excursion 266 (eq (window-buffer debugger-window) debugger-buffer))
222 (recursive-edit))))) 267 ;; Unshow debugger-buffer.
223 ;; Kill or at least neuter the backtrace buffer, so that users 268 (quit-restore-window debugger-window debugger-bury-or-kill))
224 ;; don't try to execute debugger commands in an invalid context. 269 ;; Restore previous state of debugger-buffer in case we were
225 (if (get-buffer-window debugger-buffer 0) 270 ;; in a recursive invocation of the debugger, otherwise just
226 ;; Still visible despite the save-window-excursion? Maybe it 271 ;; erase the buffer and put it into fundamental mode.
227 ;; it's in a pop-up frame. It would be annoying to delete and 272 (when (buffer-live-p debugger-buffer)
228 ;; recreate it every time the debugger stops, so instead we'll 273 (with-current-buffer debugger-buffer
229 ;; erase it (and maybe hide it) but keep it alive. 274 (let ((inhibit-read-only t))
230 (with-current-buffer debugger-buffer 275 (erase-buffer)
231 (with-selected-window (get-buffer-window debugger-buffer 0) 276 (if (null debugger-previous-state)
232 (when (and (window-dedicated-p (selected-window)) 277 (fundamental-mode)
233 (not debugger-will-be-back)) 278 (insert (nth 1 debugger-previous-state))
234 ;; If the window is not dedicated, burying the buffer 279 (funcall (nth 0 debugger-previous-state))))))
235 ;; will mean that the frame created for it is left
236 ;; around showing some random buffer, and next time we
237 ;; pop to the debugger buffer we'll create yet
238 ;; another frame.
239 ;; If debugger-will-be-back is non-nil, the frame
240 ;; would need to be de-iconified anyway immediately
241 ;; after when we re-enter the debugger, so iconifying it
242 ;; here would cause flashing.
243 ;; Drew Adams is not happy with this: he wants to frame
244 ;; to be left at the top-level, still working on how
245 ;; best to do that.
246 (bury-buffer))))
247 (unless debugger-previous-state
248 (kill-buffer debugger-buffer)))
249 ;; Restore the previous state of the debugger-buffer, in case we were
250 ;; in a recursive invocation of the debugger.
251 (when (buffer-live-p debugger-buffer)
252 (with-current-buffer debugger-buffer
253 (let ((inhibit-read-only t))
254 (erase-buffer)
255 (if (null debugger-previous-state)
256 (fundamental-mode)
257 (insert (nth 1 debugger-previous-state))
258 (funcall (nth 0 debugger-previous-state))))))
259 (with-timeout-unsuspend debugger-with-timeout-suspend) 280 (with-timeout-unsuspend debugger-with-timeout-suspend)
260 (set-match-data debugger-outer-match-data))) 281 (set-match-data debugger-outer-match-data)))
261 ;; Put into effect the modified values of these variables 282 ;; Put into effect the modified values of these variables
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 666e31f690f..64aac4b81db 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -431,6 +431,61 @@ if that value is non-nil."
431 (add-hook 'completion-at-point-functions 431 (add-hook 'completion-at-point-functions
432 'lisp-completion-at-point nil 'local)) 432 'lisp-completion-at-point nil 'local))
433 433
434;;; Emacs Lisp Byte-Code mode
435
436(eval-and-compile
437 (defconst emacs-list-byte-code-comment-re
438 (concat "\\(#\\)@\\([0-9]+\\) "
439 ;; Make sure it's a docstring and not a lazy-loaded byte-code.
440 "\\(?:[^(]\\|([^\"]\\)")))
441
442(defun emacs-lisp-byte-code-comment (end &optional _point)
443 "Try to syntactically mark the #@NNN ....^_ docstrings in byte-code files."
444 (let ((ppss (syntax-ppss)))
445 (when (and (nth 4 ppss)
446 (eq (char-after (nth 8 ppss)) ?#))
447 (let* ((n (save-excursion
448 (goto-char (nth 8 ppss))
449 (when (looking-at emacs-list-byte-code-comment-re)
450 (string-to-number (match-string 2)))))
451 ;; `maxdiff' tries to make sure the loop below terminates.
452 (maxdiff n))
453 (when n
454 (let* ((bchar (match-end 2))
455 (b (position-bytes bchar)))
456 (goto-char (+ b n))
457 (while (let ((diff (- (position-bytes (point)) b n)))
458 (unless (zerop diff)
459 (when (> diff maxdiff) (setq diff maxdiff))
460 (forward-char (- diff))
461 (setq maxdiff (if (> diff 0) diff
462 (max (1- maxdiff) 1)))
463 t))))
464 (if (<= (point) end)
465 (put-text-property (1- (point)) (point)
466 'syntax-table
467 (string-to-syntax "> b"))
468 (goto-char end)))))))
469
470(defun emacs-lisp-byte-code-syntax-propertize (start end)
471 (emacs-lisp-byte-code-comment end (point))
472 (funcall
473 (syntax-propertize-rules
474 (emacs-list-byte-code-comment-re
475 (1 (prog1 "< b" (emacs-lisp-byte-code-comment end (point))))))
476 start end))
477
478(add-to-list 'auto-mode-alist '("\\.elc\\'" . emacs-lisp-byte-code-mode))
479(define-derived-mode emacs-lisp-byte-code-mode emacs-lisp-mode
480 "Elisp-Byte-Code"
481 "Major mode for *.elc files."
482 ;; TODO: Add way to disassemble byte-code under point.
483 (setq-local open-paren-in-column-0-is-defun-start nil)
484 (setq-local syntax-propertize-function
485 #'emacs-lisp-byte-code-syntax-propertize))
486
487;;; Generic Lisp mode.
488
434(defvar lisp-mode-map 489(defvar lisp-mode-map
435 (let ((map (make-sparse-keymap)) 490 (let ((map (make-sparse-keymap))
436 (menu-map (make-sparse-keymap "Lisp"))) 491 (menu-map (make-sparse-keymap "Lisp")))
@@ -730,10 +785,12 @@ POS specifies the starting position where EXP was found and defaults to point."
730 (let ((vars ())) 785 (let ((vars ()))
731 (goto-char (point-min)) 786 (goto-char (point-min))
732 (while (re-search-forward 787 (while (re-search-forward
733 "^(def\\(?:var\\|const\\|custom\\)[ \t\n]+\\([^; '()\n\t]+\\)" 788 "(def\\(?:var\\|const\\|custom\\)[ \t\n]+\\([^; '()\n\t]+\\)"
734 pos t) 789 pos t)
735 (let ((var (intern (match-string 1)))) 790 (let ((var (intern (match-string 1))))
736 (unless (special-variable-p var) 791 (and (not (special-variable-p var))
792 (save-excursion
793 (zerop (car (syntax-ppss (match-beginning 0)))))
737 (push var vars)))) 794 (push var vars))))
738 `(progn ,@(mapcar (lambda (v) `(defvar ,v)) vars) ,exp))))) 795 `(progn ,@(mapcar (lambda (v) `(defvar ,v)) vars) ,exp)))))
739 796
@@ -820,7 +877,6 @@ if it already has a value.\)
820 877
821With argument, insert value in current buffer after the defun. 878With argument, insert value in current buffer after the defun.
822Return the result of evaluation." 879Return the result of evaluation."
823 (interactive "P")
824 ;; FIXME: the print-length/level bindings should only be applied while 880 ;; FIXME: the print-length/level bindings should only be applied while
825 ;; printing, not while evaluating. 881 ;; printing, not while evaluating.
826 (let ((debug-on-error eval-expression-debug-on-error) 882 (let ((debug-on-error eval-expression-debug-on-error)
@@ -925,6 +981,7 @@ rigidly along with this one."
925 (if (or (null indent) (looking-at "\\s<\\s<\\s<")) 981 (if (or (null indent) (looking-at "\\s<\\s<\\s<"))
926 ;; Don't alter indentation of a ;;; comment line 982 ;; Don't alter indentation of a ;;; comment line
927 ;; or a line that starts in a string. 983 ;; or a line that starts in a string.
984 ;; FIXME: inconsistency: comment-indent moves ;;; to column 0.
928 (goto-char (- (point-max) pos)) 985 (goto-char (- (point-max) pos))
929 (if (and (looking-at "\\s<") (not (looking-at "\\s<\\s<"))) 986 (if (and (looking-at "\\s<") (not (looking-at "\\s<\\s<")))
930 ;; Single-semicolon comment lines should be indented 987 ;; Single-semicolon comment lines should be indented
@@ -939,18 +996,7 @@ rigidly along with this one."
939 ;; If initial point was within line's indentation, 996 ;; If initial point was within line's indentation,
940 ;; position after the indentation. Else stay at same point in text. 997 ;; position after the indentation. Else stay at same point in text.
941 (if (> (- (point-max) pos) (point)) 998 (if (> (- (point-max) pos) (point))
942 (goto-char (- (point-max) pos))) 999 (goto-char (- (point-max) pos))))))
943 ;; If desired, shift remaining lines of expression the same amount.
944 (and whole-exp (not (zerop shift-amt))
945 (save-excursion
946 (goto-char beg)
947 (forward-sexp 1)
948 (setq end (point))
949 (goto-char beg)
950 (forward-line 1)
951 (setq beg (point))
952 (> end beg))
953 (indent-code-rigidly beg end shift-amt)))))
954 1000
955(defvar calculate-lisp-indent-last-sexp) 1001(defvar calculate-lisp-indent-last-sexp)
956 1002
@@ -1230,7 +1276,6 @@ Lisp function does not specify a special indentation."
1230(put 'prog2 'lisp-indent-function 2) 1276(put 'prog2 'lisp-indent-function 2)
1231(put 'save-excursion 'lisp-indent-function 0) 1277(put 'save-excursion 'lisp-indent-function 0)
1232(put 'save-restriction 'lisp-indent-function 0) 1278(put 'save-restriction 'lisp-indent-function 0)
1233(put 'save-match-data 'lisp-indent-function 0)
1234(put 'save-current-buffer 'lisp-indent-function 0) 1279(put 'save-current-buffer 'lisp-indent-function 0)
1235(put 'let 'lisp-indent-function 1) 1280(put 'let 'lisp-indent-function 1)
1236(put 'let* 'lisp-indent-function 1) 1281(put 'let* 'lisp-indent-function 1)
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 70eab149837..394225d697e 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -100,6 +100,17 @@ each clause."
100 (error (message "Compiler-macro error for %S: %S" (car form) err) 100 (error (message "Compiler-macro error for %S: %S" (car form) err)
101 form))) 101 form)))
102 102
103(defun macroexp--eval-if-compile (&rest _forms)
104 "Pseudo function used internally by macroexp to delay warnings.
105The purpose is to delay warnings to bytecomp.el, so they can use things
106like `byte-compile-log-warning' to get better file-and-line-number data
107and also to avoid outputting the warning during normal execution."
108 nil)
109(put 'macroexp--eval-if-compile 'byte-compile
110 (lambda (form)
111 (mapc (lambda (x) (funcall (eval x))) (cdr form))
112 (byte-compile-constant nil)))
113
103(defun macroexp--expand-all (form) 114(defun macroexp--expand-all (form)
104 "Expand all macros in FORM. 115 "Expand all macros in FORM.
105This is an internal version of `macroexpand-all'. 116This is an internal version of `macroexpand-all'.
@@ -112,14 +123,17 @@ Assumes the caller has bound `macroexpand-all-environment'."
112 (macroexpand (macroexp--all-forms form 1) 123 (macroexpand (macroexp--all-forms form 1)
113 macroexpand-all-environment) 124 macroexpand-all-environment)
114 ;; Normal form; get its expansion, and then expand arguments. 125 ;; Normal form; get its expansion, and then expand arguments.
115 (let ((new-form (macroexpand form macroexpand-all-environment))) 126 (let ((new-form
116 (when (and (not (eq form new-form)) ;It was a macro call. 127 (macroexpand form macroexpand-all-environment)))
117 (car-safe form) 128 (setq form
118 (symbolp (car form)) 129 (if (and (not (eq form new-form)) ;It was a macro call.
119 (get (car form) 'byte-obsolete-info) 130 (car-safe form)
120 (fboundp 'byte-compile-warn-obsolete)) 131 (symbolp (car form))
121 (byte-compile-warn-obsolete (car form))) 132 (get (car form) 'byte-obsolete-info))
122 (setq form new-form)) 133 `(progn (macroexp--eval-if-compile
134 (lambda () (byte-compile-warn-obsolete ',(car form))))
135 ,new-form)
136 new-form)))
123 (pcase form 137 (pcase form
124 (`(cond . ,clauses) 138 (`(cond . ,clauses)
125 (macroexp--cons 'cond (macroexp--all-clauses clauses) form)) 139 (macroexp--cons 'cond (macroexp--all-clauses clauses) form))
@@ -323,6 +337,86 @@ symbol itself."
323 "Return non-nil if EXP can be copied without extra cost." 337 "Return non-nil if EXP can be copied without extra cost."
324 (or (symbolp exp) (macroexp-const-p exp))) 338 (or (symbolp exp) (macroexp-const-p exp)))
325 339
340;;; Load-time macro-expansion.
341
342;; Because macro-expansion used to be more lazy, eager macro-expansion
343;; tends to bump into previously harmless/unnoticeable cyclic-dependencies.
344;; So, we have to delay macro-expansion like we used to when we detect
345;; such a cycle, and we also want to help coders resolve those cycles (since
346;; they can be non-obvious) by providing a usefully trimmed backtrace
347;; (hopefully) highlighting the problem.
348
349(defun macroexp--backtrace ()
350 "Return the Elisp backtrace, more recent frames first."
351 (let ((bt ())
352 (i 0))
353 (while
354 (let ((frame (backtrace-frame i)))
355 (when frame
356 (push frame bt)
357 (setq i (1+ i)))))
358 (nreverse bt)))
359
360(defun macroexp--trim-backtrace-frame (frame)
361 (pcase frame
362 (`(,_ macroexpand (,head . ,_) . ,_) `(macroexpand (,head …)))
363 (`(,_ internal-macroexpand-for-load (,head ,second . ,_) . ,_)
364 (if (or (symbolp second)
365 (and (eq 'quote (car-safe second))
366 (symbolp (cadr second))))
367 `(macroexpand-all (,head ,second …))
368 '(macroexpand-all …)))
369 (`(,_ load-with-code-conversion ,name . ,_)
370 `(load ,(file-name-nondirectory name)))))
371
372(defvar macroexp--pending-eager-loads nil
373 "Stack of files currently undergoing eager macro-expansion.")
374
375(defun internal-macroexpand-for-load (form)
376 ;; Called from the eager-macroexpansion in readevalloop.
377 (cond
378 ;; Don't repeat the same warning for every top-level element.
379 ((eq 'skip (car macroexp--pending-eager-loads)) form)
380 ;; If we detect a cycle, skip macro-expansion for now, and output a warning
381 ;; with a trimmed backtrace.
382 ((and load-file-name (member load-file-name macroexp--pending-eager-loads))
383 (let* ((bt (delq nil
384 (mapcar #'macroexp--trim-backtrace-frame
385 (macroexp--backtrace))))
386 (elem `(load ,(file-name-nondirectory load-file-name)))
387 (tail (member elem (cdr (member elem bt)))))
388 (if tail (setcdr tail (list '…)))
389 (if (eq (car-safe (car bt)) 'macroexpand-all) (setq bt (cdr bt)))
390 (message "Warning: Eager macro-expansion skipped due to cycle:\n %s"
391 (mapconcat #'prin1-to-string (nreverse bt) " => "))
392 (push 'skip macroexp--pending-eager-loads)
393 form))
394 (t
395 (condition-case err
396 (let ((macroexp--pending-eager-loads
397 (cons load-file-name macroexp--pending-eager-loads)))
398 (macroexpand-all form))
399 (error
400 ;; Hopefully this shouldn't happen thanks to the cycle detection,
401 ;; but in case it does happen, let's catch the error and give the
402 ;; code a chance to macro-expand later.
403 (message "Eager macro-expansion failure: %S" err)
404 form)))))
405
406;; ¡¡¡ Big Ugly Hack !!!
407;; src/bootstrap-emacs is mostly used to compile .el files, so it needs
408;; macroexp, bytecomp, cconv, and byte-opt to be fast. Generally this is done
409;; by compiling those files first, but this only makes a difference if those
410;; files are not preloaded. But macroexp.el is preloaded so we reload it if
411;; the current version is interpreted and there's a compiled version available.
412(eval-when-compile
413 (add-hook 'emacs-startup-hook
414 (lambda ()
415 (and (not (byte-code-function-p
416 (symbol-function 'macroexpand-all)))
417 (locate-library "macroexp.elc")
418 (load "macroexp.elc")))))
419
326(provide 'macroexp) 420(provide 'macroexp)
327 421
328;;; macroexp.el ends here 422;;; macroexp.el ends here
diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el
index e7806440bf3..289751f4944 100644
--- a/lisp/emacs-lisp/map-ynp.el
+++ b/lisp/emacs-lisp/map-ynp.el
@@ -123,16 +123,6 @@ Returns the number of actions taken."
123 map 123 map
124 (let ((map (make-sparse-keymap))) 124 (let ((map (make-sparse-keymap)))
125 (set-keymap-parent map query-replace-map) 125 (set-keymap-parent map query-replace-map)
126 (define-key map [?\C-\M-v] 'scroll-other-window)
127 (define-key map [M-next] 'scroll-other-window)
128 (define-key map [?\C-\M-\S-v] 'scroll-other-window-down)
129 (define-key map [M-prior] 'scroll-other-window-down)
130 ;; The above are rather inconvenient, so maybe we should
131 ;; provide the non-other keys for the other-scroll as well.
132 ;; (define-key map [?\C-v] 'scroll-other-window)
133 ;; (define-key map [next] 'scroll-other-window)
134 ;; (define-key map [?\M-v] 'scroll-other-window-down)
135 ;; (define-key map [prior] 'scroll-other-window-down)
136 (dolist (elt action-alist) 126 (dolist (elt action-alist)
137 (define-key map (vector (car elt)) (vector (nth 1 elt)))) 127 (define-key map (vector (car elt)) (vector (nth 1 elt))))
138 map))) 128 map)))
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 4aeed7e4d0e..09e47b69b91 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -60,6 +60,8 @@
60;; is in a loop, the repeated macro-expansion becomes terribly costly, so we 60;; is in a loop, the repeated macro-expansion becomes terribly costly, so we
61;; memoize previous macro expansions to try and avoid recomputing them 61;; memoize previous macro expansions to try and avoid recomputing them
62;; over and over again. 62;; over and over again.
63;; FIXME: Now that macroexpansion is also performed when loading an interpreted
64;; file, this is not a real problem any more.
63(defconst pcase--memoize (make-hash-table :weakness 'key :test 'eq)) 65(defconst pcase--memoize (make-hash-table :weakness 'key :test 'eq))
64;; (defconst pcase--memoize-1 (make-hash-table :test 'eq)) 66;; (defconst pcase--memoize-1 (make-hash-table :test 'eq))
65;; (defconst pcase--memoize-2 (make-hash-table :weakness 'key :test 'equal)) 67;; (defconst pcase--memoize-2 (make-hash-table :weakness 'key :test 'equal))
diff --git a/lisp/emulation/cua-rect.el b/lisp/emulation/cua-rect.el
index 39ce5901524..f63d79adf47 100644
--- a/lisp/emulation/cua-rect.el
+++ b/lisp/emulation/cua-rect.el
@@ -1423,7 +1423,9 @@ With prefix arg, indent to that column."
1423 (define-key cua--rectangle-keymap [remap set-mark-command] 'cua-toggle-rectangle-mark) 1423 (define-key cua--rectangle-keymap [remap set-mark-command] 'cua-toggle-rectangle-mark)
1424 1424
1425 (define-key cua--rectangle-keymap [remap forward-char] 'cua-resize-rectangle-right) 1425 (define-key cua--rectangle-keymap [remap forward-char] 'cua-resize-rectangle-right)
1426 (define-key cua--rectangle-keymap [remap right-char] 'cua-resize-rectangle-right)
1426 (define-key cua--rectangle-keymap [remap backward-char] 'cua-resize-rectangle-left) 1427 (define-key cua--rectangle-keymap [remap backward-char] 'cua-resize-rectangle-left)
1428 (define-key cua--rectangle-keymap [remap left-char] 'cua-resize-rectangle-left)
1427 (define-key cua--rectangle-keymap [remap next-line] 'cua-resize-rectangle-down) 1429 (define-key cua--rectangle-keymap [remap next-line] 'cua-resize-rectangle-down)
1428 (define-key cua--rectangle-keymap [remap previous-line] 'cua-resize-rectangle-up) 1430 (define-key cua--rectangle-keymap [remap previous-line] 'cua-resize-rectangle-up)
1429 (define-key cua--rectangle-keymap [remap end-of-line] 'cua-resize-rectangle-eol) 1431 (define-key cua--rectangle-keymap [remap end-of-line] 'cua-resize-rectangle-eol)
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el
index 58402e37508..d3ddab8af1b 100644
--- a/lisp/eshell/em-unix.el
+++ b/lisp/eshell/em-unix.el
@@ -1111,7 +1111,7 @@ Execute a COMMAND as the superuser or another USER.")
1111 (substring prefix 0 -1) user host dir) 1111 (substring prefix 0 -1) user host dir)
1112 (format "/sudo:%s@%s:%s" user host dir)))) 1112 (format "/sudo:%s@%s:%s" user host dir))))
1113 ;; Ensure, that Tramp has connected to that construct already. 1113 ;; Ensure, that Tramp has connected to that construct already.
1114 (file-exists-p default-directory) 1114 (ignore (file-exists-p default-directory))
1115 (eshell-named-command (car orig-args) (cdr orig-args)))))))) 1115 (eshell-named-command (car orig-args) (cdr orig-args))))))))
1116 1116
1117(put 'eshell/sudo 'eshell-no-numeric-conversions t) 1117(put 'eshell/sudo 'eshell-no-numeric-conversions t)
diff --git a/lisp/files.el b/lisp/files.el
index 6528632c841..4acdb542089 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2145,7 +2145,7 @@ unless NOMODES is non-nil."
2145 (not buffer-read-only) 2145 (not buffer-read-only)
2146 (save-excursion 2146 (save-excursion
2147 (goto-char (point-max)) 2147 (goto-char (point-max))
2148 (insert "\n"))) 2148 (ignore-errors (insert "\n"))))
2149 (when (and buffer-read-only 2149 (when (and buffer-read-only
2150 view-read-only 2150 view-read-only
2151 (not (eq (get major-mode 'mode-class) 'special))) 2151 (not (eq (get major-mode 'mode-class) 'special)))
@@ -2951,20 +2951,16 @@ UNSAFE-VARS is the list of those that aren't marked as safe or risky.
2951RISKY-VARS is the list of those that are marked as risky. 2951RISKY-VARS is the list of those that are marked as risky.
2952If these settings come from directory-local variables, then 2952If these settings come from directory-local variables, then
2953DIR-NAME is the name of the associated directory. Otherwise it is nil." 2953DIR-NAME is the name of the associated directory. Otherwise it is nil."
2954 (if noninteractive 2954 (unless noninteractive
2955 nil 2955 (let ((name (cond (dir-name)
2956 (save-window-excursion 2956 (buffer-file-name
2957 (let* ((name (or dir-name 2957 (file-name-nondirectory buffer-file-name))
2958 (if buffer-file-name 2958 ((concat "buffer " (buffer-name)))))
2959 (file-name-nondirectory buffer-file-name) 2959 (offer-save (and (eq enable-local-variables t)
2960 (concat "buffer " (buffer-name))))) 2960 unsafe-vars))
2961 (offer-save (and (eq enable-local-variables t) 2961 (buf (get-buffer-create "*Local Variables*")))
2962 unsafe-vars)) 2962 ;; Set up the contents of the *Local Variables* buffer.
2963 (exit-chars 2963 (with-current-buffer buf
2964 (if offer-save '(?! ?y ?n ?\s ?\C-g) '(?y ?n ?\s ?\C-g)))
2965 (buf (pop-to-buffer "*Local Variables*"))
2966 prompt char)
2967 (set (make-local-variable 'cursor-type) nil)
2968 (erase-buffer) 2964 (erase-buffer)
2969 (cond 2965 (cond
2970 (unsafe-vars 2966 (unsafe-vars
@@ -2999,25 +2995,35 @@ n -- to ignore the local variables list.")
2999 (let ((print-escape-newlines t)) 2995 (let ((print-escape-newlines t))
3000 (prin1 (cdr elt) buf)) 2996 (prin1 (cdr elt) buf))
3001 (insert "\n")) 2997 (insert "\n"))
3002 (setq prompt 2998 (set (make-local-variable 'cursor-type) nil)
3003 (format "Please type %s%s: " 2999 (set-buffer-modified-p nil)
3004 (if offer-save "y, n, or !" "y or n") 3000 (goto-char (point-min)))
3005 (if (< (line-number-at-pos) (window-body-height)) 3001
3006 "" 3002 ;; Display the buffer and read a choice.
3007 (push ?\C-v exit-chars) 3003 (save-window-excursion
3008 ", or C-v to scroll"))) 3004 (pop-to-buffer buf)
3009 (goto-char (point-min)) 3005 (let* ((exit-chars '(?y ?n ?\s ?\C-g ?\C-v))
3010 (while (null char) 3006 (prompt (format "Please type %s%s: "
3011 (setq char (read-char-choice prompt exit-chars t)) 3007 (if offer-save "y, n, or !" "y or n")
3012 (when (eq char ?\C-v) 3008 (if (< (line-number-at-pos (point-max))
3013 (condition-case nil 3009 (window-body-height))
3014 (scroll-up) 3010 ""
3015 (error (goto-char (point-min)))) 3011 (push ?\C-v exit-chars)
3016 (setq char nil))) 3012 ", or C-v to scroll")))
3017 (kill-buffer buf) 3013 char)
3018 (when (and offer-save (= char ?!) unsafe-vars) 3014 (if offer-save (push ?! exit-chars))
3019 (customize-push-and-save 'safe-local-variable-values unsafe-vars)) 3015 (while (null char)
3020 (memq char '(?! ?\s ?y)))))) 3016 (setq char (read-char-choice prompt exit-chars t))
3017 (when (eq char ?\C-v)
3018 (condition-case nil
3019 (scroll-up)
3020 (error (goto-char (point-min))
3021 (recenter 1)))
3022 (setq char nil)))
3023 (when (and offer-save (= char ?!) unsafe-vars)
3024 (customize-push-and-save 'safe-local-variable-values unsafe-vars))
3025 (prog1 (memq char '(?! ?\s ?y))
3026 (quit-window t)))))))
3021 3027
3022(defun hack-local-variables-prop-line (&optional mode-only) 3028(defun hack-local-variables-prop-line (&optional mode-only)
3023 "Return local variables specified in the -*- line. 3029 "Return local variables specified in the -*- line.
diff --git a/lisp/frame.el b/lisp/frame.el
index 01225639ecf..c182a964820 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -1657,6 +1657,10 @@ terminals, cursor blinking is controlled by the terminal."
1657 1657
1658(make-variable-buffer-local 'show-trailing-whitespace) 1658(make-variable-buffer-local 'show-trailing-whitespace)
1659 1659
1660;; Defined in dispnew.c.
1661(make-obsolete-variable
1662 'window-system-version "it does not give useful information." "24.3")
1663
1660(provide 'frame) 1664(provide 'frame)
1661 1665
1662;;; frame.el ends here 1666;;; frame.el ends here
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index a4e3d9bde2b..5644c394f7e 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,112 @@
12012-09-10 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * qp.el (quoted-printable-decode-region): Inline+CSE+strength-reduction.
4
52012-09-07 Chong Yidong <cyd@gnu.org>
6
7 * gnus-util.el
8 (gnus-put-text-property-excluding-characters-with-faces): Restore.
9
10 * gnus-salt.el (gnus-tree-highlight-node):
11 * gnus-sum.el (gnus-summary-highlight-line):
12 * gnus-group.el (gnus-group-highlight-line): Revert use of add-face.
13
142012-09-06 Lars Ingebrigtsen <larsi@gnus.org>
15
16 * gnus-util.el: Fix compilation error on XEmacs 21.4.
17
182012-09-06 Juri Linkov <juri@jurta.org>
19
20 * gnus-group.el (gnus-read-ephemeral-gmane-group): Change the naming
21 scheme for buffer names to be more consistent with other group and
22 article buffer names in Gnus.
23
242012-09-06 Lars Ingebrigtsen <larsi@gnus.org>
25
26 * gnus-util.el
27 (gnus-put-text-property-excluding-characters-with-faces): Remove.
28
29 * gnus-compat.el: Define compat function `add-face' from Wolfgang
30 Jenkner.
31
32 * gnus-group.el (gnus-group-highlight-line): Use combining faces.
33
34 * gnus-sum.el (gnus-summary-highlight-line): Ditto.
35
36 * gnus-salt.el (gnus-tree-highlight-node): Ditto.
37
382012-09-06 Katsumi Yamaoka <yamaoka@jpl.org>
39
40 * gnus-score.el (gnus-score-decode-text-parts): Use #' for
41 mm-text-parts used in labels macro to make it work with XEmacs 21.5.
42
43 * gnus-util.el (gnus-string-prefix-p): New function, an alias to
44 string-prefix-p in Emacs >=23.2.
45
46 * nnmaildir.el (nnmaildir--ensure-suffix, nnmaildir--add-flag)
47 (nnmaildir--remove-flag, nnmaildir--scan): Use gnus-string-match-p
48 instead of string-match-p.
49 (nnmaildir--scan): Use gnus-string-prefix-p instead of string-prefix-p.
50
512012-09-06 Kenichi Handa <handa@gnu.org>
52
53 * qp.el (quoted-printable-decode-region): Fix previous change; handle
54 lowercase a..f.
55
562012-09-05 Magnus Henoch <magnus.henoch@gmail.com>
57
58 * nnmaildir.el (nnmaildir--article-set-flags): Fix compilation error.
59
602012-09-05 Martin Stjernholm <mast@lysator.liu.se>
61
62 * gnus-demon.el (gnus-demon-init): Fixed regression when IDLE is t and
63 TIME is set.
64
652012-09-05 Juri Linkov <juri@jurta.org>
66
67 * gnus-group.el (gnus-read-ephemeral-bug-group): Allow opening more
68 than one group at a time (bug#11961).
69
702012-09-05 Julien Danjou <julien@danjou.info>
71
72 * gnus-srvr.el (gnus-server-open-server): Don't message on failure:
73 this hide the real reason with a message giving absolutely no hint.
74
752012-09-05 Lars Ingebrigtsen <larsi@gnus.org>
76
77 * gnus-group.el (gnus-group-mark-article-read): Propagate the read mark
78 to the backend (bug#11804).
79
80 * message.el (message-insert-newsgroups): Don't insert newsgroup
81 duplicates (bug#12275).
82
832012-09-05 John Wiegley <johnw@newartisans.com>
84
85 * gnus.el (gnus-expand-group-parameters): Allow regexp substitutions in
86 sieve rules.
87
882012-09-05 Jan Tatarik <jan.tatarik@gmail.com>
89
90 * gnus-score.el (gnus-score-decode-text-parts): Use #' for the local
91 function.
92
93 * gnus-logic.el (gnus-advanced-body): Allow scoring on decoded bodies.
94
95 * gnus-score.el (gnus-score-decode-text-parts): Ditto.
96
972012-09-05 Magnus Henoch <magnus.henoch@gmail.com>
98
99 * nnmaildir.el: Make nnmaildir understand and write maildir flags.
100 That is, rename files from "unique:2," to "unique:2,S" for "seen", etc.
101 This should make nnmaildir more usable with offlineimap.
102
1032012-09-03 Lars Ingebrigtsen <larsi@gnus.org>
104
105 * gnus-notifications.el (gnus-notifications-notify): Use it.
106
107 * gnus-fun.el (gnus-funcall-no-warning): New function to silence
108 warnings on XEmacs.
109
12012-09-01 Paul Eggert <eggert@cs.ucla.edu> 1102012-09-01 Paul Eggert <eggert@cs.ucla.edu>
2 111
3 Better seeds for (random). 112 Better seeds for (random).
@@ -2291,8 +2400,6 @@
2291 2400
22922011-06-30 Lars Magne Ingebrigtsen <larsi@gnus.org> 24012011-06-30 Lars Magne Ingebrigtsen <larsi@gnus.org>
2293 2402
2294 * dgnushack.el: Autoload sha1 on XEmacs.
2295
2296 * gnus-group.el (gnus-read-ephemeral-emacs-bug-group): Take an optional 2403 * gnus-group.el (gnus-read-ephemeral-emacs-bug-group): Take an optional
2297 quit window configuration. 2404 quit window configuration.
2298 2405
diff --git a/lisp/gnus/gnus-demon.el b/lisp/gnus/gnus-demon.el
index 115c5777448..671c566d09f 100644
--- a/lisp/gnus/gnus-demon.el
+++ b/lisp/gnus/gnus-demon.el
@@ -144,9 +144,12 @@ marked with SPECIAL."
144 (* (gnus-demon-time-to-step time) gnus-demon-timestep)) 144 (* (gnus-demon-time-to-step time) gnus-demon-timestep))
145 (t 145 (t
146 (* time gnus-demon-timestep)))) 146 (* time gnus-demon-timestep))))
147 (idle (if (numberp idle) 147 (idle (cond ((numberp idle)
148 (* idle gnus-demon-timestep) 148 (* idle gnus-demon-timestep))
149 idle)) 149 ((and (eq idle t) (numberp time))
150 time)
151 (t
152 idle)))
150 153
151 (timer 154 (timer
152 (cond 155 (cond
diff --git a/lisp/gnus/gnus-fun.el b/lisp/gnus/gnus-fun.el
index f33eb910c6a..f5e1c5ad691 100644
--- a/lisp/gnus/gnus-fun.el
+++ b/lisp/gnus/gnus-fun.el
@@ -278,6 +278,10 @@ colors of the displayed X-Faces."
278 values)) 278 values))
279 (mapconcat 'identity values " "))) 279 (mapconcat 'identity values " ")))
280 280
281(defun gnus-funcall-no-warning (function &rest args)
282 (when (fboundp function)
283 (apply function args)))
284
281(provide 'gnus-fun) 285(provide 'gnus-fun)
282 286
283;;; gnus-fun.el ends here 287;;; gnus-fun.el ends here
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 2f6fc0ccd19..8c7d0165976 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -2388,7 +2388,7 @@ specified by `gnus-gmane-group-download-format'."
2388 group start (+ start range))) 2388 group start (+ start range)))
2389 (write-region (point-min) (point-max) tmpfile) 2389 (write-region (point-min) (point-max) tmpfile)
2390 (gnus-group-read-ephemeral-group 2390 (gnus-group-read-ephemeral-group
2391 (format "%s.start-%s.range-%s" group start range) 2391 (format "nndoc+ephemeral:%s.start-%s.range-%s" group start range)
2392 `(nndoc ,tmpfile 2392 `(nndoc ,tmpfile
2393 (nndoc-article-type mbox)))) 2393 (nndoc-article-type mbox))))
2394 (delete-file tmpfile))) 2394 (delete-file tmpfile)))
@@ -2481,7 +2481,8 @@ the bug number, and browsing the URL must return mbox output."
2481 "/.*$" "")))) 2481 "/.*$" ""))))
2482 (write-region (point-min) (point-max) tmpfile) 2482 (write-region (point-min) (point-max) tmpfile)
2483 (gnus-group-read-ephemeral-group 2483 (gnus-group-read-ephemeral-group
2484 "gnus-read-ephemeral-bug" 2484 (format "nndoc+ephemeral:bug#%s"
2485 (mapconcat 'number-to-string ids ","))
2485 `(nndoc ,tmpfile 2486 `(nndoc ,tmpfile
2486 (nndoc-article-type mbox)) 2487 (nndoc-article-type mbox))
2487 nil window-conf)) 2488 nil window-conf))
@@ -4670,6 +4671,8 @@ you the groups that have both dormant articles and cached articles."
4670 (setq mark gnus-expirable-mark)) 4671 (setq mark gnus-expirable-mark))
4671 (setq mark (gnus-request-update-mark 4672 (setq mark (gnus-request-update-mark
4672 group article mark)) 4673 group article mark))
4674 (gnus-request-set-mark
4675 group (list (list (list article) 'add '(read))))
4673 (gnus-mark-article-as-read article mark) 4676 (gnus-mark-article-as-read article mark)
4674 (setq gnus-newsgroup-active (gnus-active group)) 4677 (setq gnus-newsgroup-active (gnus-active group))
4675 (when active 4678 (when active
diff --git a/lisp/gnus/gnus-logic.el b/lisp/gnus/gnus-logic.el
index 954295438c9..a440b779930 100644
--- a/lisp/gnus/gnus-logic.el
+++ b/lisp/gnus/gnus-logic.el
@@ -180,46 +180,51 @@
180 (setq header "article")) 180 (setq header "article"))
181 (with-current-buffer nntp-server-buffer 181 (with-current-buffer nntp-server-buffer
182 (let* ((request-func (cond ((string= "head" header) 182 (let* ((request-func (cond ((string= "head" header)
183 'gnus-request-head) 183 'gnus-request-head)
184 ((string= "body" header) 184 ;; We need to peek at the headers to detect the
185 'gnus-request-body) 185 ;; content encoding
186 (t 'gnus-request-article))) 186 ((string= "body" header)
187 ofunc article) 187 'gnus-request-article)
188 (t 'gnus-request-article)))
189 ofunc article handles)
188 ;; Not all backends support partial fetching. In that case, we 190 ;; Not all backends support partial fetching. In that case, we
189 ;; just fetch the entire article. 191 ;; just fetch the entire article.
190 (unless (gnus-check-backend-function 192 (unless (gnus-check-backend-function
191 (intern (concat "request-" header)) 193 (intern (concat "request-" header))
192 gnus-newsgroup-name) 194 gnus-newsgroup-name)
193 (setq ofunc request-func) 195 (setq ofunc request-func)
194 (setq request-func 'gnus-request-article)) 196 (setq request-func 'gnus-request-article))
195 (setq article (mail-header-number gnus-advanced-headers)) 197 (setq article (mail-header-number gnus-advanced-headers))
196 (gnus-message 7 "Scoring article %s..." article) 198 (gnus-message 7 "Scoring article %s..." article)
197 (when (funcall request-func article gnus-newsgroup-name) 199 (when (funcall request-func article gnus-newsgroup-name)
198 (goto-char (point-min)) 200 (when (string= "body" header)
199 ;; If just parts of the article is to be searched and the 201 (setq handles (gnus-score-decode-text-parts)))
200 ;; backend didn't support partial fetching, we just narrow to 202 (goto-char (point-min))
201 ;; the relevant parts. 203 ;; If just parts of the article is to be searched and the
202 (when ofunc 204 ;; backend didn't support partial fetching, we just narrow to
203 (if (eq ofunc 'gnus-request-head) 205 ;; the relevant parts.
204 (narrow-to-region 206 (when ofunc
205 (point) 207 (if (eq ofunc 'gnus-request-head)
206 (or (search-forward "\n\n" nil t) (point-max))) 208 (narrow-to-region
207 (narrow-to-region 209 (point)
208 (or (search-forward "\n\n" nil t) (point)) 210 (or (search-forward "\n\n" nil t) (point-max)))
209 (point-max)))) 211 (narrow-to-region
210 (let* ((case-fold-search (not (eq (downcase (symbol-name type)) 212 (or (search-forward "\n\n" nil t) (point))
211 (symbol-name type)))) 213 (point-max))))
212 (search-func 214 (let* ((case-fold-search (not (eq (downcase (symbol-name type))
213 (cond ((memq type '(r R regexp Regexp)) 215 (symbol-name type))))
214 're-search-forward) 216 (search-func
215 ((memq type '(s S string String)) 217 (cond ((memq type '(r R regexp Regexp))
216 'search-forward) 218 're-search-forward)
217 (t 219 ((memq type '(s S string String))
218 (error "Invalid match type: %s" type))))) 220 'search-forward)
219 (goto-char (point-min)) 221 (t
220 (prog1 222 (error "Invalid match type: %s" type)))))
221 (funcall search-func match nil t) 223 (goto-char (point-min))
222 (widen))))))) 224 (prog1
225 (funcall search-func match nil t)
226 (widen)))
227 (when handles (mm-destroy-parts handles))))))
223 228
224(provide 'gnus-logic) 229(provide 'gnus-logic)
225 230
diff --git a/lisp/gnus/gnus-notifications.el b/lisp/gnus/gnus-notifications.el
index c5129958997..f9c2d309a35 100644
--- a/lisp/gnus/gnus-notifications.el
+++ b/lisp/gnus/gnus-notifications.el
@@ -29,13 +29,16 @@
29 29
30;;; Code: 30;;; Code:
31 31
32(require 'notifications nil t) 32(ignore-errors
33 (require 'notifications))
33(require 'gnus-sum) 34(require 'gnus-sum)
34(require 'gnus-group) 35(require 'gnus-group)
35(require 'gnus-int) 36(require 'gnus-int)
36(require 'gnus-art) 37(require 'gnus-art)
37(require 'gnus-util) 38(require 'gnus-util)
38(require 'google-contacts nil t) ; Optional 39(ignore-errors
40 (require 'google-contacts)) ; Optional
41(require 'gnus-fun)
39 42
40(defgroup gnus-notifications nil 43(defgroup gnus-notifications nil
41 "Send notifications on new message in Gnus." 44 "Send notifications on new message in Gnus."
@@ -81,12 +84,14 @@ not get notifications."
81 "Send a notification about a new mail. 84 "Send a notification about a new mail.
82Return a notification id if any, or t on success." 85Return a notification id if any, or t on success."
83 (if (fboundp 'notifications-notify) 86 (if (fboundp 'notifications-notify)
84 (notifications-notify 87 (gnus-funcall-no-warning
88 'notifications-notify
85 :title from 89 :title from
86 :body subject 90 :body subject
87 :actions '("read" "Read") 91 :actions '("read" "Read")
88 :on-action 'gnus-notifications-action 92 :on-action 'gnus-notifications-action
89 :app-icon (image-search-load-path "gnus/gnus.png") 93 :app-icon (gnus-funcall-no-warning
94 'image-search-load-path "gnus/gnus.png")
90 :app-name "Gnus" 95 :app-name "Gnus"
91 :category "email.arrived" 96 :category "email.arrived"
92 :timeout gnus-notifications-timeout 97 :timeout gnus-notifications-timeout
@@ -100,7 +105,8 @@ Return a notification id if any, or t on success."
100 (let ((google-photo (when (and gnus-notifications-use-google-contacts 105 (let ((google-photo (when (and gnus-notifications-use-google-contacts
101 (fboundp 'google-contacts-get-photo)) 106 (fboundp 'google-contacts-get-photo))
102 (ignore-errors 107 (ignore-errors
103 (google-contacts-get-photo mail-address))))) 108 (gnus-funcall-no-warning
109 'google-contacts-get-photo mail-address)))))
104 (if google-photo 110 (if google-photo
105 google-photo 111 google-photo
106 (when gnus-notifications-use-gravatar 112 (when gnus-notifications-use-gravatar
diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el
index f24d889216e..f215b845514 100644
--- a/lisp/gnus/gnus-score.el
+++ b/lisp/gnus/gnus-score.el
@@ -1717,105 +1717,140 @@ score in `gnus-newsgroup-scored' by SCORE."
1717 (setq entries rest))))) 1717 (setq entries rest)))))
1718 nil) 1718 nil)
1719 1719
1720(defun gnus-score-decode-text-parts ()
1721 (labels ((mm-text-parts (handle)
1722 (cond ((stringp (car handle))
1723 (let ((parts (mapcan #'mm-text-parts (cdr handle))))
1724 (if (equal "multipart/alternative" (car handle))
1725 ;; pick the first supported alternative
1726 (list (car parts))
1727 parts)))
1728
1729 ((bufferp (car handle))
1730 (when (string-match "^text/" (mm-handle-media-type handle))
1731 (list handle)))
1732
1733 (t (mapcan #'mm-text-parts handle))))
1734 (my-mm-display-part (handle)
1735 (when handle
1736 (save-restriction
1737 (narrow-to-region (point) (point))
1738 (mm-display-inline handle)
1739 (goto-char (point-max))))))
1740
1741 (let (;(mm-text-html-renderer 'w3m-standalone)
1742 (handles (mm-dissect-buffer t)))
1743 (save-excursion
1744 (article-goto-body)
1745 (delete-region (point) (point-max))
1746 (mapc #'my-mm-display-part (mm-text-parts handles))
1747 handles))))
1748
1720(defun gnus-score-body (scores header now expire &optional trace) 1749(defun gnus-score-body (scores header now expire &optional trace)
1721 (if gnus-agent-fetching 1750 (if gnus-agent-fetching
1722 nil 1751 nil
1723 (save-excursion 1752 (save-excursion
1724 (setq gnus-scores-articles 1753 (setq gnus-scores-articles
1725 (sort gnus-scores-articles 1754 (sort gnus-scores-articles
1726 (lambda (a1 a2) 1755 (lambda (a1 a2)
1727 (< (mail-header-number (car a1)) 1756 (< (mail-header-number (car a1))
1728 (mail-header-number (car a2)))))) 1757 (mail-header-number (car a2))))))
1729 (set-buffer nntp-server-buffer) 1758 (set-buffer nntp-server-buffer)
1730 (save-restriction 1759 (save-restriction
1731 (let* ((buffer-read-only nil) 1760 (let* ((buffer-read-only nil)
1732 (articles gnus-scores-articles) 1761 (articles gnus-scores-articles)
1733 (all-scores scores) 1762 (all-scores scores)
1734 (request-func (cond ((string= "head" header) 1763 (request-func (cond ((string= "head" header)
1735 'gnus-request-head) 1764 'gnus-request-head)
1736 ((string= "body" header) 1765 ;; We need to peek at the headers to detect
1737 'gnus-request-body) 1766 ;; the content encoding
1738 (t 'gnus-request-article))) 1767 ((string= "body" header)
1739 entries alist ofunc article last) 1768 'gnus-request-article)
1740 (when articles 1769 (t 'gnus-request-article)))
1741 (setq last (mail-header-number (caar (last articles)))) 1770 entries alist ofunc article last)
1742 ;; Not all backends support partial fetching. In that case, 1771 (when articles
1743 ;; we just fetch the entire article. 1772 (setq last (mail-header-number (caar (last articles))))
1744 (unless (gnus-check-backend-function 1773 ;; Not all backends support partial fetching. In that case,
1745 (and (string-match "^gnus-" (symbol-name request-func)) 1774 ;; we just fetch the entire article.
1746 (intern (substring (symbol-name request-func) 1775 (unless (gnus-check-backend-function
1747 (match-end 0)))) 1776 (and (string-match "^gnus-" (symbol-name request-func))
1748 gnus-newsgroup-name) 1777 (intern (substring (symbol-name request-func)
1749 (setq ofunc request-func) 1778 (match-end 0))))
1750 (setq request-func 'gnus-request-article)) 1779 gnus-newsgroup-name)
1751 (while articles 1780 (setq ofunc request-func)
1752 (setq article (mail-header-number (caar articles))) 1781 (setq request-func 'gnus-request-article))
1753 (gnus-message 7 "Scoring article %s of %s..." article last) 1782 (while articles
1754 (widen) 1783 (setq article (mail-header-number (caar articles)))
1755 (when (funcall request-func article gnus-newsgroup-name) 1784 (gnus-message 7 "Scoring article %s of %s..." article last)
1756 (goto-char (point-min)) 1785 (widen)
1757 ;; If just parts of the article is to be searched, but the 1786 (let (handles)
1758 ;; backend didn't support partial fetching, we just narrow 1787 (when (funcall request-func article gnus-newsgroup-name)
1759 ;; to the relevant parts. 1788 (when (string= "body" header)
1760 (when ofunc 1789 (setq handles (gnus-score-decode-text-parts)))
1761 (if (eq ofunc 'gnus-request-head) 1790 (goto-char (point-min))
1762 (narrow-to-region 1791 ;; If just parts of the article is to be searched, but the
1763 (point) 1792 ;; backend didn't support partial fetching, we just narrow
1764 (or (search-forward "\n\n" nil t) (point-max))) 1793 ;; to the relevant parts.
1765 (narrow-to-region 1794 (when ofunc
1766 (or (search-forward "\n\n" nil t) (point)) 1795 (if (eq ofunc 'gnus-request-head)
1767 (point-max)))) 1796 (narrow-to-region
1768 (setq scores all-scores) 1797 (point)
1769 ;; Find matches. 1798 (or (search-forward "\n\n" nil t) (point-max)))
1770 (while scores 1799 (narrow-to-region
1771 (setq alist (pop scores) 1800 (or (search-forward "\n\n" nil t) (point))
1772 entries (assoc header alist)) 1801 (point-max))))
1773 (while (cdr entries) ;First entry is the header index. 1802 (setq scores all-scores)
1774 (let* ((rest (cdr entries)) 1803 ;; Find matches.
1775 (kill (car rest)) 1804 (while scores
1776 (match (nth 0 kill)) 1805 (setq alist (pop scores)
1777 (type (or (nth 3 kill) 's)) 1806 entries (assoc header alist))
1778 (score (or (nth 1 kill) 1807 (while (cdr entries) ;First entry is the header index.
1779 gnus-score-interactive-default-score)) 1808 (let* ((rest (cdr entries))
1780 (date (nth 2 kill)) 1809 (kill (car rest))
1781 (found nil) 1810 (match (nth 0 kill))
1782 (case-fold-search 1811 (type (or (nth 3 kill) 's))
1783 (not (or (eq type 'R) (eq type 'S) 1812 (score (or (nth 1 kill)
1784 (eq type 'Regexp) (eq type 'String)))) 1813 gnus-score-interactive-default-score))
1785 (search-func 1814 (date (nth 2 kill))
1786 (cond ((or (eq type 'r) (eq type 'R) 1815 (found nil)
1787 (eq type 'regexp) (eq type 'Regexp)) 1816 (case-fold-search
1788 're-search-forward) 1817 (not (or (eq type 'R) (eq type 'S)
1789 ((or (eq type 's) (eq type 'S) 1818 (eq type 'Regexp) (eq type 'String))))
1790 (eq type 'string) (eq type 'String)) 1819 (search-func
1791 'search-forward) 1820 (cond ((or (eq type 'r) (eq type 'R)
1792 (t 1821 (eq type 'regexp) (eq type 'Regexp))
1793 (error "Invalid match type: %s" type))))) 1822 're-search-forward)
1794 (goto-char (point-min)) 1823 ((or (eq type 's) (eq type 'S)
1795 (when (funcall search-func match nil t) 1824 (eq type 'string) (eq type 'String))
1796 ;; Found a match, update scores. 1825 'search-forward)
1797 (setcdr (car articles) (+ score (cdar articles))) 1826 (t
1798 (setq found t) 1827 (error "Invalid match type: %s" type)))))
1799 (when trace 1828 (goto-char (point-min))
1800 (push 1829 (when (funcall search-func match nil t)
1801 (cons (car-safe (rassq alist gnus-score-cache)) 1830 ;; Found a match, update scores.
1802 kill) 1831 (setcdr (car articles) (+ score (cdar articles)))
1803 gnus-score-trace))) 1832 (setq found t)
1804 ;; Update expire date 1833 (when trace
1805 (unless trace 1834 (push
1806 (cond 1835 (cons (car-safe (rassq alist gnus-score-cache))
1807 ((null date)) ;Permanent entry. 1836 kill)
1808 ((and found gnus-update-score-entry-dates) 1837 gnus-score-trace)))
1809 ;; Match, update date. 1838 ;; Update expire date
1810 (gnus-score-set 'touched '(t) alist) 1839 (unless trace
1811 (setcar (nthcdr 2 kill) now)) 1840 (cond
1812 ((and expire (< date expire)) ;Old entry, remove. 1841 ((null date)) ;Permanent entry.
1813 (gnus-score-set 'touched '(t) alist) 1842 ((and found gnus-update-score-entry-dates)
1814 (setcdr entries (cdr rest)) 1843 ;; Match, update date.
1815 (setq rest entries)))) 1844 (gnus-score-set 'touched '(t) alist)
1816 (setq entries rest))))) 1845 (setcar (nthcdr 2 kill) now))
1817 (setq articles (cdr articles))))))) 1846 ((and expire (< date expire)) ;Old entry, remove.
1818 nil)) 1847 (gnus-score-set 'touched '(t) alist)
1848 (setcdr entries (cdr rest))
1849 (setq rest entries))))
1850 (setq entries rest))))
1851 (when handles (mm-destroy-parts handles))))
1852 (setq articles (cdr articles)))))))
1853 nil))
1819 1854
1820(defun gnus-score-thread (scores header now expire &optional trace) 1855(defun gnus-score-thread (scores header now expire &optional trace)
1821 (gnus-score-followup scores header now expire trace t)) 1856 (gnus-score-followup scores header now expire trace t))
diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el
index 66509c939dc..f58cb80311a 100644
--- a/lisp/gnus/gnus-srvr.el
+++ b/lisp/gnus/gnus-srvr.el
@@ -490,8 +490,7 @@ The following commands are available:
490 (error "No such server: %s" server)) 490 (error "No such server: %s" server))
491 (gnus-server-set-status method 'ok) 491 (gnus-server-set-status method 'ok)
492 (prog1 492 (prog1
493 (or (gnus-open-server method) 493 (gnus-open-server method)
494 (progn (message "Couldn't open %s" server) nil))
495 (gnus-server-update-server server) 494 (gnus-server-update-server server)
496 (gnus-server-position-point)))) 495 (gnus-server-position-point))))
497 496
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index 26178afa864..4c5eabab723 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -1926,6 +1926,18 @@ Same as `string-match' except this function does not change the match data."
1926 (save-match-data 1926 (save-match-data
1927 (string-match regexp string start)))) 1927 (string-match regexp string start))))
1928 1928
1929(if (fboundp 'string-prefix-p)
1930 (defalias 'gnus-string-prefix-p 'string-prefix-p)
1931 (defun gnus-string-prefix-p (str1 str2 &optional ignore-case)
1932 "Return non-nil if STR1 is a prefix of STR2.
1933If IGNORE-CASE is non-nil, the comparison is done without paying attention
1934to case differences."
1935 (and (<= (length str1) (length str2))
1936 (let ((prefix (substring str2 0 (length str1))))
1937 (if ignore-case
1938 (string-equal (downcase str1) (downcase prefix))
1939 (string-equal str1 prefix))))))
1940
1929(eval-and-compile 1941(eval-and-compile
1930 (if (fboundp 'macroexpand-all) 1942 (if (fboundp 'macroexpand-all)
1931 (defalias 'gnus-macroexpand-all 'macroexpand-all) 1943 (defalias 'gnus-macroexpand-all 'macroexpand-all)
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el
index 5862e7807a2..8fbde5c8ecc 100644
--- a/lisp/gnus/gnus.el
+++ b/lisp/gnus/gnus.el
@@ -3824,12 +3824,28 @@ You should probably use `gnus-find-method-for-group' instead."
3824 "Go through PARAMETERS and expand them according to the match data." 3824 "Go through PARAMETERS and expand them according to the match data."
3825 (let (new) 3825 (let (new)
3826 (dolist (elem parameters) 3826 (dolist (elem parameters)
3827 (if (and (stringp (cdr elem)) 3827 (cond
3828 (string-match "\\\\[0-9&]" (cdr elem))) 3828 ((and (stringp (cdr elem))
3829 (push (cons (car elem) 3829 (string-match "\\\\[0-9&]" (cdr elem)))
3830 (gnus-expand-group-parameter match (cdr elem) group)) 3830 (push (cons (car elem)
3831 new) 3831 (gnus-expand-group-parameter match (cdr elem) group))
3832 (push elem new))) 3832 new))
3833 ;; For `sieve' group parameters, perform substitutions for every
3834 ;; string within the match rule. This allows for parameters such
3835 ;; as:
3836 ;; ("list\\.\\(.*\\)"
3837 ;; (sieve header :is "list-id" "<\\1.domain.org>"))
3838 ((eq 'sieve (car elem))
3839 (push (mapcar (lambda (sieve-elem)
3840 (if (and (stringp sieve-elem)
3841 (string-match "\\\\[0-9&]" sieve-elem))
3842 (gnus-expand-group-parameter match sieve-elem
3843 group)
3844 sieve-elem))
3845 (cdr elem))
3846 new))
3847 (t
3848 (push elem new))))
3833 new)) 3849 new))
3834 3850
3835(defun gnus-group-fast-parameter (group symbol &optional allow-list) 3851(defun gnus-group-fast-parameter (group symbol &optional allow-list)
@@ -3861,9 +3877,20 @@ The function `gnus-group-find-parameter' will do that for you."
3861 (when this-result 3877 (when this-result
3862 (setq result (car this-result)) 3878 (setq result (car this-result))
3863 ;; Expand if necessary. 3879 ;; Expand if necessary.
3864 (if (and (stringp result) (string-match "\\\\[0-9&]" result)) 3880 (cond
3865 (setq result (gnus-expand-group-parameter 3881 ((and (stringp result) (string-match "\\\\[0-9&]" result))
3866 (car head) result group))))))) 3882 (setq result (gnus-expand-group-parameter
3883 (car head) result group)))
3884 ;; For `sieve' group parameters, perform substitutions
3885 ;; for every string within the match rule (see above).
3886 ((eq symbol 'sieve)
3887 (setq result
3888 (mapcar (lambda (elem)
3889 (if (stringp elem)
3890 (gnus-expand-group-parameter (car head)
3891 elem group)
3892 elem))
3893 result))))))))
3867 ;; Done. 3894 ;; Done.
3868 result)))) 3895 result))))
3869 3896
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 18088423eb0..42911ce0648 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -3292,11 +3292,33 @@ or in the synonym headers, defined by `message-header-synonyms'."
3292(defun message-insert-newsgroups () 3292(defun message-insert-newsgroups ()
3293 "Insert the Newsgroups header from the article being replied to." 3293 "Insert the Newsgroups header from the article being replied to."
3294 (interactive) 3294 (interactive)
3295 (when (and (message-position-on-field "Newsgroups") 3295 (let ((old-newsgroups (mail-fetch-field "newsgroups"))
3296 (mail-fetch-field "newsgroups") 3296 (new-newsgroups (message-fetch-reply-field "newsgroups"))
3297 (not (string-match "\\` *\\'" (mail-fetch-field "newsgroups")))) 3297 (first t)
3298 (insert ",")) 3298 insert-newsgroups)
3299 (insert (or (message-fetch-reply-field "newsgroups") ""))) 3299 (message-position-on-field "Newsgroups")
3300 (cond
3301 ((not new-newsgroups)
3302 (error "No Newsgroups to insert"))
3303 ((not old-newsgroups)
3304 (insert new-newsgroups))
3305 (t
3306 (setq new-newsgroups (split-string new-newsgroups "[, ]+")
3307 old-newsgroups (split-string old-newsgroups "[, ]+"))
3308 (dolist (group new-newsgroups)
3309 (unless (member group old-newsgroups)
3310 (push group insert-newsgroups)))
3311 (if (null insert-newsgroups)
3312 (error "Newgroup%s already in the header"
3313 (if (> (length new-newsgroups) 1)
3314 "s" ""))
3315 (when old-newsgroups
3316 (setq first nil))
3317 (dolist (group insert-newsgroups)
3318 (unless first
3319 (insert ","))
3320 (setq first nil)
3321 (insert group)))))))
3300 3322
3301 3323
3302 3324
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index 7139a528e11..74a693a9c61 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -77,6 +77,56 @@
77 77
78(defconst nnmaildir-version "Gnus") 78(defconst nnmaildir-version "Gnus")
79 79
80(defconst nnmaildir-flag-mark-mapping
81 '((?F . tick)
82 (?R . reply)
83 (?S . read))
84 "Alist mapping Maildir filename flags to Gnus marks.
85Maildir filenames are of the form \"unique-id:2,FLAGS\",
86where FLAGS are a string of characters in ASCII order.
87Some of the FLAGS correspond to Gnus marks.")
88
89(defsubst nnmaildir--mark-to-flag (mark)
90 "Find the Maildir flag that corresponds to MARK (an atom).
91Return a character, or `nil' if not found.
92See `nnmaildir-flag-mark-mapping'."
93 (car (rassq mark nnmaildir-flag-mark-mapping)))
94
95(defsubst nnmaildir--flag-to-mark (flag)
96 "Find the Gnus mark that corresponds to FLAG (a character).
97Return an atom, or `nil' if not found.
98See `nnmaildir-flag-mark-mapping'."
99 (cdr (assq flag nnmaildir-flag-mark-mapping)))
100
101(defun nnmaildir--ensure-suffix (filename)
102 "Ensure that FILENAME contains the suffix \":2,\"."
103 (if (gnus-string-match-p ":2," filename)
104 filename
105 (concat filename ":2,")))
106
107(defun nnmaildir--add-flag (flag suffix)
108 "Return a copy of SUFFIX where FLAG is set.
109SUFFIX should start with \":2,\"."
110 (unless (gnus-string-match-p "^:2," suffix)
111 (error "Invalid suffix `%s'" suffix))
112 (let* ((flags (substring suffix 3))
113 (flags-as-list (append flags nil))
114 (new-flags
115 (concat (gnus-delete-duplicates
116 ;; maildir flags must be sorted
117 (sort (cons flag flags-as-list) '<)))))
118 (concat ":2," new-flags)))
119
120(defun nnmaildir--remove-flag (flag suffix)
121 "Return a copy of SUFFIX where FLAG is cleared.
122SUFFIX should start with \":2,\"."
123 (unless (gnus-string-match-p "^:2," suffix)
124 (error "Invalid suffix `%s'" suffix))
125 (let* ((flags (substring suffix 3))
126 (flags-as-list (append flags nil))
127 (new-flags (concat (delq flag flags-as-list))))
128 (concat ":2," new-flags)))
129
80(defvar nnmaildir-article-file-name nil 130(defvar nnmaildir-article-file-name nil
81 "*The filename of the most recently requested article. This variable is set 131 "*The filename of the most recently requested article. This variable is set
82by nnmaildir-request-article.") 132by nnmaildir-request-article.")
@@ -152,6 +202,16 @@ by nnmaildir-request-article.")
152 (gnm nil) ;; flag: split from mail-sources? 202 (gnm nil) ;; flag: split from mail-sources?
153 (target-prefix nil :type string)) ;; symlink target prefix 203 (target-prefix nil :type string)) ;; symlink target prefix
154 204
205(defun nnmaildir--article-set-flags (article new-suffix curdir)
206 (let* ((prefix (nnmaildir--art-prefix article))
207 (suffix (nnmaildir--art-suffix article))
208 (article-file (concat curdir prefix suffix))
209 (new-name (concat curdir prefix new-suffix)))
210 (unless (file-exists-p article-file)
211 (error "Couldn't find article file %s" article-file))
212 (rename-file article-file new-name 'replace)
213 (setf (nnmaildir--art-suffix article) new-suffix)))
214
155(defun nnmaildir--expired-article (group article) 215(defun nnmaildir--expired-article (group article)
156 (setf (nnmaildir--art-nov article) nil) 216 (setf (nnmaildir--art-nov article) nil)
157 (let ((flist (nnmaildir--grp-flist group)) 217 (let ((flist (nnmaildir--grp-flist group))
@@ -208,29 +268,33 @@ by nnmaildir-request-article.")
208 (eval param)) 268 (eval param))
209 269
210(defmacro nnmaildir--with-nntp-buffer (&rest body) 270(defmacro nnmaildir--with-nntp-buffer (&rest body)
271 (declare (debug (body)))
211 `(with-current-buffer nntp-server-buffer 272 `(with-current-buffer nntp-server-buffer
212 ,@body)) 273 ,@body))
213(defmacro nnmaildir--with-work-buffer (&rest body) 274(defmacro nnmaildir--with-work-buffer (&rest body)
275 (declare (debug (body)))
214 `(with-current-buffer (get-buffer-create " *nnmaildir work*") 276 `(with-current-buffer (get-buffer-create " *nnmaildir work*")
215 ,@body)) 277 ,@body))
216(defmacro nnmaildir--with-nov-buffer (&rest body) 278(defmacro nnmaildir--with-nov-buffer (&rest body)
279 (declare (debug (body)))
217 `(with-current-buffer (get-buffer-create " *nnmaildir nov*") 280 `(with-current-buffer (get-buffer-create " *nnmaildir nov*")
218 ,@body)) 281 ,@body))
219(defmacro nnmaildir--with-move-buffer (&rest body) 282(defmacro nnmaildir--with-move-buffer (&rest body)
283 (declare (debug (body)))
220 `(with-current-buffer (get-buffer-create " *nnmaildir move*") 284 `(with-current-buffer (get-buffer-create " *nnmaildir move*")
221 ,@body)) 285 ,@body))
222 286
223(defmacro nnmaildir--subdir (dir subdir) 287(defsubst nnmaildir--subdir (dir subdir)
224 `(file-name-as-directory (concat ,dir ,subdir))) 288 (file-name-as-directory (concat dir subdir)))
225(defmacro nnmaildir--srvgrp-dir (srv-dir gname) 289(defsubst nnmaildir--srvgrp-dir (srv-dir gname)
226 `(nnmaildir--subdir ,srv-dir ,gname)) 290 (nnmaildir--subdir srv-dir gname))
227(defmacro nnmaildir--tmp (dir) `(nnmaildir--subdir ,dir "tmp")) 291(defsubst nnmaildir--tmp (dir) (nnmaildir--subdir dir "tmp"))
228(defmacro nnmaildir--new (dir) `(nnmaildir--subdir ,dir "new")) 292(defsubst nnmaildir--new (dir) (nnmaildir--subdir dir "new"))
229(defmacro nnmaildir--cur (dir) `(nnmaildir--subdir ,dir "cur")) 293(defsubst nnmaildir--cur (dir) (nnmaildir--subdir dir "cur"))
230(defmacro nnmaildir--nndir (dir) `(nnmaildir--subdir ,dir ".nnmaildir")) 294(defsubst nnmaildir--nndir (dir) (nnmaildir--subdir dir ".nnmaildir"))
231(defmacro nnmaildir--nov-dir (dir) `(nnmaildir--subdir ,dir "nov")) 295(defsubst nnmaildir--nov-dir (dir) (nnmaildir--subdir dir "nov"))
232(defmacro nnmaildir--marks-dir (dir) `(nnmaildir--subdir ,dir "marks")) 296(defsubst nnmaildir--marks-dir (dir) (nnmaildir--subdir dir "marks"))
233(defmacro nnmaildir--num-dir (dir) `(nnmaildir--subdir ,dir "num")) 297(defsubst nnmaildir--num-dir (dir) (nnmaildir--subdir dir "num"))
234 298
235(defmacro nnmaildir--unlink (file-arg) 299(defmacro nnmaildir--unlink (file-arg)
236 `(let ((file ,file-arg)) 300 `(let ((file ,file-arg))
@@ -305,6 +369,7 @@ by nnmaildir-request-article.")
305 string) 369 string)
306 370
307(defmacro nnmaildir--condcase (errsym body &rest handler) 371(defmacro nnmaildir--condcase (errsym body &rest handler)
372 (declare (debug (sexp form body)))
308 `(condition-case ,errsym 373 `(condition-case ,errsym
309 (let ((system-messages-locale "C")) ,body) 374 (let ((system-messages-locale "C")) ,body)
310 (error . ,handler))) 375 (error . ,handler)))
@@ -759,7 +824,7 @@ by nnmaildir-request-article.")
759 (dolist (file (funcall ls ndir nil "\\`[^.]" 'nosort)) 824 (dolist (file (funcall ls ndir nil "\\`[^.]" 'nosort))
760 (setq x (concat ndir file)) 825 (setq x (concat ndir file))
761 (and (time-less-p (nth 5 (file-attributes x)) (current-time)) 826 (and (time-less-p (nth 5 (file-attributes x)) (current-time))
762 (rename-file x (concat cdir file ":2,")))) 827 (rename-file x (concat cdir (nnmaildir--ensure-suffix file)))))
763 (setf (nnmaildir--grp-new group) nattr)) 828 (setf (nnmaildir--grp-new group) nattr))
764 (setq cattr (nth 5 (file-attributes cdir))) 829 (setq cattr (nth 5 (file-attributes cdir)))
765 (if (equal cattr (nnmaildir--grp-cur group)) 830 (if (equal cattr (nnmaildir--grp-cur group))
@@ -784,11 +849,23 @@ by nnmaildir-request-article.")
784 cdir (nnmaildir--marks-dir nndir) 849 cdir (nnmaildir--marks-dir nndir)
785 ndir (nnmaildir--subdir cdir "tick") 850 ndir (nnmaildir--subdir cdir "tick")
786 cdir (nnmaildir--subdir cdir "read")) 851 cdir (nnmaildir--subdir cdir "read"))
787 (dolist (file files) 852 (dolist (prefix-suffix files)
788 (setq file (car file)) 853 (let ((prefix (car prefix-suffix))
789 (if (or (not (file-exists-p (concat cdir file))) 854 (suffix (cdr prefix-suffix)))
790 (file-exists-p (concat ndir file))) 855 ;; increase num for each unread or ticked article
791 (setq num (1+ num))))) 856 (when (or
857 ;; first look for marks in suffix, if it's valid...
858 (when (and (stringp suffix)
859 (gnus-string-prefix-p ":2," suffix))
860 (or
861 (not (gnus-string-match-p
862 (string (nnmaildir--mark-to-flag 'read)) suffix))
863 (gnus-string-match-p
864 (string (nnmaildir--mark-to-flag 'tick)) suffix)))
865 ;; then look in marks directories
866 (not (file-exists-p (concat cdir prefix)))
867 (file-exists-p (concat ndir prefix)))
868 (incf num)))))
792 (setf (nnmaildir--grp-cache group) (make-vector num nil)) 869 (setf (nnmaildir--grp-cache group) (make-vector num nil))
793 (let ((inhibit-quit t)) 870 (let ((inhibit-quit t))
794 (set (intern gname groups) group)) 871 (set (intern gname groups) group))
@@ -916,12 +993,15 @@ by nnmaildir-request-article.")
916 "\n"))))) 993 "\n")))))
917 'group) 994 'group)
918 995
919(defun nnmaildir-request-marks (gname info &optional server) 996(defun nnmaildir-request-update-info (gname info &optional server)
920 (let ((group (nnmaildir--prepare server gname)) 997 (let* ((group (nnmaildir--prepare server gname))
921 pgname flist always-marks never-marks old-marks dotfile num dir 998 (curdir (nnmaildir--cur
922 markdirs marks mark ranges markdir article read end new-marks ls 999 (nnmaildir--srvgrp-dir
923 old-mmth new-mmth mtime mark-sym existing missing deactivate-mark 1000 (nnmaildir--srv-dir nnmaildir--cur-server) gname)))
924 article-list) 1001 (curdir-mtime (nth 5 (file-attributes curdir)))
1002 pgname flist always-marks never-marks old-marks dotfile num dir
1003 all-marks marks mark ranges markdir read end new-marks ls
1004 old-mmth new-mmth mtime mark-sym existing missing deactivate-mark)
925 (catch 'return 1005 (catch 'return
926 (unless group 1006 (unless group
927 (setf (nnmaildir--srv-error nnmaildir--cur-server) 1007 (setf (nnmaildir--srv-error nnmaildir--cur-server)
@@ -950,34 +1030,71 @@ by nnmaildir-request-article.")
950 dir (nnmaildir--nndir dir) 1030 dir (nnmaildir--nndir dir)
951 dir (nnmaildir--marks-dir dir) 1031 dir (nnmaildir--marks-dir dir)
952 ls (nnmaildir--group-ls nnmaildir--cur-server pgname) 1032 ls (nnmaildir--group-ls nnmaildir--cur-server pgname)
953 markdirs (funcall ls dir nil "\\`[^.]" 'nosort) 1033 all-marks (gnus-delete-duplicates
954 new-mmth (nnmaildir--up2-1 (length markdirs)) 1034 ;; get mark names from mark dirs and from flag
1035 ;; mappings
1036 (append
1037 (mapcar 'cdr nnmaildir-flag-mark-mapping)
1038 (mapcar 'intern (funcall ls dir nil "\\`[^.]" 'nosort))))
1039 new-mmth (nnmaildir--up2-1 (length all-marks))
955 new-mmth (make-vector new-mmth 0) 1040 new-mmth (make-vector new-mmth 0)
956 old-mmth (nnmaildir--grp-mmth group)) 1041 old-mmth (nnmaildir--grp-mmth group))
957 (dolist (mark markdirs) 1042 (dolist (mark all-marks)
958 (setq markdir (nnmaildir--subdir dir mark) 1043 (setq markdir (nnmaildir--subdir dir (symbol-name mark))
959 mark-sym (intern mark)
960 ranges nil) 1044 ranges nil)
961 (catch 'got-ranges 1045 (catch 'got-ranges
962 (if (memq mark-sym never-marks) (throw 'got-ranges nil)) 1046 (if (memq mark never-marks) (throw 'got-ranges nil))
963 (when (memq mark-sym always-marks) 1047 (when (memq mark always-marks)
964 (setq ranges existing) 1048 (setq ranges existing)
965 (throw 'got-ranges nil)) 1049 (throw 'got-ranges nil))
966 (setq mtime (nth 5 (file-attributes markdir))) 1050 ;; Find the mtime for this mark. If this mark can be expressed as
967 (set (intern mark new-mmth) mtime) 1051 ;; a filename flag, get the later of the mtimes for markdir and
968 (when (equal mtime (symbol-value (intern-soft mark old-mmth))) 1052 ;; curdir, otherwise only the markdir counts.
969 (setq ranges (assq mark-sym old-marks)) 1053 (setq mtime
1054 (let ((markdir-mtime (nth 5 (file-attributes markdir))))
1055 (cond
1056 ((null (nnmaildir--mark-to-flag mark))
1057 markdir-mtime)
1058 ((null markdir-mtime)
1059 curdir-mtime)
1060 ((null curdir-mtime)
1061 ;; this should never happen...
1062 markdir-mtime)
1063 ((time-less-p markdir-mtime curdir-mtime)
1064 curdir-mtime)
1065 (t
1066 markdir-mtime))))
1067 (set (intern (symbol-name mark) new-mmth) mtime)
1068 (when (equal mtime (symbol-value (intern-soft (symbol-name mark) old-mmth)))
1069 (setq ranges (assq mark old-marks))
970 (if ranges (setq ranges (cdr ranges))) 1070 (if ranges (setq ranges (cdr ranges)))
971 (throw 'got-ranges nil)) 1071 (throw 'got-ranges nil))
972 (setq article-list nil) 1072 (let ((article-list nil))
973 (dolist (prefix (funcall ls markdir nil "\\`[^.]" 'nosort)) 1073 ;; Consider the article marked if it either has the flag in the
974 (setq article (nnmaildir--flist-art flist prefix)) 1074 ;; filename, or is in the markdir. As you'd rarely remove a
975 (if article 1075 ;; flag/mark, this should avoid losing information in the most
976 (setq article-list 1076 ;; common usage pattern.
977 (cons (nnmaildir--art-num article) article-list)))) 1077 (or
978 (setq ranges (gnus-add-to-range ranges (sort article-list '<)))) 1078 (let ((flag (nnmaildir--mark-to-flag mark)))
979 (if (eq mark-sym 'read) (setq read ranges) 1079 ;; If this mark has a corresponding maildir flag...
980 (if ranges (setq marks (cons (cons mark-sym ranges) marks))))) 1080 (when flag
1081 (let ((regexp
1082 (concat "\\`[^.].*:2,[A-Z]*" (string flag))))
1083 ;; ...then find all files with that flag.
1084 (dolist (filename (funcall ls curdir nil regexp 'nosort))
1085 (let* ((prefix (car (split-string filename ":2,")))
1086 (article (nnmaildir--flist-art flist prefix)))
1087 (when article
1088 (push (nnmaildir--art-num article) article-list)))))))
1089 ;; Also check Gnus-specific mark directory, if it exists.
1090 (when (file-directory-p markdir)
1091 (dolist (prefix (funcall ls markdir nil "\\`[^.]" 'nosort))
1092 (let ((article (nnmaildir--flist-art flist prefix)))
1093 (when article
1094 (push (nnmaildir--art-num article) article-list))))))
1095 (setq ranges (gnus-add-to-range ranges (sort article-list '<)))))
1096 (if (eq mark 'read) (setq read ranges)
1097 (if ranges (setq marks (cons (cons mark ranges) marks)))))
981 (gnus-info-set-read info (gnus-range-add read missing)) 1098 (gnus-info-set-read info (gnus-range-add read missing))
982 (gnus-info-set-marks info marks 'extend) 1099 (gnus-info-set-marks info marks 'extend)
983 (setf (nnmaildir--grp-mmth group) new-mmth) 1100 (setf (nnmaildir--grp-mmth group) new-mmth)
@@ -1525,39 +1642,63 @@ by nnmaildir-request-article.")
1525 didnt))) 1642 didnt)))
1526 1643
1527(defun nnmaildir-request-set-mark (gname actions &optional server) 1644(defun nnmaildir-request-set-mark (gname actions &optional server)
1528 (let ((group (nnmaildir--prepare server gname)) 1645 (let* ((group (nnmaildir--prepare server gname))
1529 (coding-system-for-write nnheader-file-coding-system) 1646 (curdir (nnmaildir--cur
1530 (buffer-file-coding-system nil) 1647 (nnmaildir--srvgrp-dir
1531 (file-coding-system-alist nil) 1648 (nnmaildir--srv-dir nnmaildir--cur-server)
1532 del-mark del-action add-action set-action marksdir nlist 1649 gname)))
1533 ranges begin end article all-marks todo-marks mdir mfile 1650 (coding-system-for-write nnheader-file-coding-system)
1534 pgname ls permarkfile deactivate-mark) 1651 (buffer-file-coding-system nil)
1652 (file-coding-system-alist nil)
1653 del-mark del-action add-action set-action marksdir nlist
1654 ranges begin end article all-marks todo-marks mdir mfile
1655 pgname ls permarkfile deactivate-mark)
1535 (setq del-mark 1656 (setq del-mark
1536 (lambda (mark) 1657 (lambda (mark)
1537 (setq mfile (nnmaildir--subdir marksdir (symbol-name mark)) 1658 (let ((prefix (nnmaildir--art-prefix article))
1538 mfile (concat mfile (nnmaildir--art-prefix article))) 1659 (suffix (nnmaildir--art-suffix article))
1539 (nnmaildir--unlink mfile)) 1660 (flag (nnmaildir--mark-to-flag mark)))
1661 (when flag
1662 ;; If this mark corresponds to a flag, remove the flag from
1663 ;; the file name.
1664 (nnmaildir--article-set-flags
1665 article (nnmaildir--remove-flag flag suffix) curdir))
1666 ;; We still want to delete the hardlink in the marks dir if
1667 ;; present, regardless of whether this mark has a maildir flag or
1668 ;; not, to avoid getting out of sync.
1669 (setq mfile (nnmaildir--subdir marksdir (symbol-name mark))
1670 mfile (concat mfile prefix))
1671 (nnmaildir--unlink mfile)))
1540 del-action (lambda (article) (mapcar del-mark todo-marks)) 1672 del-action (lambda (article) (mapcar del-mark todo-marks))
1541 add-action 1673 add-action
1542 (lambda (article) 1674 (lambda (article)
1543 (mapcar 1675 (mapcar
1544 (lambda (mark) 1676 (lambda (mark)
1545 (setq mdir (nnmaildir--subdir marksdir (symbol-name mark)) 1677 (let ((prefix (nnmaildir--art-prefix article))
1546 permarkfile (concat mdir ":") 1678 (suffix (nnmaildir--art-suffix article))
1547 mfile (concat mdir (nnmaildir--art-prefix article))) 1679 (flag (nnmaildir--mark-to-flag mark)))
1548 (nnmaildir--condcase err (add-name-to-file permarkfile mfile) 1680 (if flag
1549 (cond 1681 ;; If there is a corresponding maildir flag, just rename
1550 ((nnmaildir--eexist-p err)) 1682 ;; the file.
1551 ((nnmaildir--enoent-p err) 1683 (nnmaildir--article-set-flags
1552 (nnmaildir--mkdir mdir) 1684 article (nnmaildir--add-flag flag suffix) curdir)
1553 (nnmaildir--mkfile permarkfile) 1685 ;; Otherwise, use nnmaildir-specific marks dir.
1554 (add-name-to-file permarkfile mfile)) 1686 (setq mdir (nnmaildir--subdir marksdir (symbol-name mark))
1555 ((nnmaildir--emlink-p err) 1687 permarkfile (concat mdir ":")
1556 (let ((permarkfilenew (concat permarkfile "{new}"))) 1688 mfile (concat mdir prefix))
1557 (nnmaildir--mkfile permarkfilenew) 1689 (nnmaildir--condcase err (add-name-to-file permarkfile mfile)
1558 (rename-file permarkfilenew permarkfile 'replace) 1690 (cond
1559 (add-name-to-file permarkfile mfile))) 1691 ((nnmaildir--eexist-p err))
1560 (t (signal (car err) (cdr err)))))) 1692 ((nnmaildir--enoent-p err)
1693 (nnmaildir--mkdir mdir)
1694 (nnmaildir--mkfile permarkfile)
1695 (add-name-to-file permarkfile mfile))
1696 ((nnmaildir--emlink-p err)
1697 (let ((permarkfilenew (concat permarkfile "{new}")))
1698 (nnmaildir--mkfile permarkfilenew)
1699 (rename-file permarkfilenew permarkfile 'replace)
1700 (add-name-to-file permarkfile mfile)))
1701 (t (signal (car err) (cdr err))))))))
1561 todo-marks)) 1702 todo-marks))
1562 set-action (lambda (article) 1703 set-action (lambda (article)
1563 (funcall add-action article) 1704 (funcall add-action article)
@@ -1581,7 +1722,12 @@ by nnmaildir-request-article.")
1581 pgname (nnmaildir--pgname nnmaildir--cur-server gname) 1722 pgname (nnmaildir--pgname nnmaildir--cur-server gname)
1582 ls (nnmaildir--group-ls nnmaildir--cur-server pgname) 1723 ls (nnmaildir--group-ls nnmaildir--cur-server pgname)
1583 all-marks (funcall ls marksdir nil "\\`[^.]" 'nosort) 1724 all-marks (funcall ls marksdir nil "\\`[^.]" 'nosort)
1584 all-marks (mapcar 'intern all-marks)) 1725 all-marks (gnus-delete-duplicates
1726 ;; get mark names from mark dirs and from flag
1727 ;; mappings
1728 (append
1729 (mapcar 'cdr nnmaildir-flag-mark-mapping)
1730 (mapcar 'intern all-marks))))
1585 (dolist (action actions) 1731 (dolist (action actions)
1586 (setq ranges (car action) 1732 (setq ranges (car action)
1587 todo-marks (caddr action)) 1733 todo-marks (caddr action))
diff --git a/lisp/gnus/qp.el b/lisp/gnus/qp.el
index 87252684a48..c4487c68b5c 100644
--- a/lisp/gnus/qp.el
+++ b/lisp/gnus/qp.el
@@ -53,10 +53,7 @@ them into characters should be done separately."
53 ;; or both of which are lowercase letters in "abcdef", is 53 ;; or both of which are lowercase letters in "abcdef", is
54 ;; formally illegal. A robust implementation might choose to 54 ;; formally illegal. A robust implementation might choose to
55 ;; recognize them as the corresponding uppercase letters.'' 55 ;; recognize them as the corresponding uppercase letters.''
56 (let ((case-fold-search t) 56 (let ((case-fold-search t))
57 (decode-hex #'(lambda (n1 n2)
58 (+ (* (if (<= n1 ?9) (- n1 ?0) (+ (- n1 ?A) 10)) 16)
59 (if (<= n2 ?9) (- n2 ?0) (+ (- n2 ?A) 10))))))
60 (narrow-to-region from to) 57 (narrow-to-region from to)
61 ;; Do this in case we're called from Gnus, say, in a buffer 58 ;; Do this in case we're called from Gnus, say, in a buffer
62 ;; which already contains non-ASCII characters which would 59 ;; which already contains non-ASCII characters which would
@@ -74,8 +71,15 @@ them into characters should be done separately."
74 (let* ((n (/ (- (match-end 0) (point)) 3)) 71 (let* ((n (/ (- (match-end 0) (point)) 3))
75 (str (make-string n 0))) 72 (str (make-string n 0)))
76 (dotimes (i n) 73 (dotimes (i n)
77 (aset str i (funcall decode-hex (char-after (1+ (point))) 74 (let ((n1 (char-after (1+ (point))))
78 (char-after (+ 2 (point))))) 75 (n2 (char-after (+ 2 (point)))))
76 (aset str i
77 (+ (* 16 (- n1 (if (<= n1 ?9) ?0
78 (if (<= n1 ?F) (- ?A 10)
79 (- ?a 10)))))
80 (- n2 (if (<= n2 ?9) ?0
81 (if (<= n2 ?F) (- ?A 10)
82 (- ?a 10)))))))
79 (forward-char 3)) 83 (forward-char 3))
80 (delete-region (match-beginning 0) (match-end 0)) 84 (delete-region (match-beginning 0) (match-end 0))
81 (insert str))) 85 (insert str)))
diff --git a/lisp/help.el b/lisp/help.el
index 9740f8996c1..da11389d87c 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -585,6 +585,8 @@ temporarily enables it to allow getting help on disabled items and buttons."
585 (setq saved-yank-menu (copy-sequence yank-menu)) 585 (setq saved-yank-menu (copy-sequence yank-menu))
586 (menu-bar-update-yank-menu "(any string)" nil)) 586 (menu-bar-update-yank-menu "(any string)" nil))
587 (setq key (read-key-sequence "Describe key (or click or menu item): ")) 587 (setq key (read-key-sequence "Describe key (or click or menu item): "))
588 ;; Clear the echo area message (Bug#7014).
589 (message nil)
588 ;; If KEY is a down-event, read and discard the 590 ;; If KEY is a down-event, read and discard the
589 ;; corresponding up-event. Note that there are also 591 ;; corresponding up-event. Note that there are also
590 ;; down-events on scroll bars and mode lines: the actual 592 ;; down-events on scroll bars and mode lines: the actual
@@ -962,7 +964,11 @@ is currently activated with completion."
962 result)) 964 result))
963 965
964;;; Automatic resizing of temporary buffers. 966;;; Automatic resizing of temporary buffers.
965(defcustom temp-buffer-max-height (lambda (buffer) (/ (- (frame-height) 2) 2)) 967(defcustom temp-buffer-max-height
968 (lambda (buffer)
969 (if (eq (selected-window) (frame-root-window))
970 (/ (x-display-pixel-height) (frame-char-height) 2)
971 (/ (- (frame-height) 2) 2)))
966 "Maximum height of a window displaying a temporary buffer. 972 "Maximum height of a window displaying a temporary buffer.
967This is effective only when Temp Buffer Resize mode is enabled. 973This is effective only when Temp Buffer Resize mode is enabled.
968The value is the maximum height (in lines) which 974The value is the maximum height (in lines) which
@@ -973,7 +979,16 @@ buffer, and should return a positive integer. At the time the
973function is called, the window to be resized is selected." 979function is called, the window to be resized is selected."
974 :type '(choice integer function) 980 :type '(choice integer function)
975 :group 'help 981 :group 'help
976 :version "20.4") 982 :version "24.2")
983
984(defcustom temp-buffer-resize-frames nil
985 "Non-nil means `temp-buffer-resize-mode' can resize frames.
986A frame can be resized if and only if its root window is a live
987window. The height of the root window is subject to the values of
988`temp-buffer-max-height' and `window-min-height'."
989 :type 'boolean
990 :version "24.2"
991 :group 'help)
977 992
978(define-minor-mode temp-buffer-resize-mode 993(define-minor-mode temp-buffer-resize-mode
979 "Toggle auto-resizing temporary buffer windows (Temp Buffer Resize Mode). 994 "Toggle auto-resizing temporary buffer windows (Temp Buffer Resize Mode).
@@ -1008,9 +1023,21 @@ view."
1008 (with-selected-window window 1023 (with-selected-window window
1009 (funcall temp-buffer-max-height (window-buffer))) 1024 (funcall temp-buffer-max-height (window-buffer)))
1010 temp-buffer-max-height))) 1025 temp-buffer-max-height)))
1011 (when (and (pos-visible-in-window-p (point-min) window) 1026 (cond
1012 (window-combined-p window)) 1027 ((and (pos-visible-in-window-p (point-min) window)
1013 (fit-window-to-buffer window height)))) 1028 (window-combined-p window))
1029 (fit-window-to-buffer window height))
1030 ((and temp-buffer-resize-frames
1031 (eq window (frame-root-window window))
1032 (memq (car (window-parameter window 'quit-restore))
1033 ;; If 'same is too strong, we might additionally check
1034 ;; whether the second element is 'frame.
1035 '(same frame)))
1036 (let ((frame (window-frame window)))
1037 (fit-frame-to-buffer
1038 frame (+ (frame-height frame)
1039 (- (window-total-size window))
1040 height)))))))
1014 1041
1015;;; Help windows. 1042;;; Help windows.
1016(defcustom help-window-select 'other 1043(defcustom help-window-select 'other
diff --git a/lisp/isearch.el b/lisp/isearch.el
index e6e0a01566a..04f5a7acc2c 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1405,6 +1405,7 @@ Use `isearch-exit' to quit without signaling."
1405 (interactive) 1405 (interactive)
1406 (setq isearch-word (unless (eq isearch-word 'isearch-symbol-regexp) 1406 (setq isearch-word (unless (eq isearch-word 'isearch-symbol-regexp)
1407 'isearch-symbol-regexp)) 1407 'isearch-symbol-regexp))
1408 (if isearch-word (setq isearch-regexp nil))
1408 (setq isearch-success t isearch-adjusted t) 1409 (setq isearch-success t isearch-adjusted t)
1409 (isearch-update)) 1410 (isearch-update))
1410 1411
@@ -1579,14 +1580,10 @@ way to run word replacements from Isearch is `M-s w ... M-%'."
1579 ;; set `search-upper-case' to nil to not call 1580 ;; set `search-upper-case' to nil to not call
1580 ;; `isearch-no-upper-case-p' in `perform-replace' 1581 ;; `isearch-no-upper-case-p' in `perform-replace'
1581 (search-upper-case nil) 1582 (search-upper-case nil)
1582 (replace-search-function 1583 (replace-lax-whitespace
1583 (if (and isearch-lax-whitespace (not regexp-flag)) 1584 isearch-lax-whitespace)
1584 #'search-forward-lax-whitespace 1585 (replace-regexp-lax-whitespace
1585 replace-search-function)) 1586 isearch-regexp-lax-whitespace)
1586 (replace-re-search-function
1587 (if (and isearch-regexp-lax-whitespace regexp-flag)
1588 #'re-search-forward-lax-whitespace
1589 replace-re-search-function))
1590 ;; Set `isearch-recursive-edit' to nil to prevent calling 1587 ;; Set `isearch-recursive-edit' to nil to prevent calling
1591 ;; `exit-recursive-edit' in `isearch-done' that terminates 1588 ;; `exit-recursive-edit' in `isearch-done' that terminates
1592 ;; the execution of this command when it is non-nil. 1589 ;; the execution of this command when it is non-nil.
@@ -2956,10 +2953,14 @@ Attempt to do the search exactly the way the pending Isearch would."
2956 (let ((case-fold-search isearch-lazy-highlight-case-fold-search) 2953 (let ((case-fold-search isearch-lazy-highlight-case-fold-search)
2957 (isearch-regexp isearch-lazy-highlight-regexp) 2954 (isearch-regexp isearch-lazy-highlight-regexp)
2958 (isearch-word isearch-lazy-highlight-word) 2955 (isearch-word isearch-lazy-highlight-word)
2956 (isearch-lax-whitespace
2957 isearch-lazy-highlight-lax-whitespace)
2958 (isearch-regexp-lax-whitespace
2959 isearch-lazy-highlight-regexp-lax-whitespace)
2960 (isearch-forward isearch-lazy-highlight-forward)
2959 (search-invisible nil) ; don't match invisible text 2961 (search-invisible nil) ; don't match invisible text
2960 (retry t) 2962 (retry t)
2961 (success nil) 2963 (success nil)
2962 (isearch-forward isearch-lazy-highlight-forward)
2963 (bound (if isearch-lazy-highlight-forward 2964 (bound (if isearch-lazy-highlight-forward
2964 (min (or isearch-lazy-highlight-end-limit (point-max)) 2965 (min (or isearch-lazy-highlight-end-limit (point-max))
2965 (if isearch-lazy-highlight-wrapped 2966 (if isearch-lazy-highlight-wrapped
diff --git a/lisp/loadup.el b/lisp/loadup.el
index a460fcab339..d389427bafd 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -102,6 +102,19 @@
102(setq load-source-file-function 'load-with-code-conversion) 102(setq load-source-file-function 'load-with-code-conversion)
103(load "files") 103(load "files")
104 104
105;; Load-time macro-expansion can only take effect after setting
106;; load-source-file-function because of where it is called in lread.c.
107(load "emacs-lisp/macroexp")
108(if (byte-code-function-p (symbol-function 'macroexpand-all))
109 nil
110 ;; Since loaddefs is not yet loaded, macroexp's uses of pcase will simply
111 ;; fail until pcase is explicitly loaded. This also means that we have to
112 ;; disable eager macro-expansion while loading pcase.
113 (let ((macroexp--pending-eager-loads '(skip)))
114 (load "emacs-lisp/pcase"))
115 ;; Re-load macroexp so as to eagerly macro-expand its uses of pcase.
116 (load "emacs-lisp/macroexp"))
117
105(load "cus-face") 118(load "cus-face")
106(load "faces") ; after here, `defface' may be used. 119(load "faces") ; after here, `defface' may be used.
107 120
@@ -266,21 +279,6 @@
266;For other systems, you must edit ../src/Makefile.in. 279;For other systems, you must edit ../src/Makefile.in.
267(load "site-load" t) 280(load "site-load" t)
268 281
269;; ¡¡¡ Big Ugly Hack !!!
270;; src/bootstrap-emacs is mostly used to compile .el files, so it needs
271;; macroexp, bytecomp, cconv, and byte-opt to be fast. Generally this is done
272;; by compiling those files first, but this only makes a difference if those
273;; files are not preloaded. As it so happens, macroexp.el tends to be
274;; accidentally preloaded in src/bootstrap-emacs because cl.el and cl-macs.el
275;; require it. So let's unload it here, if needed, to make sure the
276;; byte-compiled version is used.
277(if (or (not (fboundp 'macroexpand-all))
278 (byte-code-function-p (symbol-function 'macroexpand-all)))
279 nil
280 (fmakunbound 'macroexpand-all)
281 (setq features (delq 'macroexp features))
282 (autoload 'macroexpand-all "macroexp"))
283
284;; Determine which last version number to use 282;; Determine which last version number to use
285;; based on the executables that now exist. 283;; based on the executables that now exist.
286(if (and (or (equal (nth 3 command-line-args) "dump") 284(if (and (or (equal (nth 3 command-line-args) "dump")
diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el
index 804fe7a8798..69a405436a7 100644
--- a/lisp/mail/smtpmail.el
+++ b/lisp/mail/smtpmail.el
@@ -200,10 +200,10 @@ The list is in preference order.")
200 ;; local binding in the mail buffer will take effect. 200 ;; local binding in the mail buffer will take effect.
201 (smtpmail-mail-address 201 (smtpmail-mail-address
202 (or (and mail-specify-envelope-from (mail-envelope-from)) 202 (or (and mail-specify-envelope-from (mail-envelope-from))
203 (smtpmail-user-mail-address) 203 (let ((from (mail-fetch-field "from")))
204 (let ((from (mail-fetch-field "from")))
205 (and from 204 (and from
206 (cadr (mail-extract-address-components from)))))) 205 (cadr (mail-extract-address-components from))))
206 (smtpmail-user-mail-address)))
207 (smtpmail-code-conv-from 207 (smtpmail-code-conv-from
208 (if enable-multibyte-characters 208 (if enable-multibyte-characters
209 (let ((sendmail-coding-system smtpmail-code-conv-from)) 209 (let ((sendmail-coding-system smtpmail-code-conv-from))
@@ -653,12 +653,10 @@ Returns an error if the server cannot be contacted."
653 (or smtpmail-mail-address 653 (or smtpmail-mail-address
654 (and mail-specify-envelope-from 654 (and mail-specify-envelope-from
655 (mail-envelope-from)) 655 (mail-envelope-from))
656 (smtpmail-user-mail-address)
657 ;; Fall back on the From: header as the envelope From
658 ;; address.
659 (let ((from (mail-fetch-field "from"))) 656 (let ((from (mail-fetch-field "from")))
660 (and from 657 (and from
661 (cadr (mail-extract-address-components from)))))) 658 (cadr (mail-extract-address-components from))))
659 (smtpmail-user-mail-address)))
662 response-code 660 response-code
663 process-buffer 661 process-buffer
664 result 662 result
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index f7aa5f8ed52..8daf339d376 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -744,7 +744,7 @@ narrowed."
744 (and buffer (set-buffer buffer)) 744 (and buffer (set-buffer buffer))
745 (let ((file-name 745 (let ((file-name
746 ;; Ignore real name if restricted 746 ;; Ignore real name if restricted
747 (and (= (- (point-max) (point-min)) (buffer-size)) 747 (and (not (buffer-narrowed-p))
748 (or buffer-file-name 748 (or buffer-file-name
749 (and (boundp 'dired-directory) dired-directory))))) 749 (and (boundp 'dired-directory) dired-directory)))))
750 (or file-name 750 (or file-name
diff --git a/lisp/play/blackbox.el b/lisp/play/blackbox.el
index db2e18188e5..16189600156 100644
--- a/lisp/play/blackbox.el
+++ b/lisp/play/blackbox.el
@@ -97,7 +97,9 @@
97 (let ((map (make-keymap))) 97 (let ((map (make-keymap)))
98 (suppress-keymap map t) 98 (suppress-keymap map t)
99 (blackbox-redefine-key map 'backward-char 'bb-left) 99 (blackbox-redefine-key map 'backward-char 'bb-left)
100 (blackbox-redefine-key map 'left-char 'bb-left)
100 (blackbox-redefine-key map 'forward-char 'bb-right) 101 (blackbox-redefine-key map 'forward-char 'bb-right)
102 (blackbox-redefine-key map 'right-char 'bb-right)
101 (blackbox-redefine-key map 'previous-line 'bb-up) 103 (blackbox-redefine-key map 'previous-line 'bb-up)
102 (blackbox-redefine-key map 'next-line 'bb-down) 104 (blackbox-redefine-key map 'next-line 'bb-down)
103 (blackbox-redefine-key map 'move-end-of-line 'bb-eol) 105 (blackbox-redefine-key map 'move-end-of-line 'bb-eol)
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 7cd0a0b0ae2..eec6873dc19 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -493,13 +493,16 @@ inside a literal or a macro, nothing special happens."
493 (insert-char ?\n 1) 493 (insert-char ?\n 1)
494 ;; In AWK (etc.) or in a macro, make sure this CR hasn't changed 494 ;; In AWK (etc.) or in a macro, make sure this CR hasn't changed
495 ;; the syntax. (There might already be an escaped NL there.) 495 ;; the syntax. (There might already be an escaped NL there.)
496 (when (or (c-at-vsemi-p (1- (point))) 496 (when (or
497 (let ((pt (point))) 497 (save-excursion
498 (save-excursion 498 (c-skip-ws-backward (c-point 'bopl))
499 (backward-char) 499 (c-at-vsemi-p))
500 (and (c-beginning-of-macro) 500 (let ((pt (point)))
501 (progn (c-end-of-macro) 501 (save-excursion
502 (< (point) pt)))))) 502 (backward-char)
503 (and (c-beginning-of-macro)
504 (progn (c-end-of-macro)
505 (< (point) pt))))))
503 (backward-char) 506 (backward-char)
504 (insert-char ?\\ 1) 507 (insert-char ?\\ 1)
505 (forward-char)) 508 (forward-char))
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 142ec4cdd66..2aa04cb2b0b 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -3091,6 +3091,8 @@ comment at the start of cc-engine.el for more info."
3091 c-state-cache-good-pos 1 3091 c-state-cache-good-pos 1
3092 c-state-nonlit-pos-cache nil 3092 c-state-nonlit-pos-cache nil
3093 c-state-nonlit-pos-cache-limit 1 3093 c-state-nonlit-pos-cache-limit 1
3094 c-state-semi-nonlit-pos-cache nil
3095 c-state-semi-nonlit-pos-cache-limit 1
3094 c-state-brace-pair-desert nil 3096 c-state-brace-pair-desert nil
3095 c-state-point-min 1 3097 c-state-point-min 1
3096 c-state-point-min-lit-type nil 3098 c-state-point-min-lit-type nil
@@ -3350,6 +3352,8 @@ comment at the start of cc-engine.el for more info."
3350 c-state-cache-good-pos 3352 c-state-cache-good-pos
3351 c-state-nonlit-pos-cache 3353 c-state-nonlit-pos-cache
3352 c-state-nonlit-pos-cache-limit 3354 c-state-nonlit-pos-cache-limit
3355 c-state-semi-nonlit-pos-cache
3356 c-state-semi-nonlit-pos-cache-limit
3353 c-state-brace-pair-desert 3357 c-state-brace-pair-desert
3354 c-state-point-min 3358 c-state-point-min
3355 c-state-point-min-lit-type 3359 c-state-point-min-lit-type
@@ -9579,12 +9583,12 @@ comment at the start of cc-engine.el for more info."
9579 (setq tmpsymbol nil) 9583 (setq tmpsymbol nil)
9580 (while (and (> (point) placeholder) 9584 (while (and (> (point) placeholder)
9581 (zerop (c-backward-token-2 1 t)) 9585 (zerop (c-backward-token-2 1 t))
9582 (/= (char-after) ?=)) 9586 (not (looking-at "=\\([^=]\\|$\\)")))
9583 (and c-opt-inexpr-brace-list-key 9587 (and c-opt-inexpr-brace-list-key
9584 (not tmpsymbol) 9588 (not tmpsymbol)
9585 (looking-at c-opt-inexpr-brace-list-key) 9589 (looking-at c-opt-inexpr-brace-list-key)
9586 (setq tmpsymbol 'topmost-intro-cont))) 9590 (setq tmpsymbol 'topmost-intro-cont)))
9587 (eq (char-after) ?=)) 9591 (looking-at "=\\([^=]\\|$\\)"))
9588 (looking-at c-brace-list-key)) 9592 (looking-at c-brace-list-key))
9589 (save-excursion 9593 (save-excursion
9590 (while (and (< (point) indent-point) 9594 (while (and (< (point) indent-point)
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index ad285274928..10d5fdf9c64 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -977,6 +977,9 @@ from compile.el")
977;; :type '(repeat (string number number number)) 977;; :type '(repeat (string number number number))
978;;) 978;;)
979 979
980(defvar flymake-warning-re "^[wW]arning"
981 "Regexp matching against err-text to detect a warning.")
982
980(defun flymake-parse-line (line) 983(defun flymake-parse-line (line)
981 "Parse LINE to see if it is an error or warning. 984 "Parse LINE to see if it is an error or warning.
982Return its components if so, nil otherwise." 985Return its components if so, nil otherwise."
@@ -997,7 +1000,7 @@ Return its components if so, nil otherwise."
997 (match-string (nth 4 (car patterns)) line) 1000 (match-string (nth 4 (car patterns)) line)
998 (flymake-patch-err-text (substring line (match-end 0))))) 1001 (flymake-patch-err-text (substring line (match-end 0)))))
999 (or err-text (setq err-text "<no error text>")) 1002 (or err-text (setq err-text "<no error text>"))
1000 (if (and err-text (string-match "^[wW]arning" err-text)) 1003 (if (and err-text (string-match flymake-warning-re err-text))
1001 (setq err-type "w") 1004 (setq err-type "w")
1002 ) 1005 )
1003 (flymake-log 3 "parse line: file-idx=%s line-idx=%s file=%s line=%s text=%s" file-idx line-idx 1006 (flymake-log 3 "parse line: file-idx=%s line-idx=%s file=%s line=%s text=%s" file-idx line-idx
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 601850ed0fb..ffc6c1ac885 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1824,7 +1824,11 @@ When MSG is non-nil messages the first line of STRING."
1824 (lines (split-string string "\n" t))) 1824 (lines (split-string string "\n" t)))
1825 (and msg (message "Sent: %s..." (nth 0 lines))) 1825 (and msg (message "Sent: %s..." (nth 0 lines)))
1826 (if (> (length lines) 1) 1826 (if (> (length lines) 1)
1827 (let* ((temp-file-name (make-temp-file "py")) 1827 (let* ((temporary-file-directory
1828 (if (file-remote-p default-directory)
1829 (concat (file-remote-p default-directory) "/tmp")
1830 temporary-file-directory))
1831 (temp-file-name (make-temp-file "py"))
1828 (file-name (or (buffer-file-name) temp-file-name))) 1832 (file-name (or (buffer-file-name) temp-file-name)))
1829 (with-temp-file temp-file-name 1833 (with-temp-file temp-file-name
1830 (insert string) 1834 (insert string)
@@ -1931,8 +1935,14 @@ FILE-NAME."
1931 (interactive "fFile to send: ") 1935 (interactive "fFile to send: ")
1932 (let* ((process (or process (python-shell-get-or-create-process))) 1936 (let* ((process (or process (python-shell-get-or-create-process)))
1933 (temp-file-name (when temp-file-name 1937 (temp-file-name (when temp-file-name
1934 (expand-file-name temp-file-name))) 1938 (expand-file-name
1935 (file-name (or (expand-file-name file-name) temp-file-name))) 1939 (or (file-remote-p temp-file-name 'localname)
1940 temp-file-name))))
1941 (file-name (or (when file-name
1942 (expand-file-name
1943 (or (file-remote-p file-name 'localname)
1944 file-name)))
1945 temp-file-name)))
1936 (when (not file-name) 1946 (when (not file-name)
1937 (error "If FILE-NAME is nil then TEMP-FILE-NAME must be non-nil")) 1947 (error "If FILE-NAME is nil then TEMP-FILE-NAME must be non-nil"))
1938 (python-shell-send-string 1948 (python-shell-send-string
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 457c7fee36c..77ec8084ea2 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -64,8 +64,8 @@
64 "Regexp to match keywords that nest without blocks.") 64 "Regexp to match keywords that nest without blocks.")
65 65
66(defconst ruby-indent-beg-re 66(defconst ruby-indent-beg-re
67 (concat "\\(\\s *" (regexp-opt '("class" "module" "def") t) "\\)\\|" 67 (concat "^\\s *" (regexp-opt '("class" "module" "def" "if" "unless" "case"
68 (regexp-opt '("if" "unless" "case" "while" "until" "for" "begin"))) 68 "while" "until" "for" "begin")) "\\_>")
69 "Regexp to match where the indentation gets deeper.") 69 "Regexp to match where the indentation gets deeper.")
70 70
71(defconst ruby-modifier-beg-keywords 71(defconst ruby-modifier-beg-keywords
@@ -98,6 +98,10 @@
98 98
99(defconst ruby-block-end-re "\\_<end\\_>") 99(defconst ruby-block-end-re "\\_<end\\_>")
100 100
101(defconst ruby-defun-beg-re
102 '"\\(def\\|class\\|module\\)"
103 "Regexp to match the beginning of a defun, in the general sense.")
104
101(eval-and-compile 105(eval-and-compile
102 (defconst ruby-here-doc-beg-re 106 (defconst ruby-here-doc-beg-re
103 "\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)" 107 "\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)"
@@ -138,18 +142,11 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
138 142
139(defvar ruby-mode-map 143(defvar ruby-mode-map
140 (let ((map (make-sparse-keymap))) 144 (let ((map (make-sparse-keymap)))
141 (define-key map "{" 'ruby-electric-brace)
142 (define-key map "}" 'ruby-electric-brace)
143 (define-key map (kbd "M-C-a") 'ruby-beginning-of-defun)
144 (define-key map (kbd "M-C-e") 'ruby-end-of-defun)
145 (define-key map (kbd "M-C-b") 'ruby-backward-sexp) 145 (define-key map (kbd "M-C-b") 'ruby-backward-sexp)
146 (define-key map (kbd "M-C-f") 'ruby-forward-sexp) 146 (define-key map (kbd "M-C-f") 'ruby-forward-sexp)
147 (define-key map (kbd "M-C-p") 'ruby-beginning-of-block) 147 (define-key map (kbd "M-C-p") 'ruby-beginning-of-block)
148 (define-key map (kbd "M-C-n") 'ruby-end-of-block) 148 (define-key map (kbd "M-C-n") 'ruby-end-of-block)
149 (define-key map (kbd "M-C-h") 'ruby-mark-defun)
150 (define-key map (kbd "M-C-q") 'ruby-indent-exp) 149 (define-key map (kbd "M-C-q") 'ruby-indent-exp)
151 (define-key map (kbd "C-M-h") 'backward-kill-word)
152 (define-key map (kbd "C-j") 'reindent-then-newline-and-indent)
153 (define-key map (kbd "C-c {") 'ruby-toggle-block) 150 (define-key map (kbd "C-c {") 'ruby-toggle-block)
154 map) 151 map)
155 "Keymap used in Ruby mode.") 152 "Keymap used in Ruby mode.")
@@ -840,20 +837,13 @@ and `\\' when preceded by `?'."
840 (+ indent ruby-indent-level) 837 (+ indent ruby-indent-level)
841 indent)))) 838 indent))))
842 839
843(defun ruby-electric-brace (arg)
844 "Insert a brace and re-indent the current line."
845 (interactive "P")
846 (self-insert-command (prefix-numeric-value arg))
847 (ruby-indent-line t))
848
849;; TODO: Why isn't one ruby-*-of-defun written in terms of the other?
850(defun ruby-beginning-of-defun (&optional arg) 840(defun ruby-beginning-of-defun (&optional arg)
851 "Move backward to the beginning of the current top-level defun. 841 "Move backward to the beginning of the current top-level defun.
852With ARG, move backward multiple defuns. Negative ARG means 842With ARG, move backward multiple defuns. Negative ARG means
853move forward." 843move forward."
854 (interactive "p") 844 (interactive "p")
855 (and (re-search-backward (concat "^\\(" ruby-block-beg-re "\\)\\b") 845 (and (re-search-backward (concat "^\\s *" ruby-defun-beg-re "\\_>")
856 nil 'move (or arg 1)) 846 nil t (or arg 1))
857 (beginning-of-line))) 847 (beginning-of-line)))
858 848
859(defun ruby-end-of-defun (&optional arg) 849(defun ruby-end-of-defun (&optional arg)
@@ -861,19 +851,18 @@ move forward."
861With ARG, move forward multiple defuns. Negative ARG means 851With ARG, move forward multiple defuns. Negative ARG means
862move backward." 852move backward."
863 (interactive "p") 853 (interactive "p")
864 (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)\\($\\|\\b[^_]\\)") 854 (ruby-forward-sexp)
865 nil 'move (or arg 1)) 855 (when (looking-back (concat "^\\s *" ruby-block-end-re))
866 (beginning-of-line)) 856 (forward-line 1)))
867 (forward-line 1))
868 857
869(defun ruby-beginning-of-indent () 858(defun ruby-beginning-of-indent ()
870 "TODO: document" 859 "Backtrack to a line which can be used as a reference for
871 ;; I don't understand this function. 860calculating indentation on the lines after it."
872 ;; It seems like it should move to the line where indentation should deepen, 861 (while (and (re-search-backward ruby-indent-beg-re nil 'move)
873 ;; but ruby-indent-beg-re only accounts for whitespace before class, module and def, 862 (if (ruby-in-ppss-context-p 'anything)
874 ;; so this will only match other block beginners at the beginning of the line. 863 t
875 (and (re-search-backward (concat "^\\(" ruby-indent-beg-re "\\)\\_>") nil 'move) 864 ;; We can stop, then.
876 (beginning-of-line))) 865 (beginning-of-line)))))
877 866
878(defun ruby-move-to-block (n) 867(defun ruby-move-to-block (n)
879 "Move to the beginning (N < 0) or the end (N > 0) of the current block 868 "Move to the beginning (N < 0) or the end (N > 0) of the current block
@@ -1024,15 +1013,6 @@ With ARG, do it many times. Negative ARG means move forward."
1024 ((error))) 1013 ((error)))
1025 i))) 1014 i)))
1026 1015
1027(defun ruby-mark-defun ()
1028 "Put mark at end of this Ruby function, point at beginning."
1029 (interactive)
1030 (push-mark (point))
1031 (ruby-end-of-defun)
1032 (push-mark (point) nil t)
1033 (ruby-beginning-of-defun)
1034 (re-search-backward "^\n" (- (point) 1) t))
1035
1036(defun ruby-indent-exp (&optional ignored) 1016(defun ruby-indent-exp (&optional ignored)
1037 "Indent each line in the balanced expression following the point." 1017 "Indent each line in the balanced expression following the point."
1038 (interactive "*P") 1018 (interactive "*P")
@@ -1073,7 +1053,7 @@ See `add-log-current-defun-function'."
1073 (let (mname mlist (indent 0)) 1053 (let (mname mlist (indent 0))
1074 ;; get current method (or class/module) 1054 ;; get current method (or class/module)
1075 (if (re-search-backward 1055 (if (re-search-backward
1076 (concat "^[ \t]*\\(def\\|class\\|module\\)[ \t]+" 1056 (concat "^[ \t]*" ruby-defun-beg-re "[ \t]+"
1077 "\\(" 1057 "\\("
1078 ;; \\. and :: for class method 1058 ;; \\. and :: for class method
1079 "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)" 1059 "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
@@ -1127,46 +1107,65 @@ See `add-log-current-defun-function'."
1127 (if mlist (concat mlist mname) mname) 1107 (if mlist (concat mlist mname) mname)
1128 mlist))))) 1108 mlist)))))
1129 1109
1130(defun ruby-brace-to-do-end () 1110(defun ruby-brace-to-do-end (orig end)
1131 (when (looking-at "{") 1111 (let (beg-marker end-marker)
1132 (let ((orig (point)) (end (progn (ruby-forward-sexp) (point)))) 1112 (goto-char end)
1133 (when (eq (char-before) ?\}) 1113 (when (eq (char-before) ?\})
1134 (delete-char -1) 1114 (delete-char -1)
1135 (if (eq (char-syntax (char-before)) ?w) 1115 (skip-chars-backward " \t")
1136 (insert " ")) 1116 (when (not (bolp))
1137 (insert "end") 1117 (insert "\n"))
1138 (if (eq (char-syntax (char-after)) ?w) 1118 (insert "end")
1139 (insert " ")) 1119 (setq end-marker (point-marker))
1140 (goto-char orig) 1120 (when (and (not (eobp)) (eq (char-syntax (char-after)) ?w))
1141 (delete-char 1) 1121 (insert " "))
1142 (if (eq (char-syntax (char-before)) ?w) 1122 (goto-char orig)
1143 (insert " ")) 1123 (delete-char 1)
1144 (insert "do") 1124 (when (eq (char-syntax (char-before)) ?w)
1145 (when (looking-at "\\sw\\||") 1125 (insert " "))
1146 (insert " ") 1126 (insert "do")
1147 (backward-char)) 1127 (setq beg-marker (point-marker))
1148 t)))) 1128 (when (looking-at "\\(\\s \\)*|")
1149 1129 (unless (match-beginning 1)
1150(defun ruby-do-end-to-brace () 1130 (insert " "))
1151 (when (and (or (bolp) 1131 (goto-char (1+ (match-end 0)))
1152 (not (memq (char-syntax (char-before)) '(?w ?_)))) 1132 (search-forward "|"))
1153 (looking-at "\\<do\\(\\s \\|$\\)")) 1133 (unless (looking-at "\\s *$")
1154 (let ((orig (point)) (end (progn (ruby-forward-sexp) (point)))) 1134 (insert "\n"))
1155 (backward-char 3) 1135 (indent-region beg-marker end-marker)
1156 (when (looking-at ruby-block-end-re) 1136 (goto-char beg-marker)
1157 (delete-char 3) 1137 t)))
1158 (insert "}") 1138
1159 (goto-char orig) 1139(defun ruby-do-end-to-brace (orig end)
1160 (delete-char 2) 1140 (goto-char (- end 3))
1161 (insert "{") 1141 (when (looking-at ruby-block-end-re)
1162 (if (looking-at "\\s +|") 1142 (delete-char 3)
1163 (delete-char (- (match-end 0) (match-beginning 0) 1))) 1143 (insert "}")
1164 t)))) 1144 (goto-char orig)
1145 (delete-char 2)
1146 (insert "{")
1147 (if (looking-at "\\s +|")
1148 (delete-char (- (match-end 0) (match-beginning 0) 1)))
1149 t))
1165 1150
1166(defun ruby-toggle-block () 1151(defun ruby-toggle-block ()
1152 "Toggle block type from do-end to braces or back.
1153The block must begin on the current line or above it and end after the point.
1154If the result is do-end block, it will always be multiline."
1167 (interactive) 1155 (interactive)
1168 (or (ruby-brace-to-do-end) 1156 (let ((start (point)) beg end)
1169 (ruby-do-end-to-brace))) 1157 (end-of-line)
1158 (unless
1159 (if (and (re-search-backward "\\({\\)\\|\\_<do\\(\\s \\|$\\||\\)")
1160 (progn
1161 (setq beg (point))
1162 (save-match-data (ruby-forward-sexp))
1163 (setq end (point))
1164 (> end start)))
1165 (if (match-beginning 1)
1166 (ruby-brace-to-do-end beg end)
1167 (ruby-do-end-to-brace beg end)))
1168 (goto-char start))))
1170 1169
1171(declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit)) 1170(declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit))
1172(declare-function ruby-syntax-enclosing-percent-literal "ruby-mode" (limit)) 1171(declare-function ruby-syntax-enclosing-percent-literal "ruby-mode" (limit))
@@ -1193,8 +1192,6 @@ It will be properly highlighted even when the call omits parens."))
1193 (ruby-syntax-enclosing-percent-literal end) 1192 (ruby-syntax-enclosing-percent-literal end)
1194 (funcall 1193 (funcall
1195 (syntax-propertize-rules 1194 (syntax-propertize-rules
1196 ;; #{ }, #$hoge, #@foo are not comments.
1197 ("\\(#\\)[{$@]" (1 "."))
1198 ;; $' $" $` .... are variables. 1195 ;; $' $" $` .... are variables.
1199 ;; ?' ?" ?` are ascii codes. 1196 ;; ?' ?" ?` are ascii codes.
1200 ("\\([?$]\\)[#\"'`]" 1197 ("\\([?$]\\)[#\"'`]"
@@ -1326,8 +1323,7 @@ This should only be called after matching against `ruby-here-doc-end-re'."
1326 (concat "-?\\([\"']\\|\\)" contents "\\1")))))) 1323 (concat "-?\\([\"']\\|\\)" contents "\\1"))))))
1327 1324
1328 (defconst ruby-font-lock-syntactic-keywords 1325 (defconst ruby-font-lock-syntactic-keywords
1329 `( ;; #{ }, #$hoge, #@foo are not comments 1326 `(
1330 ("\\(#\\)[{$@]" 1 (1 . nil))
1331 ;; the last $', $", $` in the respective string is not variable 1327 ;; the last $', $", $` in the respective string is not variable
1332 ;; the last ?', ?", ?` in the respective string is not ascii code 1328 ;; the last ?', ?", ?` in the respective string is not ascii code
1333 ("\\(^\\|[\[ \t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)" 1329 ("\\(^\\|[\[ \t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)"
@@ -1549,6 +1545,9 @@ See `font-lock-syntax-table'.")
1549 ;; variables 1545 ;; variables
1550 '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\>" 1546 '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\>"
1551 2 font-lock-variable-name-face) 1547 2 font-lock-variable-name-face)
1548 ;; symbols
1549 '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|@?\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
1550 2 font-lock-reference-face)
1552 ;; variables 1551 ;; variables
1553 '("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W" 1552 '("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W"
1554 1 font-lock-variable-name-face) 1553 1 font-lock-variable-name-face)
@@ -1557,12 +1556,9 @@ See `font-lock-syntax-table'.")
1557 ;; constants 1556 ;; constants
1558 '("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)" 1557 '("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)"
1559 2 font-lock-type-face) 1558 2 font-lock-type-face)
1560 ;; symbols
1561 '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)"
1562 2 font-lock-reference-face)
1563 '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-reference-face) 1559 '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-reference-face)
1564 ;; expression expansion 1560 ;; expression expansion
1565 '("#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)" 1561 '(ruby-match-expression-expansion
1566 0 font-lock-variable-name-face t) 1562 0 font-lock-variable-name-face t)
1567 ;; warn lower camel case 1563 ;; warn lower camel case
1568 ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)" 1564 ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)"
@@ -1570,6 +1566,11 @@ See `font-lock-syntax-table'.")
1570 ) 1566 )
1571 "Additional expressions to highlight in Ruby mode.") 1567 "Additional expressions to highlight in Ruby mode.")
1572 1568
1569(defun ruby-match-expression-expansion (limit)
1570 (when (re-search-forward "[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)" limit 'move)
1571 (or (ruby-in-ppss-context-p 'string)
1572 (ruby-match-expression-expansion limit))))
1573
1573;;;###autoload 1574;;;###autoload
1574(define-derived-mode ruby-mode prog-mode "Ruby" 1575(define-derived-mode ruby-mode prog-mode "Ruby"
1575 "Major mode for editing Ruby scripts. 1576 "Major mode for editing Ruby scripts.
@@ -1586,6 +1587,10 @@ The variable `ruby-indent-level' controls the amount of indentation.
1586 'ruby-imenu-create-index) 1587 'ruby-imenu-create-index)
1587 (set (make-local-variable 'add-log-current-defun-function) 1588 (set (make-local-variable 'add-log-current-defun-function)
1588 'ruby-add-log-current-method) 1589 'ruby-add-log-current-method)
1590 (set (make-local-variable 'beginning-of-defun-function)
1591 'ruby-beginning-of-defun)
1592 (set (make-local-variable 'end-of-defun-function)
1593 'ruby-end-of-defun)
1589 1594
1590 (add-hook 1595 (add-hook
1591 (cond ((boundp 'before-save-hook) 'before-save-hook) 1596 (cond ((boundp 'before-save-hook) 'before-save-hook)
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index a422462775d..b4d550bcee0 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -1062,21 +1062,22 @@ subshells can nest."
1062 (backward-char 1)) 1062 (backward-char 1))
1063 (when (eq (char-before) ?|) 1063 (when (eq (char-before) ?|)
1064 (backward-char 1) t))) 1064 (backward-char 1) t)))
1065 (when (progn (backward-char 2) 1065 (and (> (point) (1+ (point-min)))
1066 (if (> start (line-end-position)) 1066 (progn (backward-char 2)
1067 (put-text-property (point) (1+ start) 1067 (if (> start (line-end-position))
1068 'syntax-multiline t)) 1068 (put-text-property (point) (1+ start)
1069 ;; FIXME: The `in' may just be a random argument to 1069 'syntax-multiline t))
1070 ;; a normal command rather than the real `in' keyword. 1070 ;; FIXME: The `in' may just be a random argument to
1071 ;; I.e. we should look back to try and find the 1071 ;; a normal command rather than the real `in' keyword.
1072 ;; corresponding `case'. 1072 ;; I.e. we should look back to try and find the
1073 (and (looking-at ";[;&]\\|\\_<in") 1073 ;; corresponding `case'.
1074 ;; ";; esac )" is a case that looks like a case-pattern 1074 (and (looking-at ";[;&]\\|\\_<in")
1075 ;; but it's really just a close paren after a case 1075 ;; ";; esac )" is a case that looks like a case-pattern
1076 ;; statement. I.e. if we skipped over `esac' just now, 1076 ;; but it's really just a close paren after a case
1077 ;; we're not looking at a case-pattern. 1077 ;; statement. I.e. if we skipped over `esac' just now,
1078 (not (looking-at "..[ \t\n]+esac[^[:word:]_]")))) 1078 ;; we're not looking at a case-pattern.
1079 sh-st-punc)))) 1079 (not (looking-at "..[ \t\n]+esac[^[:word:]_]"))))
1080 sh-st-punc))))
1080 1081
1081(defun sh-font-lock-backslash-quote () 1082(defun sh-font-lock-backslash-quote ()
1082 (if (eq (save-excursion (nth 3 (syntax-ppss (match-beginning 0)))) ?\') 1083 (if (eq (save-excursion (nth 3 (syntax-ppss (match-beginning 0)))) ?\')
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 607ccd8b7e7..0ca3439dd60 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -4138,10 +4138,7 @@ STRING are replaced by `-' and substrings are converted to lower case."
4138 (set (make-local-variable 'imenu-generic-expression) 4138 (set (make-local-variable 'imenu-generic-expression)
4139 vhdl-imenu-generic-expression) 4139 vhdl-imenu-generic-expression)
4140 (when (and vhdl-index-menu (fboundp 'imenu)) 4140 (when (and vhdl-index-menu (fboundp 'imenu))
4141 (if (or (not (boundp 'font-lock-maximum-size)) 4141 (imenu-add-to-menubar "Index")))
4142 (> font-lock-maximum-size (buffer-size)))
4143 (imenu-add-to-menubar "Index")
4144 (message "Scanning buffer for index...buffer too big"))))
4145 4142
4146;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4147;; Source file menu (using `easy-menu.el') 4144;; Source file menu (using `easy-menu.el')
@@ -14385,10 +14382,10 @@ if required."
14385 (define-key vhdl-speedbar-key-map (int-to-string key) 14382 (define-key vhdl-speedbar-key-map (int-to-string key)
14386 `(lambda () (interactive) (vhdl-speedbar-set-depth ,key))) 14383 `(lambda () (interactive) (vhdl-speedbar-set-depth ,key)))
14387 (setq key (1+ key))))) 14384 (setq key (1+ key)))))
14388 (define-key speedbar-key-map "h" 14385 (define-key speedbar-mode-map "h"
14389 (lambda () (interactive) 14386 (lambda () (interactive)
14390 (speedbar-change-initial-expansion-list "vhdl directory"))) 14387 (speedbar-change-initial-expansion-list "vhdl directory")))
14391 (define-key speedbar-key-map "H" 14388 (define-key speedbar-mode-map "H"
14392 (lambda () (interactive) 14389 (lambda () (interactive)
14393 (speedbar-change-initial-expansion-list "vhdl project"))) 14390 (speedbar-change-initial-expansion-list "vhdl project")))
14394 ;; menu 14391 ;; menu
@@ -17400,7 +17397,8 @@ to visually support naming conventions.")
17400 "Display VARIABLE's documentation in *Help* buffer." 17397 "Display VARIABLE's documentation in *Help* buffer."
17401 (interactive) 17398 (interactive)
17402 (unless (featurep 'xemacs) 17399 (unless (featurep 'xemacs)
17403 (help-setup-xref (list #'vhdl-doc-variable variable) (interactive-p))) 17400 (help-setup-xref (list #'vhdl-doc-variable variable)
17401 (called-interactively-p 'interactive)))
17404 (with-output-to-temp-buffer 17402 (with-output-to-temp-buffer
17405 (if (fboundp 'help-buffer) (help-buffer) "*Help*") 17403 (if (fboundp 'help-buffer) (help-buffer) "*Help*")
17406 (princ (documentation-property variable 'variable-documentation)) 17404 (princ (documentation-property variable 'variable-documentation))
@@ -17412,7 +17410,8 @@ to visually support naming conventions.")
17412 "Display VHDL Mode documentation in *Help* buffer." 17410 "Display VHDL Mode documentation in *Help* buffer."
17413 (interactive) 17411 (interactive)
17414 (unless (featurep 'xemacs) 17412 (unless (featurep 'xemacs)
17415 (help-setup-xref (list #'vhdl-doc-mode) (interactive-p))) 17413 (help-setup-xref (list #'vhdl-doc-mode)
17414 (called-interactively-p 'interactive)))
17416 (with-output-to-temp-buffer 17415 (with-output-to-temp-buffer
17417 (if (fboundp 'help-buffer) (help-buffer) "*Help*") 17416 (if (fboundp 'help-buffer) (help-buffer) "*Help*")
17418 (princ mode-name) 17417 (princ mode-name)
diff --git a/lisp/register.el b/lisp/register.el
index 2816c9831de..fb35a26a653 100644
--- a/lisp/register.el
+++ b/lisp/register.el
@@ -76,6 +76,22 @@ A list of the form (WINDOW-CONFIGURATION POSITION)
76A list of the form (FRAME-CONFIGURATION POSITION) 76A list of the form (FRAME-CONFIGURATION POSITION)
77 represents a saved frame configuration plus a saved value of point.") 77 represents a saved frame configuration plus a saved value of point.")
78 78
79(defgroup register nil
80 "Register commands."
81 :group 'convenience
82 :version "24.3")
83
84(defcustom register-separator nil
85 "Register containing the text to put between collected texts, or nil if none.
86
87When collecting text with
88`append-to-register' (resp. `prepend-to-register') contents of
89this register is added to the beginning (resp. end) of the marked
90text."
91 :group 'register
92 :type '(choice (const :tag "None" nil)
93 (character :tag "Use register" :value ?+)))
94
79(defun get-register (register) 95(defun get-register (register)
80 "Return contents of Emacs register named REGISTER, or nil if none." 96 "Return contents of Emacs register named REGISTER, or nil if none."
81 (cdr (assq register register-alist))) 97 (cdr (assq register register-alist)))
@@ -192,13 +208,24 @@ Interactively, NUMBER is the prefix arg (none means nil)."
192 (string-to-number (match-string 0))) 208 (string-to-number (match-string 0)))
193 0)))) 209 0))))
194 210
195(defun increment-register (number register) 211(defun increment-register (prefix register)
196 "Add NUMBER to the contents of register REGISTER. 212 "Augment contents of REGISTER.
197Interactively, NUMBER is the prefix arg." 213Interactively, PREFIX is in raw form.
198 (interactive "p\ncIncrement register: ") 214
199 (or (numberp (get-register register)) 215If REGISTER contains a number, add `prefix-numeric-value' of
200 (error "Register does not contain a number")) 216PREFIX to it.
201 (set-register register (+ number (get-register register)))) 217
218If REGISTER is empty or if it contains text, call
219`append-to-register' with `delete-flag' set to PREFIX."
220 (interactive "P\ncIncrement register: ")
221 (let ((register-val (get-register register)))
222 (cond
223 ((numberp register-val)
224 (let ((number (prefix-numeric-value prefix)))
225 (set-register register (+ number register-val))))
226 ((or (not register-val) (stringp register-val))
227 (append-to-register register (region-beginning) (region-end) prefix))
228 (t (error "Register does not contain a number or text")))))
202 229
203(defun view-register (register) 230(defun view-register (register)
204 "Display what is contained in register named REGISTER. 231 "Display what is contained in register named REGISTER.
@@ -349,10 +376,11 @@ Called from program, takes four args: REGISTER, START, END and DELETE-FLAG.
349START and END are buffer positions indicating what to append." 376START and END are buffer positions indicating what to append."
350 (interactive "cAppend to register: \nr\nP") 377 (interactive "cAppend to register: \nr\nP")
351 (let ((reg (get-register register)) 378 (let ((reg (get-register register))
352 (text (filter-buffer-substring start end))) 379 (text (filter-buffer-substring start end))
380 (separator (and register-separator (get-register register-separator))))
353 (set-register 381 (set-register
354 register (cond ((not reg) text) 382 register (cond ((not reg) text)
355 ((stringp reg) (concat reg text)) 383 ((stringp reg) (concat reg separator text))
356 (t (error "Register does not contain text"))))) 384 (t (error "Register does not contain text")))))
357 (cond (delete-flag 385 (cond (delete-flag
358 (delete-region start end)) 386 (delete-region start end))
@@ -366,10 +394,11 @@ Called from program, takes four args: REGISTER, START, END and DELETE-FLAG.
366START and END are buffer positions indicating what to prepend." 394START and END are buffer positions indicating what to prepend."
367 (interactive "cPrepend to register: \nr\nP") 395 (interactive "cPrepend to register: \nr\nP")
368 (let ((reg (get-register register)) 396 (let ((reg (get-register register))
369 (text (filter-buffer-substring start end))) 397 (text (filter-buffer-substring start end))
398 (separator (and register-separator (get-register register-separator))))
370 (set-register 399 (set-register
371 register (cond ((not reg) text) 400 register (cond ((not reg) text)
372 ((stringp reg) (concat text reg)) 401 ((stringp reg) (concat text separator reg))
373 (t (error "Register does not contain text"))))) 402 (t (error "Register does not contain text")))))
374 (cond (delete-flag 403 (cond (delete-flag
375 (delete-region start end)) 404 (delete-region start end))
diff --git a/lisp/replace.el b/lisp/replace.el
index 3373ee8e512..001f7d1a78d 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -33,6 +33,22 @@
33 :type 'boolean 33 :type 'boolean
34 :group 'matching) 34 :group 'matching)
35 35
36(defcustom replace-lax-whitespace nil
37 "Non-nil means `query-replace' matches a sequence of whitespace chars.
38When you enter a space or spaces in the strings to be replaced,
39it will match any sequence matched by the regexp `search-whitespace-regexp'."
40 :type 'boolean
41 :group 'matching
42 :version "24.3")
43
44(defcustom replace-regexp-lax-whitespace nil
45 "Non-nil means `query-replace-regexp' matches a sequence of whitespace chars.
46When you enter a space or spaces in the regexps to be replaced,
47it will match any sequence matched by the regexp `search-whitespace-regexp'."
48 :type 'boolean
49 :group 'matching
50 :version "24.3")
51
36(defvar query-replace-history nil 52(defvar query-replace-history nil
37 "Default history list for query-replace commands. 53 "Default history list for query-replace commands.
38See `query-replace-from-history-variable' and 54See `query-replace-from-history-variable' and
@@ -226,6 +242,10 @@ letters. \(Transferring the case pattern means that if the old text
226matched is all caps, or capitalized, then its replacement is upcased 242matched is all caps, or capitalized, then its replacement is upcased
227or capitalized.) 243or capitalized.)
228 244
245If `replace-lax-whitespace' is non-nil, a space or spaces in the string
246to be replaced will match a sequence of whitespace chars defined by the
247regexp in `search-whitespace-regexp'.
248
229Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace 249Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
230only matches surrounded by word boundaries. 250only matches surrounded by word boundaries.
231Fourth and fifth arg START and END specify the region to operate on. 251Fourth and fifth arg START and END specify the region to operate on.
@@ -270,6 +290,10 @@ pattern of the old text to the new text, if `case-replace' and
270all caps, or capitalized, then its replacement is upcased or 290all caps, or capitalized, then its replacement is upcased or
271capitalized.) 291capitalized.)
272 292
293If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp
294to be replaced will match a sequence of whitespace chars defined by the
295regexp in `search-whitespace-regexp'.
296
273Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace 297Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
274only matches surrounded by word boundaries. 298only matches surrounded by word boundaries.
275Fourth and fifth arg START and END specify the region to operate on. 299Fourth and fifth arg START and END specify the region to operate on.
@@ -346,6 +370,10 @@ minibuffer.
346Preserves case in each replacement if `case-replace' and `case-fold-search' 370Preserves case in each replacement if `case-replace' and `case-fold-search'
347are non-nil and REGEXP has no uppercase letters. 371are non-nil and REGEXP has no uppercase letters.
348 372
373If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp
374to be replaced will match a sequence of whitespace chars defined by the
375regexp in `search-whitespace-regexp'.
376
349Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace 377Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
350only matches that are surrounded by word boundaries. 378only matches that are surrounded by word boundaries.
351Fourth and fifth arg START and END specify the region to operate on." 379Fourth and fifth arg START and END specify the region to operate on."
@@ -437,6 +465,10 @@ are non-nil and FROM-STRING has no uppercase letters.
437\(Preserving case means that if the string matched is all caps, or capitalized, 465\(Preserving case means that if the string matched is all caps, or capitalized,
438then its replacement is upcased or capitalized.) 466then its replacement is upcased or capitalized.)
439 467
468If `replace-lax-whitespace' is non-nil, a space or spaces in the string
469to be replaced will match a sequence of whitespace chars defined by the
470regexp in `search-whitespace-regexp'.
471
440In Transient Mark mode, if the mark is active, operate on the contents 472In Transient Mark mode, if the mark is active, operate on the contents
441of the region. Otherwise, operate from point to the end of the buffer. 473of the region. Otherwise, operate from point to the end of the buffer.
442 474
@@ -475,6 +507,10 @@ and TO-STRING is also null.)"
475Preserve case in each match if `case-replace' and `case-fold-search' 507Preserve case in each match if `case-replace' and `case-fold-search'
476are non-nil and REGEXP has no uppercase letters. 508are non-nil and REGEXP has no uppercase letters.
477 509
510If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp
511to be replaced will match a sequence of whitespace chars defined by the
512regexp in `search-whitespace-regexp'.
513
478In Transient Mark mode, if the mark is active, operate on the contents 514In Transient Mark mode, if the mark is active, operate on the contents
479of the region. Otherwise, operate from point to the end of the buffer. 515of the region. Otherwise, operate from point to the end of the buffer.
480 516
@@ -1589,14 +1625,28 @@ E to edit the replacement string"
1589 (define-key map "?" 'help) 1625 (define-key map "?" 'help)
1590 (define-key map "\C-g" 'quit) 1626 (define-key map "\C-g" 'quit)
1591 (define-key map "\C-]" 'quit) 1627 (define-key map "\C-]" 'quit)
1592 (define-key map "\e" 'exit-prefix) 1628 (define-key map "\C-v" 'scroll-up)
1629 (define-key map "\M-v" 'scroll-down)
1630 (define-key map [next] 'scroll-up)
1631 (define-key map [prior] 'scroll-down)
1632 (define-key map [?\C-\M-v] 'scroll-other-window)
1633 (define-key map [M-next] 'scroll-other-window)
1634 (define-key map [?\C-\M-\S-v] 'scroll-other-window-down)
1635 (define-key map [M-prior] 'scroll-other-window-down)
1636 ;; Binding ESC would prohibit the M-v binding. Instead, callers
1637 ;; should check for ESC specially.
1638 ;; (define-key map "\e" 'exit-prefix)
1593 (define-key map [escape] 'exit-prefix) 1639 (define-key map [escape] 'exit-prefix)
1594 map) 1640 map)
1595 "Keymap that defines the responses to questions in `query-replace'. 1641 "Keymap of responses to questions posed by commands like `query-replace'.
1596The \"bindings\" in this map are not commands; they are answers. 1642The \"bindings\" in this map are not commands; they are answers.
1597The valid answers include `act', `skip', `act-and-show', 1643The valid answers include `act', `skip', `act-and-show',
1598`exit', `act-and-exit', `edit', `edit-replacement', `delete-and-edit', 1644`act-and-exit', `exit', `exit-prefix', `recenter', `scroll-up',
1599`recenter', `automatic', `backup', `exit-prefix', `quit', and `help'.") 1645`scroll-down', `scroll-other-window', `scroll-other-window-down',
1646`edit', `edit-replacement', `delete-and-edit', `automatic',
1647`backup', `quit', and `help'.
1648
1649This keymap is used by `y-or-n-p' as well as `query-replace'.")
1600 1650
1601(defvar multi-query-replace-map 1651(defvar multi-query-replace-map
1602 (let ((map (make-sparse-keymap))) 1652 (let ((map (make-sparse-keymap)))
@@ -1717,12 +1767,12 @@ passed in. If LITERAL is set, no checking is done, anyway."
1717 (replace-match newtext fixedcase literal) 1767 (replace-match newtext fixedcase literal)
1718 noedit) 1768 noedit)
1719 1769
1720(defvar replace-search-function 'search-forward 1770(defvar replace-search-function nil
1721 "Function to use when searching for strings to replace. 1771 "Function to use when searching for strings to replace.
1722It is used by `query-replace' and `replace-string', and is called 1772It is used by `query-replace' and `replace-string', and is called
1723with three arguments, as if it were `search-forward'.") 1773with three arguments, as if it were `search-forward'.")
1724 1774
1725(defvar replace-re-search-function 're-search-forward 1775(defvar replace-re-search-function nil
1726 "Function to use when searching for regexps to replace. 1776 "Function to use when searching for regexps to replace.
1727It is used by `query-replace-regexp', `replace-regexp', 1777It is used by `query-replace-regexp', `replace-regexp',
1728`query-replace-regexp-eval', and `map-query-replace-regexp'. 1778`query-replace-regexp-eval', and `map-query-replace-regexp'.
@@ -1755,9 +1805,18 @@ make, or the user didn't cancel the call."
1755 (nocasify (not (and case-replace case-fold-search))) 1805 (nocasify (not (and case-replace case-fold-search)))
1756 (literal (or (not regexp-flag) (eq regexp-flag 'literal))) 1806 (literal (or (not regexp-flag) (eq regexp-flag 'literal)))
1757 (search-function 1807 (search-function
1758 (if regexp-flag 1808 (or (if regexp-flag
1759 replace-re-search-function 1809 replace-re-search-function
1760 replace-search-function)) 1810 replace-search-function)
1811 (let ((isearch-regexp regexp-flag)
1812 (isearch-word delimited-flag)
1813 (isearch-lax-whitespace
1814 replace-lax-whitespace)
1815 (isearch-regexp-lax-whitespace
1816 replace-regexp-lax-whitespace)
1817 (isearch-case-fold-search case-fold-search)
1818 (isearch-forward t))
1819 (isearch-search-fun))))
1761 (search-string from-string) 1820 (search-string from-string)
1762 (real-match-data nil) ; The match data for the current match. 1821 (real-match-data nil) ; The match data for the current match.
1763 (next-replacement nil) 1822 (next-replacement nil)
@@ -1811,12 +1870,6 @@ make, or the user didn't cancel the call."
1811 (vector repeat-count repeat-count 1870 (vector repeat-count repeat-count
1812 replacements replacements))))) 1871 replacements replacements)))))
1813 1872
1814 (if delimited-flag
1815 (setq search-function 're-search-forward
1816 search-string (concat "\\b"
1817 (if regexp-flag from-string
1818 (regexp-quote from-string))
1819 "\\b")))
1820 (when query-replace-lazy-highlight 1873 (when query-replace-lazy-highlight
1821 (setq isearch-lazy-highlight-last-string nil)) 1874 (setq isearch-lazy-highlight-last-string nil))
1822 1875
@@ -1898,7 +1951,7 @@ make, or the user didn't cancel the call."
1898 (replace-highlight 1951 (replace-highlight
1899 (nth 0 real-match-data) (nth 1 real-match-data) 1952 (nth 0 real-match-data) (nth 1 real-match-data)
1900 start end search-string 1953 start end search-string
1901 (or delimited-flag regexp-flag) case-fold-search)) 1954 regexp-flag delimited-flag case-fold-search))
1902 (setq noedit 1955 (setq noedit
1903 (replace-match-maybe-edit 1956 (replace-match-maybe-edit
1904 next-replacement nocasify literal 1957 next-replacement nocasify literal
@@ -1917,7 +1970,7 @@ make, or the user didn't cancel the call."
1917 (replace-highlight 1970 (replace-highlight
1918 (match-beginning 0) (match-end 0) 1971 (match-beginning 0) (match-end 0)
1919 start end search-string 1972 start end search-string
1920 (or delimited-flag regexp-flag) case-fold-search) 1973 regexp-flag delimited-flag case-fold-search)
1921 ;; Bind message-log-max so we don't fill up the message log 1974 ;; Bind message-log-max so we don't fill up the message log
1922 ;; with a bunch of identical messages. 1975 ;; with a bunch of identical messages.
1923 (let ((message-log-max nil) 1976 (let ((message-log-max nil)
@@ -2099,15 +2152,11 @@ make, or the user didn't cancel the call."
2099 (if (= replace-count 1) "" "s"))) 2152 (if (= replace-count 1) "" "s")))
2100 (or (and keep-going stack) multi-buffer))) 2153 (or (and keep-going stack) multi-buffer)))
2101 2154
2102(defvar isearch-error)
2103(defvar isearch-forward)
2104(defvar isearch-case-fold-search)
2105(defvar isearch-string)
2106
2107(defvar replace-overlay nil) 2155(defvar replace-overlay nil)
2108 2156
2109(defun replace-highlight (match-beg match-end range-beg range-end 2157(defun replace-highlight (match-beg match-end range-beg range-end
2110 string regexp case-fold) 2158 search-string regexp-flag delimited-flag
2159 case-fold-search)
2111 (if query-replace-highlight 2160 (if query-replace-highlight
2112 (if replace-overlay 2161 (if replace-overlay
2113 (move-overlay replace-overlay match-beg match-end (current-buffer)) 2162 (move-overlay replace-overlay match-beg match-end (current-buffer))
@@ -2115,13 +2164,14 @@ make, or the user didn't cancel the call."
2115 (overlay-put replace-overlay 'priority 1001) ;higher than lazy overlays 2164 (overlay-put replace-overlay 'priority 1001) ;higher than lazy overlays
2116 (overlay-put replace-overlay 'face 'query-replace))) 2165 (overlay-put replace-overlay 'face 'query-replace)))
2117 (if query-replace-lazy-highlight 2166 (if query-replace-lazy-highlight
2118 (let ((isearch-string string) 2167 (let ((isearch-string search-string)
2119 (isearch-regexp regexp) 2168 (isearch-regexp regexp-flag)
2120 ;; Set isearch-word to nil because word-replace is regexp-based, 2169 (isearch-word delimited-flag)
2121 ;; so `isearch-search-fun' should not use `word-search-forward'. 2170 (isearch-lax-whitespace
2122 (isearch-word nil) 2171 replace-lax-whitespace)
2123 (search-whitespace-regexp nil) 2172 (isearch-regexp-lax-whitespace
2124 (isearch-case-fold-search case-fold) 2173 replace-regexp-lax-whitespace)
2174 (isearch-case-fold-search case-fold-search)
2125 (isearch-forward t) 2175 (isearch-forward t)
2126 (isearch-error nil)) 2176 (isearch-error nil))
2127 (isearch-lazy-highlight-new-loop range-beg range-end)))) 2177 (isearch-lazy-highlight-new-loop range-beg range-end))))
diff --git a/lisp/ses.el b/lisp/ses.el
index 8add16a6996..7cdac74e310 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -1270,11 +1270,9 @@ when the width of cell (ROW,COL) has changed."
1270;; The data area 1270;; The data area
1271;;---------------------------------------------------------------------------- 1271;;----------------------------------------------------------------------------
1272 1272
1273(defun ses-narrowed-p () (/= (- (point-max) (point-min)) (buffer-size)))
1274
1275(defun ses-widen () 1273(defun ses-widen ()
1276 "Turn off narrowing, to be reenabled at end of command loop." 1274 "Turn off narrowing, to be reenabled at end of command loop."
1277 (if (ses-narrowed-p) 1275 (if (buffer-narrowed-p)
1278 (setq ses--deferred-narrow t)) 1276 (setq ses--deferred-narrow t))
1279 (widen)) 1277 (widen))
1280 1278
diff --git a/lisp/simple.el b/lisp/simple.el
index b7a24f4f970..d87ae3c5c15 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -974,7 +974,9 @@ rather than the region.
974 974
975If called from Lisp, return the number of words between positions 975If called from Lisp, return the number of words between positions
976START and END." 976START and END."
977 (interactive "r\nP") 977 (interactive (if current-prefix-arg
978 (list nil nil current-prefix-arg)
979 (list (region-beginning) (region-end) nil)))
978 (cond ((not (called-interactively-p 'any)) 980 (cond ((not (called-interactively-p 'any))
979 (count-words start end)) 981 (count-words start end))
980 (arg 982 (arg
@@ -1008,9 +1010,7 @@ END, without printing any message."
1008 1010
1009(defun count-words--buffer-message () 1011(defun count-words--buffer-message ()
1010 (count-words--message 1012 (count-words--message
1011 (if (= (point-max) (1+ (buffer-size))) 1013 (if (buffer-narrowed-p) "Narrowed part of buffer" "Buffer")
1012 "Buffer"
1013 "Narrowed part of buffer")
1014 (point-min) (point-max))) 1014 (point-min) (point-max)))
1015 1015
1016(defun count-words--message (str start end) 1016(defun count-words--message (str start end)
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index 16993ce1891..90cdea63e85 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -763,7 +763,7 @@ DIRECTORY-EXPRESSION to `speedbar-ignored-directory-expressions'."
763 "Non-nil means to automatically update the display. 763 "Non-nil means to automatically update the display.
764When this is nil then speedbar will not follow the attached frame's directory. 764When this is nil then speedbar will not follow the attached frame's directory.
765If you want to change this while speedbar is active, either use 765If you want to change this while speedbar is active, either use
766\\[customize] or call \\<speedbar-key-map> `\\[speedbar-toggle-updates]'." 766\\[customize] or call \\<speedbar-mode-map> `\\[speedbar-toggle-updates]'."
767 :group 'speedbar 767 :group 'speedbar
768 :initialize 'custom-initialize-default 768 :initialize 'custom-initialize-default
769 :set (lambda (sym val) 769 :set (lambda (sym val)
@@ -1083,7 +1083,7 @@ Return nil if it doesn't exist."
1083 1083
1084(define-derived-mode speedbar-mode fundamental-mode "Speedbar" 1084(define-derived-mode speedbar-mode fundamental-mode "Speedbar"
1085 "Major mode for managing a display of directories and tags. 1085 "Major mode for managing a display of directories and tags.
1086\\<speedbar-key-map> 1086\\<speedbar-mode-map>
1087The first line represents the default directory of the speedbar frame. 1087The first line represents the default directory of the speedbar frame.
1088Each directory segment is a button which jumps speedbar's default 1088Each directory segment is a button which jumps speedbar's default
1089directory to that directory. Buttons are activated by clicking `\\[speedbar-click]'. 1089directory to that directory. Buttons are activated by clicking `\\[speedbar-click]'.
@@ -1120,7 +1120,7 @@ category of tags. Click the {+} to expand the category. Jump-able
1120tags start with >. Click the name of the tag to go to that position 1120tags start with >. Click the name of the tag to go to that position
1121in the selected file. 1121in the selected file.
1122 1122
1123\\{speedbar-key-map}" 1123\\{speedbar-mode-map}"
1124 (save-excursion 1124 (save-excursion
1125 (setq font-lock-keywords nil) ;; no font-locking please 1125 (setq font-lock-keywords nil) ;; no font-locking please
1126 (setq truncate-lines t) 1126 (setq truncate-lines t)
diff --git a/lisp/subr.el b/lisp/subr.el
index 74afd59f8d5..be785ff8fba 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1548,7 +1548,7 @@ if it is empty or a duplicate."
1548 (or keep-all 1548 (or keep-all
1549 (not (equal (car history) newelt)))) 1549 (not (equal (car history) newelt))))
1550 (if history-delete-duplicates 1550 (if history-delete-duplicates
1551 (delete newelt history)) 1551 (setq history (delete newelt history)))
1552 (setq history (cons newelt history)) 1552 (setq history (cons newelt history))
1553 (when (integerp maxelt) 1553 (when (integerp maxelt)
1554 (if (= 0 maxelt) 1554 (if (= 0 maxelt)
@@ -2237,7 +2237,8 @@ keyboard-quit events while waiting for a valid input."
2237 (error "Called `read-char-choice' without valid char choices")) 2237 (error "Called `read-char-choice' without valid char choices"))
2238 (let (char done show-help (helpbuf " *Char Help*")) 2238 (let (char done show-help (helpbuf " *Char Help*"))
2239 (let ((cursor-in-echo-area t) 2239 (let ((cursor-in-echo-area t)
2240 (executing-kbd-macro executing-kbd-macro)) 2240 (executing-kbd-macro executing-kbd-macro)
2241 (esc-flag nil))
2241 (save-window-excursion ; in case we call help-form-show 2242 (save-window-excursion ; in case we call help-form-show
2242 (while (not done) 2243 (while (not done)
2243 (unless (get-text-property 0 'face prompt) 2244 (unless (get-text-property 0 'face prompt)
@@ -2261,8 +2262,12 @@ keyboard-quit events while waiting for a valid input."
2261 ;; there are no more events in the macro. Attempt to 2262 ;; there are no more events in the macro. Attempt to
2262 ;; get an event interactively. 2263 ;; get an event interactively.
2263 (setq executing-kbd-macro nil)) 2264 (setq executing-kbd-macro nil))
2264 ((and (not inhibit-keyboard-quit) (eq char ?\C-g)) 2265 ((not inhibit-keyboard-quit)
2265 (keyboard-quit)))))) 2266 (cond
2267 ((and (null esc-flag) (eq char ?\e))
2268 (setq esc-flag t))
2269 ((memq char '(?\C-g ?\e))
2270 (keyboard-quit))))))))
2266 ;; Display the question with the answer. But without cursor-in-echo-area. 2271 ;; Display the question with the answer. But without cursor-in-echo-area.
2267 (message "%s%s" prompt (char-to-string char)) 2272 (message "%s%s" prompt (char-to-string char))
2268 char)) 2273 char))
@@ -2314,11 +2319,19 @@ floating point support."
2314PROMPT is the string to display to ask the question. It should 2319PROMPT is the string to display to ask the question. It should
2315end in a space; `y-or-n-p' adds \"(y or n) \" to it. 2320end in a space; `y-or-n-p' adds \"(y or n) \" to it.
2316 2321
2317No confirmation of the answer is requested; a single character is enough. 2322No confirmation of the answer is requested; a single character is
2318Also accepts Space to mean yes, or Delete to mean no. \(Actually, it uses 2323enough. SPC also means yes, and DEL means no.
2319the bindings in `query-replace-map'; see the documentation of that variable 2324
2320for more information. In this case, the useful bindings are `act', `skip', 2325To be precise, this function translates user input into responses
2321`recenter', and `quit'.\) 2326by consulting the bindings in `query-replace-map'; see the
2327documentation of that variable for more information. In this
2328case, the useful bindings are `act', `skip', `recenter',
2329`scroll-up', `scroll-down', and `quit'.
2330An `act' response means yes, and a `skip' response means no.
2331A `quit' response means to invoke `keyboard-quit'.
2332If the user enters `recenter', `scroll-up', or `scroll-down'
2333responses, perform the requested window recentering or scrolling
2334and ask again.
2322 2335
2323Under a windowing system a dialog box will be used if `last-nonmenu-event' 2336Under a windowing system a dialog box will be used if `last-nonmenu-event'
2324is nil and `use-dialog-box' is non-nil." 2337is nil and `use-dialog-box' is non-nil."
@@ -2350,21 +2363,33 @@ is nil and `use-dialog-box' is non-nil."
2350 "" " ") 2363 "" " ")
2351 "(y or n) ")) 2364 "(y or n) "))
2352 (while 2365 (while
2353 (let* ((key 2366 (let* ((scroll-actions '(recenter scroll-up scroll-down
2367 scroll-other-window scroll-other-window-down))
2368 (key
2354 (let ((cursor-in-echo-area t)) 2369 (let ((cursor-in-echo-area t))
2355 (when minibuffer-auto-raise 2370 (when minibuffer-auto-raise
2356 (raise-frame (window-frame (minibuffer-window)))) 2371 (raise-frame (window-frame (minibuffer-window))))
2357 (read-key (propertize (if (eq answer 'recenter) 2372 (read-key (propertize (if (memq answer scroll-actions)
2358 prompt 2373 prompt
2359 (concat "Please answer y or n. " 2374 (concat "Please answer y or n. "
2360 prompt)) 2375 prompt))
2361 'face 'minibuffer-prompt))))) 2376 'face 'minibuffer-prompt)))))
2362 (setq answer (lookup-key query-replace-map (vector key) t)) 2377 (setq answer (lookup-key query-replace-map (vector key) t))
2363 (cond 2378 (cond
2364 ((memq answer '(skip act)) nil) 2379 ((memq answer '(skip act)) nil)
2365 ((eq answer 'recenter) (recenter) t) 2380 ((eq answer 'recenter)
2366 ((memq answer '(exit-prefix quit)) (signal 'quit nil) t) 2381 (recenter) t)
2367 (t t))) 2382 ((eq answer 'scroll-up)
2383 (ignore-errors (scroll-up-command)) t)
2384 ((eq answer 'scroll-down)
2385 (ignore-errors (scroll-down-command)) t)
2386 ((eq answer 'scroll-other-window)
2387 (ignore-errors (scroll-other-window)) t)
2388 ((eq answer 'scroll-other-window-down)
2389 (ignore-errors (scroll-other-window-down)) t)
2390 ((or (memq answer '(exit-prefix quit)) (eq key ?\e))
2391 (signal 'quit nil) t)
2392 (t t)))
2368 (ding) 2393 (ding)
2369 (discard-input)))) 2394 (discard-input))))
2370 (let ((ret (eq answer 'act))) 2395 (let ((ret (eq answer 'act)))
@@ -2647,6 +2672,10 @@ directory if it does not exist."
2647 2672
2648;;;; Misc. useful functions. 2673;;;; Misc. useful functions.
2649 2674
2675(defsubst buffer-narrowed-p ()
2676 "Return non-nil if the current buffer is narrowed."
2677 (/= (- (point-max) (point-min)) (buffer-size)))
2678
2650(defun find-tag-default () 2679(defun find-tag-default ()
2651 "Determine default tag to search for, based on text at point. 2680 "Determine default tag to search for, based on text at point.
2652If there is no plausible default, return nil." 2681If there is no plausible default, return nil."
@@ -3728,7 +3757,7 @@ from `standard-syntax-table' otherwise."
3728 table)) 3757 table))
3729 3758
3730(defun syntax-after (pos) 3759(defun syntax-after (pos)
3731 "Return the raw syntax of the char after POS. 3760 "Return the raw syntax descriptor for the char after POS.
3732If POS is outside the buffer's accessible portion, return nil." 3761If POS is outside the buffer's accessible portion, return nil."
3733 (unless (or (< pos (point-min)) (>= pos (point-max))) 3762 (unless (or (< pos (point-min)) (>= pos (point-max)))
3734 (let ((st (if parse-sexp-lookup-properties 3763 (let ((st (if parse-sexp-lookup-properties
@@ -3737,7 +3766,12 @@ If POS is outside the buffer's accessible portion, return nil."
3737 (aref (or st (syntax-table)) (char-after pos)))))) 3766 (aref (or st (syntax-table)) (char-after pos))))))
3738 3767
3739(defun syntax-class (syntax) 3768(defun syntax-class (syntax)
3740 "Return the syntax class part of the syntax descriptor SYNTAX. 3769 "Return the code for the syntax class described by SYNTAX.
3770
3771SYNTAX should be a raw syntax descriptor; the return value is a
3772integer which encodes the corresponding syntax class. See Info
3773node `(elisp)Syntax Table Internals' for a list of codes.
3774
3741If SYNTAX is nil, return nil." 3775If SYNTAX is nil, return nil."
3742 (and syntax (logand (car syntax) 65535))) 3776 (and syntax (logand (car syntax) 65535)))
3743 3777
diff --git a/lisp/textmodes/picture.el b/lisp/textmodes/picture.el
index 24a4ac1b033..e663c1b45f4 100644
--- a/lisp/textmodes/picture.el
+++ b/lisp/textmodes/picture.el
@@ -612,13 +612,15 @@ Leaves the region surrounding the rectangle."
612 (define-key map [remap self-insert-command] 'picture-self-insert) 612 (define-key map [remap self-insert-command] 'picture-self-insert)
613 (define-key map [remap self-insert-command] 'picture-self-insert) 613 (define-key map [remap self-insert-command] 'picture-self-insert)
614 (define-key map [remap completion-separator-self-insert-command] 614 (define-key map [remap completion-separator-self-insert-command]
615 'picture-self-insert) 615 'picture-self-insert)
616 (define-key map [remap completion-separator-self-insert-autofilling] 616 (define-key map [remap completion-separator-self-insert-autofilling]
617 'picture-self-insert) 617 'picture-self-insert)
618 (define-key map [remap forward-char] 'picture-forward-column) 618 (define-key map [remap forward-char] 'picture-forward-column)
619 (define-key map [remap right-char] 'picture-forward-column)
619 (define-key map [remap backward-char] 'picture-backward-column) 620 (define-key map [remap backward-char] 'picture-backward-column)
621 (define-key map [remap left-char] 'picture-backward-column)
620 (define-key map [remap delete-char] 'picture-clear-column) 622 (define-key map [remap delete-char] 'picture-clear-column)
621 ;; There are two possibilities for what is normally on DEL. 623 ;; There are two possibilities for what is normally on DEL.
622 (define-key map [remap backward-delete-char-untabify] 624 (define-key map [remap backward-delete-char-untabify]
623 'picture-backward-clear-column) 625 'picture-backward-clear-column)
624 (define-key map [remap delete-backward-char] 'picture-backward-clear-column) 626 (define-key map [remap delete-backward-char] 'picture-backward-clear-column)
diff --git a/lisp/userlock.el b/lisp/userlock.el
index 705d9588249..4c003e423aa 100644
--- a/lisp/userlock.el
+++ b/lisp/userlock.el
@@ -108,37 +108,27 @@ You can rewrite this to use any criterion you like to choose which one to do.
108The buffer in question is current when this function is called." 108The buffer in question is current when this function is called."
109 (discard-input) 109 (discard-input)
110 (save-window-excursion 110 (save-window-excursion
111 (let (answer) 111 (let ((prompt
112 (format "%s changed on disk; \
113really edit the buffer? (y, n, r or C-h) "
114 (file-name-nondirectory fn)))
115 (choices '(?y ?n ?r ?? ?\C-h))
116 answer)
112 (while (null answer) 117 (while (null answer)
113 (message "%s changed on disk; really edit the buffer? (y, n, r or C-h) " 118 (setq answer (read-char-choice prompt choices))
114 (file-name-nondirectory fn)) 119 (cond ((memq answer '(?? ?\C-h))
115 (let ((tem (downcase (let ((cursor-in-echo-area t)) 120 (ask-user-about-supersession-help)
116 (read-char-exclusive))))) 121 (setq answer nil))
117 (setq answer 122 ((eq answer ?r)
118 (if (= tem help-char) 123 ;; Ask for confirmation if buffer modified
119 'help 124 (revert-buffer nil (not (buffer-modified-p)))
120 (cdr (assoc tem '((?n . yield) 125 (signal 'file-supersession
121 (?\C-g . yield) 126 (list "File reverted" fn)))
122 (?y . proceed) 127 ((eq answer ?n)
123 (?r . revert) 128 (signal 'file-supersession
124 (?? . help)))))) 129 (list "File changed on disk" fn)))))
125 (cond ((null answer)
126 (beep)
127 (message "Please type y, n or r; or ? for help")
128 (sit-for 3))
129 ((eq answer 'help)
130 (ask-user-about-supersession-help)
131 (setq answer nil))
132 ((eq answer 'revert)
133 (revert-buffer nil (not (buffer-modified-p)))
134 ; ask confirmation if buffer modified
135 (signal 'file-supersession
136 (list "File reverted" fn)))
137 ((eq answer 'yield)
138 (signal 'file-supersession
139 (list "File changed on disk" fn))))))
140 (message 130 (message
141 "File on disk now will become a backup file if you save these changes.") 131 "File on disk now will become a backup file if you save these changes.")
142 (setq buffer-backed-up nil)))) 132 (setq buffer-backed-up nil))))
143 133
144(defun ask-user-about-supersession-help () 134(defun ask-user-about-supersession-help ()
diff --git a/lisp/window.el b/lisp/window.el
index f73c85e991b..dd1f55450c3 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -5521,6 +5521,62 @@ the selected one."
5521 (window--display-buffer 5521 (window--display-buffer
5522 buffer window 'reuse display-buffer-mark-dedicated))))) 5522 buffer window 'reuse display-buffer-mark-dedicated)))))
5523 5523
5524(defun display-buffer-in-previous-window (buffer alist)
5525 "Display BUFFER in a window previously showing it.
5526If ALIST has a non-nil `inhibit-same-window' entry, the selected
5527window is not eligible for reuse.
5528
5529If ALIST contains a `reusable-frames' entry, its value determines
5530which frames to search for a reusable window:
5531 nil -- the selected frame (actually the last non-minibuffer frame)
5532 A frame -- just that frame
5533 `visible' -- all visible frames
5534 0 -- all frames on the current terminal
5535 t -- all frames.
5536
5537If ALIST contains no `reusable-frames' entry, search just the
5538selected frame if `display-buffer-reuse-frames' and
5539`pop-up-frames' are both nil; search all frames on the current
5540terminal if either of those variables is non-nil.
5541
5542If ALIST has a `previous-window' entry, the window specified by
5543that entry will override any other window found by the methods
5544above, even if that window never showed BUFFER before."
5545 (let* ((alist-entry (assq 'reusable-frames alist))
5546 (inhibit-same-window
5547 (cdr (assq 'inhibit-same-window alist)))
5548 (frames (cond
5549 (alist-entry (cdr alist-entry))
5550 ((if (eq pop-up-frames 'graphic-only)
5551 (display-graphic-p)
5552 pop-up-frames)
5553 0)
5554 (display-buffer-reuse-frames 0)
5555 (t (last-nonminibuffer-frame))))
5556 entry best-window second-best-window window)
5557 ;; Scan windows whether they have shown the buffer recently.
5558 (catch 'best
5559 (dolist (window (window-list-1 (frame-first-window) 'nomini frames))
5560 (when (and (assq buffer (window-prev-buffers window))
5561 (not (window-dedicated-p window)))
5562 (if (eq window (selected-window))
5563 (unless inhibit-same-window
5564 (setq second-best-window window))
5565 (setq best-window window)
5566 (throw 'best t)))))
5567 ;; When ALIST has a `previous-window' entry, that entry may override
5568 ;; anything we found so far.
5569 (when (and (setq window (cdr (assq 'previous-window alist)))
5570 (window-live-p window)
5571 (not (window-dedicated-p window)))
5572 (if (eq window (selected-window))
5573 (unless inhibit-same-window
5574 (setq second-best-window window))
5575 (setq best-window window)))
5576 ;; Return best or second best window found.
5577 (when (setq window (or best-window second-best-window))
5578 (window--display-buffer buffer window 'reuse))))
5579
5524(defun display-buffer-use-some-window (buffer alist) 5580(defun display-buffer-use-some-window (buffer alist)
5525 "Display BUFFER in an existing window. 5581 "Display BUFFER in an existing window.
5526Search for a usable window, set that window to the buffer, and 5582Search for a usable window, set that window to the buffer, and
@@ -5642,26 +5698,28 @@ buffer with the name BUFFER-OR-NAME and return that buffer."
5642 5698
5643(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window) 5699(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
5644 "Switch to buffer BUFFER-OR-NAME in the selected window. 5700 "Switch to buffer BUFFER-OR-NAME in the selected window.
5645If called interactively, prompt for the buffer name using the 5701If the selected window cannot display the specified
5702buffer (e.g. if it is a minibuffer window or strongly dedicated
5703to another buffer), call `pop-to-buffer' to select the buffer in
5704another window.
5705
5706If called interactively, read the buffer name using the
5646minibuffer. The variable `confirm-nonexistent-file-or-buffer' 5707minibuffer. The variable `confirm-nonexistent-file-or-buffer'
5647determines whether to request confirmation before creating a new 5708determines whether to request confirmation before creating a new
5648buffer. 5709buffer.
5649 5710
5650BUFFER-OR-NAME may be a buffer, a string (a buffer name), or 5711BUFFER-OR-NAME may be a buffer, a string (a buffer name), or nil.
5651nil. If BUFFER-OR-NAME is a string that does not identify an 5712If BUFFER-OR-NAME is a string that does not identify an existing
5652existing buffer, create a buffer with that name. If 5713buffer, create a buffer with that name. If BUFFER-OR-NAME is
5653BUFFER-OR-NAME is nil, switch to the buffer returned by 5714nil, switch to the buffer returned by `other-buffer'.
5654`other-buffer'.
5655 5715
5656Optional argument NORECORD non-nil means do not put the buffer 5716If optional argument NORECORD is non-nil, do not put the buffer
5657specified by BUFFER-OR-NAME at the front of the buffer list and 5717at the front of the buffer list, and do not make the window
5658do not make the window displaying it the most recently selected 5718displaying it the most recently selected one.
5659one.
5660 5719
5661If FORCE-SAME-WINDOW is non-nil, BUFFER-OR-NAME must be displayed 5720If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
5662in the selected window; signal an error if that is 5721must be displayed in the selected window; if that is impossible,
5663impossible (e.g. if the selected window is minibuffer-only). If 5722signal an error rather than calling `pop-to-buffer'.
5664nil, BUFFER-OR-NAME may be displayed in another window.
5665 5723
5666Return the buffer switched to." 5724Return the buffer switched to."
5667 (interactive 5725 (interactive
@@ -5918,6 +5976,88 @@ WINDOW was scrolled."
5918 (error (setq delta nil))) 5976 (error (setq delta nil)))
5919 delta)))) 5977 delta))))
5920 5978
5979(defcustom fit-frame-to-buffer-bottom-margin 4
5980 "Bottom margin for `fit-frame-to-buffer'.
5981This is the number of lines `fit-frame-to-buffer' leaves free at the
5982bottom of the display in order to not obscure the system task bar."
5983 :type 'integer
5984 :version "24.2"
5985 :group 'windows)
5986
5987(defun fit-frame-to-buffer (&optional frame max-height min-height)
5988 "Adjust height of FRAME to display its buffer's contents exactly.
5989FRAME can be any live frame and defaults to the selected one.
5990
5991Optional argument MAX-HEIGHT specifies the maximum height of
5992FRAME and defaults to the height of the display below the current
5993top line of FRAME minus FIT-FRAME-TO-BUFFER-BOTTOM-MARGIN.
5994Optional argument MIN-HEIGHT specifies the minimum height of
5995FRAME."
5996 (interactive)
5997 (setq frame (window-normalize-frame frame))
5998 (let* ((root (frame-root-window frame))
5999 (frame-min-height
6000 (+ (- (frame-height frame) (window-total-size root))
6001 window-min-height))
6002 (frame-top (frame-parameter frame 'top))
6003 (top (if (consp frame-top)
6004 (funcall (car frame-top) (cadr frame-top))
6005 frame-top))
6006 (frame-max-height
6007 (- (/ (- (x-display-pixel-height frame) top)
6008 (frame-char-height frame))
6009 fit-frame-to-buffer-bottom-margin))
6010 (compensate 0)
6011 delta)
6012 (when (and (window-live-p root) (not (window-size-fixed-p root)))
6013 (with-selected-window root
6014 (cond
6015 ((not max-height)
6016 (setq max-height frame-max-height))
6017 ((numberp max-height)
6018 (setq max-height (min max-height frame-max-height)))
6019 (t
6020 (error "%s is an invalid maximum height" max-height)))
6021 (cond
6022 ((not min-height)
6023 (setq min-height frame-min-height))
6024 ((numberp min-height)
6025 (setq min-height (min min-height frame-min-height)))
6026 (t
6027 (error "%s is an invalid minimum height" min-height)))
6028 ;; When tool-bar-mode is enabled and we have just created a new
6029 ;; frame, reserve lines for toolbar resizing. This is needed
6030 ;; because for reasons unknown to me Emacs (1) reserves one line
6031 ;; for the toolbar when making the initial frame and toolbars
6032 ;; are enabled, and (2) later adds the remaining lines needed.
6033 ;; Our code runs IN BETWEEN (1) and (2). YMMV when you're on a
6034 ;; system that behaves differently.
6035 (let ((quit-restore (window-parameter root 'quit-restore))
6036 (lines (tool-bar-lines-needed frame)))
6037 (when (and quit-restore (eq (car quit-restore) 'frame)
6038 (not (zerop lines)))
6039 (setq compensate (1- lines))))
6040 (message "%s" compensate)
6041 (setq delta
6042 ;; Always count a final newline - we don't do any
6043 ;; post-processing, so let's play safe.
6044 (+ (count-screen-lines nil nil t)
6045 (- (window-body-size))
6046 compensate)))
6047 ;; Move away from final newline.
6048 (when (and (eobp) (bolp) (not (bobp)))
6049 (set-window-point root (line-beginning-position 0)))
6050 (set-window-start root (point-min))
6051 (set-window-vscroll root 0)
6052 (condition-case nil
6053 (set-frame-height
6054 frame
6055 (min (max (+ (frame-height frame) delta)
6056 min-height)
6057 max-height))
6058 (error (setq delta nil))))
6059 delta))
6060
5921(defun window-safely-shrinkable-p (&optional window) 6061(defun window-safely-shrinkable-p (&optional window)
5922 "Return t if WINDOW can be shrunk without shrinking other windows. 6062 "Return t if WINDOW can be shrunk without shrinking other windows.
5923WINDOW defaults to the selected window." 6063WINDOW defaults to the selected window."
@@ -6161,7 +6301,7 @@ This is different from `scroll-down-command' that scrolls a full screen."
6161(put 'scroll-down-line 'scroll-command t) 6301(put 'scroll-down-line 'scroll-command t)
6162 6302
6163 6303
6164(defun scroll-other-window-down (lines) 6304(defun scroll-other-window-down (&optional lines)
6165 "Scroll the \"other window\" down. 6305 "Scroll the \"other window\" down.
6166For more details, see the documentation for `scroll-other-window'." 6306For more details, see the documentation for `scroll-other-window'."
6167 (interactive "P") 6307 (interactive "P")