aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaroly Lorentey2004-02-02 19:19:08 +0000
committerKaroly Lorentey2004-02-02 19:19:08 +0000
commitd3a6748c5b378a86fc8408222c7dd26e47218af9 (patch)
tree33f9334088634447425b8c926dd45d1e83fa80e2
parent465fc071a1aa48e87f37bff460410eec921eaa53 (diff)
parentd83a97ab5fbcde063e4a87042cd721a23f13fbe0 (diff)
downloademacs-d3a6748c5b378a86fc8408222c7dd26e47218af9.tar.gz
emacs-d3a6748c5b378a86fc8408222c7dd26e47218af9.zip
Merged in changes from CVS HEAD
Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-57 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-58 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-59 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-60 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-61 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-62 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-63 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-64 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-65 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-66 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-67 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-68 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-69 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-71
-rw-r--r--ChangeLog6
-rwxr-xr-xconfigure6
-rw-r--r--configure.in6
-rw-r--r--etc/NEWS13
-rw-r--r--leim/ChangeLog4
-rw-r--r--leim/quail/cyrillic.el38
-rw-r--r--lib-src/ChangeLog11
-rw-r--r--lib-src/emacsclient.c48
-rw-r--r--lisp/ChangeLog166
-rw-r--r--lisp/dos-w32.el6
-rw-r--r--lisp/emacs-lisp/bytecomp.el148
-rw-r--r--lisp/emacs-lisp/easy-mmode.el19
-rw-r--r--lisp/emacs-lisp/lisp.el25
-rw-r--r--lisp/filecache.el36
-rw-r--r--lisp/files.el9
-rw-r--r--lisp/font-lock.el12
-rw-r--r--lisp/info-look.el13
-rw-r--r--lisp/jit-lock.el150
-rw-r--r--lisp/mail/rmail-spam-filter.el617
-rw-r--r--lisp/progmodes/executable.el27
-rw-r--r--lisp/progmodes/grep.el23
-rw-r--r--lisp/replace.el4
-rw-r--r--lisp/server.el5
-rw-r--r--lisp/ses.el22
-rw-r--r--lisp/simple.el20
-rw-r--r--lisp/term.el1
-rw-r--r--lisp/term/x-win.el6
-rw-r--r--lisp/textmodes/fill.el6
-rw-r--r--lisp/textmodes/paragraphs.el11
-rw-r--r--lispref/ChangeLog7
-rw-r--r--lispref/strings.texi56
-rw-r--r--nt/ChangeLog8
-rw-r--r--nt/gmake.defs1
-rw-r--r--nt/nmake.defs1
-rw-r--r--src/ChangeLog70
-rw-r--r--src/alloca.c2
-rw-r--r--src/callproc.c17
-rw-r--r--src/coding.c3
-rw-r--r--src/fileio.c36
-rw-r--r--src/fns.c10
-rw-r--r--src/macterm.c6
-rw-r--r--src/makefile.w32-in1
-rw-r--r--src/process.c18
-rw-r--r--src/process.h3
-rw-r--r--src/search.c12
-rw-r--r--src/sysdep.c6
-rw-r--r--src/unexmacosx.c4
-rw-r--r--src/w32fns.c72
48 files changed, 1169 insertions, 622 deletions
diff --git a/ChangeLog b/ChangeLog
index 05ce35671f2..a01025e36f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
12004-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * configure.in <darwin>: Use fink packages if available.
4
12004-01-25 Jerome Marant <jmarant@free.fr> (tiny change) 52004-01-25 Jerome Marant <jmarant@free.fr> (tiny change)
2 6
3 * make-dist (lispref): Do include lispref/index.texi. 7 * make-dist (lispref): Do include lispref/index.texi.
@@ -39,7 +43,7 @@
39 43
40 * configure.in (HAVE_GTK_MULTIDISPLAY): Check if GTK can handle 44 * configure.in (HAVE_GTK_MULTIDISPLAY): Check if GTK can handle
41 multiple displays. 45 multiple displays.
42 Wrong number of args to AC_CHECK_LIB for HAVE_X_SM test corrected. 46 Wrong number of args to AC_CHECK_LIB for HAVE_X_SM test corrected.
43 47
442003-09-23 Dave Love <fx@gnu.org> 482003-09-23 Dave Love <fx@gnu.org>
45 49
diff --git a/configure b/configure
index 1616a51eb46..ce011807fb2 100755
--- a/configure
+++ b/configure
@@ -2610,6 +2610,12 @@ _ACEOF
2610 machine=powermac opsys=darwin 2610 machine=powermac opsys=darwin
2611 # Define CPP as follows to make autoconf work correctly. 2611 # Define CPP as follows to make autoconf work correctly.
2612 CPP="${CC-cc} -E -no-cpp-precomp" 2612 CPP="${CC-cc} -E -no-cpp-precomp"
2613 # Use fink packages if available.
2614 if test -d /sw/include && test -d /sw/lib; then
2615 GCC_TEST_OPTIONS="-I/sw/include -L/sw/lib"
2616 CPP="${CPP} ${GCC_TEST_OPTIONS}"
2617 NON_GCC_TEST_OPTIONS=${GCC_TEST_OPTIONS}
2618 fi
2613 ;; 2619 ;;
2614 2620
2615 ## AMD x86-64 Linux-based GNU system 2621 ## AMD x86-64 Linux-based GNU system
diff --git a/configure.in b/configure.in
index 8663ce9765c..d5e4ba1e69b 100644
--- a/configure.in
+++ b/configure.in
@@ -1135,6 +1135,12 @@ dnl see the `changequote' comment above.
1135 machine=powermac opsys=darwin 1135 machine=powermac opsys=darwin
1136 # Define CPP as follows to make autoconf work correctly. 1136 # Define CPP as follows to make autoconf work correctly.
1137 CPP="${CC-cc} -E -no-cpp-precomp" 1137 CPP="${CC-cc} -E -no-cpp-precomp"
1138 # Use fink packages if available.
1139 if test -d /sw/include && test -d /sw/lib; then
1140 GCC_TEST_OPTIONS="-I/sw/include -L/sw/lib"
1141 CPP="${CPP} ${GCC_TEST_OPTIONS}"
1142 NON_GCC_TEST_OPTIONS=${GCC_TEST_OPTIONS}
1143 fi
1138 ;; 1144 ;;
1139 1145
1140 ## AMD x86-64 Linux-based GNU system 1146 ## AMD x86-64 Linux-based GNU system
diff --git a/etc/NEWS b/etc/NEWS
index 79cae43174a..90dc12c732f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -856,13 +856,20 @@ Instead, the `$ENVVAR' text is left as is, so that `$$' quoting
856is only rarely needed. 856is only rarely needed.
857 857
858--- 858---
859** jit-lock can now be delayed with `jit-lock-defer-time'. 859** JIT-lock changes
860*** jit-lock can now be delayed with `jit-lock-defer-time'.
860 861
861If this variable is non-nil, its value should be the amount of Emacs 862If this variable is non-nil, its value should be the amount of Emacs
862idle time in seconds to wait before starting fontification. For 863idle time in seconds to wait before starting fontification. For
863example, if you set `jit-lock-defer-time' to 0.25, fontification will 864example, if you set `jit-lock-defer-time' to 0.25, fontification will
864only happen after 0.25s of idle time. 865only happen after 0.25s of idle time.
865 866
867*** contextual refontification is now separate from stealth fontification.
868
869jit-lock-defer-contextually is renamed jit-lock-contextually and
870jit-lock-context-time determines the delay after which contextual
871refontification takes place.
872
866+++ 873+++
867** Marking commands extend the region when invoked multiple times. If 874** Marking commands extend the region when invoked multiple times. If
868you hit M-C-SPC (mark-sexp), M-@ (mark-word), M-h (mark-paragraph), or 875you hit M-C-SPC (mark-sexp), M-@ (mark-word), M-h (mark-paragraph), or
@@ -1790,6 +1797,10 @@ configuration files.
1790 1797
1791* Lisp Changes in Emacs 21.4 1798* Lisp Changes in Emacs 21.4
1792 1799
1800** The default value of `sentence-end' is now defined using the new
1801variable `sentence-end-without-space' which contains such characters
1802that end a sentence without following spaces.
1803
1793+++ 1804+++
1794** The flags, width, and precision options for %-specifications in function 1805** The flags, width, and precision options for %-specifications in function
1795`format' are now documented. Some flags that were accepted but not 1806`format' are now documented. Some flags that were accepted but not
diff --git a/leim/ChangeLog b/leim/ChangeLog
index adf72efb696..8f43358dde0 100644
--- a/leim/ChangeLog
+++ b/leim/ChangeLog
@@ -1,3 +1,7 @@
12004-01-27 Ognyan Kulev <ogi@fmi.uni-sofia.bg> (tiny change)
2
3 * quail/cyrillic.el ("bulgarian-bds"): Docstring fixed.
4
12004-01-22 Ognyan Kulev <ogi@fmi.uni-sofia.bg> (tiny change) 52004-01-22 Ognyan Kulev <ogi@fmi.uni-sofia.bg> (tiny change)
2 6
3 * quail/cyrillic.el ("bulgarian-phonetic"): Docstring fixed. 7 * quail/cyrillic.el ("bulgarian-phonetic"): Docstring fixed.
diff --git a/leim/quail/cyrillic.el b/leim/quail/cyrillic.el
index 4777bf9ba1f..9199a415a6e 100644
--- a/leim/quail/cyrillic.el
+++ b/leim/quail/cyrillic.el
@@ -1254,37 +1254,30 @@ This keyboard layout is standard for Bulgarian typewriters.
1254 1254
1255The letters $,1(F(B, $,1(<(B, $,1(G(B, $,1(@(B, $,1(;(B, $,1(1(B and $,1(K(B are not affected by Caps Lock. 1255The letters $,1(F(B, $,1(<(B, $,1(G(B, $,1(@(B, $,1(;(B, $,1(1(B and $,1(K(B are not affected by Caps Lock.
1256 1256
1257In addition to original bulgarian typewriter layout, keys \ and | 1257In addition to original Bulgarian typewriter layout, keys \\ and |
1258are transformed into ' and $,1(K(B respectively." 1258are transformed into ' and $,1(K(B respectively. Some keyboards mark these
1259keys as being transformed into ( and ) respectively. For ( and ), use
1260` and ~ respectively. This input method follows XKB."
1259 nil t t t t nil nil nil nil nil t) 1261 nil t t t t nil nil nil nil nil t)
1260 1262
1261;; () 1! 2? 3+ 4" 5% 6= 7: 8/ 9_ 0$,1uV(B -I .V 1263;; () 1! 2? 3+ 4" 5% 6= 7: 8/ 9_ 0$,1uV(B -I .V
1262;; ,$,1(k(B $,1(C(B $,1(5(B $,1(8(B $,1(H(B $,1(I(B $,1(:(B $,1(A(B $,1(4(B $,1(7(B $,1(F(B ;,A'(B 1264;; ,$,1(k(B $,1(C(B $,1(5(B $,1(8(B $,1(H(B $,1(I(B $,1(:(B $,1(A(B $,1(4(B $,1(7(B $,1(F(B ;,A'(B
1263;; $,1(l(B $,1(O(B $,1(0(B $,1(>(B $,1(6(B $,1(3(B $,1(B(B $,1(=(B $,1(2(B $,1(<(B $,1(G(B '$,1(K(B 1265;; $,1(L(B $,1(O(B $,1(0(B $,1(>(B $,1(6(B $,1(3(B $,1(B(B $,1(=(B $,1(2(B $,1(<(B $,1(G(B '$,1(K(B
1264;; $,1(N(B $,1(9(B $,1(J(B $,1(M(B $,1(D(B $,1(E(B $,1(?(B $,1(@(B $,1(;(B $,1(1(B 1266;; $,1(N(B $,1(9(B $,1(J(B $,1(M(B $,1(D(B $,1(E(B $,1(?(B $,1(@(B $,1(;(B $,1(1(B
1265 1267
1266(quail-define-rules 1268(quail-define-rules
1267 1269
1268 ("1" ?1) ("!" ?!) 1270 ("1" ?1) ("!" ?!)
1269 ("2" ?2) 1271 ("2" ?2) ("@" ??)
1270 ("@" ??) 1272 ("3" ?3) ("#" ?+)
1271 ("3" ?3) 1273 ("4" ?4) ("$" ?\")
1272 ("#" ?+)
1273 ("4" ?4)
1274 ("$" ?\")
1275 ("5" ?5) ("%" ?%) 1274 ("5" ?5) ("%" ?%)
1276 ("6" ?6) 1275 ("6" ?6) ("^" ?=)
1277 ("^" ?=) 1276 ("7" ?7) ("&" ?:)
1278 ("7" ?7) 1277 ("8" ?8) ("*" ?/)
1279 ("&" ?:) 1278 ("9" ?9) ("(" ?_)
1280 ("8" ?8) 1279 ("0" ?0) (")" ?$,1uV(B)
1281 ("*" ?/) 1280 ("-" ?-) ("_" ?I)
1282 ("9" ?9)
1283 ("(" ?_)
1284 ("0" ?0)
1285 (")" ?$,1uV(B)
1286 ("-" ?-)
1287 ("_" ?I)
1288 ("=" ?.) ("+" ?V) 1281 ("=" ?.) ("+" ?V)
1289 1282
1290 ("q" ?,) ("Q" ?$,1(k(B) 1283 ("q" ?,) ("Q" ?$,1(k(B)
@@ -1298,8 +1291,7 @@ are transformed into ' and $,1(K(B respectively."
1298 ("o" ?$,1(T(B) ("O" ?$,1(4(B) 1291 ("o" ?$,1(T(B) ("O" ?$,1(4(B)
1299 ("p" ?$,1(W(B) ("P" ?$,1(7(B) 1292 ("p" ?$,1(W(B) ("P" ?$,1(7(B)
1300 ("[" ?$,1(f(B) ("{" ?$,1(F(B) 1293 ("[" ?$,1(f(B) ("{" ?$,1(F(B)
1301 ("]" ?\;) 1294 ("]" ?\;) ("}" ?,A'(B)
1302 ("}" ?,A'(B) ;; not in XKB's bg
1303 1295
1304 ("a" ?$,1(l(B) ("A" ?$,1(L(B) 1296 ("a" ?$,1(l(B) ("A" ?$,1(L(B)
1305 ("s" ?$,1(o(B) ("S" ?$,1(O(B) 1297 ("s" ?$,1(o(B) ("S" ?$,1(O(B)
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 3e66cba3563..6ea0e8be97a 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,8 +1,19 @@
12004-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * emacsclient.c (main): Don't use the hostname in the socket name.
4 Look for relative socket names in the /tmp dir rather than in cwd.
5
12004-01-24 Richard M. Stallman <rms@gnu.org> 62004-01-24 Richard M. Stallman <rms@gnu.org>
2 7
3 * emacsclient.c (main): Restore errno from saved_errno, 8 * emacsclient.c (main): Restore errno from saved_errno,
4 so the error message comes from socket_status. 9 so the error message comes from socket_status.
5 10
112004-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
12
13 * emacsclient.c (main): Stop if socket name too long.
14 Only try su-fallback if the socket name was not explicit.
15 Check socket name length in su-fallback case as well.
16
62004-01-08 Andreas Schwab <schwab@suse.de> 172004-01-08 Andreas Schwab <schwab@suse.de>
7 18
8 * emacsclient.c (main): Save errno from socket_status. 19 * emacsclient.c (main): Save errno from socket_status.
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index d70be8c7491..0f42f096643 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -382,8 +382,6 @@ main (argc, argv)
382 int argc; 382 int argc;
383 char **argv; 383 char **argv;
384{ 384{
385 char *system_name;
386 int system_name_length;
387 int s, i, needlf = 0; 385 int s, i, needlf = 0;
388 FILE *out, *in; 386 FILE *out, *in;
389 struct sockaddr_un server; 387 struct sockaddr_un server;
@@ -418,39 +416,24 @@ main (argc, argv)
418 server.sun_family = AF_UNIX; 416 server.sun_family = AF_UNIX;
419 417
420 { 418 {
421 char *dot;
422 system_name_length = 32;
423
424 while (1)
425 {
426 system_name = (char *) xmalloc (system_name_length + 1);
427
428 /* system_name must be null-terminated string. */
429 system_name[system_name_length] = '\0';
430
431 if (gethostname (system_name, system_name_length) == 0)
432 break;
433
434 free (system_name);
435 system_name_length *= 2;
436 }
437
438 /* We always use the non-dotted host name, for simplicity. */
439 dot = index (system_name, '.');
440 if (dot)
441 *dot = '\0';
442 }
443
444 {
445 int sock_status = 0; 419 int sock_status = 0;
446 int default_sock = !socket_name; 420 int default_sock = !socket_name;
447 int saved_errno = 0; 421 int saved_errno = 0;
448 422
449 if (default_sock) 423 char *server_name = "server";
424
425 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
426 { /* socket_name is a file name component. */
427 server_name = socket_name;
428 socket_name = NULL;
429 default_sock = 1; /* Try both UIDs. */
430 }
431
432 if (default_sock)
450 { 433 {
451 socket_name = alloca (system_name_length + 100); 434 socket_name = alloca (100 + strlen (server_name));
452 sprintf (socket_name, "/tmp/emacs%d-%s/server", 435 sprintf (socket_name, "/tmp/emacs%d/%s",
453 (int) geteuid (), system_name); 436 (int) geteuid (), server_name);
454 } 437 }
455 438
456 if (strlen (socket_name) < sizeof (server.sun_path)) 439 if (strlen (socket_name) < sizeof (server.sun_path))
@@ -484,8 +467,9 @@ main (argc, argv)
484 if (pw && (pw->pw_uid != geteuid ())) 467 if (pw && (pw->pw_uid != geteuid ()))
485 { 468 {
486 /* We're running under su, apparently. */ 469 /* We're running under su, apparently. */
487 sprintf (socket_name, "/tmp/emacs%d-%s/server", 470 socket_name = alloca (100 + strlen (server_name));
488 (int) pw->pw_uid, system_name); 471 sprintf (socket_name, "/tmp/emacs%d/%s",
472 (int) pw->pw_uid, server_name);
489 473
490 if (strlen (socket_name) < sizeof (server.sun_path)) 474 if (strlen (socket_name) < sizeof (server.sun_path))
491 strcpy (server.sun_path, socket_name); 475 strcpy (server.sun_path, socket_name);
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 1f5aece0510..4458f635d2f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,12 +1,162 @@
12004-02-02 David Kastrup <dak@gnu.org>
2
3 * replace.el (perform-replace): Allow 'literal argument in
4 regexp-flag to indicate literal replacement.
5 (query-replace-regexp-eval): Use it.
6
72004-02-01 Andreas Schwab <schwab@suse.de>
8
9 * progmodes/executable.el (executable-command-find-posix-p): Doc
10 fix.
11
122004-02-01 Stephen Eglen <stephen@gnu.org>
13
14 * info-look.el: Add support for maxima-mode. Update commentary
15 because info-lookup-symbol is now bound to C-h S.
16
172004-01-31 Luc Teirlinck <teirllm@auburn.edu>
18
19 * simple.el (edit-and-eval-command): Bind print-level and
20 minibuffer-history-sexp-flag around call to read-from-minibuffer.
21 Correct initial position in command-history.
22
232004-01-30 Luc Teirlinck <teirllm@auburn.edu>
24
25 * files.el (read-directory-name): Adapt the docstring to recent
26 change in Fread_file_name.
27
282004-01-30 Jonathan Yavner <jyavner@member.fsf.org>
29
30 * ses.el (ses-print-cell): If print format too wide for column
31 width, truncate decimal places if that helps to avoid "#####" fill.
32 * ses.el (ses-initial-column-width): Revert previous change.
33
342004-01-29 Stefan Monnier <monnier@iro.umontreal.ca>
35
36 * jit-lock.el (jit-lock-context-time, jit-lock-context-timer): New var.
37 (with-buffer-unmodified, with-buffer-prepared-for-jit-lock):
38 Add edebug info.
39 (jit-lock-mode): Setup/cancel the new timer.
40 (jit-lock-context-fontify): New fun. Extracted from
41 context fontification code of jit-lock-stealth-fontify.
42 (jit-lock-stealth-fontify): Don't do context fontification any more.
43
44 * jit-lock.el (jit-lock-stealth-fontify): Allow quit.
45 (jit-lock-fontify-now): Handle the `quit' case.
46 (jit-lock-contextually): Rename from jit-lock-defer-contextually.
47
482004-01-29 Jari Aalto <jari.aalto@poboxes.com>
49
50 * progmodes/executable.el (executable-command-find-posix-p):
51 New. Check if find handles arguments Posix-style.
52
53 * progmodes/grep.el (grep-compute-defaults):
54 Use executable-command-find-posix-p.
55 (grep-find): Check `grep-find-command'.
56
57 * filecache.el (file-cache-find-posix-p): Delete.
58 (file-cache-add-directory-using-find):
59 Use `executable-command-find-posix-p'.
60
612004-01-29 Dave Love <fx@gnu.org>
62
63 * emacs-lisp/lisp.el (beginning-of-defun-raw, end-of-defun):
64 Iterate the hook function if arg is given.
65 (mark-defun, narrow-to-defun): Change order of finding the limits.
66
67 * emacs-lisp/bytecomp.el (byte-compile-compatibility): Doc fix.
68 (byte-compile-format-warn): New.
69 (byte-compile-callargs-warn): Use it.
70 (Format, message, error): Add byte-compile-format-like property.
71 (byte-compile-maybe-guarded): New.
72 (byte-compile-if, byte-compile-cond): Use it.
73 (byte-compile-lambda): Compile interactive forms,
74 just to make warnings about them.
75
762004-01-29 Jonathan Yavner <jyavner@member.fsf.org>
77
78 * ses.el (ses-initial-column-width): Increase to 14, so it will
79 work well with the default printer of "%.7g" for extreme values
80 like "-1.234567e+07".
81
822004-01-29 Kenichi Handa <handa@m17n.org>
83
84 * term/x-win.el (x-selection-value): Optimize for ASCII only case.
85
862004-01-28 Peter 'Luna' Runestig <peter@runestig.com>
87
88 * dos-w32.el: Added support for the `default-printer-name' function.
89
902004-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
91
92 * server.el (server-socket-name): Don't use the hostname in the
93 socket name since /tmp is local to the host anyway.
94
95 * emacs-lisp/easy-mmode.el (easy-mmode-define-navigation): Use a more
96 robust check of widening and fix var-naming.
97
982004-01-27 Eli Tziperman <eli@deas.harvard.edu>
99
100 * rmail-spam-filter.el: Change rmail-spam-filter- or spam-filter-
101 or rmail-spam- to rsf- in all function and variable names.
102 (rsf-min-region-to-spam-list): New variable.
103 (rsf-bbdb-auto-delete-spam-entries): Rename from
104 rmail-bbdb-auto-delete-spam-bbdb-entries. The cc: field is
105 scanned together with the recipients field for spam testing; Don't
106 delete spam message if rmail-delete-after-output is non-nil;
107 (rsf-check-field): New function, extracted from code in
108 rmail-spam-filter to ease addition of header fields like
109 content-type:;
110 (message-content-type): New variable. The content-type: field was
111 added also in defcustom of rsf-definitions-alist;
112 (rmail-spam-filter): Replace repeated test code for header fields
113 by calls to check-field; change the call to
114 rmail-output-to-rmail-file such that rmail-current-message stays
115 the same to avoid wrong deletion of unseen flags.
116 (rmail-use-spam-filter): Add autoload cookie.
117
1182004-01-27 Jari Aalto <jari.aalto@poboxes.com>
119
120 * filecache.el (file-cache-find-posix-p): New function. Detect Cygwin.
121 (file-cache-add-directory-using-find): Add Cygwin support.
122 (file-cache-find-command-posix-flag): New user variable.
123
124 * filecache.el (file-cache-add-directory): Check for
125 directories an remove them from dir-files.
126
1272004-01-27 Richard M. Stallman <rms@gnu.org>
128
129 * man.el (Man-fontify-manpage): Clean up message.
130
1312004-01-27 Kenichi Handa <handa@m17n.org>
132
133 * textmodes/paragraphs.el (sentence-end-without-space): New variable.
134 (sentence-end): Define using sentence-end-without-space.
135
136 * textmodes/fill.el (fill-delete-newlines): Don't add a space if
137 a sentence ends with one of a character in sentence-end-without-space.
138
1392004-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
140
141 * font-lock.el (font-lock): Add jit-lock as explicit group member.
142 (jit-lock): Group declaration moved to jit-lock.el.
143 (toplevel): Don't explicitly require jit-lock, since it's autoloaded
144 when necessary.
145
146 * jit-lock.el (jit-lock): Move group declaration from font-lock.el.
147 (jit-lock-context-unfontify-pos): Rename from
148 jit-lock-first-unfontify-pos.
149 (jit-lock-defer-buffers): Rename from jit-lock-buffers.
150
12004-01-25 Glenn Morris <gmorris@ast.cam.ac.uk> 1512004-01-25 Glenn Morris <gmorris@ast.cam.ac.uk>
2 152
3 * progmodes/fortran.el (fortran-break-before-delimiters): Doc fix. 153 * progmodes/fortran.el (fortran-break-before-delimiters): Doc fix.
4 (fortran-break-delimiters-re, fortran-no-break-re): New defconsts. 154 (fortran-break-delimiters-re, fortran-no-break-re): New consts.
5 (fortran-fill): When filling a string, adjust re-search-backward 155 (fortran-fill): When filling a string, adjust re-search-backward
6 argument for special case of string just on fill-column. 156 argument for special case of string just on fill-column.
7 When filling non-string, allow one extra char if 157 When filling non-string, allow one extra char if
8 fortran-break-before-delimiters is non-nil. Suggested by 158 fortran-break-before-delimiters is non-nil.
9 Michael Hagemann <michael.hagemann@unibas.ch>. 159 Suggested by Michael Hagemann <michael.hagemann@unibas.ch>.
10 Use fortran-break-delimiters-re and fortran-no-break-re to 160 Use fortran-break-delimiters-re and fortran-no-break-re to
11 correctly handle cases such as "**". 161 correctly handle cases such as "**".
12 162
@@ -41,16 +191,16 @@
41 191
422004-01-22 Kenichi Handa <handa@m17n.org> 1922004-01-22 Kenichi Handa <handa@m17n.org>
43 193
44 * language/cyrillic.el (ccl-encode-windows-1251-font): Rearrange 194 * language/cyrillic.el (ccl-encode-windows-1251-font): Rearrange code
45 code point (register r1) only for charset mule-unicode-0100-24ff. 195 point (register r1) only for charset mule-unicode-0100-24ff.
46 196
472004-01-21 Markus Rost <rost@mathematik.uni-bielefeld.de> 1972004-01-21 Markus Rost <rost@mathematik.uni-bielefeld.de>
48 198
49 * mail/rmail.el (rmail-convert-to-babyl-format): Avoid deleting 199 * mail/rmail.el (rmail-convert-to-babyl-format): Avoid deleting
50 trailing white space and ensure a final newline. 200 trailing white space and ensure a final newline.
51 201
52 * mail/rmail-spam-filter.el (rmail-use-spam-filter): Add autoload 202 * mail/rmail-spam-filter.el (rmail-use-spam-filter):
53 cookie. 203 Add autoload cookie.
54 204
552004-01-21 Benjamin Rutt <brutt@bloomington.in.us> 2052004-01-21 Benjamin Rutt <brutt@bloomington.in.us>
56 206
diff --git a/lisp/dos-w32.el b/lisp/dos-w32.el
index c1c189166bb..d7b411fab3f 100644
--- a/lisp/dos-w32.el
+++ b/lisp/dos-w32.el
@@ -378,7 +378,8 @@ indicates a specific program should be invoked."
378 (printer (or (and (boundp 'dos-printer) 378 (printer (or (and (boundp 'dos-printer)
379 (stringp (symbol-value 'dos-printer)) 379 (stringp (symbol-value 'dos-printer))
380 (symbol-value 'dos-printer)) 380 (symbol-value 'dos-printer))
381 printer-name))) 381 printer-name
382 (default-printer-name))))
382 (or (eq coding-system-for-write 'no-conversion) 383 (or (eq coding-system-for-write 'no-conversion)
383 (setq coding-system-for-write 384 (setq coding-system-for-write
384 (aref eol-type 1))) ; force conversion to DOS EOLs 385 (aref eol-type 1))) ; force conversion to DOS EOLs
@@ -411,7 +412,8 @@ indicates a specific program should be invoked."
411 (let ((printer (or (and (boundp 'dos-ps-printer) 412 (let ((printer (or (and (boundp 'dos-ps-printer)
412 (stringp (symbol-value 'dos-ps-printer)) 413 (stringp (symbol-value 'dos-ps-printer))
413 (symbol-value 'dos-ps-printer)) 414 (symbol-value 'dos-ps-printer))
414 ps-printer-name))) 415 ps-printer-name
416 (default-printer-name))))
415 (direct-print-region-helper printer start end lpr-prog 417 (direct-print-region-helper printer start end lpr-prog
416 delete-text buf display rest))) 418 delete-text buf display rest)))
417 419
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 24d2329b426..6f7e838daf0 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -10,7 +10,7 @@
10 10
11;;; This version incorporates changes up to version 2.10 of the 11;;; This version incorporates changes up to version 2.10 of the
12;;; Zawinski-Furuseth compiler. 12;;; Zawinski-Furuseth compiler.
13(defconst byte-compile-version "$Revision: 2.141 $") 13(defconst byte-compile-version "$Revision: 2.142 $")
14 14
15;; This file is part of GNU Emacs. 15;; This file is part of GNU Emacs.
16 16
@@ -251,7 +251,9 @@ if you change this variable."
251 :type 'boolean) 251 :type 'boolean)
252 252
253(defcustom byte-compile-compatibility nil 253(defcustom byte-compile-compatibility nil
254 "*Non-nil means generate output that can run in Emacs 18." 254 "*Non-nil means generate output that can run in Emacs 18.
255This only means that it can run in principle, if it doesn't require
256facilities that have been added more recently."
255 :group 'bytecomp 257 :group 'bytecomp
256 :type 'boolean) 258 :type 'boolean)
257 259
@@ -444,6 +446,11 @@ Each element looks like (FUNCTIONNAME . DEFINITION). It is
444Used for warnings when the function is not known to be defined or is later 446Used for warnings when the function is not known to be defined or is later
445defined with incorrect args.") 447defined with incorrect args.")
446 448
449(defvar byte-compile-noruntime-functions nil
450 "Alist of functions called that may not be defined when the compiled code is run.
451Used for warnings about calling a function that is defined during compilation
452but won't necessarily be defined when the compiled file is loaded.")
453
447(defvar byte-compile-tag-number 0) 454(defvar byte-compile-tag-number 0)
448(defvar byte-compile-output nil 455(defvar byte-compile-output nil
449 "Alist describing contents to put in byte code string. 456 "Alist describing contents to put in byte code string.
@@ -776,7 +783,7 @@ otherwise pop it")
776 783
777(defun byte-compile-eval (form) 784(defun byte-compile-eval (form)
778 "Eval FORM and mark the functions defined therein. 785 "Eval FORM and mark the functions defined therein.
779Each function's symbol gets marked with the `byte-compile-noruntime' property." 786Each function's symbol gets added to `byte-compile-noruntime-functions'."
780 (let ((hist-orig load-history) 787 (let ((hist-orig load-history)
781 (hist-nil-orig current-load-list)) 788 (hist-nil-orig current-load-list))
782 (prog1 (eval form) 789 (prog1 (eval form)
@@ -794,17 +801,17 @@ Each function's symbol gets marked with the `byte-compile-noruntime' property."
794 (cond 801 (cond
795 ((symbolp s) 802 ((symbolp s)
796 (unless (memq s old-autoloads) 803 (unless (memq s old-autoloads)
797 (put s 'byte-compile-noruntime t))) 804 (push s byte-compile-noruntime-functions)))
798 ((and (consp s) (eq t (car s))) 805 ((and (consp s) (eq t (car s)))
799 (push (cdr s) old-autoloads)) 806 (push (cdr s) old-autoloads))
800 ((and (consp s) (eq 'autoload (car s))) 807 ((and (consp s) (eq 'autoload (car s)))
801 (put (cdr s) 'byte-compile-noruntime t))))))) 808 (push (cdr s) byte-compile-noruntime-functions)))))))
802 ;; Go through current-load-list for the locally defined funs. 809 ;; Go through current-load-list for the locally defined funs.
803 (let (old-autoloads) 810 (let (old-autoloads)
804 (while (and hist-nil-new (not (eq hist-nil-new hist-nil-orig))) 811 (while (and hist-nil-new (not (eq hist-nil-new hist-nil-orig)))
805 (let ((s (pop hist-nil-new))) 812 (let ((s (pop hist-nil-new)))
806 (when (and (symbolp s) (not (memq s old-autoloads))) 813 (when (and (symbolp s) (not (memq s old-autoloads)))
807 (put s 'byte-compile-noruntime t)) 814 (push s byte-compile-noruntime-functions))
808 (when (and (consp s) (eq t (car s))) 815 (when (and (consp s) (eq t (car s)))
809 (push (cdr s) old-autoloads)))))))))) 816 (push (cdr s) old-autoloads))))))))))
810 817
@@ -1170,10 +1177,11 @@ Each function's symbol gets marked with the `byte-compile-noruntime' property."
1170 "requires" 1177 "requires"
1171 "accepts only") 1178 "accepts only")
1172 (byte-compile-arglist-signature-string sig)))) 1179 (byte-compile-arglist-signature-string sig))))
1180 (byte-compile-format-warn form)
1173 ;; Check to see if the function will be available at runtime 1181 ;; Check to see if the function will be available at runtime
1174 ;; and/or remember its arity if it's unknown. 1182 ;; and/or remember its arity if it's unknown.
1175 (or (and (or sig (fboundp (car form))) ; might be a subr or autoload. 1183 (or (and (or sig (fboundp (car form))) ; might be a subr or autoload.
1176 (not (get (car form) 'byte-compile-noruntime))) 1184 (not (memq (car form) byte-compile-noruntime-functions)))
1177 (eq (car form) byte-compile-current-form) ; ## this doesn't work 1185 (eq (car form) byte-compile-current-form) ; ## this doesn't work
1178 ; with recursion. 1186 ; with recursion.
1179 ;; It's a currently-undefined function. 1187 ;; It's a currently-undefined function.
@@ -1187,6 +1195,32 @@ Each function's symbol gets marked with the `byte-compile-noruntime' property."
1187 (cons (list (car form) n) 1195 (cons (list (car form) n)
1188 byte-compile-unresolved-functions))))))) 1196 byte-compile-unresolved-functions)))))))
1189 1197
1198(defun byte-compile-format-warn (form)
1199 "Warn if FORM is `format'-like with inconsistent args.
1200Applies if head of FORM is a symbol with non-nil property
1201`byte-compile-format-like' and first arg is a constant string.
1202Then check the number of format fields matches the number of
1203extra args."
1204 (when (and (symbolp (car form))
1205 (stringp (nth 1 form))
1206 (get (car form) 'byte-compile-format-like))
1207 (let ((nfields (with-temp-buffer
1208 (insert (nth 1 form))
1209 (goto-char 1)
1210 (let ((n 0))
1211 (while (re-search-forward "%." nil t)
1212 (unless (eq ?% (char-after (1+ (match-beginning 0))))
1213 (setq n (1+ n))))
1214 n)))
1215 (nargs (- (length form) 2)))
1216 (unless (= nargs nfields)
1217 (byte-compile-warn
1218 "`%s' called with %d args to fill %d format field(s)" (car form)
1219 nargs nfields)))))
1220
1221(dolist (elt '(format message error))
1222 (put elt 'byte-compile-format-like t))
1223
1190;; Warn if the function or macro is being redefined with a different 1224;; Warn if the function or macro is being redefined with a different
1191;; number of arguments. 1225;; number of arguments.
1192(defun byte-compile-arglist-warn (form macrop) 1226(defun byte-compile-arglist-warn (form macrop)
@@ -1254,7 +1288,7 @@ Each function's symbol gets marked with the `byte-compile-noruntime' property."
1254 (let ((func (car-safe form))) 1288 (let ((func (car-safe form)))
1255 (if (and byte-compile-cl-functions 1289 (if (and byte-compile-cl-functions
1256 (memq func byte-compile-cl-functions) 1290 (memq func byte-compile-cl-functions)
1257 ;; Aliases which won't have been expended at this point. 1291 ;; Aliases which won't have been expanded at this point.
1258 ;; These aren't all aliases of subrs, so not trivial to 1292 ;; These aren't all aliases of subrs, so not trivial to
1259 ;; avoid hardwiring the list. 1293 ;; avoid hardwiring the list.
1260 (not (memq func 1294 (not (memq func
@@ -2453,17 +2487,19 @@ If FORM is a lambda or a macro, byte-compile it as a function."
2453 (if (cdr (cdr int)) 2487 (if (cdr (cdr int))
2454 (byte-compile-warn "malformed interactive spec: %s" 2488 (byte-compile-warn "malformed interactive spec: %s"
2455 (prin1-to-string int))) 2489 (prin1-to-string int)))
2456 ;; If the interactive spec is a call to `list', 2490 ;; If the interactive spec is a call to `list', don't
2457 ;; don't compile it, because `call-interactively' 2491 ;; compile it, because `call-interactively' looks at the
2458 ;; looks at the args of `list'. 2492 ;; args of `list'. Actually, compile it to get warnings,
2493 ;; but don't use the result.
2459 (let ((form (nth 1 int))) 2494 (let ((form (nth 1 int)))
2460 (while (memq (car-safe form) '(let let* progn save-excursion)) 2495 (while (memq (car-safe form) '(let let* progn save-excursion))
2461 (while (consp (cdr form)) 2496 (while (consp (cdr form))
2462 (setq form (cdr form))) 2497 (setq form (cdr form)))
2463 (setq form (car form))) 2498 (setq form (car form)))
2464 (or (eq (car-safe form) 'list) 2499 (if (eq (car-safe form) 'list)
2465 (setq int (list 'interactive 2500 (byte-compile-top-level (nth 1 int))
2466 (byte-compile-top-level (nth 1 int))))))) 2501 (setq int (list 'interactive
2502 (byte-compile-top-level (nth 1 int)))))))
2467 ((cdr int) 2503 ((cdr int)
2468 (byte-compile-warn "malformed interactive spec: %s" 2504 (byte-compile-warn "malformed interactive spec: %s"
2469 (prin1-to-string int))))) 2505 (prin1-to-string int)))))
@@ -3265,51 +3301,55 @@ If FORM is a lambda or a macro, byte-compile it as a function."
3265 (if ,discard 'byte-goto-if-nil 'byte-goto-if-nil-else-pop)) 3301 (if ,discard 'byte-goto-if-nil 'byte-goto-if-nil-else-pop))
3266 ,tag)) 3302 ,tag))
3267 3303
3304(defmacro byte-compile-maybe-guarded (condition &rest body)
3305 "Execute forms in BODY, potentially guarded by CONDITION.
3306CONDITION is the test in an `if' form or in a `cond' clause.
3307BODY is to compile the first arm of the if or the body of the
3308cond clause. If CONDITION is of the form `(foundp 'foo)'
3309or `(boundp 'foo)', the relevant warnings from BODY about foo
3310being undefined will be suppressed."
3311 (declare (indent 1) (debug t))
3312 `(let* ((fbound
3313 (if (eq 'fboundp (car-safe ,condition))
3314 (and (eq 'quote (car-safe (nth 1 ,condition)))
3315 ;; Ignore if the symbol is already on the
3316 ;; unresolved list.
3317 (not (assq (nth 1 (nth 1 ,condition)) ; the relevant symbol
3318 byte-compile-unresolved-functions))
3319 (nth 1 (nth 1 ,condition)))))
3320 (bound (if (or (eq 'boundp (car-safe ,condition))
3321 (eq 'default-boundp (car-safe ,condition)))
3322 (and (eq 'quote (car-safe (nth 1 ,condition)))
3323 (nth 1 (nth 1 ,condition)))))
3324 ;; Maybe add to the bound list.
3325 (byte-compile-bound-variables
3326 (if bound
3327 (cons bound byte-compile-bound-variables)
3328 byte-compile-bound-variables)))
3329 (progn ,@body)
3330 ;; Maybe remove the function symbol from the unresolved list.
3331 (if fbound
3332 (setq byte-compile-unresolved-functions
3333 (delq (assq fbound byte-compile-unresolved-functions)
3334 byte-compile-unresolved-functions)))))
3335
3268(defun byte-compile-if (form) 3336(defun byte-compile-if (form)
3269 (byte-compile-form (car (cdr form))) 3337 (byte-compile-form (car (cdr form)))
3270 ;; Check whether we have `(if (fboundp ...' or `(if (boundp ...' 3338 ;; Check whether we have `(if (fboundp ...' or `(if (boundp ...'
3271 ;; and avoid warnings about the relevent symbols in the consequent. 3339 ;; and avoid warnings about the relevent symbols in the consequent.
3272 (let* ((clause (nth 1 form)) 3340 (let ((clause (nth 1 form))
3273 (fbound (if (eq 'fboundp (car-safe clause)) 3341 (donetag (byte-compile-make-tag)))
3274 (and (eq 'quote (car-safe (nth 1 clause)))
3275 ;; Ignore if the symbol is already on the
3276 ;; unresolved list.
3277 (not (assq
3278 (nth 1 (nth 1 clause)) ; the relevant symbol
3279 byte-compile-unresolved-functions))
3280 (nth 1 (nth 1 clause)))))
3281 (bound (if (eq 'boundp (car-safe clause))
3282 (and (eq 'quote (car-safe (nth 1 clause)))
3283 (nth 1 (nth 1 clause)))))
3284 (donetag (byte-compile-make-tag)))
3285 (if (null (nthcdr 3 form)) 3342 (if (null (nthcdr 3 form))
3286 ;; No else-forms 3343 ;; No else-forms
3287 (progn 3344 (progn
3288 (byte-compile-goto-if nil for-effect donetag) 3345 (byte-compile-goto-if nil for-effect donetag)
3289 ;; Maybe add to the bound list. 3346 (byte-compile-maybe-guarded clause
3290 (let ((byte-compile-bound-variables
3291 (if bound
3292 (cons bound byte-compile-bound-variables)
3293 byte-compile-bound-variables)))
3294 (byte-compile-form (nth 2 form) for-effect)) 3347 (byte-compile-form (nth 2 form) for-effect))
3295 ;; Maybe remove the function symbol from the unresolved list.
3296 (if fbound
3297 (setq byte-compile-unresolved-functions
3298 (delq (assq fbound byte-compile-unresolved-functions)
3299 byte-compile-unresolved-functions)))
3300 (byte-compile-out-tag donetag)) 3348 (byte-compile-out-tag donetag))
3301 (let ((elsetag (byte-compile-make-tag))) 3349 (let ((elsetag (byte-compile-make-tag)))
3302 (byte-compile-goto 'byte-goto-if-nil elsetag) 3350 (byte-compile-goto 'byte-goto-if-nil elsetag)
3303 ;; As above for the first form. 3351 (byte-compile-maybe-guarded clause
3304 (let ((byte-compile-bound-variables 3352 (byte-compile-form (nth 2 form) for-effect))
3305 (if bound
3306 (cons bound byte-compile-bound-variables)
3307 byte-compile-bound-variables)))
3308 (byte-compile-form (nth 2 form) for-effect))
3309 (if fbound
3310 (setq byte-compile-unresolved-functions
3311 (delq (assq fbound byte-compile-unresolved-functions)
3312 byte-compile-unresolved-functions)))
3313 (byte-compile-goto 'byte-goto donetag) 3353 (byte-compile-goto 'byte-goto donetag)
3314 (byte-compile-out-tag elsetag) 3354 (byte-compile-out-tag elsetag)
3315 (byte-compile-body (cdr (cdr (cdr form))) for-effect) 3355 (byte-compile-body (cdr (cdr (cdr form))) for-effect)
@@ -3332,14 +3372,16 @@ If FORM is a lambda or a macro, byte-compile it as a function."
3332 (if (null (cdr clause)) 3372 (if (null (cdr clause))
3333 ;; First clause is a singleton. 3373 ;; First clause is a singleton.
3334 (byte-compile-goto-if t for-effect donetag) 3374 (byte-compile-goto-if t for-effect donetag)
3335 (setq nexttag (byte-compile-make-tag)) 3375 (setq nexttag (byte-compile-make-tag))
3336 (byte-compile-goto 'byte-goto-if-nil nexttag) 3376 (byte-compile-goto 'byte-goto-if-nil nexttag)
3337 (byte-compile-body (cdr clause) for-effect) 3377 (byte-compile-maybe-guarded (car clause)
3338 (byte-compile-goto 'byte-goto donetag) 3378 (byte-compile-body (cdr clause) for-effect))
3339 (byte-compile-out-tag nexttag))))) 3379 (byte-compile-goto 'byte-goto donetag)
3380 (byte-compile-out-tag nexttag)))))
3340 ;; Last clause 3381 ;; Last clause
3341 (and (cdr clause) (not (eq (car clause) t)) 3382 (and (cdr clause) (not (eq (car clause) t))
3342 (progn (byte-compile-form (car clause)) 3383 (progn (byte-compile-maybe-guarded (car clause)
3384 (byte-compile-form (car clause)))
3343 (byte-compile-goto-if nil for-effect donetag) 3385 (byte-compile-goto-if nil for-effect donetag)
3344 (setq clause (cdr clause)))) 3386 (setq clause (cdr clause))))
3345 (byte-compile-body-do-effect clause) 3387 (byte-compile-body-do-effect clause)
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index 01e3e0af5ac..2439fdd4de6 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -1,6 +1,6 @@
1;;; easy-mmode.el --- easy definition for major and minor modes 1;;; easy-mmode.el --- easy definition for major and minor modes
2 2
3;; Copyright (C) 1997, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 3;; Copyright (C) 1997,2000,01,02,03,2004 Free Software Foundation, Inc.
4 4
5;; Author: Georges Brun-Cottan <Georges.Brun-Cottan@inria.fr> 5;; Author: Georges Brun-Cottan <Georges.Brun-Cottan@inria.fr>
6;; Maintainer: Stefan Monnier <monnier@gnu.org> 6;; Maintainer: Stefan Monnier <monnier@gnu.org>
@@ -433,14 +433,13 @@ found, do widen first and then call NARROWFUN with no args after moving."
433 (let* ((base-name (symbol-name base)) 433 (let* ((base-name (symbol-name base))
434 (prev-sym (intern (concat base-name "-prev"))) 434 (prev-sym (intern (concat base-name "-prev")))
435 (next-sym (intern (concat base-name "-next"))) 435 (next-sym (intern (concat base-name "-next")))
436 (check-narrow-maybe (when narrowfun 436 (check-narrow-maybe
437 '(setq was-narrowed-p 437 (when narrowfun
438 (prog1 (or (/= (point-min) 1) 438 '(setq was-narrowed
439 (/= (point-max) 439 (prog1 (or (< (- (point-max) (point-min)) (buffer-size)))
440 (1+ (buffer-size)))) 440 (widen)))))
441 (widen)))))
442 (re-narrow-maybe (when narrowfun 441 (re-narrow-maybe (when narrowfun
443 `(when was-narrowed-p (,narrowfun))))) 442 `(when was-narrowed (,narrowfun)))))
444 (unless name (setq name base-name)) 443 (unless name (setq name base-name))
445 `(progn 444 `(progn
446 (add-to-list 'debug-ignored-errors 445 (add-to-list 'debug-ignored-errors
@@ -451,7 +450,7 @@ found, do widen first and then call NARROWFUN with no args after moving."
451 (unless count (setq count 1)) 450 (unless count (setq count 1))
452 (if (< count 0) (,prev-sym (- count)) 451 (if (< count 0) (,prev-sym (- count))
453 (if (looking-at ,re) (setq count (1+ count))) 452 (if (looking-at ,re) (setq count (1+ count)))
454 (let (was-narrowed-p) 453 (let (was-narrowed)
455 ,check-narrow-maybe 454 ,check-narrow-maybe
456 (if (not (re-search-forward ,re nil t count)) 455 (if (not (re-search-forward ,re nil t count))
457 (if (looking-at ,re) 456 (if (looking-at ,re)
@@ -472,7 +471,7 @@ found, do widen first and then call NARROWFUN with no args after moving."
472 (interactive) 471 (interactive)
473 (unless count (setq count 1)) 472 (unless count (setq count 1))
474 (if (< count 0) (,next-sym (- count)) 473 (if (< count 0) (,next-sym (- count))
475 (let (was-narrowed-p) 474 (let (was-narrowed)
476 ,check-narrow-maybe 475 ,check-narrow-maybe
477 (unless (re-search-backward ,re nil t count) 476 (unless (re-search-backward ,re nil t count)
478 (error "No previous %s" ,name)) 477 (error "No previous %s" ,name))
diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el
index 7f059d3f99f..4d90abd9f4e 100644
--- a/lisp/emacs-lisp/lisp.el
+++ b/lisp/emacs-lisp/lisp.el
@@ -188,7 +188,8 @@ If variable `beginning-of-defun-function' is non-nil, its value
188is called as a function to find the defun's beginning." 188is called as a function to find the defun's beginning."
189 (interactive "p") 189 (interactive "p")
190 (if beginning-of-defun-function 190 (if beginning-of-defun-function
191 (funcall beginning-of-defun-function) 191 (dotimes (i (or arg 1))
192 (funcall beginning-of-defun-function))
192 (and arg (< arg 0) (not (eobp)) (forward-char 1)) 193 (and arg (< arg 0) (not (eobp)) (forward-char 1))
193 (and (re-search-backward (if defun-prompt-regexp 194 (and (re-search-backward (if defun-prompt-regexp
194 (concat (if open-paren-in-column-0-is-defun-start 195 (concat (if open-paren-in-column-0-is-defun-start
@@ -219,7 +220,8 @@ If variable `end-of-defun-function' is non-nil, its value
219is called as a function to find the defun's end." 220is called as a function to find the defun's end."
220 (interactive "p") 221 (interactive "p")
221 (if end-of-defun-function 222 (if end-of-defun-function
222 (funcall end-of-defun-function) 223 (dotimes (i (or arg 1))
224 (funcall end-of-defun-function))
223 (if (or (null arg) (= arg 0)) (setq arg 1)) 225 (if (or (null arg) (= arg 0)) (setq arg 1))
224 (let ((first t)) 226 (let ((first t))
225 (while (and (> arg 0) (< (point) (point-max))) 227 (while (and (> arg 0) (< (point) (point-max)))
@@ -267,10 +269,14 @@ already marked."
267 (end-of-defun) 269 (end-of-defun)
268 (point)))) 270 (point))))
269 (t 271 (t
272 ;; Do it in this order for the sake of languages with nested
273 ;; functions where several can end at the same place as with
274 ;; the offside rule, e.g. Python.
270 (push-mark (point)) 275 (push-mark (point))
271 (end-of-defun)
272 (push-mark (point) nil t)
273 (beginning-of-defun) 276 (beginning-of-defun)
277 (push-mark (point) nil t)
278 (end-of-defun)
279 (exchange-point-and-mark)
274 (re-search-backward "^\n" (- (point) 1) t)))) 280 (re-search-backward "^\n" (- (point) 1) t))))
275 281
276(defun narrow-to-defun (&optional arg) 282(defun narrow-to-defun (&optional arg)
@@ -280,10 +286,13 @@ Optional ARG is ignored."
280 (interactive) 286 (interactive)
281 (save-excursion 287 (save-excursion
282 (widen) 288 (widen)
283 (end-of-defun) 289 ;; Do it in this order for the sake of languages with nested
284 (let ((end (point))) 290 ;; functions where several can end at the same place as with the
285 (beginning-of-defun) 291 ;; offside rule, e.g. Python.
286 (narrow-to-region (point) end)))) 292 (beginning-of-defun)
293 (let ((beg (point)))
294 (end-of-defun)
295 (narrow-to-region beg (point)))))
287 296
288(defun insert-parentheses (arg) 297(defun insert-parentheses (arg)
289 "Enclose following ARG sexps in parentheses. Leave point after open-paren. 298 "Enclose following ARG sexps in parentheses. Leave point after open-paren.
diff --git a/lisp/filecache.el b/lisp/filecache.el
index 71b67af355f..ea8bdaaf232 100644
--- a/lisp/filecache.el
+++ b/lisp/filecache.el
@@ -170,6 +170,19 @@ do not use this variable."
170 :type 'string 170 :type 'string
171 :group 'file-cache) 171 :group 'file-cache)
172 172
173(defcustom file-cache-find-command-posix-flag 'not-defined
174 "*Set to t, if `file-cache-find-command' handles wildcards POSIX style.
175This variable is automatically set to nil or non-nil
176if it has the initial value `not-defined' whenever you first
177call the `file-cache-add-directory-using-find'.
178
179Under Windows operating system where Cygwin is available, this value
180should be t."
181 :type '(choice (const :tag "Yes" t)
182 (const :tag "No" nil)
183 (const :tag "Unknown" not-defined))
184 :group 'file-cache)
185
173(defcustom file-cache-locate-command "locate" 186(defcustom file-cache-locate-command "locate"
174 "*External program used by `file-cache-add-directory-using-locate'." 187 "*External program used by `file-cache-add-directory-using-locate'."
175 :type 'string 188 :type 'string
@@ -267,11 +280,13 @@ be added to the cache."
267 ;; Filter out files we don't want to see 280 ;; Filter out files we don't want to see
268 (mapcar 281 (mapcar
269 '(lambda (file) 282 '(lambda (file)
270 (mapcar 283 (if (file-directory-p file)
271 '(lambda (regexp) 284 (setq dir-files (delq file dir-files))
272 (if (string-match regexp file) 285 (mapcar
273 (setq dir-files (delq file dir-files)))) 286 '(lambda (regexp)
274 file-cache-filter-regexps)) 287 (if (string-match regexp file)
288 (setq dir-files (delq file dir-files))))
289 file-cache-filter-regexps)))
275 dir-files) 290 dir-files)
276 (file-cache-add-file-list dir-files)))) 291 (file-cache-add-file-list dir-files))))
277 292
@@ -322,12 +337,21 @@ in each directory, not to the directory list itself."
322Find is run in DIRECTORY." 337Find is run in DIRECTORY."
323 (interactive "DAdd files under directory: ") 338 (interactive "DAdd files under directory: ")
324 (let ((dir (expand-file-name directory))) 339 (let ((dir (expand-file-name directory)))
340 (if (eq file-cache-find-command-posix-flag 'not-defined)
341 (setq file-cache-find-command-posix-flag
342 (executable-command-find-posix-p file-cache-find-command)))
325 (set-buffer (get-buffer-create file-cache-buffer)) 343 (set-buffer (get-buffer-create file-cache-buffer))
326 (erase-buffer) 344 (erase-buffer)
327 (call-process file-cache-find-command nil 345 (call-process file-cache-find-command nil
328 (get-buffer file-cache-buffer) nil 346 (get-buffer file-cache-buffer) nil
329 dir "-name" 347 dir "-name"
330 (if (eq system-type 'windows-nt) "'*'" "*") 348 (cond
349 (file-cache-find-command-posix-flag
350 "\\*")
351 ((eq system-type 'windows-nt)
352 "'*'")
353 (t
354 "*"))
331 "-print") 355 "-print")
332 (file-cache-add-from-file-cache-buffer))) 356 (file-cache-add-from-file-cache-buffer)))
333 357
diff --git a/lisp/files.el b/lisp/files.el
index d11839f2498..a2676176b86 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -490,13 +490,18 @@ patterns and to guarantee valid names."
490(defun read-directory-name (prompt &optional dir default-dirname mustmatch initial) 490(defun read-directory-name (prompt &optional dir default-dirname mustmatch initial)
491 "Read directory name, prompting with PROMPT and completing in directory DIR. 491 "Read directory name, prompting with PROMPT and completing in directory DIR.
492Value is not expanded---you must call `expand-file-name' yourself. 492Value is not expanded---you must call `expand-file-name' yourself.
493Default name to DEFAULT-DIRNAME if user enters a null string. 493Default name to DEFAULT-DIRNAME if user exits with the same
494non-empty string that was inserted by this function.
494 (If DEFAULT-DIRNAME is omitted, the current buffer's directory is used, 495 (If DEFAULT-DIRNAME is omitted, the current buffer's directory is used,
495 except that if INITIAL is specified, that combined with DIR is used.) 496 except that if INITIAL is specified, that combined with DIR is used.)
497If the user exits with an empty minibuffer, this function returns
498an empty string. (This can only happen if the user erased the
499pre-inserted contents or if `insert-default-directory' is nil.)
496Fourth arg MUSTMATCH non-nil means require existing directory's name. 500Fourth arg MUSTMATCH non-nil means require existing directory's name.
497 Non-nil and non-t means also require confirmation after completion. 501 Non-nil and non-t means also require confirmation after completion.
498Fifth arg INITIAL specifies text to start with. 502Fifth arg INITIAL specifies text to start with.
499DIR defaults to current buffer's directory default." 503DIR should be an absolute directory name. It defaults to
504the value of `default-directory'."
500 (unless dir 505 (unless dir
501 (setq dir default-directory)) 506 (setq dir default-directory))
502 (unless default-dirname 507 (unless default-dirname
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index b76c818a517..c7cd817b4f1 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -210,7 +210,7 @@
210(require 'syntax) 210(require 'syntax)
211 211
212;; Define core `font-lock' group. 212;; Define core `font-lock' group.
213(defgroup font-lock nil 213(defgroup font-lock '((jit-lock custom-group))
214 "Font Lock mode text highlighting package." 214 "Font Lock mode text highlighting package."
215 :link '(custom-manual "(emacs)Font Lock") 215 :link '(custom-manual "(emacs)Font Lock")
216 :link '(custom-manual "(elisp)Font Lock Mode") 216 :link '(custom-manual "(elisp)Font Lock Mode")
@@ -237,13 +237,6 @@
237 :link '(custom-manual "(emacs)Support Modes") 237 :link '(custom-manual "(emacs)Support Modes")
238 :load 'lazy-lock 238 :load 'lazy-lock
239 :group 'font-lock) 239 :group 'font-lock)
240
241(defgroup jit-lock nil
242 "Font Lock support mode to fontify just-in-time."
243 :link '(custom-manual "(emacs)Support Modes")
244 :version "21.1"
245 :load 'jit-lock
246 :group 'font-lock)
247 240
248;; User variables. 241;; User variables.
249 242
@@ -1927,8 +1920,5 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item."
1927 1920
1928(provide 'font-lock) 1921(provide 'font-lock)
1929 1922
1930(when (eq font-lock-support-mode 'jit-lock-mode)
1931 (require 'jit-lock))
1932
1933;;; arch-tag: 682327e4-64d8-4057-b20b-1fbb9f1fc54c 1923;;; arch-tag: 682327e4-64d8-4057-b20b-1fbb9f1fc54c
1934;;; font-lock.el ends here 1924;;; font-lock.el ends here
diff --git a/lisp/info-look.el b/lisp/info-look.el
index a184567ea9c..89eb1d7e411 100644
--- a/lisp/info-look.el
+++ b/lisp/info-look.el
@@ -27,7 +27,7 @@
27;;; Commentary: 27;;; Commentary:
28 28
29;; Really cool code to lookup info indexes. 29;; Really cool code to lookup info indexes.
30;; Try especially info-lookup-symbol (aka C-h TAB). 30;; Try especially info-lookup-symbol (aka C-h S).
31 31
32;;; Code: 32;;; Code:
33 33
@@ -830,6 +830,17 @@ Return nil if there is nothing appropriate in the buffer near point."
830 nil; "^ - [^:]+:[ ]+" don't think this prefix is useful here. 830 nil; "^ - [^:]+:[ ]+" don't think this prefix is useful here.
831 nil))) 831 nil)))
832 832
833(info-lookup-maybe-add-help
834 :mode 'maxima-mode
835 :ignore-case t
836 :regexp "[a-zA-Z_%]+"
837 :doc-spec '( ("(maxima)Function and Variable Index" nil
838 "^ - [^:]+:[ ]+\\(\\[[^=]*=[ ]+\\)?" nil)))
839
840(info-lookup-maybe-add-help
841 :mode 'inferior-maxima-mode
842 :other-modes '(maxima-mode))
843
833;; coreutils and bash builtins overlap in places, eg. printf, so there's a 844;; coreutils and bash builtins overlap in places, eg. printf, so there's a
834;; question which should come first. Some of the coreutils descriptions are 845;; question which should come first. Some of the coreutils descriptions are
835;; more detailed, but if bash is usually /bin/sh on a GNU system then the 846;; more detailed, but if bash is usually /bin/sh on a GNU system then the
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el
index 8efd214ca17..67b1bfbe022 100644
--- a/lisp/jit-lock.el
+++ b/lisp/jit-lock.el
@@ -1,6 +1,6 @@
1;;; jit-lock.el --- just-in-time fontification 1;;; jit-lock.el --- just-in-time fontification
2 2
3;; Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 1998, 2000, 2001, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Gerd Moellmann <gerd@gnu.org> 5;; Author: Gerd Moellmann <gerd@gnu.org>
6;; Keywords: faces files 6;; Keywords: faces files
@@ -32,6 +32,7 @@
32(eval-when-compile 32(eval-when-compile
33 (defmacro with-buffer-unmodified (&rest body) 33 (defmacro with-buffer-unmodified (&rest body)
34 "Eval BODY, preserving the current buffer's modified state." 34 "Eval BODY, preserving the current buffer's modified state."
35 (declare (debug t))
35 (let ((modified (make-symbol "modified"))) 36 (let ((modified (make-symbol "modified")))
36 `(let ((,modified (buffer-modified-p))) 37 `(let ((,modified (buffer-modified-p)))
37 (unwind-protect 38 (unwind-protect
@@ -42,6 +43,7 @@
42 (defmacro with-buffer-prepared-for-jit-lock (&rest body) 43 (defmacro with-buffer-prepared-for-jit-lock (&rest body)
43 "Execute BODY in current buffer, overriding several variables. 44 "Execute BODY in current buffer, overriding several variables.
44Preserves the `buffer-modified-p' state of the current buffer." 45Preserves the `buffer-modified-p' state of the current buffer."
46 (declare (debug t))
45 `(with-buffer-unmodified 47 `(with-buffer-unmodified
46 (let ((buffer-undo-list t) 48 (let ((buffer-undo-list t)
47 (inhibit-read-only t) 49 (inhibit-read-only t)
@@ -56,6 +58,12 @@ Preserves the `buffer-modified-p' state of the current buffer."
56 58
57;;; Customization. 59;;; Customization.
58 60
61(defgroup jit-lock nil
62 "Font Lock support mode to fontify just-in-time."
63 :link '(custom-manual "(emacs)Support Modes")
64 :version "21.1"
65 :group 'font-lock)
66
59(defcustom jit-lock-chunk-size 500 67(defcustom jit-lock-chunk-size 500
60 "*Jit-lock chunks of this many characters, or smaller." 68 "*Jit-lock chunks of this many characters, or smaller."
61 :type 'integer 69 :type 'integer
@@ -109,15 +117,16 @@ See also `jit-lock-stealth-nice'."
109 :group 'jit-lock) 117 :group 'jit-lock)
110 118
111 119
112(defcustom jit-lock-defer-contextually 'syntax-driven 120(defvaralias 'jit-lock-defer-contextually 'jit-lock-contextually)
113 "*If non-nil, means deferred fontification should be syntactically true. 121(defcustom jit-lock-contextually 'syntax-driven
114If nil, means deferred fontification occurs only on those lines modified. This 122 "*If non-nil, means fontification should be syntactically true.
123If nil, means fontification occurs only on those lines modified. This
115means where modification on a line causes syntactic change on subsequent lines, 124means where modification on a line causes syntactic change on subsequent lines,
116those subsequent lines are not refontified to reflect their new context. 125those subsequent lines are not refontified to reflect their new context.
117If t, means deferred fontification occurs on those lines modified and all 126If t, means fontification occurs on those lines modified and all
118subsequent lines. This means those subsequent lines are refontified to reflect 127subsequent lines. This means those subsequent lines are refontified to reflect
119their new syntactic context, either immediately or when scrolling into them. 128their new syntactic context, after `jit-lock-context-time' seconds.
120If any other value, e.g., `syntax-driven', means deferred syntactically true 129If any other value, e.g., `syntax-driven', means syntactically true
121fontification occurs only if syntactic fontification is performed using the 130fontification occurs only if syntactic fontification is performed using the
122buffer mode's syntax table, i.e., only if `font-lock-keywords-only' is nil. 131buffer mode's syntax table, i.e., only if `font-lock-keywords-only' is nil.
123 132
@@ -127,6 +136,10 @@ The value of this variable is used when JIT Lock mode is turned on."
127 (other :tag "syntax-driven" syntax-driven)) 136 (other :tag "syntax-driven" syntax-driven))
128 :group 'jit-lock) 137 :group 'jit-lock)
129 138
139(defcustom jit-lock-context-time 0.5
140 "Idle time after which text is contextually refontified, if applicable."
141 :type '(number :tag "seconds"))
142
130(defcustom jit-lock-defer-time nil ;; 0.25 143(defcustom jit-lock-defer-time nil ;; 0.25
131 "Idle time after which deferred fontification should take place. 144 "Idle time after which deferred fontification should take place.
132If nil, fontification is not deferred." 145If nil, fontification is not deferred."
@@ -145,19 +158,20 @@ If nil, fontification is not deferred."
145They are called with two arguments: the START and END of the region to fontify.") 158They are called with two arguments: the START and END of the region to fontify.")
146(make-variable-buffer-local 'jit-lock-functions) 159(make-variable-buffer-local 'jit-lock-functions)
147 160
148(defvar jit-lock-first-unfontify-pos nil 161(defvar jit-lock-context-unfontify-pos nil
149 "Consider text after this position as contextually unfontified. 162 "Consider text after this position as contextually unfontified.
150If nil, contextual fontification is disabled.") 163If nil, contextual fontification is disabled.")
151(make-variable-buffer-local 'jit-lock-first-unfontify-pos) 164(make-variable-buffer-local 'jit-lock-context-unfontify-pos)
152 165
153 166
154(defvar jit-lock-stealth-timer nil 167(defvar jit-lock-stealth-timer nil
155 "Timer for stealth fontification in Just-in-time Lock mode.") 168 "Timer for stealth fontification in Just-in-time Lock mode.")
156 169(defvar jit-lock-context-timer nil
170 "Timer for context fontification in Just-in-time Lock mode.")
157(defvar jit-lock-defer-timer nil 171(defvar jit-lock-defer-timer nil
158 "Timer for deferred fontification in Just-in-time Lock mode.") 172 "Timer for deferred fontification in Just-in-time Lock mode.")
159 173
160(defvar jit-lock-buffers nil 174(defvar jit-lock-defer-buffers nil
161 "List of buffers with pending deferred fontification.") 175 "List of buffers with pending deferred fontification.")
162 176
163;;; JIT lock mode 177;;; JIT lock mode
@@ -181,9 +195,9 @@ following ways:
181 been idle for `jit-lock-stealth-time' seconds, while Emacs remains idle. 195 been idle for `jit-lock-stealth-time' seconds, while Emacs remains idle.
182 This is useful if any buffer has any deferred fontification. 196 This is useful if any buffer has any deferred fontification.
183 197
184- Deferred context fontification if `jit-lock-defer-contextually' is 198- Deferred context fontification if `jit-lock-contextually' is
185 non-nil. This means fontification updates the buffer corresponding to 199 non-nil. This means fontification updates the buffer corresponding to
186 true syntactic context, after `jit-lock-stealth-time' seconds of Emacs 200 true syntactic context, after `jit-lock-context-time' seconds of Emacs
187 idle time, while Emacs remains idle. Otherwise, fontification occurs 201 idle time, while Emacs remains idle. Otherwise, fontification occurs
188 on modified lines only, and subsequent lines can remain fontified 202 on modified lines only, and subsequent lines can remain fontified
189 corresponding to previous syntactic contexts. This is useful where 203 corresponding to previous syntactic contexts. This is useful where
@@ -212,10 +226,14 @@ the variable `jit-lock-stealth-nice'."
212 (run-with-idle-timer jit-lock-defer-time t 226 (run-with-idle-timer jit-lock-defer-time t
213 'jit-lock-deferred-fontify))) 227 'jit-lock-deferred-fontify)))
214 228
215 ;; Initialize deferred contextual fontification if requested. 229 ;; Initialize contextual fontification if requested.
216 (when (eq jit-lock-defer-contextually t) 230 (when (eq jit-lock-contextually t)
217 (setq jit-lock-first-unfontify-pos 231 (unless jit-lock-context-timer
218 (or jit-lock-first-unfontify-pos (point-max)))) 232 (setq jit-lock-context-timer
233 (run-with-idle-timer jit-lock-context-time t
234 'jit-lock-context-fontify)))
235 (setq jit-lock-context-unfontify-pos
236 (or jit-lock-context-unfontify-pos (point-max))))
219 237
220 ;; Setup our hooks. 238 ;; Setup our hooks.
221 (add-hook 'after-change-functions 'jit-lock-after-change nil t) 239 (add-hook 'after-change-functions 'jit-lock-after-change nil t)
@@ -224,7 +242,8 @@ the variable `jit-lock-stealth-nice'."
224 ;; Turn Just-in-time Lock mode off. 242 ;; Turn Just-in-time Lock mode off.
225 (t 243 (t
226 ;; Cancel our idle timers. 244 ;; Cancel our idle timers.
227 (when (and (or jit-lock-stealth-timer jit-lock-defer-timer) 245 (when (and (or jit-lock-stealth-timer jit-lock-defer-timer
246 jit-lock-context-timer)
228 ;; Only if there's no other buffer using them. 247 ;; Only if there's no other buffer using them.
229 (not (catch 'found 248 (not (catch 'found
230 (dolist (buf (buffer-list)) 249 (dolist (buf (buffer-list))
@@ -233,6 +252,9 @@ the variable `jit-lock-stealth-nice'."
233 (when jit-lock-stealth-timer 252 (when jit-lock-stealth-timer
234 (cancel-timer jit-lock-stealth-timer) 253 (cancel-timer jit-lock-stealth-timer)
235 (setq jit-lock-stealth-timer nil)) 254 (setq jit-lock-stealth-timer nil))
255 (when jit-lock-context-timer
256 (cancel-timer jit-lock-context-timer)
257 (setq jit-lock-context-timer nil))
236 (when jit-lock-defer-timer 258 (when jit-lock-defer-timer
237 (cancel-timer jit-lock-defer-timer) 259 (cancel-timer jit-lock-defer-timer)
238 (setq jit-lock-defer-timer nil))) 260 (setq jit-lock-defer-timer nil)))
@@ -248,8 +270,8 @@ FUN will be called with two arguments START and END indicating the region
248that needs to be (re)fontified. 270that needs to be (re)fontified.
249If non-nil, CONTEXTUAL means that a contextual fontification would be useful." 271If non-nil, CONTEXTUAL means that a contextual fontification would be useful."
250 (add-hook 'jit-lock-functions fun nil t) 272 (add-hook 'jit-lock-functions fun nil t)
251 (when (and contextual jit-lock-defer-contextually) 273 (when (and contextual jit-lock-contextually)
252 (set (make-local-variable 'jit-lock-defer-contextually) t)) 274 (set (make-local-variable 'jit-lock-contextually) t))
253 (jit-lock-mode t)) 275 (jit-lock-mode t))
254 276
255(defun jit-lock-unregister (fun) 277(defun jit-lock-unregister (fun)
@@ -281,8 +303,8 @@ is active."
281 ;; No deferral. 303 ;; No deferral.
282 (jit-lock-fontify-now start (+ start jit-lock-chunk-size)) 304 (jit-lock-fontify-now start (+ start jit-lock-chunk-size))
283 ;; Record the buffer for later fontification. 305 ;; Record the buffer for later fontification.
284 (unless (memq (current-buffer) jit-lock-buffers) 306 (unless (memq (current-buffer) jit-lock-defer-buffers)
285 (push (current-buffer) jit-lock-buffers)) 307 (push (current-buffer) jit-lock-defer-buffers))
286 ;; Mark the area as defer-fontified so that the redisplay engine 308 ;; Mark the area as defer-fontified so that the redisplay engine
287 ;; is happy and so that the idle timer can find the places to fontify. 309 ;; is happy and so that the idle timer can find the places to fontify.
288 (with-buffer-prepared-for-jit-lock 310 (with-buffer-prepared-for-jit-lock
@@ -330,7 +352,13 @@ Defaults to the whole buffer. END can be out of bounds."
330 ;; We mark it first, to make sure that we don't indefinitely 352 ;; We mark it first, to make sure that we don't indefinitely
331 ;; re-execute this fontification if an error occurs. 353 ;; re-execute this fontification if an error occurs.
332 (put-text-property start next 'fontified t) 354 (put-text-property start next 'fontified t)
333 (run-hook-with-args 'jit-lock-functions start next) 355 (condition-case err
356 (run-hook-with-args 'jit-lock-functions start next)
357 ;; If the user quits (which shouldn't happen in normal on-the-fly
358 ;; jit-locking), make sure the fontification will be performed
359 ;; before displaying the block again.
360 (quit (put-text-property start next 'fontified nil)
361 (funcall 'signal (car err) (cdr err))))
334 362
335 ;; Find the start of the next chunk, if any. 363 ;; Find the start of the next chunk, if any.
336 (setq start (text-property-any next end 'fontified nil)))))))) 364 (setq start (text-property-any next end 'fontified nil))))))))
@@ -390,11 +418,9 @@ This functions is called after Emacs has been idle for
390 (let ((buffers (buffer-list)) 418 (let ((buffers (buffer-list))
391 minibuffer-auto-raise 419 minibuffer-auto-raise
392 message-log-max) 420 message-log-max)
393 (while (and buffers (not (input-pending-p))) 421 (with-local-quit
394 (let ((buffer (car buffers))) 422 (while (and buffers (not (input-pending-p)))
395 (setq buffers (cdr buffers)) 423 (with-current-buffer (pop buffers)
396
397 (with-current-buffer buffer
398 (when jit-lock-mode 424 (when jit-lock-mode
399 ;; This is funny. Calling sit-for with 3rd arg non-nil 425 ;; This is funny. Calling sit-for with 3rd arg non-nil
400 ;; so that it doesn't redisplay, internally calls 426 ;; so that it doesn't redisplay, internally calls
@@ -414,28 +440,6 @@ This functions is called after Emacs has been idle for
414 (concat "JIT stealth lock " 440 (concat "JIT stealth lock "
415 (buffer-name))) 441 (buffer-name)))
416 442
417 ;; Perform deferred unfontification, if any.
418 (when jit-lock-first-unfontify-pos
419 (save-restriction
420 (widen)
421 (when (and (>= jit-lock-first-unfontify-pos (point-min))
422 (< jit-lock-first-unfontify-pos (point-max)))
423 ;; If we're in text that matches a complex multi-line
424 ;; font-lock pattern, make sure the whole text will be
425 ;; redisplayed eventually.
426 (when (get-text-property jit-lock-first-unfontify-pos
427 'jit-lock-defer-multiline)
428 (setq jit-lock-first-unfontify-pos
429 (or (previous-single-property-change
430 jit-lock-first-unfontify-pos
431 'jit-lock-defer-multiline)
432 (point-min))))
433 (with-buffer-prepared-for-jit-lock
434 (remove-text-properties
435 jit-lock-first-unfontify-pos (point-max)
436 '(fontified nil jit-lock-defer-multiline nil)))
437 (setq jit-lock-first-unfontify-pos (point-max)))))
438
439 ;; In the following code, the `sit-for' calls cause a 443 ;; In the following code, the `sit-for' calls cause a
440 ;; redisplay, so it's required that the 444 ;; redisplay, so it's required that the
441 ;; buffer-modified flag of a buffer that is displayed 445 ;; buffer-modified flag of a buffer that is displayed
@@ -452,8 +456,8 @@ This functions is called after Emacs has been idle for
452 (jit-lock-fontify-now start (+ start jit-lock-chunk-size)) 456 (jit-lock-fontify-now start (+ start jit-lock-chunk-size))
453 ;; If stealth jit-locking is done backwards, this leads to 457 ;; If stealth jit-locking is done backwards, this leads to
454 ;; excessive O(n^2) refontification. -stef 458 ;; excessive O(n^2) refontification. -stef
455 ;; (when (>= jit-lock-first-unfontify-pos start) 459 ;; (when (>= jit-lock-context-unfontify-pos start)
456 ;; (setq jit-lock-first-unfontify-pos end)) 460 ;; (setq jit-lock-context-unfontify-pos end))
457 461
458 ;; Wait a little if load is too high. 462 ;; Wait a little if load is too high.
459 (when (and jit-lock-stealth-load 463 (when (and jit-lock-stealth-load
@@ -466,9 +470,9 @@ This functions is called after Emacs has been idle for
466 470
467(defun jit-lock-deferred-fontify () 471(defun jit-lock-deferred-fontify ()
468 "Fontify what was deferred." 472 "Fontify what was deferred."
469 (when jit-lock-buffers 473 (when jit-lock-defer-buffers
470 ;; Mark the deferred regions back to `fontified = nil' 474 ;; Mark the deferred regions back to `fontified = nil'
471 (dolist (buffer jit-lock-buffers) 475 (dolist (buffer jit-lock-defer-buffers)
472 (when (buffer-live-p buffer) 476 (when (buffer-live-p buffer)
473 (with-current-buffer buffer 477 (with-current-buffer buffer
474 ;; (message "Jit-Defer %s" (buffer-name)) 478 ;; (message "Jit-Defer %s" (buffer-name))
@@ -482,7 +486,7 @@ This functions is called after Emacs has been idle for
482 pos 'fontified nil (point-max))) 486 pos 'fontified nil (point-max)))
483 'fontified nil)) 487 'fontified nil))
484 (setq pos (next-single-property-change pos 'fontified))))))))) 488 (setq pos (next-single-property-change pos 'fontified)))))))))
485 (setq jit-lock-buffers nil) 489 (setq jit-lock-defer-buffers nil)
486 ;; Force fontification of the visible parts. 490 ;; Force fontification of the visible parts.
487 (let ((jit-lock-defer-time nil)) 491 (let ((jit-lock-defer-time nil))
488 ;; (message "Jit-Defer Now") 492 ;; (message "Jit-Defer Now")
@@ -491,6 +495,36 @@ This functions is called after Emacs has been idle for
491 ))) 495 )))
492 496
493 497
498(defun jit-lock-context-fontify ()
499 "Refresh fontification to take new context into account."
500 (dolist (buffer (buffer-list))
501 (with-current-buffer buffer
502 (when jit-lock-context-unfontify-pos
503 ;; (message "Jit-Context %s" (buffer-name))
504 (save-restriction
505 (widen)
506 (when (and (>= jit-lock-context-unfontify-pos (point-min))
507 (< jit-lock-context-unfontify-pos (point-max)))
508 ;; If we're in text that matches a complex multi-line
509 ;; font-lock pattern, make sure the whole text will be
510 ;; redisplayed eventually.
511 ;; Despite its name, we treat jit-lock-defer-multiline here
512 ;; rather than in jit-lock-defer since it has to do with multiple
513 ;; lines, i.e. with context.
514 (when (get-text-property jit-lock-context-unfontify-pos
515 'jit-lock-defer-multiline)
516 (setq jit-lock-context-unfontify-pos
517 (or (previous-single-property-change
518 jit-lock-context-unfontify-pos
519 'jit-lock-defer-multiline)
520 (point-min))))
521 (with-buffer-prepared-for-jit-lock
522 ;; Force contextual refontification.
523 (remove-text-properties
524 jit-lock-context-unfontify-pos (point-max)
525 '(fontified nil jit-lock-defer-multiline nil)))
526 (setq jit-lock-context-unfontify-pos (point-max))))))))
527
494(defun jit-lock-after-change (start end old-len) 528(defun jit-lock-after-change (start end old-len)
495 "Mark the rest of the buffer as not fontified after a change. 529 "Mark the rest of the buffer as not fontified after a change.
496Installed on `after-change-functions'. 530Installed on `after-change-functions'.
@@ -522,9 +556,9 @@ will take place when text is fontified stealthily."
522 ;; Request refontification. 556 ;; Request refontification.
523 (put-text-property start end 'fontified nil)) 557 (put-text-property start end 'fontified nil))
524 ;; Mark the change for deferred contextual refontification. 558 ;; Mark the change for deferred contextual refontification.
525 (when jit-lock-first-unfontify-pos 559 (when jit-lock-context-unfontify-pos
526 (setq jit-lock-first-unfontify-pos 560 (setq jit-lock-context-unfontify-pos
527 (min jit-lock-first-unfontify-pos start)))))) 561 (min jit-lock-context-unfontify-pos start))))))
528 562
529(provide 'jit-lock) 563(provide 'jit-lock)
530 564
diff --git a/lisp/mail/rmail-spam-filter.el b/lisp/mail/rmail-spam-filter.el
index d5a45fe5d87..b811e5991e7 100644
--- a/lisp/mail/rmail-spam-filter.el
+++ b/lisp/mail/rmail-spam-filter.el
@@ -1,9 +1,9 @@
1;;; rmail-spam-filter.el --- spam filter for RMAIL 1;;; rmail-spam-filter.el --- spam filter for rmail, the emacs mail reader.
2
3;; Copyright (C) 2002 Free Software Foundation, Inc.
2 4
3;; Copyright (C) 2002
4;; Free Software Foundation, Inc.
5;; Keywords: email, spam, filter, rmail 5;; Keywords: email, spam, filter, rmail
6;; Author: Eli Tziperman <eli@beach.weizmann.ac.il> 6;; Author: Eli Tziperman <eli AT deas.harvard.edu>
7 7
8;; This file is part of GNU Emacs. 8;; This file is part of GNU Emacs.
9 9
@@ -23,62 +23,69 @@
23;; Boston, MA 02111-1307, USA. 23;; Boston, MA 02111-1307, USA.
24 24
25;;; Commentary: 25;;; Commentary:
26;;; -----------
26 27
27;; Automatically recognize and delete junk email before it is 28;;; Automatically recognize and delete junk email before it is
28;; displayed in rmail/rmail-summary. Spam emails are defined by 29;;; displayed in rmail/rmail-summary. Spam emails are defined by
29;; specifying one or more of the sender, subject and contents. 30;;; specifying one or more of the sender, subject and contents.
30;; URL: http://www.weizmann.ac.il/~eli/Downloads/rmail-spam-filter/ 31;;; URL: http://deas.harvard.edu/climate/eli/Downloads/rmail-spam-filter/
31 32
32;; Usage: 33;;; Usage:
33;; ------ 34;;; ------
34 35
35;; put in your .emacs: 36;;; put in your .emacs:
36 37
37;; (load "rmail-spam-filter.el") 38;;; (load "rmail-spam-filter.el")
38 39
39;; and use customize (in rmail-spam-filter group) to: 40;;; and use customize (in rmail-spam-filter group) to:
40 41
41;; (*) turn on the variable rmail-use-spam-filter, 42;;; (*) turn on the variable rmail-use-spam-filter,
42 43
43;; (*) specify in variable rmail-spam-definitions-alist what sender, 44;;; (*) specify in variable rsf-definitions-alist what sender,
44;; subject and contents make an email be considered spam. 45;;; subject and contents make an email be considered spam.
45 46
46;; in addition, you may: 47;;; in addition, you may:
47 48
48;; (*) Block future mail with the subject or sender of a message 49;;; (*) Block future mail with the subject or sender of a message
49;; while reading it in RMAIL: just click on the "Spam" item on the 50;;; while reading it in RMAIL: just click on the "Spam" item on the
50;; menubar, and add the subject or sender to the list of spam 51;;; menubar, and add the subject or sender to the list of spam
51;; definitions using the mouse and the appropriate menu item. Â  You 52;;; definitions using the mouse and the appropriate menu item. You
52;; need to later also save the list of spam definitions using the 53;;; need to later also save the list of spam definitions using the
53;; same menu item, or alternatively, see variable 54;;; same menu item, or alternatively, see variable
54;; `rmail-spam-filter-autosave-newly-added-spam-definitions'. 55;;; `rsf-autosave-newly-added-definitions'.
55 56
56;; (*) specify if blind-cc'ed mail (no "To:" header field) is to be 57;;; (*) specify if blind-cc'ed mail (no "To:" header field) is to be
57;; treated as spam (variable rmail-spam-no-blind-cc; Thanks to Ethan 58;;; treated as spam (variable rsf-no-blind-cc; Thanks to Ethan
58;; Brown <ethan@gso.saic.com> for this). 59;;; Brown <ethan@gso.saic.com> for this).
59 60
60;; (*) specify if rmail-spam-filter should ignore case of spam 61;;; (*) specify if rmail-spam-filter should ignore case of spam
61;; definitions (variable rmail-spam-filter-ignore-case; Thanks to 62;;; definitions (variable rsf-ignore-case; Thanks to
62;; Ethan Brown <ethan@gso.saic.com> for the suggestion). 63;;; Ethan Brown <ethan@gso.saic.com> for the suggestion).
63 64
64;; (*) Specify a "white-list" of trusted senders. If any 65;;; (*) Specify a "white-list" of trusted senders. If any
65;; rmail-spam-white-list string matches a substring of the "From" 66;;; rsf-white-list string matches a substring of the "From"
66;; header, the message is flagged as a valid, non-spam message (Ethan 67;;; header, the message is flagged as a valid, non-spam message (Ethan
67;; Brown <ethan@gso.saic.com>). 68;;; Brown <ethan@gso.saic.com>).
68 69
69;; (*) rmail spam filter also works with bbdb to prevent spam senders 70;;; (*) rmail-spam-filter is best used with a general purpose spam
70;; from entering into the .bbdb file. See variable 71;;; filter such as the procmail-based http://www.spambouncer.org/.
71;; "rmail-spam-filter-auto-delete-spam-bbdb-entries". This is done 72;;; Spambouncer is set to only mark messages as spam/blocked/bulk/OK
72;; in two ways: (a) bbdb is made not to auto-create entries for 73;;; via special headers, and these headers may then be defined in
73;; messages that are deleted by the rmail-spam-filter, (b) when a 74;;; rmail-spam-filter such that the spam is rejected by
74;; message is deleted in rmail, the user is offered to delete the 75;;; rmail-spam-filter itself.
75;; sender's bbdb entry as well _if_ it was created at the same day.
76 76
77;;; Code: 77;;; (*) rmail spam filter also works with bbdb to prevent spam senders
78;;; from entering into the .bbdb file. See variable
79;;; "rsf-auto-delete-spam-bbdb-entries". This is done
80;;; in two ways: (a) bbdb is made not to auto-create entries for
81;;; messages that are deleted by the rmail-spam-filter, (b) when a
82;;; message is deleted in rmail, the user is offered to delete the
83;;; sender's bbdb entry as well _if_ it was created at the same day.
78 84
79(require 'rmail) 85(require 'rmail)
86(require 'rmailsum)
80 87
81;; For find-if and other cool common lisp functions we may want to use. (EDB) 88;; For find-if and other cool common lisp functions we may want to use.
82(eval-when-compile 89(eval-when-compile
83 (require 'cl)) 90 (require 'cl))
84 91
@@ -89,41 +96,51 @@
89;;;###autoload 96;;;###autoload
90(defcustom rmail-use-spam-filter nil 97(defcustom rmail-use-spam-filter nil
91 "*Non-nil to activate the rmail spam filter. 98 "*Non-nil to activate the rmail spam filter.
92Specify `rmail-spam-definitions-alist' to define what you consider spam 99Specify `rsf-definitions-alist' to define what you consider spam
93emails." 100emails."
94 :type 'boolean 101 :type 'boolean
95 :group 'rmail-spam-filter ) 102 :group 'rmail-spam-filter )
96 103
97(defcustom rmail-spam-file "~/XRMAIL-SPAM" 104(defcustom rsf-file "~/XRMAIL-SPAM"
98 "*Name of rmail file for optionally saving some of the spam. 105 "*Name of rmail file for optionally saving some of the spam.
99Spam may be either just deleted, or saved in a separate spam file to 106Spam may be either just deleted, or saved in a separate spam file to
100be looked at at a later time. Whether the spam is just deleted or 107be looked at at a later time. Whether the spam is just deleted or
101also saved in a separete spam file is specified for each definition of 108also saved in a separete spam file is specified for each definition of
102spam, as one of the fields of `rmail-spam-definitions-alist'" 109spam, as one of the fields of `rsf-definitions-alist'"
103 :type 'string 110 :type 'string
104 :group 'rmail-spam-filter ) 111 :group 'rmail-spam-filter )
105 112
106(defcustom rmail-spam-no-blind-cc nil 113(defcustom rsf-no-blind-cc nil
107 "*Non-nil to treat blind CC (no To: header) as spam." 114 "*Non-nil to treat blind CC (no To: header) as spam."
108 :type 'boolean 115 :type 'boolean
109 :group 'rmail-spam-filter ) 116 :group 'rmail-spam-filter )
110 117
111(defcustom rmail-spam-filter-ignore-case nil 118(defcustom rsf-ignore-case nil
112 "*Non-nil to ignore case in `rmail-spam-definitions-alist'." 119 "*Non-nil to ignore case in `rsf-definitions-alist'."
113 :type 'boolean 120 :type 'boolean
114 :group 'rmail-spam-filter ) 121 :group 'rmail-spam-filter )
115 122
116(defcustom rmail-spam-filter-beep nil 123(defcustom rsf-beep nil
117 "*Non-nil to beep if spam is found." 124 "*Non-nil to beep if spam is found."
118 :type 'boolean 125 :type 'boolean
119 :group 'rmail-spam-filter ) 126 :group 'rmail-spam-filter )
120 127
121(defcustom rmail-spam-sleep-after-message 2.0 128(defcustom rsf-sleep-after-message 2.0
122 "*Seconds to wait after display of message that spam was found." 129 "*Seconds to wait after display of message that spam was found."
123 :type 'number 130 :type 'number
124 :group 'rmail-spam-filter ) 131 :group 'rmail-spam-filter )
125 132
126(defcustom rmail-spam-filter-auto-delete-spam-bbdb-entries nil 133(defcustom rsf-min-region-to-spam-list 7
134 "*User may highlight a region in an incomming message and use
135 the menubar to add this region to the spam definitions. This
136 variable specifies the minimum size of region that may be added
137 to spam list, to avoid accidentally adding a too short region
138 which would result in false positive identification of spam
139 messages."
140 :type 'integer
141 :group 'rmail-spam-filter )
142
143(defcustom rsf-auto-delete-spam-bbdb-entries nil
127 "*Non-nil to make sure no entries are made in bbdb for spam emails. 144 "*Non-nil to make sure no entries are made in bbdb for spam emails.
128This is done in two ways: (1) bbdb is made not to auto-create entries 145This is done in two ways: (1) bbdb is made not to auto-create entries
129for messages that are deleted by the `rmail-spam-filter', (2) when a 146for messages that are deleted by the `rmail-spam-filter', (2) when a
@@ -134,7 +151,7 @@ take an effect."
134 :type 'boolean 151 :type 'boolean
135 :group 'rmail-spam-filter ) 152 :group 'rmail-spam-filter )
136 153
137(defcustom rmail-spam-filter-autosave-newly-added-spam-definitions nil 154(defcustom rsf-autosave-newly-added-definitions nil
138 "*Non-nil to auto save new spam entries. 155 "*Non-nil to auto save new spam entries.
139New entries entered via the spam menu bar item are then saved to 156New entries entered via the spam menu bar item are then saved to
140customization file immediately after being added via the menu bar, and 157customization file immediately after being added via the menu bar, and
@@ -143,17 +160,17 @@ entries."
143 :type 'boolean 160 :type 'boolean
144 :group 'rmail-spam-filter ) 161 :group 'rmail-spam-filter )
145 162
146(defcustom rmail-spam-white-list nil 163(defcustom rsf-white-list nil
147 "*List of strings to identify valid senders. 164 "*List of strings to identify valid senders.
148If any rmail-spam-white-list string matches a substring of the 'From' 165If any rsf-white-list string matches a substring of the 'From'
149header, the message is flagged as a valid, non-spam message. Example: 166header, the message is flagged as a valid, non-spam message. Example:
150If your domain is emacs.com then including 'emacs.com' in your 167If your domain is emacs.com then including 'emacs.com' in your
151rmail-spam-white-list would flag all mail from your colleagues as 168rsf-white-list would flag all mail from your colleagues as
152valid." 169valid."
153 :type '(repeat string) 170 :type '(repeat string)
154 :group 'rmail-spam-filter ) 171 :group 'rmail-spam-filter )
155 172
156(defcustom rmail-spam-definitions-alist nil 173(defcustom rsf-definitions-alist nil
157 "*Alist matching strings defining what messages are considered spam. 174 "*Alist matching strings defining what messages are considered spam.
158Each definition may contain specifications of one or more of the 175Each definition may contain specifications of one or more of the
159elements {subject, sender, recipients or contents}, as well as a 176elements {subject, sender, recipients or contents}, as well as a
@@ -162,8 +179,10 @@ is defined as one that fits all of the specified elements of any one
162of the spam definitions. The strings that specify spam subject, 179of the spam definitions. The strings that specify spam subject,
163sender, etc, may be regexp. For example, to specify that the subject 180sender, etc, may be regexp. For example, to specify that the subject
164may be either 'this is spam' or 'another spam', use the regexp: 'this 181may be either 'this is spam' or 'another spam', use the regexp: 'this
165is spam\|another spam' (without the single quotes)." 182is spam\\|another spam' (without the single quotes). To specify that
166 :type '(repeat 183if the contents contain both this and that the message is spam,
184specify 'this\\&that' in the appropriate spam definition field."
185 :type '(repeat
167 (list :format "%v" 186 (list :format "%v"
168 (cons :format "%v" :value (from . "") 187 (cons :format "%v" :value (from . "")
169 (const :format "" from) 188 (const :format "" from)
@@ -174,25 +193,53 @@ is spam\|another spam' (without the single quotes)."
174 (cons :format "%v" :value (subject . "") 193 (cons :format "%v" :value (subject . "")
175 (const :format "" subject) 194 (const :format "" subject)
176 (string :tag "Subject" "")) 195 (string :tag "Subject" ""))
196 (cons :format "%v" :value (content-type . "")
197 (const :format "" content-type)
198 (string :tag "Content-Type" ""))
177 (cons :format "%v" :value (contents . "") 199 (cons :format "%v" :value (contents . "")
178 (const :format "" contents) 200 (const :format "" contents)
179 (string :tag "Contents" "")) 201 (string :tag "Contents" ""))
180 (cons :format "%v" :value (action . output-and-delete) 202 (cons :format "%v" :value (action . output-and-delete)
181 (const :format "" action) 203 (const :format "" action)
182 (choice :tag "Action selection" 204 (choice :tag "Action selection"
183 (const :tag "output to spam folder and delete" output-and-delete) 205 (const :tag "output to spam folder and delete" output-and-delete)
184 (const :tag "delete spam" delete-spam) 206 (const :tag "delete spam" delete-spam)
185 )) 207 ))
186 )) 208 ))
187 :group 'rmail-spam-filter) 209 :group 'rmail-spam-filter)
188 210
189(defvar rmail-spam-filter-scanning-messages-now nil 211(defvar rsf-scanning-messages-now nil
190 "Non nil when rmail-spam-filter scans messages, 212 "Non nil when rmail-spam-filter scans messages,
191for interaction with `rmail-bbdb-auto-delete-spam-entries'") 213for interaction with `rsf-bbdb-auto-delete-spam-entries'")
214
215;; the advantage over the automatic filter definitions is the AND conjunction
216;; of in-one-definition-elements
217(defun rsf-check-field (field-symbol message-data definition result)
218 "Check if field-symbol is in `rsf-definitions-alist'.
219Capture maybe-spam and this-is-a-spam-email in a cons in result,
220where maybe-spam is in first and this-is-a-spam-email is in rest.
221The values are returned by destructively changing result.
222If FIELD-SYMBOL field does not exist AND is not specified,
223this may still be spam due to another element...
224if (first result) is nil, we already have a contradiction in another
225field"
226 (let ((definition-field (cdr (assoc field-symbol definition))))
227 (if (and (first result) (> (length definition-field) 0))
228 ;; only in this case can maybe-spam change from t to nil
229 ;; ... else, if FIELD-SYMBOL field does appear in the message,
230 ;; and it also appears in spam definition list, this
231 ;; is potentially a spam:
232 (if (and message-data
233 (string-match definition-field message-data))
234 ;; if we do not get a contradiction from another field, this is
235 ;; spam
236 (setf (rest result) t)
237 ;; the message data contradicts the specification, this is no spam
238 (setf (first result) nil)))))
192 239
193(defun rmail-spam-filter (msg) 240(defun rmail-spam-filter (msg)
194 "Return nil if msg is spam based on rmail-spam-definitions-alist. 241 "Return nil if msg is spam based on rsf-definitions-alist.
195If spam, optionally output msg to a file `rmail-spam-file' and delete 242If spam, optionally output msg to a file `rsf-file' and delete
196it from rmail file. Called for each new message retrieved by 243it from rmail file. Called for each new message retrieved by
197`rmail-get-new-mail'." 244`rmail-get-new-mail'."
198 245
@@ -203,22 +250,23 @@ it from rmail file. Called for each new message retrieved by
203 (message-sender) 250 (message-sender)
204 (message-recipients) 251 (message-recipients)
205 (message-subject) 252 (message-subject)
253 (message-content-type)
206 (num-spam-definition-elements) 254 (num-spam-definition-elements)
207 (num-element 0) 255 (num-element 0)
208 (exit-while-loop nil) 256 (exit-while-loop nil)
209 (saved-case-fold-search case-fold-search) 257 (saved-case-fold-search case-fold-search)
210 (save-current-msg) 258 (save-current-msg)
211 (rmail-spam-filter-saved-bbdb/mail_auto_create_p nil) 259 (rsf-saved-bbdb/mail_auto_create_p nil)
212 ) 260 )
213 261
214 ;; make sure bbdb does not create entries for messages while spam 262 ;; make sure bbdb does not create entries for messages while spam
215 ;; filter is scanning the rmail file: 263 ;; filter is scanning the rmail file:
216 (setq rmail-spam-filter-saved-bbdb/mail_auto_create_p 'bbdb/mail_auto_create_p) 264 (setq rsf-saved-bbdb/mail_auto_create_p 'bbdb/mail_auto_create_p)
217 (setq bbdb/mail_auto_create_p nil) 265 (setq bbdb/mail_auto_create_p nil)
218 ;; let `rmail-bbdb-auto-delete-spam-entries' know that rmail spam 266 ;; let `rsf-bbdb-auto-delete-spam-entries' know that rmail spam
219 ;; filter is running, so that deletion of rmail messages should be 267 ;; filter is running, so that deletion of rmail messages should be
220 ;; ignored for now: 268 ;; ignored for now:
221 (setq rmail-spam-filter-scanning-messages-now t) 269 (setq rsf-scanning-messages-now t)
222 (save-excursion 270 (save-excursion
223 (save-restriction 271 (save-restriction
224 (setq this-is-a-spam-email nil) 272 (setq this-is-a-spam-email nil)
@@ -228,166 +276,111 @@ it from rmail file. Called for each new message retrieved by
228 (goto-char (rmail-msgbeg msg)) 276 (goto-char (rmail-msgbeg msg))
229 (narrow-to-region (point) (progn (search-forward "\n\n") (point))) 277 (narrow-to-region (point) (progn (search-forward "\n\n") (point)))
230 (setq message-sender (mail-fetch-field "From")) 278 (setq message-sender (mail-fetch-field "From"))
231 (setq message-recipients (mail-fetch-field "To")) 279 (setq message-recipients
280 (concat (mail-fetch-field "To")
281 (if (mail-fetch-field "Cc")
282 (concat ", " (mail-fetch-field "Cc")))))
232 (setq message-subject (mail-fetch-field "Subject")) 283 (setq message-subject (mail-fetch-field "Subject"))
284 (setq message-content-type (mail-fetch-field "Content-Type"))
233 ) 285 )
234 ;; Find number of spam-definition elements in the list 286 ;; Find number of spam-definition elements in the list
235 ;; rmail-spam-definitions-alist specified by user: 287 ;; rsf-definitions-alist specified by user:
236 (setq num-spam-definition-elements (safe-length 288 (setq num-spam-definition-elements (safe-length
237 rmail-spam-definitions-alist)) 289 rsf-definitions-alist))
238 290
239 ;;; do we want to ignore case in spam definitions: 291 ;;; do we want to ignore case in spam definitions:
240 (setq case-fold-search rmail-spam-filter-ignore-case) 292 (setq case-fold-search rsf-ignore-case)
241 293
242 ;; Check for blind CC condition. Set vars such that while 294 ;; Check for blind CC condition. Set vars such that while
243 ;; loop will be bypassed and spam condition will trigger (EDB) 295 ;; loop will be bypassed and spam condition will trigger
244 (if (and rmail-spam-no-blind-cc 296 (if (and rsf-no-blind-cc
245 (null message-recipients)) 297 (null message-recipients))
246 (progn 298 (setq exit-while-loop t
247 (setq exit-while-loop t) 299 maybe-spam t
248 (setq maybe-spam t) 300 this-is-a-spam-email t))
249 (setq this-is-a-spam-email t))) 301
250 302 ;; Check white list, and likewise cause while loop
251 ;; Check white list, and likewise cause while loop 303 ;; bypass.
252 ;; bypass. (EDB) 304 (if (let ((white-list rsf-white-list)
253 (if (find-if '(lambda (white-str) 305 (found nil))
254 (string-match white-str message-sender)) 306 (while (and (not found) white-list)
255 rmail-spam-white-list) 307 (if (string-match (car white-list) message-sender)
256 (progn 308 (setq found t)
257 (setq exit-while-loop t) 309 (setq white-list (cdr white-list))))
258 (setq maybe-spam nil) 310 found)
259 (setq this-is-a-spam-email nil))) 311 (setq exit-while-loop t
260 312 maybe-spam nil
261 ;; scan all elements of the list rmail-spam-definitions-alist 313 this-is-a-spam-email nil))
314
315 ;; maybe-spam is in first, this-is-a-spam-email in rest, this
316 ;; simplifies the call to rsf-check-field
317 (setq maybe-spam (cons maybe-spam this-is-a-spam-email))
318
319 ;; scan all elements of the list rsf-definitions-alist
262 (while (and 320 (while (and
263 (< num-element num-spam-definition-elements) 321 (< num-element num-spam-definition-elements)
264 (not exit-while-loop)) 322 (not exit-while-loop))
265 (progn 323 (let ((definition (nth num-element rsf-definitions-alist)))
266 ;; Initialize maybe-spam which is set to t in one of two 324 ;; Initialize maybe-spam which is set to t in one of two
267 ;; cases: (1) unspecified definition-elements are found in 325 ;; cases: (1) unspecified definition-elements are found in
268 ;; rmail-spam-definitions-alist, (2) empty field is found 326 ;; rsf-definitions-alist, (2) empty field is found
269 ;; in the message being scanned (e.g. empty subject, 327 ;; in the message being scanned (e.g. empty subject,
270 ;; sender, recipients, etc). The variable is set to nil 328 ;; sender, recipients, etc). The variable is set to nil
271 ;; if a non empty field of the scanned message does not 329 ;; if a non empty field of the scanned message does not
272 ;; match a specified field in 330 ;; match a specified field in
273 ;; rmail-spam-definitions-alist. 331 ;; rsf-definitions-alist.
274 (setq maybe-spam t) 332
275 ;; initialize this-is-a-spam-email to nil. This variable 333 ;; initialize this-is-a-spam-email to nil. This variable
276 ;; is set to t if one of the spam definitions matches a 334 ;; is set to t if one of the spam definitions matches a
277 ;; field in the scanned message. 335 ;; field in the scanned message.
278 (setq this-is-a-spam-email nil) 336 (setq maybe-spam (cons t nil))
279 337
280 ;; start scanning incoming message: 338 ;; start scanning incoming message:
281 ;;--------------------------------- 339 ;;---------------------------------
282 340
283 ;; if sender field is not specified in message being 341 ;; Maybe the different fields should also be done in a
342 ;; loop to make the whole thing more flexible
343 ;; if sender field is not specified in message being
284 ;; scanned, AND if "from" field does not appear in spam 344 ;; scanned, AND if "from" field does not appear in spam
285 ;; definitions for this element, this may still be spam 345 ;; definitions for this element, this may still be spam
286 ;; due to another element... 346 ;; due to another element...
287 (if (and (not message-sender) 347 (rsf-check-field 'from message-sender definition maybe-spam)
288 (string-match 348 ;; next, if spam was not ruled out already, check recipients:
289 (cdr (assoc 'from (nth num-element 349 (rsf-check-field 'to message-recipients definition maybe-spam)
290 rmail-spam-definitions-alist))) "")) 350 ;; next, if spam was not ruled out already, check subject:
291 (setq maybe-spam t) 351 (rsf-check-field 'subject message-subject definition maybe-spam)
292 ;; ... else, if message-sender does appear in the 352 ;; next, if spam was not ruled out already, check content-type:
293 ;; message, and it also appears in the spam definition 353 (rsf-check-field 'content-type message-content-type
294 ;; list, it is potentially spam: 354 definition maybe-spam)
295 (if (and message-sender
296 (string-match
297 (cdr (assoc 'from (nth num-element
298 rmail-spam-definitions-alist)))
299 message-sender)
300 )
301 (setq this-is-a-spam-email t)
302 (setq maybe-spam nil)
303 )
304 )
305 ;; next, if spam was not ruled out already, check recipients:
306 (if maybe-spam
307 ;; if To field does not exist AND is not specified,
308 ;; this may still be spam due to another element...
309 (if (and (not message-recipients)
310 (string-match
311 (cdr (assoc 'to
312 (nth num-element
313 rmail-spam-definitions-alist))) ""))
314 (setq maybe-spam t)
315 ;; ... else, if To field does appear in the message,
316 ;; and it also appears in spam definition list, this
317 ;; is potentially a spam:
318 (if (and message-recipients
319 (string-match
320 (cdr (assoc 'to (nth num-element
321 rmail-spam-definitions-alist)))
322 message-recipients)
323 )
324 (setq this-is-a-spam-email t)
325 (setq maybe-spam nil)
326 )
327 )
328 )
329 ;; next, if spam was not ruled out already, check subject:
330 (if maybe-spam
331 ;; if subject field does not exist AND is not
332 ;; specified, this may still be spam due to another
333 ;; element...
334 (if (and (not message-subject)
335 (string-match
336 (cdr (assoc 'subject
337 (nth num-element
338 rmail-spam-definitions-alist)))
339 ""))
340 (setq maybe-spam t)
341 ;; ... else, if subject field does appear in the
342 ;; message, and it also appears in the spam
343 ;; definition list, this is potentially a spam:
344 (if (and message-subject
345 (string-match
346 (cdr (assoc 'subject (nth num-element
347 rmail-spam-definitions-alist)))
348 message-subject)
349 )
350 (setq this-is-a-spam-email t)
351 (setq maybe-spam nil)
352 )
353 )
354 )
355 ;; next, if spam was not ruled out already, check 355 ;; next, if spam was not ruled out already, check
356 ;; contents: if contents field is not specified, this may 356 ;; contents: if contents field is not specified, this may
357 ;; still be spam due to another element... 357 ;; still be spam due to another element...
358 (if maybe-spam 358 (rsf-check-field 'contents
359 (if (string-match 359 (buffer-substring
360 (cdr (assoc 'contents 360 (rmail-msgbeg msg) (rmail-msgend msg))
361 (nth num-element 361 definition maybe-spam)
362 rmail-spam-definitions-alist))) "") 362
363 (setq maybe-spam t) 363 ;; if the search in rsf-definitions-alist found
364 ;; ... else, check to see if it appears in spam
365 ;; definition:
366 (if (string-match
367 (cdr (assoc 'contents
368 (nth num-element
369 rmail-spam-definitions-alist)))
370 (buffer-substring
371 (rmail-msgbeg msg) (rmail-msgend msg)))
372 (setq this-is-a-spam-email t)
373 (setq maybe-spam nil)))
374 )
375 ;; if the search in rmail-spam-definitions-alist found
376 ;; that this email is spam, output the email to the spam 364 ;; that this email is spam, output the email to the spam
377 ;; rmail file, mark the email for deletion, leave the 365 ;; rmail file, mark the email for deletion, leave the
378 ;; while loop and return nil so that an rmail summary line 366 ;; while loop and return nil so that an rmail summary line
379 ;; wont be displayed for this message: 367 ;; wont be displayed for this message:
380 (if (and this-is-a-spam-email maybe-spam) 368 (if (and (first maybe-spam) (rest maybe-spam))
381 ;; found that this is spam, no need to look at the 369 ;; found that this is spam, no need to look at the
382 ;; rest of the rmail-spam-definitions-alist, exit 370 ;; rest of the rsf-definitions-alist, exit
383 ;; loop: 371 ;; loop:
384 (setq exit-while-loop t) 372 (setq exit-while-loop t)
385 ;; else, spam was not yet found, increment number of 373 ;; else, spam was not yet found, increment number of
386 ;; element in rmail-spam-definitions-alist and proceed 374 ;; element in rsf-definitions-alist and proceed
387 ;; to next element: 375 ;; to next element:
388 (setq num-element (+ num-element 1))) 376 (setq num-element (+ num-element 1)))
389 ) 377 )
390 ) 378 )
379
380 ;; (BK) re-set originally used variables
381 (setq this-is-a-spam-email (rest maybe-spam)
382 maybe-spam (first maybe-spam))
383
391 (if (and this-is-a-spam-email maybe-spam) 384 (if (and this-is-a-spam-email maybe-spam)
392 (progn 385 (progn
393 ;;(message "Found spam!") 386 ;;(message "Found spam!")
@@ -397,39 +390,42 @@ it from rmail file. Called for each new message retrieved by
397 ;; output and delete the spam msg if needed: 390 ;; output and delete the spam msg if needed:
398 (setq save-current-msg rmail-current-message) 391 (setq save-current-msg rmail-current-message)
399 (setq rmail-current-message msg) 392 (setq rmail-current-message msg)
400 ;; check action item and rmail-spam-definitions-alist 393 ;; check action item and rsf-definitions-alist
401 ;; and do it: 394 ;; and do it:
402 (cond 395 (cond
403 ((equal (cdr (assoc 'action 396 ((equal (cdr (assoc 'action
404 (nth num-element rmail-spam-definitions-alist))) 397 (nth num-element rsf-definitions-alist)))
405 'output-and-delete) 398 'output-and-delete)
406 (progn 399 (progn
407 (rmail-output-to-rmail-file rmail-spam-file) 400 (rmail-output-to-rmail-file rsf-file 1 t)
408 (rmail-delete-message) 401 ;; Don't delete if automatic deletion after output
402 ;; is turned on
403 (unless rmail-delete-after-output (rmail-delete-message))
409 )) 404 ))
410 ((equal (cdr (assoc 'action 405 ((equal (cdr (assoc 'action
411 (nth num-element rmail-spam-definitions-alist))) 406 (nth num-element rsf-definitions-alist)))
412 'delete-spam) 407 'delete-spam)
413 (progn 408 (progn
414 (rmail-delete-message) 409 (rmail-delete-message)
415 )) 410 ))
416 ) 411 )
417 (setq rmail-current-message save-current-msg) 412 (setq rmail-current-message save-current-msg)
418 (setq bbdb/mail_auto_create_p 'rmail-spam-filter-saved-bbdb/mail_auto_create_p) 413 (setq bbdb/mail_auto_create_p
414 'rsf-saved-bbdb/mail_auto_create_p)
419 ;; set return value. These lines must be last in the 415 ;; set return value. These lines must be last in the
420 ;; function, so that they will determine the value 416 ;; function, so that they will determine the value
421 ;; returned by rmail-spam-filter: 417 ;; returned by rmail-spam-filter:
422 (setq return-value nil)) 418 (setq return-value nil))
423 (setq return-value t)))) 419 (setq return-value t))))
424 (setq case-fold-search saved-case-fold-search) 420 (setq case-fold-search saved-case-fold-search)
425 (setq rmail-spam-filter-scanning-messages-now nil) 421 (setq rsf-scanning-messages-now nil)
426 return-value)) 422 return-value))
427 423
428 424
429;; define functions for interactively adding sender/subject of a 425;; define functions for interactively adding sender/subject of a
430;; specific message to the spam definitions while reading it, using 426;; specific message to the spam definitions while reading it, using
431;; the menubar: 427;; the menubar:
432(defun rmail-spam-filter-add-subject-to-spam-list () 428(defun rsf-add-subject-to-spam-list ()
433 (interactive) 429 (interactive)
434 (set-buffer rmail-buffer) 430 (set-buffer rmail-buffer)
435 (let ((message-subject)) 431 (let ((message-subject))
@@ -437,15 +433,16 @@ it from rmail file. Called for each new message retrieved by
437 ;; note the use of a backquote and comma on the subject line here, 433 ;; note the use of a backquote and comma on the subject line here,
438 ;; to make sure message-subject is actually evaluated and its value 434 ;; to make sure message-subject is actually evaluated and its value
439 ;; substituted: 435 ;; substituted:
440 (add-to-list 'rmail-spam-definitions-alist 436 (add-to-list 'rsf-definitions-alist
441 (list '(from . "") 437 (list '(from . "")
442 '(to . "") 438 '(to . "")
443 `(subject . ,message-subject) 439 `(subject . ,message-subject)
440 '(content-type . "")
444 '(contents . "") 441 '(contents . "")
445 '(action . output-and-delete)) 442 '(action . output-and-delete))
446 t) 443 t)
447 (customize-mark-to-save 'rmail-spam-definitions-alist) 444 (customize-mark-to-save 'rsf-definitions-alist)
448 (if rmail-spam-filter-autosave-newly-added-spam-definitions 445 (if rsf-autosave-newly-added-definitions
449 (progn 446 (progn
450 (custom-save-all) 447 (custom-save-all)
451 (message (concat "added subject \n <<< \n" message-subject 448 (message (concat "added subject \n <<< \n" message-subject
@@ -453,10 +450,11 @@ it from rmail file. Called for each new message retrieved by
453 "and saved the spam definitions to file."))) 450 "and saved the spam definitions to file.")))
454 (message (concat "added subject \n <<< \n" message-subject 451 (message (concat "added subject \n <<< \n" message-subject
455 " \n >>> \n to list of spam definitions. \n" 452 " \n >>> \n to list of spam definitions. \n"
456 "Don't forget to save the spam definitions to file using the spam menu")) 453 "Don't forget to save the spam definitions to file using the spam
454 menu"))
457 ))) 455 )))
458 456
459(defun rmail-spam-filter-add-sender-to-spam-list () 457(defun rsf-add-sender-to-spam-list ()
460 (interactive) 458 (interactive)
461 (set-buffer rmail-buffer) 459 (set-buffer rmail-buffer)
462 (let ((message-sender)) 460 (let ((message-sender))
@@ -464,15 +462,16 @@ it from rmail file. Called for each new message retrieved by
464 ;; note the use of a backquote and comma on the "from" line here, 462 ;; note the use of a backquote and comma on the "from" line here,
465 ;; to make sure message-sender is actually evaluated and its value 463 ;; to make sure message-sender is actually evaluated and its value
466 ;; substituted: 464 ;; substituted:
467 (add-to-list 'rmail-spam-definitions-alist 465 (add-to-list 'rsf-definitions-alist
468 (list `(from . ,message-sender) 466 (list `(from . ,message-sender)
469 '(to . "") 467 '(to . "")
470 '(subject . "") 468 '(subject . "")
469 '(content-type . "")
471 '(contents . "") 470 '(contents . "")
472 '(action . output-and-delete)) 471 '(action . output-and-delete))
473 t) 472 t)
474 (customize-mark-to-save 'rmail-spam-definitions-alist) 473 (customize-mark-to-save 'rsf-definitions-alist)
475 (if rmail-spam-filter-autosave-newly-added-spam-definitions 474 (if rsf-autosave-newly-added-definitions
476 (progn 475 (progn
477 (custom-save-all) 476 (custom-save-all)
478 (message (concat "added sender \n <<< \n" message-sender 477 (message (concat "added sender \n <<< \n" message-sender
@@ -480,13 +479,14 @@ it from rmail file. Called for each new message retrieved by
480 "and saved the spam definitions to file."))) 479 "and saved the spam definitions to file.")))
481 (message (concat "added sender \n <<< \n " message-sender 480 (message (concat "added sender \n <<< \n " message-sender
482 " \n >>> \n to list of spam definitions." 481 " \n >>> \n to list of spam definitions."
483 "Don't forget to save the spam definitions to file using the spam menu")) 482 "Don't forget to save the spam definitions to file using the spam
483 menu"))
484 ))) 484 )))
485 485
486 486
487(defun rmail-spam-filter-add-region-to-spam-list () 487(defun rsf-add-region-to-spam-list ()
488 "Add the region makred by user in the rmail buffer to the list of 488 "Add the region makred by user in the rmail buffer to spam list.
489 spam definitions as a contents field." 489Added to spam definitions as a contents field."
490 (interactive) 490 (interactive)
491 (set-buffer rmail-buffer) 491 (set-buffer rmail-buffer)
492 (let ((region-to-spam-list)) 492 (let ((region-to-spam-list))
@@ -494,41 +494,48 @@ it from rmail file. Called for each new message retrieved by
494 (if (not (and mark-active (not (= (region-beginning) (region-end))))) 494 (if (not (and mark-active (not (= (region-beginning) (region-end)))))
495 ;; if inactive, print error message: 495 ;; if inactive, print error message:
496 (message "you need to first highlight some text in the rmail buffer") 496 (message "you need to first highlight some text in the rmail buffer")
497 ;; if active, add to list of spam definisions: 497 (if (< (- (region-end) (region-beginning)) rsf-min-region-to-spam-list)
498 (progn 498 (message
499 (setq region-to-spam-list (buffer-substring (region-beginning) (region-end))) 499 (concat "highlighted region is too small; min length set by variable \n"
500 ;; note the use of a backquote and comma on the "from" line here, 500 "rsf-min-region-to-spam-list"
501 ;; to make sure message-sender is actually evaluated and its value 501 " is " (number-to-string rsf-min-region-to-spam-list)))
502 ;; substituted: 502 ;; if region active and long enough, add to list of spam definisions:
503 (add-to-list 'rmail-spam-definitions-alist 503 (progn
504 (list '(from . "") 504 (setq region-to-spam-list (buffer-substring (region-beginning) (region-end)))
505 '(to . "") 505 ;; note the use of a backquote and comma on the "from" line here,
506 '(subject . "") 506 ;; to make sure message-sender is actually evaluated and its value
507 `(contents . ,region-to-spam-list) 507 ;; substituted:
508 '(action . output-and-delete)) 508 (add-to-list 'rsf-definitions-alist
509 t) 509 (list '(from . "")
510 (customize-mark-to-save 'rmail-spam-definitions-alist) 510 '(to . "")
511 (if rmail-spam-filter-autosave-newly-added-spam-definitions 511 '(subject . "")
512 (progn 512 '(content-type . "")
513 (custom-save-all) 513 `(contents . ,region-to-spam-list)
514 (message (concat "added highlighted text \n <<< \n" region-to-spam-list 514 '(action . output-and-delete))
515 " \n >>> \n to list of spam definitions. \n" 515 t)
516 "and saved the spam definitions to file."))) 516 (customize-mark-to-save 'rsf-definitions-alist)
517 (message (concat "added highlighted text \n <<< \n " region-to-spam-list 517 (if rsf-autosave-newly-added-definitions
518 " \n >>> \n to list of spam definitions." 518 (progn
519 "Don't forget to save the spam definitions to file using the spam menu")) 519 (custom-save-all)
520 ))))) 520 (message (concat "added highlighted text \n <<< \n" region-to-spam-list
521 521 " \n >>> \n to list of spam definitions. \n"
522 522 "and saved the spam definitions to file.")))
523(defun rmail-spam-filter-customize-spam-definitions () 523 (message (concat "added highlighted text \n <<< \n " region-to-spam-list
524 " \n >>> \n to list of spam definitions."
525 "Don't forget to save the spam definitions to file using the
526 spam menu"))
527 ))))))
528
529
530(defun rsf-customize-spam-definitions ()
524 (interactive) 531 (interactive)
525 (customize-variable (quote rmail-spam-definitions-alist))) 532 (customize-variable (quote rsf-definitions-alist)))
526 533
527(defun rmail-spam-filter-customize-group () 534(defun rsf-customize-group ()
528 (interactive) 535 (interactive)
529 (customize-group (quote rmail-spam-filter))) 536 (customize-group (quote rmail-spam-filter)))
530 537
531(defun rmail-spam-custom-save-all () 538(defun rsf-custom-save-all ()
532 (interactive) 539 (interactive)
533 (custom-save-all)) 540 (custom-save-all))
534 541
@@ -540,97 +547,89 @@ it from rmail file. Called for each new message retrieved by
540 (cons "Spam" (make-sparse-keymap "Spam"))) 547 (cons "Spam" (make-sparse-keymap "Spam")))
541 548
542(define-key rmail-summary-mode-map [menu-bar spam customize-group] 549(define-key rmail-summary-mode-map [menu-bar spam customize-group]
543 '("Browse customizations of rmail spam filter" . rmail-spam-filter-customize-group)) 550 '("Browse customizations of rmail spam filter" . rsf-customize-group))
544(define-key rmail-mode-map [menu-bar spam customize-group] 551(define-key rmail-mode-map [menu-bar spam customize-group]
545 '("Browse customizations of rmail spam filter" . rmail-spam-filter-customize-group)) 552 '("Browse customizations of rmail spam filter" . rsf-customize-group))
546(define-key rmail-summary-mode-map "\C-cSg" 'rmail-spam-filter-customize-group) 553(define-key rmail-summary-mode-map "\C-cSg" 'rsf-customize-group)
547(define-key rmail-mode-map "\C-cSg" 'rmail-spam-filter-customize-group) 554(define-key rmail-mode-map "\C-cSg" 'rsf-customize-group)
548 555
549(define-key rmail-summary-mode-map [menu-bar spam customize-spam-list] 556(define-key rmail-summary-mode-map [menu-bar spam customize-spam-list]
550 '("Customize list of spam definitions" . rmail-spam-filter-customize-spam-definitions)) 557 '("Customize list of spam definitions" . rsf-customize-spam-definitions))
551(define-key rmail-mode-map [menu-bar spam customize-spam-list] 558(define-key rmail-mode-map [menu-bar spam customize-spam-list]
552 '("Customize list of spam definitions" . rmail-spam-filter-customize-spam-definitions)) 559 '("Customize list of spam definitions" . rsf-customize-spam-definitions))
553(define-key rmail-summary-mode-map "\C-cSd" 'rmail-spam-filter-customize-spam-definitions) 560(define-key rmail-summary-mode-map "\C-cSd" 'rsf-customize-spam-definitions)
554(define-key rmail-mode-map "\C-cSd" 'rmail-spam-filter-customize-spam-definitions) 561(define-key rmail-mode-map "\C-cSd" 'rsf-customize-spam-definitions)
555 562
556(define-key rmail-summary-mode-map [menu-bar spam lambda] '("----")) 563(define-key rmail-summary-mode-map [menu-bar spam lambda] '("----"))
557(define-key rmail-mode-map [menu-bar spam lambda] '("----")) 564(define-key rmail-mode-map [menu-bar spam lambda] '("----"))
558 565
559(define-key rmail-summary-mode-map [menu-bar spam my-custom-save-all] 566(define-key rmail-summary-mode-map [menu-bar spam my-custom-save-all]
560 '("save newly added spam definitions to customization file" . rmail-spam-custom-save-all)) 567 '("save newly added spam definitions to customization file" . rsf-custom-save-all))
561(define-key rmail-mode-map [menu-bar spam my-custom-save-all] 568(define-key rmail-mode-map [menu-bar spam my-custom-save-all]
562 '("save newly added spam definitions to customization file" . rmail-spam-custom-save-all)) 569 '("save newly added spam definitions to customization file" . rsf-custom-save-all))
563(define-key rmail-summary-mode-map "\C-cSa" 'rmail-spam-custom-save-all) 570(define-key rmail-summary-mode-map "\C-cSa" 'rsf-custom-save-all)
564(define-key rmail-mode-map "\C-cSa" 'rmail-spam-custom-save-all) 571(define-key rmail-mode-map "\C-cSa" 'rsf-custom-save-all)
565 572
566(define-key rmail-summary-mode-map [menu-bar spam add-region-to-spam-list] 573(define-key rmail-summary-mode-map [menu-bar spam add-region-to-spam-list]
567 '("add region to spam list" . rmail-spam-filter-add-region-to-spam-list)) 574 '("add region to spam list" . rsf-add-region-to-spam-list))
568(define-key rmail-mode-map [menu-bar spam add-region-to-spam-list] 575(define-key rmail-mode-map [menu-bar spam add-region-to-spam-list]
569 '("add region to spam list" . rmail-spam-filter-add-region-to-spam-list)) 576 '("add region to spam list" . rsf-add-region-to-spam-list))
570(define-key rmail-summary-mode-map "\C-cSn" 'rmail-spam-filter-add-region-to-spam-list) 577(define-key rmail-summary-mode-map "\C-cSn" 'rsf-add-region-to-spam-list)
571(define-key rmail-mode-map "\C-cSn" 'rmail-spam-filter-add-region-to-spam-list) 578(define-key rmail-mode-map "\C-cSn" 'rsf-add-region-to-spam-list)
572 579
573(define-key rmail-summary-mode-map [menu-bar spam add-sender-to-spam-list] 580(define-key rmail-summary-mode-map [menu-bar spam add-sender-to-spam-list]
574 '("add sender to spam list" . rmail-spam-filter-add-sender-to-spam-list)) 581 '("add sender to spam list" . rsf-add-sender-to-spam-list))
575(define-key rmail-mode-map [menu-bar spam add-sender-to-spam-list] 582(define-key rmail-mode-map [menu-bar spam add-sender-to-spam-list]
576 '("add sender to spam list" . rmail-spam-filter-add-sender-to-spam-list)) 583 '("add sender to spam list" . rsf-add-sender-to-spam-list))
577(define-key rmail-summary-mode-map "\C-cSr" 'rmail-spam-filter-add-sender-to-spam-list) 584(define-key rmail-summary-mode-map "\C-cSr" 'rsf-add-sender-to-spam-list)
578(define-key rmail-mode-map "\C-cSr" 'rmail-spam-filter-add-sender-to-spam-list) 585(define-key rmail-mode-map "\C-cSr" 'rsf-add-sender-to-spam-list)
579 586
580(define-key rmail-summary-mode-map [menu-bar spam add-subject-to-spam-list] 587(define-key rmail-summary-mode-map [menu-bar spam add-subject-to-spam-list]
581 '("add subject to spam list" . rmail-spam-filter-add-subject-to-spam-list)) 588 '("add subject to spam list" . rsf-add-subject-to-spam-list))
582(define-key rmail-mode-map [menu-bar spam add-subject-to-spam-list] 589(define-key rmail-mode-map [menu-bar spam add-subject-to-spam-list]
583 '("add subject to spam list" . rmail-spam-filter-add-subject-to-spam-list)) 590 '("add subject to spam list" . rsf-add-subject-to-spam-list))
584(define-key rmail-summary-mode-map "\C-cSt" 'rmail-spam-filter-add-subject-to-spam-list) 591(define-key rmail-summary-mode-map "\C-cSt" 'rsf-add-subject-to-spam-list)
585(define-key rmail-mode-map "\C-cSt" 'rmail-spam-filter-add-subject-to-spam-list) 592(define-key rmail-mode-map "\C-cSt" 'rsf-add-subject-to-spam-list)
586 593
587 594(defun rsf-add-content-type-field ()
588(defun rmail-bbdb-auto-delete-spam-entries () 595 "Maintain backward compatibility with previous versions of rmail-spam-filter.
589 "When deleting a message in RMAIL, check to see if the bbdb entry 596The most recent version of rmai-spam-filter checks the contents
590was created today, and if it was, prompt to delete it too. This function 597field of the incoming mail to see if it spam. The format of
591needs to be called via the `rmail-delete-message-hook' like this: 598`rsf-definitions-alist' has therefore changed. This function
592\(add-hook 'rmail-delete-message-hook 'rmail-bbdb-auto-delete-spam-entries)" 599checks to see if old format is used, and if it is, it converts
593 (interactive) 600`rsf-definitions-alist' to the new format. Invoked
594 (require 'bbdb-hooks) 601automatically, no user input is required."
595 (if (not rmail-spam-filter-scanning-messages-now)
596 (if (get-buffer "*BBDB*")
597 (save-excursion
598 (set-buffer (get-buffer "*BBDB*"))
599 (if (bbdb-current-record)
600 (if (equal
601 (format-time-string bbdb-time-internal-format (current-time))
602 (bbdb-record-getprop (bbdb-current-record) 'creation-date))
603 (bbdb-delete-current-record (bbdb-current-record))))))))
604
605(defun rmail-spam-filter-bbdb-dont-create-entries-for-spam ()
606 "Make sure senderes of rmail messages marked as deleted are not added to bbdb.
607Need to add this as a hook like this:
608\(setq bbdb/mail-auto-create-p 'rmail-spam-filter-bbdb-dont-create-entries-for-spam)
609and this is also used in conjunction with rmail-bbdb-auto-delete-spam-entries.
610More doc: rmail-bbdb-auto-delete-spam-entries will delete newly created bbdb
611entries of mail that is deleted. However, if one scrolls back to the deleted
612messages, then the sender is again added to the bbdb. This function
613prevents this. Also, don't create entries for messages in the `rmail-spam-file'."
614 (interactive) 602 (interactive)
615 (not 603 (if (and rsf-definitions-alist
616 ;; don't create a bbdb entry if one of the following conditions is satisfied: 604 (not (assoc 'content-type (car rsf-definitions-alist))))
617 (or 605 (let ((result nil)
618 ;; 1) looking at a deleted message: 606 (current nil)
619 (rmail-message-deleted-p rmail-current-message) 607 (definitions rsf-definitions-alist))
620 ;; 2) looking at messages in rmail-spam-file: 608 (while definitions
621 (string-match 609 (setq current (car definitions))
622 (expand-file-name rmail-spam-file) 610 (setq definitions (cdr definitions))
623 (expand-file-name (buffer-file-name rmail-buffer))) 611 (setq result
624 ))) 612 (append result
625 613 (list
626;; activate bbdb-anti-spam measures: 614 (list (assoc 'from current)
627(if rmail-spam-filter-auto-delete-spam-bbdb-entries 615 (assoc 'to current)
628 (progn 616 (assoc 'subject current)
629 (add-hook 'rmail-delete-message-hook 'rmail-bbdb-auto-delete-spam-entries) 617 (cons 'content-type "")
630 (setq bbdb/mail-auto-create-p 'rmail-spam-filter-bbdb-dont-create-entries-for-spam) 618 (assoc 'contents current)
631 )) 619 (assoc 'action current))))))
620 (setq rsf-definitions-alist result)
621 (customize-mark-to-save 'rsf-definitions-alist)
622 (if rsf-autosave-newly-added-definitions
623 (progn
624 (custom-save-all)
625 (message (concat "converted spam definitions to new format\n"
626 "and saved the spam definitions to file.")))
627 (message (concat "converted spam definitions to new format\n"
628 "Don't forget to save the spam definitions to file using the
629 spam menu"))
630 ))))
632 631
633(provide 'rmail-spam-filter) 632(provide 'rmail-spam-filter)
634 633
635;;; arch-tag: 03e1d45d-b72f-4dd7-8f04-e7fd78249746 634;;; arch-tag: 03e1d45d-b72f-4dd7-8f04-e7fd78249746
636;;; rmail-spam-filter.el ends here 635;;; rmail-spam-fitler ends here
diff --git a/lisp/progmodes/executable.el b/lisp/progmodes/executable.el
index 21f894753a1..b301d84d144 100644
--- a/lisp/progmodes/executable.el
+++ b/lisp/progmodes/executable.el
@@ -1,6 +1,6 @@
1;;; executable.el --- base functionality for executable interpreter scripts -*- byte-compile-dynamic: t -*- 1;;; executable.el --- base functionality for executable interpreter scripts -*- byte-compile-dynamic: t -*-
2 2
3;; Copyright (C) 1994, 1995, 1996, 2000, 2003 by Free Software Foundation, Inc. 3;; Copyright (C) 1994, 1995, 1996, 2000, 2003, 2004 by Free Software Foundation, Inc.
4 4
5;; Author: Daniel Pfeiffer <occitan@esperanto.org> 5;; Author: Daniel Pfeiffer <occitan@esperanto.org>
6;; Keywords: languages, unix 6;; Keywords: languages, unix
@@ -141,6 +141,31 @@ See `compilation-error-regexp-alist'.")
141(defvaralias 'executable-binary-suffixes 'exec-suffixes) 141(defvaralias 'executable-binary-suffixes 'exec-suffixes)
142 142
143;;;###autoload 143;;;###autoload
144(defun executable-command-find-posix-p (&optional program)
145 "Check if PROGRAM handles arguments Posix-style.
146If PROGRAM is non-nil, use that instead of \"find\"."
147 ;; Pick file to search from location we know
148 (let* ((dir (car load-path))
149 (file (find-if
150 (lambda (x)
151 ;; Filter directories . and ..
152 (not (string-match "^\\.\\.?$" x)))
153 (directory-files dir))))
154 (with-temp-buffer
155 (call-process (or program "find")
156 nil
157 (current-buffer)
158 nil
159 dir
160 "-name"
161 file
162 "-maxdepth"
163 "1")
164 (goto-char (point-min))
165 (if (search-forward file nil t)
166 t))))
167
168;;;###autoload
144(defun executable-find (command) 169(defun executable-find (command)
145 "Search for COMMAND in `exec-path' and return the absolute file name. 170 "Search for COMMAND in `exec-path' and return the absolute file name.
146Return nil if COMMAND is not found anywhere in `exec-path'." 171Return nil if COMMAND is not found anywhere in `exec-path'."
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index cb8fcf6e042..279d7211cdd 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -318,7 +318,12 @@ Sets `grep-last-buffer' and runs `grep-setup-hook'."
318 'gnu))) 318 'gnu)))
319 (unless grep-find-command 319 (unless grep-find-command
320 (setq grep-find-command 320 (setq grep-find-command
321 (cond ((eq grep-find-use-xargs 'gnu) 321 (cond ((not (executable-command-find-unix-p "find"))
322 (message
323 (concat "compile.el: Unix type find(1) not found. "
324 "Please set `grep-find-command'."))
325 nil)
326 ((eq grep-find-use-xargs 'gnu)
322 (format "%s . -type f -print0 | xargs -0 -e %s" 327 (format "%s . -type f -print0 | xargs -0 -e %s"
323 find-program grep-command)) 328 find-program grep-command))
324 (grep-find-use-xargs 329 (grep-find-use-xargs
@@ -443,11 +448,17 @@ easily repeat a find command."
443 (progn 448 (progn
444 (unless grep-find-command 449 (unless grep-find-command
445 (grep-compute-defaults)) 450 (grep-compute-defaults))
446 (list (read-from-minibuffer "Run find (like this): " 451 (if grep-find-command
447 grep-find-command nil nil 452 (list (read-from-minibuffer "Run find (like this): "
448 'grep-find-history)))) 453 grep-find-command nil nil
449 (let ((null-device nil)) ; see grep 454 'grep-find-history))
450 (grep command-args))) 455 ;; No default was set
456 (read-string
457 "compile.el: No `grep-find-command' command available. Press RET.")
458 (list nil))))
459 (when (and grep-find-command command-args)
460 (let ((null-device nil)) ; see grep
461 (grep command-args))))
451 462
452(defun grep-expand-command-macros (command &optional regexp files dir excl case-fold) 463(defun grep-expand-command-macros (command &optional regexp files dir excl case-fold)
453 "Patch grep COMMAND replacing <D>, etc." 464 "Patch grep COMMAND replacing <D>, etc."
diff --git a/lisp/replace.el b/lisp/replace.el
index 0c89c22b1fa..e8ecef12039 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -223,7 +223,7 @@ Fourth and fifth arg START and END specify the region to operate on."
223 (if (and transient-mark-mode mark-active) 223 (if (and transient-mark-mode mark-active)
224 (region-end))))) 224 (region-end)))))
225 (perform-replace regexp (cons 'replace-eval-replacement to-expr) 225 (perform-replace regexp (cons 'replace-eval-replacement to-expr)
226 t t delimited nil nil start end)) 226 t 'literal delimited nil nil start end))
227 227
228(defun map-query-replace-regexp (regexp to-strings &optional n start end) 228(defun map-query-replace-regexp (regexp to-strings &optional n start end)
229 "Replace some matches for REGEXP with various strings, in rotation. 229 "Replace some matches for REGEXP with various strings, in rotation.
@@ -1057,7 +1057,7 @@ make, or the user didn't cancel the call."
1057 (case-fold-search (and case-fold-search 1057 (case-fold-search (and case-fold-search
1058 (string-equal from-string 1058 (string-equal from-string
1059 (downcase from-string)))) 1059 (downcase from-string))))
1060 (literal (not regexp-flag)) 1060 (literal (or (not regexp-flag) (eq regexp-flag 'literal)))
1061 (search-function (if regexp-flag 're-search-forward 'search-forward)) 1061 (search-function (if regexp-flag 're-search-forward 'search-forward))
1062 (search-string from-string) 1062 (search-string from-string)
1063 (real-match-data nil) ; the match data for the current match 1063 (real-match-data nil) ; the match data for the current match
diff --git a/lisp/server.el b/lisp/server.el
index 315a1545cf5..6d59b0d69c7 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1,6 +1,6 @@
1;;; server.el --- Lisp code for GNU Emacs running as server process 1;;; server.el --- Lisp code for GNU Emacs running as server process
2 2
3;; Copyright (C) 1986,87,92,94,95,96,97,98,99,2000,01,02,2003 3;; Copyright (C) 1986,87,92,94,95,96,97,98,99,2000,01,02,03,2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: William Sommerfeld <wesommer@athena.mit.edu> 6;; Author: William Sommerfeld <wesommer@athena.mit.edu>
@@ -168,8 +168,7 @@ are done with it in the server.")
168(make-variable-buffer-local 'server-existing-buffer) 168(make-variable-buffer-local 'server-existing-buffer)
169 169
170(defvar server-socket-name 170(defvar server-socket-name
171 (format "/tmp/emacs%d-%s/server" (user-uid) 171 (format "/tmp/emacs%d/server" (user-uid)))
172 (substring (system-name) 0 (string-match "\\." (system-name)))))
173 172
174(defun server-log (string &optional client) 173(defun server-log (string &optional client)
175 "If a *server* buffer exists, write STRING to it for logging purposes." 174 "If a *server* buffer exists, write STRING to it for logging purposes."
diff --git a/lisp/ses.el b/lisp/ses.el
index d799be032ab..a56b1b5c87a 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -1,6 +1,6 @@
1;;;; ses.el -- Simple Emacs Spreadsheet 1;;;; ses.el -- Simple Emacs Spreadsheet
2 2
3;; Copyright (C) 2002 Free Software Foundation, Inc. 3;; Copyright (C) 2002,03,04 Free Software Foundation, Inc.
4 4
5;; Author: Jonathan Yavner <jyavner@member.fsf.org> 5;; Author: Jonathan Yavner <jyavner@member.fsf.org>
6;; Maintainer: Jonathan Yavner <jyavner@member.fsf.org> 6;; Maintainer: Jonathan Yavner <jyavner@member.fsf.org>
@@ -720,11 +720,23 @@ preceding cell has spilled over."
720 ;;Fill to complete width of all the fields spanned 720 ;;Fill to complete width of all the fields spanned
721 (setq text (concat text (make-string (- maxwidth len) ? ))) 721 (setq text (concat text (make-string (- maxwidth len) ? )))
722 ;;Not enough room to end of line or next non-nil field. Truncate 722 ;;Not enough room to end of line or next non-nil field. Truncate
723 ;;if string; otherwise fill with error indicator 723 ;;if string or decimal; otherwise fill with error indicator
724 (setq sig `(error "Too wide" ,text)) 724 (setq sig `(error "Too wide" ,text))
725 (if (stringp value) 725 (cond
726 (setq text (substring text 0 maxwidth)) 726 ((stringp value)
727 (setq text (make-string maxwidth ?#)))))))) 727 (setq text (substring text 0 maxwidth)))
728 ((and (numberp value)
729 (string-match "\\.[0-9]+" text)
730 (>= 0 (setq width
731 (- len maxwidth
732 (- (match-end 0) (match-beginning 0))))))
733 ;; Turn 6.6666666666e+49 into 6.66e+49. Rounding is too hard!
734 (setq text (concat (substring text
735 0
736 (- (match-beginning 0) width))
737 (substring text (match-end 0)))))
738 (t
739 (setq text (make-string maxwidth ?#)))))))))
728 ;;Substitute question marks for tabs and newlines. Newlines are 740 ;;Substitute question marks for tabs and newlines. Newlines are
729 ;;used as row-separators; tabs could confuse the reimport logic. 741 ;;used as row-separators; tabs could confuse the reimport logic.
730 (setq text (replace-regexp-in-string "[\t\n]" "?" text)) 742 (setq text (replace-regexp-in-string "[\t\n]" "?" text))
diff --git a/lisp/simple.el b/lisp/simple.el
index 3d2be573012..23d5e2c3440 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -678,15 +678,17 @@ the echo area."
678COMMAND is a Lisp expression. Let user edit that expression in 678COMMAND is a Lisp expression. Let user edit that expression in
679the minibuffer, then read and evaluate the result." 679the minibuffer, then read and evaluate the result."
680 (let ((command 680 (let ((command
681 (unwind-protect 681 (let ((print-level nil)
682 (read-from-minibuffer prompt 682 (minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
683 (prin1-to-string command) 683 (unwind-protect
684 read-expression-map t 684 (read-from-minibuffer prompt
685 '(command-history . 1)) 685 (prin1-to-string command)
686 ;; If command was added to command-history as a string, 686 read-expression-map t
687 ;; get rid of that. We want only evaluable expressions there. 687 'command-history)
688 (if (stringp (car command-history)) 688 ;; If command was added to command-history as a string,
689 (setq command-history (cdr command-history)))))) 689 ;; get rid of that. We want only evaluable expressions there.
690 (if (stringp (car command-history))
691 (setq command-history (cdr command-history)))))))
690 692
691 ;; If command to be redone does not match front of history, 693 ;; If command to be redone does not match front of history,
692 ;; add it to the history. 694 ;; add it to the history.
diff --git a/lisp/term.el b/lisp/term.el
index b329004c083..b1144268a09 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -1172,6 +1172,7 @@ without any interpretation."
1172 ;; Give temporary modes such as isearch a chance to turn off. 1172 ;; Give temporary modes such as isearch a chance to turn off.
1173 (run-hooks 'mouse-leave-buffer-hook) 1173 (run-hooks 'mouse-leave-buffer-hook)
1174 (setq this-command 'yank) 1174 (setq this-command 'yank)
1175 (mouse-set-point click)
1175 (term-send-raw-string (current-kill (cond 1176 (term-send-raw-string (current-kill (cond
1176 ((listp arg) 0) 1177 ((listp arg) 0)
1177 ((eq arg '-) -1) 1178 ((eq arg '-) -1)
diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el
index c69aa01c356..cdba8a9445f 100644
--- a/lisp/term/x-win.el
+++ b/lisp/term/x-win.el
@@ -2201,8 +2201,10 @@ order until succeed.")
2201 (error nil)) 2201 (error nil))
2202 utf8-coding last-coding-system-used) 2202 utf8-coding last-coding-system-used)
2203 (if utf8 2203 (if utf8
2204 ;; If it is a locale selection, choose it. 2204 ;; If it is a local selection, or it contains only
2205 (or (get-text-property 0 'foreign-selection utf8) 2205 ;; ASCII characers, choose it.
2206 (if (or (not (get-text-property 0 'foreign-selection utf8))
2207 (= (length utf8) (string-bytes utf8)))
2206 (setq text utf8))) 2208 (setq text utf8)))
2207 ;; If not yet decided, try COMPOUND_TEXT. 2209 ;; If not yet decided, try COMPOUND_TEXT.
2208 (if (not text) 2210 (if (not text)
diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el
index 69b17f677ff..5aded4a85e8 100644
--- a/lisp/textmodes/fill.el
+++ b/lisp/textmodes/fill.el
@@ -423,9 +423,13 @@ Point is moved to just past the fill prefix on the first line."
423 ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" sentence-end) 423 ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" sentence-end)
424 (concat (replace-match ".:" nil nil sentence-end 1) "$")) 424 (concat (replace-match ".:" nil nil sentence-end 1) "$"))
425 ;; Can't find the right spot to insert the colon. 425 ;; Can't find the right spot to insert the colon.
426 (t "[.?!:][])}\"']*$")))) 426 (t "[.?!:][])}\"']*$")))
427 (sentence-end-without-space-list
428 (string-to-list sentence-end-without-space)))
427 (while (re-search-forward eol-double-space-re to t) 429 (while (re-search-forward eol-double-space-re to t)
428 (or (>= (point) to) (memq (char-before) '(?\t ?\ )) 430 (or (>= (point) to) (memq (char-before) '(?\t ?\ ))
431 (memq (char-after (match-beginning 0))
432 sentence-end-without-space-list)
429 (insert-and-inherit ?\ )))) 433 (insert-and-inherit ?\ ))))
430 434
431 (goto-char from) 435 (goto-char from)
diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el
index 97abc2c1583..0c5d969105f 100644
--- a/lisp/textmodes/paragraphs.el
+++ b/lisp/textmodes/paragraphs.el
@@ -132,14 +132,23 @@ without a period."
132 :type 'boolean 132 :type 'boolean
133 :group 'fill) 133 :group 'fill)
134 134
135(defcustom sentence-end-without-space
136 "$B!#!%!)!*$A!##.#?#!$(0!$!%!)!*$(G!$!%!)!*(B"
137 "*String containing characters that end sentence without following spaces.
138If you change this, you should also change `sentence-end'. See Info
139node `Sentences'."
140 :group 'paragraphs
141 :type 'string)
142
135(defcustom sentence-end 143(defcustom sentence-end
136 (purecopy 144 (purecopy
137 ;; This is a bit stupid since it's not auto-updated when the 145 ;; This is a bit stupid since it's not auto-updated when the
138 ;; other variables are changes, but it's still useful info. 146 ;; other variables are changes, but it's still useful info.
139 (concat (if sentence-end-without-period "\\w \\|") 147 (concat (if sentence-end-without-period "\\w \\|")
140 "[.?!$B!#!%!)!*$A!##.#?#!$(0!$!%!)!*$(G!$!%!)!*(B][]\"')}]*" 148 "\\([.?!][]\"')}]*"
141 (if sentence-end-double-space 149 (if sentence-end-double-space
142 "\\($\\| $\\|\t\\| \\)" "\\($\\|[\t ]\\)") 150 "\\($\\| $\\|\t\\| \\)" "\\($\\|[\t ]\\)")
151 "\\|[" sentence-end-without-space "]+\\)"
143 "[ \t\n]*")) 152 "[ \t\n]*"))
144 "*Regexp describing the end of a sentence. 153 "*Regexp describing the end of a sentence.
145The value includes the whitespace following the sentence. 154The value includes the whitespace following the sentence.
diff --git a/lispref/ChangeLog b/lispref/ChangeLog
index 88ec3ca1338..20dd4f13d03 100644
--- a/lispref/ChangeLog
+++ b/lispref/ChangeLog
@@ -1,3 +1,10 @@
12004-01-26 Luc Teirlinck <teirllm@auburn.edu>
2
3 * strings.texi (Text Comparison): assoc-string also matches
4 elements of alists that are strings instead of conses.
5 (Formatting Strings): Standardize Texinfo usage. Update index
6 entries.
7
12004-01-20 Luc Teirlinck <teirllm@auburn.edu> 82004-01-20 Luc Teirlinck <teirllm@auburn.edu>
2 9
3 * lists.texi (Sets And Lists): Add delete-dups. 10 * lists.texi (Sets And Lists): Add delete-dups.
diff --git a/lispref/strings.texi b/lispref/strings.texi
index 60a74313a85..a29e84f8edd 100644
--- a/lispref/strings.texi
+++ b/lispref/strings.texi
@@ -293,7 +293,7 @@ null strings are always omitted from the result. Thus:
293@end example 293@end example
294 294
295The result is not @samp{("" "two" "words" "")}, which would rarely be 295The result is not @samp{("" "two" "words" "")}, which would rarely be
296useful. If you need such a result, use an explict value for 296useful. If you need such a result, use an explicit value for
297@var{separators}: 297@var{separators}:
298 298
299@example 299@example
@@ -530,6 +530,9 @@ portion) is less.
530This function works like @code{assoc}, except that @var{key} must be a 530This function works like @code{assoc}, except that @var{key} must be a
531string, and comparison is done using @code{compare-strings}. If 531string, and comparison is done using @code{compare-strings}. If
532@var{case-fold} is non-@code{nil}, it ignores case differences. 532@var{case-fold} is non-@code{nil}, it ignores case differences.
533Unlike @code{assoc}, this function can also match elements of the alist
534that are strings rather than conses. In particular, @var{alist} can
535be a list of strings rather than an actual alist.
533@xref{Association Lists}. 536@xref{Association Lists}.
534@end defun 537@end defun
535 538
@@ -795,21 +798,20 @@ operation} error.
795@end group 798@end group
796@end example 799@end example
797 800
798@cindex numeric prefix
799@cindex field width 801@cindex field width
800@cindex padding 802@cindex padding
801 All the specification characters allow an optional ``width'', which 803 All the specification characters allow an optional ``width'', which
802is a digit-string between the @samp{%} and the character. If the 804is a digit-string between the @samp{%} and the character. If the
803printed representation of the object contains fewer characters than 805printed representation of the object contains fewer characters than
804this width, then it is padded. The padding is on the left if the 806this width, then it is padded. The padding is on the left if the
805prefix is positive (or starts with zero) and on the right if the 807width is positive (or starts with zero) and on the right if the
806prefix is negative. The padding character is normally a space, but if 808width is negative. The padding character is normally a space, but if
807the width starts with a zero, zeros are used for padding. Some of 809the width starts with a zero, zeros are used for padding. Some of
808these conventions are ignored for specification characters for which 810these conventions are ignored for specification characters for which
809they do not make sense. That is, %s, %S and %c accept a width 811they do not make sense. That is, @samp{%s}, @samp{%S} and @samp{%c}
810starting with 0, but still pad with @emph{spaces} on the left. Also, 812accept a width starting with 0, but still pad with @emph{spaces} on
811%% accepts a width, but ignores it. Here are some examples of 813the left. Also, @samp{%%} accepts a width, but ignores it. Here are
812padding: 814some examples of padding:
813 815
814@example 816@example
815(format "%06d is padded on the left with zeros" 123) 817(format "%06d is padded on the left with zeros" 123)
@@ -849,27 +851,31 @@ not truncated. In the third case, the padding is on the right.
849@end group 851@end group
850@end smallexample 852@end smallexample
851 853
854@cindex precision in format specifications
852 All the specification characters allow an optional ``precision'' 855 All the specification characters allow an optional ``precision''
853before the character (after the width, if present). The precision is 856before the character (after the width, if present). The precision is
854a decimal-point @samp{.} followed by a digit-string. For the 857a decimal-point @samp{.} followed by a digit-string. For the
855floating-point specifications (%e, %f, %g), the precision specifies 858floating-point specifications (@samp{%e}, @samp{%f}, @samp{%g}), the
856how many decimal places to show; if zero, the decimal-point itself is 859precision specifies how many decimal places to show; if zero, the
857also omitted. For %s and %S, the precision truncates the string to 860decimal-point itself is also omitted. For @samp{%s} and @samp{%S},
858the given width, so @code{"%.3s"} shows only the first three 861the precision truncates the string to the given width, so
859characters of the representation for @var{object}. Precision is 862@samp{%.3s} shows only the first three characters of the
860ignored for other specification characters. 863representation for @var{object}. Precision is ignored for other
861 864specification characters.
862Immediately after the % and before the optional width and precision, 865
863you can put certain ``flag'' characters. 866@cindex flags in format specifications
864 867Immediately after the @samp{%} and before the optional width and
865A space @var{" "} inserts a space for positive numbers (otherwise 868precision, you can put certain ``flag'' characters.
869
870A space character inserts a space for positive numbers (otherwise
866nothing is inserted for positive numbers). This flag is ignored 871nothing is inserted for positive numbers). This flag is ignored
867except for %d, %e, %f, %g. 872except for @samp{%d}, @samp{%e}, @samp{%f}, @samp{%g}.
868 873
869The flag @var{"#"} indicates ``alternate form''. For %o it ensures 874The flag @samp{#} indicates ``alternate form''. For @samp{%o} it
870that the result begins with a 0. For %x and %X the result is prefixed 875ensures that the result begins with a 0. For @samp{%x} and @samp{%X}
871with ``0x'' or ``0X''. For %e, %f, and %g a decimal point is always 876the result is prefixed with @samp{0x} or @samp{0X}. For @samp{%e},
872shown even if the precision is zero. 877@samp{%f}, and @samp{%g} a decimal point is always shown even if the
878precision is zero.
873 879
874@node Case Conversion 880@node Case Conversion
875@comment node-name, next, previous, up 881@comment node-name, next, previous, up
@@ -1035,7 +1041,7 @@ and @samp{A} are related by case-conversion, they should have the same
1035canonical equivalent character (which should be either @samp{a} for both 1041canonical equivalent character (which should be either @samp{a} for both
1036of them, or @samp{A} for both of them). 1042of them, or @samp{A} for both of them).
1037 1043
1038 The extra table @var{equivalences} is a map that cyclicly permutes 1044 The extra table @var{equivalences} is a map that cyclically permutes
1039each equivalence class (of characters with the same canonical 1045each equivalence class (of characters with the same canonical
1040equivalent). (For ordinary @acronym{ASCII}, this would map @samp{a} into 1046equivalent). (For ordinary @acronym{ASCII}, this would map @samp{a} into
1041@samp{A} and @samp{A} into @samp{a}, and likewise for each set of 1047@samp{A} and @samp{A} into @samp{a}, and likewise for each set of
diff --git a/nt/ChangeLog b/nt/ChangeLog
index 4a51c1ab4ee..91fb3f510c1 100644
--- a/nt/ChangeLog
+++ b/nt/ChangeLog
@@ -1,12 +1,16 @@
12004-01-28 Peter Runestig <peter@runestig.com>
2
3 * gmake.defs, nmake.defs: Add linking to ``winspool.lib''.
4
12003-12-24 Miles Bader <miles@gnu.ai.mit.edu> 52003-12-24 Miles Bader <miles@gnu.ai.mit.edu>
2 6
3 * .cvsignore: Add `.arch-inventory'. 7 * .cvsignore: Add `.arch-inventory'.
4 8
52003-11-22 Lars Hansen <larsh@math.ku.dk> 92003-11-22 Lars Hansen <larsh@math.ku.dk>
6 10
7 * inc/grp.h: Added. 11 * inc/grp.h: Added.
8 12
92003-09-03 Peter Runestig <peter@runestig.com> 132003-09-03 Peter Runestig <peter@runestig.com>
10 14
11 * configure.bat: Create ``makefile'' in directories man, lispref 15 * configure.bat: Create ``makefile'' in directories man, lispref
12 and lispintro. 16 and lispintro.
diff --git a/nt/gmake.defs b/nt/gmake.defs
index 0bf3f48dd6e..7fe580426a8 100644
--- a/nt/gmake.defs
+++ b/nt/gmake.defs
@@ -177,6 +177,7 @@ SHELL32 = -lshell32
177USER32 = -luser32 177USER32 = -luser32
178WSOCK32 = -lwsock32 178WSOCK32 = -lwsock32
179WINMM = -lwinmm 179WINMM = -lwinmm
180WINSPOOL = -lwinspool
180 181
181ifdef NOOPT 182ifdef NOOPT
182DEBUG_CFLAGS = -DEMACSDEBUG 183DEBUG_CFLAGS = -DEMACSDEBUG
diff --git a/nt/nmake.defs b/nt/nmake.defs
index f18b9e06405..aef2b6cf472 100644
--- a/nt/nmake.defs
+++ b/nt/nmake.defs
@@ -124,6 +124,7 @@ SHELL32 = shell32.lib
124USER32 = user32.lib 124USER32 = user32.lib
125WSOCK32 = wsock32.lib 125WSOCK32 = wsock32.lib
126WINMM = winmm.lib 126WINMM = winmm.lib
127WINSPOOL = winspool.lib
127 128
128!ifdef NOOPT 129!ifdef NOOPT
129DEBUG_CFLAGS = -DEMACSDEBUG 130DEBUG_CFLAGS = -DEMACSDEBUG
diff --git a/src/ChangeLog b/src/ChangeLog
index a71cb27cf33..9a93ac894ca 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,73 @@
12004-02-02 Kenichi Handa <handa@m17n.org>
2
3 * coding.c (coding_restore_composition): Check invalid
4 composition data more rigidly.
5
62004-01-30 Luc Teirlinck <teirllm@auburn.edu>
7
8 * fileio.c (Fread_file_name_internal): Correctly handle the case
9 where insert-default-directory is nil.
10 (Fread_file_name): Always return an empty string if the user exits
11 with an empty minibuffer. Adapt the docstring accordingly.
12 (syms_of_fileio): Adapt the docstring of insert-default-directory
13 to the change in Fread_file_name.
14
152004-01-29 Eli Zaretskii <eliz@elta.co.il>
16
17 * alloca.c [!alloca]: Fix the prototype for xfree.
18
192004-01-29 Kenichi Handa <handa@m17n.org>
20
21 * fns.c (string_char_to_byte): Optimize for ASCII only string.
22 (string_byte_to_char): Likewise.
23
242004-01-28 Peter Runestig <peter@runestig.com>
25
26 * makefile.w32-in, w32fns.c: Add `default-printer-name' function.
27
282004-01-27 Steven Tamm <steventamm@mac.com>
29
30 * unexmacosx.c (unexec_copy): Do not copy more than was
31 requested to prevent overwriting during unexec.
32
332004-01-27 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
34
35 * process.c (sigchld_handler): Add comment about not calling malloc.
36
37 * process.h: Add extern to synch_process_termsig.
38
392004-01-27 Steven Tamm <steventamm@mac.com>
40
41 * macterm.c (make_mac_frame, make_mac_terminal_frame): Move
42 setting of scroll bars from make_mac_frame to
43 make_mac_terminal_frame to prevent clobbering of
44 scroll-bar-mode.
45
462004-01-26 Richard M. Stallman <rms@gnu.org>
47
48 * search.c (Freplace_match): Handle nonexistent
49 back-references properly.
50
512004-01-03 Richard M. Stallman <rms@gnu.org>
52
53 * window.c (decode_any_window): New function.
54 (Fwindow_height, Fwindow_width, Fwindow_edges)
55 (Fwindow_pixel_edges, Fwindow_inside_edges)
56 (Fwindow_inside_pixel_edges): Use decode_any_window.
57
582004-01-27 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
59
60 * process.h: synch_process_termsig new variable.
61
62 * callproc.c: Define synch_process_termsig.
63 (Fcall_process): Initiate synch_process_termsig to zero and
64 check if non-zero and get signal name after subprocess has ended.
65
66 * process.c (sigchld_handler): Set synch_process_termsig
67 if terminated by a signal. synch_process_death setting removed.
68
69 * sysdep.c (mkdir, rmdir): Also check synch_process_termsig.
70
12004-01-26 Andreas Schwab <schwab@suse.de> 712004-01-26 Andreas Schwab <schwab@suse.de>
2 72
3 * print.c (print_preprocess): Declare size as EMACS_INT to not 73 * print.c (print_preprocess): Declare size as EMACS_INT to not
diff --git a/src/alloca.c b/src/alloca.c
index 460d0ae9a54..e8c8319adc4 100644
--- a/src/alloca.c
+++ b/src/alloca.c
@@ -100,7 +100,7 @@ typedef POINTER_TYPE *pointer;
100# define free xfree 100# define free xfree
101 101
102void *xmalloc _P ((size_t)); 102void *xmalloc _P ((size_t));
103void xfree _P ((void *)) 103void xfree _P ((void *));
104 104
105/* Define STACK_DIRECTION if you know the direction of stack 105/* Define STACK_DIRECTION if you know the direction of stack
106 growth for your system; otherwise it will be automatically 106 growth for your system; otherwise it will be automatically
diff --git a/src/callproc.c b/src/callproc.c
index 00068a908fb..73d81d81b18 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -123,6 +123,9 @@ int synch_process_alive;
123/* Nonzero => this is a string explaining death of synchronous subprocess. */ 123/* Nonzero => this is a string explaining death of synchronous subprocess. */
124char *synch_process_death; 124char *synch_process_death;
125 125
126/* Nonzero => this is the signal number that terminated the subprocess. */
127int synch_process_termsig;
128
126/* If synch_process_death is zero, 129/* If synch_process_death is zero,
127 this is exit code of synchronous subprocess. */ 130 this is exit code of synchronous subprocess. */
128int synch_process_retcode; 131int synch_process_retcode;
@@ -506,6 +509,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
506 to avoid timing error if process terminates soon. */ 509 to avoid timing error if process terminates soon. */
507 synch_process_death = 0; 510 synch_process_death = 0;
508 synch_process_retcode = 0; 511 synch_process_retcode = 0;
512 synch_process_termsig = 0;
509 513
510 if (NILP (error_file)) 514 if (NILP (error_file))
511 fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); 515 fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0);
@@ -977,6 +981,19 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
977 981
978 unbind_to (count, Qnil); 982 unbind_to (count, Qnil);
979 983
984 if (synch_process_termsig)
985 {
986 char *signame;
987
988 synchronize_system_messages_locale ();
989 signame = strsignal (synch_process_termsig);
990
991 if (signame == 0)
992 signame = "unknown";
993
994 synch_process_death = signame;
995 }
996
980 if (synch_process_death) 997 if (synch_process_death)
981 return code_convert_string_norecord (build_string (synch_process_death), 998 return code_convert_string_norecord (build_string (synch_process_death),
982 Vlocale_coding_system, 0); 999 Vlocale_coding_system, 0);
diff --git a/src/coding.c b/src/coding.c
index d9620b90722..7880e439e9d 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -5458,6 +5458,9 @@ coding_restore_composition (coding, obj)
5458 if (method == COMPOSITION_WITH_RULE_ALTCHARS 5458 if (method == COMPOSITION_WITH_RULE_ALTCHARS
5459 && len % 2 == 0) 5459 && len % 2 == 0)
5460 len --; 5460 len --;
5461 if (len < 1)
5462 /* Invalid composition data. */
5463 break;
5461 for (j = 0; j < len; j++) 5464 for (j = 0; j < len; j++)
5462 args[j] = make_number (data[4 + j]); 5465 args[j] = make_number (data[4 + j]);
5463 components = (method == COMPOSITION_WITH_ALTCHARS 5466 components = (method == COMPOSITION_WITH_ALTCHARS
diff --git a/src/fileio.c b/src/fileio.c
index a2b207169cf..c7959b3672d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6095,6 +6095,7 @@ DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_inte
6095 if (SCHARS (name) == 0) 6095 if (SCHARS (name) == 0)
6096 return Qt; 6096 return Qt;
6097#endif /* VMS */ 6097#endif /* VMS */
6098 string = Fexpand_file_name (string, dir);
6098 if (!NILP (Vread_file_name_predicate)) 6099 if (!NILP (Vread_file_name_predicate))
6099 return call1 (Vread_file_name_predicate, string); 6100 return call1 (Vread_file_name_predicate, string);
6100 return Ffile_exists_p (string); 6101 return Ffile_exists_p (string);
@@ -6103,15 +6104,20 @@ DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_inte
6103DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0, 6104DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0,
6104 doc: /* Read file name, prompting with PROMPT and completing in directory DIR. 6105 doc: /* Read file name, prompting with PROMPT and completing in directory DIR.
6105Value is not expanded---you must call `expand-file-name' yourself. 6106Value is not expanded---you must call `expand-file-name' yourself.
6106Default name to DEFAULT-FILENAME if user enters a null string. 6107Default name to DEFAULT-FILENAME if user exits the minibuffer with
6108the same non-empty string that was inserted by this function.
6107 (If DEFAULT-FILENAME is omitted, the visited file name is used, 6109 (If DEFAULT-FILENAME is omitted, the visited file name is used,
6108 except that if INITIAL is specified, that combined with DIR is used.) 6110 except that if INITIAL is specified, that combined with DIR is used.)
6111If the user exits with an empty minibuffer, this function returns
6112an empty string. (This can only happen if the user erased the
6113pre-inserted contents or if `insert-default-directory' is nil.)
6109Fourth arg MUSTMATCH non-nil means require existing file's name. 6114Fourth arg MUSTMATCH non-nil means require existing file's name.
6110 Non-nil and non-t means also require confirmation after completion. 6115 Non-nil and non-t means also require confirmation after completion.
6111Fifth arg INITIAL specifies text to start with. 6116Fifth arg INITIAL specifies text to start with.
6112If optional sixth arg PREDICATE is non-nil, possible completions and the 6117If optional sixth arg PREDICATE is non-nil, possible completions and
6113resulting file name must satisfy (funcall PREDICATE NAME). 6118the resulting file name must satisfy (funcall PREDICATE NAME).
6114DIR defaults to current buffer's directory default. 6119DIR should be an absolute directory name. It defaults to the value of
6120`default-directory'.
6115 6121
6116If this command was invoked with the mouse, use a file dialog box if 6122If this command was invoked with the mouse, use a file dialog box if
6117`use-dialog-box' is non-nil, and the window system or X toolkit in use 6123`use-dialog-box' is non-nil, and the window system or X toolkit in use
@@ -6275,13 +6281,6 @@ provides a file dialog box. */)
6275 6281
6276 if (!NILP (tem) && !NILP (default_filename)) 6282 if (!NILP (tem) && !NILP (default_filename))
6277 val = default_filename; 6283 val = default_filename;
6278 else if (SCHARS (val) == 0 && NILP (insdef))
6279 {
6280 if (!NILP (default_filename))
6281 val = default_filename;
6282 else
6283 error ("No default file name");
6284 }
6285 val = Fsubstitute_in_file_name (val); 6284 val = Fsubstitute_in_file_name (val);
6286 6285
6287 if (replace_in_history) 6286 if (replace_in_history)
@@ -6457,7 +6456,20 @@ same format as a regular save would use. */);
6457 Vread_file_name_predicate = Qnil; 6456 Vread_file_name_predicate = Qnil;
6458 6457
6459 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory, 6458 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
6460 doc: /* *Non-nil means when reading a filename start with default dir in minibuffer. */); 6459 doc: /* *Non-nil means when reading a filename start with default dir in minibuffer.
6460If the initial minibuffer contents are non-empty, you can usually
6461request a default filename by typing RETURN without editing. For some
6462commands, exiting with an empty minibuffer has a special meaning,
6463such as making the current buffer visit no file in the case of
6464`set-visited-file-name'.
6465If this variable is non-nil, the minibuffer contents are always
6466initially non-empty and typing RETURN without editing will fetch the
6467default name, if one is provided. Note however that this default name
6468is not necessarily the name originally inserted in the minibuffer, if
6469that is just the default directory.
6470If this variable is nil, the minibuffer often starts out empty. In
6471that case you may have to explicitly fetch the next history element to
6472request the default name. */);
6461 insert_default_directory = 1; 6473 insert_default_directory = 1;
6462 6474
6463 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm, 6475 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
diff --git a/src/fns.c b/src/fns.c
index 6383e09302b..493d7ba2897 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -884,12 +884,11 @@ string_char_to_byte (string, char_index)
884 int best_below, best_below_byte; 884 int best_below, best_below_byte;
885 int best_above, best_above_byte; 885 int best_above, best_above_byte;
886 886
887 if (! STRING_MULTIBYTE (string))
888 return char_index;
889
890 best_below = best_below_byte = 0; 887 best_below = best_below_byte = 0;
891 best_above = SCHARS (string); 888 best_above = SCHARS (string);
892 best_above_byte = SBYTES (string); 889 best_above_byte = SBYTES (string);
890 if (best_above == best_above_byte)
891 return char_index;
893 892
894 if (EQ (string, string_char_byte_cache_string)) 893 if (EQ (string, string_char_byte_cache_string))
895 { 894 {
@@ -957,12 +956,11 @@ string_byte_to_char (string, byte_index)
957 int best_below, best_below_byte; 956 int best_below, best_below_byte;
958 int best_above, best_above_byte; 957 int best_above, best_above_byte;
959 958
960 if (! STRING_MULTIBYTE (string))
961 return byte_index;
962
963 best_below = best_below_byte = 0; 959 best_below = best_below_byte = 0;
964 best_above = SCHARS (string); 960 best_above = SCHARS (string);
965 best_above_byte = SBYTES (string); 961 best_above_byte = SBYTES (string);
962 if (best_above == best_above_byte)
963 return byte_index;
966 964
967 if (EQ (string, string_char_byte_cache_string)) 965 if (EQ (string, string_char_byte_cache_string))
968 { 966 {
diff --git a/src/macterm.c b/src/macterm.c
index a4124a0c7bc..9c7c497c00b 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -8205,9 +8205,6 @@ NewMacWindow (FRAME_PTR fp)
8205void 8205void
8206make_mac_frame (struct frame *f) 8206make_mac_frame (struct frame *f)
8207{ 8207{
8208 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
8209 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
8210
8211 FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR; 8208 FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
8212 8209
8213 NewMacWindow(f); 8210 NewMacWindow(f);
@@ -8256,6 +8253,9 @@ make_mac_terminal_frame (struct frame *f)
8256 FRAME_COLS (f) = 96; 8253 FRAME_COLS (f) = 96;
8257 FRAME_LINES (f) = 4; 8254 FRAME_LINES (f) = 4;
8258 8255
8256 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
8257 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
8258
8259 make_mac_frame (f); 8259 make_mac_frame (f);
8260 8260
8261 x_make_gc (f); 8261 x_make_gc (f);
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index c8e9addff63..bd5ad98571c 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -140,6 +140,7 @@ LIBS = $(TLIB0) \
140 $(USER32) \ 140 $(USER32) \
141 $(MPR) \ 141 $(MPR) \
142 $(SHELL32) \ 142 $(SHELL32) \
143 $(WINSPOOL) \
143 $(libc) 144 $(libc)
144 145
145# 146#
diff --git a/src/process.c b/src/process.c
index 2114d333905..be6094438e9 100644
--- a/src/process.c
+++ b/src/process.c
@@ -6094,7 +6094,10 @@ kill_buffer_processes (buffer)
6094 queued and the signal-catching function will be continually 6094 queued and the signal-catching function will be continually
6095 reentered until the queue is empty". Invoking signal() causes the 6095 reentered until the queue is empty". Invoking signal() causes the
6096 kernel to reexamine the SIGCLD queue. Fred Fish, UniSoft Systems 6096 kernel to reexamine the SIGCLD queue. Fred Fish, UniSoft Systems
6097 Inc. */ 6097 Inc.
6098
6099 ** Malloc WARNING: This should never call malloc either directly or
6100 indirectly; if it does, that is a bug */
6098 6101
6099SIGTYPE 6102SIGTYPE
6100sigchld_handler (signo) 6103sigchld_handler (signo)
@@ -6212,18 +6215,7 @@ sigchld_handler (signo)
6212 if (WIFEXITED (w)) 6215 if (WIFEXITED (w))
6213 synch_process_retcode = WRETCODE (w); 6216 synch_process_retcode = WRETCODE (w);
6214 else if (WIFSIGNALED (w)) 6217 else if (WIFSIGNALED (w))
6215 { 6218 synch_process_termsig = WTERMSIG (w);
6216 int code = WTERMSIG (w);
6217 char *signame;
6218
6219 synchronize_system_messages_locale ();
6220 signame = strsignal (code);
6221
6222 if (signame == 0)
6223 signame = "unknown";
6224
6225 synch_process_death = signame;
6226 }
6227 6219
6228 /* Tell wait_reading_process_input that it needs to wake up and 6220 /* Tell wait_reading_process_input that it needs to wake up and
6229 look around. */ 6221 look around. */
diff --git a/src/process.h b/src/process.h
index 2f46e74d4d0..6e2641d6b06 100644
--- a/src/process.h
+++ b/src/process.h
@@ -136,6 +136,9 @@ extern int synch_process_alive;
136/* Nonzero => this is a string explaining death of synchronous subprocess. */ 136/* Nonzero => this is a string explaining death of synchronous subprocess. */
137extern char *synch_process_death; 137extern char *synch_process_death;
138 138
139/* Nonzero => this is the signal number that terminated the subprocess. */
140extern int synch_process_termsig;
141
139/* If synch_process_death is zero, 142/* If synch_process_death is zero,
140 this is exit code of synchronous subprocess. */ 143 this is exit code of synchronous subprocess. */
141extern int synch_process_retcode; 144extern int synch_process_retcode;
diff --git a/src/search.c b/src/search.c
index 020573b75a1..c60d68b9374 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2366,13 +2366,21 @@ since only regular expressions have distinguished subexpressions. */)
2366 substart = search_regs.start[sub]; 2366 substart = search_regs.start[sub];
2367 subend = search_regs.end[sub]; 2367 subend = search_regs.end[sub];
2368 } 2368 }
2369 else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0') 2369 else if (c >= '1' && c <= '9')
2370 { 2370 {
2371 if (search_regs.start[c - '0'] >= 0) 2371 if (search_regs.start[c - '0'] >= 0
2372 && c <= search_regs.num_regs + '0')
2372 { 2373 {
2373 substart = search_regs.start[c - '0']; 2374 substart = search_regs.start[c - '0'];
2374 subend = search_regs.end[c - '0']; 2375 subend = search_regs.end[c - '0'];
2375 } 2376 }
2377 else
2378 {
2379 /* If that subexp did not match,
2380 replace \\N with nothing. */
2381 substart = 0;
2382 subend = 0;
2383 }
2376 } 2384 }
2377 else if (c == '\\') 2385 else if (c == '\\')
2378 delbackslash = 1; 2386 delbackslash = 1;
diff --git a/src/sysdep.c b/src/sysdep.c
index d8422b839f9..2b7a029b5ba 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -3832,7 +3832,8 @@ mkdir (dpath, dmode)
3832 wait_for_termination (cpid); 3832 wait_for_termination (cpid);
3833 } 3833 }
3834 3834
3835 if (synch_process_death != 0 || synch_process_retcode != 0) 3835 if (synch_process_death != 0 || synch_process_retcode != 0
3836 || synch_process_termsig != 0)
3836 { 3837 {
3837 errno = EIO; /* We don't know why, but */ 3838 errno = EIO; /* We don't know why, but */
3838 return -1; /* /bin/mkdir failed */ 3839 return -1; /* /bin/mkdir failed */
@@ -3878,7 +3879,8 @@ rmdir (dpath)
3878 wait_for_termination (cpid); 3879 wait_for_termination (cpid);
3879 } 3880 }
3880 3881
3881 if (synch_process_death != 0 || synch_process_retcode != 0) 3882 if (synch_process_death != 0 || synch_process_retcode != 0
3883 || synch_process_termsig != 0)
3882 { 3884 {
3883 errno = EIO; /* We don't know why, but */ 3885 errno = EIO; /* We don't know why, but */
3884 return -1; /* /bin/rmdir failed */ 3886 return -1; /* /bin/rmdir failed */
diff --git a/src/unexmacosx.c b/src/unexmacosx.c
index b8532325973..b41c586d2e0 100644
--- a/src/unexmacosx.c
+++ b/src/unexmacosx.c
@@ -192,6 +192,7 @@ static int
192unexec_copy (off_t dest, off_t src, ssize_t count) 192unexec_copy (off_t dest, off_t src, ssize_t count)
193{ 193{
194 ssize_t bytes_read; 194 ssize_t bytes_read;
195 ssize_t bytes_to_read;
195 196
196 char buf[UNEXEC_COPY_BUFSZ]; 197 char buf[UNEXEC_COPY_BUFSZ];
197 198
@@ -203,7 +204,8 @@ unexec_copy (off_t dest, off_t src, ssize_t count)
203 204
204 while (count > 0) 205 while (count > 0)
205 { 206 {
206 bytes_read = read (infd, buf, UNEXEC_COPY_BUFSZ); 207 bytes_to_read = count > UNEXEC_COPY_BUFSZ ? UNEXEC_COPY_BUFSZ : count;
208 bytes_read = read (infd, buf, bytes_to_read);
207 if (bytes_read <= 0) 209 if (bytes_read <= 0)
208 return 0; 210 return 0;
209 if (write (outfd, buf, bytes_read) != bytes_read) 211 if (write (outfd, buf, bytes_read) != bytes_read)
diff --git a/src/w32fns.c b/src/w32fns.c
index 7bffea34a28..1854c3908bd 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -51,6 +51,7 @@ Boston, MA 02111-1307, USA. */
51#include <commdlg.h> 51#include <commdlg.h>
52#include <shellapi.h> 52#include <shellapi.h>
53#include <ctype.h> 53#include <ctype.h>
54#include <winspool.h>
54 55
55#include <dlgs.h> 56#include <dlgs.h>
56#define FILE_NAME_TEXT_FIELD edt1 57#define FILE_NAME_TEXT_FIELD edt1
@@ -13921,6 +13922,76 @@ If the underlying system call fails, value is nil. */)
13921 return value; 13922 return value;
13922} 13923}
13923 13924
13925DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
13926 0, 0, 0, doc: /* Return the name of Windows default printer device. */)
13927 ()
13928{
13929 static char pname_buf[256];
13930 int err;
13931 HANDLE hPrn;
13932 PRINTER_INFO_2 *ppi2 = NULL;
13933 DWORD dwNeeded = 0, dwReturned = 0;
13934
13935 /* Retrieve the default string from Win.ini (the registry).
13936 * String will be in form "printername,drivername,portname".
13937 * This is the most portable way to get the default printer. */
13938 if (GetProfileString ("windows", "device", ",,", pname_buf, sizeof (pname_buf)) <= 0)
13939 return Qnil;
13940 /* printername precedes first "," character */
13941 strtok (pname_buf, ",");
13942 /* We want to know more than the printer name */
13943 if (!OpenPrinter (pname_buf, &hPrn, NULL))
13944 return Qnil;
13945 GetPrinter (hPrn, 2, NULL, 0, &dwNeeded);
13946 if (dwNeeded == 0)
13947 {
13948 ClosePrinter (hPrn);
13949 return Qnil;
13950 }
13951 /* Allocate memory for the PRINTER_INFO_2 struct */
13952 ppi2 = (PRINTER_INFO_2 *) xmalloc (dwNeeded);
13953 if (!ppi2)
13954 {
13955 ClosePrinter (hPrn);
13956 return Qnil;
13957 }
13958 /* Call GetPrinter() again with big enouth memory block */
13959 err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned);
13960 ClosePrinter (hPrn);
13961 if (!err)
13962 {
13963 xfree(ppi2);
13964 return Qnil;
13965 }
13966
13967 if (ppi2)
13968 {
13969 if (ppi2->Attributes & PRINTER_ATTRIBUTE_SHARED && ppi2->pServerName)
13970 {
13971 /* a remote printer */
13972 if (*ppi2->pServerName == '\\')
13973 _snprintf(pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
13974 ppi2->pShareName);
13975 else
13976 _snprintf(pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
13977 ppi2->pShareName);
13978 pname_buf[sizeof (pname_buf) - 1] = '\0';
13979 }
13980 else
13981 {
13982 /* a local printer */
13983 strncpy(pname_buf, ppi2->pPortName, sizeof (pname_buf));
13984 pname_buf[sizeof (pname_buf) - 1] = '\0';
13985 /* `pPortName' can include several ports, delimited by ','.
13986 * we only use the first one. */
13987 strtok(pname_buf, ",");
13988 }
13989 xfree(ppi2);
13990 }
13991
13992 return build_string (pname_buf);
13993}
13994
13924/*********************************************************************** 13995/***********************************************************************
13925 Initialization 13996 Initialization
13926 ***********************************************************************/ 13997 ***********************************************************************/
@@ -14373,6 +14444,7 @@ versions of Windows) characters. */);
14373 defsubr (&Sw32_find_bdf_fonts); 14444 defsubr (&Sw32_find_bdf_fonts);
14374 14445
14375 defsubr (&Sfile_system_info); 14446 defsubr (&Sfile_system_info);
14447 defsubr (&Sdefault_printer_name);
14376 14448
14377 /* Setting callback functions for fontset handler. */ 14449 /* Setting callback functions for fontset handler. */
14378 get_font_info_func = w32_get_font_info; 14450 get_font_info_func = w32_get_font_info;