aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaroly Lorentey2004-02-17 01:52:25 +0000
committerKaroly Lorentey2004-02-17 01:52:25 +0000
commite581a4668750ed98d77f13500c983439770ec600 (patch)
treeccbc5c82753658d45458e9306feb41203ae3757b
parent806c1866e6cdfe84bd8353dda02c4c8c61267480 (diff)
parent0f98bc23509b4e909cc92237e4b082c6866da258 (diff)
downloademacs-e581a4668750ed98d77f13500c983439770ec600.tar.gz
emacs-e581a4668750ed98d77f13500c983439770ec600.zip
Merged in changes from CVS HEAD
Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-71 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-72 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-73 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-74 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-75 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-76 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-77 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-78 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-79 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-80 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-81 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-82 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-83 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-84 Add lisp/emacs-lisp/macroexp.el * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-85 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-86 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-87 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-88 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-89 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-90 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-91 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-92 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-93 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-94 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-95 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-96 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-97 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-77
-rw-r--r--AUTHORS2
-rw-r--r--ChangeLog9
-rw-r--r--Makefile.in4
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/NEWS71
-rw-r--r--leim/ChangeLog4
-rw-r--r--leim/Makefile.in2
-rw-r--r--lib-src/ChangeLog26
-rw-r--r--lib-src/emacsclient.c4
-rwxr-xr-xlib-src/rcs2log28
-rw-r--r--lisp/ChangeLog312
-rw-r--r--lisp/Makefile.in15
-rw-r--r--lisp/autorevert.el103
-rw-r--r--lisp/calc/calc-ext.el4
-rw-r--r--lisp/calc/calc-forms.el6
-rw-r--r--lisp/calc/calc-map.el7
-rw-r--r--lisp/diff-mode.el40
-rw-r--r--lisp/diff.el292
-rw-r--r--lisp/dired-aux.el4
-rw-r--r--lisp/dired.el98
-rw-r--r--lisp/ediff-util.el12
-rw-r--r--lisp/emacs-lisp/cl-macs.el8
-rw-r--r--lisp/emacs-lisp/lisp-mnt.el6
-rw-r--r--lisp/emacs-lisp/lisp-mode.el2
-rw-r--r--lisp/emacs-lisp/macroexp.el197
-rw-r--r--lisp/emacs-lisp/rx.el3
-rw-r--r--lisp/emulation/vi.el15
-rw-r--r--lisp/emulation/viper-ex.el4
-rw-r--r--lisp/eshell/em-hist.el4
-rw-r--r--lisp/eshell/esh-mode.el4
-rw-r--r--lisp/filecache.el13
-rw-r--r--lisp/files.el2
-rw-r--r--lisp/format.el4
-rw-r--r--lisp/fringe.el27
-rw-r--r--lisp/gnus/ChangeLog6
-rw-r--r--lisp/gnus/gnus-score.el4
-rw-r--r--lisp/gnus/nnlistserv.el4
-rw-r--r--lisp/hexl.el4
-rw-r--r--lisp/international/ccl.el3
-rw-r--r--lisp/iswitchb.el17
-rw-r--r--lisp/loadup.el1
-rw-r--r--lisp/mail/mail-utils.el10
-rw-r--r--lisp/mail/rmail.el14
-rw-r--r--lisp/mail/smtpmail.el8
-rw-r--r--lisp/midnight.el4
-rw-r--r--lisp/net/webjump.el5
-rw-r--r--lisp/newcomment.el267
-rw-r--r--lisp/pcvs-defs.el3
-rw-r--r--lisp/play/zone.el4
-rw-r--r--lisp/progmodes/compile.el10
-rw-r--r--lisp/progmodes/cperl-mode.el11
-rw-r--r--lisp/progmodes/grep.el11
-rw-r--r--lisp/progmodes/gud.el12
-rw-r--r--lisp/progmodes/prolog.el88
-rw-r--r--lisp/progmodes/xscheme.el8
-rw-r--r--lisp/ses.el950
-rw-r--r--lisp/simple.el15
-rw-r--r--lisp/tar-mode.el5
-rw-r--r--lisp/term/x-win.el17
-rw-r--r--lisp/textmodes/refer.el8
-rw-r--r--lisp/textmodes/reftex-toc.el6
-rw-r--r--lisp/vc.el14
-rw-r--r--lisp/window.el14
-rw-r--r--lisp/x-dnd.el870
-rw-r--r--lispref/ChangeLog46
-rw-r--r--lispref/display.texi19
-rw-r--r--lispref/makefile.w32-in23
-rw-r--r--lispref/minibuf.texi337
-rw-r--r--lispref/positions.texi7
-rw-r--r--lispref/tips.texi17
-rw-r--r--man/ChangeLog15
-rw-r--r--man/frames.texi35
-rw-r--r--man/ses.texi18
-rw-r--r--src/ChangeLog289
-rw-r--r--src/Makefile.in3
-rw-r--r--src/atimer.c4
-rw-r--r--src/buffer.c22
-rw-r--r--src/data.c15
-rw-r--r--src/dispextern.h97
-rw-r--r--src/dispnew.c22
-rw-r--r--src/editfns.c4
-rw-r--r--src/emacs.c9
-rw-r--r--src/fns.c24
-rw-r--r--src/frame.h4
-rw-r--r--src/fringe.c1362
-rw-r--r--src/keyboard.c1
-rw-r--r--src/keymap.c24
-rw-r--r--src/lisp.h5
-rw-r--r--src/macfns.c23
-rw-r--r--src/macterm.c93
-rw-r--r--src/makefile.w32-in3
-rw-r--r--src/minibuf.c210
-rw-r--r--src/process.c2
-rw-r--r--src/region-cache.c4
-rw-r--r--src/sysdep.c2
-rw-r--r--src/w32fns.c28
-rw-r--r--src/w32select.c5
-rw-r--r--src/w32term.c86
-rw-r--r--src/window.c4
-rw-r--r--src/xdisp.c787
-rw-r--r--src/xfaces.c1
-rw-r--r--src/xfns.c273
-rw-r--r--src/xselect.c384
-rw-r--r--src/xterm.c61
-rw-r--r--src/xterm.h17
105 files changed, 5838 insertions, 2276 deletions
diff --git a/AUTHORS b/AUTHORS
index 0849acd7603..88d4edbebdd 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -882,7 +882,7 @@ Jonathan Stigelman: wrote hilit19.el
882 882
883Jonathan Vail: changed vc.el 883Jonathan Vail: changed vc.el
884 884
885Jonathan Yavner: wrote ses.el testcover-ses.el testcover-unsafep.el 885Jonathan Yavner: wrote ses.el tcover-ses.el tcover-unsafep.el
886 testcover.el unsafep.el 886 testcover.el unsafep.el
887and changed Makefile.in files.el ses-example.ses ses.texi 887and changed Makefile.in files.el ses-example.ses ses.texi
888 888
diff --git a/ChangeLog b/ChangeLog
index a01025e36f3..403c8d8ae5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
12004-02-14 Jonathan Yavner <jyavner@member.fsf.org>
2
3 * AUTHORS (JonathanYavner): Rename testcover-*.el to tcover-*.el
4 to match previous changes by Eli Zaretskii.
5
62004-02-09 Luc Teirlinck <teirllm@auburn.edu>
7
8 * Makefile.in: Set CDPATH to an empty string.
9
12004-01-27 Stefan Monnier <monnier@iro.umontreal.ca> 102004-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
2 11
3 * configure.in <darwin>: Use fink packages if available. 12 * configure.in <darwin>: Use fink packages if available.
diff --git a/Makefile.in b/Makefile.in
index 264b99f6d33..cf572f25812 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -53,6 +53,10 @@
53 53
54SHELL = /bin/sh 54SHELL = /bin/sh
55 55
56# This may not work with certain non-GNU make's. It only matters when
57# inheriting a CDPATH not starting with the current directory.
58CDPATH=
59
56# If Make doesn't predefine MAKE, set it here. 60# If Make doesn't predefine MAKE, set it here.
57@SET_MAKE@ 61@SET_MAKE@
58 62
diff --git a/etc/ChangeLog b/etc/ChangeLog
index bceac931cd5..c1e6cc50516 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,7 @@
12004-02-08 Andreas Schwab <schwab@suse.de>
2
3 * NEWS: Fix typo.
4
12003-12-29 Ognyan Kulev <ogi@fmi.uni-sofia.bg> 52003-12-29 Ognyan Kulev <ogi@fmi.uni-sofia.bg>
2 6
3 * TUTORIAL.bg: Use windows-1251 encoding. Fix punctuation errors. 7 * TUTORIAL.bg: Use windows-1251 encoding. Fix punctuation errors.
diff --git a/etc/NEWS b/etc/NEWS
index 90dc12c732f..2e460f4a8b4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -97,16 +97,28 @@ cursor will be displayed in the fringe when positioned on that newline.
97The new user option 'overflow-newline-into-fringe' may be set to nil to 97The new user option 'overflow-newline-into-fringe' may be set to nil to
98revert to the old behaviour of continuing such lines. 98revert to the old behaviour of continuing such lines.
99 99
100** The buffer boundaries (i.e. first and last line in the buffer) may now 100** The buffer boundaries (i.e. first and last line in the buffer) may
101be marked with bitmaps in the fringes. In addition, up and down 101now be marked with angle bitmaps in the fringes. In addition, up and
102arrow bitmaps may be shown at the top and bottom of the right fringe 102down arrow bitmaps may be shown at the top and bottom of the left or
103if the window can be scrolled in either direction. 103right fringe if the window can be scrolled in either direction.
104 104
105This behavior is activated by setting the buffer-local variable 105This behavior is activated by setting the buffer-local variable
106`indicate-buffer-boundaries' to a non-nil value. If value is t, both 106`indicate-buffer-boundaries' to a non-nil value. The default value of
107boundaries and scrolling arrows are shown; any other non-nil value 107this variable is found in `default-indicate-buffer-boundaries'.
108shows only the buffer boundaries. The default value of this variable 108
109is found in `default-indicate-buffer-boundaries'. 109If value is `left' or `right', both angle and arrow bitmaps are
110displayed in the left or right fringe, resp. Any other non-nil value
111causes the bitmap on the top line to be displayed in the left fringe,
112and the bitmap on the bottom line in the right fringe.
113
114If value is a cons (ANGLES . ARROWS), the car specifies the position
115of the angle bitmaps, and the cdr specifies the position of the arrow
116bitmaps.
117
118For example, (t . right) places the top angle bitmap in left fringe,
119the bottom angle bitmap in right fringe, and both arrow bitmaps in
120right fringe. To show just the angle bitmaps in the left fringe, but
121no arrow bitmaps, use (left . nil).
110 122
111** New command `display-local-help' displays any local help at point 123** New command `display-local-help' displays any local help at point
112in the echo area. It is bound to `C-h .'. It normally displays the 124in the echo area. It is bound to `C-h .'. It normally displays the
@@ -283,7 +295,12 @@ or when the frame is resized.
283** New functions frame-current-scroll-bars and window-current-scroll-bars. 295** New functions frame-current-scroll-bars and window-current-scroll-bars.
284 296
285These functions return the current locations of the vertical and 297These functions return the current locations of the vertical and
286horisontal scroll bars in a frame or window. 298horizontal scroll bars in a frame or window.
299
300---
301** Emacs now supports drag and drop for X. Dropping a file on a window
302 opens it, dropping text inserts the text. Dropping a file on a dired
303 buffer copies or moves the file to that directory.
287 304
288** Under X, mouse-wheel-mode is turned on by default. 305** Under X, mouse-wheel-mode is turned on by default.
289 306
@@ -968,7 +985,7 @@ attempt to construct a unique auto-save name (e.g. for remote files).
968+++ 985+++
969** Diary sexp entries can have custom marking in the calendar. 986** Diary sexp entries can have custom marking in the calendar.
970Diary sexp functions which only apply to certain days (such as 987Diary sexp functions which only apply to certain days (such as
971`diary-block' or `diary-cyclic' now take an optional parameter MARK, 988`diary-block' or `diary-cyclic') now take an optional parameter MARK,
972which is the name of a face or a single-character string indicating 989which is the name of a face or a single-character string indicating
973how to highlight the day in the calendar display. Specifying a 990how to highlight the day in the calendar display. Specifying a
974single-character string as @var{mark} places the character next to the 991single-character string as @var{mark} places the character next to the
@@ -1797,6 +1814,40 @@ configuration files.
1797 1814
1798* Lisp Changes in Emacs 21.4 1815* Lisp Changes in Emacs 21.4
1799 1816
1817** New function 'define-fringe-bitmap' can now be used to change the
1818built-in fringe bitmaps, as well as create new fringe bitmaps.
1819The return value is a number identifying the new fringe bitmap.
1820
1821To change a built-in bitmap, do (require 'fringe) and identify the
1822bitmap to change with the value of the corresponding symbol, like
1823`left-truncation-fringe-bitmap' or `continued-line-fringe-bitmap'.
1824
1825** New function 'destroy-fringe-bitmap' may be used to destroy a
1826previously created bitmap, or restore a built-in bitmap.
1827
1828** New function 'set-fringe-bitmap-face' can now be used to set a
1829specific face to be used for a specific fringe bitmap. Normally,
1830this should be a face derived from the `fringe' face, specifying
1831the foreground color as the desired color of the bitmap.
1832
1833** There are new display properties, left-fringe and right-fringe,
1834that can be used to show a specific bitmap in the left or right fringe
1835bitmap of the display line.
1836
1837Format is 'display '(left-fringe BITMAP [FACE]), where BITMAP is a
1838number identifying a fringe bitmap, either built-in or as returned by
1839`define-fringe-bitmap', and FACE is an optional face name to be used
1840for displaying the bitmap.
1841
1842** New function `fringe-bitmaps-at-pos' returns a cons (LEFT . RIGHT)
1843identifying the current fringe bitmaps in the display line at a given
1844buffer position. A nil value means no bitmap.
1845
1846+++
1847** New function `line-number-at-pos' returns line number of current
1848line in current buffer, or if optional buffer position is given, line
1849number of corresponding line in current buffer.
1850
1800** The default value of `sentence-end' is now defined using the new 1851** The default value of `sentence-end' is now defined using the new
1801variable `sentence-end-without-space' which contains such characters 1852variable `sentence-end-without-space' which contains such characters
1802that end a sentence without following spaces. 1853that end a sentence without following spaces.
diff --git a/leim/ChangeLog b/leim/ChangeLog
index 8f43358dde0..1b048bcddd7 100644
--- a/leim/ChangeLog
+++ b/leim/ChangeLog
@@ -1,3 +1,7 @@
12004-02-16 J,bi(Br,bt(Bme Marant <jmarant@nerim.net> (tiny change)
2
3 * Makefile.in (distclean maintainer-clean): Depend on clean.
4
12004-01-27 Ognyan Kulev <ogi@fmi.uni-sofia.bg> (tiny change) 52004-01-27 Ognyan Kulev <ogi@fmi.uni-sofia.bg> (tiny change)
2 6
3 * quail/cyrillic.el ("bulgarian-bds"): Docstring fixed. 7 * quail/cyrillic.el ("bulgarian-bds"): Docstring fixed.
diff --git a/leim/Makefile.in b/leim/Makefile.in
index 49b2e716be7..af20c278d3a 100644
--- a/leim/Makefile.in
+++ b/leim/Makefile.in
@@ -226,7 +226,7 @@ clean mostlyclean:
226 rm -f ${TIT} ${NON-TIT} ${WORLD} ${TIT:.elc=.el} \ 226 rm -f ${TIT} ${NON-TIT} ${WORLD} ${TIT:.elc=.el} \
227 ${MISC-DIC} ${MISC-DIC:.elc=.el} leim-list.el 227 ${MISC-DIC} ${MISC-DIC:.elc=.el} leim-list.el
228 228
229distclean maintainer-clean: 229distclean maintainer-clean: clean
230 if test -f stamp-subdir; then rm -rf ${SUBDIRS} stamp-subdir; fi 230 if test -f stamp-subdir; then rm -rf ${SUBDIRS} stamp-subdir; fi
231 rm -f Makefile 231 rm -f Makefile
232 232
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 6ea0e8be97a..5758a6d0b89 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,18 @@
12004-02-14 Paul Eggert <eggert@twinsun.com>
2
3 * rcs2log: Work correctly if CVSROOT specifies :fork: or
4 :local: methods, or omits the colon between the hostname
5 and the path. Allow :/ in repository path, since CVS does.
6 Fix typo: "pository" should be set from $CVSROOT, not $repository.
7 This fixes a bug reported by Wolfgang Scherer in
8 <http://mail.gnu.org/archive/html/bug-gnu-emacs/2004-02/msg00085.html>,
9 along with some related bugs I discovered by inspecting how
10 CVS itself parses $CVSROOT.
11
122004-02-04 J,bi(Br,bt(Bme Marant <jmarant@nerim.net> (tiny)
13
14 * emacsclient.c (decode_options): Fix handling of alternate editor.
15
12004-01-27 Stefan Monnier <monnier@iro.umontreal.ca> 162004-01-27 Stefan Monnier <monnier@iro.umontreal.ca>
2 17
3 * emacsclient.c (main): Don't use the hostname in the socket name. 18 * emacsclient.c (main): Don't use the hostname in the socket name.
@@ -14,6 +29,12 @@
14 Only try su-fallback if the socket name was not explicit. 29 Only try su-fallback if the socket name was not explicit.
15 Check socket name length in su-fallback case as well. 30 Check socket name length in su-fallback case as well.
16 31
322004-01-20 Stefan Monnier <monnier@iro.umontreal.ca>
33
34 * emacsclient.c (main): Stop if socket name too long.
35 Only try su-fallback if the socket name was not explicit.
36 Check socket name length in su-fallback case as well.
37
172004-01-08 Andreas Schwab <schwab@suse.de> 382004-01-08 Andreas Schwab <schwab@suse.de>
18 39
19 * emacsclient.c (main): Save errno from socket_status. 40 * emacsclient.c (main): Save errno from socket_status.
@@ -54,7 +75,7 @@
54 75
552003-08-25 Takaaki Ota <Takaaki.Ota@am.sony.com> (tiny change) 762003-08-25 Takaaki Ota <Takaaki.Ota@am.sony.com> (tiny change)
56 77
57 * etags.c (consider_token): check C++ `operator' only when the 78 * etags.c (consider_token): Check C++ `operator' only when the
58 token len is long enough. 79 token len is long enough.
59 80
602003-08-20 Dave Love <fx@gnu.org> 812003-08-20 Dave Love <fx@gnu.org>
@@ -5493,7 +5514,8 @@ Tue Jul 1 01:09:07 1997 Geoff Voelker <voelker@cs.washington.edu>
5493;; coding: iso-2022-7bit 5514;; coding: iso-2022-7bit
5494;; End: 5515;; End:
5495 5516
5496 Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 5517 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
5518 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004
5497 Free Software Foundation, Inc. 5519 Free Software Foundation, Inc.
5498 Copying and distribution of this file, with or without modification, 5520 Copying and distribution of this file, with or without modification,
5499 are permitted provided the copyright notice and this notice are preserved. 5521 are permitted provided the copyright notice and this notice are preserved.
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 0f42f096643..771eeac05e6 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -106,6 +106,8 @@ decode_options (argc, argv)
106 int argc; 106 int argc;
107 char **argv; 107 char **argv;
108{ 108{
109 alternate_editor = getenv ("ALTERNATE_EDITOR");
110
109 while (1) 111 while (1)
110 { 112 {
111 int opt = getopt_long (argc, argv, 113 int opt = getopt_long (argc, argv,
@@ -114,8 +116,6 @@ decode_options (argc, argv)
114 if (opt == EOF) 116 if (opt == EOF)
115 break; 117 break;
116 118
117 alternate_editor = getenv ("ALTERNATE_EDITOR");
118
119 switch (opt) 119 switch (opt)
120 { 120 {
121 case 0: 121 case 0:
diff --git a/lib-src/rcs2log b/lib-src/rcs2log
index 4400fb72578..658a30c789b 100755
--- a/lib-src/rcs2log
+++ b/lib-src/rcs2log
@@ -29,10 +29,10 @@ Options:
29 29
30Report bugs to <bug-gnu-emacs@gnu.org>.' 30Report bugs to <bug-gnu-emacs@gnu.org>.'
31 31
32Id='$Id: rcs2log,v 1.52 2003/12/27 08:18:08 uid65632 Exp $' 32Id='$Id: rcs2log,v 1.53 2004/02/15 07:41:58 uid65632 Exp $'
33 33
34# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003 34# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003,
35# Free Software Foundation, Inc. 35# 2004 Free Software Foundation, Inc.
36 36
37# This program is free software; you can redistribute it and/or modify 37# This program is free software; you can redistribute it and/or modify
38# it under the terms of the GNU General Public License as published by 38# it under the terms of the GNU General Public License as published by
@@ -49,7 +49,7 @@ Id='$Id: rcs2log,v 1.52 2003/12/27 08:18:08 uid65632 Exp $'
49# Free Software Foundation, Inc., 59 Temple Place - Suite 330, 49# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
50# Boston, MA 02111-1307, USA. 50# Boston, MA 02111-1307, USA.
51 51
52Copyright='Copyright (C) 2003 Free Software Foundation, Inc. 52Copyright='Copyright (C) 2004 Free Software Foundation, Inc.
53This program comes with NO WARRANTY, to the extent permitted by law. 53This program comes with NO WARRANTY, to the extent permitted by law.
54You may redistribute copies of this program 54You may redistribute copies of this program
55under the terms of the GNU General Public License. 55under the terms of the GNU General Public License.
@@ -251,18 +251,24 @@ case $rlogfile in
251 rlog='cvs -q log' 251 rlog='cvs -q log'
252 repository=`sed 1q <CVS/Repository` || exit 252 repository=`sed 1q <CVS/Repository` || exit
253 test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit 253 test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit
254 pository=
254 case $CVSROOT in 255 case $CVSROOT in
255 *:/*:/*) 256 /* | :fork:* | :local:*) ;;
256 echo >&2 "$0: $CVSROOT: CVSROOT has multiple ':/'s" 257 */*)
257 exit 1;;
258 *:/*)
259 # remote repository 258 # remote repository
260 pository=`expr "X$repository" : '.*:\(/.*\)'`;; 259 pository=`expr "X$CVSROOT" : '[^/]*\(.*\)'`;;
261 *) 260 esac
261 case $pository in
262 '')
262 # local repository 263 # local repository
263 case $repository in 264 case $repository in
264 /*) ;; 265 /*) ;;
265 *) repository=${CVSROOT?}/$repository;; 266 *)
267 repository=${CVSROOT?}/$repository
268 case $repository in
269 :fork:* | :local:*)
270 repository=`expr "$repository" : ':[^:]*:\(.*\)'`;;
271 esac;;
266 esac 272 esac
267 if test ! -d "$repository" 273 if test ! -d "$repository"
268 then 274 then
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 8e5ad91126e..c13e5dff431 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,312 @@
12004-02-16 Jari Aalto <jari.aalto@poboxes.com> (tiny change)
2
3 * filecache.el: All message and error commands now use prefix
4 "Filecache:" to make it easy to read *Messages* buffer.
5
62004-02-16 Jari Aalto <jari.aalto@poboxes.com>
7
8 Autorevert: Add support to detect changed dired buffers.
9 * autorevert.el (auto-revert-active-p, auto-revert-list-diff)
10 (auto-revert-dired-file-list, auto-revert-dired-changed-p)
11 (auto-revert-handler, auto-revert-active-p): New functions.
12 (auto-revert-buffers): Moved revert logic to `auto-revert-handler'
13 and `auto-revert-active-p'.
14 (eval-when-compile): Defvar dired-directory.
15
162004-02-16 Alfred M. Szmidt <ams@kemisten.nu> (tiny change)
17
18 * progmodes/compile.el (compilation-directory): New defvar.
19 (compile): Save current directory in compilation-directory.
20 (recompile): Bind default-directory to compilation-directory if
21 that is non-nil.
22
232004-02-16 Dave Love <fx@gnu.org>
24
25 * newcomment.el (comment-insert-comment-function)
26 (comment-region-function, uncomment-region-function): New.
27 (comment-indent): Use comment-insert-comment-function.
28 (uncomment-region): Use uncomment-region-function.
29 (comment-region): Use comment-region-function.
30
31 * emacs-lisp/rx.el (rx-not): Bind case-fold-search to nil.
32
332004-02-16 Richard Stallman <rms@gnu.org>
34
35 * Makefile.in (TAGS, TAGS-LISP): Filter out of `els' only
36 loaddefs* and ldefs-boot*.
37
382004-02-16 Eli Zaretskii <eliz@elta.co.il>
39
40 * mail/mail-utils.el (rmail-dont-reply-to): Anchor user login name
41 and email address at the beginning and end of the address.
42
43 * mail/rmail.el (rmail-default-dont-reply-to-names): Make "info-"
44 anchored at the beginning of the email address.
45
462004-02-16 TAKAI Kousuke <tak@kmc.gr.jp> (tiny change)
47
48 * international/ccl.el (ccl-compile-write): Pass `left' to
49 ccl-embed-code to generate correct code of write-expr-register.
50
512004-02-15 Dan Nicolaescu <dann@ics.uci.edu> (tiny change)
52
53 * progmodes/grep.el (grep-compute-defaults): Fix typos.
54
552004-02-15 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
56
57 * x-dnd.el: Mention support for Motif in commentary.
58 (x-dnd-handle-drag-n-drop-event): Ditto.
59
602004-02-14 Jonathan Yavner <jyavner@member.fsf.org>
61
62 * ses.el: Use "ses--" prefixes for buffer-local variables.
63 Use (point-min) instead of 1, even when we know the buffer
64 is unnarrowed.
65 (ses-build-load-map): Delete. Distribute its content to defconst's for
66 the three maps.
67 (ses-menu, ses-header-line-menu): New menus.
68 (ses-mode-map): Use them.
69 (ses-read-number) New fun. Duplicates code from interactive "N" spec.
70
712004-02-14 Martin Stjernholm <bug-cc-mode@gnu.org>
72
73 * Makefile.in: Fixed the CC Mode recompile kludge so it works
74 when building in a different directory.
75
762004-02-13 Luc Teirlinck <teirllm@auburn.edu>
77
78 * simple.el (kill-new): Put yank-handler property on the entire string.
79
802004-02-11 Stefan Monnier <monnier@iro.umontreal.ca>
81
82 * pcvs-defs.el (cvs-menu): Add `tag'.
83
842004-02-11 Luc Teirlinck <teirllm@auburn.edu>
85
86 * simple.el (kill-append): Doc fix.
87
88 * emacs-lisp/lisp-mode.el (lisp-mode-variables):
89 Adapt outline-regexp to the new conventions for commenting out code.
90
912004-02-11 John Paul Wallington <jpw@gnu.org>
92
93 * mail/smtpmail.el (smtpmail-try-auth-methods): Fix typo.
94
952004-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
96
97 * diff.el (diff-switches): New fun.
98 (diff, diff-backup): Use it.
99 (diff): Clean up the args construction. Use backquote.
100 Use listp instead of consp to avoid putting a nil arg.
101
1022004-02-10 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
103
104 * x-dnd.el (x-dnd-types-alist): Add COMPOUND_TEXT, FILE_NAME
105 handeled by x-dnd-handle-file-name.
106 (x-dnd-known-types): Add COMPOUND_TEXT.
107 (x-dnd-init-frame): Call x-dnd-init-motif-for-frame.
108 (x-dnd-get-state-cons-for-frame): Must do copy-sequence on
109 x-dnd-empty-state.
110 (x-dnd-forget-drop): Ditto.
111 (x-dnd-save-state): Add optional parameter extra-data (for Motif).
112 (x-dnd-handle-one-url): Return private when inserting text.
113 (x-dnd-insert-ctext): New function.
114 (x-dnd-handle-file-name): New function for FILE_NAME.
115 (x-dnd-handle-drag-n-drop-event): Add Motif, remove call to error.
116 (x-dnd-init-motif-for-frame, x-dnd-get-motif-value)
117 (x-dnd-motif-value-to-list, x-dnd-handle-motif): New functions.
118
1192004-02-10 Kenichi Handa <handa@m17n.org>
120
121 * term/x-win.el (x-select-utf8-or-ctext): Use compare-strings
122 instead of while loop.
123
1242004-02-10 Miles Bader <miles@gnu.org>
125
126 * emacs-lisp/macroexp.el: New file, implements `macroexpand-all'.
127
1282004-02-09 Kenichi Handa <handa@m17n.org>
129
130 * tar-mode.el (tar-extract): Fix for the case that a file doesn't
131 have end-of-line.
132
1332004-02-09 Martin Stjernholm <bug-cc-mode@gnu.org>
134
135 * Makefile.in: Added extra dependencies in the recompile target
136 needed to cope with the compile time macro expansions in CC Mode.
137
1382004-02-09 Kim F. Storm <storm@cua.dk>
139
140 * fringe.el (no-fringe-bitmap, undef-fringe-bitmap)
141 (left-truncation-fringe-bitmap, right-truncation-fringe-bitmap)
142 (up-arrow-fringe-bitmap, down-arrow-fringe-bitmap)
143 (continued-line-fringe-bitmap, continuation-line-fringe-bitmap)
144 (overlay-arrow-fringe-bitmap, top-left-angle-fringe-bitmap)
145 (top-right-angle-fringe-bitmap, bottom-left-angle-fringe-bitmap)
146 (bottom-right-angle-fringe-bitmap, left-bracket-fringe-bitmap)
147 (right-bracket-fringe-bitmap, filled-box-cursor-fringe-bitmap)
148 (hollow-box-cursor-fringe-bitmap, hollow-square-fringe-bitmap)
149 (bar-cursor-fringe-bitmap, hbar-cursor-fringe-bitmap)
150 (empty-line-fringe-bitmap): Define standard fringe bitmaps id's.
151
1522004-02-08 Stefan Monnier <monnier@iro.umontreal.ca>
153
154 * window.el (window-safely-shrinkable-p): Don't change the buffer-list.
155 Don't allow shrink if there's a window on our right.
156
157 * progmodes/prolog.el (prolog-program-name): Use gprolog if available.
158 (prolog-mode-syntax-table, prolog-mode-abbrev-table, prolog-mode-map):
159 Bring together declaration and initialization.
160 (prolog-mode-variables): Don't set the syntax table.
161 Don't set paragraph-start and comment-indent-function.
162 Add /*..*/ to the comment regexps.
163 (prolog-mode-commands): Remove. Do it during init of prolog-mode-map.
164 (prolog-mode-map): Don't bind TAB.
165 (prolog-mode): Set the syntax table.
166 (prolog-comment-indent): Remove.
167 (inferior-prolog-mode-map): Initialize in the declaration.
168 (inferior-prolog-mode-syntax-table)
169 (inferior-prolog-mode-abbrev-table): New vars.
170 (inferior-prolog-mode): Derive from comint-mode.
171 (run-prolog): Avoid switch-to-buffer which can fail in dedicated and
172 minibuffer windows.
173
174 * progmodes/grep.el (grep-regexp-alist): Allow :, \t and (
175 in file names, as long as it is unabmiguous.
176
1772004-02-08 Andreas Schwab <schwab@suse.de>
178
179 * textmodes/reftex-toc.el
180 (reftex-toc-load-all-files-for-promotion): Remove useless use of
181 format. Doc fix.
182
183 * textmodes/refer.el (refer-find-entry-internal): Remove extra
184 format string arguments.
185
186 * tar-mode.el (tar-parse-octal-integer-safe): Add missing format
187 string argument.
188
189 * progmodes/xscheme.el (verify-xscheme-buffer): Fix format strings.
190
191 * play/zone.el (zone-call): Fix format string.
192
193 * net/webjump.el (webjump-builtin): Add missing format string argument.
194
195 * midnight.el (midnight-delay-set): Remove extra format string argument.
196
197 * mail/rmail.el (rmail-get-new-mail): Remove useless use of format.
198
199 * hexl.el (hexl-insert-char): Add missing format string argument.
200
201 * format.el (format-decode): Fix format string.
202
203 * emulation/vi.el (vi-mode): Remove extra format string argument.
204 (vi-repeat-last-search): Likewise.
205 (vi-reverse-last-search): Likewise.
206 (vi-goto-mark): Likewise.
207 (vi-reverse-last-find-char): Likewise.
208 (vi-repeat-last-find-char): Likewise.
209 (vi-locate-def): Likewise.
210
211 * emacs-lisp/lisp-mnt.el (lm-verify): Remove useless use of format.
212
213 * ediff-util.el (ediff-toggle-read-only): Remove extra format
214 string argument.
215 (ediff-toggle-regexp-match): Likewise.
216
217 * dired-aux.el (dired-do-query-replace-regexp): Add missing
218 format string argument.
219
220 * calc/calc-map.el (calc-get-operator): Remove extra format
221 string argument.
222
223 * calc/calc-forms.el (calc-convert-time-zones): Fix format string.
224
225 * calc/calc-ext.el (calc-do-prefix-help): Remove extra format
226 string argument.
227
228 * eshell/esh-mode.el (eshell-send-invisible): Fix format string.
229
230 * eshell/em-hist.el (eshell-hist-word-reference): Fix format string.
231
232 * emulation/viper-ex.el (ex-mark): Remove extra format string argument.
233
234 * emacs-lisp/cl-macs.el (defstruct): Remove extra format string arg.
235 (cl-struct-setf-expander): Likewise.
236
237 * vc.el (with-vc-file): Fix unsafe uses of error.
238 (vc-cancel-version): Likewise.
239
2402004-02-08 Jan Nieuwenhuizen <jan.nieuwenhuizen@aspiratie.nl> (tiny change)
241
242 * progmodes/gud.el (gud-jdb-marker-filter): Add period as optional
243 thousands separator; fixes <class>:<line-number> regexp for
244 non-english locales.
245
2462004-02-08 Andreas Schwab <schwab@suse.de>
247
248 * view.el (view-mode-enable): Revert previous change.
249
2502004-02-07 Kim F. Storm <storm@cua.dk>
251
252 * simple.el (line-number-at-pos): Rename from line-at-pos.
253 Uses changed (what-line and vc-annotate-warp-version).
254
2552004-02-06 Stefan Monnier <monnier@iro.umontreal.ca>
256
257 * diff-mode.el (diff-file-regexp-alist, diff-error-regexp-alist)
258 (diff-mode): Remove aborted attempt at support for compile.el.
259 (diff-mode, diff-minor-mode): Avoid obsolete write-contents-hooks.
260
2612004-02-06 Andreas Schwab <schwab@suse.de>
262
263 * view.el (view-mode-enable): Add view-mode-map to
264 minor-mode-overriding-map-alist.
265
2662004-02-05 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
267
268 * x-dnd.el (x-dnd-get-local-file-name): Fix byte compiler warning
269
2702004-02-04 Stefan Monnier <monnier@iro.umontreal.ca>
271
272 * progmodes/cperl-mode.el (cperl-fill-paragraph): Call fill-paragraph
273 with point inside rather than after the paragraph.
274
2752004-02-04 Sam Steingold <sds@gnu.org>
276
277 * mail/smtpmail.el (smtpmail-try-auth-methods):
278 Do not try authentication when no mechanism is available.
279 Pass port-name as defaultport to `netrc-machine'.
280
2812004-02-04 Stephen Eglen <stephen@gnu.org>
282
283 * iswitchb.el (iswitchb-minibuffer-setup-hook): Update doc string
284 to show how minibuffer height can be constrained.
285
2862004-02-04 John Paul Wallington <jpw@gnu.org>
287
288 * files.el (auto-mode-alist): Fix .scm, .stk, .ss, .sch entry.
289
2902004-02-03 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
291
292 * x-dnd.el: New file for drag and drop.
293
294 * term/x-win.el: require x-dnd, set after-make-frame-functions
295 to x-dnd-init-frame, let x-dnd-handle-drag-n-drop-event handle
296 drag-n-drop event.
297
298 * dired.el (dired-dnd-test-function, dired-dnd-popup-notice)
299 (dired-dnd-do-ask-action, dired-dnd-handle-local-file)
300 (dired-dnd-handle-file): New functions for drag and drop support.
301 (dired-mode): Initialize drag and drop if x-dnd present.
302
3032004-02-02 Stefan Monnier <monnier@iro.umontreal.ca>
304
305 * progmodes/cperl-mode.el (cperl-mode-map, cperl-do-auto-fill)
306 (cperl-menu): Use fill-paragraph, not cperl-fill-paragraph.
307 (cperl-mode): Set fill-paragraph-function.
308 (cperl-fill-paragraph): Make it non-interactive.
309
12004-02-02 Benjamin Rutt <brutt@bloomington.in.us> 3102004-02-02 Benjamin Rutt <brutt@bloomington.in.us>
2 311
3 * diff-mode.el (diff-mode-shared-map): Bind q to `quit-window'. 312 * diff-mode.el (diff-mode-shared-map): Bind q to `quit-window'.
@@ -10,8 +319,7 @@
10 319
112004-02-01 Andreas Schwab <schwab@suse.de> 3202004-02-01 Andreas Schwab <schwab@suse.de>
12 321
13 * progmodes/executable.el (executable-command-find-posix-p): Doc 322 * progmodes/executable.el (executable-command-find-posix-p): Doc fix.
14 fix.
15 323
162004-02-01 Stephen Eglen <stephen@gnu.org> 3242004-02-01 Stephen Eglen <stephen@gnu.org>
17 325
diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index 8baf0278fe9..fad13704c3c 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -188,11 +188,11 @@ update-authors:
188 $(emacs) -f batch-update-authors $(srcdir)/AUTHORS $(srcdir) 188 $(emacs) -f batch-update-authors $(srcdir)/AUTHORS $(srcdir)
189 189
190TAGS: $(lisptagsfiles1) $(lisptagsfiles2) 190TAGS: $(lisptagsfiles1) $(lisptagsfiles2)
191 els=`echo $(lisptagsfiles1) $(lisptagsfiles2) | sed -e "s,$(lisp)/loaddefs.*\.el,,"`; \ 191 els=`echo $(lisptagsfiles1) $(lisptagsfiles2) | sed -e "s,$(lisp)/loaddefs[^ ]*,," -e "s,$(lisp)/ldefs-boot[^ ]*,,"`; \
192 ${ETAGS} $$els 192 ${ETAGS} $$els
193 193
194TAGS-LISP: $(lisptagsfiles1) $(lisptagsfiles2) 194TAGS-LISP: $(lisptagsfiles1) $(lisptagsfiles2)
195 els=`echo $(lisptagsfiles1) $(lisptagsfiles2) | sed -e "s,$(lisp)/loaddefs.*\.el,,"`; \ 195 els=`echo $(lisptagsfiles1) $(lisptagsfiles2) | sed -e "s,$(lisp)/loaddefs[^ ]*,," -e "s,$(lisp)/ldefs-boot[^ ]*,,"`; \
196 ${ETAGS} -o TAGS-LISP $$els 196 ${ETAGS} -o TAGS-LISP $$els
197 197
198.SUFFIXES: .elc .el 198.SUFFIXES: .elc .el
@@ -273,9 +273,18 @@ compile-after-backup: backup-compiled-files compile-always
273# Note that this doesn't create .elc files. It only recompiles if an 273# Note that this doesn't create .elc files. It only recompiles if an
274# .elc is present. 274# .elc is present.
275 275
276recompile: doit 276recompile: doit $(lisp)/progmodes/cc-mode.elc
277 $(EMACS) $(EMACSOPT) -f batch-byte-recompile-directory $(lisp) 277 $(EMACS) $(EMACSOPT) -f batch-byte-recompile-directory $(lisp)
278 278
279# CC Mode uses a compile time macro system which causes a compile time
280# dependency in cc-mode.elc on the macros in cc-langs.el and the
281# version string in cc-defs.el.
282$(lisp)/progmodes/cc-mode.elc: \
283 $(lisp)/progmodes/cc-mode.el \
284 $(lisp)/progmodes/cc-langs.el \
285 $(lisp)/progmodes/cc-defs.el
286 $(EMACS) $(EMACSOPT) -f batch-byte-compile $(lisp)/progmodes/cc-mode.el
287
279# Prepare a bootstrap in the lisp subdirectory. 288# Prepare a bootstrap in the lisp subdirectory.
280# 289#
281# Build loaddefs.el, because it's not sure it's up-to-date, and if it's not, 290# Build loaddefs.el, because it's not sure it's up-to-date, and if it's not,
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index fac91332a5e..309517476e1 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -70,7 +70,11 @@
70;; Dependencies: 70;; Dependencies:
71 71
72(require 'timer) 72(require 'timer)
73(eval-when-compile (require 'cl)) 73(autoload 'dired-get-filename "dired")
74
75(eval-when-compile
76 (defvar dired-directory)
77 (require 'cl))
74 78
75 79
76;; Custom Group: 80;; Custom Group:
@@ -244,6 +248,82 @@ Use `auto-revert-mode' to revert a particular buffer."
244 'auto-revert-buffers) 248 'auto-revert-buffers)
245 nil))) 249 nil)))
246 250
251(defun auto-revert-active-p ()
252 "Check if auto-revert is active (in current buffer or globally)."
253 (or auto-revert-mode
254 (and
255 global-auto-revert-mode
256 (not global-auto-revert-ignore-buffer)
257 (not (memq major-mode
258 global-auto-revert-ignore-modes)))))
259
260(defun auto-revert-list-diff (a b)
261 "Check if strings in list A differ from list B."
262 (when (and a b)
263 (setq a (sort a 'string-lessp))
264 (setq b (sort b 'string-lessp))
265 (let (elt1 elt2)
266 (catch 'break
267 (while (and (setq elt1 (and a (pop a)))
268 (setq elt2 (and b (pop b))))
269 (if (not (string= elt1 elt2))
270 (throw 'break t)))))))
271
272(defun auto-revert-dired-file-list ()
273 "Return list of dired files."
274 (let (file list)
275 (save-excursion
276 (goto-char (point-min))
277 (while (not (eobp))
278 (if (setq file (dired-get-filename t t))
279 (push file list))
280 (forward-line 1)))
281 list))
282
283(defun auto-revert-dired-changed-p ()
284 "Check if dired buffer has changed."
285 (when (and (stringp dired-directory)
286 ;; Exclude remote buffers, would be too slow for user
287 ;; modem, timeouts, network lag ... all is possible
288 (not (string-match "@" dired-directory))
289 (file-directory-p dired-directory))
290 (let ((files (directory-files dired-directory))
291 (dired (auto-revert-dired-file-list)))
292 (or (not (eq (length files) (length dired)))
293 (auto-revert-list-diff files dired)))))
294
295(defun auto-revert-buffer-p ()
296 "Check if current buffer should be reverted."
297 ;; Always include dired buffers to list. It would be too expensive
298 ;; to test the "revert" status here each time timer launches.
299 (or (eq major-mode 'dired-mode)
300 (and (not (buffer-modified-p))
301 (if (buffer-file-name)
302 (and (file-readable-p (buffer-file-name))
303 (not (verify-visited-file-modtime (current-buffer))))
304 (and revert-buffer-function
305 (or (and global-auto-revert-mode
306 global-auto-revert-non-file-buffers)
307 auto-revert-mode))))))
308
309(defun auto-revert-handler ()
310 "Revert current buffer."
311 (let (done)
312 (cond
313 ((eq major-mode 'dired-mode)
314 ;; Dired includes revert-buffer-function
315 (when (and revert-buffer-function
316 (auto-revert-dired-changed-p))
317 (setq done t)
318 (revert-buffer t t t)))
319 ((or (buffer-file-name)
320 revert-buffer-function)
321 (setq done t)
322 (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes)))
323 (if (and done
324 auto-revert-verbose)
325 (message "Reverting buffer `%s'." (buffer-name)))))
326
247(defun auto-revert-buffers () 327(defun auto-revert-buffers ()
248 "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode. 328 "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode.
249 329
@@ -294,24 +374,9 @@ the timer when no buffers need to be checked."
294 (memq buf auto-revert-buffer-list)) 374 (memq buf auto-revert-buffer-list))
295 (setq auto-revert-buffer-list 375 (setq auto-revert-buffer-list
296 (delq buf auto-revert-buffer-list))) 376 (delq buf auto-revert-buffer-list)))
297 (when (and 377 (when (and (auto-revert-active-p)
298 (or auto-revert-mode 378 (auto-revert-buffer-p))
299 (and 379 (auto-revert-handler)
300 global-auto-revert-mode
301 (not global-auto-revert-ignore-buffer)
302 (not (memq major-mode
303 global-auto-revert-ignore-modes))))
304 (not (buffer-modified-p))
305 (if (buffer-file-name)
306 (and (file-readable-p (buffer-file-name))
307 (not (verify-visited-file-modtime buf)))
308 (and revert-buffer-function
309 (or (and global-auto-revert-mode
310 global-auto-revert-non-file-buffers)
311 auto-revert-mode))))
312 (if auto-revert-verbose
313 (message "Reverting buffer `%s'." buf))
314 (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes)
315 ;; `preserve-modes' avoids changing the (minor) modes. But we 380 ;; `preserve-modes' avoids changing the (minor) modes. But we
316 ;; do want to reset the mode for VC, so we do it explicitly. 381 ;; do want to reset the mode for VC, so we do it explicitly.
317 (vc-find-file-hook))) 382 (vc-find-file-hook)))
diff --git a/lisp/calc/calc-ext.el b/lisp/calc/calc-ext.el
index 3fa254cc05d..eafcc0766c2 100644
--- a/lisp/calc/calc-ext.el
+++ b/lisp/calc/calc-ext.el
@@ -1,6 +1,6 @@
1;;; calc-ext.el --- various extension functions for Calc 1;;; calc-ext.el --- various extension functions for Calc
2 2
3;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2004 Free Software Foundation, Inc.
4 4
5;; Author: David Gillespie <daveg@synaptics.com> 5;; Author: David Gillespie <daveg@synaptics.com>
6;; Maintainers: D. Goel <deego@gnufans.org> 6;; Maintainers: D. Goel <deego@gnufans.org>
@@ -1262,7 +1262,7 @@ calc-kill calc-kill-region calc-yank))))
1262 (if key 1262 (if key
1263 (if msgs 1263 (if msgs
1264 (message "%s: %s: %c-" group (car msgs) key) 1264 (message "%s: %s: %c-" group (car msgs) key)
1265 (message "%s: (none) %c-" group (car msgs) key)) 1265 (message "%s: (none) %c-" group key))
1266 (message "%s: %s" group (car msgs)))) 1266 (message "%s: %s" group (car msgs))))
1267 (and key (calc-unread-command key)))) 1267 (and key (calc-unread-command key))))
1268 1268
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index e5a0d6ae7fd..31f9e776a0c 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -1,6 +1,6 @@
1;;; calc-forms.el --- data format conversion functions for Calc 1;;; calc-forms.el --- data format conversion functions for Calc
2 2
3;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2004 Free Software Foundation, Inc.
4 4
5;; Author: David Gillespie <daveg@synaptics.com> 5;; Author: David Gillespie <daveg@synaptics.com>
6;; Maintainers: D. Goel <deego@gnufans.org> 6;; Maintainers: D. Goel <deego@gnufans.org>
@@ -212,11 +212,11 @@
212 ", to zone: ")))) 212 ", to zone: "))))
213 (if (stringp old) (setq old (math-read-expr old))) 213 (if (stringp old) (setq old (math-read-expr old)))
214 (if (eq (car-safe old) 'error) 214 (if (eq (car-safe old) 'error)
215 (error "Error in expression: " (nth 1 old))) 215 (error "Error in expression: %S" (nth 1 old)))
216 (if (equal new "") (setq new "local")) 216 (if (equal new "") (setq new "local"))
217 (if (stringp new) (setq new (math-read-expr new))) 217 (if (stringp new) (setq new (math-read-expr new)))
218 (if (eq (car-safe new) 'error) 218 (if (eq (car-safe new) 'error)
219 (error "Error in expression: " (nth 1 new))) 219 (error "Error in expression: %S" (nth 1 new)))
220 (calc-enter-result 1 "tzcv" (list 'calcFunc-tzconv 220 (calc-enter-result 1 "tzcv" (list 'calcFunc-tzconv
221 (calc-top-n 1) old new))))) 221 (calc-top-n 1) old new)))))
222 222
diff --git a/lisp/calc/calc-map.el b/lisp/calc/calc-map.el
index 07279a677aa..a6a5777df7e 100644
--- a/lisp/calc/calc-map.el
+++ b/lisp/calc/calc-map.el
@@ -1,6 +1,6 @@
1;;; calc-map.el --- higher-order functions for Calc 1;;; calc-map.el --- higher-order functions for Calc
2 2
3;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2004 Free Software Foundation, Inc.
4 4
5;; Author: David Gillespie <daveg@synaptics.com> 5;; Author: David Gillespie <daveg@synaptics.com>
6;; Maintainers: D. Goel <deego@gnufans.org> 6;; Maintainers: D. Goel <deego@gnufans.org>
@@ -700,10 +700,7 @@
700 (calcFunc-afixp . 2)))))) 700 (calcFunc-afixp . 2))))))
701 (oper3 (if (eq (nth 2 oper) 'calcFunc-inner) 701 (oper3 (if (eq (nth 2 oper) 'calcFunc-inner)
702 (calc-get-operator 702 (calc-get-operator
703 (format "%s%s, inner (add)" msg dir 703 (format "%s%s, inner (add)" msg dir))
704 (substring
705 (symbol-name (nth 2 oper))
706 9)))
707 '(0 0 0))) 704 '(0 0 0)))
708 (args nil) 705 (args nil)
709 (nargs (if (> (nth 1 oper) 0) 706 (nargs (if (> (nth 1 oper) 0)
diff --git a/lisp/diff-mode.el b/lisp/diff-mode.el
index e44e79856e8..14be2e841a3 100644
--- a/lisp/diff-mode.el
+++ b/lisp/diff-mode.el
@@ -1,6 +1,6 @@
1;;; diff-mode.el --- a mode for viewing/editing context diffs 1;;; diff-mode.el --- a mode for viewing/editing context diffs
2 2
3;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 1998,1999,2000,01,02,03,2004 Free Software Foundation, Inc.
4 4
5;; Author: Stefan Monnier <monnier@cs.yale.edu> 5;; Author: Stefan Monnier <monnier@cs.yale.edu>
6;; Keywords: convenience patch diff 6;; Keywords: convenience patch diff
@@ -28,7 +28,7 @@
28;; commands, editing and various conversions as well as jumping 28;; commands, editing and various conversions as well as jumping
29;; to the corresponding source file. 29;; to the corresponding source file.
30 30
31;; Inspired by Pavel Machek's patch-mode.el (<pavel@atrey.karlin.mff.cuni.cz>) 31;; Inspired by Pavel Machek's patch-mode.el (<pavel@@atrey.karlin.mff.cuni.cz>)
32;; Some efforts were spent to have it somewhat compatible with XEmacs' 32;; Some efforts were spent to have it somewhat compatible with XEmacs'
33;; diff-mode as well as with compilation-minor-mode 33;; diff-mode as well as with compilation-minor-mode
34 34
@@ -272,18 +272,6 @@ when editing big diffs)."
272 (nil "^--- \\([^\t\n]+\\)\t.*\n\\*" 1))) ; context diffs 272 (nil "^--- \\([^\t\n]+\\)\t.*\n\\*" 1))) ; context diffs
273 273
274;;;; 274;;;;
275;;;; Compile support
276;;;;
277
278(defvar diff-file-regexp-alist
279 '(("Index: \\(.+\\)" 1)))
280
281(defvar diff-error-regexp-alist
282 '(("@@ -\\([0-9]+\\),[0-9]+ \\+\\([0-9]+\\),[0-9]+ @@" nil 2)
283 ("--- \\([0-9]+\\),[0-9]+ ----" nil 1)
284 ("\\([0-9]+\\)\\(,[0-9]+\\)?[adc]\\([0-9]+\\)" nil 3)))
285
286;;;;
287;;;; Movement 275;;;; Movement
288;;;; 276;;;;
289 277
@@ -879,31 +867,11 @@ a diff with \\[diff-reverse-direction]."
879 ;; (set (make-local-variable 'page-delimiter) "--- [^\t]+\t") 867 ;; (set (make-local-variable 'page-delimiter) "--- [^\t]+\t")
880 ;; compile support 868 ;; compile support
881 869
882 ;;;; compile support is not good enough yet. It should be merged
883 ;;;; with diff.el's support.
884 (set (make-local-variable 'compilation-file-regexp-alist)
885 diff-file-regexp-alist)
886 (set (make-local-variable 'compilation-error-regexp-alist)
887 diff-error-regexp-alist)
888 (when (string-match "\\.rej\\'" (or buffer-file-name ""))
889 (set (make-local-variable 'compilation-current-file)
890 (substring buffer-file-name 0 (match-beginning 0))))
891 ;; Be careful not to change compilation-last-buffer when we're just
892 ;; doing a C-x v = (for example).
893 (if (boundp 'compilation-last-buffer)
894 (let ((compilation-last-buffer compilation-last-buffer))
895 (compilation-minor-mode 1))
896 (compilation-minor-mode 1))
897 ;; M-RET and RET should be done by diff-mode because the `compile'
898 ;; support is significantly less good.
899 (add-to-list 'minor-mode-overriding-map-alist
900 (cons 'compilation-minor-mode (make-sparse-keymap)))
901
902 (when (and (> (point-max) (point-min)) diff-default-read-only) 870 (when (and (> (point-max) (point-min)) diff-default-read-only)
903 (toggle-read-only t)) 871 (toggle-read-only t))
904 ;; setup change hooks 872 ;; setup change hooks
905 (if (not diff-update-on-the-fly) 873 (if (not diff-update-on-the-fly)
906 (add-hook 'write-contents-hooks 'diff-write-contents-hooks) 874 (add-hook 'write-contents-functions 'diff-write-contents-hooks nil t)
907 (make-local-variable 'diff-unhandled-changes) 875 (make-local-variable 'diff-unhandled-changes)
908 (add-hook 'after-change-functions 'diff-after-change-function nil t) 876 (add-hook 'after-change-functions 'diff-after-change-function nil t)
909 (add-hook 'post-command-hook 'diff-post-command-hook nil t)) 877 (add-hook 'post-command-hook 'diff-post-command-hook nil t))
@@ -924,7 +892,7 @@ a diff with \\[diff-reverse-direction]."
924 ;; FIXME: setup font-lock 892 ;; FIXME: setup font-lock
925 ;; setup change hooks 893 ;; setup change hooks
926 (if (not diff-update-on-the-fly) 894 (if (not diff-update-on-the-fly)
927 (add-hook 'write-contents-hooks 'diff-write-contents-hooks) 895 (add-hook 'write-contents-functions 'diff-write-contents-hooks nil t)
928 (make-local-variable 'diff-unhandled-changes) 896 (make-local-variable 'diff-unhandled-changes)
929 (add-hook 'after-change-functions 'diff-after-change-function nil t) 897 (add-hook 'after-change-functions 'diff-after-change-function nil t)
930 (add-hook 'post-command-hook 'diff-post-command-hook nil t))) 898 (add-hook 'post-command-hook 'diff-post-command-hook nil t)))
diff --git a/lisp/diff.el b/lisp/diff.el
index 5981e1888e1..231130db212 100644
--- a/lisp/diff.el
+++ b/lisp/diff.el
@@ -1,6 +1,6 @@
1;;; diff.el --- run `diff' in compilation-mode 1;;; diff.el --- run `diff' in compilation-mode
2 2
3;; Copyright (C) 1992, 1994, 1996, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 1994, 1996, 2001, 2004 Free Software Foundation, Inc.
4 4
5;; Maintainer: FSF 5;; Maintainer: FSF
6;; Keywords: unix, tools 6;; Keywords: unix, tools
@@ -30,8 +30,6 @@
30 30
31;;; Code: 31;;; Code:
32 32
33(require 'compile)
34
35(defgroup diff nil 33(defgroup diff nil
36 "Comparing files with `diff'." 34 "Comparing files with `diff'."
37 :group 'tools) 35 :group 'tools)
@@ -48,237 +46,109 @@
48 :type 'string 46 :type 'string
49 :group 'diff) 47 :group 'diff)
50 48
51(defvar diff-regexp-alist
52 '(
53 ;; -u format: @@ -OLDSTART,OLDEND +NEWSTART,NEWEND @@
54 ("^@@ -\\([0-9]+\\),[0-9]+ \\+\\([0-9]+\\),[0-9]+ @@$" 1 2)
55
56 ;; -c format: *** OLDSTART,OLDEND ****
57 ("^\\*\\*\\* \\([0-9]+\\),[0-9]+ \\*\\*\\*\\*$" 1 nil)
58 ;; --- NEWSTART,NEWEND ----
59 ("^--- \\([0-9]+\\),[0-9]+ ----$" nil 1)
60
61 ;; plain diff format: OLDSTART[,OLDEND]{a,d,c}NEWSTART[,NEWEND]
62 ("^\\([0-9]+\\)\\(,[0-9]+\\)?[adc]\\([0-9]+\\)\\(,[0-9]+\\)?$" 1 3)
63
64 ;; -e (ed) format: OLDSTART[,OLDEND]{a,d,c}
65 ("^\\([0-9]+\\)\\(,[0-9]+\\)?[adc]$" 1)
66
67 ;; -f format: {a,d,c}OLDSTART[ OLDEND]
68 ;; -n format: {a,d,c}OLDSTART LINES-CHANGED
69 ("^[adc]\\([0-9]+\\)\\( [0-9]+\\)?$" 1)
70 )
71 "Alist of regular expressions to match difference sections in \\[diff] output.
72Each element has the form (REGEXP OLD-IDX NEW-IDX).
73Any text that REGEXP matches identifies one difference hunk
74or the header of a hunk.
75
76The OLD-IDX'th subexpression of REGEXP gives the line number
77in the old file, and NEW-IDX'th subexpression gives the line number
78in the new file. If OLD-IDX or NEW-IDX
79is nil, REGEXP matches only half a hunk.")
80
81(defvar diff-old-file nil
82 "This is the old file name in the comparison in this buffer.")
83(defvar diff-new-file nil
84 "This is the new file name in the comparison in this buffer.")
85(defvar diff-old-temp-file nil 49(defvar diff-old-temp-file nil
86 "This is the name of a temp file to be deleted after diff finishes.") 50 "This is the name of a temp file to be deleted after diff finishes.")
87(defvar diff-new-temp-file nil 51(defvar diff-new-temp-file nil
88 "This is the name of a temp file to be deleted after diff finishes.") 52 "This is the name of a temp file to be deleted after diff finishes.")
89 53
90;; See compilation-parse-errors-function (compile.el). 54;; prompt if prefix arg present
91(defun diff-parse-differences (limit-search find-at-least) 55(defun diff-switches ()
92 (setq compilation-error-list nil) 56 (if current-prefix-arg
93 (message "Parsing differences...") 57 (read-string "Diff switches: "
94 58 (if (stringp diff-switches)
95 ;; Don't reparse diffs already seen at last parse. 59 diff-switches
96 (if compilation-parsing-end (goto-char compilation-parsing-end)) 60 (mapconcat 'identity diff-switches " ")))))
97 61
98 ;; Construct in REGEXP a regexp composed of all those in dired-regexp-alist. 62(defun diff-sentinel (code)
99 (let ((regexp (mapconcat (lambda (elt) 63 "Code run when the diff process exits.
100 (concat "\\(" (car elt) "\\)")) 64CODE is the exit code of the process. It should be 0 iff no diffs were found."
101 diff-regexp-alist 65 (if diff-old-temp-file (delete-file diff-old-temp-file))
102 "\\|")) 66 (if diff-new-temp-file (delete-file diff-new-temp-file))
103 ;; (GROUP-IDX OLD-IDX NEW-IDX) 67 (save-excursion
104 (groups (let ((subexpr 1)) 68 (goto-char (point-max))
105 (mapcar (lambda (elt) 69 (insert (format "\nDiff finished%s. %s\n"
106 (prog1 70 (if (equal 0 code) " (no differences)" "")
107 (cons subexpr 71 (current-time-string)))))
108 (mapcar (lambda (n)
109 (and n
110 (+ subexpr n)))
111 (cdr elt)))
112 (setq subexpr (+ subexpr 1
113 (count-regexp-groupings
114 (car elt))))))
115 diff-regexp-alist)))
116
117 (new-error
118 (function (lambda (file subexpr)
119 (setq compilation-error-list
120 (cons
121 (list (save-excursion
122 ;; Report location of message
123 ;; at beginning of line.
124 (goto-char
125 (match-beginning subexpr))
126 (beginning-of-line)
127 (point-marker))
128 ;; Report location of corresponding text.
129 (list file nil)
130 (string-to-int
131 (buffer-substring
132 (match-beginning subexpr)
133 (match-end subexpr)))
134 nil)
135 compilation-error-list)))))
136
137 (found-desired nil)
138 (num-loci-found 0)
139 g)
140
141 (while (and (not found-desired)
142 ;; We don't just pass LIMIT-SEARCH to re-search-forward
143 ;; because we want to find matches containing LIMIT-SEARCH
144 ;; but which extend past it.
145 (re-search-forward regexp nil t))
146
147 ;; Find which individual regexp matched.
148 (setq g groups)
149 (while (and g (null (match-beginning (car (car g)))))
150 (setq g (cdr g)))
151 (setq g (car g))
152
153 (if (nth 1 g) ;OLD-IDX
154 (funcall new-error diff-old-file (nth 1 g)))
155 (if (nth 2 g) ;NEW-IDX
156 (funcall new-error diff-new-file (nth 2 g)))
157
158 (setq num-loci-found (1+ num-loci-found))
159 (if (or (and find-at-least
160 (>= num-loci-found find-at-least))
161 (and limit-search (>= (point) limit-search)))
162 ;; We have found as many new loci as the user wants,
163 ;; or the user wanted a specific diff, and we're past it.
164 (setq found-desired t)))
165 (set-marker compilation-parsing-end
166 (if found-desired (point)
167 ;; Set to point-max, not point, so we don't perpetually
168 ;; parse the last bit of text when it isn't a diff header.
169 (point-max)))
170 (message "Parsing differences...done"))
171 (setq compilation-error-list (nreverse compilation-error-list)))
172
173(defun diff-process-setup ()
174 "Set up \`compilation-exit-message-function' for \`diff'."
175 ;; Avoid frightening people with "abnormally terminated"
176 ;; if diff finds differences.
177 (set (make-local-variable 'compilation-exit-message-function)
178 (lambda (status code msg)
179 (cond ((not (eq status 'exit))
180 (cons msg code))
181 ((zerop code)
182 '("finished (no differences)\n" . "no differences"))
183 ((= code 1)
184 '("finished\n" . "differences found"))
185 (t
186 (cons msg code))))))
187 72
188;;;###autoload 73;;;###autoload
189(defun diff (old new &optional switches no-async) 74(defun diff (old new &optional switches no-async)
190 "Find and display the differences between OLD and NEW files. 75 "Find and display the differences between OLD and NEW files.
191Interactively the current buffer's file name is the default for NEW 76Interactively the current buffer's file name is the default for NEW
192and a backup file for NEW is the default for OLD. 77and a backup file for NEW is the default for OLD.
193With prefix arg, prompt for diff switches. 78If NO-ASYNC is non-nil, call diff synchronously.
194If NO-ASYNC is non-nil, call diff synchronously." 79With prefix arg, prompt for diff switches."
195 (interactive 80 (interactive
196 (nconc 81 (let (oldf newf)
197 (let (oldf newf) 82 (setq newf (buffer-file-name)
198 (nreverse 83 newf (if (and newf (file-exists-p newf))
199 (list 84 (read-file-name
200 (setq newf (buffer-file-name) 85 (concat "Diff new file: (default "
201 newf (if (and newf (file-exists-p newf)) 86 (file-name-nondirectory newf) ") ")
202 (read-file-name 87 nil newf t)
203 (concat "Diff new file: (default " 88 (read-file-name "Diff new file: " nil nil t)))
204 (file-name-nondirectory newf) ") ") 89 (setq oldf (file-newest-backup newf)
205 nil newf t) 90 oldf (if (and oldf (file-exists-p oldf))
206 (read-file-name "Diff new file: " nil nil t))) 91 (read-file-name
207 (setq oldf (file-newest-backup newf) 92 (concat "Diff original file: (default "
208 oldf (if (and oldf (file-exists-p oldf)) 93 (file-name-nondirectory oldf) ") ")
209 (read-file-name 94 (file-name-directory oldf) oldf t)
210 (concat "Diff original file: (default " 95 (read-file-name "Diff original file: "
211 (file-name-nondirectory oldf) ") ") 96 (file-name-directory newf) nil t)))
212 (file-name-directory oldf) oldf t) 97 (list oldf newf (diff-switches))))
213 (read-file-name "Diff original file: "
214 (file-name-directory newf) nil t))))))
215 (if current-prefix-arg
216 (list (read-string "Diff switches: "
217 (if (stringp diff-switches)
218 diff-switches
219 (mapconcat 'identity diff-switches " "))))
220 nil)))
221 (setq new (expand-file-name new) 98 (setq new (expand-file-name new)
222 old (expand-file-name old)) 99 old (expand-file-name old))
223 (let ((old-alt (file-local-copy old)) 100 (or switches (setq switches diff-switches)) ; If not specified, use default.
101 (let* ((old-alt (file-local-copy old))
224 (new-alt (file-local-copy new)) 102 (new-alt (file-local-copy new))
225 buf) 103 (command
104 (mapconcat 'identity
105 `(,diff-command
106 ;; Use explicitly specified switches
107 ,@(if (listp switches) switches (list switches))
108 ,@(if (or old-alt new-alt)
109 (list "-L" old "-L" new))
110 ,(shell-quote-argument (or old-alt old))
111 ,(shell-quote-argument (or new-alt new)))
112 " "))
113 (buf (get-buffer-create "*Diff*"))
114 proc)
226 (save-excursion 115 (save-excursion
227 (let ((compilation-process-setup-function 'diff-process-setup) 116 (display-buffer buf)
228 (command 117 (set-buffer buf)
229 (mapconcat 'identity 118 (setq buffer-read-only nil)
230 (append (list diff-command) 119 (buffer-disable-undo (current-buffer))
231 ;; Use explicitly specified switches 120 (erase-buffer)
232 (if switches 121 (buffer-enable-undo (current-buffer))
233 (if (consp switches) 122 (diff-mode)
234 switches (list switches)) 123 (set (make-local-variable 'revert-buffer-function)
235 ;; If not specified, use default. 124 `(lambda (ignore-auto noconfirm)
236 (if (consp diff-switches) 125 (diff ',old ',new ',switches ',no-async)))
237 diff-switches 126 (set (make-local-variable 'diff-old-temp-file) old-alt)
238 (list diff-switches))) 127 (set (make-local-variable 'diff-new-temp-file) new-alt)
239 (if (or old-alt new-alt) 128 (insert command "\n")
240 (list "-L" old "-L" new)) 129 (if (and (not no-async) (fboundp 'start-process))
241 (list 130 (progn
242 (shell-quote-argument (or old-alt old))) 131 (setq proc (start-process "Diff" buf shell-file-name
243 (list 132 shell-command-switch command))
244 (shell-quote-argument (or new-alt new)))) 133 (set-process-sentinel
245 " "))) 134 proc (lambda (proc msg)
246 (setq buf 135 (with-current-buffer (process-buffer proc)
247 (compile-internal command 136 (diff-sentinel (process-exit-status proc))))))
248 "No more differences" "Diff" 137 ;; Async processes aren't available.
249 'diff-parse-differences 138 (diff-sentinel
250 nil nil nil nil nil nil no-async)) 139 (call-process shell-file-name nil buf nil
251 (set-buffer buf) 140 shell-command-switch command))))
252 (set (make-local-variable 'diff-old-file) old) 141 buf))
253 (set (make-local-variable 'diff-new-file) new)
254 (set (make-local-variable 'diff-old-temp-file) old-alt)
255 (set (make-local-variable 'diff-new-temp-file) new-alt)
256 (set (make-local-variable 'compilation-finish-function)
257 (function (lambda (buff msg)
258 (if diff-old-temp-file
259 (delete-file diff-old-temp-file))
260 (if diff-new-temp-file
261 (delete-file diff-new-temp-file)))))
262 ;; When async processes aren't available, the compilation finish
263 ;; function doesn't get chance to run. Invoke it by hand.
264 (or (fboundp 'start-process)
265 (funcall compilation-finish-function nil nil))
266 buf))))
267 142
268;;;###autoload 143;;;###autoload
269(defun diff-backup (file &optional switches) 144(defun diff-backup (file &optional switches)
270 "Diff this file with its backup file or vice versa. 145 "Diff this file with its backup file or vice versa.
271Uses the latest backup, if there are several numerical backups. 146Uses the latest backup, if there are several numerical backups.
272If this file is a backup, diff it with its original. 147If this file is a backup, diff it with its original.
273The backup file is the first file given to `diff'." 148The backup file is the first file given to `diff'.
149With prefix arg, prompt for diff switches."
274 (interactive (list (read-file-name "Diff (file with backup): ") 150 (interactive (list (read-file-name "Diff (file with backup): ")
275 (if current-prefix-arg 151 (diff-switches)))
276 (read-string "Diff switches: "
277 (if (stringp diff-switches)
278 diff-switches
279 (mapconcat 'identity
280 diff-switches " ")))
281 nil)))
282 (let (bak ori) 152 (let (bak ori)
283 (if (backup-file-name-p file) 153 (if (backup-file-name-p file)
284 (setq bak file 154 (setq bak file
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 0a3fa220248..fe8e33cfd48 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1,6 +1,6 @@
1;;; dired-aux.el --- less commonly used parts of dired -*-byte-compile-dynamic: t;-*- 1;;; dired-aux.el --- less commonly used parts of dired -*-byte-compile-dynamic: t;-*-
2 2
3;; Copyright (C) 1985, 1986, 1992, 1994, 1998, 2000, 2001 3;; Copyright (C) 1985, 1986, 1992, 1994, 1998, 2000, 2001, 2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>. 6;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>.
@@ -2114,7 +2114,7 @@ with the command \\[tags-loop-continue]."
2114 (let ((buffer (get-file-buffer file))) 2114 (let ((buffer (get-file-buffer file)))
2115 (if (and buffer (with-current-buffer buffer 2115 (if (and buffer (with-current-buffer buffer
2116 buffer-read-only)) 2116 buffer-read-only))
2117 (error "File `%s' is visited read-only")))) 2117 (error "File `%s' is visited read-only" file))))
2118 (tags-query-replace from to delimited 2118 (tags-query-replace from to delimited
2119 '(dired-get-marked-files nil nil 'dired-nondirectory-p))) 2119 '(dired-get-marked-files nil nil 'dired-nondirectory-p)))
2120 2120
diff --git a/lisp/dired.el b/lisp/dired.el
index c15134e3bc9..c3511baea47 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1292,7 +1292,16 @@ Keybindings:
1292 (or switches dired-listing-switches)) 1292 (or switches dired-listing-switches))
1293 (set (make-local-variable 'font-lock-defaults) '(dired-font-lock-keywords t)) 1293 (set (make-local-variable 'font-lock-defaults) '(dired-font-lock-keywords t))
1294 (dired-sort-other dired-actual-switches t) 1294 (dired-sort-other dired-actual-switches t)
1295 (run-hooks 'dired-mode-hook)) 1295 (run-hooks 'dired-mode-hook)
1296 (when (featurep 'x-dnd)
1297 (make-variable-buffer-local 'x-dnd-test-function)
1298 (make-variable-buffer-local 'x-dnd-protocol-alist)
1299 (setq x-dnd-test-function 'dired-dnd-test-function)
1300 (setq x-dnd-protocol-alist
1301 (append '(("^file:///" . dired-dnd-handle-local-file)
1302 ("^file://" . dired-dnd-handle-file)
1303 ("^file:" . dired-dnd-handle-local-file))
1304 x-dnd-protocol-alist))))
1296 1305
1297;; Idiosyncratic dired commands that don't deal with marks. 1306;; Idiosyncratic dired commands that don't deal with marks.
1298 1307
@@ -3131,6 +3140,93 @@ true then the type of the file linked to by FILE is printed instead."
3131 3140
3132(autoload 'dired-query "dired-aux") 3141(autoload 'dired-query "dired-aux")
3133 3142
3143
3144;;;; Drag and drop support
3145
3146(defun dired-dnd-test-function (window action types)
3147 "The test function for drag and drop into dired buffers.
3148WINDOW is where the mouse is when this function is called. It may be a frame
3149if the mouse is over the menu bar, scroll bar or tool bar.
3150ACTION is the suggested action from the source, and TYPES are the
3151types the drop data can have. This function only accepts drops with
3152types in `x-dnd-known-types'. It returns the action suggested by the source."
3153 (let ((type (x-dnd-choose-type types)))
3154 (if type
3155 (cons action type)
3156 nil)))
3157
3158(defun dired-dnd-popup-notice ()
3159 (x-popup-dialog
3160 t
3161 '("Recursive copies not enabled.\nSee variable dired-recursive-copies."
3162 ("Ok" . nil))))
3163
3164
3165(defun dired-dnd-do-ask-action (uri)
3166 ;; No need to get actions and descriptions from the source,
3167 ;; we only have three actions anyway.
3168 (let ((action (x-popup-menu
3169 t
3170 (list "What action?"
3171 (cons ""
3172 '(("Copy here" . copy)
3173 ("Move here" . move)
3174 ("Link here" . link)
3175 "--"
3176 ("Cancel" . nil)))))))
3177 (if action
3178 (dired-dnd-handle-local-file uri action)
3179 nil)))
3180
3181(defun dired-dnd-handle-local-file (uri action)
3182 "Copy, move or link a file to the dired directory.
3183URI is the file to handle, ACTION is one of copy, move, link or ask.
3184Ask means pop up a menu for the user to select one of copy, move or link."
3185 (require 'dired-aux)
3186 (let* ((from (x-dnd-get-local-file-name uri t))
3187 (to (if from (concat (dired-current-directory)
3188 (file-name-nondirectory from))
3189 nil)))
3190 (if from
3191 (cond ((or (eq action 'copy)
3192 (eq action 'private)) ; Treat private as copy.
3193
3194 ;; If copying a directory and dired-recursive-copies is nil,
3195 ;; dired-copy-file silently fails. Pop up a notice.
3196 (if (and (file-directory-p from)
3197 (not dired-recursive-copies))
3198 (dired-dnd-popup-notice)
3199 (progn
3200 (dired-copy-file from to 1)
3201 (dired-relist-entry to)
3202 action)))
3203
3204 ((eq action 'move)
3205 (dired-rename-file from to 1)
3206 (dired-relist-entry to)
3207 action)
3208
3209 ((eq action 'link)
3210 (make-symbolic-link from to 1)
3211 (dired-relist-entry to)
3212 action)
3213
3214 ((eq action 'ask)
3215 (dired-dnd-do-ask-action uri))
3216
3217 (t nil)))))
3218
3219(defun dired-dnd-handle-file (uri action)
3220 "Copy, move or link a file to the dired directory if it is a local file.
3221URI is the file to handle. If the hostname in the URI isn't local, do nothing.
3222ACTION is one of copy, move, link or ask.
3223Ask means pop up a menu for the user to select one of copy, move or link."
3224 (let ((local-file (x-dnd-get-local-file-uri uri)))
3225 (if local-file (dired-dnd-handle-local-file local-file action)
3226 nil)))
3227
3228
3229
3134(if (eq system-type 'vax-vms) 3230(if (eq system-type 'vax-vms)
3135 (load "dired-vms")) 3231 (load "dired-vms"))
3136 3232
diff --git a/lisp/ediff-util.el b/lisp/ediff-util.el
index d69997394e4..9550e65c2e9 100644
--- a/lisp/ediff-util.el
+++ b/lisp/ediff-util.el
@@ -1,6 +1,6 @@
1;;; ediff-util.el --- the core commands and utilities of ediff 1;;; ediff-util.el --- the core commands and utilities of ediff
2 2
3;; Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02 Free Software Foundation, Inc. 3;; Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 04 Free Software Foundation, Inc.
4 4
5;; Author: Michael Kifer <kifer@cs.stonybrook.edu> 5;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
6 6
@@ -1080,8 +1080,10 @@ of the current buffer."
1080 (eq this-command 'ediff-toggle-read-only) 1080 (eq this-command 'ediff-toggle-read-only)
1081 (file-exists-p file) 1081 (file-exists-p file)
1082 (not (file-writable-p file))) 1082 (not (file-writable-p file)))
1083 (message "Warning: file %s is read-only" 1083 (progn
1084 (ediff-abbreviate-file-name file) (beep 1))) 1084 (beep 1)
1085 (message "Warning: file %s is read-only"
1086 (ediff-abbreviate-file-name file))))
1085 )))) 1087 ))))
1086 1088
1087;; checkout if visited file is checked in 1089;; checkout if visited file is checked in
@@ -2233,7 +2235,7 @@ a regular expression typed in by the user."
2233 (if (y-or-n-p 2235 (if (y-or-n-p
2234 (format 2236 (format
2235 "Ignore regions that match %s regexps, OK? " 2237 "Ignore regions that match %s regexps, OK? "
2236 msg-connective alt-msg-connective)) 2238 msg-connective))
2237 (message "Will ignore regions that match %s regexps" msg-connective) 2239 (message "Will ignore regions that match %s regexps" msg-connective)
2238 (setq ediff-hide-regexp-connective alt-connective) 2240 (setq ediff-hide-regexp-connective alt-connective)
2239 (message "Will ignore regions that match %s regexps" 2241 (message "Will ignore regions that match %s regexps"
@@ -2272,7 +2274,7 @@ a regular expression typed in by the user."
2272 (if (y-or-n-p 2274 (if (y-or-n-p
2273 (format 2275 (format
2274 "Focus on regions that match %s regexps, OK? " 2276 "Focus on regions that match %s regexps, OK? "
2275 msg-connective alt-msg-connective)) 2277 msg-connective))
2276 (message "Will focus on regions that match %s regexps" 2278 (message "Will focus on regions that match %s regexps"
2277 msg-connective) 2279 msg-connective)
2278 (setq ediff-focus-regexp-connective alt-connective) 2280 (setq ediff-focus-regexp-connective alt-connective)
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 038786bb944..6a6b006c2ba 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -1,6 +1,6 @@
1;;; cl-macs.el --- Common Lisp macros -*-byte-compile-dynamic: t;-*- 1;;; cl-macs.el --- Common Lisp macros -*-byte-compile-dynamic: t;-*-
2 2
3;; Copyright (C) 1993, 2003 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 2003, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Dave Gillespie <daveg@synaptics.com> 5;; Author: Dave Gillespie <daveg@synaptics.com>
6;; Version: 2.02 6;; Version: 2.02
@@ -2261,8 +2261,7 @@ copier, a `NAME-p' predicate, and setf-able `NAME-SLOT' accessors.
2261 (list (list 'or pred-check 2261 (list (list 'or pred-check
2262 (list 'error 2262 (list 'error
2263 (format "%s accessing a non-%s" 2263 (format "%s accessing a non-%s"
2264 accessor name) 2264 accessor name)))))
2265 'cl-x))))
2266 (list (if (eq type 'vector) (list 'aref 'cl-x pos) 2265 (list (if (eq type 'vector) (list 'aref 'cl-x pos)
2267 (if (= pos 0) '(car cl-x) 2266 (if (= pos 0) '(car cl-x)
2268 (list 'nth pos 'cl-x)))))) forms) 2267 (list 'nth pos 'cl-x)))))) forms)
@@ -2340,8 +2339,7 @@ copier, a `NAME-p' predicate, and setf-able `NAME-SLOT' accessors.
2340 (list (list 'or (subst temp 'cl-x pred-form) 2339 (list (list 'or (subst temp 'cl-x pred-form)
2341 (list 'error 2340 (list 'error
2342 (format 2341 (format
2343 "%s storing a non-%s" accessor name) 2342 "%s storing a non-%s" accessor name)))))
2344 temp))))
2345 (list (if (eq (car (get name 'cl-struct-type)) 'vector) 2343 (list (if (eq (car (get name 'cl-struct-type)) 'vector)
2346 (list 'aset temp pos store) 2344 (list 'aset temp pos store)
2347 (list 'setcar 2345 (list 'setcar
diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el
index 245772dfc54..e67835eb82d 100644
--- a/lisp/emacs-lisp/lisp-mnt.el
+++ b/lisp/emacs-lisp/lisp-mnt.el
@@ -1,6 +1,6 @@
1;;; lisp-mnt.el --- utility functions for Emacs Lisp maintainers 1;;; lisp-mnt.el --- utility functions for Emacs Lisp maintainers
2 2
3;; Copyright (C) 1992, 1994, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 1994, 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Eric S. Raymond <esr@snark.thyrsus.com> 5;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
6;; Maintainer: FSF 6;; Maintainer: FSF
@@ -522,7 +522,7 @@ copyright notice is allowed."
522 (setq ret 522 (setq ret
523 (cond 523 (cond
524 ((null name) 524 ((null name)
525 (format "Package %s does not exist")) 525 "Can't find package name")
526 ((not (lm-authors)) 526 ((not (lm-authors))
527 "`Author:' tag missing") 527 "`Author:' tag missing")
528 ((not (lm-maintainer)) 528 ((not (lm-maintainer))
@@ -546,7 +546,7 @@ copyright notice is allowed."
546 (concat "^;;;[ \t]+" name "[ \t]+ends here[ \t]*$" 546 (concat "^;;;[ \t]+" name "[ \t]+ends here[ \t]*$"
547 "\\|^;;;[ \t]+ End of file[ \t]+" name) 547 "\\|^;;;[ \t]+ End of file[ \t]+" name)
548 nil t))) 548 nil t)))
549 (format "Can't find the footer line")) 549 "Can't find the footer line")
550 ((not (and (lm-copyright-mark) (lm-crack-copyright))) 550 ((not (and (lm-copyright-mark) (lm-crack-copyright)))
551 "Can't find a valid copyright notice") 551 "Can't find a valid copyright notice")
552 ((not (or non-fsf-ok 552 ((not (or non-fsf-ok
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 04d00a2bdb5..c2dc3e6a16c 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -182,7 +182,7 @@
182 (make-local-variable 'parse-sexp-ignore-comments) 182 (make-local-variable 'parse-sexp-ignore-comments)
183 (setq parse-sexp-ignore-comments t) 183 (setq parse-sexp-ignore-comments t)
184 (make-local-variable 'outline-regexp) 184 (make-local-variable 'outline-regexp)
185 (setq outline-regexp ";;;;* \\|(") 185 (setq outline-regexp ";;;;* [^ \t\n]\\|(")
186 (make-local-variable 'outline-level) 186 (make-local-variable 'outline-level)
187 (setq outline-level 'lisp-outline-level) 187 (setq outline-level 'lisp-outline-level)
188 (make-local-variable 'comment-start) 188 (make-local-variable 'comment-start)
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
new file mode 100644
index 00000000000..b5a279bbbf4
--- /dev/null
+++ b/lisp/emacs-lisp/macroexp.el
@@ -0,0 +1,197 @@
1;;; macroexp.el --- Additional macro-expansion support
2;;
3;; Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
4;;
5;; Author: Miles Bader <miles@gnu.org>
6;; Keywords: lisp, compiler, macros
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
24
25;;; Commentary:
26;;
27;; This file contains macro-expansions functions that are not defined in
28;; the Lisp core, namely `macroexpand-all', which expands all macros in
29;; a form, not just a top-level one.
30;;
31
32;;; Code:
33
34;; Bound by the top-level `macroexpand-all', and modified to include any
35;; macros defined by `defmacro'.
36(defvar macroexpand-all-environment nil)
37
38(defun maybe-cons (car cdr original-cons)
39 "Return (CAR . CDR), using ORIGINAL-CONS if possible."
40 (if (and (eq car (car original-cons)) (eq cdr (cdr original-cons)))
41 original-cons
42 (cons car cdr)))
43
44;; We use this special macro to iteratively process forms and share list
45;; structure of the result with the input. Doing so recursively using
46;; `maybe-cons' results in excessively deep recursion for very long
47;; input forms.
48(defmacro macroexp-accumulate (#1=#:\(var\ list\) &rest body)
49 "Return a list of the results of evaluating BODY for each element of LIST.
50Evaluate BODY with VAR bound to each `car' from LIST, in turn.
51Return a list of the values of the final form in BODY.
52The list structure of the result will share as much with LIST as
53possible (for instance, when BODY just returns VAR unchanged, the
54result will be eq to LIST)."
55 (let ((var (car #1#))
56 (list (cadr #1#))
57 (shared (make-symbol "shared"))
58 (unshared (make-symbol "unshared"))
59 (tail (make-symbol "tail"))
60 (new-el (make-symbol "new-el")))
61 `(let* ((,shared ,list)
62 (,unshared nil)
63 (,tail ,shared)
64 ,var ,new-el)
65 (while ,tail
66 (setq ,var (car ,tail)
67 ,new-el (progn ,@body))
68 (unless (eq ,var ,new-el)
69 (while (not (eq ,shared ,tail))
70 (push (pop ,shared) ,unshared))
71 (setq ,shared (cdr ,shared))
72 (push ,new-el ,unshared))
73 (setq ,tail (cdr ,tail)))
74 (nconc (nreverse ,unshared) ,shared))))
75(put 'macroexp-accumulate 'lisp-indent-function 1)
76
77(defun macroexpand-all-forms (forms &optional skip)
78 "Return FORMS with macros expanded. FORMS is a list of forms.
79If SKIP is non-nil, then don't expand that many elements at the start of
80FORMS."
81 (macroexp-accumulate (form forms)
82 (if (or (null skip) (zerop skip))
83 (macroexpand-all-1 form)
84 (setq skip (1- skip))
85 form)))
86
87(defun macroexpand-all-clauses (clauses &optional skip)
88 "Return CLAUSES with macros expanded.
89CLAUSES is a list of lists of forms; any clause that's not a list is ignored.
90If SKIP is non-nil, then don't expand that many elements at the start of
91each clause."
92 (macroexp-accumulate (clause clauses)
93 (if (listp clause)
94 (macroexpand-all-forms clause skip)
95 clause)))
96
97(defun macroexpand-all-1 (form)
98 "Expand all macros in FORM.
99This is an internal version of `macroexpand-all'.
100Assumes the caller has bound `macroexpand-all-environment'."
101 (if (and (listp form) (eq (car form) 'backquote-list*))
102 ;; Special-case `backquote-list*', as it is normally a macro that
103 ;; generates exceedingly deep expansions from relatively shallow input
104 ;; forms. We just process it `in reverse' -- first we expand all the
105 ;; arguments, _then_ we expand the top-level definition.
106 (macroexpand (macroexpand-all-forms form 1)
107 macroexpand-all-environment)
108 ;; Normal form; get its expansion, and then expand arguments.
109 (setq form (macroexpand form macroexpand-all-environment))
110 (if (consp form)
111 (let ((fun (car form)))
112 (cond
113 ((eq fun 'cond)
114 (maybe-cons fun (macroexpand-all-clauses (cdr form)) form))
115 ((eq fun 'condition-case)
116 (maybe-cons
117 fun
118 (maybe-cons (cadr form)
119 (maybe-cons (macroexpand-all-1 (nth 2 form))
120 (macroexpand-all-clauses (nthcdr 3 form) 1)
121 (cddr form))
122 (cdr form))
123 form))
124 ((eq fun 'defmacro)
125 (push (cons (cadr form) (cons 'lambda (cddr form)))
126 macroexpand-all-environment)
127 (macroexpand-all-forms form 3))
128 ((eq fun 'defun)
129 (macroexpand-all-forms form 3))
130 ((memq fun '(defvar defconst))
131 (macroexpand-all-forms form 2))
132 ((eq fun 'function)
133 (if (and (consp (cadr form)) (eq (car (cadr form)) 'lambda))
134 (maybe-cons fun
135 (maybe-cons (macroexpand-all-forms (cadr form) 2)
136 nil
137 (cadr form))
138 form)
139 form))
140 ((memq fun '(let let*))
141 (maybe-cons fun
142 (maybe-cons (macroexpand-all-clauses (cadr form) 1)
143 (macroexpand-all-forms (cddr form))
144 (cdr form))
145 form))
146 ((eq fun 'quote)
147 form)
148 ((and (consp fun) (eq (car fun) 'lambda))
149 ;; embedded lambda
150 (maybe-cons (macroexpand-all-forms fun 2)
151 (macroexpand-all-forms (cdr form))
152 form))
153 ;; The following few cases are for normal function calls that
154 ;; are known to funcall one of their arguments. The byte
155 ;; compiler has traditionally handled these functions specially
156 ;; by treating a lambda expression quoted by `quote' as if it
157 ;; were quoted by `function'. We make the same transformation
158 ;; here, so that any code that cares about the difference will
159 ;; see the same transformation.
160 ;; First arg is a function:
161 ((and (memq fun '(apply mapcar mapatoms mapconcat mapc))
162 (consp (cadr form))
163 (eq (car (cadr form)) 'quote))
164 ;; We don't use `maybe-cons' since there's clearly a change.
165 (cons fun
166 (cons (macroexpand-all-1 (cons 'function (cdr (cadr form))))
167 (macroexpand-all-forms (cddr form)))))
168 ;; Second arg is a function:
169 ((and (eq fun 'sort)
170 (consp (nth 2 form))
171 (eq (car (nth 2 form)) 'quote))
172 ;; We don't use `maybe-cons' since there's clearly a change.
173 (cons fun
174 (cons (macroexpand-all-1 (cadr form))
175 (cons (macroexpand-all-1
176 (cons 'function (cdr (nth 2 form))))
177 (macroexpand-all-forms (nthcdr 3 form))))))
178 (t
179 ;; For everything else, we just expand each argument (for
180 ;; setq/setq-default this works alright because the variable names
181 ;; are symbols).
182 (macroexpand-all-forms form 1))))
183 form)))
184
185;;;###autoload
186(defun macroexpand-all (form &optional environment)
187 "Return result of expanding macros at all levels in FORM.
188If no macros are expanded, FORM is returned unchanged.
189The second optional arg ENVIRONMENT specifies an environment of macro
190definitions to shadow the loaded ones for use in file byte-compilation."
191 (let ((macroexpand-all-environment environment))
192 (macroexpand-all-1 form)))
193
194(provide 'macroexp)
195
196;;; arch-tag: af9b8c24-c196-43bc-91e1-a3570790fa5a
197;;; macroexp.el ends here
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index bc16a84b156..c6f9ce6f4a6 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -345,7 +345,8 @@ matches anything."
345(defun rx-not (form) 345(defun rx-not (form)
346 "Parse and produce code from FORM. FORM is `(not ...)'." 346 "Parse and produce code from FORM. FORM is `(not ...)'."
347 (rx-check form) 347 (rx-check form)
348 (let ((result (rx-to-string (cadr form) 'no-group))) 348 (let ((result (rx-to-string (cadr form) 'no-group))
349 case-fold-search)
349 (cond ((string-match "\\`\\[^" result) 350 (cond ((string-match "\\`\\[^" result)
350 (if (= (length result) 4) 351 (if (= (length result) 4)
351 (substring result 2 3) 352 (substring result 2 3)
diff --git a/lisp/emulation/vi.el b/lisp/emulation/vi.el
index b0a6b4c2666..4e17644e66a 100644
--- a/lisp/emulation/vi.el
+++ b/lisp/emulation/vi.el
@@ -455,7 +455,7 @@ Syntax table and abbrevs while in vi mode remain as they were in Emacs."
455 (vi-mode-setup)) 455 (vi-mode-setup))
456 456
457 (if (eq major-mode 'vi-mode) 457 (if (eq major-mode 'vi-mode)
458 (message "Already in vi-mode." (ding)) 458 (progn (ding) (message "Already in vi-mode."))
459 (setq vi-mode-old-local-map (current-local-map)) 459 (setq vi-mode-old-local-map (current-local-map))
460 (setq vi-mode-old-mode-name mode-name) 460 (setq vi-mode-old-mode-name mode-name)
461 (setq vi-mode-old-major-mode major-mode) 461 (setq vi-mode-old-major-mode major-mode)
@@ -703,7 +703,7 @@ use those instead of the ones saved."
703 regexp-search-ring 703 regexp-search-ring
704 search-ring)))) 704 search-ring))))
705 (if (null search-command) 705 (if (null search-command)
706 (message "No last search command to repeat." (ding)) 706 (progn (ding) (message "No last search command to repeat."))
707 (funcall search-command search-string nil nil arg))) 707 (funcall search-command search-string nil nil arg)))
708 708
709(defun vi-reverse-last-search (arg &optional search-command search-string) 709(defun vi-reverse-last-search (arg &optional search-command search-string)
@@ -718,7 +718,7 @@ If the optional search args are given, use those instead of the ones saved."
718 regexp-search-ring 718 regexp-search-ring
719 search-ring)))) 719 search-ring))))
720 (if (null search-command) 720 (if (null search-command)
721 (message "No last search command to repeat." (ding)) 721 (progn (ding) (message "No last search command to repeat."))
722 (funcall (cond ((eq search-command 're-search-forward) 're-search-backward) 722 (funcall (cond ((eq search-command 're-search-forward) 're-search-backward)
723 ((eq search-command 're-search-backward) 're-search-forward) 723 ((eq search-command 're-search-backward) 're-search-forward)
724 ((eq search-command 'search-forward) 'search-backward) 724 ((eq search-command 'search-forward) 'search-backward)
@@ -838,7 +838,7 @@ Goto mark '@' means jump into and pop the top mark on the mark ring."
838 (t 838 (t
839 (let ((mark (vi-get-mark mark-char))) 839 (let ((mark (vi-get-mark mark-char)))
840 (if (null mark) 840 (if (null mark)
841 (message "Mark register undefined." (vi-ding)) 841 (progn (vi-ding) (message "Mark register undefined."))
842 (set-mark-command nil) 842 (set-mark-command nil)
843 (goto-char mark) 843 (goto-char mark)
844 (if line-flag (back-to-indentation))))))) 844 (if line-flag (back-to-indentation)))))))
@@ -881,7 +881,7 @@ is given, it is used instead of the saved one."
881 (interactive "p") 881 (interactive "p")
882 (if (null find-arg) (setq find-arg vi-last-find-char)) 882 (if (null find-arg) (setq find-arg vi-last-find-char))
883 (if (null find-arg) 883 (if (null find-arg)
884 (message "No last find char to repeat." (ding)) 884 (progn (ding) (message "No last find char to repeat."))
885 (vi-find-char (cons (* (car find-arg) -1) (cdr find-arg)) count))) ;6/13/86 885 (vi-find-char (cons (* (car find-arg) -1) (cdr find-arg)) count))) ;6/13/86
886 886
887(defun vi-find-char (arg count) 887(defun vi-find-char (arg count)
@@ -909,7 +909,7 @@ it is used instead of the saved one."
909 (interactive "p") 909 (interactive "p")
910 (if (null find-arg) (setq find-arg vi-last-find-char)) 910 (if (null find-arg) (setq find-arg vi-last-find-char))
911 (if (null find-arg) 911 (if (null find-arg)
912 (message "No last find char to repeat." (ding)) 912 (progn (ding) (message "No last find char to repeat."))
913 (vi-find-char find-arg count))) 913 (vi-find-char find-arg count)))
914 914
915(defun vi-backward-find-char (count char) 915(defun vi-backward-find-char (count char)
@@ -1465,7 +1465,8 @@ It assumes a `(def..' always starts at the beginning of a line."
1465 (goto-char (point-min)) 1465 (goto-char (point-min))
1466 (if (re-search-forward (concat "^(def[unvarconst ]*" name) nil t) 1466 (if (re-search-forward (concat "^(def[unvarconst ]*" name) nil t)
1467 nil 1467 nil
1468 (message "No definition for \"%s\" in current file." name (ding)) 1468 (ding)
1469 (message "No definition for \"%s\" in current file." name)
1469 (set-mark-command t)))) 1470 (set-mark-command t))))
1470 1471
1471(defun vi-split-open-line (arg) 1472(defun vi-split-open-line (arg)
diff --git a/lisp/emulation/viper-ex.el b/lisp/emulation/viper-ex.el
index eab8ebab591..c94edf54bc2 100644
--- a/lisp/emulation/viper-ex.el
+++ b/lisp/emulation/viper-ex.el
@@ -1,6 +1,6 @@
1;;; viper-ex.el --- functions implementing the Ex commands for Viper 1;;; viper-ex.el --- functions implementing the Ex commands for Viper
2 2
3;; Copyright (C) 1994, 95, 96, 97, 98, 2000, 01, 02 Free Software Foundation, Inc. 3;; Copyright (C) 1994, 95, 96, 97, 98, 2000, 01, 02, 04 Free Software Foundation, Inc.
4 4
5;; Author: Michael Kifer <kifer@cs.stonybrook.edu> 5;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
6 6
@@ -1458,7 +1458,7 @@ reversed."
1458 (if (eq 1 (length name)) 1458 (if (eq 1 (length name))
1459 (setq char (string-to-char name)) 1459 (setq char (string-to-char name))
1460 (error "`%s': Spurious text \"%s\" after mark name" 1460 (error "`%s': Spurious text \"%s\" after mark name"
1461 name (substring name 1) viper-SpuriousText)) 1461 name (substring name 1)))
1462 (save-window-excursion 1462 (save-window-excursion
1463 (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name)) 1463 (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
1464 (set-buffer viper-ex-work-buf) 1464 (set-buffer viper-ex-work-buf)
diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el
index 438e296d9c1..b38c7a519ec 100644
--- a/lisp/eshell/em-hist.el
+++ b/lisp/eshell/em-hist.el
@@ -1,6 +1,6 @@
1;;; em-hist.el --- history list management 1;;; em-hist.el --- history list management
2 2
3;; Copyright (C) 1999, 2000 Free Software Foundation 3;; Copyright (C) 1999, 2000, 2004 Free Software Foundation
4 4
5;; Author: John Wiegley <johnw@gnu.org> 5;; Author: John Wiegley <johnw@gnu.org>
6 6
@@ -523,7 +523,7 @@ See also `eshell-read-history'."
523 ((string= "^" ref) 1) 523 ((string= "^" ref) 1)
524 ((string= "$" ref) nil) 524 ((string= "$" ref) nil)
525 ((string= "%" ref) 525 ((string= "%" ref)
526 (error "`%' history word designator not yet implemented")))) 526 (error "`%%' history word designator not yet implemented"))))
527 527
528(defun eshell-hist-parse-arguments (&optional silent b e) 528(defun eshell-hist-parse-arguments (&optional silent b e)
529 "Parse current command arguments in a history-code-friendly way." 529 "Parse current command arguments in a history-code-friendly way."
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index 579d1200caf..f76900bf482 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -1,6 +1,6 @@
1;;; esh-mode.el --- user interface 1;;; esh-mode.el --- user interface
2 2
3;; Copyright (C) 1999, 2000, 2001 Free Software Foundation 3;; Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation
4 4
5;; Author: John Wiegley <johnw@gnu.org> 5;; Author: John Wiegley <johnw@gnu.org>
6 6
@@ -1017,7 +1017,7 @@ a key."
1017Then send it to the process running in the current buffer." 1017Then send it to the process running in the current buffer."
1018 (interactive "P") ; Defeat snooping via C-x ESC ESC 1018 (interactive "P") ; Defeat snooping via C-x ESC ESC
1019 (let ((str (read-passwd 1019 (let ((str (read-passwd
1020 (format "Password: " 1020 (format "%s Password: "
1021 (process-name (eshell-interactive-process)))))) 1021 (process-name (eshell-interactive-process))))))
1022 (if (stringp str) 1022 (if (stringp str)
1023 (process-send-string (eshell-interactive-process) 1023 (process-send-string (eshell-interactive-process)
diff --git a/lisp/filecache.el b/lisp/filecache.el
index ea8bdaaf232..bd0b0f77781 100644
--- a/lisp/filecache.el
+++ b/lisp/filecache.el
@@ -310,7 +310,7 @@ in each directory, not to the directory list itself."
310 "Add FILE to the file cache." 310 "Add FILE to the file cache."
311 (interactive "fAdd File: ") 311 (interactive "fAdd File: ")
312 (if (not (file-exists-p file)) 312 (if (not (file-exists-p file))
313 (message "File %s does not exist" file) 313 (message "Filecache: file %s does not exist" file)
314 (let* ((file-name (file-name-nondirectory file)) 314 (let* ((file-name (file-name-nondirectory file))
315 (dir-name (file-name-directory file)) 315 (dir-name (file-name-directory file))
316 (the-entry (assoc-string 316 (the-entry (assoc-string
@@ -441,7 +441,8 @@ or the optional REGEXP argument."
441 (setq delete-list (cons (car elt) delete-list)))) 441 (setq delete-list (cons (car elt) delete-list))))
442 file-cache-alist) 442 file-cache-alist)
443 (file-cache-delete-file-list delete-list) 443 (file-cache-delete-file-list delete-list)
444 (message "Deleted %d files from file cache" (length delete-list)))) 444 (message "Filecache: deleted %d files from file cache"
445 (length delete-list))))
445 446
446(defun file-cache-delete-directory (directory) 447(defun file-cache-delete-directory (directory)
447 "Delete DIRECTORY from the file cache." 448 "Delete DIRECTORY from the file cache."
@@ -454,8 +455,8 @@ or the optional REGEXP argument."
454 (setq result (1+ result)))) 455 (setq result (1+ result))))
455 file-cache-alist) 456 file-cache-alist)
456 (if (zerop result) 457 (if (zerop result)
457 (error "No entries containing %s found in cache" directory) 458 (error "Filecache: no entries containing %s found in cache" directory)
458 (message "Deleted %d entries" result)))) 459 (message "Filecache: deleted %d entries" result))))
459 460
460(defun file-cache-do-delete-directory (dir entry) 461(defun file-cache-do-delete-directory (dir entry)
461 (let ((directory-list (cdr entry)) 462 (let ((directory-list (cdr entry))
@@ -488,14 +489,14 @@ or the optional REGEXP argument."
488 (num) 489 (num)
489 ) 490 )
490 (if (not (listp directory-list)) 491 (if (not (listp directory-list))
491 (error "Unknown type in file-cache-alist for key %s" file)) 492 (error "Filecache: unknown type in file-cache-alist for key %s" file))
492 (cond 493 (cond
493 ;; Single element 494 ;; Single element
494 ((eq 1 len) 495 ((eq 1 len)
495 (setq directory (elt directory-list 0))) 496 (setq directory (elt directory-list 0)))
496 ;; No elements 497 ;; No elements
497 ((eq 0 len) 498 ((eq 0 len)
498 (error "No directory found for key %s" file)) 499 (error "Filecache: no directory found for key %s" file))
499 ;; Multiple elements 500 ;; Multiple elements
500 (t 501 (t
501 (let* ((minibuffer-dir (file-name-directory (minibuffer-contents))) 502 (let* ((minibuffer-dir (file-name-directory (minibuffer-contents)))
diff --git a/lisp/files.el b/lisp/files.el
index a2676176b86..3b178af029b 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1619,7 +1619,7 @@ in that case, this function acts as if `enable-local-variables' were t."
1619 ("\\.ltx\\'" . latex-mode) 1619 ("\\.ltx\\'" . latex-mode)
1620 ("\\.dtx\\'" . doctex-mode) 1620 ("\\.dtx\\'" . doctex-mode)
1621 ("\\.el\\'" . emacs-lisp-mode) 1621 ("\\.el\\'" . emacs-lisp-mode)
1622 ("\\.scm\\|\\.stk\\|\\.ss\\|\\.sch\\'" . scheme-mode) 1622 ("\\.\\(scm\\|stk\\|ss\\|sch\\)\\'" . scheme-mode)
1623 ("\\.l\\'" . lisp-mode) 1623 ("\\.l\\'" . lisp-mode)
1624 ("\\.lisp\\'" . lisp-mode) 1624 ("\\.lisp\\'" . lisp-mode)
1625 ("\\.f\\'" . fortran-mode) 1625 ("\\.f\\'" . fortran-mode)
diff --git a/lisp/format.el b/lisp/format.el
index aeadb68d60f..90047e98a6c 100644
--- a/lisp/format.el
+++ b/lisp/format.el
@@ -1,6 +1,6 @@
1;;; format.el --- read and save files in multiple formats 1;;; format.el --- read and save files in multiple formats
2 2
3;; Copyright (c) 1994, 1995, 1997, 1999 Free Software Foundation 3;; Copyright (c) 1994, 1995, 1997, 1999, 2004 Free Software Foundation
4 4
5;; Author: Boris Goldowsky <boris@gnu.org> 5;; Author: Boris Goldowsky <boris@gnu.org>
6 6
@@ -287,7 +287,7 @@ For most purposes, consider using `format-decode-region' instead."
287 (let ((do format) f) 287 (let ((do format) f)
288 (while do 288 (while do
289 (or (setq f (assq (car do) format-alist)) 289 (or (setq f (assq (car do) format-alist))
290 (error "Unknown format" (car do))) 290 (error "Unknown format %s" (car do)))
291 ;; Decode: 291 ;; Decode:
292 (if (nth 3 f) 292 (if (nth 3 f)
293 (setq end (format-decode-run-method (nth 3 f) begin end))) 293 (setq end (format-decode-run-method (nth 3 f) begin end)))
diff --git a/lisp/fringe.el b/lisp/fringe.el
index 16a21752b58..ab7709332f5 100644
--- a/lisp/fringe.el
+++ b/lisp/fringe.el
@@ -35,6 +35,33 @@
35 35
36;;; Code: 36;;; Code:
37 37
38;; Standard fringe bitmaps
39
40(defconst no-fringe-bitmap 0)
41(defconst undef-fringe-bitmap 1)
42(defconst left-truncation-fringe-bitmap 2)
43(defconst right-truncation-fringe-bitmap 3)
44(defconst up-arrow-fringe-bitmap 4)
45(defconst down-arrow-fringe-bitmap 5)
46(defconst continued-line-fringe-bitmap 6)
47(defconst continuation-line-fringe-bitmap 7)
48(defconst overlay-arrow-fringe-bitmap 8)
49(defconst top-left-angle-fringe-bitmap 9)
50(defconst top-right-angle-fringe-bitmap 10)
51(defconst bottom-left-angle-fringe-bitmap 11)
52(defconst bottom-right-angle-fringe-bitmap 12)
53(defconst left-bracket-fringe-bitmap 13)
54(defconst right-bracket-fringe-bitmap 14)
55(defconst filled-box-cursor-fringe-bitmap 15)
56(defconst hollow-box-cursor-fringe-bitmap 16)
57(defconst hollow-square-fringe-bitmap 17)
58(defconst bar-cursor-fringe-bitmap 18)
59(defconst hbar-cursor-fringe-bitmap 19)
60(defconst empty-line-fringe-bitmap 20)
61
62
63;; Control presence of fringes
64
38(defvar fringe-mode) 65(defvar fringe-mode)
39 66
40(defun set-fringe-mode-1 (ignore value) 67(defun set-fringe-mode-1 (ignore value)
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index e48f5823c4b..60679f8250a 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,9 @@
12004-02-08 Andreas Schwab <schwab@suse.de>
2
3 * nnlistserv.el (nnlistserv-kk-wash-article): Fix paren nesting.
4
5 * gnus-score.el (gnus-summary-increase-score): Fix format string.
6
12003-06-25 Sam Steingold <sds@gnu.org> 72003-06-25 Sam Steingold <sds@gnu.org>
2 8
3 * gnus-group.el (gnus-group-suspend): Avoid some consing. 9 * gnus-group.el (gnus-group-suspend): Avoid some consing.
diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el
index 7e716fc028a..0623d1bd8f1 100644
--- a/lisp/gnus/gnus-score.el
+++ b/lisp/gnus/gnus-score.el
@@ -1,5 +1,5 @@
1;;; gnus-score.el --- scoring code for Gnus 1;;; gnus-score.el --- scoring code for Gnus
2;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 2;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2004
3;; Free Software Foundation, Inc. 3;; Free Software Foundation, Inc.
4 4
5;; Author: Per Abrahamsen <amanda@iesd.auc.dk> 5;; Author: Per Abrahamsen <amanda@iesd.auc.dk>
@@ -616,7 +616,7 @@ used as score."
616 (gnus-score-insert-help "Match permanence" char-to-perm 2))) 616 (gnus-score-insert-help "Match permanence" char-to-perm 2)))
617 617
618 (gnus-score-kill-help-buffer) 618 (gnus-score-kill-help-buffer)
619 (if mimic (message "%c %c %c" prefix hchar tchar pchar) 619 (if mimic (message "%c %c %c %c" prefix hchar tchar pchar)
620 (message "")) 620 (message ""))
621 (unless (setq temporary (cadr (assq pchar char-to-perm))) 621 (unless (setq temporary (cadr (assq pchar char-to-perm)))
622 ;; Deal with der(r)ided superannuated paradigms. 622 ;; Deal with der(r)ided superannuated paradigms.
diff --git a/lisp/gnus/nnlistserv.el b/lisp/gnus/nnlistserv.el
index 12978435f7f..b6ce46c82f2 100644
--- a/lisp/gnus/nnlistserv.el
+++ b/lisp/gnus/nnlistserv.el
@@ -1,6 +1,6 @@
1;;; nnlistserv.el --- retrieving articles via web mailing list archives 1;;; nnlistserv.el --- retrieving articles via web mailing list archives
2 2
3;; Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. 3;; Copyright (C) 1997, 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 5;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
6;; Keywords: news, mail 6;; Keywords: news, mail
@@ -127,7 +127,7 @@
127 (nnweb-decode-entities) 127 (nnweb-decode-entities)
128 (while headers 128 (while headers
129 (goto-char (point-min)) 129 (goto-char (point-min))
130 (re-search-forward (format "<!-- %s=\"\\([^\"]+\\)" (car headers) nil t)) 130 (re-search-forward (format "<!-- %s=\"\\([^\"]+\\)" (car headers)) nil t)
131 (set (pop headers) (match-string 1))) 131 (set (pop headers) (match-string 1)))
132 (goto-char (point-min)) 132 (goto-char (point-min))
133 (search-forward "<!-- body" nil t) 133 (search-forward "<!-- body" nil t)
diff --git a/lisp/hexl.el b/lisp/hexl.el
index a4e9792dc6b..413344fc375 100644
--- a/lisp/hexl.el
+++ b/lisp/hexl.el
@@ -1,6 +1,6 @@
1;;; hexl.el --- edit a file in a hex dump format using the hexl filter 1;;; hexl.el --- edit a file in a hex dump format using the hexl filter
2 2
3;; Copyright (C) 1989, 1994, 1998, 2001, 2002, 2003 Free Software Foundation, Inc. 3;; Copyright (C) 1989, 1994, 1998, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Keith Gabryelski <ag@wheaties.ai.mit.edu> 5;; Author: Keith Gabryelski <ag@wheaties.ai.mit.edu>
6;; Maintainer: FSF 6;; Maintainer: FSF
@@ -742,7 +742,7 @@ and their encoded form is inserted byte by byte."
742 742
743CH must be a unibyte character whose value is between 0 and 255." 743CH must be a unibyte character whose value is between 0 and 255."
744 (if (or (< ch 0) (> ch 255)) 744 (if (or (< ch 0) (> ch 255))
745 (error "Invalid character 0x%x -- must be in the range [0..255]")) 745 (error "Invalid character 0x%x -- must be in the range [0..255]" ch))
746 (let ((address (hexl-current-address t))) 746 (let ((address (hexl-current-address t)))
747 (while (> num 0) 747 (while (> num 0)
748 (let ((hex-position 748 (let ((hex-position
diff --git a/lisp/international/ccl.el b/lisp/international/ccl.el
index 4ffea66caeb..e9e46bb0c6c 100644
--- a/lisp/international/ccl.el
+++ b/lisp/international/ccl.el
@@ -774,7 +774,8 @@
774 (ccl-check-register right rrr) 774 (ccl-check-register right rrr)
775 (ccl-embed-code 'write-expr-register 0 775 (ccl-embed-code 'write-expr-register 0
776 (logior (ash op 3) 776 (logior (ash op 3)
777 (get right 'ccl-register-number)))))) 777 (get right 'ccl-register-number))
778 left))))
778 779
779 (t 780 (t
780 (error "CCL: Invalid argument: %s" cmd)))) 781 (error "CCL: Invalid argument: %s" cmd))))
diff --git a/lisp/iswitchb.el b/lisp/iswitchb.el
index 51797da5605..aab768387d0 100644
--- a/lisp/iswitchb.el
+++ b/lisp/iswitchb.el
@@ -377,18 +377,11 @@ See documentation of `walk-windows' for useful values.")
377 "Iswitchb-specific customization of minibuffer setup. 377 "Iswitchb-specific customization of minibuffer setup.
378 378
379This hook is run during minibuffer setup iff `iswitchb' will be active. 379This hook is run during minibuffer setup iff `iswitchb' will be active.
380It is intended for use in customizing iswitchb for interoperation 380For instance:
381with other packages." 381\(add-hook 'iswitchb-minibuffer-setup-hook
382;;; For instance: 382 '\(lambda () (set (make-local-variable 'max-mini-window-height) 3)))
383 383will constrain the minibuffer to a maximum height of 3 lines when
384;;; \(add-hook 'iswitchb-minibuffer-setup-hook 384iswitchb is running."
385;;; \(function
386;;; \(lambda ()
387;;; \(make-local-variable 'resize-minibuffer-window-max-height)
388;;; \(setq resize-minibuffer-window-max-height 3))))
389
390;;; will constrain rsz-mini to a maximum minibuffer height of 3 lines when
391;;; iswitchb is running. Copied from `icomplete-minibuffer-setup-hook'."
392 :type 'hook 385 :type 'hook
393 :group 'iswitchb) 386 :group 'iswitchb)
394 387
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 07ed6e8d463..82f6b1d6641 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -194,6 +194,7 @@
194(when (fboundp 'x-create-frame) 194(when (fboundp 'x-create-frame)
195 (load "mouse") 195 (load "mouse")
196 (load "international/fontset") 196 (load "international/fontset")
197 (load "x-dnd")
197 (load "term/x-win")) 198 (load "term/x-win"))
198 199
199(message "%s" (garbage-collect)) 200(message "%s" (garbage-collect))
diff --git a/lisp/mail/mail-utils.el b/lisp/mail/mail-utils.el
index e60e8358de9..96a57b38f07 100644
--- a/lisp/mail/mail-utils.el
+++ b/lisp/mail/mail-utils.el
@@ -227,9 +227,15 @@ the comma-separated list. The pruned list is returned."
227 "") 227 "")
228 (if (and user-mail-address 228 (if (and user-mail-address
229 (not (equal user-mail-address user-login-name))) 229 (not (equal user-mail-address user-login-name)))
230 (concat (regexp-quote user-mail-address) "\\|") 230 ;; Anchor the login name and email address so
231 ;; that we don't match substrings: if the
232 ;; login name is "foo", we shouldn't match
233 ;; "barfoo@baz.com".
234 (concat "\\`"
235 (regexp-quote user-mail-address)
236 "\\'\\|")
231 "") 237 "")
232 (concat (regexp-quote user-login-name) "\\>")))) 238 (concat "\\`" (regexp-quote user-login-name) "@"))))
233 ;; Split up DESTINATIONS and match each element separately. 239 ;; Split up DESTINATIONS and match each element separately.
234 (let ((start-pos 0) (cur-pos 0) 240 (let ((start-pos 0) (cur-pos 0)
235 (case-fold-search t)) 241 (case-fold-search t))
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index 462919d36d4..512c962c0bc 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -1,6 +1,6 @@
1;;; rmail.el --- main code of "RMAIL" mail reader for Emacs 1;;; rmail.el --- main code of "RMAIL" mail reader for Emacs
2 2
3;; Copyright (C) 1985,86,87,88,93,94,95,96,97,98,2000, 2001 3;; Copyright (C) 1985,86,87,88,93,94,95,96,97,98,2000, 01, 2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Maintainer: FSF 6;; Maintainer: FSF
@@ -139,9 +139,9 @@ plus whatever is specified by `rmail-default-dont-reply-to-names'."
139 :group 'rmail-reply) 139 :group 'rmail-reply)
140 140
141;;;###autoload 141;;;###autoload
142(defvar rmail-default-dont-reply-to-names "info-" "\ 142(defvar rmail-default-dont-reply-to-names "\\`info-" "\
143A regular expression specifying part of the value of the default value of 143A regular expression specifying part of the default value of the
144the variable `rmail-dont-reply-to-names', for when the user does not set 144variable `rmail-dont-reply-to-names', for when the user does not set
145`rmail-dont-reply-to-names' explicitly. (The other part of the default 145`rmail-dont-reply-to-names' explicitly. (The other part of the default
146value is the user's email address and name.) 146value is the user's email address and name.)
147It is useful to set this variable in the site customization file.") 147It is useful to set this variable in the site customization file.")
@@ -1488,13 +1488,11 @@ It returns t if it got any new messages."
1488 ;; print out a message on number of spam messages found: 1488 ;; print out a message on number of spam messages found:
1489 (if (and rmail-use-spam-filter (> rsf-number-of-spam 0)) 1489 (if (and rmail-use-spam-filter (> rsf-number-of-spam 0))
1490 (if (= 1 new-messages) 1490 (if (= 1 new-messages)
1491 (format ", and found to be a spam message" 1491 ", and found to be a spam message"
1492 rsf-number-of-spam)
1493 (if (> rsf-number-of-spam 1) 1492 (if (> rsf-number-of-spam 1)
1494 (format ", %d of which found to be spam messages" 1493 (format ", %d of which found to be spam messages"
1495 rsf-number-of-spam) 1494 rsf-number-of-spam)
1496 (format ", one of which found to be a spam message" 1495 ", one of which found to be a spam message"))
1497 rsf-number-of-spam)))
1498 "")) 1496 ""))
1499 (if (and rmail-use-spam-filter (> rsf-number-of-spam 0)) 1497 (if (and rmail-use-spam-filter (> rsf-number-of-spam 0))
1500 (progn (if rmail-spam-filter-beep (beep t)) 1498 (progn (if rmail-spam-filter-beep (beep t))
diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el
index bd9d5d7dd39..e516133c6a0 100644
--- a/lisp/mail/smtpmail.el
+++ b/lisp/mail/smtpmail.el
@@ -488,9 +488,9 @@ This is relative to `smtpmail-queue-dir'.")
488 (mech (car (smtpmail-intersection smtpmail-auth-supported mechs))) 488 (mech (car (smtpmail-intersection smtpmail-auth-supported mechs)))
489 (cred (if (stringp smtpmail-auth-credentials) 489 (cred (if (stringp smtpmail-auth-credentials)
490 (let* ((netrc (netrc-parse smtpmail-auth-credentials)) 490 (let* ((netrc (netrc-parse smtpmail-auth-credentials))
491 (hostentry (netrc-machine 491 (port-name (format "%s" (or port "smtp")))
492 netrc host (format "%s" (or port "smtp")) 492 (hostentry (netrc-machine netrc host port-name
493 "smtp"))) 493 port-name)))
494 (when hostentry 494 (when hostentry
495 (list host port 495 (list host port
496 (netrc-get hostentry "login") 496 (netrc-get hostentry "login")
@@ -504,7 +504,7 @@ This is relative to `smtpmail-queue-dir'.")
504 (smtpmail-cred-server cred) 504 (smtpmail-cred-server cred)
505 (smtpmail-cred-port cred)))))) 505 (smtpmail-cred-port cred))))))
506 ret) 506 ret)
507 (when cred 507 (when (and cred mech)
508 (cond 508 (cond
509 ((eq mech 'cram-md5) 509 ((eq mech 'cram-md5)
510 (smtpmail-send-command process (format "AUTH %s" mech)) 510 (smtpmail-send-command process (format "AUTH %s" mech))
diff --git a/lisp/midnight.el b/lisp/midnight.el
index 6678925eedb..37bdf065f51 100644
--- a/lisp/midnight.el
+++ b/lisp/midnight.el
@@ -1,6 +1,6 @@
1;;; midnight.el --- run something every midnight, e.g., kill old buffers 1;;; midnight.el --- run something every midnight, e.g., kill old buffers
2 2
3;;; Copyright (C) 1998 Free Software Foundation, Inc. 3;;; Copyright (C) 1998, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Sam Steingold <sds@usa.net> 5;; Author: Sam Steingold <sds@usa.net>
6;; Maintainer: Sam Steingold <sds@usa.net> 6;; Maintainer: Sam Steingold <sds@usa.net>
@@ -215,7 +215,7 @@ the time when it is run.")
215Sets the first argument SYMB (which must be symbol `midnight-delay') 215Sets the first argument SYMB (which must be symbol `midnight-delay')
216to its second argument TM." 216to its second argument TM."
217 (assert (eq symb 'midnight-delay) t 217 (assert (eq symb 'midnight-delay) t
218 "Illegal argument to `midnight-delay-set': `%s'" symb) 218 "Illegal argument to `midnight-delay-set': `%s'")
219 (set symb tm) 219 (set symb tm)
220 (when (timerp midnight-timer) (cancel-timer midnight-timer)) 220 (when (timerp midnight-timer) (cancel-timer midnight-timer))
221 (setq midnight-timer 221 (setq midnight-timer
diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el
index 7c5e869a5d4..3f004b8864e 100644
--- a/lisp/net/webjump.el
+++ b/lisp/net/webjump.el
@@ -1,6 +1,6 @@
1;;; webjump.el --- programmable Web hotlist 1;;; webjump.el --- programmable Web hotlist
2 2
3;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. 3;; Copyright (C) 1996, 1997, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Neil W. Van Dyke <nwv@acm.org> 5;; Author: Neil W. Van Dyke <nwv@acm.org>
6;; Created: 09-Aug-1996 6;; Created: 09-Aug-1996
@@ -300,7 +300,8 @@ Please submit bug reports and other feedback to the author, Neil W. Van Dyke
300 ((eq builtin 'mirrors) 300 ((eq builtin 'mirrors)
301 (if (= (length expr) 1) 301 (if (= (length expr) 1)
302 (error 302 (error
303 "WebJump URL builtin \"mirrors\" for \"%s\" needs at least 1 arg")) 303 "WebJump URL builtin \"mirrors\" for \"%s\" needs at least 1 arg"
304 name))
304 (webjump-choose-mirror name (cdr (append expr nil)))) 305 (webjump-choose-mirror name (cdr (append expr nil))))
305 ((eq builtin 'name) 306 ((eq builtin 'name)
306 name) 307 name)
diff --git a/lisp/newcomment.el b/lisp/newcomment.el
index 7bd4465c9f2..cf5a815fe95 100644
--- a/lisp/newcomment.el
+++ b/lisp/newcomment.el
@@ -129,6 +129,31 @@ the comment's starting delimiter and should return either the desired
129column indentation or nil. 129column indentation or nil.
130If nil is returned, indentation is delegated to `indent-according-to-mode'.") 130If nil is returned, indentation is delegated to `indent-according-to-mode'.")
131 131
132;;;###autoload
133(defvar comment-insert-comment-function nil
134 "Function to insert a comment when a line doesn't contain one.
135The function has no args.
136
137Applicable at least in modes for languages like fixed-format Fortran where
138comments always start in column zero.")
139
140(defvar comment-region-function nil
141 "Function to comment a region.
142Its args are the same as those of `comment-region', but BEG and END are
143guaranteed to be correctly ordered. It is called within `save-excursion'.
144
145Applicable at least in modes for languages like fixed-format Fortran where
146comments always start in column zero.")
147
148(defvar uncomment-region-function nil
149 "Function to uncomment a region.
150Its args are the same as those of `uncomment-region', but BEG and END are
151guaranteed to be correctly ordered. It is called within `save-excursion'.
152
153Applicable at least in modes for languages like fixed-format Fortran where
154comments always start in column zero.")
155
156;; ?? never set
132(defvar block-comment-start nil) 157(defvar block-comment-start nil)
133(defvar block-comment-end nil) 158(defvar block-comment-end nil)
134 159
@@ -460,7 +485,7 @@ Point is assumed to be just at the end of a comment."
460 485
461;;;###autoload 486;;;###autoload
462(defun comment-indent (&optional continue) 487(defun comment-indent (&optional continue)
463 "Indent this line's comment to comment column, or insert an empty comment. 488 "Indent this line's comment to `comment-column', or insert an empty comment.
464If CONTINUE is non-nil, use the `comment-continue' markers if any." 489If CONTINUE is non-nil, use the `comment-continue' markers if any."
465 (interactive "*") 490 (interactive "*")
466 (comment-normalize-vars) 491 (comment-normalize-vars)
@@ -486,9 +511,12 @@ If CONTINUE is non-nil, use the `comment-continue' markers if any."
486 (forward-char (/ (skip-chars-backward " \t") -2))) 511 (forward-char (/ (skip-chars-backward " \t") -2)))
487 (setq cpos (point-marker))) 512 (setq cpos (point-marker)))
488 ;; If none, insert one. 513 ;; If none, insert one.
514 (if comment-insert-comment-function
515 (funcall comment-insert-comment-function)
489 (save-excursion 516 (save-excursion
490 ;; Some comment-indent-function insist on not moving comments that 517 ;; Some `comment-indent-function's insist on not moving
491 ;; are in column 0, so we first go to the likely target column. 518 ;; comments that are in column 0, so we first go to the
519 ;; likely target column.
492 (indent-to comment-column) 520 (indent-to comment-column)
493 ;; Ensure there's a space before the comment for things 521 ;; Ensure there's a space before the comment for things
494 ;; like sh where it matters (as well as being neater). 522 ;; like sh where it matters (as well as being neater).
@@ -497,7 +525,7 @@ If CONTINUE is non-nil, use the `comment-continue' markers if any."
497 (setq begpos (point)) 525 (setq begpos (point))
498 (insert starter) 526 (insert starter)
499 (setq cpos (point-marker)) 527 (setq cpos (point-marker))
500 (insert ender))) 528 (insert ender))))
501 (goto-char begpos) 529 (goto-char begpos)
502 ;; Compute desired indent. 530 ;; Compute desired indent.
503 (setq indent (save-excursion (funcall comment-indent-function))) 531 (setq indent (save-excursion (funcall comment-indent-function)))
@@ -672,30 +700,32 @@ comment markers."
672 (comment-normalize-vars) 700 (comment-normalize-vars)
673 (if (> beg end) (let (mid) (setq mid beg beg end end mid))) 701 (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
674 (save-excursion 702 (save-excursion
675 (goto-char beg) 703 (if uncomment-region-function
676 (setq end (copy-marker end)) 704 (funcall uncomment-region-function beg end arg)
677 (let* ((numarg (prefix-numeric-value arg)) 705 (goto-char beg)
678 (ccs comment-continue) 706 (setq end (copy-marker end))
679 (srei (comment-padright ccs 're)) 707 (let* ((numarg (prefix-numeric-value arg))
680 (csre (comment-padright comment-start 're)) 708 (ccs comment-continue)
681 (sre (and srei (concat "^\\s-*?\\(" srei "\\)"))) 709 (srei (comment-padright ccs 're))
682 spt) 710 (csre (comment-padright comment-start 're))
683 (while (and (< (point) end) 711 (sre (and srei (concat "^\\s-*?\\(" srei "\\)")))
684 (setq spt (comment-search-forward end t))) 712 spt)
685 (let ((ipt (point)) 713 (while (and (< (point) end)
686 ;; Find the end of the comment. 714 (setq spt (comment-search-forward end t)))
687 (ept (progn 715 (let ((ipt (point))
688 (goto-char spt) 716 ;; Find the end of the comment.
689 (unless (comment-forward) 717 (ept (progn
690 (error "Can't find the comment end")) 718 (goto-char spt)
691 (point))) 719 (unless (comment-forward)
692 (box nil) 720 (error "Can't find the comment end"))
693 (box-equal nil)) ;Whether we might be using `=' for boxes. 721 (point)))
694 (save-restriction 722 (box nil)
695 (narrow-to-region spt ept) 723 (box-equal nil)) ;Whether we might be using `=' for boxes.
696 724 (save-restriction
697 ;; Remove the comment-start. 725 (narrow-to-region spt ept)
698 (goto-char ipt) 726
727 ;; Remove the comment-start.
728 (goto-char ipt)
699 (skip-syntax-backward " ") 729 (skip-syntax-backward " ")
700 ;; A box-comment starts with a looong comment-start marker. 730 ;; A box-comment starts with a looong comment-start marker.
701 (when (and (or (and (= (- (point) (point-min)) 1) 731 (when (and (or (and (= (- (point) (point-min)) 1)
@@ -715,52 +745,52 @@ comment markers."
715 (goto-char (match-end 0))) 745 (goto-char (match-end 0)))
716 (if (null arg) (delete-region (point-min) (point)) 746 (if (null arg) (delete-region (point-min) (point))
717 (skip-syntax-backward " ") 747 (skip-syntax-backward " ")
718 (delete-char (- numarg)) 748 (delete-char (- numarg))
719 (unless (or (bobp) 749 (unless (or (bobp)
720 (save-excursion (goto-char (point-min)) 750 (save-excursion (goto-char (point-min))
721 (looking-at comment-start-skip))) 751 (looking-at comment-start-skip)))
722 ;; If there's something left but it doesn't look like 752 ;; If there's something left but it doesn't look like
723 ;; a comment-start any more, just remove it. 753 ;; a comment-start any more, just remove it.
724 (delete-region (point-min) (point)))) 754 (delete-region (point-min) (point))))
725 755
726 ;; Remove the end-comment (and leading padding and such). 756 ;; Remove the end-comment (and leading padding and such).
727 (goto-char (point-max)) (comment-enter-backward) 757 (goto-char (point-max)) (comment-enter-backward)
728 ;; Check for special `=' used sometimes in comment-box. 758 ;; Check for special `=' used sometimes in comment-box.
729 (when (and box-equal (not (eq (char-before (point-max)) ?\n))) 759 (when (and box-equal (not (eq (char-before (point-max)) ?\n)))
730 (let ((pos (point))) 760 (let ((pos (point)))
731 ;; skip `=' but only if there are at least 7. 761 ;; skip `=' but only if there are at least 7.
732 (when (> (skip-chars-backward "=") -7) (goto-char pos)))) 762 (when (> (skip-chars-backward "=") -7) (goto-char pos))))
733 (unless (looking-at "\\(\n\\|\\s-\\)*\\'") 763 (unless (looking-at "\\(\n\\|\\s-\\)*\\'")
734 (when (and (bolp) (not (bobp))) (backward-char)) 764 (when (and (bolp) (not (bobp))) (backward-char))
735 (if (null arg) (delete-region (point) (point-max)) 765 (if (null arg) (delete-region (point) (point-max))
736 (skip-syntax-forward " ") 766 (skip-syntax-forward " ")
737 (delete-char numarg) 767 (delete-char numarg)
738 (unless (or (eobp) (looking-at comment-end-skip)) 768 (unless (or (eobp) (looking-at comment-end-skip))
739 ;; If there's something left but it doesn't look like 769 ;; If there's something left but it doesn't look like
740 ;; a comment-end any more, just remove it. 770 ;; a comment-end any more, just remove it.
741 (delete-region (point) (point-max))))) 771 (delete-region (point) (point-max)))))
742 772
743 ;; Unquote any nested end-comment. 773 ;; Unquote any nested end-comment.
744 (comment-quote-nested comment-start comment-end t) 774 (comment-quote-nested comment-start comment-end t)
745 775
746 ;; Eliminate continuation markers as well. 776 ;; Eliminate continuation markers as well.
747 (when sre 777 (when sre
748 (let* ((cce (comment-string-reverse (or comment-continue 778 (let* ((cce (comment-string-reverse (or comment-continue
749 comment-start))) 779 comment-start)))
750 (erei (and box (comment-padleft cce 're))) 780 (erei (and box (comment-padleft cce 're)))
751 (ere (and erei (concat "\\(" erei "\\)\\s-*$")))) 781 (ere (and erei (concat "\\(" erei "\\)\\s-*$"))))
752 (goto-char (point-min)) 782 (goto-char (point-min))
753 (while (progn 783 (while (progn
754 (if (and ere (re-search-forward 784 (if (and ere (re-search-forward
755 ere (line-end-position) t)) 785 ere (line-end-position) t))
756 (replace-match "" t t nil (if (match-end 2) 2 1)) 786 (replace-match "" t t nil (if (match-end 2) 2 1))
757 (setq ere nil)) 787 (setq ere nil))
758 (forward-line 1) 788 (forward-line 1)
759 (re-search-forward sre (line-end-position) t)) 789 (re-search-forward sre (line-end-position) t))
760 (replace-match "" t t nil (if (match-end 2) 2 1))))) 790 (replace-match "" t t nil (if (match-end 2) 2 1)))))
761 ;; Go to the end for the next comment. 791 ;; Go to the end for the next comment.
762 (goto-char (point-max))))) 792 (goto-char (point-max)))))))
763 (set-marker end nil)))) 793 (set-marker end nil)))
764 794
765(defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block) 795(defun comment-make-extra-lines (cs ce ccs cce min-indent max-indent &optional block)
766 "Make the leading and trailing extra lines. 796 "Make the leading and trailing extra lines.
@@ -930,49 +960,52 @@ The strings used as comment starts are built from
930 (block (nth 1 style)) 960 (block (nth 1 style))
931 (multi (nth 0 style))) 961 (multi (nth 0 style)))
932 (save-excursion 962 (save-excursion
933 ;; we use `chars' instead of `syntax' because `\n' might be 963 (if comment-region-function
934 ;; of end-comment syntax rather than of whitespace syntax. 964 (funcall comment-region-function beg end arg)
935 ;; sanitize BEG and END 965 ;; we use `chars' instead of `syntax' because `\n' might be
936 (goto-char beg) (skip-chars-forward " \t\n\r") (beginning-of-line) 966 ;; of end-comment syntax rather than of whitespace syntax.
937 (setq beg (max beg (point))) 967 ;; sanitize BEG and END
938 (goto-char end) (skip-chars-backward " \t\n\r") (end-of-line) 968 (goto-char beg) (skip-chars-forward " \t\n\r") (beginning-of-line)
939 (setq end (min end (point))) 969 (setq beg (max beg (point)))
940 (if (>= beg end) (error "Nothing to comment")) 970 (goto-char end) (skip-chars-backward " \t\n\r") (end-of-line)
941 971 (setq end (min end (point)))
942 ;; sanitize LINES 972 (if (>= beg end) (error "Nothing to comment"))
943 (setq lines 973
944 (and 974 ;; sanitize LINES
945 lines ;; multi 975 (setq lines
946 (progn (goto-char beg) (beginning-of-line) 976 (and
947 (skip-syntax-forward " ") 977 lines ;; multi
948 (>= (point) beg)) 978 (progn (goto-char beg) (beginning-of-line)
949 (progn (goto-char end) (end-of-line) (skip-syntax-backward " ") 979 (skip-syntax-forward " ")
950 (<= (point) end)) 980 (>= (point) beg))
951 (or block (not (string= "" comment-end))) 981 (progn (goto-char end) (end-of-line) (skip-syntax-backward " ")
952 (or block (progn (goto-char beg) (search-forward "\n" end t)))))) 982 (<= (point) end))
953 983 (or block (not (string= "" comment-end)))
954 ;; don't add end-markers just because the user asked for `block' 984 (or block (progn (goto-char beg) (search-forward "\n" end t))))))
955 (unless (or lines (string= "" comment-end)) (setq block nil)) 985
956 986 ;; don't add end-markers just because the user asked for `block'
957 (cond 987 (unless (or lines (string= "" comment-end)) (setq block nil))
958 ((consp arg) (uncomment-region beg end)) 988
959 ((< numarg 0) (uncomment-region beg end (- numarg))) 989 (cond
960 (t 990 ((consp arg) (uncomment-region beg end))
961 (setq numarg (if (and (null arg) (= (length comment-start) 1)) 991 ((< numarg 0) (uncomment-region beg end (- numarg)))
962 add (1- numarg))) 992 (t
963 (comment-region-internal 993 (setq numarg (if (and (null arg) (= (length comment-start) 1))
964 beg end 994 add (1- numarg)))
965 (let ((s (comment-padright comment-start numarg))) 995 (comment-region-internal
966 (if (string-match comment-start-skip s) s 996 beg end
967 (comment-padright comment-start))) 997 (let ((s (comment-padright comment-start numarg)))
968 (let ((s (comment-padleft comment-end numarg))) 998 (if (string-match comment-start-skip s) s
969 (and s (if (string-match comment-end-skip s) s 999 (comment-padright comment-start)))
970 (comment-padright comment-end)))) 1000 (let ((s (comment-padleft comment-end numarg)))
971 (if multi (comment-padright comment-continue numarg)) 1001 (and s (if (string-match comment-end-skip s) s
972 (if multi (comment-padleft (comment-string-reverse comment-continue) numarg)) 1002 (comment-padright comment-end))))
973 block 1003 (if multi (comment-padright comment-continue numarg))
974 lines 1004 (if multi
975 (nth 3 style)))))) 1005 (comment-padleft (comment-string-reverse comment-continue) numarg))
1006 block
1007 lines
1008 (nth 3 style)))))))
976 1009
977(defun comment-box (beg end &optional arg) 1010(defun comment-box (beg end &optional arg)
978 "Comment out the BEG .. END region, putting it inside a box. 1011 "Comment out the BEG .. END region, putting it inside a box.
diff --git a/lisp/pcvs-defs.el b/lisp/pcvs-defs.el
index 3f4b1a04b6c..dadb194abb9 100644
--- a/lisp/pcvs-defs.el
+++ b/lisp/pcvs-defs.el
@@ -1,6 +1,6 @@
1;;; pcvs-defs.el --- variable definitions for PCL-CVS 1;;; pcvs-defs.el --- variable definitions for PCL-CVS
2 2
3;; Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2003 3;; Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 03, 2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: Stefan Monnier <monnier@cs.yale.edu> 6;; Author: Stefan Monnier <monnier@cs.yale.edu>
@@ -413,6 +413,7 @@ This variable is buffer local and only used in the *cvs* buffer.")
413 ["Update" cvs-mode-update (cvs-enabledp 'update)] 413 ["Update" cvs-mode-update (cvs-enabledp 'update)]
414 ["Re-examine" cvs-mode-examine t] 414 ["Re-examine" cvs-mode-examine t]
415 ["Commit" cvs-mode-commit-setup (cvs-enabledp 'commit)] 415 ["Commit" cvs-mode-commit-setup (cvs-enabledp 'commit)]
416 ["Tag" cvs-mode-tag (cvs-enabledp (when cvs-force-dir-tag 'tag))]
416 ["Undo changes" cvs-mode-undo (cvs-enabledp 'undo)] 417 ["Undo changes" cvs-mode-undo (cvs-enabledp 'undo)]
417 ["Add" cvs-mode-add (cvs-enabledp 'add)] 418 ["Add" cvs-mode-add (cvs-enabledp 'add)]
418 ["Remove" cvs-mode-remove (cvs-enabledp 'remove)] 419 ["Remove" cvs-mode-remove (cvs-enabledp 'remove)]
diff --git a/lisp/play/zone.el b/lisp/play/zone.el
index ca46c0a1562..abe9657a9d8 100644
--- a/lisp/play/zone.el
+++ b/lisp/play/zone.el
@@ -1,6 +1,6 @@
1;;; zone.el --- idle display hacks 1;;; zone.el --- idle display hacks
2 2
3;; Copyright (C) 2000, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Victor Zandy <zandy@cs.wisc.edu> 5;; Author: Victor Zandy <zandy@cs.wisc.edu>
6;; Maintainer: Thien-Thi Nguyen <ttn@gnu.org> 6;; Maintainer: Thien-Thi Nguyen <ttn@gnu.org>
@@ -125,7 +125,7 @@ If the element is a function or a list of a function and a number,
125 (functionp (car elem)) 125 (functionp (car elem))
126 (numberp (cadr elem))) 126 (numberp (cadr elem)))
127 (apply 'zone-call elem)) 127 (apply 'zone-call elem))
128 (t (error "bad `zone-call' elem:" elem)))) 128 (t (error "bad `zone-call' elem: %S" elem))))
129 program)))) 129 program))))
130 130
131;;;###autoload 131;;;###autoload
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index de050411411..5f9ffbf2c33 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -386,6 +386,9 @@ If any FILE-FORMAT is given, each is a format string to produce a file name to
386try; %s in the string is replaced by the text matching the FILE-IDX'th 386try; %s in the string is replaced by the text matching the FILE-IDX'th
387subexpression.") 387subexpression.")
388 388
389(defvar compilation-directory nil
390 "Directory to restore to when doing `recompile'.")
391
389(defvar compilation-enter-directory-regexp-alist 392(defvar compilation-enter-directory-regexp-alist
390 '( 393 '(
391 ;; Matches lines printed by the `-w' option of GNU Make. 394 ;; Matches lines printed by the `-w' option of GNU Make.
@@ -578,6 +581,7 @@ to a function that generates a unique name."
578 (unless (equal command (eval compile-command)) 581 (unless (equal command (eval compile-command))
579 (setq compile-command command)) 582 (setq compile-command command))
580 (save-some-buffers (not compilation-ask-about-save) nil) 583 (save-some-buffers (not compilation-ask-about-save) nil)
584 (setq compilation-directory default-directory)
581 (compile-internal command "No more errors")) 585 (compile-internal command "No more errors"))
582 586
583;; run compile with the default command line 587;; run compile with the default command line
@@ -587,8 +591,10 @@ If this is run in a compilation-mode buffer, re-use the arguments from the
587original use. Otherwise, it recompiles using `compile-command'." 591original use. Otherwise, it recompiles using `compile-command'."
588 (interactive) 592 (interactive)
589 (save-some-buffers (not compilation-ask-about-save) nil) 593 (save-some-buffers (not compilation-ask-about-save) nil)
590 (apply 'compile-internal (or compilation-arguments 594 (let ((default-directory (or compilation-directory default-directory)))
591 `(,(eval compile-command) "No more errors")))) 595 (apply 'compile-internal (or compilation-arguments
596 `(,(eval compile-command)
597 "No more errors")))))
592 598
593(defcustom compilation-scroll-output nil 599(defcustom compilation-scroll-output nil
594 "*Non-nil to scroll the *compilation* buffer window as output appears. 600 "*Non-nil to scroll the *compilation* buffer window as output appears.
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 7202a083d79..155648fadb1 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -4313,11 +4313,12 @@ indentation and initial hashes. Behaves usually outside of comment."
4313 (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]"))) 4313 (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")))
4314 (point))) 4314 (point)))
4315 ;; Remove existing hashes 4315 ;; Remove existing hashes
4316 (goto-char (point-min)) 4316 (save-excursion
4317 (while (progn (forward-line 1) (< (point) (point-max))) 4317 (goto-char (point-min))
4318 (skip-chars-forward " \t") 4318 (while (progn (forward-line 1) (< (point) (point-max)))
4319 (and (looking-at "#+") 4319 (skip-chars-forward " \t")
4320 (delete-char (- (match-end 0) (match-beginning 0))))) 4320 (and (looking-at "#+")
4321 (delete-char (- (match-end 0) (match-beginning 0))))))
4321 4322
4322 ;; Lines with only hashes on them can be paragraph boundaries. 4323 ;; Lines with only hashes on them can be paragraph boundaries.
4323 (let ((paragraph-start (concat paragraph-start "\\|^[ \t#]*$")) 4324 (let ((paragraph-start (concat paragraph-start "\\|^[ \t#]*$"))
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index 279d7211cdd..c85a3db492d 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -1,6 +1,6 @@
1;;; grep.el --- run compiler as inferior of Emacs, parse error messages 1;;; grep.el --- run compiler as inferior of Emacs, parse error messages
2 2
3;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 1999, 2001, 2002 3;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 1999, 2001, 02, 2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: Roland McGrath <roland@gnu.org> 6;; Author: Roland McGrath <roland@gnu.org>
@@ -216,7 +216,7 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
216;; Note: the character class after the optional drive letter does not 216;; Note: the character class after the optional drive letter does not
217;; include a space to support file names with blanks. 217;; include a space to support file names with blanks.
218(defvar grep-regexp-alist 218(defvar grep-regexp-alist
219 '(("\\([a-zA-Z]?:?[^:(\t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 2)) 219 '(("\\([a-zA-Z]?:?.+?\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 2))
220 "Regexp used to match grep hits. See `compilation-error-regexp-alist'.") 220 "Regexp used to match grep hits. See `compilation-error-regexp-alist'.")
221 221
222(defvar grep-program 222(defvar grep-program
@@ -318,9 +318,9 @@ 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 ((not (executable-command-find-unix-p "find")) 321 (cond ((not (executable-command-find-posix-p "find"))
322 (message 322 (message
323 (concat "compile.el: Unix type find(1) not found. " 323 (concat "compile.el: Posix-style find(1) not found. "
324 "Please set `grep-find-command'.")) 324 "Please set `grep-find-command'."))
325 nil) 325 nil)
326 ((eq grep-find-use-xargs 'gnu) 326 ((eq grep-find-use-xargs 'gnu)
@@ -542,6 +542,5 @@ those sub directories of DIR."
542 542
543(provide 'grep) 543(provide 'grep)
544 544
545;;; grep.el ends here
546
547;;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d 545;;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d
546;;; grep.el ends here
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index f63998270dc..de68d012470 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -1967,14 +1967,14 @@ nil)
1967 ;; FIXME: Java ID's are UNICODE strings, this matches ASCII 1967 ;; FIXME: Java ID's are UNICODE strings, this matches ASCII
1968 ;; ID's only. 1968 ;; ID's only.
1969 ;; 1969 ;;
1970 ;; The "," in the last square-bracket is necessary because of 1970 ;; The ".," in the last square-bracket are necessary because
1971 ;; Sun's total disrespect for backwards compatibility in 1971 ;; of Sun's total disrespect for backwards compatibility in
1972 ;; reported line numbers from jdb - starting in 1.4.0 they 1972 ;; reported line numbers from jdb - starting in 1.4.0 they
1973 ;; introduced a comma at the thousands position (how 1973 ;; print line numbers using LOCALE, inserting a comma or a
1974 ;; ingenious!) 1974 ;; period at the thousands positions (how ingenious!).
1975 1975
1976 "\\(\[[0-9]+\] \\)*\\([a-zA-Z0-9.$_]+\\)\\.[a-zA-Z0-9$_<>(),]+ \ 1976 "\\(\[[0-9]+\] \\)*\\([a-zA-Z0-9.$_]+\\)\\.[a-zA-Z0-9$_<>(),]+ \
1977\\(([a-zA-Z0-9.$_]+:\\|line=\\)\\([0-9,]+\\)" 1977\\(([a-zA-Z0-9.$_]+:\\|line=\\)\\([0-9.,]+\\)"
1978 gud-marker-acc) 1978 gud-marker-acc)
1979 1979
1980 ;; A good marker is one that: 1980 ;; A good marker is one that:
@@ -2001,7 +2001,7 @@ nil)
2001 (string-to-int 2001 (string-to-int
2002 (let 2002 (let
2003 ((numstr (match-string 4 gud-marker-acc))) 2003 ((numstr (match-string 4 gud-marker-acc)))
2004 (if (string-match "," numstr) 2004 (if (string-match "[.,]" numstr)
2005 (replace-match "" nil nil numstr) 2005 (replace-match "" nil nil numstr)
2006 numstr))))) 2006 numstr)))))
2007 (message "Could not find source file."))) 2007 (message "Could not find source file.")))
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 48ed5a9512f..c5a169d2fa1 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -1,6 +1,6 @@
1;;; prolog.el --- major mode for editing and running Prolog under Emacs 1;;; prolog.el --- major mode for editing and running Prolog under Emacs
2 2
3;; Copyright (C) 1986, 1987 Free Software Foundation, Inc. 3;; Copyright (C) 1986, 1987, 2003, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Masanobu UMEDA <umerin@mse.kyutech.ac.jp> 5;; Author: Masanobu UMEDA <umerin@mse.kyutech.ac.jp>
6;; Keywords: languages 6;; Keywords: languages
@@ -30,16 +30,17 @@
30 30
31;;; Code: 31;;; Code:
32 32
33(defvar prolog-mode-syntax-table nil)
34(defvar prolog-mode-abbrev-table nil)
35(defvar prolog-mode-map nil)
36
37(defgroup prolog nil 33(defgroup prolog nil
38 "Major mode for editing and running Prolog under Emacs" 34 "Major mode for editing and running Prolog under Emacs"
39 :group 'languages) 35 :group 'languages)
40 36
41 37
42(defcustom prolog-program-name "prolog" 38(defcustom prolog-program-name
39 (let ((names '("prolog" "gprolog")))
40 (while (and names
41 (not (executable-find (car names))))
42 (setq names (cdr names)))
43 (or (car names) "prolog"))
43 "*Program name for invoking an inferior Prolog with `run-prolog'." 44 "*Program name for invoking an inferior Prolog with `run-prolog'."
44 :type 'string 45 :type 'string
45 :group 'prolog) 46 :group 'prolog)
@@ -75,8 +76,7 @@ nil means send actual operating system end of file."
75 (3 font-lock-variable-name-face))) 76 (3 font-lock-variable-name-face)))
76 "Font-lock keywords for Prolog mode.") 77 "Font-lock keywords for Prolog mode.")
77 78
78(if prolog-mode-syntax-table 79(defvar prolog-mode-syntax-table
79 ()
80 (let ((table (make-syntax-table))) 80 (let ((table (make-syntax-table)))
81 (modify-syntax-entry ?_ "w" table) 81 (modify-syntax-entry ?_ "w" table)
82 (modify-syntax-entry ?\\ "\\" table) 82 (modify-syntax-entry ?\\ "\\" table)
@@ -90,17 +90,14 @@ nil means send actual operating system end of file."
90 (modify-syntax-entry ?< "." table) 90 (modify-syntax-entry ?< "." table)
91 (modify-syntax-entry ?> "." table) 91 (modify-syntax-entry ?> "." table)
92 (modify-syntax-entry ?\' "\"" table) 92 (modify-syntax-entry ?\' "\"" table)
93 (setq prolog-mode-syntax-table table))) 93 table))
94 94
95(defvar prolog-mode-abbrev-table nil)
95(define-abbrev-table 'prolog-mode-abbrev-table ()) 96(define-abbrev-table 'prolog-mode-abbrev-table ())
96 97
97(defun prolog-mode-variables () 98(defun prolog-mode-variables ()
98 (set-syntax-table prolog-mode-syntax-table)
99 (setq local-abbrev-table prolog-mode-abbrev-table)
100 (make-local-variable 'paragraph-start)
101 (setq paragraph-start (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
102 (make-local-variable 'paragraph-separate) 99 (make-local-variable 'paragraph-separate)
103 (setq paragraph-separate paragraph-start) 100 (setq paragraph-separate (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
104 (make-local-variable 'paragraph-ignore-fill-prefix) 101 (make-local-variable 'paragraph-ignore-fill-prefix)
105 (setq paragraph-ignore-fill-prefix t) 102 (setq paragraph-ignore-fill-prefix t)
106 (make-local-variable 'imenu-generic-expression) 103 (make-local-variable 'imenu-generic-expression)
@@ -110,20 +107,16 @@ nil means send actual operating system end of file."
110 (make-local-variable 'comment-start) 107 (make-local-variable 'comment-start)
111 (setq comment-start "%") 108 (setq comment-start "%")
112 (make-local-variable 'comment-start-skip) 109 (make-local-variable 'comment-start-skip)
113 (setq comment-start-skip "%+ *") 110 (setq comment-start-skip "\\(?:%+\\|/\\*+\\)[ \t]*")
111 (make-local-variable 'comment-end-skip)
112 (setq comment-end-skip "[ \t]*\\(\n\\|\\*+/\\)")
114 (make-local-variable 'comment-column) 113 (make-local-variable 'comment-column)
115 (setq comment-column 48) 114 (setq comment-column 48))
116 (make-local-variable 'comment-indent-function)
117 (setq comment-indent-function 'prolog-comment-indent))
118
119(defun prolog-mode-commands (map)
120 (define-key map "\t" 'prolog-indent-line)
121 (define-key map "\e\C-x" 'prolog-consult-region))
122 115
123(if prolog-mode-map 116(defvar prolog-mode-map
124 nil 117 (let ((map (make-sparse-keymap)))
125 (setq prolog-mode-map (make-sparse-keymap)) 118 (define-key map "\e\C-x" 'prolog-consult-region)
126 (prolog-mode-commands prolog-mode-map)) 119 map))
127 120
128;;;###autoload 121;;;###autoload
129(defun prolog-mode () 122(defun prolog-mode ()
@@ -136,6 +129,7 @@ if that value is non-nil."
136 (interactive) 129 (interactive)
137 (kill-all-local-variables) 130 (kill-all-local-variables)
138 (use-local-map prolog-mode-map) 131 (use-local-map prolog-mode-map)
132 (set-syntax-table prolog-mode-syntax-table)
139 (setq major-mode 'prolog-mode) 133 (setq major-mode 'prolog-mode)
140 (setq mode-name "Prolog") 134 (setq mode-name "Prolog")
141 (prolog-mode-variables) 135 (prolog-mode-variables)
@@ -143,7 +137,7 @@ if that value is non-nil."
143 (setq font-lock-defaults '(prolog-font-lock-keywords 137 (setq font-lock-defaults '(prolog-font-lock-keywords
144 nil nil nil 138 nil nil nil
145 beginning-of-line)) 139 beginning-of-line))
146 (run-hooks 'prolog-mode-hook)) 140 (run-mode-hooks 'prolog-mode-hook))
147 141
148(defun prolog-indent-line (&optional whole-exp) 142(defun prolog-indent-line (&optional whole-exp)
149 "Indent current line as Prolog code. 143 "Indent current line as Prolog code.
@@ -217,26 +211,20 @@ rigidly along with this one (not yet)."
217 (if (re-search-forward comment-start-skip eolpos 'move) 211 (if (re-search-forward comment-start-skip eolpos 'move)
218 (goto-char (match-beginning 0))) 212 (goto-char (match-beginning 0)))
219 (skip-chars-backward " \t"))) 213 (skip-chars-backward " \t")))
220
221(defun prolog-comment-indent ()
222 "Compute prolog comment indentation."
223 (cond ((looking-at "%%%") 0)
224 ((looking-at "%%") (prolog-indent-level))
225 (t
226 (save-excursion
227 (skip-chars-backward " \t")
228 ;; Insert one space at least, except at left margin.
229 (max (+ (current-column) (if (bolp) 0 1))
230 comment-column)))
231 ))
232
233 214
234;;; 215;;;
235;;; Inferior prolog mode 216;;; Inferior prolog mode
236;;; 217;;;
237(defvar inferior-prolog-mode-map nil) 218(defvar inferior-prolog-mode-map
219 (let ((map (make-sparse-keymap)))
220 ;; This map will inherit from `comint-mode-map' when entering
221 ;; inferior-prolog-mode.
222 map))
223
224(defvar inferior-prolog-mode-syntax-table prolog-mode-syntax-table)
225(defvar inferior-prolog-mode-abbrev-table prolog-mode-abbrev-table)
238 226
239(defun inferior-prolog-mode () 227(define-derived-mode inferior-prolog-mode comint-mode "Inferior Prolog"
240 "Major mode for interacting with an inferior Prolog process. 228 "Major mode for interacting with an inferior Prolog process.
241 229
242The following commands are available: 230The following commands are available:
@@ -260,25 +248,15 @@ Return not at end copies rest of line to end and sends it.
260\\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing. 248\\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
261\\[comint-interrupt-subjob] interrupts the shell or its current subjob if any. 249\\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
262\\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal." 250\\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal."
263 (interactive) 251 (setq comint-prompt-regexp "^| [ ?][- ] *")
264 (require 'comint) 252 (prolog-mode-variables))
265 (comint-mode)
266 (setq major-mode 'inferior-prolog-mode
267 mode-name "Inferior Prolog"
268 comint-prompt-regexp "^| [ ?][- ] *")
269 (prolog-mode-variables)
270 (if inferior-prolog-mode-map nil
271 (setq inferior-prolog-mode-map (copy-keymap comint-mode-map))
272 (prolog-mode-commands inferior-prolog-mode-map))
273 (use-local-map inferior-prolog-mode-map)
274 (run-hooks 'prolog-mode-hook))
275 253
276;;;###autoload 254;;;###autoload
277(defun run-prolog () 255(defun run-prolog ()
278 "Run an inferior Prolog process, input and output via buffer *prolog*." 256 "Run an inferior Prolog process, input and output via buffer *prolog*."
279 (interactive) 257 (interactive)
280 (require 'comint) 258 (require 'comint)
281 (switch-to-buffer (make-comint "prolog" prolog-program-name)) 259 (pop-to-buffer (make-comint "prolog" prolog-program-name))
282 (inferior-prolog-mode)) 260 (inferior-prolog-mode))
283 261
284(defun prolog-consult-region (compile beg end) 262(defun prolog-consult-region (compile beg end)
diff --git a/lisp/progmodes/xscheme.el b/lisp/progmodes/xscheme.el
index 555445eda6b..609c7db1e2a 100644
--- a/lisp/progmodes/xscheme.el
+++ b/lisp/progmodes/xscheme.el
@@ -1,6 +1,6 @@
1;;; xscheme.el --- run MIT Scheme under Emacs 1;;; xscheme.el --- run MIT Scheme under Emacs
2 2
3;; Copyright (C) 1986, 1987, 1989, 1990, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 1986, 1987, 1989, 1990, 2001, 2004 Free Software Foundation, Inc.
4 4
5;; Maintainer: FSF 5;; Maintainer: FSF
6;; Keywords: languages, lisp 6;; Keywords: languages, lisp
@@ -222,14 +222,14 @@ With argument, asks for a command line."
222 (let* ((buffer (get-buffer buffer-name)) 222 (let* ((buffer (get-buffer buffer-name))
223 (process (and buffer (get-buffer-process buffer)))) 223 (process (and buffer (get-buffer-process buffer))))
224 (cond ((not buffer) 224 (cond ((not buffer)
225 (error "Buffer does not exist" buffer-name)) 225 (error "Buffer `%s' does not exist" buffer-name))
226 ((not process) 226 ((not process)
227 (error "Buffer is not a scheme interaction buffer" buffer-name)) 227 (error "Buffer `%s' is not a scheme interaction buffer" buffer-name))
228 (t 228 (t
229 (save-excursion 229 (save-excursion
230 (set-buffer buffer) 230 (set-buffer buffer)
231 (if (not (xscheme-process-buffer-current-p)) 231 (if (not (xscheme-process-buffer-current-p))
232 (error "Buffer is not a scheme interaction buffer" 232 (error "Buffer `%s' is not a scheme interaction buffer"
233 buffer-name))) 233 buffer-name)))
234 (process-name process))))) 234 (process-name process)))))
235 235
diff --git a/lisp/ses.el b/lisp/ses.el
index a56b1b5c87a..314ca603861 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -1,4 +1,4 @@
1;;;; ses.el -- Simple Emacs Spreadsheet 1;;; ses.el -- Simple Emacs Spreadsheet
2 2
3;; Copyright (C) 2002,03,04 Free Software Foundation, Inc. 3;; Copyright (C) 2002,03,04 Free Software Foundation, Inc.
4 4
@@ -24,11 +24,12 @@
24;; Boston, MA 02111-1307, USA. 24;; Boston, MA 02111-1307, USA.
25 25
26;;; To-do list: 26;;; To-do list:
27;; * Use $ or … for truncated fields
28;; * Add command to make a range of columns be temporarily invisible.
29;; * Allow paste of one cell to a range of cells -- copy formula to each.
27;; * Do something about control characters & octal codes in cell print 30;; * Do something about control characters & octal codes in cell print
28;; areas. Currently they distort the columnar appearance, but fixing them 31;; areas. Use string-width?
29;; seems like too much work? Use text-char-description?
30;; * Input validation functions. How specified? 32;; * Input validation functions. How specified?
31;; * Menubar and popup menus.
32;; * Faces (colors & styles) in print cells. 33;; * Faces (colors & styles) in print cells.
33;; * Move a column by dragging its letter in the header line. 34;; * Move a column by dragging its letter in the header line.
34;; * Left-margin column for row number. 35;; * Left-margin column for row number.
@@ -87,16 +88,119 @@ usually runs a cursor-movement function. Each function is called with ARG=1."
87(defvar ses-read-printer-history nil 88(defvar ses-read-printer-history nil
88 "List of printer functions that have been typed in.") 89 "List of printer functions that have been typed in.")
89 90
90(defvar ses-mode-map nil 91(easy-menu-define ses-header-line-menu nil
91 "Local keymap for Simple Emacs Spreadsheet.") 92 "Context menu when mouse-3 is used on the header-line in an SES buffer."
93 '("SES header row"
94 ["Set current row" ses-set-header-row t]
95 ["Unset row" ses-unset-header-row (> header-row 0)]))
92 96
93(defvar ses-mode-print-map nil 97(defconst ses-mode-map
94 "Local keymap for SES print area.") 98 (let ((keys `("\C-c\M-\C-l" ses-reconstruct-all
99 "\C-c\C-l" ses-recalculate-all
100 "\C-c\C-n" ses-renarrow-buffer
101 "\C-c\C-c" ses-recalculate-cell
102 "\C-c\M-\C-s" ses-sort-column
103 "\C-c\M-\C-h" ses-set-header-row
104 "\C-c\C-t" ses-truncate-cell
105 "\C-c\C-j" ses-jump
106 "\C-c\C-p" ses-read-default-printer
107 "\M-\C-l" ses-reprint-all
108 [?\S-\C-l] ses-reprint-all
109 [header-line down-mouse-3] ,ses-header-line-menu
110 [header-line mouse-2] ses-sort-column-click))
111 (newmap (make-sparse-keymap)))
112 (while keys
113 (define-key (1value newmap) (car keys) (cadr keys))
114 (setq keys (cddr keys)))
115 newmap)
116 "Local keymap for Simple Emacs Spreadsheet.")
95 117
96(defvar ses-mode-edit-map nil 118(easy-menu-define ses-menu ses-mode-map
119 "Menu bar menu for SES."
120 '("SES"
121 ["Insert row" ses-insert-row (ses-in-print-area)]
122 ["Delete row" ses-delete-row (ses-in-print-area)]
123 ["Insert column" ses-insert-column (ses-in-print-area)]
124 ["Delete column" ses-delete-column (ses-in-print-area)]
125 ["Set column printer" ses-read-column-printer t]
126 ["Set column width" ses-set-column-width t]
127 ["Set default printer" ses-read-default-printer t]
128 ["Jump to cell" ses-jump t]
129 ["Set cell printer" ses-read-cell-printer t]
130 ["Recalculate cell" ses-recalculate-cell t]
131 ["Truncate cell display" ses-truncate-cell t]
132 ["Export values" ses-export-tsv t]
133 ["Export formulas" ses-export-tsf t]))
134
135(defconst ses-mode-edit-map
136 (let ((keys '("\C-c\C-r" ses-insert-range
137 "\C-c\C-s" ses-insert-ses-range
138 [S-mouse-3] ses-insert-range-click
139 [C-S-mouse-3] ses-insert-ses-range-click
140 "\M-\C-i" lisp-complete-symbol))
141 (newmap (make-sparse-keymap)))
142 (set-keymap-parent newmap minibuffer-local-map)
143 (while keys
144 (define-key newmap (car keys) (cadr keys))
145 (setq keys (cddr keys)))
146 newmap)
97 "Local keymap for SES minibuffer cell-editing.") 147 "Local keymap for SES minibuffer cell-editing.")
98 148
99;Key map used for 'x' key. 149;Local keymap for SES print area
150(defalias 'ses-mode-print-map
151 (let ((keys '([backtab] backward-char
152 [tab] ses-forward-or-insert
153 "\C-i" ses-forward-or-insert ;Needed for ses-coverage.el?
154 "\M-o" ses-insert-column
155 "\C-o" ses-insert-row
156 "\C-m" ses-edit-cell
157 "\M-k" ses-delete-column
158 "\M-y" ses-yank-pop
159 "\C-k" ses-delete-row
160 "\C-j" ses-append-row-jump-first-column
161 "\M-h" ses-mark-row
162 "\M-H" ses-mark-column
163 "\C-d" ses-clear-cell-forward
164 "\C-?" ses-clear-cell-backward
165 "(" ses-read-cell
166 "\"" ses-read-cell
167 "'" ses-read-symbol
168 "=" ses-edit-cell
169 "j" ses-jump
170 "p" ses-read-cell-printer
171 "w" ses-set-column-width
172 "x" ses-export-keymap
173 "\M-p" ses-read-column-printer))
174 (repl '(;;We'll replace these wherever they appear in the keymap
175 clipboard-kill-region ses-kill-override
176 end-of-line ses-end-of-line
177 kill-line ses-delete-row
178 kill-region ses-kill-override
179 open-line ses-insert-row))
180 (numeric "0123456789.-")
181 (newmap (make-keymap)))
182 ;;Get rid of printables
183 (suppress-keymap newmap t)
184 ;;These keys insert themselves as the beginning of a numeric value
185 (dotimes (x (length numeric))
186 (define-key newmap (substring numeric x (1+ x)) 'ses-read-cell))
187 ;;Override these global functions wherever they're bound
188 (while repl
189 (substitute-key-definition (car repl) (cadr repl) newmap
190 (current-global-map))
191 (setq repl (cddr repl)))
192 ;;Apparently substitute-key-definition doesn't catch this?
193 (define-key newmap [(menu-bar) edit cut] 'ses-kill-override)
194 ;;Define our other local keys
195 (while keys
196 (define-key newmap (car keys) (cadr keys))
197 (setq keys (cddr keys)))
198 newmap))
199
200;;Helptext for ses-mode wants keymap as variable, not function
201(defconst ses-mode-print-map (symbol-function 'ses-mode-print-map))
202
203;;Key map used for 'x' key.
100(defalias 'ses-export-keymap 204(defalias 'ses-export-keymap
101 (let ((map (make-sparse-keymap "SES export"))) 205 (let ((map (make-sparse-keymap "SES export")))
102 (define-key map "T" (cons " tab-formulas" 'ses-export-tsf)) 206 (define-key map "T" (cons " tab-formulas" 'ses-export-tsf))
@@ -132,8 +236,9 @@ usually runs a cursor-movement function. Each function is called with ARG=1."
132REFERENCES.") 236REFERENCES.")
133 237
134(defconst ses-paramlines-plist 238(defconst ses-paramlines-plist
135 '(column-widths 2 col-printers 3 default-printer 4 header-row 5 239 '(ses--col-widths 2 ses--col-printers 3 ses--default-printer 4
136 file-format 8 numrows 9 numcols 10) 240 ses--header-row 5 ses--file-format 8 ses--numrows 9
241 ses--numcols 10)
137 "Offsets from last cell line to various parameter lines in the data area 242 "Offsets from last cell line to various parameter lines in the data area
138of a spreadsheet.") 243of a spreadsheet.")
139 244
@@ -150,11 +255,13 @@ default printer and then modify its output.")
150 255
151(eval-and-compile 256(eval-and-compile
152 (defconst ses-localvars 257 (defconst ses-localvars
153 '(blank-line cells col-printers column-widths curcell curcell-overlay 258 '(ses--blank-line ses--cells ses--col-printers ses--col-widths ses--curcell
154 default-printer deferred-narrow deferred-recalc deferred-write 259 ses--curcell-overlay ses--default-printer ses--deferred-narrow
155 file-format header-hscroll header-row header-string linewidth 260 ses--deferred-recalc ses--deferred-write ses--file-format
156 mode-line-process next-line-add-newlines numcols numrows 261 ses--header-hscroll ses--header-row ses--header-string ses--linewidth
157 symbolic-formulas transient-mark-mode) 262 ses--numcols ses--numrows ses--symbolic-formulas
263 ;;Global variables that we override
264 mode-line-process next-line-add-newlines transient-mark-mode)
158 "Buffer-local variables used by SES.")) 265 "Buffer-local variables used by SES."))
159 266
160;;When compiling, create all the buffer locals and give them values 267;;When compiling, create all the buffer locals and give them values
@@ -195,7 +302,7 @@ when to emit a progress message.")
195 302
196(defmacro ses-get-cell (row col) 303(defmacro ses-get-cell (row col)
197 "Return the cell structure that stores information about cell (ROW,COL)." 304 "Return the cell structure that stores information about cell (ROW,COL)."
198 `(aref (aref cells ,row) ,col)) 305 `(aref (aref ses--cells ,row) ,col))
199 306
200(defmacro ses-cell-symbol (row &optional col) 307(defmacro ses-cell-symbol (row &optional col)
201 "From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1." 308 "From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1."
@@ -220,11 +327,11 @@ functions refer to its value."
220 327
221(defmacro ses-col-width (col) 328(defmacro ses-col-width (col)
222 "Return the width for column COL." 329 "Return the width for column COL."
223 `(aref column-widths ,col)) 330 `(aref ses--col-widths ,col))
224 331
225(defmacro ses-col-printer (col) 332(defmacro ses-col-printer (col)
226 "Return the default printer for column COL." 333 "Return the default printer for column COL."
227 `(aref col-printers ,col)) 334 `(aref ses--col-printers ,col))
228 335
229(defmacro ses-sym-rowcol (sym) 336(defmacro ses-sym-rowcol (sym)
230 "From a cell-symbol SYM, gets the cons (row . col). A1 => (0 . 0). Result 337 "From a cell-symbol SYM, gets the cons (row . col). A1 => (0 . 0). Result
@@ -246,7 +353,7 @@ PRINTER are deferred until first use."
246 (stringp printer) 353 (stringp printer)
247 (eq safe-functions t) 354 (eq safe-functions t)
248 (setq printer `(ses-safe-printer ,printer))) 355 (setq printer `(ses-safe-printer ,printer)))
249 (aset (aref cells (car rowcol)) 356 (aset (aref ses--cells (car rowcol))
250 (cdr rowcol) 357 (cdr rowcol)
251 (vector sym formula printer references))) 358 (vector sym formula printer references)))
252 (set sym value) 359 (set sym value)
@@ -255,39 +362,39 @@ PRINTER are deferred until first use."
255(defmacro ses-column-widths (widths) 362(defmacro ses-column-widths (widths)
256 "Load the vector of column widths from the spreadsheet file. This is a 363 "Load the vector of column widths from the spreadsheet file. This is a
257macro to prevent propagate-on-load viruses." 364macro to prevent propagate-on-load viruses."
258 (or (and (vectorp widths) (= (length widths) numcols)) 365 (or (and (vectorp widths) (= (length widths) ses--numcols))
259 (error "Bad column-width vector")) 366 (error "Bad column-width vector"))
260 ;;To save time later, we also calculate the total width of each line in the 367 ;;To save time later, we also calculate the total width of each line in the
261 ;;print area (excluding the terminating newline) 368 ;;print area (excluding the terminating newline)
262 (setq column-widths widths 369 (setq ses--col-widths widths
263 linewidth (apply '+ -1 (mapcar '1+ widths)) 370 ses--linewidth (apply '+ -1 (mapcar '1+ widths))
264 blank-line (concat (make-string linewidth ? ) "\n")) 371 ses--blank-line (concat (make-string ses--linewidth ? ) "\n"))
265 t) 372 t)
266 373
267(defmacro ses-column-printers (printers) 374(defmacro ses-column-printers (printers)
268 "Load the vector of column printers from the spreadsheet file and checks 375 "Load the vector of column printers from the spreadsheet file and checks
269them for safety. This is a macro to prevent propagate-on-load viruses." 376them for safety. This is a macro to prevent propagate-on-load viruses."
270 (or (and (vectorp printers) (= (length printers) numcols)) 377 (or (and (vectorp printers) (= (length printers) ses--numcols))
271 (error "Bad column-printers vector")) 378 (error "Bad column-printers vector"))
272 (dotimes (x numcols) 379 (dotimes (x ses--numcols)
273 (aset printers x (ses-safe-printer (aref printers x)))) 380 (aset printers x (ses-safe-printer (aref printers x))))
274 (setq col-printers printers) 381 (setq ses--col-printers printers)
275 (mapc 'ses-printer-record printers) 382 (mapc 'ses-printer-record printers)
276 t) 383 t)
277 384
278(defmacro ses-default-printer (def) 385(defmacro ses-default-printer (def)
279 "Load the global default printer from the spreadsheet file and checks it 386 "Load the global default printer from the spreadsheet file and checks it
280for safety. This is a macro to prevent propagate-on-load viruses." 387for safety. This is a macro to prevent propagate-on-load viruses."
281 (setq default-printer (ses-safe-printer def)) 388 (setq ses--default-printer (ses-safe-printer def))
282 (ses-printer-record def) 389 (ses-printer-record def)
283 t) 390 t)
284 391
285(defmacro ses-header-row (row) 392(defmacro ses-header-row (row)
286 "Load the header row from the spreadsheet file and checks it 393 "Load the header row from the spreadsheet file and checks it
287for safety. This is a macro to prevent propagate-on-load viruses." 394for safety. This is a macro to prevent propagate-on-load viruses."
288 (or (and (wholenump row) (< row numrows)) 395 (or (and (wholenump row) (< row ses--numrows))
289 (error "Bad header-row")) 396 (error "Bad header-row"))
290 (setq header-row row) 397 (setq ses--header-row row)
291 t) 398 t)
292 399
293(defmacro ses-dotimes-msg (spec msg &rest body) 400(defmacro ses-dotimes-msg (spec msg &rest body)
@@ -405,7 +512,7 @@ checking that it is a valid printer function."
405for this spreadsheet." 512for this spreadsheet."
406 (when (and (eq (car-safe formula) 'quote) 513 (when (and (eq (car-safe formula) 'quote)
407 (symbolp (cadr formula))) 514 (symbolp (cadr formula)))
408 (add-to-list 'symbolic-formulas 515 (add-to-list 'ses--symbolic-formulas
409 (list (symbol-name (cadr formula)))))) 516 (list (symbol-name (cadr formula))))))
410 517
411(defun ses-column-letter (col) 518(defun ses-column-letter (col)
@@ -451,7 +558,7 @@ for this spreadsheet."
451 "Flags the header string for update. Upon undo, the header string will be 558 "Flags the header string for update. Upon undo, the header string will be
452updated again." 559updated again."
453 (push '(ses-reset-header-string) buffer-undo-list) 560 (push '(ses-reset-header-string) buffer-undo-list)
454 (setq header-hscroll -1)) 561 (setq ses--header-hscroll -1))
455 562
456;;Split this code off into a function to avoid coverage-testing difficulties 563;;Split this code off into a function to avoid coverage-testing difficulties
457(defun ses-time-check (format arg) 564(defun ses-time-check (format arg)
@@ -480,7 +587,7 @@ cell (ROW,COL). This is undoable. The cell's data will be updated through
480 (ses-set-with-undo (ses-cell-symbol cell) val) 587 (ses-set-with-undo (ses-cell-symbol cell) val)
481 (ses-aset-with-undo cell elt val))) 588 (ses-aset-with-undo cell elt val)))
482 (if change 589 (if change
483 (add-to-list 'deferred-write (cons row col)))) 590 (add-to-list 'ses--deferred-write (cons row col))))
484 nil) ;Make coverage-tester happy 591 nil) ;Make coverage-tester happy
485 592
486(defun ses-cell-set-formula (row col formula) 593(defun ses-cell-set-formula (row col formula)
@@ -496,7 +603,7 @@ means Emacs will crash if FORMULA contains a circular list."
496 (newref (ses-formula-references formula)) 603 (newref (ses-formula-references formula))
497 (inhibit-quit t) 604 (inhibit-quit t)
498 x xrow xcol) 605 x xrow xcol)
499 (add-to-list 'deferred-recalc sym) 606 (add-to-list 'ses--deferred-recalc sym)
500 ;;Delete old references from this cell. Skip the ones that are also 607 ;;Delete old references from this cell. Skip the ones that are also
501 ;;in the new list. 608 ;;in the new list.
502 (dolist (ref oldref) 609 (dolist (ref oldref)
@@ -542,10 +649,10 @@ the old and FORCE is nil."
542 ;;Don't lose the *skip* - previous field spans this one 649 ;;Don't lose the *skip* - previous field spans this one
543 (setq newval '*skip*)) 650 (setq newval '*skip*))
544 (when (or force (not (eq newval oldval))) 651 (when (or force (not (eq newval oldval)))
545 (add-to-list 'deferred-write (cons row col)) ;In case force=t 652 (add-to-list 'ses--deferred-write (cons row col)) ;In case force=t
546 (ses-set-cell row col 'value newval) 653 (ses-set-cell row col 'value newval)
547 (dolist (ref (ses-cell-references cell)) 654 (dolist (ref (ses-cell-references cell))
548 (add-to-list 'deferred-recalc ref)))) 655 (add-to-list 'ses--deferred-recalc ref))))
549 (setq printer-error (ses-print-cell row col)) 656 (setq printer-error (ses-print-cell row col))
550 (or formula-error printer-error))) 657 (or formula-error printer-error)))
551 658
@@ -558,31 +665,31 @@ the old and FORCE is nil."
558 "Recalculate cells in LIST, checking for dependency loops. Prints 665 "Recalculate cells in LIST, checking for dependency loops. Prints
559progress messages every second. Dependent cells are not recalculated 666progress messages every second. Dependent cells are not recalculated
560if the cell's value is unchanged if FORCE is nil." 667if the cell's value is unchanged if FORCE is nil."
561 (let ((deferred-recalc list) 668 (let ((ses--deferred-recalc list)
562 (nextlist list) 669 (nextlist list)
563 (pos (point)) 670 (pos (point))
564 curlist prevlist rowcol formula) 671 curlist prevlist rowcol formula)
565 (with-temp-message " " 672 (with-temp-message " "
566 (while (and deferred-recalc (not (equal nextlist prevlist))) 673 (while (and ses--deferred-recalc (not (equal nextlist prevlist)))
567 ;;In each loop, recalculate cells that refer only to other cells that 674 ;;In each loop, recalculate cells that refer only to other cells that
568 ;;have already been recalculated or aren't in the recalculation 675 ;;have already been recalculated or aren't in the recalculation
569 ;;region. Repeat until all cells have been processed or until the 676 ;;region. Repeat until all cells have been processed or until the
570 ;;set of cells being worked on stops changing. 677 ;;set of cells being worked on stops changing.
571 (if prevlist 678 (if prevlist
572 (message "Recalculating... (%d cells left)" 679 (message "Recalculating... (%d cells left)"
573 (length deferred-recalc))) 680 (length ses--deferred-recalc)))
574 (setq curlist deferred-recalc 681 (setq curlist ses--deferred-recalc
575 deferred-recalc nil 682 ses--deferred-recalc nil
576 prevlist nextlist) 683 prevlist nextlist)
577 (while curlist 684 (while curlist
578 (setq rowcol (ses-sym-rowcol (car curlist)) 685 (setq rowcol (ses-sym-rowcol (car curlist))
579 formula (ses-cell-formula (car rowcol) (cdr rowcol))) 686 formula (ses-cell-formula (car rowcol) (cdr rowcol)))
580 (or (catch 'ref 687 (or (catch 'ref
581 (dolist (ref (ses-formula-references formula)) 688 (dolist (ref (ses-formula-references formula))
582 (when (or (memq ref curlist) 689 (when (or (memq ref curlist)
583 (memq ref deferred-recalc)) 690 (memq ref ses--deferred-recalc))
584 ;;This cell refers to another that isn't done yet 691 ;;This cell refers to another that isn't done yet
585 (add-to-list 'deferred-recalc (car curlist)) 692 (add-to-list 'ses--deferred-recalc (car curlist))
586 (throw 'ref t)))) 693 (throw 'ref t))))
587 ;;ses-update-cells is called from post-command-hook, so 694 ;;ses-update-cells is called from post-command-hook, so
588 ;;inhibit-quit is implicitly bound to t. 695 ;;inhibit-quit is implicitly bound to t.
@@ -591,19 +698,19 @@ if the cell's value is unchanged if FORCE is nil."
591 (error "Quit")) 698 (error "Quit"))
592 (ses-calculate-cell (car rowcol) (cdr rowcol) force)) 699 (ses-calculate-cell (car rowcol) (cdr rowcol) force))
593 (setq curlist (cdr curlist))) 700 (setq curlist (cdr curlist)))
594 (dolist (ref deferred-recalc) 701 (dolist (ref ses--deferred-recalc)
595 (add-to-list 'nextlist ref)) 702 (add-to-list 'nextlist ref))
596 (setq nextlist (sort (copy-sequence nextlist) 'string<)) 703 (setq nextlist (sort (copy-sequence nextlist) 'string<))
597 (if (equal nextlist prevlist) 704 (if (equal nextlist prevlist)
598 ;;We'll go around the loop one more time. 705 ;;We'll go around the loop one more time.
599 (add-to-list 'nextlist t))) 706 (add-to-list 'nextlist t)))
600 (when deferred-recalc 707 (when ses--deferred-recalc
601 ;;Just couldn't finish these 708 ;;Just couldn't finish these
602 (dolist (x deferred-recalc) 709 (dolist (x ses--deferred-recalc)
603 (let ((rowcol (ses-sym-rowcol x))) 710 (let ((rowcol (ses-sym-rowcol x)))
604 (ses-set-cell (car rowcol) (cdr rowcol) 'value '*error*) 711 (ses-set-cell (car rowcol) (cdr rowcol) 'value '*error*)
605 (1value (ses-print-cell (car rowcol) (cdr rowcol))))) 712 (1value (ses-print-cell (car rowcol) (cdr rowcol)))))
606 (error "Circular references: %s" deferred-recalc)) 713 (error "Circular references: %s" ses--deferred-recalc))
607 (message " ")) 714 (message " "))
608 ;;Can't use save-excursion here: if the cell under point is 715 ;;Can't use save-excursion here: if the cell under point is
609 ;;updated, save-excusion's marker will move past the cell. 716 ;;updated, save-excusion's marker will move past the cell.
@@ -614,46 +721,50 @@ if the cell's value is unchanged if FORCE is nil."
614;;;; The print area 721;;;; The print area
615;;;---------------------------------------------------------------------------- 722;;;----------------------------------------------------------------------------
616 723
724(defun ses-in-print-area ()
725 "Returns t if point is in print area of spreadsheet."
726 (eq (get-text-property (point) 'keymap) 'ses-mode-print-map))
727
617;;;We turn off point-motion-hooks and explicitly position the cursor, in case 728;;;We turn off point-motion-hooks and explicitly position the cursor, in case
618;;;the intangible properties have gotten screwed up (e.g., when 729;;;the intangible properties have gotten screwed up (e.g., when
619;;;ses-goto-print is called during a recursive ses-print-cell). 730;;;ses-goto-print is called during a recursive ses-print-cell).
620(defun ses-goto-print (row col) 731(defun ses-goto-print (row col)
621 "Move point to print area for cell (ROW,COL)." 732 "Move point to print area for cell (ROW,COL)."
622 (let ((inhibit-point-motion-hooks t)) 733 (let ((inhibit-point-motion-hooks t))
623 (goto-char 1) 734 (goto-char (point-min))
624 (forward-line row) 735 (forward-line row)
625 (dotimes (c col) 736 (dotimes (c col)
626 (forward-char (1+ (ses-col-width c)))))) 737 (forward-char (1+ (ses-col-width c))))))
627 738
628(defun ses-set-curcell () 739(defun ses-set-curcell ()
629 "Sets `curcell' to the current cell symbol, or a cons (BEG,END) for a 740 "Sets `ses--curcell' to the current cell symbol, or a cons (BEG,END) for a
630region, or nil if cursor is not at a cell." 741region, or nil if cursor is not at a cell."
631 (if (or (not mark-active) 742 (if (or (not mark-active)
632 deactivate-mark 743 deactivate-mark
633 (= (region-beginning) (region-end))) 744 (= (region-beginning) (region-end)))
634 ;;Single cell 745 ;;Single cell
635 (setq curcell (get-text-property (point) 'intangible)) 746 (setq ses--curcell (get-text-property (point) 'intangible))
636 ;;Range 747 ;;Range
637 (let ((bcell (get-text-property (region-beginning) 'intangible)) 748 (let ((bcell (get-text-property (region-beginning) 'intangible))
638 (ecell (get-text-property (1- (region-end)) 'intangible))) 749 (ecell (get-text-property (1- (region-end)) 'intangible)))
639 (setq curcell (if (and bcell ecell) 750 (setq ses--curcell (if (and bcell ecell)
640 (cons bcell ecell) 751 (cons bcell ecell)
641 nil)))) 752 nil))))
642 nil) 753 nil)
643 754
644(defun ses-check-curcell (&rest args) 755(defun ses-check-curcell (&rest args)
645 "Signal an error if curcell is inappropriate. The end marker is 756 "Signal an error if ses--curcell is inappropriate. The end marker is
646appropriate if some argument is 'end. A range is appropriate if some 757appropriate if some argument is 'end. A range is appropriate if some
647argument is 'range. A single cell is appropriate unless some argument is 758argument is 'range. A single cell is appropriate unless some argument is
648'needrange." 759'needrange."
649 (if (eq curcell t) 760 (if (eq ses--curcell t)
650 ;;curcell recalculation was postponed, but user typed ahead 761 ;;curcell recalculation was postponed, but user typed ahead
651 (ses-set-curcell)) 762 (ses-set-curcell))
652 (cond 763 (cond
653 ((not curcell) 764 ((not ses--curcell)
654 (or (memq 'end args) 765 (or (memq 'end args)
655 (error "Not at cell"))) 766 (error "Not at cell")))
656 ((consp curcell) 767 ((consp ses--curcell)
657 (or (memq 'range args) 768 (or (memq 'range args)
658 (memq 'needrange args) 769 (memq 'needrange args)
659 (error "Can't use a range"))) 770 (error "Can't use a range")))
@@ -689,7 +800,7 @@ preceding cell has spilled over."
689 ;;Print the value 800 ;;Print the value
690 (setq text (ses-call-printer (or printer 801 (setq text (ses-call-printer (or printer
691 (ses-col-printer col) 802 (ses-col-printer col)
692 default-printer) 803 ses--default-printer)
693 value)) 804 value))
694 (if (consp ses-call-printer-return) 805 (if (consp ses-call-printer-return)
695 ;;Printer returned an error 806 ;;Printer returned an error
@@ -708,7 +819,7 @@ preceding cell has spilled over."
708 ;;Spill over into following cells, if possible 819 ;;Spill over into following cells, if possible
709 (let ((maxwidth width)) 820 (let ((maxwidth width))
710 (while (and (> len maxwidth) 821 (while (and (> len maxwidth)
711 (< maxcol numcols) 822 (< maxcol ses--numcols)
712 (or (not (setq x (ses-cell-value row maxcol))) 823 (or (not (setq x (ses-cell-value row maxcol)))
713 (eq x '*skip*))) 824 (eq x '*skip*)))
714 (unless x 825 (unless x
@@ -748,7 +859,7 @@ preceding cell has spilled over."
748 (delete-char (1+ (length text))) 859 (delete-char (1+ (length text)))
749 ;;We use concat instead of inserting separate strings in order to 860 ;;We use concat instead of inserting separate strings in order to
750 ;;reduce the number of cells in the undo list. 861 ;;reduce the number of cells in the undo list.
751 (setq x (concat text (if (< maxcol numcols) " " "\n"))) 862 (setq x (concat text (if (< maxcol ses--numcols) " " "\n")))
752 ;;We use set-text-properties to prevent a wacky print function 863 ;;We use set-text-properties to prevent a wacky print function
753 ;;from inserting rogue properties, and to ensure that the keymap 864 ;;from inserting rogue properties, and to ensure that the keymap
754 ;;property is inherited (is it a bug that only unpropertied strings 865 ;;property is inherited (is it a bug that only unpropertied strings
@@ -759,15 +870,16 @@ preceding cell has spilled over."
759 (ses-cell-symbol cell)) 870 (ses-cell-symbol cell))
760 (when (and (zerop row) (zerop col)) 871 (when (and (zerop row) (zerop col))
761 ;;Reconstruct special beginning-of-buffer attributes 872 ;;Reconstruct special beginning-of-buffer attributes
762 (put-text-property 1 (point) 'keymap 'ses-mode-print-map) 873 (put-text-property (point-min) (point) 'keymap 'ses-mode-print-map)
763 (put-text-property 1 (point) 'read-only 'ses) 874 (put-text-property (point-min) (point) 'read-only 'ses)
764 (put-text-property 1 2 'front-sticky t))) 875 (put-text-property (point-min) (1+ (point-min)) 'front-sticky t)))
765 (if (= row (1- header-row)) 876 (if (= row (1- ses--header-row))
766 ;;This line is part of the header - force recalc 877 ;;This line is part of the header - force recalc
767 (ses-reset-header-string)) 878 (ses-reset-header-string))
768 ;;If this cell (or a preceding one on the line) previously spilled over 879 ;;If this cell (or a preceding one on the line) previously spilled over
769 ;;and has gotten shorter, redraw following cells on line recursively. 880 ;;and has gotten shorter, redraw following cells on line recursively.
770 (when (and (< maxcol numcols) (eq (ses-cell-value row maxcol) '*skip*)) 881 (when (and (< maxcol ses--numcols)
882 (eq (ses-cell-value row maxcol) '*skip*))
771 (ses-set-cell row maxcol 'value nil) 883 (ses-set-cell row maxcol 'value nil)
772 (ses-print-cell row maxcol)) 884 (ses-print-cell row maxcol))
773 ;;Return to start of cell 885 ;;Return to start of cell
@@ -808,12 +920,12 @@ COL=NUMCOLS. Deletes characters if CHANGE < 0. Caller should bind
808inhibit-quit to t." 920inhibit-quit to t."
809 (let ((inhibit-read-only t) 921 (let ((inhibit-read-only t)
810 (blank (if (> change 0) (make-string change ? ))) 922 (blank (if (> change 0) (make-string change ? )))
811 (at-end (= col numcols))) 923 (at-end (= col ses--numcols)))
812 (ses-set-with-undo 'linewidth (+ linewidth change)) 924 (ses-set-with-undo 'ses--linewidth (+ ses--linewidth change))
813 ;;ses-set-with-undo always returns t for strings. 925 ;;ses-set-with-undo always returns t for strings.
814 (1value (ses-set-with-undo 'blank-line 926 (1value (ses-set-with-undo 'ses--blank-line
815 (concat (make-string linewidth ? ) "\n"))) 927 (concat (make-string ses--linewidth ? ) "\n")))
816 (dotimes (row numrows) 928 (dotimes (row ses--numrows)
817 (ses-goto-print row col) 929 (ses-goto-print row col)
818 (when at-end 930 (when at-end
819 ;;Insert new columns before newline 931 ;;Insert new columns before newline
@@ -841,21 +953,22 @@ cell (ROW,COL) has changed."
841;;;---------------------------------------------------------------------------- 953;;;----------------------------------------------------------------------------
842 954
843(defun ses-goto-data (def &optional col) 955(defun ses-goto-data (def &optional col)
844 "Move point to data area for (DEF,COL). If DEF is a row number, COL is the 956 "Move point to data area for (DEF,COL). If DEF is a row
845column number for a data cell -- otherwise DEF is one of the symbols 957number, COL is the column number for a data cell -- otherwise DEF
846column-widths, col-printers, default-printer, numrows, or numcols." 958is one of the symbols ses--col-widths, ses--col-printers,
959ses--default-printer, ses--numrows, or ses--numcols."
847 (if (< (point-max) (buffer-size)) 960 (if (< (point-max) (buffer-size))
848 (setq deferred-narrow t)) 961 (setq ses--deferred-narrow t))
849 (widen) 962 (widen)
850 (let ((inhibit-point-motion-hooks t)) ;In case intangible attrs are wrong 963 (let ((inhibit-point-motion-hooks t)) ;In case intangible attrs are wrong
851 (goto-char 1) 964 (goto-char (point-min))
852 (if col 965 (if col
853 ;;It's a cell 966 ;;It's a cell
854 (forward-line (+ numrows 2 (* def (1+ numcols)) col)) 967 (forward-line (+ ses--numrows 2 (* def (1+ ses--numcols)) col))
855 ;;Convert def-symbol to offset 968 ;;Convert def-symbol to offset
856 (setq def (plist-get ses-paramlines-plist def)) 969 (setq def (plist-get ses-paramlines-plist def))
857 (or def (signal 'args-out-of-range nil)) 970 (or def (signal 'args-out-of-range nil))
858 (forward-line (+ (* numrows (+ numcols 2)) def))))) 971 (forward-line (+ (* ses--numrows (+ ses--numcols 2)) def)))))
859 972
860(defun ses-set-parameter (def value &optional elem) 973(defun ses-set-parameter (def value &optional elem)
861 "Sets parameter DEF to VALUE (with undo) and writes the value to the data 974 "Sets parameter DEF to VALUE (with undo) and writes the value to the data
@@ -870,19 +983,19 @@ be set to VALUE."
870 (ses-aset-with-undo (symbol-value def) elem value) 983 (ses-aset-with-undo (symbol-value def) elem value)
871 (ses-set-with-undo def value)) 984 (ses-set-with-undo def value))
872 (let ((inhibit-read-only t) 985 (let ((inhibit-read-only t)
873 (fmt (plist-get '(column-widths "(ses-column-widths %S)" 986 (fmt (plist-get '(ses--column-widths "(ses-column-widths %S)"
874 col-printers "(ses-column-printers %S)" 987 ses--col-printers "(ses-column-printers %S)"
875 default-printer "(ses-default-printer %S)" 988 ses--default-printer "(ses-default-printer %S)"
876 header-row "(ses-header-row %S)" 989 ses--header-row "(ses-header-row %S)"
877 file-format " %S ;SES file-format" 990 ses--file-format " %S ;SES file-format"
878 numrows " %S ;numrows" 991 ses--numrows " %S ;numrows"
879 numcols " %S ;numcols") 992 ses--numcols " %S ;numcols")
880 def))) 993 def)))
881 (delete-region (point) (line-end-position)) 994 (delete-region (point) (line-end-position))
882 (insert (format fmt (symbol-value def)))))) 995 (insert (format fmt (symbol-value def))))))
883 996
884(defun ses-write-cells () 997(defun ses-write-cells ()
885 "`deferred-write' is a list of (ROW,COL) for cells to be written from 998 "`ses--deferred-write' is a list of (ROW,COL) for cells to be written from
886buffer-local variables to data area. Newlines in the data are escaped." 999buffer-local variables to data area. Newlines in the data are escaped."
887 (let* ((inhibit-read-only t) 1000 (let* ((inhibit-read-only t)
888 (print-escape-newlines t) 1001 (print-escape-newlines t)
@@ -890,10 +1003,10 @@ buffer-local variables to data area. Newlines in the data are escaped."
890 (setq ses-start-time (float-time)) 1003 (setq ses-start-time (float-time))
891 (with-temp-message " " 1004 (with-temp-message " "
892 (save-excursion 1005 (save-excursion
893 (while deferred-write 1006 (while ses--deferred-write
894 (ses-time-check "Writing... (%d cells left)" 1007 (ses-time-check "Writing... (%d cells left)"
895 '(length deferred-write)) 1008 '(length ses--deferred-write))
896 (setq rowcol (pop deferred-write) 1009 (setq rowcol (pop ses--deferred-write)
897 row (car rowcol) 1010 row (car rowcol)
898 col (cdr rowcol) 1011 col (cdr rowcol)
899 cell (ses-get-cell row col) 1012 cell (ses-get-cell row col)
@@ -1013,7 +1126,7 @@ by (ROWINCR,COLINCR)."
1013 (setq row (+ row rowincr) 1126 (setq row (+ row rowincr)
1014 col (+ col colincr)) 1127 col (+ col colincr))
1015 (if (and (>= row startrow) (>= col startcol) 1128 (if (and (>= row startrow) (>= col startcol)
1016 (< row numrows) (< col numcols)) 1129 (< row ses--numrows) (< col ses--numcols))
1017 ;;Relocate this variable 1130 ;;Relocate this variable
1018 (ses-create-cell-symbol row col) 1131 (ses-create-cell-symbol row col)
1019 ;;Delete reference to a deleted cell 1132 ;;Delete reference to a deleted cell
@@ -1050,7 +1163,8 @@ if the range was altered."
1050 (if (not max) 1163 (if (not max)
1051 (if (> rowincr 0) 1164 (if (> rowincr 0)
1052 ;;Trying to insert a nonexistent row 1165 ;;Trying to insert a nonexistent row
1053 (setq max (ses-create-cell-symbol (1- numrows) (cdr minrowcol))) 1166 (setq max (ses-create-cell-symbol (1- ses--numrows)
1167 (cdr minrowcol)))
1054 ;;End of range is being deleted 1168 ;;End of range is being deleted
1055 (setq max (ses-create-cell-symbol (1- startrow) (cdr minrowcol)) 1169 (setq max (ses-create-cell-symbol (1- startrow) (cdr minrowcol))
1056 ses-relocate-return 'range)) 1170 ses-relocate-return 'range))
@@ -1070,7 +1184,8 @@ if the range was altered."
1070 (if (not max) 1184 (if (not max)
1071 (if (> colincr 0) 1185 (if (> colincr 0)
1072 ;;Trying to insert a nonexistent column 1186 ;;Trying to insert a nonexistent column
1073 (setq max (ses-create-cell-symbol (car maxrowcol) (1- numcols))) 1187 (setq max (ses-create-cell-symbol (car maxrowcol)
1188 (1- ses--numcols)))
1074 ;;End of range is being deleted 1189 ;;End of range is being deleted
1075 (setq max (ses-create-cell-symbol (car maxrowcol) (1- startcol)) 1190 (setq max (ses-create-cell-symbol (car maxrowcol) (1- startcol))
1076 ses-relocate-return 'range)) 1191 ses-relocate-return 'range))
@@ -1095,8 +1210,8 @@ the rectangle (MINROW,MINCOL)..(NUMROWS,NUMCOLS) by adding ROWINCR and COLINCR
1095to each symbol." 1210to each symbol."
1096 (let (reform) 1211 (let (reform)
1097 (let (mycell newval) 1212 (let (mycell newval)
1098 (ses-dotimes-msg (row numrows) "Relocating formulas..." 1213 (ses-dotimes-msg (row ses--numrows) "Relocating formulas..."
1099 (dotimes (col numcols) 1214 (dotimes (col ses--numcols)
1100 (setq ses-relocate-return nil 1215 (setq ses-relocate-return nil
1101 mycell (ses-get-cell row col) 1216 mycell (ses-get-cell row col)
1102 newval (ses-relocate-formula (ses-cell-formula mycell) 1217 newval (ses-relocate-formula (ses-cell-formula mycell)
@@ -1110,7 +1225,7 @@ to each symbol."
1110 ;;This cell referred to a cell that's been deleted or is no 1225 ;;This cell referred to a cell that's been deleted or is no
1111 ;;longer part of the range. We can't fix that now because 1226 ;;longer part of the range. We can't fix that now because
1112 ;;reference lists cells have been partially updated. 1227 ;;reference lists cells have been partially updated.
1113 (add-to-list 'deferred-recalc 1228 (add-to-list 'ses--deferred-recalc
1114 (ses-create-cell-symbol row col))) 1229 (ses-create-cell-symbol row col)))
1115 (setq newval (ses-relocate-formula (ses-cell-references mycell) 1230 (setq newval (ses-relocate-formula (ses-cell-references mycell)
1116 minrow mincol rowincr colincr)) 1231 minrow mincol rowincr colincr))
@@ -1123,25 +1238,25 @@ to each symbol."
1123 (cond 1238 (cond
1124 ((and (<= rowincr 0) (<= colincr 0)) 1239 ((and (<= rowincr 0) (<= colincr 0))
1125 ;;Deletion of rows and/or columns 1240 ;;Deletion of rows and/or columns
1126 (ses-dotimes-msg (row (- numrows minrow)) "Relocating variables..." 1241 (ses-dotimes-msg (row (- ses--numrows minrow)) "Relocating variables..."
1127 (setq myrow (+ row minrow)) 1242 (setq myrow (+ row minrow))
1128 (dotimes (col (- numcols mincol)) 1243 (dotimes (col (- ses--numcols mincol))
1129 (setq mycol (+ col mincol) 1244 (setq mycol (+ col mincol)
1130 xrow (- myrow rowincr) 1245 xrow (- myrow rowincr)
1131 xcol (- mycol colincr)) 1246 xcol (- mycol colincr))
1132 (if (and (< xrow numrows) (< xcol numcols)) 1247 (if (and (< xrow ses--numrows) (< xcol ses--numcols))
1133 (setq oldval (ses-cell-value xrow xcol)) 1248 (setq oldval (ses-cell-value xrow xcol))
1134 ;;Cell is off the end of the array 1249 ;;Cell is off the end of the array
1135 (setq oldval (symbol-value (ses-create-cell-symbol xrow xcol)))) 1250 (setq oldval (symbol-value (ses-create-cell-symbol xrow xcol))))
1136 (ses-set-cell myrow mycol 'value oldval)))) 1251 (ses-set-cell myrow mycol 'value oldval))))
1137 ((and (wholenump rowincr) (wholenump colincr)) 1252 ((and (wholenump rowincr) (wholenump colincr))
1138 ;;Insertion of rows and/or columns. Run the loop backwards. 1253 ;;Insertion of rows and/or columns. Run the loop backwards.
1139 (let ((disty (1- numrows)) 1254 (let ((disty (1- ses--numrows))
1140 (distx (1- numcols)) 1255 (distx (1- ses--numcols))
1141 myrow mycol) 1256 myrow mycol)
1142 (ses-dotimes-msg (row (- numrows minrow)) "Relocating variables..." 1257 (ses-dotimes-msg (row (- ses--numrows minrow)) "Relocating variables..."
1143 (setq myrow (- disty row)) 1258 (setq myrow (- disty row))
1144 (dotimes (col (- numcols mincol)) 1259 (dotimes (col (- ses--numcols mincol))
1145 (setq mycol (- distx col) 1260 (setq mycol (- distx col)
1146 xrow (- myrow rowincr) 1261 xrow (- myrow rowincr)
1147 xcol (- mycol colincr)) 1262 xcol (- mycol colincr))
@@ -1192,7 +1307,8 @@ cdr--its arglist."
1192 (if (not (eq major-mode 'ses-mode)) 1307 (if (not (eq major-mode 'ses-mode))
1193 ad-do-it 1308 ad-do-it
1194 ;;Here is some extra code for SES mode. 1309 ;;Here is some extra code for SES mode.
1195 (setq deferred-narrow (or deferred-narrow (< (point-max) (buffer-size)))) 1310 (setq ses--deferred-narrow
1311 (or ses--deferred-narrow (< (point-max) (buffer-size))))
1196 (widen) 1312 (widen)
1197 (condition-case x 1313 (condition-case x
1198 ad-do-it 1314 ad-do-it
@@ -1241,101 +1357,6 @@ stuff."
1241;;;; Startup for major mode 1357;;;; Startup for major mode
1242;;;---------------------------------------------------------------------------- 1358;;;----------------------------------------------------------------------------
1243 1359
1244(defun ses-build-mode-map ()
1245 "Set up `ses-mode-map', `ses-mode-print-map', and `ses-mode-edit-map' with
1246standard keymap bindings for SES."
1247 (message "Building mode map...")
1248 ;;;Define ses-mode-map
1249 (let ((keys '("\C-c\M-\C-l" ses-reconstruct-all
1250 "\C-c\C-l" ses-recalculate-all
1251 "\C-c\C-n" ses-renarrow-buffer
1252 "\C-c\C-c" ses-recalculate-cell
1253 "\C-c\M-\C-s" ses-sort-column
1254 "\C-c\M-\C-h" ses-read-header-row
1255 "\C-c\C-t" ses-truncate-cell
1256 "\C-c\C-j" ses-jump
1257 "\C-c\C-p" ses-read-default-printer
1258 "\M-\C-l" ses-reprint-all
1259 [?\S-\C-l] ses-reprint-all
1260 [header-line mouse-2] ses-sort-column-click))
1261 (newmap (make-sparse-keymap)))
1262 (while keys
1263 (define-key (1value newmap) (car keys) (cadr keys))
1264 (setq keys (cddr keys)))
1265 (setq ses-mode-map (1value newmap)))
1266 ;;;Define ses-mode-print-map
1267 (let ((keys '(;;At least three ways to define shift-tab--and some PC systems
1268 ;;won't generate it at all!
1269 [S-tab] backward-char
1270 [backtab] backward-char
1271 [S-iso-backtab] backward-char
1272 [S-iso-lefttab] backward-char
1273 [tab] ses-forward-or-insert
1274 "\C-i" ses-forward-or-insert ;Needed for ses-coverage.el?
1275 "\M-o" ses-insert-column
1276 "\C-o" ses-insert-row
1277 "\C-m" ses-edit-cell
1278 "\M-k" ses-delete-column
1279 "\M-y" ses-yank-pop
1280 "\C-k" ses-delete-row
1281 "\C-j" ses-append-row-jump-first-column
1282 "\M-h" ses-mark-row
1283 "\M-H" ses-mark-column
1284 "\C-d" ses-clear-cell-forward
1285 "\C-?" ses-clear-cell-backward
1286 "(" ses-read-cell
1287 "\"" ses-read-cell
1288 "'" ses-read-symbol
1289 "=" ses-edit-cell
1290 "j" ses-jump
1291 "p" ses-read-cell-printer
1292 "w" ses-set-column-width
1293 "x" ses-export-keymap
1294 "\M-p" ses-read-column-printer))
1295 (repl '(;;We'll replace these wherever they appear in the keymap
1296 clipboard-kill-region ses-kill-override
1297 end-of-line ses-end-of-line
1298 kill-line ses-delete-row
1299 kill-region ses-kill-override
1300 open-line ses-insert-row))
1301 (numeric "0123456789.-")
1302 (newmap (make-keymap)))
1303 ;;Get rid of printables
1304 (suppress-keymap (1value newmap) t)
1305 ;;These keys insert themselves as the beginning of a numeric value
1306 (dotimes (x (length (1value numeric)))
1307 (define-key (1value newmap)
1308 (substring (1value numeric) x (1+ x))
1309 'ses-read-cell))
1310 ;;Override these global functions wherever they're bound
1311 (while repl
1312 (substitute-key-definition (car repl) (cadr repl)
1313 (1value newmap)
1314 (current-global-map))
1315 (setq repl (cddr repl)))
1316 ;;Apparently substitute-key-definition doesn't catch this?
1317 (define-key (1value newmap) [(menu-bar) edit cut] 'ses-kill-override)
1318 ;;Define our other local keys
1319 (while keys
1320 (define-key (1value newmap) (car keys) (cadr keys))
1321 (setq keys (cddr keys)))
1322 ;;Keymap property wants the map as a function, not a variable
1323 (fset 'ses-mode-print-map (1value newmap))
1324 (setq ses-mode-print-map (1value newmap)))
1325 ;;;Define ses-mode-edit-map
1326 (let ((keys '("\C-c\C-r" ses-insert-range
1327 "\C-c\C-s" ses-insert-ses-range
1328 [S-mouse-3] ses-insert-range-click
1329 [C-S-mouse-3] ses-insert-ses-range-click
1330 "\M-\C-i" lisp-complete-symbol))
1331 (newmap (make-sparse-keymap)))
1332 (1value (set-keymap-parent (1value newmap) (1value minibuffer-local-map)))
1333 (while keys
1334 (define-key (1value newmap) (car keys) (cadr keys))
1335 (setq keys (cddr keys)))
1336 (setq ses-mode-edit-map (1value newmap)))
1337 (message nil))
1338
1339(defun ses-load () 1360(defun ses-load ()
1340 "Parse the current buffer and sets up buffer-local variables. Does not 1361 "Parse the current buffer and sets up buffer-local variables. Does not
1341execute cell formulas or print functions." 1362execute cell formulas or print functions."
@@ -1353,34 +1374,34 @@ execute cell formulas or print functions."
1353 (numberp (nth 2 params)) 1374 (numberp (nth 2 params))
1354 (> (nth 2 params) 0)) 1375 (> (nth 2 params) 0))
1355 (error "Invalid SES file")) 1376 (error "Invalid SES file"))
1356 (setq file-format (car params) 1377 (setq ses--file-format (car params)
1357 numrows (cadr params) 1378 ses--numrows (cadr params)
1358 numcols (nth 2 params)) 1379 ses--numcols (nth 2 params))
1359 (when (= file-format 1) 1380 (when (= ses--file-format 1)
1360 (let (buffer-undo-list) ;This is not undoable 1381 (let (buffer-undo-list) ;This is not undoable
1361 (ses-goto-data 'header-row) 1382 (ses-goto-data 'ses--header-row)
1362 (insert "(ses-header-row 0)\n") 1383 (insert "(ses-header-row 0)\n")
1363 (ses-set-parameter 'file-format 2) 1384 (ses-set-parameter 'ses--file-format 2)
1364 (message "Upgrading from SES-1 file format"))) 1385 (message "Upgrading from SES-1 file format")))
1365 (or (= file-format 2) 1386 (or (= ses--file-format 2)
1366 (error "This file needs a newer version of the SES library code.")) 1387 (error "This file needs a newer version of the SES library code."))
1367 (ses-create-cell-variable-range 0 (1- numrows) 0 (1- numcols)) 1388 (ses-create-cell-variable-range 0 (1- ses--numrows) 0 (1- ses--numcols))
1368 ;;Initialize cell array 1389 ;;Initialize cell array
1369 (setq cells (make-vector numrows nil)) 1390 (setq ses--cells (make-vector ses--numrows nil))
1370 (dotimes (row numrows) 1391 (dotimes (row ses--numrows)
1371 (aset cells row (make-vector numcols nil)))) 1392 (aset ses--cells row (make-vector ses--numcols nil))))
1372 ;;Skip over print area, which we assume is correct 1393 ;;Skip over print area, which we assume is correct
1373 (goto-char 1) 1394 (goto-char (point-min))
1374 (forward-line numrows) 1395 (forward-line ses--numrows)
1375 (or (looking-at ses-print-data-boundary) 1396 (or (looking-at ses-print-data-boundary)
1376 (error "Missing marker between print and data areas")) 1397 (error "Missing marker between print and data areas"))
1377 (forward-char (length ses-print-data-boundary)) 1398 (forward-char (length ses-print-data-boundary))
1378 ;;Initialize printer and symbol lists 1399 ;;Initialize printer and symbol lists
1379 (mapc 'ses-printer-record ses-standard-printer-functions) 1400 (mapc 'ses-printer-record ses-standard-printer-functions)
1380 (setq symbolic-formulas nil) 1401 (setq ses--symbolic-formulas nil)
1381 ;;Load cell definitions 1402 ;;Load cell definitions
1382 (dotimes (row numrows) 1403 (dotimes (row ses--numrows)
1383 (dotimes (col numcols) 1404 (dotimes (col ses--numcols)
1384 (let* ((x (read (current-buffer))) 1405 (let* ((x (read (current-buffer)))
1385 (rowcol (ses-sym-rowcol (car-safe (cdr-safe x))))) 1406 (rowcol (ses-sym-rowcol (car-safe (cdr-safe x)))))
1386 (or (and (looking-at "\n") 1407 (or (and (looking-at "\n")
@@ -1421,7 +1442,7 @@ execute cell formulas or print functions."
1421 ;;Check for overall newline count in definitions area 1442 ;;Check for overall newline count in definitions area
1422 (forward-line 3) 1443 (forward-line 3)
1423 (let ((start (point))) 1444 (let ((start (point)))
1424 (ses-goto-data 'numrows) 1445 (ses-goto-data 'ses--numrows)
1425 (or (= (point) start) 1446 (or (= (point) start)
1426 (error "Extraneous newlines someplace?")))) 1447 (error "Extraneous newlines someplace?"))))
1427 1448
@@ -1431,28 +1452,28 @@ execute cell formulas or print functions."
1431Narrows the buffer to show only the print area. Gives it `read-only' and 1452Narrows the buffer to show only the print area. Gives it `read-only' and
1432`intangible' properties. Sets up highlighting for current cell." 1453`intangible' properties. Sets up highlighting for current cell."
1433 (interactive) 1454 (interactive)
1434 (let ((end 1) 1455 (let ((end (point-min))
1435 (inhibit-read-only t) 1456 (inhibit-read-only t)
1436 (was-modified (buffer-modified-p)) 1457 (was-modified (buffer-modified-p))
1437 pos sym) 1458 pos sym)
1438 (ses-goto-data 0 0) ;;Include marker between print-area and data-area 1459 (ses-goto-data 0 0) ;;Include marker between print-area and data-area
1439 (set-text-properties (point) (buffer-size) nil) ;Delete garbage props 1460 (set-text-properties (point) (point-max) nil) ;Delete garbage props
1440 (mapc 'delete-overlay (overlays-in 1 (buffer-size))) 1461 (mapc 'delete-overlay (overlays-in (point-min) (point-max)))
1441 ;;The print area is read-only (except for our special commands) and uses a 1462 ;;The print area is read-only (except for our special commands) and uses a
1442 ;;special keymap. 1463 ;;special keymap.
1443 (put-text-property 1 (1- (point)) 'read-only 'ses) 1464 (put-text-property (point-min) (1- (point)) 'read-only 'ses)
1444 (put-text-property 1 (1- (point)) 'keymap 'ses-mode-print-map) 1465 (put-text-property (point-min) (1- (point)) 'keymap 'ses-mode-print-map)
1445 ;;For the beginning of the buffer, we want the read-only and keymap 1466 ;;For the beginning of the buffer, we want the read-only and keymap
1446 ;;attributes to be inherited from the first character 1467 ;;attributes to be inherited from the first character
1447 (put-text-property 1 2 'front-sticky t) 1468 (put-text-property (point-min) (1+ (point-min)) 'front-sticky t)
1448 ;;Create intangible properties, which also indicate which cell the text 1469 ;;Create intangible properties, which also indicate which cell the text
1449 ;;came from. 1470 ;;came from.
1450 (ses-dotimes-msg (row numrows) "Finding cells..." 1471 (ses-dotimes-msg (row ses--numrows) "Finding cells..."
1451 (dotimes (col numcols) 1472 (dotimes (col ses--numcols)
1452 (setq pos end 1473 (setq pos end
1453 sym (ses-cell-symbol row col)) 1474 sym (ses-cell-symbol row col))
1454 ;;Include skipped cells following this one 1475 ;;Include skipped cells following this one
1455 (while (and (< col (1- numcols)) 1476 (while (and (< col (1- ses--numcols))
1456 (eq (ses-cell-value row (1+ col)) '*skip*)) 1477 (eq (ses-cell-value row (1+ col)) '*skip*))
1457 (setq end (+ end (ses-col-width col) 1) 1478 (setq end (+ end (ses-col-width col) 1)
1458 col (1+ col))) 1479 col (1+ col)))
@@ -1465,8 +1486,8 @@ Narrows the buffer to show only the print area. Gives it `read-only' and
1465 (buffer-enable-undo))) 1486 (buffer-enable-undo)))
1466 ;;Create the underlining overlay. It's impossible for (point) to be 2, 1487 ;;Create the underlining overlay. It's impossible for (point) to be 2,
1467 ;;because column A must be at least 1 column wide. 1488 ;;because column A must be at least 1 column wide.
1468 (setq curcell-overlay (make-overlay 2 2)) 1489 (setq ses--curcell-overlay (make-overlay (1+ (point-min)) (1+ (point-min))))
1469 (overlay-put curcell-overlay 'face 'underline)) 1490 (overlay-put ses--curcell-overlay 'face 'underline))
1470 1491
1471(defun ses-cleanup () 1492(defun ses-cleanup ()
1472 "Cleanup when changing a buffer from SES mode to something else. Delete 1493 "Cleanup when changing a buffer from SES mode to something else. Delete
@@ -1476,15 +1497,16 @@ overlay, remove special text properties."
1476 (was-modified (buffer-modified-p)) 1497 (was-modified (buffer-modified-p))
1477 end) 1498 end)
1478 ;;Delete read-only, keymap, and intangible properties 1499 ;;Delete read-only, keymap, and intangible properties
1479 (set-text-properties 1 (point-max) nil) 1500 (set-text-properties (point-min) (point-max) nil)
1480 ;;Delete overlay 1501 ;;Delete overlay
1481 (mapc 'delete-overlay (overlays-in 1 (point-max))) 1502 (mapc 'delete-overlay (overlays-in (point-min) (point-max)))
1482 (unless was-modified 1503 (unless was-modified
1483 (set-buffer-modified-p nil)))) 1504 (set-buffer-modified-p nil))))
1484 1505
1485;;;###autoload 1506;;;###autoload
1486(defun ses-mode () 1507(defun ses-mode ()
1487 "Major mode for Simple Emacs Spreadsheet. See \"ses-readme.txt\" for more info. 1508 "Major mode for Simple Emacs Spreadsheet.
1509See \"ses-example.ses\" (in the etc data directory) for more info.
1488 1510
1489Key definitions: 1511Key definitions:
1490\\{ses-mode-map} 1512\\{ses-mode-map}
@@ -1493,8 +1515,8 @@ These key definitions are active only in the print area (the visible part):
1493These are active only in the minibuffer, when entering or editing a formula: 1515These are active only in the minibuffer, when entering or editing a formula:
1494\\{ses-mode-edit-map}" 1516\\{ses-mode-edit-map}"
1495 (interactive) 1517 (interactive)
1496 (unless (and (boundp 'deferred-narrow) 1518 (unless (and (boundp 'ses--deferred-narrow)
1497 (eq deferred-narrow 'ses-mode)) 1519 (eq ses--deferred-narrow 'ses-mode))
1498 (kill-all-local-variables) 1520 (kill-all-local-variables)
1499 (mapc 'make-local-variable ses-localvars) 1521 (mapc 'make-local-variable ses-localvars)
1500 (setq major-mode 'ses-mode 1522 (setq major-mode 'ses-mode
@@ -1505,23 +1527,22 @@ These are active only in the minibuffer, when entering or editing a formula:
1505 show-trailing-whitespace nil 1527 show-trailing-whitespace nil
1506 ;;Cell ranges do not work reasonably without this 1528 ;;Cell ranges do not work reasonably without this
1507 transient-mark-mode t) 1529 transient-mark-mode t)
1508 (unless (and ses-mode-map ses-mode-print-map ses-mode-edit-map)
1509 (ses-build-mode-map))
1510 (1value (add-hook 'change-major-mode-hook 'ses-cleanup nil t)) 1530 (1value (add-hook 'change-major-mode-hook 'ses-cleanup nil t))
1511 (1value (add-hook 'before-revert-hook 'ses-cleanup nil t)) 1531 (1value (add-hook 'before-revert-hook 'ses-cleanup nil t))
1512 (setq curcell nil 1532 (setq ses--curcell nil
1513 deferred-recalc nil 1533 ses--deferred-recalc nil
1514 deferred-write nil 1534 ses--deferred-write nil
1515 header-hscroll -1 ;Flag for "initial recalc needed" 1535 ses--header-hscroll -1 ;Flag for "initial recalc needed"
1516 header-line-format '(:eval (progn 1536 header-line-format '(:eval (progn
1517 (when (/= (window-hscroll) 1537 (when (/= (window-hscroll)
1518 header-hscroll) 1538 ses--header-hscroll)
1519 ;;Reset header-hscroll first, to 1539 ;;Reset ses--header-hscroll first, to
1520 ;;avoid recursion problems when 1540 ;;avoid recursion problems when
1521 ;;debugging ses-create-header-string 1541 ;;debugging ses-create-header-string
1522 (setq header-hscroll (window-hscroll)) 1542 (setq ses--header-hscroll
1523 (ses-create-header-string)) 1543 (window-hscroll))
1524 header-string))) 1544 (ses-create-header-string))
1545 ses--header-string)))
1525 (let ((was-empty (zerop (buffer-size))) 1546 (let ((was-empty (zerop (buffer-size)))
1526 (was-modified (buffer-modified-p))) 1547 (was-modified (buffer-modified-p)))
1527 (save-excursion 1548 (save-excursion
@@ -1531,20 +1552,20 @@ These are active only in the minibuffer, when entering or editing a formula:
1531 (ses-load) 1552 (ses-load)
1532 (ses-setup)) 1553 (ses-setup))
1533 (when was-empty 1554 (when was-empty
1534 (unless (equal ses-initial-default-printer (1value default-printer)) 1555 (unless (equal ses-initial-default-printer (1value ses--default-printer))
1535 (1value (ses-read-default-printer ses-initial-default-printer))) 1556 (1value (ses-read-default-printer ses-initial-default-printer)))
1536 (unless (= ses-initial-column-width (1value (ses-col-width 0))) 1557 (unless (= ses-initial-column-width (1value (ses-col-width 0)))
1537 (1value (ses-set-column-width 0 ses-initial-column-width))) 1558 (1value (ses-set-column-width 0 ses-initial-column-width)))
1538 (ses-set-curcell) 1559 (ses-set-curcell)
1539 (if (> (car ses-initial-size) (1value numrows)) 1560 (if (> (car ses-initial-size) (1value ses--numrows))
1540 (1value (ses-insert-row (1- (car ses-initial-size))))) 1561 (1value (ses-insert-row (1- (car ses-initial-size)))))
1541 (if (> (cdr ses-initial-size) (1value numcols)) 1562 (if (> (cdr ses-initial-size) (1value ses--numcols))
1542 (1value (ses-insert-column (1- (cdr ses-initial-size))))) 1563 (1value (ses-insert-column (1- (cdr ses-initial-size)))))
1543 (ses-write-cells) 1564 (ses-write-cells)
1544 (set-buffer-modified-p was-modified) 1565 (restore-buffer-modified-p was-modified)
1545 (buffer-disable-undo) 1566 (buffer-disable-undo)
1546 (buffer-enable-undo) 1567 (buffer-enable-undo)
1547 (goto-char 1))) 1568 (goto-char (point-min))))
1548 (use-local-map ses-mode-map) 1569 (use-local-map ses-mode-map)
1549 ;;Set the deferred narrowing flag (we can't narrow until after 1570 ;;Set the deferred narrowing flag (we can't narrow until after
1550 ;;after-find-file completes). If .ses is on the auto-load alist and the 1571 ;;after-find-file completes). If .ses is on the auto-load alist and the
@@ -1552,7 +1573,7 @@ These are active only in the minibuffer, when entering or editing a formula:
1552 ;;a special flag to detect this (will be reset by ses-command-hook). 1573 ;;a special flag to detect this (will be reset by ses-command-hook).
1553 ;;For find-alternate-file, post-command-hook doesn't get run for some 1574 ;;For find-alternate-file, post-command-hook doesn't get run for some
1554 ;;reason, so use an idle timer to make sure. 1575 ;;reason, so use an idle timer to make sure.
1555 (setq deferred-narrow 'ses-mode) 1576 (setq ses--deferred-narrow 'ses-mode)
1556 (1value (add-hook 'post-command-hook 'ses-command-hook nil t)) 1577 (1value (add-hook 'post-command-hook 'ses-command-hook nil t))
1557 (run-with-idle-timer 0.01 nil 'ses-command-hook) 1578 (run-with-idle-timer 0.01 nil 'ses-command-hook)
1558 (run-hooks 'ses-mode-hook))) 1579 (run-hooks 'ses-mode-hook)))
@@ -1566,50 +1587,51 @@ writes that have been deferred. If buffer-narrowing has been deferred,
1566narrows the buffer now." 1587narrows the buffer now."
1567 (condition-case err 1588 (condition-case err
1568 (when (eq major-mode 'ses-mode) ;Otherwise, not our buffer anymore 1589 (when (eq major-mode 'ses-mode) ;Otherwise, not our buffer anymore
1569 (when deferred-recalc 1590 (when ses--deferred-recalc
1570 ;;We reset the deferred list before starting on the recalc -- in case 1591 ;;We reset the deferred list before starting on the recalc -- in case
1571 ;;of error, we don't want to retry the recalc after every keystroke! 1592 ;;of error, we don't want to retry the recalc after every keystroke!
1572 (let ((old deferred-recalc)) 1593 (let ((old ses--deferred-recalc))
1573 (setq deferred-recalc nil) 1594 (setq ses--deferred-recalc nil)
1574 (ses-update-cells old))) 1595 (ses-update-cells old)))
1575 (if deferred-write 1596 (if ses--deferred-write
1576 ;;We don't reset the deferred list before starting -- the most 1597 ;;We don't reset the deferred list before starting -- the most
1577 ;;likely error is keyboard-quit, and we do want to keep trying 1598 ;;likely error is keyboard-quit, and we do want to keep trying
1578 ;;these writes after a quit. 1599 ;;these writes after a quit.
1579 (ses-write-cells)) 1600 (ses-write-cells))
1580 (when deferred-narrow 1601 (when ses--deferred-narrow
1581 ;;We're not allowed to narrow the buffer until after-find-file has 1602 ;;We're not allowed to narrow the buffer until after-find-file has
1582 ;;read the local variables at the end of the file. Now it's safe to 1603 ;;read the local variables at the end of the file. Now it's safe to
1583 ;;do the narrowing. 1604 ;;do the narrowing.
1584 (save-excursion 1605 (save-excursion
1585 (goto-char 1) 1606 (goto-char (point-min))
1586 (forward-line numrows) 1607 (forward-line ses--numrows)
1587 (narrow-to-region 1 (point))) 1608 (narrow-to-region (point-min) (point)))
1588 (setq deferred-narrow nil)) 1609 (setq ses--deferred-narrow nil))
1589 ;;Update the modeline 1610 ;;Update the modeline
1590 (let ((oldcell curcell)) 1611 (let ((oldcell ses--curcell))
1591 (ses-set-curcell) 1612 (ses-set-curcell)
1592 (unless (eq curcell oldcell) 1613 (unless (eq ses--curcell oldcell)
1593 (cond 1614 (cond
1594 ((not curcell) 1615 ((not ses--curcell)
1595 (setq mode-line-process nil)) 1616 (setq mode-line-process nil))
1596 ((atom curcell) 1617 ((atom ses--curcell)
1597 (setq mode-line-process (list " cell " (symbol-name curcell)))) 1618 (setq mode-line-process (list " cell "
1619 (symbol-name ses--curcell))))
1598 (t 1620 (t
1599 (setq mode-line-process (list " range " 1621 (setq mode-line-process (list " range "
1600 (symbol-name (car curcell)) 1622 (symbol-name (car ses--curcell))
1601 "-" 1623 "-"
1602 (symbol-name (cdr curcell)))))) 1624 (symbol-name (cdr ses--curcell))))))
1603 (force-mode-line-update))) 1625 (force-mode-line-update)))
1604 ;;Use underline overlay for single-cells only, turn off otherwise 1626 ;;Use underline overlay for single-cells only, turn off otherwise
1605 (if (listp curcell) 1627 (if (listp ses--curcell)
1606 (move-overlay curcell-overlay 2 2) 1628 (move-overlay ses--curcell-overlay 2 2)
1607 (let ((next (next-single-property-change (point) 'intangible))) 1629 (let ((next (next-single-property-change (point) 'intangible)))
1608 (move-overlay curcell-overlay (point) (1- next)))) 1630 (move-overlay ses--curcell-overlay (point) (1- next))))
1609 (when (not (pos-visible-in-window-p)) 1631 (when (not (pos-visible-in-window-p))
1610 ;;Scrolling will happen later 1632 ;;Scrolling will happen later
1611 (run-with-idle-timer 0.01 nil 'ses-command-hook) 1633 (run-with-idle-timer 0.01 nil 'ses-command-hook)
1612 (setq curcell t))) 1634 (setq ses--curcell t)))
1613 ;;Prevent errors in this post-command-hook from silently erasing the hook! 1635 ;;Prevent errors in this post-command-hook from silently erasing the hook!
1614 (error 1636 (error
1615 (unless executing-kbd-macro 1637 (unless executing-kbd-macro
@@ -1633,23 +1655,23 @@ narrows the buffer now."
1633 (+ left-fringe left-scrollbar))) 1655 (+ left-fringe left-scrollbar)))
1634 1656
1635(defun ses-create-header-string () 1657(defun ses-create-header-string ()
1636 "Sets up `header-string' as the buffer's header line, based on the 1658 "Sets up `ses--header-string' as the buffer's header line, based on the
1637current set of columns and window-scroll position." 1659current set of columns and window-scroll position."
1638 (let* ((left-offset (ses-header-string-left-offset)) 1660 (let* ((left-offset (ses-header-string-left-offset))
1639 (totwidth (- left-offset (window-hscroll))) 1661 (totwidth (- left-offset (window-hscroll)))
1640 result width result x) 1662 result width result x)
1641 ;;Leave room for the left-side fringe and scrollbar 1663 ;;Leave room for the left-side fringe and scrollbar
1642 (push (make-string left-offset ? ) result) 1664 (push (make-string left-offset ? ) result)
1643 (dotimes (col numcols) 1665 (dotimes (col ses--numcols)
1644 (setq width (ses-col-width col) 1666 (setq width (ses-col-width col)
1645 totwidth (+ totwidth width 1)) 1667 totwidth (+ totwidth width 1))
1646 (if (= totwidth (+ left-offset 1)) 1668 (if (= totwidth (+ left-offset 1))
1647 ;;Scrolled so intercolumn space is leftmost 1669 ;;Scrolled so intercolumn space is leftmost
1648 (push " " result)) 1670 (push " " result))
1649 (when (> totwidth (+ left-offset 1)) 1671 (when (> totwidth (+ left-offset 1))
1650 (if (> header-row 0) 1672 (if (> ses--header-row 0)
1651 (save-excursion 1673 (save-excursion
1652 (ses-goto-print (1- header-row) col) 1674 (ses-goto-print (1- ses--header-row) col)
1653 (setq x (buffer-substring-no-properties (point) 1675 (setq x (buffer-substring-no-properties (point)
1654 (+ (point) width))) 1676 (+ (point) width)))
1655 (if (>= width (- totwidth left-offset)) 1677 (if (>= width (- totwidth left-offset))
@@ -1665,11 +1687,11 @@ current set of columns and window-scroll position."
1665 ;;Coverage test ignores properties, thinks this is always a space! 1687 ;;Coverage test ignores properties, thinks this is always a space!
1666 (push (1value (propertize " " 'display `((space :align-to ,totwidth)))) 1688 (push (1value (propertize " " 'display `((space :align-to ,totwidth))))
1667 result))) 1689 result)))
1668 (if (> header-row 0) 1690 (if (> ses--header-row 0)
1669 (push (propertize (format " [row %d]" header-row) 1691 (push (propertize (format " [row %d]" ses--header-row)
1670 'display '((height (- 1)))) 1692 'display '((height (- 1))))
1671 result)) 1693 result))
1672 (setq header-string (apply 'concat (nreverse result))))) 1694 (setq ses--header-string (apply 'concat (nreverse result)))))
1673 1695
1674 1696
1675;;;---------------------------------------------------------------------------- 1697;;;----------------------------------------------------------------------------
@@ -1697,23 +1719,23 @@ print area if NONARROW is nil."
1697 (interactive "*P") 1719 (interactive "*P")
1698 (widen) 1720 (widen)
1699 (unless nonarrow 1721 (unless nonarrow
1700 (setq deferred-narrow t)) 1722 (setq ses--deferred-narrow t))
1701 (let ((startcell (get-text-property (point) 'intangible)) 1723 (let ((startcell (get-text-property (point) 'intangible))
1702 (inhibit-read-only t)) 1724 (inhibit-read-only t))
1703 (ses-begin-change) 1725 (ses-begin-change)
1704 (goto-char 1) 1726 (goto-char (point-min))
1705 (search-forward ses-print-data-boundary) 1727 (search-forward ses-print-data-boundary)
1706 (backward-char (length ses-print-data-boundary)) 1728 (backward-char (length ses-print-data-boundary))
1707 (delete-region 1 (point)) 1729 (delete-region (point-min) (point))
1708 ;;Insert all blank lines before printing anything, so ses-print-cell can 1730 ;;Insert all blank lines before printing anything, so ses-print-cell can
1709 ;;find the data area when inserting or deleting *skip* values for cells 1731 ;;find the data area when inserting or deleting *skip* values for cells
1710 (dotimes (row numrows) 1732 (dotimes (row ses--numrows)
1711 (insert-and-inherit blank-line)) 1733 (insert-and-inherit ses--blank-line))
1712 (ses-dotimes-msg (row numrows) "Reprinting..." 1734 (ses-dotimes-msg (row ses--numrows) "Reprinting..."
1713 (if (eq (ses-cell-value row 0) '*skip*) 1735 (if (eq (ses-cell-value row 0) '*skip*)
1714 ;;Column deletion left a dangling skip 1736 ;;Column deletion left a dangling skip
1715 (ses-set-cell row 0 'value nil)) 1737 (ses-set-cell row 0 'value nil))
1716 (dotimes (col numcols) 1738 (dotimes (col ses--numcols)
1717 (ses-print-cell row col)) 1739 (ses-print-cell row col))
1718 (beginning-of-line 2)) 1740 (beginning-of-line 2))
1719 (ses-jump-safe startcell))) 1741 (ses-jump-safe startcell)))
@@ -1730,12 +1752,12 @@ to are recalculated first."
1730 (ses-begin-change) 1752 (ses-begin-change)
1731 (let (sig) 1753 (let (sig)
1732 (setq ses-start-time (float-time)) 1754 (setq ses-start-time (float-time))
1733 (if (atom curcell) 1755 (if (atom ses--curcell)
1734 (setq sig (ses-sym-rowcol curcell) 1756 (setq sig (ses-sym-rowcol ses--curcell)
1735 sig (ses-calculate-cell (car sig) (cdr sig) t)) 1757 sig (ses-calculate-cell (car sig) (cdr sig) t))
1736 ;;First, recalculate all cells that don't refer to other cells and 1758 ;;First, recalculate all cells that don't refer to other cells and
1737 ;;produce a list of cells with references. 1759 ;;produce a list of cells with references.
1738 (ses-dorange curcell 1760 (ses-dorange ses--curcell
1739 (ses-time-check "Recalculating... %s" '(ses-cell-symbol row col)) 1761 (ses-time-check "Recalculating... %s" '(ses-cell-symbol row col))
1740 (condition-case nil 1762 (condition-case nil
1741 (progn 1763 (progn
@@ -1745,26 +1767,27 @@ to are recalculated first."
1745 (setq sig (ses-calculate-cell row col t))) 1767 (setq sig (ses-calculate-cell row col t)))
1746 (wrong-type-argument 1768 (wrong-type-argument
1747 ;;The formula contains a reference 1769 ;;The formula contains a reference
1748 (add-to-list 'deferred-recalc (ses-cell-symbol row col)))))) 1770 (add-to-list 'ses--deferred-recalc (ses-cell-symbol row col))))))
1749 ;;Do the update now, so we can force recalculation 1771 ;;Do the update now, so we can force recalculation
1750 (let ((x deferred-recalc)) 1772 (let ((x ses--deferred-recalc))
1751 (setq deferred-recalc nil) 1773 (setq ses--deferred-recalc nil)
1752 (condition-case hold 1774 (condition-case hold
1753 (ses-update-cells x t) 1775 (ses-update-cells x t)
1754 (error (setq sig hold)))) 1776 (error (setq sig hold))))
1755 (cond 1777 (cond
1756 (sig 1778 (sig
1757 (message (error-message-string sig))) 1779 (message (error-message-string sig)))
1758 ((consp curcell) 1780 ((consp ses--curcell)
1759 (message " ")) 1781 (message " "))
1760 (t 1782 (t
1761 (princ (symbol-value curcell)))))) 1783 (princ (symbol-value ses--curcell))))))
1762 1784
1763(defun ses-recalculate-all () 1785(defun ses-recalculate-all ()
1764 "Recalculate and reprint all cells." 1786 "Recalculate and reprint all cells."
1765 (interactive "*") 1787 (interactive "*")
1766 (let ((startcell (get-text-property (point) 'intangible)) 1788 (let ((startcell (get-text-property (point) 'intangible))
1767 (curcell (cons 'A1 (ses-cell-symbol (1- numrows) (1- numcols))))) 1789 (ses--curcell (cons 'A1 (ses-cell-symbol (1- ses--numrows)
1790 (1- ses--numcols)))))
1768 (ses-recalculate-cell) 1791 (ses-recalculate-cell)
1769 (ses-jump-safe startcell))) 1792 (ses-jump-safe startcell)))
1770 1793
@@ -1773,10 +1796,10 @@ to are recalculated first."
1773cells." 1796cells."
1774 (interactive "*") 1797 (interactive "*")
1775 (ses-check-curcell) 1798 (ses-check-curcell)
1776 (let* ((rowcol (ses-sym-rowcol curcell)) 1799 (let* ((rowcol (ses-sym-rowcol ses--curcell))
1777 (row (car rowcol)) 1800 (row (car rowcol))
1778 (col (cdr rowcol))) 1801 (col (cdr rowcol)))
1779 (when (and (< col (1- numcols)) ;;Last column can't spill over, anyway 1802 (when (and (< col (1- ses--numcols)) ;;Last column can't spill over, anyway
1780 (eq (ses-cell-value row (1+ col)) '*skip*)) 1803 (eq (ses-cell-value row (1+ col)) '*skip*))
1781 ;;This cell has spill-over. We'll momentarily pretend the following 1804 ;;This cell has spill-over. We'll momentarily pretend the following
1782 ;;cell has a `t' in it. 1805 ;;cell has a `t' in it.
@@ -1793,12 +1816,12 @@ cells."
1793 ;;Reconstruct reference lists. 1816 ;;Reconstruct reference lists.
1794 (let (refs x yrow ycol) 1817 (let (refs x yrow ycol)
1795 ;;Delete old reference lists 1818 ;;Delete old reference lists
1796 (ses-dotimes-msg (row numrows) "Deleting references..." 1819 (ses-dotimes-msg (row ses--numrows) "Deleting references..."
1797 (dotimes (col numcols) 1820 (dotimes (col ses--numcols)
1798 (ses-set-cell row col 'references nil))) 1821 (ses-set-cell row col 'references nil)))
1799 ;;Create new reference lists 1822 ;;Create new reference lists
1800 (ses-dotimes-msg (row numrows) "Computing references..." 1823 (ses-dotimes-msg (row ses--numrows) "Computing references..."
1801 (dotimes (col numcols) 1824 (dotimes (col ses--numcols)
1802 (dolist (ref (ses-formula-references (ses-cell-formula row col))) 1825 (dolist (ref (ses-formula-references (ses-cell-formula row col)))
1803 (setq x (ses-sym-rowcol ref) 1826 (setq x (ses-sym-rowcol ref)
1804 yrow (car x) 1827 yrow (car x)
@@ -1808,35 +1831,35 @@ cells."
1808 (ses-cell-references yrow ycol))))))) 1831 (ses-cell-references yrow ycol)))))))
1809 ;;Delete everything and reconstruct basic data area 1832 ;;Delete everything and reconstruct basic data area
1810 (if (< (point-max) (buffer-size)) 1833 (if (< (point-max) (buffer-size))
1811 (setq deferred-narrow t)) 1834 (setq ses--deferred-narrow t))
1812 (widen) 1835 (widen)
1813 (let ((inhibit-read-only t)) 1836 (let ((inhibit-read-only t))
1814 (goto-char (point-max)) 1837 (goto-char (point-max))
1815 (if (search-backward ";;; Local Variables:\n" nil t) 1838 (if (search-backward ";;; Local Variables:\n" nil t)
1816 (delete-region 1 (point)) 1839 (delete-region (point-min) (point))
1817 ;;Buffer is quite screwed up - can't even save the user-specified locals 1840 ;;Buffer is quite screwed up - can't even save the user-specified locals
1818 (delete-region 1 (point-max)) 1841 (delete-region (point-min) (point-max))
1819 (insert ses-initial-file-trailer) 1842 (insert ses-initial-file-trailer)
1820 (goto-char 1)) 1843 (goto-char (point-min)))
1821 ;;Create a blank display area 1844 ;;Create a blank display area
1822 (dotimes (row numrows) 1845 (dotimes (row ses--numrows)
1823 (insert blank-line)) 1846 (insert ses--blank-line))
1824 (insert ses-print-data-boundary) 1847 (insert ses-print-data-boundary)
1825 ;;Placeholders for cell data 1848 ;;Placeholders for cell data
1826 (insert (make-string (* numrows (1+ numcols)) ?\n)) 1849 (insert (make-string (* ses--numrows (1+ ses--numcols)) ?\n))
1827 ;;Placeholders for col-widths, col-printers, default-printer, header-row 1850 ;;Placeholders for col-widths, col-printers, default-printer, header-row
1828 (insert "\n\n\n\n") 1851 (insert "\n\n\n\n")
1829 (insert ses-initial-global-parameters)) 1852 (insert ses-initial-global-parameters))
1830 (ses-set-parameter 'column-widths column-widths) 1853 (ses-set-parameter 'ses--col-widths ses--col-widths)
1831 (ses-set-parameter 'col-printers col-printers) 1854 (ses-set-parameter 'ses--col-printers ses--col-printers)
1832 (ses-set-parameter 'default-printer default-printer) 1855 (ses-set-parameter 'ses--default-printer ses--default-printer)
1833 (ses-set-parameter 'header-row header-row) 1856 (ses-set-parameter 'ses--header-row ses--header-row)
1834 (ses-set-parameter 'numrows numrows) 1857 (ses-set-parameter 'ses--numrows ses--numrows)
1835 (ses-set-parameter 'numcols numcols) 1858 (ses-set-parameter 'ses--numcols ses--numcols)
1836 ;;Keep our old narrowing 1859 ;;Keep our old narrowing
1837 (ses-setup) 1860 (ses-setup)
1838 (ses-recalculate-all) 1861 (ses-recalculate-all)
1839 (goto-char 1)) 1862 (goto-char (point-min)))
1840 1863
1841 1864
1842;;;---------------------------------------------------------------------------- 1865;;;----------------------------------------------------------------------------
@@ -1850,7 +1873,7 @@ cell formula was unsafe and user declined confirmation."
1850 (progn 1873 (progn
1851 (barf-if-buffer-read-only) 1874 (barf-if-buffer-read-only)
1852 (ses-check-curcell) 1875 (ses-check-curcell)
1853 (let* ((rowcol (ses-sym-rowcol curcell)) 1876 (let* ((rowcol (ses-sym-rowcol ses--curcell))
1854 (row (car rowcol)) 1877 (row (car rowcol))
1855 (col (cdr rowcol)) 1878 (col (cdr rowcol))
1856 (formula (ses-cell-formula row col)) 1879 (formula (ses-cell-formula row col))
@@ -1864,7 +1887,7 @@ cell formula was unsafe and user declined confirmation."
1864 ;;Position cursor inside close-quote 1887 ;;Position cursor inside close-quote
1865 (setq initial (cons initial (length initial)))) 1888 (setq initial (cons initial (length initial))))
1866 (list row col 1889 (list row col
1867 (read-from-minibuffer (format "Cell %s: " curcell) 1890 (read-from-minibuffer (format "Cell %s: " ses--curcell)
1868 initial 1891 initial
1869 ses-mode-edit-map 1892 ses-mode-edit-map
1870 t ;Convert to Lisp object 1893 t ;Convert to Lisp object
@@ -1878,7 +1901,7 @@ cell formula was unsafe and user declined confirmation."
1878 "Self-insert for initial character of cell function." 1901 "Self-insert for initial character of cell function."
1879 (interactive 1902 (interactive
1880 (let ((initial (this-command-keys)) 1903 (let ((initial (this-command-keys))
1881 (rowcol (progn (ses-check-curcell) (ses-sym-rowcol curcell)))) 1904 (rowcol (progn (ses-check-curcell) (ses-sym-rowcol ses--curcell))))
1882 (barf-if-buffer-read-only) 1905 (barf-if-buffer-read-only)
1883 (if (string= initial "\"") 1906 (if (string= initial "\"")
1884 (setq initial "\"\"") ;Enter a string 1907 (setq initial "\"\"") ;Enter a string
@@ -1886,7 +1909,7 @@ cell formula was unsafe and user declined confirmation."
1886 (setq initial "()"))) ;Enter a formula list 1909 (setq initial "()"))) ;Enter a formula list
1887 (list (car rowcol) 1910 (list (car rowcol)
1888 (cdr rowcol) 1911 (cdr rowcol)
1889 (read-from-minibuffer (format "Cell %s: " curcell) 1912 (read-from-minibuffer (format "Cell %s: " ses--curcell)
1890 (cons initial 2) 1913 (cons initial 2)
1891 ses-mode-edit-map 1914 ses-mode-edit-map
1892 t ;Convert to Lisp object 1915 t ;Convert to Lisp object
@@ -1900,11 +1923,11 @@ cell formula was unsafe and user declined confirmation."
1900 "Self-insert for a symbol as a cell formula. The set of all symbols that 1923 "Self-insert for a symbol as a cell formula. The set of all symbols that
1901have been used as formulas in this spreadsheet is available for completions." 1924have been used as formulas in this spreadsheet is available for completions."
1902 (interactive 1925 (interactive
1903 (let ((rowcol (progn (ses-check-curcell) (ses-sym-rowcol curcell))) 1926 (let ((rowcol (progn (ses-check-curcell) (ses-sym-rowcol ses--curcell)))
1904 newval) 1927 newval)
1905 (barf-if-buffer-read-only) 1928 (barf-if-buffer-read-only)
1906 (setq newval (completing-read (format "Cell %s ': " curcell) 1929 (setq newval (completing-read (format "Cell %s ': " ses--curcell)
1907 symbolic-formulas)) 1930 ses--symbolic-formulas))
1908 (list (car rowcol) 1931 (list (car rowcol)
1909 (cdr rowcol) 1932 (cdr rowcol)
1910 (if (string= newval "") 1933 (if (string= newval "")
@@ -1925,7 +1948,7 @@ With prefix, deletes several cells."
1925 (ses-begin-change) 1948 (ses-begin-change)
1926 (dotimes (x count) 1949 (dotimes (x count)
1927 (ses-set-curcell) 1950 (ses-set-curcell)
1928 (let ((rowcol (ses-sym-rowcol curcell))) 1951 (let ((rowcol (ses-sym-rowcol ses--curcell)))
1929 (or rowcol (signal 'end-of-buffer nil)) 1952 (or rowcol (signal 'end-of-buffer nil))
1930 (ses-clear-cell (car rowcol) (cdr rowcol))) 1953 (ses-clear-cell (car rowcol) (cdr rowcol)))
1931 (forward-char 1)))) 1954 (forward-char 1))))
@@ -1941,7 +1964,7 @@ cells."
1941 (dotimes (x count) 1964 (dotimes (x count)
1942 (backward-char 1) ;Will signal 'beginning-of-buffer if appropriate 1965 (backward-char 1) ;Will signal 'beginning-of-buffer if appropriate
1943 (ses-set-curcell) 1966 (ses-set-curcell)
1944 (let ((rowcol (ses-sym-rowcol curcell))) 1967 (let ((rowcol (ses-sym-rowcol ses--curcell)))
1945 (ses-clear-cell (car rowcol) (cdr rowcol)))))) 1968 (ses-clear-cell (car rowcol) (cdr rowcol))))))
1946 1969
1947 1970
@@ -1986,11 +2009,11 @@ latter two cases, the function's result should be either a string (will be
1986right-justified) or a list of one string (will be left-justified)." 2009right-justified) or a list of one string (will be left-justified)."
1987 (interactive 2010 (interactive
1988 (let ((default t) 2011 (let ((default t)
1989 prompt) 2012 prompt x)
1990 (ses-check-curcell 'range) 2013 (ses-check-curcell 'range)
1991 ;;Default is none if not all cells in range have same printer 2014 ;;Default is none if not all cells in range have same printer
1992 (catch 'ses-read-cell-printer 2015 (catch 'ses-read-cell-printer
1993 (ses-dorange curcell 2016 (ses-dorange ses--curcell
1994 (setq x (ses-cell-printer row col)) 2017 (setq x (ses-cell-printer row col))
1995 (if (eq (car-safe x) 'ses-safe-printer) 2018 (if (eq (car-safe x) 'ses-safe-printer)
1996 (setq x (cadr x))) 2019 (setq x (cadr x)))
@@ -2000,10 +2023,11 @@ right-justified) or a list of one string (will be left-justified)."
2000 ;;Range contains differing printer functions 2023 ;;Range contains differing printer functions
2001 (setq default t) 2024 (setq default t)
2002 (throw 'ses-read-cell-printer t))))) 2025 (throw 'ses-read-cell-printer t)))))
2003 (list (ses-read-printer (format "Cell %S printer: " curcell) default)))) 2026 (list (ses-read-printer (format "Cell %S printer: " ses--curcell)
2027 default))))
2004 (unless (eq newval t) 2028 (unless (eq newval t)
2005 (ses-begin-change) 2029 (ses-begin-change)
2006 (ses-dorange curcell 2030 (ses-dorange ses--curcell
2007 (ses-set-cell row col 'printer newval) 2031 (ses-set-cell row col 'printer newval)
2008 (ses-print-cell row col)))) 2032 (ses-print-cell row col))))
2009 2033
@@ -2011,7 +2035,7 @@ right-justified) or a list of one string (will be left-justified)."
2011 "Set the printer function for the current column. See 2035 "Set the printer function for the current column. See
2012`ses-read-cell-printer' for input forms." 2036`ses-read-cell-printer' for input forms."
2013 (interactive 2037 (interactive
2014 (let ((col (cdr (ses-sym-rowcol curcell)))) 2038 (let ((col (cdr (ses-sym-rowcol ses--curcell))))
2015 (ses-check-curcell) 2039 (ses-check-curcell)
2016 (list col (ses-read-printer (format "Column %s printer: " 2040 (list col (ses-read-printer (format "Column %s printer: "
2017 (ses-column-letter col)) 2041 (ses-column-letter col))
@@ -2019,19 +2043,19 @@ right-justified) or a list of one string (will be left-justified)."
2019 2043
2020 (unless (eq newval t) 2044 (unless (eq newval t)
2021 (ses-begin-change) 2045 (ses-begin-change)
2022 (ses-set-parameter 'col-printers newval col) 2046 (ses-set-parameter 'ses--col-printers newval col)
2023 (save-excursion 2047 (save-excursion
2024 (dotimes (row numrows) 2048 (dotimes (row ses--numrows)
2025 (ses-print-cell row col))))) 2049 (ses-print-cell row col)))))
2026 2050
2027(defun ses-read-default-printer (newval) 2051(defun ses-read-default-printer (newval)
2028 "Set the default printer function for cells that have no other. See 2052 "Set the default printer function for cells that have no other. See
2029`ses-read-cell-printer' for input forms." 2053`ses-read-cell-printer' for input forms."
2030 (interactive 2054 (interactive
2031 (list (ses-read-printer "Default printer: " default-printer))) 2055 (list (ses-read-printer "Default printer: " ses--default-printer)))
2032 (unless (eq newval t) 2056 (unless (eq newval t)
2033 (ses-begin-change) 2057 (ses-begin-change)
2034 (ses-set-parameter 'default-printer newval) 2058 (ses-set-parameter 'ses--default-printer newval)
2035 (ses-reprint-all t))) 2059 (ses-reprint-all t)))
2036 2060
2037 2061
@@ -2048,47 +2072,47 @@ before current one."
2048 (ses-begin-change) 2072 (ses-begin-change)
2049 (let ((inhibit-quit t) 2073 (let ((inhibit-quit t)
2050 (inhibit-read-only t) 2074 (inhibit-read-only t)
2051 (row (or (car (ses-sym-rowcol curcell)) numrows)) 2075 (row (or (car (ses-sym-rowcol ses--curcell)) ses--numrows))
2052 newrow) 2076 newrow)
2053 ;;Create a new set of cell-variables 2077 ;;Create a new set of cell-variables
2054 (ses-create-cell-variable-range numrows (+ numrows count -1) 2078 (ses-create-cell-variable-range ses--numrows (+ ses--numrows count -1)
2055 0 (1- numcols)) 2079 0 (1- ses--numcols))
2056 (ses-set-parameter 'numrows (+ numrows count)) 2080 (ses-set-parameter 'ses--numrows (+ ses--numrows count))
2057 ;;Insert each row 2081 ;;Insert each row
2058 (ses-goto-print row 0) 2082 (ses-goto-print row 0)
2059 (ses-dotimes-msg (x count) "Inserting row..." 2083 (ses-dotimes-msg (x count) "Inserting row..."
2060 ;;Create a row of empty cells. The `symbol' fields will be set by 2084 ;;Create a row of empty cells. The `symbol' fields will be set by
2061 ;;the call to ses-relocate-all. 2085 ;;the call to ses-relocate-all.
2062 (setq newrow (make-vector numcols nil)) 2086 (setq newrow (make-vector ses--numcols nil))
2063 (dotimes (col numcols) 2087 (dotimes (col ses--numcols)
2064 (aset newrow col (make-vector ses-cell-size nil))) 2088 (aset newrow col (make-vector ses-cell-size nil)))
2065 (setq cells (ses-vector-insert cells row newrow)) 2089 (setq ses--cells (ses-vector-insert ses--cells row newrow))
2066 (push `(ses-vector-delete cells ,row 1) buffer-undo-list) 2090 (push `(ses-vector-delete ses--cells ,row 1) buffer-undo-list)
2067 (insert blank-line)) 2091 (insert ses--blank-line))
2068 ;;Insert empty lines in cell data area (will be replaced by 2092 ;;Insert empty lines in cell data area (will be replaced by
2069 ;;ses-relocate-all) 2093 ;;ses-relocate-all)
2070 (ses-goto-data row 0) 2094 (ses-goto-data row 0)
2071 (insert (make-string (* (1+ numcols) count) ?\n)) 2095 (insert (make-string (* (1+ ses--numcols) count) ?\n))
2072 (ses-relocate-all row 0 count 0) 2096 (ses-relocate-all row 0 count 0)
2073 ;;If any cell printers insert constant text, insert that text 2097 ;;If any cell printers insert constant text, insert that text
2074 ;;into the line. 2098 ;;into the line.
2075 (let ((cols (mapconcat #'ses-call-printer col-printers nil)) 2099 (let ((cols (mapconcat #'ses-call-printer ses--col-printers nil))
2076 (global (ses-call-printer default-printer))) 2100 (global (ses-call-printer ses--default-printer)))
2077 (if (or (> (length cols) 0) (> (length global) 0)) 2101 (if (or (> (length cols) 0) (> (length global) 0))
2078 (dotimes (x count) 2102 (dotimes (x count)
2079 (dotimes (col numcols) 2103 (dotimes (col ses--numcols)
2080 ;;These cells are always nil, only constant formatting printed 2104 ;;These cells are always nil, only constant formatting printed
2081 (1value (ses-print-cell (+ x row) col)))))) 2105 (1value (ses-print-cell (+ x row) col))))))
2082 (when (> header-row row) 2106 (when (> ses--header-row row)
2083 ;;Inserting before header 2107 ;;Inserting before header
2084 (ses-set-parameter 'header-row (+ header-row count)) 2108 (ses-set-parameter 'ses--header-row (+ ses--header-row count))
2085 (ses-reset-header-string))) 2109 (ses-reset-header-string)))
2086 ;;Reconstruct text attributes 2110 ;;Reconstruct text attributes
2087 (ses-setup) 2111 (ses-setup)
2088 ;;Return to current cell 2112 ;;Return to current cell
2089 (if curcell 2113 (if ses--curcell
2090 (ses-jump-safe curcell) 2114 (ses-jump-safe ses--curcell)
2091 (ses-goto-print (1- numrows) 0))) 2115 (ses-goto-print (1- ses--numrows) 0)))
2092 2116
2093(defun ses-delete-row (count) 2117(defun ses-delete-row (count)
2094 "Delete the current row. With prefix, Deletes COUNT rows starting from the 2118 "Delete the current row. With prefix, Deletes COUNT rows starting from the
@@ -2098,31 +2122,31 @@ current one."
2098 (or (> count 0) (signal 'args-out-of-range nil)) 2122 (or (> count 0) (signal 'args-out-of-range nil))
2099 (let ((inhibit-quit t) 2123 (let ((inhibit-quit t)
2100 (inhibit-read-only t) 2124 (inhibit-read-only t)
2101 (row (car (ses-sym-rowcol curcell))) 2125 (row (car (ses-sym-rowcol ses--curcell)))
2102 pos) 2126 pos)
2103 (setq count (min count (- numrows row))) 2127 (setq count (min count (- ses--numrows row)))
2104 (ses-begin-change) 2128 (ses-begin-change)
2105 (ses-set-parameter 'numrows (- numrows count)) 2129 (ses-set-parameter 'ses--numrows (- ses--numrows count))
2106 ;;Delete lines from print area 2130 ;;Delete lines from print area
2107 (ses-goto-print row 0) 2131 (ses-goto-print row 0)
2108 (ses-delete-line count) 2132 (ses-delete-line count)
2109 ;;Delete lines from cell data area 2133 ;;Delete lines from cell data area
2110 (ses-goto-data row 0) 2134 (ses-goto-data row 0)
2111 (ses-delete-line (* count (1+ numcols))) 2135 (ses-delete-line (* count (1+ ses--numcols)))
2112 ;;Relocate variables and formulas 2136 ;;Relocate variables and formulas
2113 (ses-set-with-undo 'cells (ses-vector-delete cells row count)) 2137 (ses-set-with-undo 'ses--cells (ses-vector-delete ses--cells row count))
2114 (ses-relocate-all row 0 (- count) 0) 2138 (ses-relocate-all row 0 (- count) 0)
2115 (ses-destroy-cell-variable-range numrows (+ numrows count -1) 2139 (ses-destroy-cell-variable-range ses--numrows (+ ses--numrows count -1)
2116 0 (1- numcols)) 2140 0 (1- ses--numcols))
2117 (when (> header-row row) 2141 (when (> ses--header-row row)
2118 (if (<= header-row (+ row count)) 2142 (if (<= ses--header-row (+ row count))
2119 ;;Deleting the header row 2143 ;;Deleting the header row
2120 (ses-set-parameter 'header-row 0) 2144 (ses-set-parameter 'ses--header-row 0)
2121 (ses-set-parameter 'header-row (- header-row count))) 2145 (ses-set-parameter 'ses--header-row (- ses--header-row count)))
2122 (ses-reset-header-string))) 2146 (ses-reset-header-string)))
2123 ;;Reconstruct attributes 2147 ;;Reconstruct attributes
2124 (ses-setup) 2148 (ses-setup)
2125 (ses-jump-safe curcell)) 2149 (ses-jump-safe ses--curcell))
2126 2150
2127(defun ses-insert-column (count &optional col width printer) 2151(defun ses-insert-column (count &optional col width printer)
2128 "Insert a new column before COL (default is the current one). With prefix, 2152 "Insert a new column before COL (default is the current one). With prefix,
@@ -2133,30 +2157,30 @@ the current column)."
2133 (ses-check-curcell) 2157 (ses-check-curcell)
2134 (or (> count 0) (signal 'args-out-of-range nil)) 2158 (or (> count 0) (signal 'args-out-of-range nil))
2135 (or col 2159 (or col
2136 (setq col (cdr (ses-sym-rowcol curcell)) 2160 (setq col (cdr (ses-sym-rowcol ses--curcell))
2137 width (ses-col-width col) 2161 width (ses-col-width col)
2138 printer (ses-col-printer col))) 2162 printer (ses-col-printer col)))
2139 (ses-begin-change) 2163 (ses-begin-change)
2140 (let ((inhibit-quit t) 2164 (let ((inhibit-quit t)
2141 (inhibit-read-only t) 2165 (inhibit-read-only t)
2142 (widths column-widths) 2166 (widths ses--col-widths)
2143 (printers col-printers) 2167 (printers ses--col-printers)
2144 has-skip) 2168 has-skip)
2145 ;;Create a new set of cell-variables 2169 ;;Create a new set of cell-variables
2146 (ses-create-cell-variable-range 0 (1- numrows) 2170 (ses-create-cell-variable-range 0 (1- ses--numrows)
2147 numcols (+ numcols count -1)) 2171 ses--numcols (+ ses--numcols count -1))
2148 ;;Insert each column. 2172 ;;Insert each column.
2149 (ses-dotimes-msg (x count) "Inserting column..." 2173 (ses-dotimes-msg (x count) "Inserting column..."
2150 ;;Create a column of empty cells. The `symbol' fields will be set by 2174 ;;Create a column of empty cells. The `symbol' fields will be set by
2151 ;;the call to ses-relocate-all. 2175 ;;the call to ses-relocate-all.
2152 (ses-adjust-print-width col (1+ width)) 2176 (ses-adjust-print-width col (1+ width))
2153 (ses-set-parameter 'numcols (1+ numcols)) 2177 (ses-set-parameter 'ses--numcols (1+ ses--numcols))
2154 (dotimes (row numrows) 2178 (dotimes (row ses--numrows)
2155 (and (< (1+ col) numcols) (eq (ses-cell-value row col) '*skip*) 2179 (and (< (1+ col) ses--numcols) (eq (ses-cell-value row col) '*skip*)
2156 ;;Inserting in the middle of a spill-over 2180 ;;Inserting in the middle of a spill-over
2157 (setq has-skip t)) 2181 (setq has-skip t))
2158 (ses-aset-with-undo cells row 2182 (ses-aset-with-undo ses--cells row
2159 (ses-vector-insert (aref cells row) 2183 (ses-vector-insert (aref ses--cells row)
2160 col 2184 col
2161 (make-vector ses-cell-size nil))) 2185 (make-vector ses-cell-size nil)))
2162 ;;Insert empty lines in cell data area (will be replaced by 2186 ;;Insert empty lines in cell data area (will be replaced by
@@ -2166,22 +2190,22 @@ the current column)."
2166 ;;Insert column width and printer 2190 ;;Insert column width and printer
2167 (setq widths (ses-vector-insert widths col width) 2191 (setq widths (ses-vector-insert widths col width)
2168 printers (ses-vector-insert printers col printer))) 2192 printers (ses-vector-insert printers col printer)))
2169 (ses-set-parameter 'column-widths widths) 2193 (ses-set-parameter 'ses--col-widths widths)
2170 (ses-set-parameter 'col-printers printers) 2194 (ses-set-parameter 'ses--col-printers printers)
2171 (ses-reset-header-string) 2195 (ses-reset-header-string)
2172 (ses-relocate-all 0 col 0 count) 2196 (ses-relocate-all 0 col 0 count)
2173 (if has-skip 2197 (if has-skip
2174 (ses-reprint-all t) 2198 (ses-reprint-all t)
2175 (when (or (> (length (ses-call-printer printer)) 0) 2199 (when (or (> (length (ses-call-printer printer)) 0)
2176 (> (length (ses-call-printer default-printer)) 0)) 2200 (> (length (ses-call-printer ses--default-printer)) 0))
2177 ;;Either column printer or global printer inserts some constant text 2201 ;;Either column printer or global printer inserts some constant text
2178 ;;Reprint the new columns to insert that text. 2202 ;;Reprint the new columns to insert that text.
2179 (dotimes (x numrows) 2203 (dotimes (x ses--numrows)
2180 (dotimes (y count) 2204 (dotimes (y count)
2181 ;Always nil here - this is a blank column 2205 ;Always nil here - this is a blank column
2182 (1value (ses-print-cell-new-width x (+ y col)))))) 2206 (1value (ses-print-cell-new-width x (+ y col))))))
2183 (ses-setup))) 2207 (ses-setup)))
2184 (ses-jump-safe curcell)) 2208 (ses-jump-safe ses--curcell))
2185 2209
2186(defun ses-delete-column (count) 2210(defun ses-delete-column (count)
2187 "Delete the current column. With prefix, Deletes COUNT columns starting 2211 "Delete the current column. With prefix, Deletes COUNT columns starting
@@ -2191,45 +2215,45 @@ from the current one."
2191 (or (> count 0) (signal 'args-out-of-range nil)) 2215 (or (> count 0) (signal 'args-out-of-range nil))
2192 (let ((inhibit-quit t) 2216 (let ((inhibit-quit t)
2193 (inhibit-read-only t) 2217 (inhibit-read-only t)
2194 (rowcol (ses-sym-rowcol curcell)) 2218 (rowcol (ses-sym-rowcol ses--curcell))
2195 (width 0) 2219 (width 0)
2196 new col origrow has-skip) 2220 new col origrow has-skip)
2197 (setq origrow (car rowcol) 2221 (setq origrow (car rowcol)
2198 col (cdr rowcol) 2222 col (cdr rowcol)
2199 count (min count (- numcols col))) 2223 count (min count (- ses--numcols col)))
2200 (if (= count numcols) 2224 (if (= count ses--numcols)
2201 (error "Can't delete all columns!")) 2225 (error "Can't delete all columns!"))
2202 ;;Determine width of column(s) being deleted 2226 ;;Determine width of column(s) being deleted
2203 (dotimes (x count) 2227 (dotimes (x count)
2204 (setq width (+ width (ses-col-width (+ col x)) 1))) 2228 (setq width (+ width (ses-col-width (+ col x)) 1)))
2205 (ses-begin-change) 2229 (ses-begin-change)
2206 (ses-set-parameter 'numcols (- numcols count)) 2230 (ses-set-parameter 'ses--numcols (- ses--numcols count))
2207 (ses-adjust-print-width col (- width)) 2231 (ses-adjust-print-width col (- width))
2208 (ses-dotimes-msg (row numrows) "Deleting column..." 2232 (ses-dotimes-msg (row ses--numrows) "Deleting column..."
2209 ;;Delete lines from cell data area 2233 ;;Delete lines from cell data area
2210 (ses-goto-data row col) 2234 (ses-goto-data row col)
2211 (ses-delete-line count) 2235 (ses-delete-line count)
2212 ;;Delete cells. Check if deletion area begins or ends with a skip. 2236 ;;Delete cells. Check if deletion area begins or ends with a skip.
2213 (if (or (eq (ses-cell-value row col) '*skip*) 2237 (if (or (eq (ses-cell-value row col) '*skip*)
2214 (and (< col numcols) 2238 (and (< col ses--numcols)
2215 (eq (ses-cell-value row (+ col count)) '*skip*))) 2239 (eq (ses-cell-value row (+ col count)) '*skip*)))
2216 (setq has-skip t)) 2240 (setq has-skip t))
2217 (ses-aset-with-undo cells row 2241 (ses-aset-with-undo ses--cells row
2218 (ses-vector-delete (aref cells row) col count))) 2242 (ses-vector-delete (aref ses--cells row) col count)))
2219 ;;Update globals 2243 ;;Update globals
2220 (ses-set-parameter 'column-widths 2244 (ses-set-parameter 'ses--col-widths
2221 (ses-vector-delete column-widths col count)) 2245 (ses-vector-delete ses--col-widths col count))
2222 (ses-set-parameter 'col-printers 2246 (ses-set-parameter 'ses--col-printers
2223 (ses-vector-delete col-printers col count)) 2247 (ses-vector-delete ses--col-printers col count))
2224 (ses-reset-header-string) 2248 (ses-reset-header-string)
2225 ;;Relocate variables and formulas 2249 ;;Relocate variables and formulas
2226 (ses-relocate-all 0 col 0 (- count)) 2250 (ses-relocate-all 0 col 0 (- count))
2227 (ses-destroy-cell-variable-range 0 (1- numrows) 2251 (ses-destroy-cell-variable-range 0 (1- ses--numrows)
2228 numcols (+ numcols count -1)) 2252 ses--numcols (+ ses--numcols count -1))
2229 (if has-skip 2253 (if has-skip
2230 (ses-reprint-all t) 2254 (ses-reprint-all t)
2231 (ses-setup)) 2255 (ses-setup))
2232 (if (>= col numcols) 2256 (if (>= col ses--numcols)
2233 (setq col (1- col))) 2257 (setq col (1- col)))
2234 (ses-goto-print origrow col))) 2258 (ses-goto-print origrow col)))
2235 2259
@@ -2241,11 +2265,11 @@ inserts a new row if at bottom of print area. Repeat COUNT times."
2241 (setq deactivate-mark t) ;Doesn't combine well with ranges 2265 (setq deactivate-mark t) ;Doesn't combine well with ranges
2242 (dotimes (x count) 2266 (dotimes (x count)
2243 (ses-set-curcell) 2267 (ses-set-curcell)
2244 (if (not curcell) 2268 (if (not ses--curcell)
2245 (progn ;At bottom of print area 2269 (progn ;At bottom of print area
2246 (barf-if-buffer-read-only) 2270 (barf-if-buffer-read-only)
2247 (ses-insert-row 1)) 2271 (ses-insert-row 1))
2248 (let ((col (cdr (ses-sym-rowcol curcell)))) 2272 (let ((col (cdr (ses-sym-rowcol ses--curcell))))
2249 (when (/= 32 2273 (when (/= 32
2250 (char-before (next-single-property-change (point) 2274 (char-before (next-single-property-change (point)
2251 'intangible))) 2275 'intangible)))
@@ -2253,7 +2277,7 @@ inserts a new row if at bottom of print area. Repeat COUNT times."
2253 ;;new column. 2277 ;;new column.
2254 (barf-if-buffer-read-only) 2278 (barf-if-buffer-read-only)
2255 (ses-insert-column (- count x) 2279 (ses-insert-column (- count x)
2256 numcols 2280 ses--numcols
2257 (ses-col-width col) 2281 (ses-col-width col)
2258 (ses-col-printer col))))) 2282 (ses-col-printer col)))))
2259 (forward-char))) 2283 (forward-char)))
@@ -2270,7 +2294,7 @@ inserts a new row if at bottom of print area. Repeat COUNT times."
2270(defun ses-set-column-width (col newwidth) 2294(defun ses-set-column-width (col newwidth)
2271 "Set the width of the current column." 2295 "Set the width of the current column."
2272 (interactive 2296 (interactive
2273 (let ((col (cdr (progn (ses-check-curcell) (ses-sym-rowcol curcell))))) 2297 (let ((col (cdr (progn (ses-check-curcell) (ses-sym-rowcol ses--curcell)))))
2274 (barf-if-buffer-read-only) 2298 (barf-if-buffer-read-only)
2275 (list col 2299 (list col
2276 (if current-prefix-arg 2300 (if current-prefix-arg
@@ -2291,8 +2315,8 @@ inserts a new row if at bottom of print area. Repeat COUNT times."
2291 (save-excursion 2315 (save-excursion
2292 (let ((inhibit-quit t)) 2316 (let ((inhibit-quit t))
2293 (ses-adjust-print-width col (- newwidth (ses-col-width col))) 2317 (ses-adjust-print-width col (- newwidth (ses-col-width col)))
2294 (ses-set-parameter 'column-widths newwidth col)) 2318 (ses-set-parameter 'ses--col-widths newwidth col))
2295 (dotimes (row numrows) 2319 (dotimes (row ses--numrows)
2296 (ses-print-cell-new-width row col)))) 2320 (ses-print-cell-new-width row col))))
2297 2321
2298 2322
@@ -2373,9 +2397,9 @@ cells instead of deleting them."
2373 ;;check whether the buffer really is read-only. 2397 ;;check whether the buffer really is read-only.
2374 (barf-if-buffer-read-only) 2398 (barf-if-buffer-read-only)
2375 (ses-begin-change) 2399 (ses-begin-change)
2376 (ses-dorange curcell 2400 (ses-dorange ses--curcell
2377 (ses-clear-cell row col)) 2401 (ses-clear-cell row col))
2378 (ses-jump (car curcell))) 2402 (ses-jump (car ses--curcell)))
2379 2403
2380(defadvice yank (around ses-yank activate preactivate) 2404(defadvice yank (around ses-yank activate preactivate)
2381 "In SES mode, the yanked text is inserted as cells. 2405 "In SES mode, the yanked text is inserted as cells.
@@ -2560,10 +2584,12 @@ is a list. Ignore a final newline."
2560confirmation and then inserts them. Result is (row,col) for top left of yank 2584confirmation and then inserts them. Result is (row,col) for top left of yank
2561spot, or error signal if user requests cancel." 2585spot, or error signal if user requests cancel."
2562 (ses-begin-change) 2586 (ses-begin-change)
2563 (let ((rowcol (if curcell (ses-sym-rowcol curcell) (cons numrows 0))) 2587 (let ((rowcol (if ses--curcell
2588 (ses-sym-rowcol ses--curcell)
2589 (cons ses--numrows 0)))
2564 rowbool colbool) 2590 rowbool colbool)
2565 (setq needrows (- (+ (car rowcol) needrows) numrows) 2591 (setq needrows (- (+ (car rowcol) needrows) ses--numrows)
2566 needcols (- (+ (cdr rowcol) needcols) numcols) 2592 needcols (- (+ (cdr rowcol) needcols) ses--numcols)
2567 rowbool (> needrows 0) 2593 rowbool (> needrows 0)
2568 colbool (> needcols 0)) 2594 colbool (> needcols 0))
2569 (when (or rowbool colbool) 2595 (when (or rowbool colbool)
@@ -2574,15 +2600,15 @@ spot, or error signal if user requests cancel."
2574 (if colbool (format "%d columns" needcols) ""))) 2600 (if colbool (format "%d columns" needcols) "")))
2575 (error "Cancelled")) 2601 (error "Cancelled"))
2576 (when rowbool 2602 (when rowbool
2577 (let (curcell) 2603 (let (ses--curcell)
2578 (save-excursion 2604 (save-excursion
2579 (ses-goto-print numrows 0) 2605 (ses-goto-print ses--numrows 0)
2580 (ses-insert-row needrows)))) 2606 (ses-insert-row needrows))))
2581 (when colbool 2607 (when colbool
2582 (ses-insert-column needcols 2608 (ses-insert-column needcols
2583 numcols 2609 ses--numcols
2584 (ses-col-width (1- numcols)) 2610 (ses-col-width (1- ses--numcols))
2585 (ses-col-printer (1- numcols))))) 2611 (ses-col-printer (1- ses--numcols)))))
2586 rowcol)) 2612 rowcol))
2587 2613
2588(defun ses-export-tsv (beg end) 2614(defun ses-export-tsv (beg end)
@@ -2604,7 +2630,7 @@ WANT-FORMULAS is non-nil. Newlines and tabs in the export text are escaped."
2604 (ses-check-curcell 'needrange) 2630 (ses-check-curcell 'needrange)
2605 (let ((print-escape-newlines t) 2631 (let ((print-escape-newlines t)
2606 result item) 2632 result item)
2607 (ses-dorange curcell 2633 (ses-dorange ses--curcell
2608 (setq item (if want-formulas 2634 (setq item (if want-formulas
2609 (ses-cell-formula row col) 2635 (ses-cell-formula row col)
2610 (ses-cell-value row col))) 2636 (ses-cell-value row col)))
@@ -2632,19 +2658,55 @@ WANT-FORMULAS is non-nil. Newlines and tabs in the export text are escaped."
2632;;;; Other user commands 2658;;;; Other user commands
2633;;;---------------------------------------------------------------------------- 2659;;;----------------------------------------------------------------------------
2634 2660
2635(defun ses-read-header-row (row) 2661;; This should be used by `call-interactively'.
2636 (interactive "NHeader row: ") 2662(defun ses-read-number (prompt &optional default)
2637 (if (or (< row 0) (> row numrows)) 2663 (let ((n nil))
2664 (when default
2665 (setq prompt
2666 (if (string-match "\\(\\):[^:]*" prompt)
2667 (replace-match (format " [%s]" default) t t prompt 1)
2668 (concat prompt (format " [%s] " default)))))
2669 (while
2670 (progn
2671 (let ((str (read-from-minibuffer prompt nil nil nil nil
2672 (number-to-string default))))
2673 (setq n (cond
2674 ((zerop (length str)) default)
2675 ((stringp str) (read str)))))
2676 (unless (numberp n)
2677 (message "Please enter a number.")
2678 (sit-for 1)
2679 t)))
2680 n))
2681
2682(defun ses-unset-header-row ()
2683 "Select the default header row."
2684 (interactive)
2685 (ses-set-header-row 0))
2686
2687(defun ses-set-header-row (row)
2688 "Set the ROW to display in the header-line.
2689With a numerical prefix arg, use that row.
2690With no prefix arg, use the current row.
2691With a \\[universal-argument] prefix arg, prompt the user.
2692The top row is row 1. Selecting row 0 displays the default header row."
2693 (interactive
2694 (list (if (numberp current-prefix-arg) current-prefix-arg
2695 (let ((currow (1+ (car (ses-sym-rowcol ses--curcell)))))
2696 (if current-prefix-arg
2697 (ses-read-number "Header row: " currow)
2698 currow)))))
2699 (if (or (< row 0) (> row ses--numrows))
2638 (error "Invalid header-row")) 2700 (error "Invalid header-row"))
2639 (ses-begin-change) 2701 (ses-begin-change)
2640 (ses-set-parameter 'header-row row) 2702 (ses-set-parameter 'ses--header-row row)
2641 (ses-reset-header-string)) 2703 (ses-reset-header-string))
2642 2704
2643(defun ses-mark-row () 2705(defun ses-mark-row ()
2644 "Marks the entirety of current row as a range." 2706 "Marks the entirety of current row as a range."
2645 (interactive) 2707 (interactive)
2646 (ses-check-curcell 'range) 2708 (ses-check-curcell 'range)
2647 (let ((row (car (ses-sym-rowcol (or (car-safe curcell) curcell))))) 2709 (let ((row (car (ses-sym-rowcol (or (car-safe ses--curcell) ses--curcell)))))
2648 (push-mark (point)) 2710 (push-mark (point))
2649 (ses-goto-print (1+ row) 0) 2711 (ses-goto-print (1+ row) 0)
2650 (push-mark (point) nil t) 2712 (push-mark (point) nil t)
@@ -2654,10 +2716,10 @@ WANT-FORMULAS is non-nil. Newlines and tabs in the export text are escaped."
2654 "Marks the entirety of current column as a range." 2716 "Marks the entirety of current column as a range."
2655 (interactive) 2717 (interactive)
2656 (ses-check-curcell 'range) 2718 (ses-check-curcell 'range)
2657 (let ((col (cdr (ses-sym-rowcol (or (car-safe curcell) curcell)))) 2719 (let ((col (cdr (ses-sym-rowcol (or (car-safe ses--curcell) ses--curcell))))
2658 (row 0)) 2720 (row 0))
2659 (push-mark (point)) 2721 (push-mark (point))
2660 (ses-goto-print (1- numrows) col) 2722 (ses-goto-print (1- ses--numrows) col)
2661 (forward-char 1) 2723 (forward-char 1)
2662 (push-mark (point) nil t) 2724 (push-mark (point) nil t)
2663 (while (eq '*skip* (ses-cell-value row col)) 2725 (while (eq '*skip* (ses-cell-value row col))
@@ -2669,25 +2731,25 @@ WANT-FORMULAS is non-nil. Newlines and tabs in the export text are escaped."
2669 "Move point to last cell on line." 2731 "Move point to last cell on line."
2670 (interactive) 2732 (interactive)
2671 (ses-check-curcell 'end 'range) 2733 (ses-check-curcell 'end 'range)
2672 (when curcell ;Otherwise we're at the bottom row, which is empty anyway 2734 (when ses--curcell ;Otherwise we're at the bottom row, which is empty anyway
2673 (let ((col (1- numcols)) 2735 (let ((col (1- ses--numcols))
2674 row rowcol) 2736 row rowcol)
2675 (if (symbolp curcell) 2737 (if (symbolp ses--curcell)
2676 ;;Single cell 2738 ;;Single cell
2677 (setq row (car (ses-sym-rowcol curcell))) 2739 (setq row (car (ses-sym-rowcol ses--curcell)))
2678 ;;Range - use whichever end of the range the point is at 2740 ;;Range - use whichever end of the range the point is at
2679 (setq rowcol (ses-sym-rowcol (if (< (point) (mark)) 2741 (setq rowcol (ses-sym-rowcol (if (< (point) (mark))
2680 (car curcell) 2742 (car ses--curcell)
2681 (cdr curcell)))) 2743 (cdr ses--curcell))))
2682 ;;If range already includes the last cell in a row, point is actually 2744 ;;If range already includes the last cell in a row, point is actually
2683 ;;in the following row 2745 ;;in the following row
2684 (if (<= (cdr rowcol) (1- col)) 2746 (if (<= (cdr rowcol) (1- col))
2685 (setq row (car rowcol)) 2747 (setq row (car rowcol))
2686 (setq row (1+ (car rowcol))) 2748 (setq row (1+ (car rowcol)))
2687 (if (= row numrows) 2749 (if (= row ses--numrows)
2688 ;;Already at end - can't go anywhere 2750 ;;Already at end - can't go anywhere
2689 (setq col 0)))) 2751 (setq col 0))))
2690 (when (< row numrows) ;Otherwise it's a range that includes last cell 2752 (when (< row ses--numrows) ;Otherwise it's a range that includes last cell
2691 (while (eq (ses-cell-value row col) '*skip*) 2753 (while (eq (ses-cell-value row col) '*skip*)
2692 ;;Back to beginning of multi-column cell 2754 ;;Back to beginning of multi-column cell
2693 (setq col (1- col))) 2755 (setq col (1- col)))
@@ -2696,15 +2758,15 @@ WANT-FORMULAS is non-nil. Newlines and tabs in the export text are escaped."
2696(defun ses-renarrow-buffer () 2758(defun ses-renarrow-buffer ()
2697 "Narrow the buffer so only the print area is visible. Use after \\[widen]." 2759 "Narrow the buffer so only the print area is visible. Use after \\[widen]."
2698 (interactive) 2760 (interactive)
2699 (setq deferred-narrow t)) 2761 (setq ses--deferred-narrow t))
2700 2762
2701(defun ses-sort-column (sorter &optional reverse) 2763(defun ses-sort-column (sorter &optional reverse)
2702 "Sorts the range by a specified column. With prefix, sorts in 2764 "Sorts the range by a specified column. With prefix, sorts in
2703REVERSE order." 2765REVERSE order."
2704 (interactive "*sSort column: \nP") 2766 (interactive "*sSort column: \nP")
2705 (ses-check-curcell 'needrange) 2767 (ses-check-curcell 'needrange)
2706 (let ((min (ses-sym-rowcol (car curcell))) 2768 (let ((min (ses-sym-rowcol (car ses--curcell)))
2707 (max (ses-sym-rowcol (cdr curcell)))) 2769 (max (ses-sym-rowcol (cdr ses--curcell))))
2708 (let ((minrow (car min)) 2770 (let ((minrow (car min))
2709 (mincol (cdr min)) 2771 (mincol (cdr min))
2710 (maxrow (car max)) 2772 (maxrow (car max))
@@ -2737,15 +2799,16 @@ REVERSE order."
2737 (ses-yank-cells (pop extracts) nil))))) 2799 (ses-yank-cells (pop extracts) nil)))))
2738 2800
2739(defun ses-sort-column-click (event reverse) 2801(defun ses-sort-column-click (event reverse)
2802 "Mouse version of `ses-sort-column'."
2740 (interactive "*e\nP") 2803 (interactive "*e\nP")
2741 (setq event (event-end event)) 2804 (setq event (event-end event))
2742 (select-window (posn-window event)) 2805 (select-window (posn-window event))
2743 (setq event (car (posn-col-row event))) ;Click column 2806 (setq event (car (posn-col-row event))) ;Click column
2744 (let ((col 0)) 2807 (let ((col 0))
2745 (while (and (< col numcols) (> event (ses-col-width col))) 2808 (while (and (< col ses--numcols) (> event (ses-col-width col)))
2746 (setq event (- event (ses-col-width col) 1) 2809 (setq event (- event (ses-col-width col) 1)
2747 col (1+ col))) 2810 col (1+ col)))
2748 (if (>= col numcols) 2811 (if (>= col ses--numcols)
2749 (ding) 2812 (ding)
2750 (ses-sort-column (ses-column-letter col) reverse)))) 2813 (ses-sort-column (ses-column-letter col) reverse))))
2751 2814
@@ -2757,7 +2820,8 @@ spreadsheet."
2757 (with-current-buffer (window-buffer minibuffer-scroll-window) 2820 (with-current-buffer (window-buffer minibuffer-scroll-window)
2758 (ses-command-hook) ;For ses-coverage 2821 (ses-command-hook) ;For ses-coverage
2759 (ses-check-curcell 'needrange) 2822 (ses-check-curcell 'needrange)
2760 (setq x (cdr (macroexpand `(ses-range ,(car curcell) ,(cdr curcell)))))) 2823 (setq x (cdr (macroexpand `(ses-range ,(car ses--curcell)
2824 ,(cdr ses--curcell))))))
2761 (insert (substring (prin1-to-string (nreverse x)) 1 -1)))) 2825 (insert (substring (prin1-to-string (nreverse x)) 1 -1))))
2762 2826
2763(defun ses-insert-ses-range () 2827(defun ses-insert-ses-range ()
@@ -2768,7 +2832,9 @@ highlighted range in the spreadsheet."
2768 (with-current-buffer (window-buffer minibuffer-scroll-window) 2832 (with-current-buffer (window-buffer minibuffer-scroll-window)
2769 (ses-command-hook) ;For ses-coverage 2833 (ses-command-hook) ;For ses-coverage
2770 (ses-check-curcell 'needrange) 2834 (ses-check-curcell 'needrange)
2771 (setq x (format "(ses-range %S %S)" (car curcell) (cdr curcell)))) 2835 (setq x (format "(ses-range %S %S)"
2836 (car ses--curcell)
2837 (cdr ses--curcell))))
2772 (insert x))) 2838 (insert x)))
2773 2839
2774(defun ses-insert-range-click (event) 2840(defun ses-insert-range-click (event)
@@ -2879,17 +2945,15 @@ TEST is evaluated."
2879;;dynamically bound by ses-print-cell. We define these varables at 2945;;dynamically bound by ses-print-cell. We define these varables at
2880;;compile-time to make the compiler happy. 2946;;compile-time to make the compiler happy.
2881(eval-when-compile 2947(eval-when-compile
2882 (make-local-variable 'row) 2948 (dolist (x '(row col))
2883 (make-local-variable 'col) 2949 (make-local-variable x)
2884 ;;Don't use setq -- that gives a "free variable" compiler warning 2950 (set x nil)))
2885 (set 'row nil)
2886 (set 'col nil))
2887 2951
2888(defun ses-center (value &optional span fill) 2952(defun ses-center (value &optional span fill)
2889 "Print VALUE, centered within column. FILL is the fill character for 2953 "Print VALUE, centered within column. FILL is the fill character for
2890centering (default = space). SPAN indicates how many additional rightward 2954centering (default = space). SPAN indicates how many additional rightward
2891columns to include in width (default = 0)." 2955columns to include in width (default = 0)."
2892 (let ((printer (or (ses-col-printer col) default-printer)) 2956 (let ((printer (or (ses-col-printer col) ses--default-printer))
2893 (width (ses-col-width col)) 2957 (width (ses-col-width col))
2894 half) 2958 half)
2895 (or fill (setq fill ? )) 2959 (or fill (setq fill ? ))
@@ -2909,7 +2973,7 @@ columns to include in width (default = 0)."
2909and continues until the next nonblank column. FILL specifies the fill 2973and continues until the next nonblank column. FILL specifies the fill
2910character (default = space)." 2974character (default = space)."
2911 (let ((end (1+ col))) 2975 (let ((end (1+ col)))
2912 (while (and (< end numcols) 2976 (while (and (< end ses--numcols)
2913 (memq (ses-cell-value row end) '(nil *skip*))) 2977 (memq (ses-cell-value row end) '(nil *skip*)))
2914 (setq end (1+ end))) 2978 (setq end (1+ end)))
2915 (ses-center value (- end col 1) fill))) 2979 (ses-center value (- end col 1) fill)))
diff --git a/lisp/simple.el b/lisp/simple.el
index 23d5e2c3440..8017878dd2a 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -499,14 +499,14 @@ that uses or sets the mark."
499 "Print the current buffer line number and narrowed line number of point." 499 "Print the current buffer line number and narrowed line number of point."
500 (interactive) 500 (interactive)
501 (let ((opoint (point)) (start (point-min)) 501 (let ((opoint (point)) (start (point-min))
502 (n (line-at-pos))) 502 (n (line-number-at-pos)))
503 (if (= start 1) 503 (if (= start 1)
504 (message "Line %d" n) 504 (message "Line %d" n)
505 (save-excursion 505 (save-excursion
506 (save-restriction 506 (save-restriction
507 (widen) 507 (widen)
508 (message "line %d (narrowed line %d)" 508 (message "line %d (narrowed line %d)"
509 (+ n (line-at-pos start) -1) n)))))) 509 (+ n (line-number-at-pos start) -1) n))))))
510 510
511(defun count-lines (start end) 511(defun count-lines (start end)
512 "Return number of lines between START and END. 512 "Return number of lines between START and END.
@@ -531,7 +531,7 @@ and the greater of them is not at the start of a line."
531 done))) 531 done)))
532 (- (buffer-size) (forward-line (buffer-size))))))) 532 (- (buffer-size) (forward-line (buffer-size)))))))
533 533
534(defun line-at-pos (&optional pos) 534(defun line-number-at-pos (&optional pos)
535 "Return (narrowed) buffer line number at position POS. 535 "Return (narrowed) buffer line number at position POS.
536If POS is nil, use current buffer location." 536If POS is nil, use current buffer location."
537 (let ((opoint (or pos (point))) start) 537 (let ((opoint (or pos (point))) start)
@@ -1834,7 +1834,7 @@ the front of the kill ring, rather than being added to the list.
1834Optional third arguments YANK-HANDLER controls how the STRING is later 1834Optional third arguments YANK-HANDLER controls how the STRING is later
1835inserted into a buffer; see `insert-for-yank' for details. 1835inserted into a buffer; see `insert-for-yank' for details.
1836When a yank handler is specified, STRING must be non-empty (the yank 1836When a yank handler is specified, STRING must be non-empty (the yank
1837handler is stored as a `yank-handler'text property on STRING). 1837handler is stored as a `yank-handler' text property on STRING).
1838 1838
1839When the yank handler has a non-nil PARAM element, the original STRING 1839When the yank handler has a non-nil PARAM element, the original STRING
1840argument is not used by `insert-for-yank'. However, since Lisp code 1840argument is not used by `insert-for-yank'. However, since Lisp code
@@ -1842,7 +1842,8 @@ may access and use elements from the kill-ring directly, the STRING
1842argument should still be a \"useful\" string for such uses." 1842argument should still be a \"useful\" string for such uses."
1843 (if (> (length string) 0) 1843 (if (> (length string) 0)
1844 (if yank-handler 1844 (if yank-handler
1845 (put-text-property 0 1 'yank-handler yank-handler string)) 1845 (put-text-property 0 (length string)
1846 'yank-handler yank-handler string))
1846 (if yank-handler 1847 (if yank-handler
1847 (signal 'args-out-of-range 1848 (signal 'args-out-of-range
1848 (list string "yank-handler specified for empty string")))) 1849 (list string "yank-handler specified for empty string"))))
@@ -1863,8 +1864,8 @@ If BEFORE-P is non-nil, prepend STRING to the kill.
1863Optional third argument YANK-HANDLER specifies the yank-handler text 1864Optional third argument YANK-HANDLER specifies the yank-handler text
1864property to be set on the combined kill ring string. If the specified 1865property to be set on the combined kill ring string. If the specified
1865yank-handler arg differs from the yank-handler property of the latest 1866yank-handler arg differs from the yank-handler property of the latest
1866kill string, STRING is added as a new kill ring element instead of 1867kill string, this function adds the combined string to the kill
1867being appending to the last kill. 1868ring as a new element, instead of replacing the last kill with it.
1868If `interprogram-cut-function' is set, pass the resulting kill to it." 1869If `interprogram-cut-function' is set, pass the resulting kill to it."
1869 (let* ((cur (car kill-ring))) 1870 (let* ((cur (car kill-ring)))
1870 (kill-new (if before-p (concat string cur) (concat cur string)) 1871 (kill-new (if before-p (concat string cur) (concat cur string))
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el
index be17e70c785..0f0c22cabe1 100644
--- a/lisp/tar-mode.el
+++ b/lisp/tar-mode.el
@@ -1,6 +1,6 @@
1;;; tar-mode.el --- simple editing of tar files from GNU emacs 1;;; tar-mode.el --- simple editing of tar files from GNU emacs
2 2
3;; Copyright (C) 1990,91,93,94,95,96,97,98,99,2000,2001 3;; Copyright (C) 1990,91,93,94,95,96,97,98,99,2000,01,2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: Jamie Zawinski <jwz@lucid.com> 6;; Author: Jamie Zawinski <jwz@lucid.com>
@@ -289,7 +289,7 @@ write-date, checksum, link-type, and link-name."
289 (dotimes (i L) 289 (dotimes (i L)
290 (if (or (< (aref string i) ?0) 290 (if (or (< (aref string i) ?0)
291 (> (aref string i) ?7)) 291 (> (aref string i) ?7))
292 (error "`%c' is not an octal digit")))) 292 (error "`%c' is not an octal digit" (aref string i)))))
293 (tar-parse-octal-integer string)) 293 (tar-parse-octal-integer string))
294 294
295 295
@@ -743,6 +743,7 @@ appear on disk when you save the tar-file's buffer."
743 (min (+ (point-min) 16384) (point-max)) t))) 743 (min (+ (point-min) 16384) (point-max)) t)))
744 (if coding 744 (if coding
745 (or (numberp (coding-system-eol-type coding)) 745 (or (numberp (coding-system-eol-type coding))
746 (vectorp (coding-system-eol-type detected))
746 (setq coding (coding-system-change-eol-conversion 747 (setq coding (coding-system-change-eol-conversion
747 coding 748 coding
748 (coding-system-eol-type detected)))) 749 (coding-system-eol-type detected))))
diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el
index cdba8a9445f..e09285e86c1 100644
--- a/lisp/term/x-win.el
+++ b/lisp/term/x-win.el
@@ -82,6 +82,7 @@
82(require 'select) 82(require 'select)
83(require 'menu-bar) 83(require 'menu-bar)
84(require 'fontset) 84(require 'fontset)
85(require 'x-dnd)
85 86
86(defvar x-invocation-args) 87(defvar x-invocation-args)
87 88
@@ -2180,13 +2181,11 @@ order until succeed.")
2180 char) 2181 char)
2181 (if (/= len-utf8 len-ctext) 2182 (if (/= len-utf8 len-ctext)
2182 (if (> len-utf8 len-ctext) utf8 ctext) 2183 (if (> len-utf8 len-ctext) utf8 ctext)
2183 (while (< i len-utf8) 2184 (let ((result (compare-strings utf8 0 len-utf8 ctext 0 len-ctext)))
2184 (setq char (aref ctext i)) 2185 (if (or (eq result t)
2185 (if (and (< char 128) (/= char (aref utf8 i))) 2186 (>= (aref ctext (1- (abs result))) 128))
2186 (setq selected utf8 2187 ctext
2187 i len-utf8) 2188 utf8)))))
2188 (setq i (1+ i))))
2189 selected)))
2190 2189
2191(defun x-selection-value (type) 2190(defun x-selection-value (type)
2192 (let (text) 2191 (let (text)
@@ -2484,5 +2483,9 @@ order until succeed.")
2484 2483
2485(provide 'x-win) 2484(provide 'x-win)
2486 2485
2486;; Initiate drag and drop
2487(add-hook 'after-make-frame-functions 'x-dnd-init-frame)
2488(global-set-key [drag-n-drop] 'x-dnd-handle-drag-n-drop-event)
2489
2487;;; arch-tag: f1501302-db8b-4d95-88e3-116697d89f78 2490;;; arch-tag: f1501302-db8b-4d95-88e3-116697d89f78
2488;;; x-win.el ends here 2491;;; x-win.el ends here
diff --git a/lisp/textmodes/refer.el b/lisp/textmodes/refer.el
index dd2006ad40d..1c77a8f4b36 100644
--- a/lisp/textmodes/refer.el
+++ b/lisp/textmodes/refer.el
@@ -1,6 +1,6 @@
1;;; refer.el --- look up references in bibliography files 1;;; refer.el --- look up references in bibliography files
2 2
3;; Copyright (C) 1992, 1996, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 1996, 2001, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Ashwin Ram <ashwin@cc.gatech.edu> 5;; Author: Ashwin Ram <ashwin@cc.gatech.edu>
6;; Maintainer: Gernot Heiser <gernot@acm.org> 6;; Maintainer: Gernot Heiser <gernot@acm.org>
@@ -226,10 +226,12 @@ found on the last refer-find-entry or refer-find-next-entry."
226 (throw 'found (find-file file))) 226 (throw 'found (find-file file)))
227 (setq refer-saved-pos nil 227 (setq refer-saved-pos nil
228 files (cdr files))) 228 files (cdr files)))
229 (progn (message "Scanning %s... No such file" (car files) (ding)) 229 (progn (ding)
230 (message "Scanning %s... No such file" (car files))
230 (sit-for 1) 231 (sit-for 1)
231 (setq files (cdr files)))))) 232 (setq files (cdr files))))))
232 (message "Keywords \"%s\" not found in any \.bib file" keywords (ding))) 233 (ding)
234 (message "Keywords \"%s\" not found in any \.bib file" keywords))
233 (select-window old-window))) 235 (select-window old-window)))
234 236
235(defun refer-find-entry-in-file (keywords-list file &optional old-pos) 237(defun refer-find-entry-in-file (keywords-list file &optional old-pos)
diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el
index 4d31c8caf19..8d217f08dfb 100644
--- a/lisp/textmodes/reftex-toc.el
+++ b/lisp/textmodes/reftex-toc.el
@@ -1,5 +1,5 @@
1;;; reftex-toc.el --- RefTeX's table of contents mode 1;;; reftex-toc.el --- RefTeX's table of contents mode
2;; Copyright (c) 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. 2;; Copyright (c) 1997, 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
3 3
4;; Author: Carsten Dominik <dominik@science.uva.nl> 4;; Author: Carsten Dominik <dominik@science.uva.nl>
5;; Version: 4.21 5;; Version: 4.21
@@ -754,13 +754,13 @@ if these sets are sorted blocks in the alist."
754 "Make sure all files of the document are being visited by buffers, 754 "Make sure all files of the document are being visited by buffers,
755and that the scanning info is absolutely up to date. 755and that the scanning info is absolutely up to date.
756We do this by rescanning with reftex-keep-temporary-buffers bound to t. 756We do this by rescanning with reftex-keep-temporary-buffers bound to t.
757The variable PRO-OR-DE is assumed to be dynamically scoped into thes function. 757The variable PRO-OR-DE is assumed to be dynamically scoped into this function.
758When finished, we exit with an error message." 758When finished, we exit with an error message."
759 (let ((reftex-keep-temporary-buffers t)) 759 (let ((reftex-keep-temporary-buffers t))
760 (reftex-toc-Rescan) 760 (reftex-toc-Rescan)
761 (reftex-toc-restore-region start-line mark-line) 761 (reftex-toc-restore-region start-line mark-line)
762 (throw 'exit 762 (throw 'exit
763 (format "TOC had to be updated first. Please check selection and repeat the command." pro-or-de)))) 763 "TOC had to be updated first. Please check selection and repeat the command.")))
764 764
765(defun reftex-toc-rename-label () 765(defun reftex-toc-rename-label ()
766 "Rename the currently selected label in the *TOC* buffer. 766 "Rename the currently selected label in the *TOC* buffer.
diff --git a/lisp/vc.el b/lisp/vc.el
index 33bb04e4aa1..5ef5711331d 100644
--- a/lisp/vc.el
+++ b/lisp/vc.el
@@ -1,13 +1,13 @@
1;;; vc.el --- drive a version-control system from within Emacs 1;;; vc.el --- drive a version-control system from within Emacs
2 2
3;; Copyright (C) 1992,93,94,95,96,97,98,2000,01,2003 3;; Copyright (C) 1992,93,94,95,96,97,98,2000,01,2003,2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: FSF (see below for full credits) 6;; Author: FSF (see below for full credits)
7;; Maintainer: Andre Spiegel <spiegel@gnu.org> 7;; Maintainer: Andre Spiegel <spiegel@gnu.org>
8;; Keywords: tools 8;; Keywords: tools
9 9
10;; $Id: vc.el,v 1.365 2004/01/23 11:20:55 uid65624 Exp $ 10;; $Id: vc.el,v 1.367 2004/02/08 22:42:42 uid65629 Exp $
11 11
12;; This file is part of GNU Emacs. 12;; This file is part of GNU Emacs.
13 13
@@ -804,11 +804,11 @@ somebody else, signal error."
804 (let ((filevar (make-symbol "file"))) 804 (let ((filevar (make-symbol "file")))
805 `(let ((,filevar (expand-file-name ,file))) 805 `(let ((,filevar (expand-file-name ,file)))
806 (or (vc-backend ,filevar) 806 (or (vc-backend ,filevar)
807 (error (format "File not under version control: `%s'" file))) 807 (error "File not under version control: `%s'" file))
808 (unless (vc-editable-p ,filevar) 808 (unless (vc-editable-p ,filevar)
809 (let ((state (vc-state ,filevar))) 809 (let ((state (vc-state ,filevar)))
810 (if (stringp state) 810 (if (stringp state)
811 (error (format "`%s' is locking `%s'" state ,filevar)) 811 (error "`%s' is locking `%s'" state ,filevar)
812 (vc-checkout ,filevar t)))) 812 (vc-checkout ,filevar t))))
813 (save-excursion 813 (save-excursion
814 ,@body) 814 ,@body)
@@ -2487,7 +2487,7 @@ A prefix argument NOREVERT means do not revert the buffer afterwards."
2487 ((not (vc-call latest-on-branch-p file)) 2487 ((not (vc-call latest-on-branch-p file))
2488 (error "This is not the latest version; VC cannot cancel it")) 2488 (error "This is not the latest version; VC cannot cancel it"))
2489 ((not (vc-up-to-date-p file)) 2489 ((not (vc-up-to-date-p file))
2490 (error (substitute-command-keys "File is not up to date; use \\[vc-revert-buffer] to discard changes")))) 2490 (error "%s" (substitute-command-keys "File is not up to date; use \\[vc-revert-buffer] to discard changes"))))
2491 (if (null (yes-or-no-p (format "Remove version %s from master? " target))) 2491 (if (null (yes-or-no-p (format "Remove version %s from master? " target)))
2492 (error "Aborted") 2492 (error "Aborted")
2493 (setq norevert (or norevert (not 2493 (setq norevert (or norevert (not
@@ -3144,7 +3144,7 @@ string, then it describes a revision number, so warp to that
3144revision." 3144revision."
3145 (if (not (equal major-mode 'vc-annotate-mode)) 3145 (if (not (equal major-mode 'vc-annotate-mode))
3146 (message "Cannot be invoked outside of a vc annotate buffer") 3146 (message "Cannot be invoked outside of a vc annotate buffer")
3147 (let* ((oldline (line-at-pos)) 3147 (let* ((oldline (line-number-at-pos))
3148 (revspeccopy revspec) 3148 (revspeccopy revspec)
3149 (newrev nil)) 3149 (newrev nil))
3150 (cond 3150 (cond
@@ -3176,7 +3176,7 @@ revision."
3176 (switch-to-buffer (car (car (last vc-annotate-buffers)))) 3176 (switch-to-buffer (car (car (last vc-annotate-buffers))))
3177 (goto-line (min oldline (progn (goto-char (point-max)) 3177 (goto-line (min oldline (progn (goto-char (point-max))
3178 (previous-line) 3178 (previous-line)
3179 (line-at-pos)))))))) 3179 (line-number-at-pos))))))))
3180 3180
3181(defun vc-annotate-car-last-cons (a-list) 3181(defun vc-annotate-car-last-cons (a-list)
3182 "Return car of last cons in association list A-LIST." 3182 "Return car of last cons in association list A-LIST."
diff --git a/lisp/window.el b/lisp/window.el
index c4ae59e148f..91b91cfb158 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -1,6 +1,6 @@
1;;; window.el --- GNU Emacs window commands aside from those written in C 1;;; window.el --- GNU Emacs window commands aside from those written in C
2 2
3;; Copyright (C) 1985, 1989, 1992, 1993, 1994, 2000, 2001, 2002 3;; Copyright (C) 1985, 1989, 1992, 1993, 1994, 2000, 2001, 2002, 2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Maintainer: FSF 6;; Maintainer: FSF
@@ -188,13 +188,11 @@ even if it is inactive."
188(defun window-safely-shrinkable-p (&optional window) 188(defun window-safely-shrinkable-p (&optional window)
189 "Non-nil if the WINDOW can be shrunk without shrinking other windows. 189 "Non-nil if the WINDOW can be shrunk without shrinking other windows.
190If WINDOW is nil or omitted, it defaults to the currently selected window." 190If WINDOW is nil or omitted, it defaults to the currently selected window."
191 (save-selected-window 191 (with-selected-window (or window (selected-window))
192 (when window (select-window window)) 192 (let ((edges (window-edges)))
193 (or (and (not (eq window (frame-first-window))) 193 (or (= (nth 2 edges) (nth 2 (window-edges (previous-window))))
194 (= (car (window-edges)) 194 (= (nth 0 edges) (nth 0 (window-edges (next-window))))))))
195 (car (window-edges (previous-window))))) 195
196 (= (car (window-edges))
197 (car (window-edges (next-window)))))))
198 196
199(defun balance-windows () 197(defun balance-windows ()
200 "Make all visible windows the same height (approximately)." 198 "Make all visible windows the same height (approximately)."
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el
new file mode 100644
index 00000000000..91ca053afa2
--- /dev/null
+++ b/lisp/x-dnd.el
@@ -0,0 +1,870 @@
1;;; x-dnd.el --- drag and drop support for X.
2
3;; Copyright (C) 2004
4;; Free Software Foundation, Inc.
5
6;; Author: Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
7;; Maintainer: FSF
8;; Keywords: window, drag, drop
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation; either version 2, or (at your option)
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
26
27;;; Commentary:
28
29;; This file provides the drop part only. Currently supported protocols
30;; are XDND, Motif and the old KDE 1.x protocol.
31
32;;; Code:
33
34;;; Customizable variables
35
36
37(defcustom x-dnd-test-function 'x-dnd-default-test-function
38 "The function drag and drop uses to determine if to accept or reject a drop.
39The function takes three arguments, WINDOW ACTION and TYPES.
40WINDOW is where the mouse is when the function is called. WINDOW may be a
41frame if the mouse isn't over a real window (i.e. menu bar, tool bar or
42scroll bar). ACTION is the suggested action from the drag and drop source,
43one of the symbols move, copy link or ask. TYPES is a list of available types
44for the drop.
45
46The function shall return nil to reject the drop or a cons with two values,
47the wanted action as car and the wanted type as cdr. The wanted action
48can be copy, move, link, ask or private.
49The default value for this variable is `x-dnd-default-test-function'."
50 :type 'symbol
51 :group 'x)
52
53(defcustom x-dnd-protocol-alist
54 '(
55 ("^file:///" . x-dnd-open-local-file) ; XDND format.
56 ("^file://" . x-dnd-open-file) ; URL with host
57 ("^file:" . x-dnd-open-local-file) ; Old KDE, Motif, Sun
58 )
59
60 "The functions to call for different protocols when a drop is made.
61This variable is used by `x-dnd-handle-uri-list' and `x-dnd-handle-moz-url'.
62The list contains of (REGEXP . FUNCTION) pairs.
63The functions shall take two arguments, URL, which is the URL dropped and
64ACTION which is the action to be performed for the drop (move, copy, link,
65private or ask).
66If no match is found here, and the value of `browse-url-browser-function'
67is a pair of (REGEXP . FUNCTION), those regexps are tried for a match.
68Insertion of text is not handeled by these functions, see `x-dnd-types-alist'
69for that.
70The function shall return the action done (move, copy, link or private)
71if some action was made, or nil if the URL is ignored."
72 :type 'alist
73 :group 'x)
74
75
76(defcustom x-dnd-types-alist
77 '(
78 ("text/uri-list" . x-dnd-handle-uri-list)
79 ("text/x-moz-url" . x-dnd-handle-moz-url)
80 ("_NETSCAPE_URL" . x-dnd-handle-uri-list)
81 ("FILE_NAME" . x-dnd-handle-file-name)
82 ("UTF8_STRING" . x-dnd-insert-utf8-text)
83 ("text/plain;charset=UTF-8" . x-dnd-insert-utf8-text)
84 ("text/plain;charset=utf-8" . x-dnd-insert-utf8-text)
85 ("text/unicode" . x-dnd-insert-utf16-text)
86 ("text/plain" . x-dnd-insert-text)
87 ("COMPOUND_TEXT" . x-dnd-insert-ctext)
88 ("STRING" . x-dnd-insert-text)
89 ("TEXT" . x-dnd-insert-text)
90 )
91 "Which function to call to handle a drop of that type.
92If the type for the drop is not present, or the function is nil,
93the drop is rejected. The function takes three arguments, WINDOW, ACTION
94and DATA. WINDOW is where the drop occured, ACTION is the action for
95this drop (copy, move, link, private or ask) as determined by a previous
96call to `x-dnd-test-function'. DATA is the drop data.
97The function shall return the action used (copy, move, link or private) if drop
98is successful, nil if not."
99 :type 'alist
100 :group 'x)
101
102(defcustom x-dnd-open-file-other-window nil
103 "If non-nil, always use find-file-other-window to open dropped files."
104 :type 'boolean
105 :group 'x)
106
107;; Internal variables
108
109(defvar x-dnd-known-types
110 '("text/uri-list"
111 "text/x-moz-url"
112 "_NETSCAPE_URL"
113 "FILE_NAME"
114 "UTF8_STRING"
115 "text/plain;charset=UTF-8"
116 "text/plain;charset=utf-8"
117 "text/unicode"
118 "text/plain"
119 "COMPOUND_TEXT"
120 "STRING"
121 "TEXT"
122 )
123 "The types accepted by default for dropped data.
124The types are chosen in the order they appear in the list.")
125
126(defvar x-dnd-current-state nil
127 "The current state for a drop.
128This is an alist with one entry for each display. The value for each display
129is a vector that contains the state for drag and drop for that display.
130Elements in the vector are:
131Last buffer drag was in,
132last window drag was in,
133types available for drop,
134the action suggested by the source,
135the type we want for the drop,
136the action we want for the drop,
137any protocol specific data.")
138
139(defvar x-dnd-empty-state [nil nil nil nil nil nil nil])
140
141
142
143(defun x-dnd-init-frame (&optional frame)
144 "Setup drag and drop for FRAME (i.e. create appropriate properties)."
145 (x-dnd-init-xdnd-for-frame frame)
146 (x-dnd-init-motif-for-frame frame))
147
148(defun x-dnd-get-state-cons-for-frame (frame-or-window)
149 "Return the entry in x-dnd-current-state for a frame or window."
150 (let* ((frame (if (framep frame-or-window) frame-or-window
151 (window-frame frame-or-window)))
152 (display (frame-parameter frame 'display)))
153 (if (not (assoc display x-dnd-current-state))
154 (push (cons display (copy-sequence x-dnd-empty-state))
155 x-dnd-current-state))
156 (assoc display x-dnd-current-state)))
157
158(defun x-dnd-get-state-for-frame (frame-or-window)
159 "Return the state in x-dnd-current-state for a frame or window."
160 (cdr (x-dnd-get-state-cons-for-frame frame-or-window)))
161
162(defun x-dnd-default-test-function (window action types)
163 "The default test function for drag and drop.
164WINDOW is where the mouse is when this function is called. It may be a frame
165if the mouse is over the menu bar, scroll bar or tool bar.
166ACTION is the suggested action from the source, and TYPES are the
167types the drop data can have. This function only accepts drops with
168types in `x-dnd-known-types'. It always returns the action private."
169 (let ((type (x-dnd-choose-type types)))
170 (when type (cons 'private type))))
171
172
173(defun x-dnd-current-type (frame-or-window)
174 "Return the type we want the DND data to be in for the current drop.
175FRAME-OR-WINDOW is the frame or window that the mouse is over."
176 (aref (x-dnd-get-state-for-frame frame-or-window) 4))
177
178(defun x-dnd-forget-drop (frame-or-window)
179 "Remove all state for the last drop.
180FRAME-OR-WINDOW is the frame or window that the mouse is over."
181 (setcdr (x-dnd-get-state-cons-for-frame frame-or-window)
182 (copy-sequence x-dnd-empty-state)))
183
184(defun x-dnd-maybe-call-test-function (window action)
185 "Call `x-dnd-test-function' if something has changed.
186WINDOW is the window the mouse is over. ACTION is the suggested
187action from the source. If nothing has changed, return the last
188action and type we got from `x-dnd-test-function'."
189 (let ((buffer (when (and (windowp window) (window-live-p window))
190 (window-buffer window)))
191 (current-state (x-dnd-get-state-for-frame window)))
192 (when (or (not (equal buffer (aref current-state 0)))
193 (not (equal window (aref current-state 1)))
194 (not (equal action (aref current-state 3))))
195 (save-excursion
196 (when buffer (set-buffer buffer))
197 (let* ((action-type (funcall x-dnd-test-function
198 window
199 action
200 (aref current-state 2)))
201 (handler (cdr (assoc (cdr action-type) x-dnd-types-alist))))
202 ;; Ignore action-type if we have no handler.
203 (setq current-state
204 (x-dnd-save-state window
205 action
206 (when handler action-type)))))))
207 (let ((current-state (x-dnd-get-state-for-frame window)))
208 (cons (aref current-state 5)
209 (aref current-state 4))))
210
211(defun x-dnd-save-state (window action action-type &optional types extra-data)
212 "Save the state of the current drag and drop.
213WINDOW is the window the mouse is over. ACTION is the action suggested
214by the source. ACTION-TYPE is the result of calling `x-dnd-test-function'.
215If given, TYPES are the types for the drop data that the source supports.
216EXTRA-DATA is data needed for a specific protocol."
217 (let ((current-state (x-dnd-get-state-for-frame window)))
218 (aset current-state 5 (car action-type))
219 (aset current-state 4 (cdr action-type))
220 (aset current-state 3 action)
221 (when types (aset current-state 2 types))
222 (when extra-data (aset current-state 6 extra-data))
223 (aset current-state 1 window)
224 (aset current-state 0 (if (and (windowp window)
225 (window-live-p window))
226 (window-buffer window) nil))
227 (setcdr (x-dnd-get-state-cons-for-frame window) current-state)))
228
229
230(defun x-dnd-handle-one-url (window action arg)
231 "Handle one dropped url by calling the appropriate handler.
232The handler is first localted by looking at `x-dnd-protocol-alist'.
233If no match is found here, and the value of `browse-url-browser-function'
234is a pair of (REGEXP . FUNCTION), those regexps are tried for a match.
235If no match is found, just call `x-dnd-insert-text'.
236WINDOW is where the drop happend, ACTION is the action for the drop,
237ARG is the URL that has been dropped.
238Returns ACTION."
239 (require 'browse-url)
240 (let* ((uri (replace-regexp-in-string
241 "%[A-Z0-9][A-Z0-9]"
242 (lambda (arg)
243 (format "%c" (string-to-number (substring arg 1) 16)))
244 arg))
245 ret)
246 (or
247 (catch 'done
248 (dolist (bf x-dnd-protocol-alist)
249 (when (string-match (car bf) uri)
250 (setq ret (funcall (cdr bf) uri action))
251 (throw 'done t)))
252 nil)
253 (when (not (functionp browse-url-browser-function))
254 (catch 'done
255 (dolist (bf browse-url-browser-function)
256 (when (string-match (car bf) uri)
257 (setq ret 'private)
258 (funcall (cdr bf) uri action)
259 (throw 'done t)))
260 nil))
261 (progn
262 (x-dnd-insert-text window action uri)
263 (setq ret 'private)))
264 ret))
265
266
267(defun x-dnd-get-local-file-uri (uri)
268 "Return an uri converted to file:/// syntax if uri is a local file.
269Return nil if URI is not a local file."
270
271 ;; The hostname may be our hostname, in that case, convert to a local
272 ;; file. Otherwise return nil. TODO: How about an IP-address as hostname?
273 (let ((hostname (when (string-match "^file://\\([^/]*\\)" uri)
274 (downcase (match-string 1 uri))))
275 (system-name-no-dot
276 (downcase (if (string-match "^[^\\.]+" system-name)
277 (match-string 0 system-name)
278 system-name))))
279 (when (and hostname
280 (or (string-equal "localhost" hostname)
281 (string-equal (downcase system-name) hostname)
282 (string-equal system-name-no-dot hostname)))
283 (concat "file://" (substring uri (+ 7 (length hostname)))))))
284
285(defun x-dnd-get-local-file-name (uri &optional must-exist)
286 "Return file name converted from file:/// or file: syntax.
287URI is the uri for the file. If MUST-EXIST is given and non-nil,
288only return non-nil if the file exists.
289Return nil if URI is not a local file."
290 (let ((f (cond ((string-match "^file:///" uri) ; XDND format.
291 (substring uri (1- (match-end 0))))
292 ((string-match "^file:" uri) ; Old KDE, Motif, Sun
293 (substring uri (match-end 0))))))
294 (when (and f must-exist)
295 (let* ((decoded-f (decode-coding-string
296 f
297 (or file-name-coding-system
298 default-file-name-coding-system)))
299 (try-f (if (file-readable-p decoded-f) decoded-f f)))
300 (when (file-readable-p try-f) try-f)))))
301
302
303(defun x-dnd-open-local-file (uri action)
304 "Open a local file.
305The file is opened in the current window, or a new window if
306`x-dnd-open-file-other-window' is set. URI is the url for the file,
307and must have the format file:file-name or file:///file-name.
308The last / in file:/// is part of the file name. ACTION is ignored."
309
310 (let* ((f (x-dnd-get-local-file-name uri t)))
311 (when f
312 (if (file-readable-p f)
313 (progn
314 (if x-dnd-open-file-other-window
315 (find-file-other-window f)
316 (find-file f))
317 'private)
318 (error "Can not read %s (%s)" f uri)))))
319
320(defun x-dnd-open-file (uri action)
321 "Open a local or remote file.
322The file is opened in the current window, or a new window if
323`x-dnd-open-file-other-window' is set. URI is the url for the file,
324and must have the format file://hostname/file-name. ACTION is ignored.
325The last / in file://hostname/ is part of the file name."
326
327 ;; The hostname may be our hostname, in that case, convert to a local
328 ;; file. Otherwise return nil.
329 (let ((local-file (x-dnd-get-local-file-uri uri)))
330 (when local-file (x-dnd-open-local-file local-file action))))
331
332
333(defun x-dnd-handle-moz-url (window action data)
334 "Handle one item of type text/x-moz-url.
335WINDOW is the window where the drop happened. ACTION is ignored.
336DATA is the moz-url, which is formatted as two strings separated by \r\n.
337The first string is the URL, the second string is the title of that URL.
338DATA is encoded in utf-16. Decode the URL and call `x-dnd-handle-uri-list'."
339 (let* ((string (decode-coding-string data 'utf-16le)) ;; ALWAYS LE???
340 (strings (split-string string "[\r\n]" t))
341 ;; Can one drop more than one moz-url ?? Assume not.
342 (url (car strings))
343 (title (car (cdr strings))))
344 (x-dnd-handle-uri-list window action url)))
345
346(defun x-dnd-insert-utf8-text (window action text)
347 "Decode the UTF-8 text and insert it at point.
348TEXT is the text as a string, WINDOW is the window where the drop happened."
349 (x-dnd-insert-text window action (decode-coding-string text 'utf-8)))
350
351(defun x-dnd-insert-utf16-text (window action text)
352 "Decode the UTF-16 text and insert it at point.
353TEXT is the text as a string, WINDOW is the window where the drop happened."
354 (x-dnd-insert-text window action (decode-coding-string text 'utf-16le)))
355
356(defun x-dnd-insert-ctext (window action text)
357 "Decode the compound text and insert it at point.
358TEXT is the text as a string, WINDOW is the window where the drop happened."
359 (x-dnd-insert-text window action
360 (decode-coding-string text
361 'compound-text-with-extensions)))
362
363(defun x-dnd-insert-text (window action text)
364 "Insert text at point or push to the kill ring if buffer is read only.
365TEXT is the text as a string, WINDOW is the window where the drop happened."
366 (if (or buffer-read-only
367 (not (windowp window)))
368 (progn
369 (kill-new text)
370 (message
371 (substitute-command-keys
372 "The dropped text can be accessed with \\[yank]")))
373 (insert text))
374 action)
375
376(defun x-dnd-handle-uri-list (window action string)
377 "Split an uri-list into separate URIs and call `x-dnd-handle-one-url'.
378WINDOW is the window where the drop happened.
379STRING is the uri-list as a string. The URIs are separated by \r\n."
380 (let ((uri-list (split-string string "[\0\r\n]" t))
381 retval)
382 (dolist (bf uri-list)
383 ;; If one URL is handeled, treat as if the whole drop succeeded.
384 (let ((did-action (x-dnd-handle-one-url window action bf)))
385 (when did-action (setq retval did-action))))
386 retval))
387
388(defun x-dnd-handle-file-name (window action string)
389 "Prepend file:// to file names and call `x-dnd-handle-one-url'.
390WINDOW is the window where the drop happened.
391STRING is the file names as a string, separated by nulls."
392 (let ((uri-list (split-string string "[\0\r\n]" t))
393 retval)
394 (dolist (bf uri-list)
395 ;; If one URL is handeled, treat as if the whole drop succeeded.
396 (let* ((file-uri (concat "file://" bf))
397 (did-action (x-dnd-handle-one-url window action file-uri)))
398 (when did-action (setq retval did-action))))
399 retval))
400
401
402(defun x-dnd-choose-type (types &optional known-types)
403 "Choose which type we want to receive for the drop.
404TYPES are the types the source of the drop offers, a vector of type names
405as strings or symbols. Select among the types in `x-dnd-known-types' or
406KNOWN-TYPES if given, and return that type name.
407If no suitable type is found, return nil."
408 (let* ((known-list (or known-types x-dnd-known-types))
409 (first-known-type (car known-list))
410 (types-array types)
411 (found (when first-known-type
412 (catch 'done
413 (dotimes (i (length types-array))
414 (let* ((type (aref types-array i))
415 (typename (if (symbolp type)
416 (symbol-name type) type)))
417 (when (equal first-known-type typename)
418 (throw 'done first-known-type))))
419 nil))))
420
421 (if (and (not found) (cdr known-list))
422 (x-dnd-choose-type types (cdr known-list))
423 found)))
424
425(defun x-dnd-drop-data (event frame window data type)
426 "Drop one data item onto a frame.
427EVENT is the client message for the drop, FRAME is the frame the drop occurred
428on. WINDOW is the window of FRAME where the drop happened. DATA is the data
429received from the source, and type is the type for DATA, see
430`x-dnd-types-alist').
431
432Returns the action used (move, copy, link, private) if drop was successful,
433nil if not."
434 (let* ((type-info (assoc type x-dnd-types-alist))
435 (handler (cdr type-info))
436 (state (x-dnd-get-state-for-frame frame))
437 (action (aref state 5))
438 (w (posn-window (event-start event))))
439 (when handler
440 (if (and (windowp w) (window-live-p w))
441 ;; If dropping in a window, open files in that window rather
442 ;; than in a new widow.
443 (let ((x-dnd-open-file-other-window nil))
444 (goto-char (posn-point (event-start event)))
445 (funcall handler window action data))
446 (let ((x-dnd-open-file-other-window t)) ;; Dropping on non-window.
447 (select-frame frame)
448 (funcall handler window action data))))))
449
450(defun x-dnd-handle-drag-n-drop-event (event)
451 "Receive drag and drop events (X client messages).
452Currently XDND, Motif and old KDE 1.x protocols are recognized."
453 (interactive "e")
454 (let* ((client-message (car (cdr (cdr event))))
455 (window (posn-window (event-start event)))
456 (message-atom (aref client-message 0))
457 (frame (aref client-message 1))
458 (format (aref client-message 2))
459 (data (aref client-message 3)))
460
461 (cond ((equal "DndProtocol" message-atom) ; Old KDE 1.x.
462 (x-dnd-handle-old-kde event frame window message-atom format data))
463
464 ((equal "_MOTIF_DRAG_AND_DROP_MESSAGE" message-atom) ; Motif
465 (x-dnd-handle-motif event frame window message-atom format data))
466
467 ((and (> (length message-atom) 4) ; XDND protocol.
468 (equal "Xdnd" (substring message-atom 0 4)))
469 (x-dnd-handle-xdnd event frame window message-atom format data)))))
470
471
472;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
473;;; Old KDE protocol. Only dropping of files.
474
475(defun x-dnd-handle-old-kde (event frame window message format data)
476 "Open the files in a KDE 1.x drop."
477 (let ((values (x-window-property "DndSelection" frame nil 0 t)))
478 (x-dnd-handle-uri-list window 'private
479 (replace-regexp-in-string "\0$" "" values))))
480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
481
482
483
484;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
485;;; XDND protocol.
486
487(defvar x-dnd-xdnd-to-action
488 '(("XdndActionPrivate" . private)
489 ("XdndActionCopy" . copy)
490 ("XdndActionMove" . move)
491 ("XdndActionLink" . link)
492 ("XdndActionAsk" . ask))
493 "Mapping from XDND action types to lisp symbols.")
494
495(defun x-dnd-init-xdnd-for-frame (frame)
496 "Set the XdndAware property for FRAME to indicate that we do XDND."
497 (x-change-window-property "XdndAware"
498 '(5) ;; The version of XDND we support.
499 frame "ATOM" 32 t))
500
501(defun x-dnd-get-drop-width-height (frame w accept)
502 "Return the widht/height to be sent in a XDndStatus message.
503FRAME is the frame and W is the window where the drop happened.
504If ACCEPT is nil return 0 (empty rectangle),
505otherwise if W is a window, return its widht/height,
506otherwise return the frame width/height."
507 (if accept
508 (if (windowp w) ;; w is not a window if dropping on the menu bar,
509 ;; scroll bar or tool bar.
510 (let ((edges (window-inside-pixel-edges w)))
511 (cons
512 (- (nth 2 edges) (nth 0 edges)) ;; right - left
513 (- (nth 3 edges) (nth 1 edges)))) ;; bottom - top
514 (cons (frame-pixel-width frame)
515 (frame-pixel-height frame)))
516 0))
517
518(defun x-dnd-get-drop-x-y (frame w)
519 "Return the x/y coordinates to be sent in a XDndStatus message.
520Coordinates are required to be absolute.
521FRAME is the frame and W is the window where the drop happened.
522If W is a window, return its absolute corrdinates,
523otherwise return the frame coordinates."
524 (let* ((frame-left (frame-parameter frame 'left))
525 ;; If the frame is outside the display, frame-left looks like
526 ;; '(0 -16). Extract the -16.
527 (frame-real-left (if (consp frame-left) (car (cdr frame-left))
528 frame-left))
529 (frame-top (frame-parameter frame 'top))
530 (frame-real-top (if (consp frame-top) (car (cdr frame-top))
531 frame-top)))
532 (if (windowp w)
533 (let ((edges (window-inside-pixel-edges w)))
534 (cons
535 (+ frame-real-left (nth 0 edges))
536 (+ frame-real-top (nth 1 edges))))
537 (cons frame-real-left frame-real-top))))
538
539(defun x-dnd-handle-xdnd (event frame window message format data)
540 "Receive one XDND event (client message) and send the appropriate reply.
541EVENT is the client message. FRAME is where the mouse is now.
542WINDOW is the window within FRAME where the mouse is now.
543FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent."
544 (cond ((equal "XdndEnter" message)
545 (let ((version (ash (car (aref data 1)) -8))
546 (more-than-3 (cdr (aref data 1)))
547 (dnd-source (aref data 0)))
548 (x-dnd-save-state
549 window nil nil
550 (if (> more-than-3 0)
551 (x-window-property "XdndTypeList"
552 frame "AnyPropertyType"
553 dnd-source nil t)
554 (vector (x-get-atom-name (aref data 2))
555 (x-get-atom-name (aref data 3))
556 (x-get-atom-name (aref data 4)))))))
557
558 ((equal "XdndPosition" message)
559 (let* ((x (car (aref data 2)))
560 (y (cdr (aref data 2)))
561 (action (x-get-atom-name (aref data 4)))
562 (dnd-source (aref data 0))
563 (dnd-time (aref data 3))
564 (action-type (x-dnd-maybe-call-test-function
565 window
566 (cdr (assoc action x-dnd-xdnd-to-action))))
567 (reply-action (car (rassoc (car action-type)
568 x-dnd-xdnd-to-action)))
569 (accept ;; 1 = accept, 0 = reject
570 (if (and reply-action action-type) 1 0))
571 (list-to-send
572 (list (string-to-number
573 (frame-parameter frame 'outer-window-id))
574 accept ;; 1 = Accept, 0 = reject.
575 (x-dnd-get-drop-x-y frame window)
576 (x-dnd-get-drop-width-height
577 frame window (eq accept 1))
578 (or reply-action 0)
579 )))
580 (x-send-client-message
581 frame dnd-source frame "XdndStatus" 32 list-to-send)
582 ))
583
584 ((equal "XdndLeave" message)
585 (x-dnd-forget-drop window))
586
587 ((equal "XdndDrop" message)
588 (if (windowp window) (select-window window))
589 (let* ((dnd-source (aref data 0))
590 (value (and (x-dnd-current-type window)
591 (x-get-selection-internal
592 'XdndSelection
593 (intern (x-dnd-current-type window)))))
594 success action ret-action)
595
596 (setq action (if value
597 (condition-case info
598 (x-dnd-drop-data event frame window value
599 (x-dnd-current-type window))
600 (error
601 (message "Error: %s" info)
602 nil))))
603
604 (setq success (if action 1 0))
605 (setq ret-action
606 (if (eq success 1)
607 (or (car (rassoc action x-dnd-xdnd-to-action))
608 "XdndActionPrivate")
609 0))
610
611 (x-send-client-message
612 frame dnd-source frame "XdndFinished" 32
613 (list (string-to-number (frame-parameter frame 'outer-window-id))
614 success ;; 1 = Success, 0 = Error
615 (if success "XdndActionPrivate" 0)
616 ))
617 (x-dnd-forget-drop window)))
618
619 (t (error "Unknown XDND message %s %s" message data))))
620
621;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
622;;; Motif protocol.
623
624(defun x-dnd-init-motif-for-frame (frame)
625 "Set _MOTIF_DRAG_RECEIVER_INFO for FRAME to indicate that we do Motif DND."
626 (x-change-window-property "_MOTIF_DRAG_RECEIVER_INFO"
627 (list
628 (byteorder)
629 0 ; The Motif DND version.
630 5 ; We want drag dynamic.
631 0 0 0 0 0 0 0
632 0 0 0 0 0 0) ; Property must be 16 bytes.
633 frame "_MOTIF_DRAG_RECEIVER_INFO" 8 t))
634
635(defun x-dnd-get-motif-value (data offset size byteorder)
636 (cond ((eq size 2)
637 (if (eq byteorder ?l)
638 (+ (ash (aref data (1+ offset)) 8)
639 (aref data offset))
640 (+ (ash (aref data offset) 8)
641 (aref data (1+ offset)))))
642
643 ((eq size 4)
644 (if (eq byteorder ?l)
645 (cons (+ (ash (aref data (+ 3 offset)) 8)
646 (aref data (+ 2 offset)))
647 (+ (ash (aref data (1+ offset)) 8)
648 (aref data offset)))
649 (cons (+ (ash (aref data offset) 8)
650 (aref data (1+ offset)))
651 (+ (ash (aref data (+ 2 offset)) 8)
652 (aref data (+ 3 offset))))))))
653
654(defun x-dnd-motif-value-to-list (value size byteorder)
655 (let ((bytes (cond ((eq size 2)
656 (list (logand (lsh value -8) ?\xff)
657 (logand value ?\xff)))
658
659 ((eq size 4)
660 (if (consp value)
661 (list (logand (lsh (car value) -8) ?\xff)
662 (logand (car value) ?\xff)
663 (logand (lsh (cdr value) -8) ?\xff)
664 (logand (cdr value) ?\xff))
665 (list (logand (lsh value -24) ?\xff)
666 (logand (lsh value -16) ?\xff)
667 (logand (lsh value -8) ?\xff)
668 (logand value ?\xff)))))))
669 (if (eq byteorder ?l)
670 (reverse bytes)
671 bytes)))
672
673
674(defvar x-dnd-motif-message-types
675 '((0 . XmTOP_LEVEL_ENTER)
676 (1 . XmTOP_LEVEL_LEAVE)
677 (2 . XmDRAG_MOTION)
678 (3 . XmDROP_SITE_ENTER)
679 (4 . XmDROP_SITE_LEAVE)
680 (5 . XmDROP_START)
681 (6 . XmDROP_FINISH)
682 (7 . XmDRAG_DROP_FINISH)
683 (8 . XmOPERATION_CHANGED))
684 "Mapping from numbers to Motif DND message types.")
685
686(defvar x-dnd-motif-to-action
687 '((1 . move)
688 (2 . copy)
689 (3 . link) ; Both 3 and 4 has been seen as link.
690 (4 . link)
691 (2 . private)) ; Motif does not have private, so use copy for private.
692 "Mapping from number to operation for Motif DND.")
693
694(defun x-dnd-handle-motif (event frame window message-atom format data)
695 (let* ((message-type (cdr (assoc (aref data 0) x-dnd-motif-message-types)))
696 (source-byteorder (aref data 1))
697 (my-byteorder (byteorder))
698 (source-flags (x-dnd-get-motif-value data 2 2 source-byteorder))
699 (source-action (cdr (assoc (logand ?\xF source-flags)
700 x-dnd-motif-to-action))))
701
702 (cond ((eq message-type 'XmTOP_LEVEL_ENTER)
703 (let* ((dnd-source (x-dnd-get-motif-value
704 data 8 4 source-byteorder))
705 (selection-atom (x-dnd-get-motif-value
706 data 12 4 source-byteorder))
707 (atom-name (x-get-atom-name selection-atom))
708 (types (when atom-name
709 (x-get-selection-internal (intern atom-name)
710 'TARGETS))))
711 (x-dnd-forget-drop frame)
712 (when types (x-dnd-save-state window nil nil
713 types
714 dnd-source))))
715
716 ;; Can not forget drop here, LEAVE comes before DROP_START and
717 ;; we need the state in DROP_START.
718 ((eq message-type 'XmTOP_LEVEL_LEAVE)
719 nil)
720
721 ((eq message-type 'XmDRAG_MOTION)
722 (let* ((state (x-dnd-get-state-for-frame frame))
723 (timestamp (x-dnd-motif-value-to-list
724 (x-dnd-get-motif-value data 4 4
725 source-byteorder)
726 4 my-byteorder))
727 (x (x-dnd-motif-value-to-list
728 (x-dnd-get-motif-value data 8 2 source-byteorder)
729 2 my-byteorder))
730 (y (x-dnd-motif-value-to-list
731 (x-dnd-get-motif-value data 10 2 source-byteorder)
732 2 my-byteorder))
733 (dnd-source (aref state 6))
734 (first-move (not (aref state 3)))
735 (action-type (x-dnd-maybe-call-test-function
736 window
737 source-action))
738 (reply-action (car (rassoc (car action-type)
739 x-dnd-motif-to-action)))
740 (reply-flags
741 (x-dnd-motif-value-to-list
742 (if reply-action
743 (+ reply-action
744 ?\x30 ; 30: valid drop site
745 ?\x700) ; 700: can do copy, move or link
746 ?\x30) ; 30: drop site, but noop.
747 2 my-byteorder))
748 (reply (append
749 (list
750 (+ ?\x80 ; 0x80 indicates a reply.
751 (if first-move
752 3 ; First time, reply is SITE_ENTER.
753 2)) ; Not first time, reply is DRAG_MOTION.
754 my-byteorder)
755 reply-flags
756 timestamp
757 x
758 y)))
759 (x-send-client-message frame
760 dnd-source
761 frame
762 "_MOTIF_DRAG_AND_DROP_MESSAGE"
763 8
764 reply)))
765
766 ((eq message-type 'XmOPERATION_CHANGED)
767 (let* ((state (x-dnd-get-state-for-frame frame))
768 (timestamp (x-dnd-motif-value-to-list
769 (x-dnd-get-motif-value data 4 4 source-byteorder)
770 4 my-byteorder))
771 (dnd-source (aref state 6))
772 (action-type (x-dnd-maybe-call-test-function
773 window
774 source-action))
775 (reply-action (car (rassoc (car action-type)
776 x-dnd-motif-to-action)))
777 (reply-flags
778 (x-dnd-motif-value-to-list
779 (if reply-action
780 (+ reply-action
781 ?\x30 ; 30: valid drop site
782 ?\x700) ; 700: can do copy, move or link
783 ?\x30) ; 30: drop site, but noop
784 2 my-byteorder))
785 (reply (append
786 (list
787 (+ ?\x80 ; 0x80 indicates a reply.
788 8) ; 8 is OPERATION_CHANGED
789 my-byteorder)
790 reply-flags
791 timestamp)))
792 (x-send-client-message frame
793 dnd-source
794 frame
795 "_MOTIF_DRAG_AND_DROP_MESSAGE"
796 8
797 reply)))
798
799 ((eq message-type 'XmDROP_START)
800 (let* ((x (x-dnd-motif-value-to-list
801 (x-dnd-get-motif-value data 8 2 source-byteorder)
802 2 my-byteorder))
803 (y (x-dnd-motif-value-to-list
804 (x-dnd-get-motif-value data 10 2 source-byteorder)
805 2 my-byteorder))
806 (selection-atom (x-dnd-get-motif-value
807 data 12 4 source-byteorder))
808 (atom-name (x-get-atom-name selection-atom))
809 (dnd-source (x-dnd-get-motif-value
810 data 16 4 source-byteorder))
811 (action-type (x-dnd-maybe-call-test-function
812 window
813 source-action))
814 (reply-action (car (rassoc (car action-type)
815 x-dnd-motif-to-action)))
816 (reply-flags
817 (x-dnd-motif-value-to-list
818 (if reply-action
819 (+ reply-action
820 ?\x30 ; 30: valid drop site
821 ?\x700) ; 700: can do copy, move or link
822 (+ ?\x30 ; 30: drop site, but noop.
823 ?\x200)) ; 200: drop cancel.
824 2 my-byteorder))
825 (reply (append
826 (list
827 (+ ?\x80 ; 0x80 indicates a reply.
828 5) ; DROP_START.
829 my-byteorder)
830 reply-flags
831 x
832 y))
833 (timestamp (x-dnd-get-motif-value
834 data 4 4 source-byteorder))
835 action)
836
837 (x-send-client-message frame
838 dnd-source
839 frame
840 "_MOTIF_DRAG_AND_DROP_MESSAGE"
841 8
842 reply)
843 (setq action
844 (when (and reply-action atom-name)
845 (let* ((value (x-get-selection-internal
846 (intern atom-name)
847 (intern (x-dnd-current-type window)))))
848 (when value
849 (condition-case info
850 (x-dnd-drop-data event frame window value
851 (x-dnd-current-type window))
852 (error
853 (message "Error: %s" info)
854 nil))))))
855 (x-get-selection-internal
856 (intern atom-name)
857 (if action 'XmTRANSFER_SUCCESS 'XmTRANSFER_FAILURE)
858 timestamp)
859 (x-dnd-forget-drop frame)))
860
861 (t (error "Unknown Motif DND message %s %s" message data)))))
862
863
864;;;
865
866
867(provide 'x-dnd)
868
869;;; arch-tag: b621fb7e-50da-4323-850b-5fc71ae64621
870;;; x-dnd.el ends here
diff --git a/lispref/ChangeLog b/lispref/ChangeLog
index 20dd4f13d03..eb3bacd1d36 100644
--- a/lispref/ChangeLog
+++ b/lispref/ChangeLog
@@ -1,3 +1,49 @@
12004-02-12 Kim F. Storm <storm@cua.dk>
2
3 * display.texi (Fringes): Use consistent wording.
4 Note that window-fringe's window arg is optional.
5 (Scroll Bars): Use consistent wording.
6
72004-02-11 Luc Teirlinck <teirllm@auburn.edu>
8
9 * tips.texi (Comment Tips): Document the new conventions for
10 commenting out code.
11
122004-02-07 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
13
14 * positions.texi (Text Lines): Added missing end defun.
15
162004-02-07 Kim F. Storm <storm@cua.dk>
17
18 * positions.texi (Text Lines): Add line-number-at-pos.
19
202004-02-06 John Paul Wallington <jpw@gnu.org>
21
22 * display.texi (Button Properties, Button Buffer Commands):
23 mouse-2 invokes button, not down-mouse-1.
24
252004-02-04 Jason Rumney <jasonr@gnu.org>
26
27 * makefile.w32-in: Sync with Makefile.in changes.
28
292004-02-03 Luc Teirlinck <teirllm@auburn.edu>
30
31 * minibuf.texi (Text from Minibuffer): Various corrections and
32 clarifications.
33 (Object from Minibuffer): Correct Lisp description of
34 read-minibuffer.
35 (Minibuffer History): Clarify description of cons values for
36 HISTORY arguments.
37 (Basic Completion): Various corrections and clarifications. Add
38 completion-regexp-list.
39 (Minibuffer Completion): Correct and clarify description of
40 completing-read.
41 (Completion Commands): Mention Partial Completion mode. Various
42 other minor changes.
43 (High-Level Completion): Various corrections and clarifications.
44 (Reading File Names): Ditto.
45 (Minibuffer Misc): Ditto.
46
12004-01-26 Luc Teirlinck <teirllm@auburn.edu> 472004-01-26 Luc Teirlinck <teirllm@auburn.edu>
2 48
3 * strings.texi (Text Comparison): assoc-string also matches 49 * strings.texi (Text Comparison): assoc-string also matches
diff --git a/lispref/display.texi b/lispref/display.texi
index fc1cdb038ef..54ba32c39da 100644
--- a/lispref/display.texi
+++ b/lispref/display.texi
@@ -2563,7 +2563,7 @@ you can call @code{set-window-buffer} to display it in a window again.
2563 2563
2564@defun set-window-fringes window left &optional right outside-margins 2564@defun set-window-fringes window left &optional right outside-margins
2565This function sets the fringe widthes of window @var{window}. 2565This function sets the fringe widthes of window @var{window}.
2566If window is @code{nil}, that stands for the selected window. 2566If @var{window} is @code{nil}, the selected window is used.
2567 2567
2568The argument @var{left} specifies the width in pixels of the left 2568The argument @var{left} specifies the width in pixels of the left
2569fringe, and likewise @var{right} for the right fringe. A value of 2569fringe, and likewise @var{right} for the right fringe. A value of
@@ -2572,9 +2572,10 @@ fringe, and likewise @var{right} for the right fringe. A value of
2572should appear outside of the display margins. 2572should appear outside of the display margins.
2573@end defun 2573@end defun
2574 2574
2575@defun window-fringes window 2575@defun window-fringes &optional window
2576This function returns information about the fringes of a window 2576This function returns information about the fringes of a window
2577@var{window}. The value has the form @code{(@var{left-width} 2577@var{window}. If @var{window} is omitted or @code{nil}, the selected
2578window is used. The value has the form @code{(@var{left-width}
2578@var{right-width} @var{frames-outside-margins})}. 2579@var{right-width} @var{frames-outside-margins})}.
2579@end defun 2580@end defun
2580 2581
@@ -2591,8 +2592,8 @@ You can also control this for individual windows. Call the function
2591@code{set-window-scroll-bars} to specify what to do for a specific window: 2592@code{set-window-scroll-bars} to specify what to do for a specific window:
2592 2593
2593@defun set-window-scroll-bars window width &optional vertical-type horizontal-type 2594@defun set-window-scroll-bars window width &optional vertical-type horizontal-type
2594Set width and type of scroll bars of window @var{window}. (If 2595Set width and type of scroll bars of window @var{window}.
2595@var{window} is @code{nil}, this applies to the selected window.) 2596If @var{window} is @code{nil}, the selected window is used.
2596@var{width} specifies the scroll bar width in pixels (@code{nil} means 2597@var{width} specifies the scroll bar width in pixels (@code{nil} means
2597use whatever is specified for width for the frame). 2598use whatever is specified for width for the frame).
2598@var{vertical-type} specifies whether to have a vertical scroll bar 2599@var{vertical-type} specifies whether to have a vertical scroll bar
@@ -2607,8 +2608,8 @@ implemented, it has no effect.
2607 2608
2608@defun window-scroll-bars &optional window 2609@defun window-scroll-bars &optional window
2609Report the width and type of scroll bars specified for @var{window}. 2610Report the width and type of scroll bars specified for @var{window}.
2610If @var{window} is omitted or @code{nil}, it defaults to the currently 2611If @var{window} is omitted or @code{nil}, the selected window is used.
2611selected window. The value is a list of the form @code{(@var{width} 2612The value is a list of the form @code{(@var{width}
2612@var{cols} @var{vertical-type} @var{horizontal-type})}. The value 2613@var{cols} @var{vertical-type} @var{horizontal-type})}. The value
2613@var{width} is the value that was specified for the width (which may 2614@var{width} is the value that was specified for the width (which may
2614be @code{nil}); @var{cols} is the number of columns that the scroll 2615be @code{nil}); @var{cols} is the number of columns that the scroll
@@ -3483,7 +3484,7 @@ the usual emacs @code{highlight} face.
3483The button's keymap, defining bindings active within the button 3484The button's keymap, defining bindings active within the button
3484region. By default this is the usual button region keymap, stored 3485region. By default this is the usual button region keymap, stored
3485in the variable @code{button-map}, which defines @key{RET} and 3486in the variable @code{button-map}, which defines @key{RET} and
3486@key{down-mouse-1} to invoke the button. 3487@key{mouse-2} to invoke the button.
3487 3488
3488@item type 3489@item type
3489@kindex type @r{(button property)} 3490@kindex type @r{(button property)}
@@ -3668,7 +3669,7 @@ buttons in an emacs buffer.
3668 3669
3669@code{push-button} is the command that a user uses to actually `push' 3670@code{push-button} is the command that a user uses to actually `push'
3670a button, and is bound by default in the button itself to @key{RET} 3671a button, and is bound by default in the button itself to @key{RET}
3671and to @key{mouse-down-1} using a region-specific keymap. Commands 3672and to @key{mouse-2} using a region-specific keymap. Commands
3672that are useful outside the buttons itself, such as 3673that are useful outside the buttons itself, such as
3673@code{forward-button} and @code{backward-button} are additionally 3674@code{forward-button} and @code{backward-button} are additionally
3674available in the keymap stored in @code{button-buffer-map}; a mode 3675available in the keymap stored in @code{button-buffer-map}; a mode
diff --git a/lispref/makefile.w32-in b/lispref/makefile.w32-in
index 8cb9aa83330..f5f6c306eec 100644
--- a/lispref/makefile.w32-in
+++ b/lispref/makefile.w32-in
@@ -39,9 +39,6 @@ texinputdir = $(srcdir)\..\nt\envadd.bat "TEXINPUTS=$(srcdir);$(TEXINPUTS)" /C
39VERSION=2.9 39VERSION=2.9
40manual = elisp-manual-21-$(VERSION) 40manual = elisp-manual-21-$(VERSION)
41 41
42# Uncomment this line for permuted index.
43# permuted_index = 1
44
45# List of all the texinfo files in the manual: 42# List of all the texinfo files in the manual:
46 43
47srcs = \ 44srcs = \
@@ -95,8 +92,7 @@ srcs = \
95 $(srcdir)/tips.texi \ 92 $(srcdir)/tips.texi \
96 $(srcdir)/variables.texi \ 93 $(srcdir)/variables.texi \
97 $(srcdir)/windows.texi \ 94 $(srcdir)/windows.texi \
98 $(srcdir)/index.unperm \ 95 $(srcdir)/index.texi \
99 $(srcdir)/index.perm \
100 $(srcdir)/gpl.texi \ 96 $(srcdir)/gpl.texi \
101 $(srcdir)/doclicense.texi 97 $(srcdir)/doclicense.texi
102 98
@@ -107,29 +103,16 @@ srcs = \
107info: $(infodir)/elisp 103info: $(infodir)/elisp
108 $(INSTALL_INFO) --info-dir=$(infodir) $(infodir)/elisp 104 $(INSTALL_INFO) --info-dir=$(infodir) $(infodir)/elisp
109 105
110$(infodir)/elisp: $(srcs) index.texi 106$(infodir)/elisp: $(srcs)
111 $(MAKEINFO) -I. -I$(srcdir) $(srcdir)/elisp.texi -o $(infodir)/elisp 107 $(MAKEINFO) -I. -I$(srcdir) $(srcdir)/elisp.texi -o $(infodir)/elisp
112 108
113elisp.dvi: $(srcs) index.texi 109elisp.dvi: $(srcs)
114# Avoid losing old contents of aux file entirely.
115 -ren elisp.aux elisp.oaux
116# First shot to define xrefs.
117 $(texinputdir) $(TEX) $(srcdir)/elisp.texi
118 if not a$(permuted_index) == a sh $(srcdir)/permute-index
119 if not a$(permuted_index) == a ren permuted.fns elisp.fns
120 if not a$(permuted_index) == a texindex elisp.tp
121 if a$(permuted_index) == a texindex elisp.??
122 $(texinputdir) $(TEX) $(srcdir)/elisp.texi 110 $(texinputdir) $(TEX) $(srcdir)/elisp.texi
123 111
124index.texi:
125 if a$(permuted_index) == a cp $(srcdir)/index.unperm index.texi
126 if not a$(permuted_index) == a cp $(srcdir)/index.perm index.texi
127
128clean: 112clean:
129 rm -f *.toc *.aux *.log *.cp *.cps *.fn *.fns *.tp *.tps \ 113 rm -f *.toc *.aux *.log *.cp *.cps *.fn *.fns *.tp *.tps \
130 *.vr *.vrs *.pg *.pgs *.ky *.kys 114 *.vr *.vrs *.pg *.pgs *.ky *.kys
131 rm -f make.out core 115 rm -f make.out core
132 rm -f index.texi
133 rm -f $(infodir)/elisp* 116 rm -f $(infodir)/elisp*
134 117
135distclean: clean 118distclean: clean
diff --git a/lispref/minibuf.texi b/lispref/minibuf.texi
index 473859ccd6c..5b073148d4e 100644
--- a/lispref/minibuf.texi
+++ b/lispref/minibuf.texi
@@ -135,13 +135,17 @@ reads the text and returns the resulting Lisp object, unevaluated.
135(@xref{Input Functions}, for information about reading.) 135(@xref{Input Functions}, for information about reading.)
136 136
137The argument @var{default} specifies a default value to make available 137The argument @var{default} specifies a default value to make available
138through the history commands. It should be a string, or @code{nil}. If 138through the history commands. It should be a string, or @code{nil}.
139@var{read} is non-@code{nil}, then @var{default} is also used as the 139If non-@code{nil}, the user can access it using
140input to @code{read}, if the user enters empty input. However, in the 140@code{next-history-element}, usually bound in the minibuffer to
141usual case (where @var{read} is @code{nil}), @code{read-from-minibuffer} 141@kbd{M-n}. If @var{read} is non-@code{nil}, then @var{default} is
142does not return @var{default} when the user enters empty input; it 142also used as the input to @code{read}, if the user enters empty input.
143returns an empty string, @code{""}. In this respect, it is different 143(If @var{read} is non-@code{nil} and @var{default} is @code{nil}, empty
144from all the other minibuffer input functions in this chapter. 144input results in an @code{end-of-file} error.) However, in the usual
145case (where @var{read} is @code{nil}), @code{read-from-minibuffer}
146ignores @var{default} when the user enters empty input and returns an
147empty string, @code{""}. In this respect, it is different from all
148the other minibuffer input functions in this chapter.
145 149
146If @var{keymap} is non-@code{nil}, that keymap is the local keymap to 150If @var{keymap} is non-@code{nil}, that keymap is the local keymap to
147use in the minibuffer. If @var{keymap} is omitted or @code{nil}, the 151use in the minibuffer. If @var{keymap} is omitted or @code{nil}, the
@@ -171,8 +175,9 @@ its initial contents.
171 175
172Alternatively, @var{initial-contents} can be a cons cell of the form 176Alternatively, @var{initial-contents} can be a cons cell of the form
173@code{(@var{string} . @var{position})}. This means to insert 177@code{(@var{string} . @var{position})}. This means to insert
174@var{string} in the minibuffer but put point @var{position} characters 178@var{string} in the minibuffer but put point at @emph{one-indexed}
175from the beginning, rather than at the end. 179@var{position} in the minibuffer, rather than at the end. Any integer
180value less or equal to one puts point at the beginning of the string.
176 181
177@strong{Usage note:} The @var{initial-contents} argument and the 182@strong{Usage note:} The @var{initial-contents} argument and the
178@var{default} argument are two alternative features for more or less the 183@var{default} argument are two alternative features for more or less the
@@ -180,21 +185,21 @@ same job. It does not make sense to use both features in a single call
180to @code{read-from-minibuffer}. In general, we recommend using 185to @code{read-from-minibuffer}. In general, we recommend using
181@var{default}, since this permits the user to insert the default value 186@var{default}, since this permits the user to insert the default value
182when it is wanted, but does not burden the user with deleting it from 187when it is wanted, but does not burden the user with deleting it from
183the minibuffer on other occasions. 188the minibuffer on other occasions. For an exception to this rule,
189see @ref{Minibuffer History}.
184@end defun 190@end defun
185 191
186@defun read-string prompt &optional initial history default inherit-input-method 192@defun read-string prompt &optional initial history default inherit-input-method
187This function reads a string from the minibuffer and returns it. The 193This function reads a string from the minibuffer and returns it. The
188arguments @var{prompt} and @var{initial} are used as in 194arguments @var{prompt}, @var{initial}, @var{history} and
189@code{read-from-minibuffer}. The keymap used is 195@var{inherit-input-method} are used as in @code{read-from-minibuffer}.
190@code{minibuffer-local-map}. 196The keymap used is @code{minibuffer-local-map}.
191 197
192The optional argument @var{history}, if non-@code{nil}, specifies a 198The optional argument @var{default} is used as in
193history list and optionally the initial position in the list. The 199@code{read-from-minibuffer}, except that, if non-@code{nil}, it also
194optional argument @var{default} specifies a default value to return if 200specifies a default value to return if the user enters null input. As
195the user enters null input; it should be a string. The optional 201in @code{read-from-minibuffer} it should be a string, or @code{nil},
196argument @var{inherit-input-method} specifies whether to inherit the 202which is equivalent to an empty string.
197current buffer's input method.
198 203
199This function is a simplified interface to the 204This function is a simplified interface to the
200@code{read-from-minibuffer} function: 205@code{read-from-minibuffer} function:
@@ -206,7 +211,7 @@ This function is a simplified interface to the
206(let ((value 211(let ((value
207 (read-from-minibuffer @var{prompt} @var{initial} nil nil 212 (read-from-minibuffer @var{prompt} @var{initial} nil nil
208 @var{history} @var{default} @var{inherit}))) 213 @var{history} @var{default} @var{inherit})))
209 (if (equal value "") 214 (if (and (equal value "") @var{default})
210 @var{default} 215 @var{default}
211 value)) 216 value))
212@end group 217@end group
@@ -216,13 +221,15 @@ This function is a simplified interface to the
216@defvar minibuffer-allow-text-properties 221@defvar minibuffer-allow-text-properties
217If this variable is @code{nil}, then @code{read-from-minibuffer} strips 222If this variable is @code{nil}, then @code{read-from-minibuffer} strips
218all text properties from the minibuffer input before returning it. 223all text properties from the minibuffer input before returning it.
219Since all minibuffer input uses @code{read-from-minibuffer}, this 224This variable also affects @code{read-string}. However,
220variable applies to all minibuffer input. 225@code{read-no-blanks-input} (see below), as well as
221 226@code{read-minibuffer} and related functions (@pxref{Object from
222Note that the completion functions discard text properties unconditionally, 227Minibuffer,, Reading Lisp Objects With the Minibuffer}), and all
223regardless of the value of this variable. 228functions that do minibuffer input with completion, discard text
229properties unconditionally, regardless of the value of this variable.
224@end defvar 230@end defvar
225 231
232@anchor{Definition of minibuffer-local-map}
226@defvar minibuffer-local-map 233@defvar minibuffer-local-map
227This is the default local keymap for reading from the minibuffer. By 234This is the default local keymap for reading from the minibuffer. By
228default, it makes the following bindings: 235default, it makes the following bindings:
@@ -243,10 +250,10 @@ default, it makes the following bindings:
243@item @kbd{M-p} 250@item @kbd{M-p}
244@code{previous-history-element} 251@code{previous-history-element}
245 252
246@item @kbd{M-r} 253@item @kbd{M-s}
247@code{next-matching-history-element} 254@code{next-matching-history-element}
248 255
249@item @kbd{M-s} 256@item @kbd{M-r}
250@code{previous-matching-history-element} 257@code{previous-matching-history-element}
251@end table 258@end table
252@end defvar 259@end defvar
@@ -265,11 +272,15 @@ keymap as the @var{keymap} argument for that function. Since the keymap
265@code{minibuffer-local-ns-map} does not rebind @kbd{C-q}, it @emph{is} 272@code{minibuffer-local-ns-map} does not rebind @kbd{C-q}, it @emph{is}
266possible to put a space into the string, by quoting it. 273possible to put a space into the string, by quoting it.
267 274
275This function discards text properties, regardless of the value of
276@code{minibuffer-allow-text-properties}.
277
268@smallexample 278@smallexample
269@group 279@group
270(read-no-blanks-input @var{prompt} @var{initial}) 280(read-no-blanks-input @var{prompt} @var{initial})
271@equiv{} 281@equiv{}
272(read-from-minibuffer @var{prompt} @var{initial} minibuffer-local-ns-map) 282(let (minibuffer-allow-text-properties)
283 (read-from-minibuffer @var{prompt} @var{initial} minibuffer-local-ns-map))
273@end group 284@end group
274@end smallexample 285@end smallexample
275@end defun 286@end defun
@@ -312,7 +323,8 @@ This is a simplified interface to the
312@group 323@group
313(read-minibuffer @var{prompt} @var{initial}) 324(read-minibuffer @var{prompt} @var{initial})
314@equiv{} 325@equiv{}
315(read-from-minibuffer @var{prompt} @var{initial} nil t) 326(let (minibuffer-allow-text-properties)
327 (read-from-minibuffer @var{prompt} @var{initial} nil t))
316@end group 328@end group
317@end smallexample 329@end smallexample
318 330
@@ -421,11 +433,16 @@ Use @var{variable} (a symbol) as the history list.
421 433
422@item (@var{variable} . @var{startpos}) 434@item (@var{variable} . @var{startpos})
423Use @var{variable} (a symbol) as the history list, and assume that the 435Use @var{variable} (a symbol) as the history list, and assume that the
424initial history position is @var{startpos} (an integer, counting from 436initial history position is @var{startpos} (a nonnegative integer).
425zero which specifies the most recent element of the history). 437
426 438Specifying 0 for @var{startpos} is equivalent to just specifying the
427If you specify @var{startpos}, then you should also specify that element 439symbol @var{variable}. @code{previous-history-element} will display
428of the history as the initial minibuffer contents, for consistency. 440the most recent element of the history list in the minibuffer. If you
441specify a positive @var{startpos}, the minibuffer history functions
442behave as if @code{(elt @var{variable} (1- @var{STARTPOS}))} were the
443history element currently shown in the minibuffer. For consistency,
444you should also specify that element of the history as the initial
445minibuffer contents.
429@end table 446@end table
430 447
431 If you don't specify @var{hist}, then the default history list 448 If you don't specify @var{hist}, then the default history list
@@ -539,8 +556,9 @@ the higher-level completion features that do use the minibuffer.
539@defun try-completion string collection &optional predicate 556@defun try-completion string collection &optional predicate
540This function returns the longest common substring of all possible 557This function returns the longest common substring of all possible
541completions of @var{string} in @var{collection}. The value of 558completions of @var{string} in @var{collection}. The value of
542@var{collection} must be a list of strings, an alist, an obarray, or a 559@var{collection} must be a list of strings, an alist, an obarray, a
543function that implements a virtual set of strings (see below). 560hash table, or a function that implements a virtual set of strings
561(see below).
544 562
545Completion compares @var{string} against each of the permissible 563Completion compares @var{string} against each of the permissible
546completions specified by @var{collection}; if the beginning of the 564completions specified by @var{collection}; if the beginning of the
@@ -552,7 +570,12 @@ longest initial sequence common to all the permissible completions that
552match. 570match.
553 571
554If @var{collection} is an alist (@pxref{Association Lists}), the 572If @var{collection} is an alist (@pxref{Association Lists}), the
555@sc{car}s of the alist elements form the set of permissible completions. 573permissible completions are the elements of the alist that are either
574strings or conses whose @sc{car} is a string. Other elements of the
575alist are ignored. (Remember that in Emacs Lisp, the elements of
576alists do not @emph{have} to be conses.) As all elements of the alist
577can be strings, this case actually includes lists of strings, even
578though we usually do not think of such lists as alists.
556 579
557@cindex obarray in completion 580@cindex obarray in completion
558If @var{collection} is an obarray (@pxref{Creating Symbols}), the names 581If @var{collection} is an obarray (@pxref{Creating Symbols}), the names
@@ -564,6 +587,9 @@ Note that the only valid way to make a new obarray is to create it
564empty and then add symbols to it one by one using @code{intern}. 587empty and then add symbols to it one by one using @code{intern}.
565Also, you cannot intern a given symbol in more than one obarray. 588Also, you cannot intern a given symbol in more than one obarray.
566 589
590If @var{collection} is a hash table, then the keys that are strings
591are the possible completions. Other keys are ignored.
592
567You can also use a symbol that is a function as @var{collection}. Then 593You can also use a symbol that is a function as @var{collection}. Then
568the function is solely responsible for performing completion; 594the function is solely responsible for performing completion;
569@code{try-completion} returns whatever this function returns. The 595@code{try-completion} returns whatever this function returns. The
@@ -573,11 +599,20 @@ function can be used in @code{all-completions} and do the appropriate
573thing in either case.) @xref{Programmed Completion}. 599thing in either case.) @xref{Programmed Completion}.
574 600
575If the argument @var{predicate} is non-@code{nil}, then it must be a 601If the argument @var{predicate} is non-@code{nil}, then it must be a
576function of one argument. It is used to test each possible match, and 602function of one argument, unless @var{collection} is a hash table, in
577the match is accepted only if @var{predicate} returns non-@code{nil}. 603which case it should be a function of two arguments. It is used to
578The argument given to @var{predicate} is either a string from the 604test each possible match, and the match is accepted only if
579list, a cons cell from the alist (the @sc{car} of which is a string) 605@var{predicate} returns non-@code{nil}. The argument given to
580or a symbol (@emph{not} a symbol name) from the obarray. 606@var{predicate} is either a string or a cons cell (the @sc{car} of
607which is a string) from the alist, or a symbol (@emph{not} a symbol
608name) from the obarray. If @var{collection} is a hash table,
609@var{predicate} is called with two arguments, the string key and the
610associated value.
611
612In addition, to be acceptable, a completion must also match all the
613regular expressions in @code{completion-regexp-list}. (Unless
614@var{collection} is a function, in which case that function has to
615handle @code{completion-regexp-list} itself.)
581 616
582In the first of the following examples, the string @samp{foo} is 617In the first of the following examples, the string @samp{foo} is
583matched by three of the alist @sc{car}s. All of the matches begin with 618matched by three of the alist @sc{car}s. All of the matches begin with
@@ -633,10 +668,13 @@ too short). Both of those begin with the string @samp{foobar}.
633 668
634@defun all-completions string collection &optional predicate nospace 669@defun all-completions string collection &optional predicate nospace
635This function returns a list of all possible completions of 670This function returns a list of all possible completions of
636@var{string}. The arguments to this function (aside from @var{nospace}) 671@var{string}. The arguments to this function (aside from
637are the same as those of @code{try-completion}. If @var{nospace} is 672@var{nospace}) are the same as those of @code{try-completion}. Also,
638non-@code{nil}, completions that start with a space are ignored unless 673this function uses @code{completion-regexp-list} in the same way that
639@var{string} also starts with a space. 674@code{try-completion} does. The optional argument @var{nospace} only
675matters if @var{string} is the empty string. In that case, if
676@var{nospace} is non-@code{nil}, completions that start with a space
677are ignored.
640 678
641If @var{collection} is a function, it is called with three arguments: 679If @var{collection} is a function, it is called with three arguments:
642@var{string}, @var{predicate} and @code{t}; then @code{all-completions} 680@var{string}, @var{predicate} and @code{t}; then @code{all-completions}
@@ -662,13 +700,24 @@ example for @code{try-completion}:
662@end smallexample 700@end smallexample
663@end defun 701@end defun
664 702
703@anchor{Definition of test-completion}
665@defun test-completion string collection &optional predicate 704@defun test-completion string collection &optional predicate
666This function returns non-@code{nil} if @var{string} is a valid 705This function returns non-@code{nil} if @var{string} is a valid
667completion possibility specified by @var{collection} and 706completion possibility specified by @var{collection} and
668@var{predicate}. The other arguments are the same as in 707@var{predicate}. The arguments are the same as in
669@code{try-completion}. For instance, if @var{collection} is a list, 708@code{try-completion}. For instance, if @var{collection} is a list of
670this is true if @var{string} appears in the list and @var{predicate} 709strings, this is true if @var{string} appears in the list and
671is satisfied. 710@var{predicate} is satisfied.
711
712@code{test-completion} uses @code{completion-regexp-list} in the same
713way that @code{try-completion} does.
714
715If @var{predicate} is non-@code{nil} and if @var{collection} contains
716several strings that are equal to each other, as determined by
717@code{compare-strings} according to @code{completion-ignore-case},
718then @var{predicate} should accept either all or none of them.
719Otherwise, the return value of @code{test-completion} is essentially
720unpredictable.
672 721
673If @var{collection} is a function, it is called with three arguments, 722If @var{collection} is a function, it is called with three arguments,
674the values @var{string}, @var{predicate} and @code{lambda}; whatever 723the values @var{string}, @var{predicate} and @code{lambda}; whatever
@@ -680,6 +729,13 @@ If the value of this variable is non-@code{nil}, Emacs does not
680consider case significant in completion. 729consider case significant in completion.
681@end defvar 730@end defvar
682 731
732@defvar completion-regexp-list
733This is a list of regular expressions. The completion functions only
734consider a completion acceptable if it matches all regular expressions
735in this list, with @code{case-fold-search} (@pxref{Searching and Case})
736bound to the value of @code{completion-ignore-case}.
737@end defvar
738
683@defmac lazy-completion-table var fun &rest args 739@defmac lazy-completion-table var fun &rest args
684This macro provides a way to initialize the variable @var{var} as a 740This macro provides a way to initialize the variable @var{var} as a
685collection for completion in a lazy way, not computing its actual 741collection for completion in a lazy way, not computing its actual
@@ -711,8 +767,12 @@ providing completion. It activates the minibuffer with prompt
711@var{prompt}, which must be a string. 767@var{prompt}, which must be a string.
712 768
713The actual completion is done by passing @var{collection} and 769The actual completion is done by passing @var{collection} and
714@var{predicate} to the function @code{try-completion}. This happens in 770@var{predicate} to the function @code{try-completion}. This happens
715certain commands bound in the local keymaps used for completion. 771in certain commands bound in the local keymaps used for completion.
772Some of these commands also call @code{test-completion}. Thus, if
773@var{predicate} is non-@code{nil}, it should be compatible with
774@var{collection} and @code{completion-ignore-case}. @xref{Definition
775of test-completion}.
716 776
717If @var{require-match} is @code{nil}, the exit commands work regardless 777If @var{require-match} is @code{nil}, the exit commands work regardless
718of the input in the minibuffer. If @var{require-match} is @code{t}, the 778of the input in the minibuffer. If @var{require-match} is @code{t}, the
@@ -723,19 +783,13 @@ input already in the buffer matches an element of @var{collection}.
723 783
724However, empty input is always permitted, regardless of the value of 784However, empty input is always permitted, regardless of the value of
725@var{require-match}; in that case, @code{completing-read} returns 785@var{require-match}; in that case, @code{completing-read} returns
726@var{default}. The value of @var{default} (if non-@code{nil}) is also 786@var{default}, or @code{""}, if @var{default} is @code{nil}. The
727available to the user through the history commands. 787value of @var{default} (if non-@code{nil}) is also available to the
728 788user through the history commands.
729The user can exit with null input by typing @key{RET} with an empty 789
730minibuffer. Then @code{completing-read} returns @code{""}. This is how 790The function @code{completing-read} uses
731the user requests whatever default the command uses for the value being 791@code{minibuffer-local-completion-map} as the keymap if
732read. The user can return using @key{RET} in this way regardless of the 792@var{require-match} is @code{nil}, and uses
733value of @var{require-match}, and regardless of whether the empty string
734is included in @var{collection}.
735
736The function @code{completing-read} works by calling
737@code{read-minibuffer}. It uses @code{minibuffer-local-completion-map}
738as the keymap if @var{require-match} is @code{nil}, and uses
739@code{minibuffer-local-must-match-map} if @var{require-match} is 793@code{minibuffer-local-must-match-map} if @var{require-match} is
740non-@code{nil}. @xref{Completion Commands}. 794non-@code{nil}. @xref{Completion Commands}.
741 795
@@ -744,15 +798,21 @@ saving the input and for minibuffer history commands. It defaults to
744@code{minibuffer-history}. @xref{Minibuffer History}. 798@code{minibuffer-history}. @xref{Minibuffer History}.
745 799
746If @var{initial} is non-@code{nil}, @code{completing-read} inserts it 800If @var{initial} is non-@code{nil}, @code{completing-read} inserts it
747into the minibuffer as part of the input. Then it allows the user to 801into the minibuffer as part of the input, with point at the end. Then
748edit the input, providing several commands to attempt completion. 802it allows the user to edit the input, providing several commands to
749In most cases, we recommend using @var{default}, and not @var{initial}. 803attempt completion. @var{initial} can also be a cons cell of the form
804@code{(@var{string} . @var{position})}. In that case, point is put at
805@emph{zero-indexed} position @var{position} in @var{string}. Note
806that this is different from @code{read-from-minibuffer} and related
807functions, which use a one-indexed position. In most cases, we
808recommend using @var{default}, and not @var{initial}.
750 809
751@strong{We discourage use of a non-@code{nil} value for 810@strong{We discourage use of a non-@code{nil} value for
752@var{initial}}, because it is an intrusive interface. The history 811@var{initial}}, because it is an intrusive interface. The history
753list feature (which did not exist when we introduced @var{initial}) 812list feature (which did not exist when we introduced @var{initial})
754offers a far more convenient and general way for the user to get the 813offers a far more convenient and general way for the user to get the
755default and edit it, and it is always available. 814default and edit it, and it is always available. For an exception to
815this rule, see @ref{Minibuffer History}.
756 816
757If the argument @var{inherit-input-method} is non-@code{nil}, then the 817If the argument @var{inherit-input-method} is non-@code{nil}, then the
758minibuffer inherits the current input method (@pxref{Input 818minibuffer inherits the current input method (@pxref{Input
@@ -799,8 +859,11 @@ see @ref{Completion Commands}.
799@node Completion Commands 859@node Completion Commands
800@subsection Minibuffer Commands that Do Completion 860@subsection Minibuffer Commands that Do Completion
801 861
802 This section describes the keymaps, commands and user options used in 862 This section describes the keymaps, commands and user options used
803the minibuffer to do completion. 863in the minibuffer to do completion. The description refers to the
864situation when Partial Completion mode is disabled (as it is by
865default). When enabled, this minor mode uses its own alternatives to
866some of the commands described below.
804 867
805@defvar minibuffer-local-completion-map 868@defvar minibuffer-local-completion-map
806@code{completing-read} uses this value as the local keymap when an 869@code{completing-read} uses this value as the local keymap when an
@@ -820,7 +883,7 @@ keymap makes the following bindings:
820 883
821@noindent 884@noindent
822with other characters bound as in @code{minibuffer-local-map} 885with other characters bound as in @code{minibuffer-local-map}
823(@pxref{Text from Minibuffer}). 886(@pxref{Definition of minibuffer-local-map}).
824@end defvar 887@end defvar
825 888
826@defvar minibuffer-local-must-match-map 889@defvar minibuffer-local-must-match-map
@@ -852,8 +915,8 @@ with other characters bound as in @code{minibuffer-local-map}.
852@end defvar 915@end defvar
853 916
854@defvar minibuffer-completion-table 917@defvar minibuffer-completion-table
855The value of this variable is the alist or obarray used for completion 918The value of this variable is the collection used for completion in
856in the minibuffer. This is the global variable that contains what 919the minibuffer. This is the global variable that contains what
857@code{completing-read} passes to @code{try-completion}. It is used by 920@code{completing-read} passes to @code{try-completion}. It is used by
858minibuffer completion commands such as @code{minibuffer-complete-word}. 921minibuffer completion commands such as @code{minibuffer-complete-word}.
859@end defvar 922@end defvar
@@ -907,8 +970,10 @@ This function displays @var{completions} to the stream in
907information about streams.) The argument @var{completions} is normally 970information about streams.) The argument @var{completions} is normally
908a list of completions just returned by @code{all-completions}, but it 971a list of completions just returned by @code{all-completions}, but it
909does not have to be. Each element may be a symbol or a string, either 972does not have to be. Each element may be a symbol or a string, either
910of which is simply printed, or a list of two strings, which is printed 973of which is simply printed. It can also be a list of two strings,
911as if the strings were concatenated. 974which is printed as if the strings were concatenated. The first of
975the two strings is the actual completion, the second string serves as
976annotation.
912 977
913This function is called by @code{minibuffer-completion-help}. The 978This function is called by @code{minibuffer-completion-help}. The
914most common way to use it is together with 979most common way to use it is together with
@@ -948,9 +1013,10 @@ is not inserted in the minibuffer as initial input.
948If @var{existing} is non-@code{nil}, then the name specified must be 1013If @var{existing} is non-@code{nil}, then the name specified must be
949that of an existing buffer. The usual commands to exit the minibuffer 1014that of an existing buffer. The usual commands to exit the minibuffer
950do not exit if the text is not valid, and @key{RET} does completion to 1015do not exit if the text is not valid, and @key{RET} does completion to
951attempt to find a valid name. (However, @var{default} is not checked 1016attempt to find a valid name. If @var{existing} is neither @code{nil}
952for validity; it is returned, whatever it is, if the user exits with the 1017nor @code{t}, confirmation is required after completion. (However,
953minibuffer empty.) 1018@var{default} is not checked for validity; it is returned, whatever it
1019is, if the user exits with the minibuffer empty.)
954 1020
955In the following example, the user enters @samp{minibuffer.t}, and 1021In the following example, the user enters @samp{minibuffer.t}, and
956then types @key{RET}. The argument @var{existing} is @code{t}, and the 1022then types @key{RET}. The argument @var{existing} is @code{t}, and the
@@ -996,7 +1062,8 @@ The argument @var{default} specifies what to return if the user enters
996null input. It can be a symbol or a string; if it is a string, 1062null input. It can be a symbol or a string; if it is a string,
997@code{read-command} interns it before returning it. If @var{default} is 1063@code{read-command} interns it before returning it. If @var{default} is
998@code{nil}, that means no default has been specified; then if the user 1064@code{nil}, that means no default has been specified; then if the user
999enters null input, the return value is @code{nil}. 1065enters null input, the return value is @code{(intern "")}, that is, a
1066symbol whose name is an empty string.
1000 1067
1001@example 1068@example
1002(read-command "Command name? ") 1069(read-command "Command name? ")
@@ -1041,7 +1108,7 @@ The argument @var{default} specifies what to return if the user enters
1041null input. It can be a symbol or a string; if it is a string, 1108null input. It can be a symbol or a string; if it is a string,
1042@code{read-variable} interns it before returning it. If @var{default} 1109@code{read-variable} interns it before returning it. If @var{default}
1043is @code{nil}, that means no default has been specified; then if the 1110is @code{nil}, that means no default has been specified; then if the
1044user enters null input, the return value is @code{nil}. 1111user enters null input, the return value is @code{(intern "")}.
1045 1112
1046@example 1113@example
1047@group 1114@group
@@ -1090,10 +1157,7 @@ of the default directory.
1090 1157
1091@defun read-file-name prompt &optional directory default existing initial predicate 1158@defun read-file-name prompt &optional directory default existing initial predicate
1092This function reads a file name in the minibuffer, prompting with 1159This function reads a file name in the minibuffer, prompting with
1093@var{prompt} and providing completion. If @var{default} is 1160@var{prompt} and providing completion.
1094non-@code{nil}, then the function returns @var{default} if the user just
1095types @key{RET}. @var{default} is not checked for validity; it is
1096returned, whatever it is, if the user exits with the minibuffer empty.
1097 1161
1098If @var{existing} is non-@code{nil}, then the user must specify the name 1162If @var{existing} is non-@code{nil}, then the user must specify the name
1099of an existing file; @key{RET} performs completion to make the name 1163of an existing file; @key{RET} performs completion to make the name
@@ -1104,10 +1168,10 @@ value of @var{existing} is neither @code{nil} nor @code{t}, then
1104acceptable. 1168acceptable.
1105 1169
1106The argument @var{directory} specifies the directory to use for 1170The argument @var{directory} specifies the directory to use for
1107completion of relative file names. If @code{insert-default-directory} 1171completion of relative file names. It should be an absolute directory
1108is non-@code{nil}, @var{directory} is also inserted in the minibuffer as 1172name. If @code{insert-default-directory} is non-@code{nil},
1109initial input. It defaults to the current buffer's value of 1173@var{directory} is also inserted in the minibuffer as initial input.
1110@code{default-directory}. 1174It defaults to the current buffer's value of @code{default-directory}.
1111 1175
1112@c Emacs 19 feature 1176@c Emacs 19 feature
1113If you specify @var{initial}, that is an initial file name to insert 1177If you specify @var{initial}, that is an initial file name to insert
@@ -1118,11 +1182,45 @@ case, point goes at the beginning of @var{initial}. The default for
1118note:} we recommend using @var{default} rather than @var{initial} in 1182note:} we recommend using @var{default} rather than @var{initial} in
1119most cases. 1183most cases.
1120 1184
1185If @var{default} is non-@code{nil}, then the function returns
1186@var{default} if the user exits the minibuffer with the same non-empty
1187contents that @code{read-file-name} inserted initially. The initial
1188minibuffer contents are always non-empty if
1189@code{insert-default-directory} is non-@code{nil}, as it is by
1190default. @var{default} is not checked for validity, regardless of the
1191value of @var{existing}. However, if @var{existing} is
1192non-@code{nil}, the initial minibuffer contents should be a valid file
1193(or directory) name. Otherwise @code{read-file-name} attempts
1194completion if the user exits without any editing, and does not return
1195@var{default}. @var{default} is also available through the history
1196commands.
1197
1198If @var{default} is @code{nil}, @code{read-file-name} tries to find a
1199substitute default to use in its place, which it treats in exactly the
1200same way as if it had been specified explicitly. If @var{default} is
1201@code{nil}, but @var{initial} is non-@code{nil}, then the default is
1202the absolute file name obtained from @var{directory} and
1203@var{initial}. If both @var{default} and @var{initial} are @code{nil}
1204and the buffer is visiting a file, @code{read-file-name} uses the
1205absolute file name of that file as default. If the buffer is not
1206visiting a file, then there is no default. In that case, if the user
1207types @key{RET} without any editing, @code{read-file-name} simply
1208returns the pre-inserted contents of the minibuffer.
1209
1210If the user types @key{RET} in an empty minibuffer, this function
1211returns an empty string, regardless of the value of @var{existing}.
1212This is, for instance, how the user can make the current buffer visit
1213no file using @code{M-x set-visited-file-name}.
1214
1121If @var{predicate} is non-@code{nil}, it specifies a function of one 1215If @var{predicate} is non-@code{nil}, it specifies a function of one
1122argument that decides which file names are acceptable completion 1216argument that decides which file names are acceptable completion
1123possibilities. A file name is an acceptable value if @var{predicate} 1217possibilities. A file name is an acceptable value if @var{predicate}
1124returns non-@code{nil} for it. 1218returns non-@code{nil} for it.
1125 1219
1220@code{read-file-name} does not automatically expand file names. You
1221must call @code{expand-file-name} yourself if an absolute file name is
1222required.
1223
1126Here is an example: 1224Here is an example:
1127 1225
1128@example 1226@example
@@ -1160,17 +1258,35 @@ as the string @code{"/gp/gnu/elisp/manual.texi"}.
1160@defun read-directory-name prompt &optional directory default existing initial 1258@defun read-directory-name prompt &optional directory default existing initial
1161This function is like @code{read-file-name} but allows only directory 1259This function is like @code{read-file-name} but allows only directory
1162names as completion possibilities. 1260names as completion possibilities.
1261
1262If @var{default} is @code{nil} and @var{initial} is non-@code{nil},
1263@code{read-directory-name} constructs a substitute default by
1264combining @var{directory} (or the current buffer's default directory
1265if @var{directory} is @code{nil}) and @var{initial}. If both
1266@var{default} and @var{initial} are @code{nil}, this function uses the
1267current buffer's default directory as substitute default, ignoring
1268@var{directory}.
1163@end defun 1269@end defun
1164 1270
1165@defopt insert-default-directory 1271@defopt insert-default-directory
1166This variable is used by @code{read-file-name}. Its value controls 1272This variable is used by @code{read-file-name}, and thus, indirectly,
1167whether @code{read-file-name} starts by placing the name of the default 1273by most commands reading file names. (This includes all commands that
1168directory in the minibuffer, plus the initial file name if any. If the 1274use the code letters @samp{f} or @samp{F} in their interactive form.
1169value of this variable is @code{nil}, then @code{read-file-name} does 1275@xref{Interactive Codes,, Code Characters for interactive}.) Its
1170not place any initial input in the minibuffer (unless you specify 1276value controls whether @code{read-file-name} starts by placing the
1171initial input with the @var{initial} argument). In that case, the 1277name of the default directory in the minibuffer, plus the initial file
1172default directory is still used for completion of relative file names, 1278name if any. If the value of this variable is @code{nil}, then
1173but is not displayed. 1279@code{read-file-name} does not place any initial input in the
1280minibuffer (unless you specify initial input with the @var{initial}
1281argument). In that case, the default directory is still used for
1282completion of relative file names, but is not displayed.
1283
1284If this variable is @code{nil} and the initial minibuffer contents are
1285empty, the user may have to explicitly fetch the next history element
1286to access a default value. If the variable is non-@code{nil}, the
1287initial minibuffer contents are always non-empty and the user can
1288always request a default value by immediately typing @key{RET} in an
1289unedited minibuffer. (See above.)
1174 1290
1175For example: 1291For example:
1176 1292
@@ -1627,9 +1743,10 @@ The current value of this variable is used to rebind @code{help-form}
1627locally inside the minibuffer (@pxref{Help Functions}). 1743locally inside the minibuffer (@pxref{Help Functions}).
1628@end defvar 1744@end defvar
1629 1745
1630@defun minibufferp &optional buffer 1746@defun minibufferp &optional buffer-or-name
1631This function returns non-@code{nil} if @var{buffer} is a minibuffer. 1747This function returns non-@code{nil} if @var{buffer-or-name} is a
1632If @var{buffer} is omitted, it tests the current buffer. 1748minibuffer. If @var{buffer-or-name} is omitted, it tests the current
1749buffer.
1633@end defun 1750@end defun
1634 1751
1635@defun active-minibuffer-window 1752@defun active-minibuffer-window
@@ -1654,8 +1771,10 @@ choosing the minibuffer window according to the current frame.
1654@end defun 1771@end defun
1655 1772
1656@c Emacs 19 feature 1773@c Emacs 19 feature
1657@defun window-minibuffer-p window 1774@defun window-minibuffer-p &optional window
1658This function returns non-@code{nil} if @var{window} is a minibuffer window. 1775This function returns non-@code{nil} if @var{window} is a minibuffer
1776window.
1777@var{window} defaults to the selected window.
1659@end defun 1778@end defun
1660 1779
1661It is not correct to determine whether a given window is a minibuffer by 1780It is not correct to determine whether a given window is a minibuffer by
@@ -1704,14 +1823,16 @@ another window to do it.
1704@c Emacs 19 feature 1823@c Emacs 19 feature
1705If a command name has a property @code{enable-recursive-minibuffers} 1824If a command name has a property @code{enable-recursive-minibuffers}
1706that is non-@code{nil}, then the command can use the minibuffer to read 1825that is non-@code{nil}, then the command can use the minibuffer to read
1707arguments even if it is invoked from the minibuffer. The minibuffer 1826arguments even if it is invoked from the minibuffer. A command can
1708command @code{next-matching-history-element} (normally @kbd{M-s} in the 1827also achieve this by binding @code{enable-recursive-minibuffers}
1709minibuffer) uses this feature. 1828to @code{t} in the interactive declaration (@pxref{Using Interactive}).
1829The minibuffer command @code{next-matching-history-element} (normally
1830@kbd{M-s} in the minibuffer) does the latter.
1710 1831
1711@defun minibuffer-message string &optional timeout 1832@defun minibuffer-message string
1712This function displays @var{string} temporarily at the end of the 1833This function displays @var{string} temporarily at the end of the
1713minibuffer text, for @var{timeout} seconds. (The default is 2 1834minibuffer text, for two seconds, or until the next input event
1714seconds.) 1835arrives, whichever comes first.
1715@end defun 1836@end defun
1716 1837
1717@ignore 1838@ignore
diff --git a/lispref/positions.texi b/lispref/positions.texi
index 72b84a6a0ce..1dee0398050 100644
--- a/lispref/positions.texi
+++ b/lispref/positions.texi
@@ -409,6 +409,13 @@ Here is an example of using @code{count-lines}:
409@end example 409@end example
410@end defun 410@end defun
411 411
412@defun line-number-at-pos &optional pos
413@cindex line number
414This function returns the line number in the current buffer
415corresponding the buffer position @var{pos}. If @var{pos} is nil or
416omitted, the current buffer position is used.
417@end defun
418
412@ignore 419@ignore
413@c ================ 420@c ================
414The @code{previous-line} and @code{next-line} commands are functions 421The @code{previous-line} and @code{next-line} commands are functions
diff --git a/lispref/tips.texi b/lispref/tips.texi
index 585ec8ee475..c78d13f947e 100644
--- a/lispref/tips.texi
+++ b/lispref/tips.texi
@@ -802,19 +802,30 @@ Comments that start with three semicolons, @samp{;;;}, should start at
802the left margin. These are used, occasionally, for comments within 802the left margin. These are used, occasionally, for comments within
803functions that should start at the margin. We also use them sometimes 803functions that should start at the margin. We also use them sometimes
804for comments that are between functions---whether to use two or three 804for comments that are between functions---whether to use two or three
805semicolons there is a matter of style. 805semicolons depends on whether the comment should be considered a
806``heading'' by Outline minor mode. By default, comments starting with
807at least three semicolons (followed by a single space and a
808non-whitespace character) are considered headings, comments starting
809with two or less are not.
806 810
807Another use for triple-semicolon comments is for commenting out lines 811Another use for triple-semicolon comments is for commenting out lines
808within a function. We use three semicolons for this precisely so that 812within a function. We use three semicolons for this precisely so that
809they remain at the left margin. 813they remain at the left margin. By default, Outline minor mode does
814not consider a comment to be a heading (even if it starts with at
815least three semicolons) if the semicolons are followed by at least two
816spaces. Thus, if you add an introductory comment to the commented out
817code, make sure to indent it by at least two spaces after the three
818semicolons.
810 819
811@smallexample 820@smallexample
812(defun foo (a) 821(defun foo (a)
813;;; This is no longer necessary. 822;;; This is no longer necessary.
814;;; (force-mode-line-update) 823;;; (force-mode-line-update)
815 (message "Finished with %s" a)) 824 (message "Finished with %s" a))
816@end smallexample 825@end smallexample
817 826
827When commenting out entire functions, use two semicolons.
828
818@item ;;;; 829@item ;;;;
819Comments that start with four semicolons, @samp{;;;;}, should be aligned 830Comments that start with four semicolons, @samp{;;;;}, should be aligned
820to the left margin and are used for headings of major sections of a 831to the left margin and are used for headings of major sections of a
diff --git a/man/ChangeLog b/man/ChangeLog
index 0cb867e5af1..02c2aed55a9 100644
--- a/man/ChangeLog
+++ b/man/ChangeLog
@@ -1,3 +1,18 @@
12004-02-15 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2
3 * frames.texi (Drag and drop): Add Motif to list of supported
4 protocols.
5
62004-02-14 Jonathan Yavner <jyavner@member.fsf.org>
7
8 * ses.texi (Advanced Features): New functionality for
9 ses-set-header-row (defaults to current row unless C-u used).
10 (Acknowledgements): Added Stefan Monnier.
11
122004-02-03 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
13
14 * frames.texi (Drag and drop): New section.
15
12004-01-24 Richard M. Stallman <rms@gnu.org> 162004-01-24 Richard M. Stallman <rms@gnu.org>
2 17
3 * emacs.texi (Acknowledgments): Renamed from Acknowledgements. 18 * emacs.texi (Acknowledgments): Renamed from Acknowledgements.
diff --git a/man/frames.texi b/man/frames.texi
index 2663a417b10..7896adc41f6 100644
--- a/man/frames.texi
+++ b/man/frames.texi
@@ -48,6 +48,7 @@ under X.
48* Frame Parameters:: Changing the colors and other modes of frames. 48* Frame Parameters:: Changing the colors and other modes of frames.
49* Scroll Bars:: How to enable and disable scroll bars; how to use them. 49* Scroll Bars:: How to enable and disable scroll bars; how to use them.
50* Wheeled Mice:: Using mouse wheels for scrolling. 50* Wheeled Mice:: Using mouse wheels for scrolling.
51* Drag and drop:: Using drag and drop to open files and insert text.
51* Menu Bars:: Enabling and disabling the menu bar. 52* Menu Bars:: Enabling and disabling the menu bar.
52* Tool Bars:: Enabling and disabling the tool bar. 53* Tool Bars:: Enabling and disabling the tool bar.
53* Dialog Boxes:: Controlling use of dialog boxes. 54* Dialog Boxes:: Controlling use of dialog boxes.
@@ -795,6 +796,40 @@ generating appropriate events for Emacs.
795@code{mouse-wheel-scroll-amount} determine where and by how much 796@code{mouse-wheel-scroll-amount} determine where and by how much
796buffers are scrolled. 797buffers are scrolled.
797 798
799@node Drag and drop
800@section Drag and drop in Emacs.
801
802@cindex drag and drop
803 Emacs supports drag and drop so that dropping of files and text is handeled.
804Currently supported drag and drop protocols are XDND, Motif and the old
805KDE 1.x protocol. There is no drag support yet.
806When text is dropped on Emacs, Emacs inserts the text where it is dropped.
807When a file is dragged from a file manager to Emacs, Emacs opens that file.
808As a special case, if a file is dropped on a dired buffer the file is
809copied or moved (depends on exactly how it is dragged and the application
810it was dragged from) to the directory the dired buffer is displaying.
811
812@vindex x-dnd-open-file-other-window
813 A file is normally opened in the window it is dropped on, but if you
814prefer the file to be opened in a new window you can customize the variable
815@code{x-dnd-open-file-other-window}.
816
817@vindex x-dnd-types-alist
818 If you want to change the way Emacs handles drop of different types
819or add a new type, you shall customize @code{x-dnd-types-alist}. This
820requires detailed knowledge of what types other applications use
821for drag and drop.
822
823@vindex x-dnd-protocol-alist
824 When an URL is dropped on Emacs it may be a file, but it may also be
825another URL type (ftp, http, etc.). Emacs first checks
826@code{x-dnd-protocol-alist} to determine what to do with the URL. If there
827is no match there and if @code{browse-url-browser-function} is an alist,
828Emacs looks for a match there. If no match is found the text for the URL
829is inserted. If you want to alter Emacs behaviour you can customize these
830variables.
831
832
798@node Menu Bars 833@node Menu Bars
799@section Menu Bars 834@section Menu Bars
800@cindex Menu Bar mode 835@cindex Menu Bar mode
diff --git a/man/ses.texi b/man/ses.texi
index 05f321fb4ff..ecdc5eed8ba 100644
--- a/man/ses.texi
+++ b/man/ses.texi
@@ -406,11 +406,15 @@ safety belts!
406 406
407@table @kbd 407@table @kbd
408@item C-c M-C-h 408@item C-c M-C-h
409(@code{ses-read-header-row}). The header line at the top of the SES 409(@code{ses-set-header-row}). The header line at the top of the SES
410window normally shows the column letter for each column. You can set 410window normally shows the column letter for each column. You can set
411it to show a copy of some row, such as a row of column titles, so that 411it to show a copy of some row, such as a row of column titles, so that
412row will always be visible. Set the header line to row 0 to show 412row will always be visible. Default is to set the current row as the
413column letters again. 413header; use C-u to prompt for header row. Set the header to row 0 to
414show column letters again.
415@item [header-line mouse-3]
416Pops up a menu to set the current row as the header, or revert to
417column letters.
414@end table 418@end table
415 419
416@menu 420@menu
@@ -816,6 +820,13 @@ cell.
816@node Acknowledgements, , For Gurus, Top 820@node Acknowledgements, , For Gurus, Top
817@chapter Acknowledgements 821@chapter Acknowledgements
818 822
823Coding by:
824@quotation
825Jonathan Yavner @email{jyavner@@member.fsf.org}@*
826Stefan Monnier @email{monnier@@gnu.org}
827@end quotation
828
829Ideas from:
819@quotation 830@quotation
820Christoph Conrad @email{christoph.conrad@@gmx.de}@* 831Christoph Conrad @email{christoph.conrad@@gmx.de}@*
821CyberBob @email{cyberbob@@redneck.gacracker.org}@* 832CyberBob @email{cyberbob@@redneck.gacracker.org}@*
@@ -832,6 +843,7 @@ Pedro Pinto @email{ppinto@@cs.cmu.edu}@*
832Stefan Reichör @email{xsteve@@riic.at}@* 843Stefan Reichör @email{xsteve@@riic.at}@*
833Oliver Scholz @email{epameinondas@@gmx.de}@* 844Oliver Scholz @email{epameinondas@@gmx.de}@*
834Richard M. Stallman @email{rms@@gnu.org}@* 845Richard M. Stallman @email{rms@@gnu.org}@*
846Luc Teirlinck @email{teirllm@@dms.auburn.edu}@*
835J. Otto Tennant @email{jotto@@pobox.com}@* 847J. Otto Tennant @email{jotto@@pobox.com}@*
836Jean-Philippe Theberge @email{jphil@@acs.pagesjaunes.fr} 848Jean-Philippe Theberge @email{jphil@@acs.pagesjaunes.fr}
837@end quotation 849@end quotation
diff --git a/src/ChangeLog b/src/ChangeLog
index 76d63cab844..179b7a16a48 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,285 @@
12004-02-16 Stephen Eglen <stephen@gnu.org>
2
3 * fringe.c (init_fringe_bitmap): Define j in MAC_OS code.
4
52004-02-15 Stefan Monnier <monnier@iro.umontreal.ca>
6
7 * data.c (Fbyteorder):
8 * fringe.c (Fdefine_fringe_bitmap):
9 * xdisp.c (handle_single_display_prop):
10 * xselect.c (x_handle_dnd_message): Lisp_Object/int mixup.
11
122004-02-16 Jason Rumney <jasonr@gnu.org>
13
14 * w32term.c (w32_draw_fringe_bitmap): Handle overlay fringe bitmaps.
15
162004-02-15 Steven Tamm <steventamm@mac.com>
17
18 * macterm.c (Vmac_emulate_three_button_mouse): New variable for
19 controlling emulation of a three button mouse with option and
20 command keys.
21 (Qreverse, mac_get_enumlated_btn): Handle the emulation
22 (mac_event_to_emacs_modifiers, XTread_socket): Ditto
23
242004-02-15 Kim F. Storm <storm@cua.dk>
25
26 * buffer.c (syms_of_buffer): Doc fix for indicate-buffer-boundaries.
27
28 * fringe.c (init_fringe_bitmap) [MAC_OS, WORDS_BIG_ENDIAN]:
29 Perform byte-swapping.
30
312004-02-14 Kim F. Storm <storm@cua.dk>
32
33 * dispextern.h (struct draw_fringe_bitmap_params): Change member
34 bits from char to short to facilitate wider bitmaps.
35 (struct redisplay_interface): Fix prototype of define_fringe_bitmap
36 member.
37
38 * fringe.c (struct fringe_bitmap): Change member bits from char to
39 short to facilitate 16 bits wide bitmaps. Modify all standard
40 bitmaps accordingly.
41 (BYTES_PER_BITMAP_ROW, STANDARD_BITMAP_HEIGHT): New macros.
42 (FRBITS): Use STANDARD_BITMAP_HEIGHT instead of just sizeof.
43 (draw_fringe_bitmap): Ditto.
44 (init_fringe_bitmap) [MAC_OS]: Don't bitswap.
45 (init_fringe_bitmap) [HAVE_X_WINDOWS]: Enhance bitswapping to
46 handle up to 16 bits wide bitmaps.
47 (Fdefine_fringe_bitmap): Doc fix. Handle wider bitmaps.
48 (Ffringe_bitmaps_at_pos): Add missing arg declarations.
49
50 * macterm.c (mac_draw_bitmap): Handle 16 bits wide bitmaps directly.
51 (x_draw_fringe_bitmap): Use enhanced mac_draw_bitmap, so we no longer
52 need to call mac_create_bitmap_from_bitmap_data and mac_free_bitmap.
53
54 * w32term.c (w32_define_fringe_bitmap): Bitmaps are now 16 bits wide,
55 so it is no longer necessary to expand them here.
56
57 * xterm.c (x_draw_fringe_bitmap): Handle wider bitmaps (max 16 bits).
58
592004-02-12 Kim F. Storm <storm@cua.dk>
60
61 * window.c (Fwindow_fringes): Doc fix.
62
632004-02-10 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
64
65 * xselect.c (x_get_foreign_selection): Add new optional parameter
66 time_stamp.
67 (Fx_get_selection_internal): Ditto, pass time_stamp to
68 x_get_foreign_selection.
69
70 * data.c (Fbyteorder): New function.
71
722004-02-09 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
73
74 * atimer.c: Move include stdio.h to same place as in other files.
75
76 * region-cache.c: Ditto.
77
78 * sysdep.c: Ditto.
79
80 * xfaces.c: Ditto.
81
822004-02-09 Sam Steingold <sds@gnu.org>
83
84 * w32term.c (w32_draw_fringe_bitmap): Fixed a typo in the last patch.
85
862004-02-09 Kim F. Storm <storm@cua.dk>
87
88 * fringe.c: New file. Move original fringe related declarations
89 and code from dispextern.h and xdisp.c here.
90 Rework code to support user defined fringe bitmaps, redefining
91 standard bitmaps, ability to overlay user defined bitmap with
92 overlay arrow bitmap, and add faces to bitmaps.
93 (Voverflow_newline_into_fringe): Declare here.
94 (enum fringe_bitmap_align): New enum.
95 (..._bits): All bitmaps are now defined without bitswapping; that
96 is now done in init_fringe_once (if necessary).
97 (standard_bitmaps): New array with specifications for the
98 standard fringe bitmaps.
99 (fringe_faces): New array.
100 (valid_fringe_bitmap_id_p): New function.
101 (draw_fringe_bitmap_1): Rename from draw_fringe_bitmap.
102 (draw_fringe_bitmap): New function which draws fringe bitmap,
103 possibly overlaying bitmap with cursor in right fringe or the
104 overlay arrow in the left fringe.
105 (update_window_fringes): Do not handle overlay arrow here.
106 Compare and copy fringe bitmap faces.
107 (init_fringe_bitmap): New function.
108 (Fdefine_fringe_bitmap, Fdestroy_fringe_bitmap): New DEFUNs to
109 define and destroy user defined fringe bitmaps.
110 (Fset_fringe_bitmap_face): New DEFUN to set face for a fringe bitmap.
111 (Ffringe_bitmaps_at_pos): New DEFUN to read current fringe bitmaps.
112 (syms_of_fringe): New function. Defsubr new DEFUNs.
113 DEFVAR_LISP Voverflow_newline_into_fringe.
114 (init_fringe_once, init_fringe): New functions.
115 (w32_init_fringe, w32_reset_fringes) [WINDOWS_NT]: New functions.
116
117 * Makefile.in (obj): Add fringe.o.
118 (fringe.o): New dependencies.
119
120 * dispextern.h (FRINGE_ID_BITS): New definition for number of
121 bits allocated to hold a fringe number. Increase number of bits
122 from 4 to 8 to allow user defined fringe bitmaps.
123 (struct glyph_row, struct it): New members left_user_fringe_bitmap,
124 left_user_fringe_face_id, right_user_fringe_bitmap,
125 right_user_fringe_face_id.
126 (enum fringe_bitmap_type, struct fringe_bitmap, fringe_bitmaps):
127 Move to new file fringe.c.
128 (MAX_FRINGE_BITMAPS): Define here.
129 (struct draw_fringe_bitmap_params): New members bits, cursor_p,
130 and overlay_p. Change member which to int.
131 (struct redisplay_interface): New members define_fringe_bitmap
132 and destroy_fringe_bitmap.
133 (valid_fringe_bitmap_id_p): Add prototype.
134 (w32_init_fringe, w32_reset_fringes) [WINDOWS_NT]: Add prototypes.
135
136 * dispnew.c (row_equal_p): Compare fringe bitmap faces and overlay
137 arrows.
138 (update_frame): Do flush_display if force_flush_display_p to
139 ensure display (specifically fringes) are updated in a timely
140 manner when resizing the frame by dragging the mouse.
141 (update_window_line): Update row if overlay arrow changed.
142 (scrolling_window): Redraw fringe bitmaps if fringe bitmap faces
143 or overlay arrow changed.
144
145 * emacs.c (main) [HAVE_WINDOW_SYSTEM]: Call init_fringe_once,
146 syms_of_fringe, and init_fringe.
147
148 * frame.h (struct frame): New member force_flush_display_p.
149
150 * lisp.h (syms_of_fringe, init_fringe, init_fringe_once):
151 Add prototypes.
152
153 * macterm.c (mac_draw_bitmap): Add overlay_p arg.
154 (x_draw_fringe_bitmap): Handle overlayed fringe bitmaps;
155 thanks to YAMAMOTO Mitsuharu for advice on how to do this.
156 Use cursor color for displaying cursor in fringe.
157 (x_redisplay_interface): Add null handlers for
158 define_fringe_bitmap and destroy_fringe_bitmap functions.
159
160 * w32term.c (w32_draw_fringe_bitmap): Copy unadapted code from
161 xterm.c to handle overlayed fringe bitmaps and to use cursor color
162 for displaying cursor in fringe.
163 (w32_define_fringe_bitmap, w32_destroy_fringe_bitmap): New W32
164 specific functions to define and destroy fringe bitmaps in fringe_bmp.
165 (w32_redisplay_interface): Add them to redisplay_interface.
166 (w32_term_init): Call w32_init_fringe instead of explicitly
167 defining fringe bitmaps in fringe_bmp array.
168 (x_delete_display): Call w32_reset_fringes instead of explicitly
169 destroying fringe bitmaps in fringe_bmp array.
170
171 * xdisp.c (Voverflow_newline_into_fringe, syms_of_xdisp)
172 (left_bits, right_bits, up_arrow_bits, down_arrow_bits)
173 (continued_bits, continuation_bits, ov_bits, first_line_bits)
174 (last_line_bits, filled_box_cursor_bits, hollow_box_cursor_bits)
175 (bar_cursor_bits, hbar_cursor_bits, zv_bits, hollow_square_bits)
176 (fringe_bitmaps, draw_fringe_bitmap, draw_row_fringe_bitmaps)
177 (draw_window_fringes, compute_fringe_widths, update_window_fringes):
178 Move fringe handling vars and code to new file fringe.c.
179 (handle_display_prop): Handle left-fringe and right-fringe
180 display properties; store user fringe bitmaps in iterator.
181 (move_it_in_display_line_to): Handle cursor in fringe at eob.
182 (clear_garbaged_frames): Set force_flush_display_p if resized.
183 (redisplay_window): Redraw fringe bitmaps if not just_this_one_p.
184 (display_line): Handle cursor in fringe at eob.
185 (display_line): Set row user fringe bitmaps from iterator.
186
187 * xterm.c (x_draw_fringe_bitmap): Handle overlayed fringe bitmaps.
188 Use cursor color for displaying cursor in fringe.
189 (x_redisplay_interface): Add null handlers for
190 define_fringe_bitmap and destroy_fringe_bitmap functions.
191
1922004-02-07 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
193
194 * macfns.c (Fx_change_window_property): Make doc string and
195 parameters same as for X version.
196
197 * w32fns.c (Fx_change_window_property): Ditto.
198
1992004-02-07 Kim F. Storm <storm@cua.dk>
200
201 * xdisp.c (hscroll_window_tree): Position cursor near to right
202 margin in hscrolled window when jumping to end of line (rather
203 than centering cursor).
204
205 * process.c (wait_reading_process_input): Don't do adaptive read
206 buffering if waiting for a specific process.
207
2082004-02-05 Luc Teirlinck <teirllm@auburn.edu>
209
210 * minibuf.c (Fminibufferp, Fread_from_minibuffer)
211 (Fread_minibuffer, Feval_minibuffer)
212 (Fread_string, Fread_no_blanks_input)
213 (Fcompleting_read): Doc fixes.
214 (syms_of_minibuf): Doc fixes for minibuffer-completion-table and
215 completion-regexp-list. Define Qcase_fold_search and staticpro it.
216 (read_minibuf): Fix initial comment.
217 (Ftry_completion, Fall_completions, Ftest_completion): Bind
218 case-fold-serach to the value of completion-ignore-case when
219 checking completion-regexp-list.
220 (Fdisplay_completion_list): Make it handle arguments that are
221 symbols. Doc fix.
222
2232004-02-05 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
224
225 * xterm.h: Add declaration of free_frame_menubar.
226
227 * xfns.c (x_create_bitmap_mask): Removed unused variable depth.
228 (x_set_menu_bar_lines): Added ! defined USE_GTK for olines.
229 (Fx_change_window_property): Add declaration of parameters type and
230 format. Remove unused variable cons.
231
232 * xselect.c: Include stdio,h.
233
2342004-02-05 Kenichi Handa <handa@m17n.org>
235
236 * fns.c (Fset_char_table_range): Fix previous change.
237
238 * buffer.c (Fset_buffer_multibyte): Fix docstring.
239
2402004-02-04 Luc Teirlinck <teirllm@auburn.edu>
241
242 * editfns.c (Fchar_after, Fchar_before): Doc fixes.
243
2442004-02-04 Stefan Monnier <monnier@iro.umontreal.ca>
245
246 * keymap.c (Vmouse_events): Rename from Vmenu_events.
247 (syms_of_keymap): Add mouse-[45], header-line, and mode-line to it.
248
2492004-02-04 Kenichi Handa <handa@m17n.org>
250
251 * fns.c (Fset_char_table_range): Handle charsets ascii,
252 eight-bit-control, and eight-bit-graphic correctly.
253
2542004-02-03 Jason Rumney <jasonr@gnu.org>
255
256 * w32select.c (Fw32_set_clipboard_data): Make coding iso2022 safe.
257
258 * w32fns.c (x_to_w32_font): Likewise.
259
2602004-02-03 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
261
262 * xterm.h: Add x_handle_dnd_message, x_check_property_data,
263 x_fill_property_data, x_property_data_to_lisp and check_x_display_info.
264
265 * xterm.c (handle_one_xevent): Call x_handle_dnd_message for
266 ClientMessages.
267
268 * xselect.c: Include termhooks.h and X11/Xproto.h
269 (x_check_property_data, x_fill_property_data)
270 (x_property_data_to_lisp, mouse_position_for_drop)
271 (Fx_get_atom_name, x_handle_dnd_message): New functions for DND support.
272 (Fx_send_client_event): Move here from xfns.c.
273 (syms_of_xselect): Add Sx_get_atom_name and Sx_send_client_message.
274
275 * xfns.c (x-send-client-message): Move to xselect.c
276 (Fx_change_window_property): Add optional arguments TYPE, FORMAT and
277 OUTER_P.
278 (Fx_window_property): Add optional arguments TYPE, SOURCE, DELETE_P,
279 VECTOR_RET_P. Handle AnyPropertyType. Call x_property_data_to_lisp
280 if vector_ret_p is true.
281 (syms_of_xfns): Sx_send_client_message moved to xselect.c.
282
12004-02-02 Eli Zaretskii <eliz@elta.co.il> 2832004-02-02 Eli Zaretskii <eliz@elta.co.il>
2 284
3 * fileio.c (Fcopy_file): If NEWNAME is a directory, expand the 285 * fileio.c (Fcopy_file): If NEWNAME is a directory, expand the
@@ -43,10 +325,9 @@
43 325
442004-01-27 Steven Tamm <steventamm@mac.com> 3262004-01-27 Steven Tamm <steventamm@mac.com>
45 327
46 * macterm.c (make_mac_frame, make_mac_terminal_frame): Move 328 * macterm.c (make_mac_frame, make_mac_terminal_frame):
47 setting of scroll bars from make_mac_frame to 329 Move setting of scroll bars from make_mac_frame to
48 make_mac_terminal_frame to prevent clobbering of 330 make_mac_terminal_frame to prevent clobbering of scroll-bar-mode.
49 scroll-bar-mode.
50 331
512004-01-26 Richard M. Stallman <rms@gnu.org> 3322004-01-26 Richard M. Stallman <rms@gnu.org>
52 333
diff --git a/src/Makefile.in b/src/Makefile.in
index 94579aed476..ac9cae31061 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -571,7 +571,7 @@ XMENU_OBJ = xmenu.o
571 571
572/* lastfile must follow all files 572/* lastfile must follow all files
573 whose initialized data areas should be dumped as pure by dump-emacs. */ 573 whose initialized data areas should be dumped as pure by dump-emacs. */
574obj= dispnew.o frame.o scroll.o xdisp.o $(XMENU_OBJ) window.o \ 574obj= dispnew.o frame.o scroll.o xdisp.o fringe.o $(XMENU_OBJ) window.o \
575 charset.o coding.o category.o ccl.o \ 575 charset.o coding.o category.o ccl.o \
576 cm.o term.o xfaces.o $(XOBJ) \ 576 cm.o term.o xfaces.o $(XOBJ) \
577 emacs.o keyboard.o macros.o keymap.o sysdep.o \ 577 emacs.o keyboard.o macros.o keymap.o sysdep.o \
@@ -1075,6 +1075,7 @@ filemode.o: filemode.c $(config_h)
1075frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \ 1075frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
1076 blockinput.h atimer.h systime.h buffer.h charset.h fontset.h \ 1076 blockinput.h atimer.h systime.h buffer.h charset.h fontset.h \
1077 msdos.h dosfns.h dispextern.h $(config_h) 1077 msdos.h dosfns.h dispextern.h $(config_h)
1078fringe.o: fringe.c dispextern.h frame.h window.h buffer.h $(config_h)
1078fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h charset.h frame.h \ 1079fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h charset.h frame.h \
1079 keyboard.h termhooks.h $(config_h) 1080 keyboard.h termhooks.h $(config_h)
1080getloadavg.o: getloadavg.c $(config_h) 1081getloadavg.o: getloadavg.c $(config_h)
diff --git a/src/atimer.c b/src/atimer.c
index 6b0e0777886..2ddc7427f56 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -19,13 +19,13 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */ 19Boston, MA 02111-1307, USA. */
20 20
21#include <config.h> 21#include <config.h>
22#include <lisp.h>
23#include <signal.h> 22#include <signal.h>
23#include <stdio.h>
24#include <lisp.h>
24#include <syssignal.h> 25#include <syssignal.h>
25#include <systime.h> 26#include <systime.h>
26#include <blockinput.h> 27#include <blockinput.h>
27#include <atimer.h> 28#include <atimer.h>
28#include <stdio.h>
29 29
30#ifdef HAVE_UNISTD_H 30#ifdef HAVE_UNISTD_H
31#include <unistd.h> 31#include <unistd.h>
diff --git a/src/buffer.c b/src/buffer.c
index fa5a9c85c2d..ad1dde93da7 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2081,7 +2081,9 @@ DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte,
2081If FLAG is t, this makes the buffer a multibyte buffer. 2081If FLAG is t, this makes the buffer a multibyte buffer.
2082If FLAG is nil, this makes the buffer a single-byte buffer. 2082If FLAG is nil, this makes the buffer a single-byte buffer.
2083The buffer contents remain unchanged as a sequence of bytes 2083The buffer contents remain unchanged as a sequence of bytes
2084but the contents viewed as characters do change. */) 2084but the contents viewed as characters do change.
2085If the multibyte flag was really changed, undo information of the
2086current buffer is cleared. */)
2085 (flag) 2087 (flag)
2086 Lisp_Object flag; 2088 Lisp_Object flag;
2087{ 2089{
@@ -5637,10 +5639,20 @@ window-systems. */);
5637 DEFVAR_PER_BUFFER ("indicate-buffer-boundaries", 5639 DEFVAR_PER_BUFFER ("indicate-buffer-boundaries",
5638 &current_buffer->indicate_buffer_boundaries, Qnil, 5640 &current_buffer->indicate_buffer_boundaries, Qnil,
5639 doc: /* *Visually indicate buffer boundaries and scrolling. 5641 doc: /* *Visually indicate buffer boundaries and scrolling.
5640If non-nil, the first and last line of the buffer are marked in the left and 5642If non-nil, the first and last line of the buffer are marked in the fringe
5641right fringe of a window on window-systems. 5643of a window on window-systems with angle bitmaps, or if the window can be
5642In addition, if value is t, the top and bottom line of the window are marked 5644scrolled, the top and bottom line of the window are marked with up and down
5643with up and down arrow bitmaps in the right fringe if window can be scrolled. */); 5645arrow bitmaps.
5646If value is `left' or `right', both angle and arrow bitmaps are displayed in
5647the left or right fringe, resp. Any other non-nil value causes the
5648bitmap on the top line to be displayed in the left fringe, and the
5649bitmap on the bottom line in the right fringe.
5650If value is a cons (ANGLES . ARROWS), the car specifies the position
5651of the angle bitmaps, and the cdr specifies the position of the arrow
5652bitmaps. For example, (t . right) places the top angle bitmap in left
5653fringe, the bottom angle bitmap in right fringe, and both arrow
5654bitmaps in right fringe. To show just the angle bitmaps in the left
5655fringe, but no arrow bitmaps, use (left . nil). */);
5644 5656
5645 DEFVAR_PER_BUFFER ("scroll-up-aggressively", 5657 DEFVAR_PER_BUFFER ("scroll-up-aggressively",
5646 &current_buffer->scroll_up_aggressively, Qnil, 5658 &current_buffer->scroll_up_aggressively, Qnil,
diff --git a/src/data.c b/src/data.c
index c4e3937f3fa..bff2baaed27 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2879,6 +2879,20 @@ DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
2879 XSETINT (number, ~XINT (number)); 2879 XSETINT (number, ~XINT (number));
2880 return number; 2880 return number;
2881} 2881}
2882
2883DEFUN ("byteorder", Fbyteorder, Sbyteorder, 0, 0, 0,
2884 doc: /* Return the byteorder for the machine.
2885Returns 66 (ASCII uppercase B) for big endian machines or 108 (ASCII
2886lowercase l) for small endian machines. */)
2887 ()
2888{
2889 unsigned i = 0x04030201;
2890 int order = *(char *)&i == 4 ? 66 : 108;
2891
2892 return make_number (order);
2893}
2894
2895
2882 2896
2883void 2897void
2884syms_of_data () 2898syms_of_data ()
@@ -3281,6 +3295,7 @@ syms_of_data ()
3281 defsubr (&Sadd1); 3295 defsubr (&Sadd1);
3282 defsubr (&Ssub1); 3296 defsubr (&Ssub1);
3283 defsubr (&Slognot); 3297 defsubr (&Slognot);
3298 defsubr (&Sbyteorder);
3284 defsubr (&Ssubr_arity); 3299 defsubr (&Ssubr_arity);
3285 3300
3286 XSYMBOL (Qwholenump)->function = XSYMBOL (Qnatnump)->function; 3301 XSYMBOL (Qwholenump)->function = XSYMBOL (Qnatnump)->function;
diff --git a/src/dispextern.h b/src/dispextern.h
index e157a2ff3e6..48893aa133d 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -126,6 +126,9 @@ enum window_part
126 ON_RIGHT_MARGIN 126 ON_RIGHT_MARGIN
127}; 127};
128 128
129/* Number of bits allocated to store fringe bitmap numbers. */
130#define FRINGE_ID_BITS 8
131
129 132
130 133
131/*********************************************************************** 134/***********************************************************************
@@ -710,10 +713,28 @@ struct glyph_row
710 struct display_pos end; 713 struct display_pos end;
711 714
712 /* Left fringe bitmap number (enum fringe_bitmap_type). */ 715 /* Left fringe bitmap number (enum fringe_bitmap_type). */
713 unsigned left_fringe_bitmap : 4; 716 unsigned left_user_fringe_bitmap : FRINGE_ID_BITS;
717
718 /* Face of the left fringe glyph. */
719 unsigned left_user_fringe_face_id : FACE_ID_BITS;
720
721 /* Right fringe bitmap number (enum fringe_bitmap_type). */
722 unsigned right_user_fringe_bitmap : FRINGE_ID_BITS;
723
724 /* Face of the right fringe glyph. */
725 unsigned right_user_fringe_face_id : FACE_ID_BITS;
726
727 /* Left fringe bitmap number (enum fringe_bitmap_type). */
728 unsigned left_fringe_bitmap : FRINGE_ID_BITS;
729
730 /* Face of the left fringe glyph. */
731 unsigned left_fringe_face_id : FACE_ID_BITS;
714 732
715 /* Right fringe bitmap number (enum fringe_bitmap_type). */ 733 /* Right fringe bitmap number (enum fringe_bitmap_type). */
716 unsigned right_fringe_bitmap : 4; 734 unsigned right_fringe_bitmap : FRINGE_ID_BITS;
735
736 /* Face of the right fringe glyph. */
737 unsigned right_fringe_face_id : FACE_ID_BITS;
717 738
718 /* 1 means that we must draw the bitmaps of this row. */ 739 /* 1 means that we must draw the bitmaps of this row. */
719 unsigned redraw_fringe_bitmaps_p : 1; 740 unsigned redraw_fringe_bitmaps_p : 1;
@@ -1609,35 +1630,6 @@ extern int face_change_count;
1609 Fringes 1630 Fringes
1610 ***********************************************************************/ 1631 ***********************************************************************/
1611 1632
1612enum fringe_bitmap_type
1613{
1614 NO_FRINGE_BITMAP = 0,
1615 LEFT_TRUNCATION_BITMAP,
1616 RIGHT_TRUNCATION_BITMAP,
1617 UP_ARROW_BITMAP,
1618 DOWN_ARROW_BITMAP,
1619 CONTINUED_LINE_BITMAP,
1620 CONTINUATION_LINE_BITMAP,
1621 OVERLAY_ARROW_BITMAP,
1622 FIRST_LINE_BITMAP,
1623 LAST_LINE_BITMAP,
1624 FILLED_BOX_CURSOR_BITMAP,
1625 HOLLOW_BOX_CURSOR_BITMAP,
1626 BAR_CURSOR_BITMAP,
1627 HBAR_CURSOR_BITMAP,
1628 ZV_LINE_BITMAP,
1629 HOLLOW_SQUARE_BITMAP,
1630 MAX_FRINGE_BITMAPS
1631};
1632
1633struct fringe_bitmap
1634{
1635 int width;
1636 int height;
1637 int period;
1638 unsigned char *bits;
1639};
1640
1641/* Structure used to describe where and how to draw a fringe bitmap. 1633/* Structure used to describe where and how to draw a fringe bitmap.
1642 WHICH is the fringe bitmap to draw. WD and H is the (adjusted) 1634 WHICH is the fringe bitmap to draw. WD and H is the (adjusted)
1643 width and height of the bitmap, DH is the height adjustment (if 1635 width and height of the bitmap, DH is the height adjustment (if
@@ -1648,14 +1640,17 @@ struct fringe_bitmap
1648 1640
1649struct draw_fringe_bitmap_params 1641struct draw_fringe_bitmap_params
1650{ 1642{
1651 enum fringe_bitmap_type which; 1643 int which; /* enum fringe_bitmap_type */
1644 unsigned short *bits;
1652 int wd, h, dh; 1645 int wd, h, dh;
1653 int x, y; 1646 int x, y;
1654 int bx, nx, by, ny; 1647 int bx, nx, by, ny;
1648 unsigned cursor_p : 1;
1649 unsigned overlay_p : 1;
1655 struct face *face; 1650 struct face *face;
1656}; 1651};
1657 1652
1658extern struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS]; 1653#define MAX_FRINGE_BITMAPS (1<<FRINGE_ID_BITS)
1659 1654
1660 1655
1661/*********************************************************************** 1656/***********************************************************************
@@ -2025,6 +2020,18 @@ struct it
2025 /* Horizontal matrix position reached in move_it_in_display_line. 2020 /* Horizontal matrix position reached in move_it_in_display_line.
2026 Only set there, not in display_line. */ 2021 Only set there, not in display_line. */
2027 int hpos; 2022 int hpos;
2023
2024 /* Left fringe bitmap number (enum fringe_bitmap_type). */
2025 unsigned left_user_fringe_bitmap : FRINGE_ID_BITS;
2026
2027 /* Face of the left fringe glyph. */
2028 unsigned left_user_fringe_face_id : FACE_ID_BITS;
2029
2030 /* Right fringe bitmap number (enum fringe_bitmap_type). */
2031 unsigned right_user_fringe_bitmap : FRINGE_ID_BITS;
2032
2033 /* Face of the right fringe glyph. */
2034 unsigned right_user_fringe_face_id : FACE_ID_BITS;
2028}; 2035};
2029 2036
2030 2037
@@ -2181,6 +2188,11 @@ struct redisplay_interface
2181 void (*draw_fringe_bitmap) P_ ((struct window *w, struct glyph_row *row, 2188 void (*draw_fringe_bitmap) P_ ((struct window *w, struct glyph_row *row,
2182 struct draw_fringe_bitmap_params *p)); 2189 struct draw_fringe_bitmap_params *p));
2183 2190
2191 /* Define and destroy fringe bitmap no. WHICH. */
2192 void (*define_fringe_bitmap) P_ ((int which, unsigned short *bits,
2193 int h, int wd));
2194 void (*destroy_fringe_bitmap) P_ ((int which));
2195
2184/* Get metrics of character CHAR2B in FONT of type FONT_TYPE. 2196/* Get metrics of character CHAR2B in FONT of type FONT_TYPE.
2185 Value is null if CHAR2B is not contained in the font. */ 2197 Value is null if CHAR2B is not contained in the font. */
2186 XCharStruct * (*per_char_metric) P_ ((XFontStruct *font, XChar2b *char2b, 2198 XCharStruct * (*per_char_metric) P_ ((XFontStruct *font, XChar2b *char2b,
@@ -2526,11 +2538,6 @@ void move_it_past_eol P_ ((struct it *));
2526int in_display_vector_p P_ ((struct it *)); 2538int in_display_vector_p P_ ((struct it *));
2527int frame_mode_line_height P_ ((struct frame *)); 2539int frame_mode_line_height P_ ((struct frame *));
2528void highlight_trailing_whitespace P_ ((struct frame *, struct glyph_row *)); 2540void highlight_trailing_whitespace P_ ((struct frame *, struct glyph_row *));
2529void draw_fringe_bitmap P_ ((struct window *, struct glyph_row *, int));
2530void draw_row_fringe_bitmaps P_ ((struct window *, struct glyph_row *));
2531void draw_window_fringes P_ ((struct window *));
2532int update_window_fringes P_ ((struct window *, int));
2533void compute_fringe_widths P_ ((struct frame *, int));
2534extern Lisp_Object Qtool_bar; 2541extern Lisp_Object Qtool_bar;
2535extern Lisp_Object Vshow_trailing_whitespace; 2542extern Lisp_Object Vshow_trailing_whitespace;
2536extern int mode_line_in_non_selected_windows; 2543extern int mode_line_in_non_selected_windows;
@@ -2600,6 +2607,20 @@ extern int x_intersect_rectangles P_ ((XRectangle *, XRectangle *,
2600 XRectangle *)); 2607 XRectangle *));
2601#endif 2608#endif
2602 2609
2610/* Defined in fringe.c */
2611
2612int valid_fringe_bitmap_id_p (int);
2613void draw_fringe_bitmap P_ ((struct window *, struct glyph_row *, int));
2614void draw_row_fringe_bitmaps P_ ((struct window *, struct glyph_row *));
2615void draw_window_fringes P_ ((struct window *));
2616int update_window_fringes P_ ((struct window *, int));
2617void compute_fringe_widths P_ ((struct frame *, int));
2618
2619#ifdef WINDOWS_NT
2620void w32_init_fringe P_ ((void));
2621void w32_reset_fringes P_ ((void));
2622#endif
2623
2603/* Defined in sysdep.c */ 2624/* Defined in sysdep.c */
2604 2625
2605void get_tty_size P_ ((int, int *, int *)); 2626void get_tty_size P_ ((int, int *, int *));
diff --git a/src/dispnew.c b/src/dispnew.c
index 1bd54a589c4..aaf3c440f34 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -1503,7 +1503,10 @@ row_equal_p (w, a, b, mouse_face_p)
1503 if (a->fill_line_p != b->fill_line_p 1503 if (a->fill_line_p != b->fill_line_p
1504 || a->cursor_in_fringe_p != b->cursor_in_fringe_p 1504 || a->cursor_in_fringe_p != b->cursor_in_fringe_p
1505 || a->left_fringe_bitmap != b->left_fringe_bitmap 1505 || a->left_fringe_bitmap != b->left_fringe_bitmap
1506 || a->left_fringe_face_id != b->left_fringe_face_id
1506 || a->right_fringe_bitmap != b->right_fringe_bitmap 1507 || a->right_fringe_bitmap != b->right_fringe_bitmap
1508 || a->right_fringe_face_id != b->right_fringe_face_id
1509 || a->overlay_arrow_p != b->overlay_arrow_p
1507 || a->exact_window_width_line_p != b->exact_window_width_line_p 1510 || a->exact_window_width_line_p != b->exact_window_width_line_p
1508 || a->overlapped_p != b->overlapped_p 1511 || a->overlapped_p != b->overlapped_p
1509 || (MATRIX_ROW_CONTINUATION_LINE_P (a) 1512 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
@@ -3820,10 +3823,15 @@ update_frame (f, force_p, inhibit_hairy_id_p)
3820 paused_p = update_window_tree (root_window, force_p); 3823 paused_p = update_window_tree (root_window, force_p);
3821 update_end (f); 3824 update_end (f);
3822 3825
3823#if 0 /* This flush is a performance bottleneck under X, 3826 /* This flush is a performance bottleneck under X,
3824 and it doesn't seem to be necessary anyway. */ 3827 and it doesn't seem to be necessary anyway (in general).
3825 FRAME_RIF (f)->flush_display (f); 3828 It is necessary when resizing the window with the mouse, or
3826#endif 3829 at least the fringes are not redrawn in a timely manner. ++kfs */
3830 if (f->force_flush_display_p)
3831 {
3832 FRAME_RIF (f)->flush_display (f);
3833 f->force_flush_display_p = 0;
3834 }
3827 } 3835 }
3828 else 3836 else
3829 { 3837 {
@@ -4524,6 +4532,7 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
4524 || desired_row->y != current_row->y 4532 || desired_row->y != current_row->y
4525 || desired_row->visible_height != current_row->visible_height 4533 || desired_row->visible_height != current_row->visible_height
4526 || desired_row->cursor_in_fringe_p != current_row->cursor_in_fringe_p 4534 || desired_row->cursor_in_fringe_p != current_row->cursor_in_fringe_p
4535 || desired_row->overlay_arrow_p != current_row->overlay_arrow_p
4527 || current_row->redraw_fringe_bitmaps_p 4536 || current_row->redraw_fringe_bitmaps_p
4528 || desired_row->mode_line_p != current_row->mode_line_p 4537 || desired_row->mode_line_p != current_row->mode_line_p
4529 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p 4538 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
@@ -5032,7 +5041,10 @@ scrolling_window (w, header_line_p)
5032 to_overlapped_p = to->overlapped_p; 5041 to_overlapped_p = to->overlapped_p;
5033 if (!from->mode_line_p && !w->pseudo_window_p 5042 if (!from->mode_line_p && !w->pseudo_window_p
5034 && (to->left_fringe_bitmap != from->left_fringe_bitmap 5043 && (to->left_fringe_bitmap != from->left_fringe_bitmap
5035 || to->right_fringe_bitmap != from->right_fringe_bitmap)) 5044 || to->right_fringe_bitmap != from->right_fringe_bitmap
5045 || to->left_fringe_face_id != from->left_fringe_face_id
5046 || to->right_fringe_face_id != from->right_fringe_face_id
5047 || to->overlay_arrow_p != from->overlay_arrow_p))
5036 from->redraw_fringe_bitmaps_p = 1; 5048 from->redraw_fringe_bitmaps_p = 1;
5037 assign_row (to, from); 5049 assign_row (to, from);
5038 to->enabled_p = 1, from->enabled_p = 0; 5050 to->enabled_p = 1, from->enabled_p = 0;
diff --git a/src/editfns.c b/src/editfns.c
index d3039ca0273..9a1ce81f316 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1138,7 +1138,7 @@ DEFUN ("eolp", Feolp, Seolp, 0, 0, 0,
1138 1138
1139DEFUN ("char-after", Fchar_after, Schar_after, 0, 1, 0, 1139DEFUN ("char-after", Fchar_after, Schar_after, 0, 1, 0,
1140 doc: /* Return character in current buffer at position POS. 1140 doc: /* Return character in current buffer at position POS.
1141POS is an integer or a marker. 1141POS is an integer or a marker and defaults to point.
1142If POS is out of range, the value is nil. */) 1142If POS is out of range, the value is nil. */)
1143 (pos) 1143 (pos)
1144 Lisp_Object pos; 1144 Lisp_Object pos;
@@ -1171,7 +1171,7 @@ If POS is out of range, the value is nil. */)
1171 1171
1172DEFUN ("char-before", Fchar_before, Schar_before, 0, 1, 0, 1172DEFUN ("char-before", Fchar_before, Schar_before, 0, 1, 0,
1173 doc: /* Return character in current buffer preceding position POS. 1173 doc: /* Return character in current buffer preceding position POS.
1174POS is an integer or a marker. 1174POS is an integer or a marker and defaults to point.
1175If POS is out of range, the value is nil. */) 1175If POS is out of range, the value is nil. */)
1176 (pos) 1176 (pos)
1177 Lisp_Object pos; 1177 Lisp_Object pos;
diff --git a/src/emacs.c b/src/emacs.c
index 4f66e4bdb07..20c6295e2e2 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1236,6 +1236,9 @@ main (argc, argv
1236 1236
1237 init_window_once (); /* Init the window system. */ 1237 init_window_once (); /* Init the window system. */
1238 init_fileio_once (); /* Must precede any path manipulation. */ 1238 init_fileio_once (); /* Must precede any path manipulation. */
1239#ifdef HAVE_WINDOW_SYSTEM
1240 init_fringe_once (); /* Swap bitmaps if necessary. */
1241#endif /* HAVE_WINDOW_SYSTEM */
1239 } 1242 }
1240 1243
1241 init_alloc (); 1244 init_alloc ();
@@ -1500,6 +1503,9 @@ main (argc, argv
1500#endif /* WINDOWSNT */ 1503#endif /* WINDOWSNT */
1501 syms_of_window (); 1504 syms_of_window ();
1502 syms_of_xdisp (); 1505 syms_of_xdisp ();
1506#ifdef HAVE_WINDOW_SYSTEM
1507 syms_of_fringe ();
1508#endif /* HAVE_WINDOW_SYSTEM */
1503#ifdef HAVE_X_WINDOWS 1509#ifdef HAVE_X_WINDOWS
1504 syms_of_xterm (); 1510 syms_of_xterm ();
1505 syms_of_xfns (); 1511 syms_of_xfns ();
@@ -1581,6 +1587,9 @@ main (argc, argv
1581#endif /* HAVE_X_WINDOWS */ 1587#endif /* HAVE_X_WINDOWS */
1582 init_fns (); 1588 init_fns ();
1583 init_xdisp (); 1589 init_xdisp ();
1590#ifdef HAVE_WINDOW_SYSTEM
1591 init_fringe ();
1592#endif /* HAVE_WINDOW_SYSTEM */
1584 init_macros (); 1593 init_macros ();
1585 init_editfns (); 1594 init_editfns ();
1586 init_floatfns (); 1595 init_floatfns ();
diff --git a/src/fns.c b/src/fns.c
index 493d7ba2897..1d6767cebab 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2512,14 +2512,26 @@ character set, or a character code. Return VALUE. */)
2512 else if (SYMBOLP (range)) 2512 else if (SYMBOLP (range))
2513 { 2513 {
2514 Lisp_Object charset_info; 2514 Lisp_Object charset_info;
2515 int charset_id;
2515 2516
2516 charset_info = Fget (range, Qcharset); 2517 charset_info = Fget (range, Qcharset);
2517 CHECK_VECTOR (charset_info); 2518 if (! VECTORP (charset_info)
2518 2519 || ! NATNUMP (AREF (charset_info, 0))
2519 return Faset (char_table, 2520 || (charset_id = XINT (AREF (charset_info, 0)),
2520 make_number (XINT (XVECTOR (charset_info)->contents[0]) 2521 ! CHARSET_DEFINED_P (charset_id)))
2521 + 128), 2522 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (range)));
2522 value); 2523
2524 if (charset_id == CHARSET_ASCII)
2525 for (i = 0; i < 128; i++)
2526 XCHAR_TABLE (char_table)->contents[i] = value;
2527 else if (charset_id == CHARSET_8_BIT_CONTROL)
2528 for (i = 128; i < 160; i++)
2529 XCHAR_TABLE (char_table)->contents[i] = value;
2530 else if (charset_id == CHARSET_8_BIT_GRAPHIC)
2531 for (i = 160; i < 256; i++)
2532 XCHAR_TABLE (char_table)->contents[i] = value;
2533 else
2534 XCHAR_TABLE (char_table)->contents[charset_id + 128] = value;
2523 } 2535 }
2524 else if (INTEGERP (range)) 2536 else if (INTEGERP (range))
2525 Faset (char_table, range, value); 2537 Faset (char_table, range, value);
diff --git a/src/frame.h b/src/frame.h
index 14806b2bc04..5037ffd0553 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -438,6 +438,10 @@ struct frame
438 Clear the frame in clear_garbaged_frames if set. */ 438 Clear the frame in clear_garbaged_frames if set. */
439 unsigned resized_p : 1; 439 unsigned resized_p : 1;
440 440
441 /* Set to non-zero in when we want for force a flush_display in
442 update_frame, usually after resizing the frame. */
443 unsigned force_flush_display_p : 1;
444
441 /* All display backends seem to need these two pixel values. */ 445 /* All display backends seem to need these two pixel values. */
442 unsigned long background_pixel; 446 unsigned long background_pixel;
443 unsigned long foreground_pixel; 447 unsigned long foreground_pixel;
diff --git a/src/fringe.c b/src/fringe.c
new file mode 100644
index 00000000000..bd93b4cfce5
--- /dev/null
+++ b/src/fringe.c
@@ -0,0 +1,1362 @@
1/* Fringe handling (split from xdisp.c).
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22#include <config.h>
23#include <stdio.h>
24
25#include "lisp.h"
26#include "frame.h"
27#include "window.h"
28#include "dispextern.h"
29#include "buffer.h"
30#include "blockinput.h"
31#include "termhooks.h"
32
33#ifdef HAVE_WINDOW_SYSTEM
34
35extern Lisp_Object Qtop, Qbottom, Qcenter;
36
37/* Non-nil means that newline may flow into the right fringe. */
38
39Lisp_Object Voverflow_newline_into_fringe;
40
41
42enum fringe_bitmap_type
43{
44 NO_FRINGE_BITMAP = 0,
45 UNDEF_FRINGE_BITMAP,
46 LEFT_TRUNCATION_BITMAP,
47 RIGHT_TRUNCATION_BITMAP,
48 UP_ARROW_BITMAP,
49 DOWN_ARROW_BITMAP,
50 CONTINUED_LINE_BITMAP,
51 CONTINUATION_LINE_BITMAP,
52 OVERLAY_ARROW_BITMAP,
53 TOP_LEFT_ANGLE_BITMAP,
54 TOP_RIGHT_ANGLE_BITMAP,
55 BOTTOM_LEFT_ANGLE_BITMAP,
56 BOTTOM_RIGHT_ANGLE_BITMAP,
57 LEFT_BRACKET_BITMAP,
58 RIGHT_BRACKET_BITMAP,
59 FILLED_BOX_CURSOR_BITMAP,
60 HOLLOW_BOX_CURSOR_BITMAP,
61 HOLLOW_SQUARE_BITMAP,
62 BAR_CURSOR_BITMAP,
63 HBAR_CURSOR_BITMAP,
64 ZV_LINE_BITMAP,
65 MAX_STANDARD_FRINGE_BITMAPS
66};
67
68enum fringe_bitmap_align
69{
70 ALIGN_BITMAP_CENTER = 0,
71 ALIGN_BITMAP_TOP,
72 ALIGN_BITMAP_BOTTOM
73};
74
75struct fringe_bitmap
76{
77 unsigned short *bits;
78 unsigned height : 8;
79 unsigned width : 8;
80 unsigned period : 8;
81 unsigned align : 2;
82 unsigned dynamic : 1;
83};
84
85
86/***********************************************************************
87 Fringe bitmaps
88 ***********************************************************************/
89
90/* Undefined bitmap. A question mark. */
91/*
92 ..xxxx..
93 .xxxxxx.
94 xx....xx
95 xx....xx
96 ....xx..
97 ...xx...
98 ...xx...
99 ........
100 ...xx...
101 ...xx...
102*/
103static unsigned short unknown_bits[] = {
104 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
105
106/* An arrow like this: `<-'. */
107/*
108 ...xx...
109 ..xx....
110 .xx.....
111 xxxxxx..
112 xxxxxx..
113 .xx.....
114 ..xx....
115 ...xx...
116*/
117static unsigned short left_arrow_bits[] = {
118 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
119
120
121/* Right truncation arrow bitmap `->'. */
122/*
123 ...xx...
124 ....xx..
125 .....xx.
126 ..xxxxxx
127 ..xxxxxx
128 .....xx.
129 ....xx..
130 ...xx...
131*/
132static unsigned short right_arrow_bits[] = {
133 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
134
135
136/* Up arrow bitmap. */
137/*
138 ...xx...
139 ..xxxx..
140 .xxxxxx.
141 xxxxxxxx
142 ...xx...
143 ...xx...
144 ...xx...
145 ...xx...
146*/
147static unsigned short up_arrow_bits[] = {
148 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
149
150
151/* Down arrow bitmap. */
152/*
153 ...xx...
154 ...xx...
155 ...xx...
156 ...xx...
157 xxxxxxxx
158 .xxxxxx.
159 ..xxxx..
160 ...xx...
161*/
162static unsigned short down_arrow_bits[] = {
163 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
164
165/* Marker for continued lines. */
166/*
167 ..xxxx..
168 ..xxxxx.
169 ......xx
170 ..x..xxx
171 ..xxxxxx
172 ..xxxxx.
173 ..xxxx..
174 ..xxxxx.
175*/
176static unsigned short continued_bits[] = {
177 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
178
179/* Marker for continuation lines. */
180/*
181 ..xxxx..
182 .xxxxx..
183 xx......
184 xxx..x..
185 xxxxxx..
186 .xxxxx..
187 ..xxxx..
188 .xxxxx..
189*/
190static unsigned short continuation_bits[] = {
191 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
192
193/* Overlay arrow bitmap. A triangular arrow. */
194/*
195 xx......
196 xxxx....
197 xxxxx...
198 xxxxxx..
199 xxxxxx..
200 xxxxx...
201 xxxx....
202 xx......
203*/
204static unsigned short ov_bits[] = {
205 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
206
207#if 0
208/* Reverse Overlay arrow bitmap. A triangular arrow. */
209/*
210 ......xx
211 ....xxxx
212 ...xxxxx
213 ..xxxxxx
214 ..xxxxxx
215 ...xxxxx
216 ....xxxx
217 ......xx
218*/
219static unsigned short rev_ov_bits[] = {
220 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
221#endif
222
223/* First line bitmap. An top-left angle. */
224/*
225 xxxxxx..
226 xxxxxx..
227 xx......
228 xx......
229 xx......
230 xx......
231 xx......
232 ........
233*/
234static unsigned short top_left_angle_bits[] = {
235 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
236
237/* First line bitmap. An right-up angle. */
238/*
239 ..xxxxxx
240 ..xxxxxx
241 ......xx
242 ......xx
243 ......xx
244 ......xx
245 ......xx
246 ........
247*/
248static unsigned short top_right_angle_bits[] = {
249 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
250
251/* Last line bitmap. An left-down angle. */
252/*
253 ........
254 xx......
255 xx......
256 xx......
257 xx......
258 xx......
259 xxxxxx..
260 xxxxxx..
261*/
262static unsigned short bottom_left_angle_bits[] = {
263 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
264
265/* Last line bitmap. An right-down angle. */
266/*
267 ........
268 ......xx
269 ......xx
270 ......xx
271 ......xx
272 ......xx
273 ..xxxxxx
274 ..xxxxxx
275*/
276static unsigned short bottom_right_angle_bits[] = {
277 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
278
279/* First/last line bitmap. An left bracket. */
280/*
281 xxxxxx..
282 xxxxxx..
283 xx......
284 xx......
285 xx......
286 xx......
287 xx......
288 xx......
289 xxxxxx..
290 xxxxxx..
291*/
292static unsigned short left_bracket_bits[] = {
293 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
294
295/* First/last line bitmap. An right bracket. */
296/*
297 ..xxxxxx
298 ..xxxxxx
299 ......xx
300 ......xx
301 ......xx
302 ......xx
303 ......xx
304 ......xx
305 ..xxxxxx
306 ..xxxxxx
307*/
308static unsigned short right_bracket_bits[] = {
309 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
310
311/* Filled box cursor bitmap. A filled box; max 13 pixels high. */
312/*
313 xxxxxxx.
314 xxxxxxx.
315 xxxxxxx.
316 xxxxxxx.
317 xxxxxxx.
318 xxxxxxx.
319 xxxxxxx.
320 xxxxxxx.
321 xxxxxxx.
322 xxxxxxx.
323 xxxxxxx.
324 xxxxxxx.
325 xxxxxxx.
326*/
327static unsigned short filled_box_cursor_bits[] = {
328 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
329
330/* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
331/*
332 xxxxxxx.
333 x.....x.
334 x.....x.
335 x.....x.
336 x.....x.
337 x.....x.
338 x.....x.
339 x.....x.
340 x.....x.
341 x.....x.
342 x.....x.
343 x.....x.
344 xxxxxxx.
345*/
346static unsigned short hollow_box_cursor_bits[] = {
347 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
348
349/* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
350/*
351 xx......
352 xx......
353 xx......
354 xx......
355 xx......
356 xx......
357 xx......
358 xx......
359 xx......
360 xx......
361 xx......
362 xx......
363 xx......
364*/
365static unsigned short bar_cursor_bits[] = {
366 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
367
368/* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
369/*
370 xxxxxxx.
371 xxxxxxx.
372*/
373static unsigned short hbar_cursor_bits[] = {
374 0xfe, 0xfe};
375
376
377/* Bitmap drawn to indicate lines not displaying text if
378 `indicate-empty-lines' is non-nil. */
379/*
380 ........
381 ..xxxx..
382 ........
383 ........
384 ..xxxx..
385 ........
386*/
387static unsigned short zv_bits[] = {
388 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
389 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
390 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
391 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
392 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
393 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
394 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
395 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
396
397/* Hollow square bitmap. */
398/*
399 .xxxxxx.
400 .x....x.
401 .x....x.
402 .x....x.
403 .x....x.
404 .xxxxxx.
405*/
406static unsigned short hollow_square_bits[] = {
407 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
408
409
410#define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
411#define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
412#define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
413
414struct fringe_bitmap standard_bitmaps[MAX_STANDARD_FRINGE_BITMAPS] =
415{
416 { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
417 { FRBITS (unknown_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
418 { FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
419 { FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
420 { FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
421 { FRBITS (down_arrow_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
422 { FRBITS (continued_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
423 { FRBITS (continuation_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
424 { FRBITS (ov_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
425 { FRBITS (top_left_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
426 { FRBITS (top_right_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
427 { FRBITS (bottom_left_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
428 { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
429 { FRBITS (left_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
430 { FRBITS (right_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
431 { FRBITS (filled_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
432 { FRBITS (hollow_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
433 { FRBITS (hollow_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
434 { FRBITS (bar_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
435 { FRBITS (hbar_cursor_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
436 { FRBITS (zv_bits), 8, 3, ALIGN_BITMAP_TOP, 0 },
437};
438
439static struct fringe_bitmap *fringe_bitmaps[MAX_FRINGE_BITMAPS];
440static unsigned fringe_faces[MAX_FRINGE_BITMAPS];
441
442static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
443
444/* Return 1 if FRINGE_ID is a valid fringe bitmap id. */
445
446int
447valid_fringe_bitmap_id_p (fringe_id)
448 int fringe_id;
449{
450 return (fringe_id >= NO_FRINGE_BITMAP
451 && fringe_id < max_used_fringe_bitmap
452 && (fringe_id < MAX_STANDARD_FRINGE_BITMAPS
453 || fringe_bitmaps[fringe_id] != NULL));
454}
455
456/* Draw the bitmap WHICH in one of the left or right fringes of
457 window W. ROW is the glyph row for which to display the bitmap; it
458 determines the vertical position at which the bitmap has to be
459 drawn.
460 LEFT_P is 1 for left fringe, 0 for right fringe.
461*/
462
463void
464draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
465 struct window *w;
466 struct glyph_row *row;
467 int left_p, overlay;
468 enum fringe_bitmap_type which;
469{
470 struct frame *f = XFRAME (WINDOW_FRAME (w));
471 struct draw_fringe_bitmap_params p;
472 struct fringe_bitmap *fb;
473 int period;
474 int face_id = DEFAULT_FACE_ID;
475
476 p.cursor_p = 0;
477 p.overlay_p = (overlay & 1) == 1;
478 p.cursor_p = (overlay & 2) == 2;
479
480 if (which != NO_FRINGE_BITMAP)
481 {
482 }
483 else if (left_p)
484 {
485 which = row->left_fringe_bitmap;
486 face_id = row->left_fringe_face_id;
487 }
488 else
489 {
490 which = row->right_fringe_bitmap;
491 face_id = row->right_fringe_face_id;
492 }
493
494 if (face_id == DEFAULT_FACE_ID)
495 face_id = fringe_faces[which];
496
497 fb = fringe_bitmaps[which];
498 if (fb == NULL)
499 fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
500 ? which : UNDEF_FRINGE_BITMAP];
501
502 period = fb->period;
503
504 /* Convert row to frame coordinates. */
505 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
506
507 p.which = which;
508 p.bits = fb->bits;
509 p.wd = fb->width;
510
511 p.h = fb->height;
512 p.dh = (period > 0 ? (p.y % period) : 0);
513 p.h -= p.dh;
514 /* Clip bitmap if too high. */
515 if (p.h > row->height)
516 p.h = row->height;
517
518 p.face = FACE_FROM_ID (f, face_id);
519
520 if (p.face == NULL)
521 {
522 /* Why does this happen? ++kfs */
523 return;
524 }
525
526 PREPARE_FACE_FOR_DISPLAY (f, p.face);
527
528 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
529 the fringe. */
530 p.bx = -1;
531 if (left_p)
532 {
533 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
534 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
535 ? LEFT_MARGIN_AREA
536 : TEXT_AREA));
537 if (p.wd > wd)
538 p.wd = wd;
539 p.x = x - p.wd - (wd - p.wd) / 2;
540
541 if (p.wd < wd || row->height > p.h)
542 {
543 /* If W has a vertical border to its left, don't draw over it. */
544 wd -= ((!WINDOW_LEFTMOST_P (w)
545 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
546 ? 1 : 0);
547 p.bx = x - wd;
548 p.nx = wd;
549 }
550 }
551 else
552 {
553 int x = window_box_right (w,
554 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
555 ? RIGHT_MARGIN_AREA
556 : TEXT_AREA));
557 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
558 if (p.wd > wd)
559 p.wd = wd;
560 p.x = x + (wd - p.wd) / 2;
561 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
562 the fringe. */
563 if (p.wd < wd || row->height > p.h)
564 {
565 p.bx = x;
566 p.nx = wd;
567 }
568 }
569
570 if (p.bx >= 0)
571 {
572 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
573
574 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
575 p.ny = row->visible_height;
576 }
577
578 /* Adjust y to the offset in the row to start drawing the bitmap. */
579 switch (fb->align)
580 {
581 case ALIGN_BITMAP_CENTER:
582 p.y += (row->height - p.h) / 2;
583 break;
584 case ALIGN_BITMAP_BOTTOM:
585 p.h = fb->height;
586 p.y += (row->visible_height - p.h);
587 break;
588 case ALIGN_BITMAP_TOP:
589 break;
590 }
591
592 FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
593}
594
595void
596draw_fringe_bitmap (w, row, left_p)
597 struct window *w;
598 struct glyph_row *row;
599 int left_p;
600{
601 int overlay = 0;
602
603 if (!left_p && row->cursor_in_fringe_p)
604 {
605 int cursor = NO_FRINGE_BITMAP;
606
607 switch (w->phys_cursor_type)
608 {
609 case HOLLOW_BOX_CURSOR:
610 if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits))
611 cursor = HOLLOW_BOX_CURSOR_BITMAP;
612 else
613 cursor = HOLLOW_SQUARE_BITMAP;
614 break;
615 case FILLED_BOX_CURSOR:
616 cursor = FILLED_BOX_CURSOR_BITMAP;
617 break;
618 case BAR_CURSOR:
619 cursor = BAR_CURSOR_BITMAP;
620 break;
621 case HBAR_CURSOR:
622 cursor = HBAR_CURSOR_BITMAP;
623 break;
624 case NO_CURSOR:
625 default:
626 w->phys_cursor_on_p = 0;
627 row->cursor_in_fringe_p = 0;
628 break;
629 }
630 if (cursor != NO_FRINGE_BITMAP)
631 {
632 draw_fringe_bitmap_1 (w, row, 0, 2, cursor);
633 overlay = cursor == FILLED_BOX_CURSOR_BITMAP ? 3 : 1;
634 }
635 }
636
637 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
638
639 if (left_p && row->overlay_arrow_p)
640 draw_fringe_bitmap_1 (w, row, 1, 1, OVERLAY_ARROW_BITMAP);
641}
642
643
644/* Draw fringe bitmaps for glyph row ROW on window W. Call this
645 function with input blocked. */
646
647void
648draw_row_fringe_bitmaps (w, row)
649 struct window *w;
650 struct glyph_row *row;
651{
652 xassert (interrupt_input_blocked);
653
654 /* If row is completely invisible, because of vscrolling, we
655 don't have to draw anything. */
656 if (row->visible_height <= 0)
657 return;
658
659 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
660 draw_fringe_bitmap (w, row, 1);
661
662 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
663 draw_fringe_bitmap (w, row, 0);
664}
665
666/* Draw the fringes of window W. Only fringes for rows marked for
667 update in redraw_fringe_bitmaps_p are drawn. */
668
669void
670draw_window_fringes (w)
671 struct window *w;
672{
673 struct glyph_row *row;
674 int yb = window_text_bottom_y (w);
675 int nrows = w->current_matrix->nrows;
676 int y = 0, rn;
677
678 if (w->pseudo_window_p)
679 return;
680
681 for (y = 0, rn = 0, row = w->current_matrix->rows;
682 y < yb && rn < nrows;
683 y += row->height, ++row, ++rn)
684 {
685 if (!row->redraw_fringe_bitmaps_p)
686 continue;
687 draw_row_fringe_bitmaps (w, row);
688 row->redraw_fringe_bitmaps_p = 0;
689 }
690}
691
692
693/* Recalculate the bitmaps to show in the fringes of window W.
694 If FORCE_P is 0, only mark rows with modified bitmaps for update in
695 redraw_fringe_bitmaps_p; else mark all rows for update. */
696
697int
698update_window_fringes (w, force_p)
699 struct window *w;
700 int force_p;
701{
702 struct glyph_row *row, *cur = 0;
703 int yb = window_text_bottom_y (w);
704 int rn, nrows = w->current_matrix->nrows;
705 int y;
706 int redraw_p = 0;
707 Lisp_Object ind;
708 int boundary_pos = 0, arrow_pos = 0;
709 int empty_pos = 0;
710
711 if (w->pseudo_window_p)
712 return 0;
713
714 if (!MINI_WINDOW_P (w)
715 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
716 {
717 int do_eob = 1, do_bob = 1;
718 Lisp_Object arrows;
719
720 if (CONSP (ind))
721 arrows = XCDR (ind), ind = XCAR (ind);
722 else
723 arrows = ind;
724
725 if (EQ (ind, Qleft))
726 boundary_pos = -1;
727 else if (EQ (ind, Qright))
728 boundary_pos = 1;
729
730 if (EQ (arrows, Qleft))
731 arrow_pos = -1;
732 else if (EQ (arrows, Qright))
733 arrow_pos = 1;
734
735 for (y = 0, rn = 0;
736 y < yb && rn < nrows;
737 y += row->height, ++rn)
738 {
739 unsigned indicate_bob_p, indicate_top_line_p;
740 unsigned indicate_eob_p, indicate_bottom_line_p;
741
742 row = w->desired_matrix->rows + rn;
743 if (!row->enabled_p)
744 row = w->current_matrix->rows + rn;
745
746 indicate_bob_p = row->indicate_bob_p;
747 indicate_top_line_p = row->indicate_top_line_p;
748 indicate_eob_p = row->indicate_eob_p;
749 indicate_bottom_line_p = row->indicate_bottom_line_p;
750
751 row->indicate_bob_p = row->indicate_top_line_p = 0;
752 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
753
754 if (!NILP (ind)
755 && MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)))
756 row->indicate_bob_p = do_bob, do_bob = 0;
757 else if (!NILP (arrows)
758 && (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) == rn)
759 row->indicate_top_line_p = 1;
760
761 if (!NILP (ind)
762 && MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)))
763 row->indicate_eob_p = do_eob, do_eob = 0;
764 else if (!NILP (arrows)
765 && y + row->height >= yb)
766 row->indicate_bottom_line_p = 1;
767
768 if (indicate_bob_p != row->indicate_bob_p
769 || indicate_top_line_p != row->indicate_top_line_p
770 || indicate_eob_p != row->indicate_eob_p
771 || indicate_bottom_line_p != row->indicate_bottom_line_p)
772 row->redraw_fringe_bitmaps_p = 1;
773 }
774 }
775
776 if (EQ (XBUFFER (w->buffer)->indicate_empty_lines, Qright))
777 empty_pos = 1;
778 else if (EQ (XBUFFER (w->buffer)->indicate_empty_lines, Qleft))
779 empty_pos = -1;
780
781 for (y = 0, rn = 0;
782 y < yb && rn < nrows;
783 y += row->height, rn++)
784 {
785 enum fringe_bitmap_type left, right;
786 unsigned left_face_id, right_face_id;
787
788 row = w->desired_matrix->rows + rn;
789 cur = w->current_matrix->rows + rn;
790 if (!row->enabled_p)
791 row = cur;
792
793 left_face_id = right_face_id = DEFAULT_FACE_ID;
794
795 /* Decide which bitmap to draw in the left fringe. */
796 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
797 left = NO_FRINGE_BITMAP;
798 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
799 {
800 left = row->left_user_fringe_bitmap;
801 left_face_id = row->left_user_fringe_face_id;
802 }
803#if 0 /* this is now done via an overlay */
804 else if (row->overlay_arrow_p)
805 left = OVERLAY_ARROW_BITMAP;
806#endif
807 else if (row->indicate_bob_p && boundary_pos <= 0)
808 left = ((row->indicate_eob_p && boundary_pos < 0)
809 ? LEFT_BRACKET_BITMAP : TOP_LEFT_ANGLE_BITMAP);
810 else if (row->indicate_eob_p && boundary_pos < 0)
811 left = BOTTOM_LEFT_ANGLE_BITMAP;
812 else if (row->truncated_on_left_p)
813 left = LEFT_TRUNCATION_BITMAP;
814 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
815 left = CONTINUATION_LINE_BITMAP;
816 else if (row->indicate_empty_line_p && empty_pos <= 0)
817 left = ZV_LINE_BITMAP;
818 else if (row->indicate_top_line_p && arrow_pos <= 0)
819 left = UP_ARROW_BITMAP;
820 else if (row->indicate_bottom_line_p && arrow_pos < 0)
821 left = DOWN_ARROW_BITMAP;
822 else
823 left = NO_FRINGE_BITMAP;
824
825 /* Decide which bitmap to draw in the right fringe. */
826 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
827 right = NO_FRINGE_BITMAP;
828 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
829 {
830 right = row->right_user_fringe_bitmap;
831 right_face_id = row->right_user_fringe_face_id;
832 }
833 else if (row->indicate_bob_p && boundary_pos > 0)
834 right = ((row->indicate_eob_p && boundary_pos >= 0)
835 ? RIGHT_BRACKET_BITMAP : TOP_RIGHT_ANGLE_BITMAP);
836 else if (row->indicate_eob_p && boundary_pos >= 0)
837 right = BOTTOM_RIGHT_ANGLE_BITMAP;
838 else if (row->truncated_on_right_p)
839 right = RIGHT_TRUNCATION_BITMAP;
840 else if (row->continued_p)
841 right = CONTINUED_LINE_BITMAP;
842 else if (row->indicate_top_line_p && arrow_pos > 0)
843 right = UP_ARROW_BITMAP;
844 else if (row->indicate_bottom_line_p && arrow_pos >= 0)
845 right = DOWN_ARROW_BITMAP;
846 else if (row->indicate_empty_line_p
847 && (empty_pos > 0
848 || (WINDOW_LEFT_FRINGE_WIDTH (w) == 0 && empty_pos == 0)))
849 right = ZV_LINE_BITMAP;
850 else
851 right = NO_FRINGE_BITMAP;
852
853 if (force_p
854 || row->y != cur->y
855 || row->visible_height != cur->visible_height
856 || left != cur->left_fringe_bitmap
857 || right != cur->right_fringe_bitmap
858 || left_face_id != cur->left_fringe_face_id
859 || right_face_id != cur->right_fringe_face_id
860 || cur->redraw_fringe_bitmaps_p)
861 {
862 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
863 cur->left_fringe_bitmap = left;
864 cur->right_fringe_bitmap = right;
865 cur->left_fringe_face_id = left_face_id;
866 cur->right_fringe_face_id = right_face_id;
867 }
868
869 if (row->overlay_arrow_p != cur->overlay_arrow_p)
870 {
871 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
872 cur->overlay_arrow_p = row->overlay_arrow_p;
873 }
874
875 row->left_fringe_bitmap = left;
876 row->right_fringe_bitmap = right;
877 row->left_fringe_face_id = left_face_id;
878 row->right_fringe_face_id = right_face_id;
879 }
880
881 return redraw_p;
882}
883
884
885/* Compute actual fringe widths for frame F.
886
887 If REDRAW is 1, redraw F if the fringe settings was actually
888 modified and F is visible.
889
890 Since the combined left and right fringe must occupy an integral
891 number of columns, we may need to add some pixels to each fringe.
892 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
893 but a negative width value is taken literally (after negating it).
894
895 We never make the fringes narrower than specified. It is planned
896 to make fringe bitmaps customizable and expandable, and at that
897 time, the user will typically specify the minimum number of pixels
898 needed for his bitmaps, so we shouldn't select anything less than
899 what is specified.
900*/
901
902void
903compute_fringe_widths (f, redraw)
904 struct frame *f;
905 int redraw;
906{
907 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
908 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
909 int o_cols = FRAME_FRINGE_COLS (f);
910
911 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
912 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
913 int left_fringe_width, right_fringe_width;
914
915 if (!NILP (left_fringe))
916 left_fringe = Fcdr (left_fringe);
917 if (!NILP (right_fringe))
918 right_fringe = Fcdr (right_fringe);
919
920 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
921 XINT (left_fringe));
922 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
923 XINT (right_fringe));
924
925 if (left_fringe_width || right_fringe_width)
926 {
927 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
928 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
929 int conf_wid = left_wid + right_wid;
930 int font_wid = FRAME_COLUMN_WIDTH (f);
931 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
932 int real_wid = cols * font_wid;
933 if (left_wid && right_wid)
934 {
935 if (left_fringe_width < 0)
936 {
937 /* Left fringe width is fixed, adjust right fringe if necessary */
938 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
939 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
940 }
941 else if (right_fringe_width < 0)
942 {
943 /* Right fringe width is fixed, adjust left fringe if necessary */
944 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
945 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
946 }
947 else
948 {
949 /* Adjust both fringes with an equal amount.
950 Note that we are doing integer arithmetic here, so don't
951 lose a pixel if the total width is an odd number. */
952 int fill = real_wid - conf_wid;
953 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
954 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
955 }
956 }
957 else if (left_fringe_width)
958 {
959 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
960 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
961 }
962 else
963 {
964 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
965 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
966 }
967 FRAME_FRINGE_COLS (f) = cols;
968 }
969 else
970 {
971 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
972 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
973 FRAME_FRINGE_COLS (f) = 0;
974 }
975
976 if (redraw && FRAME_VISIBLE_P (f))
977 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
978 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
979 o_cols != FRAME_FRINGE_COLS (f))
980 redraw_frame (f);
981}
982
983DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
984 1, 1, 0,
985 doc: /* Destroy fringe bitmap WHICH.
986If WHICH overrides a standard fringe bitmap, the original bitmap is restored. */)
987 (which)
988 Lisp_Object which;
989{
990 int n;
991 struct fringe_bitmap **fbp;
992
993 CHECK_NUMBER (which);
994 if (n = XINT (which), n >= max_used_fringe_bitmap)
995 return Qnil;
996
997 fringe_faces[n] = FRINGE_FACE_ID;
998
999 fbp = &fringe_bitmaps[n];
1000 if (*fbp && (*fbp)->dynamic)
1001 {
1002 /* XXX Is SELECTED_FRAME OK here? */
1003 if (FRAME_RIF (SELECTED_FRAME ())->destroy_fringe_bitmap)
1004 FRAME_RIF (SELECTED_FRAME ())->destroy_fringe_bitmap (n);
1005 xfree (*fbp);
1006 *fbp = NULL;
1007 }
1008
1009 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1010 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1011 max_used_fringe_bitmap--;
1012
1013 return Qnil;
1014}
1015
1016
1017/* Initialize bitmap bit.
1018
1019 On X, we bit-swap the built-in bitmaps and reduce bitmap
1020 from short to char array if width is <= 8 bits.
1021
1022 On MAC with big-endian CPU, we need to byte-swap each short.
1023
1024 On W32 and MAC (little endian), there's no need to do this.
1025*/
1026
1027void
1028init_fringe_bitmap (which, fb, once_p)
1029 enum fringe_bitmap_type which;
1030 struct fringe_bitmap *fb;
1031 int once_p;
1032{
1033 if (once_p || fb->dynamic)
1034 {
1035#if defined (HAVE_X_WINDOWS)
1036 static unsigned char swap_nibble[16]
1037 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1038 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1039 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1040 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1041 unsigned short *bits = fb->bits;
1042 int j;
1043
1044 if (fb->width <= 8)
1045 {
1046 unsigned char *cbits = (unsigned char *)fb->bits;
1047 for (j = 0; j < fb->height; j++)
1048 {
1049 unsigned short b = *bits++;
1050 unsigned char c;
1051 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1052 | (swap_nibble[(b>>4) & 0xf]));
1053 *cbits++ = (c >> (8 - fb->width));
1054 }
1055 }
1056 else
1057 {
1058 for (j = 0; j < fb->height; j++)
1059 {
1060 unsigned short b = *bits;
1061 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1062 | (swap_nibble[(b>>4) & 0xf] << 8)
1063 | (swap_nibble[(b>>8) & 0xf] << 4)
1064 | (swap_nibble[(b>>12) & 0xf]));
1065 *bits++ = (b >> (16 - fb->width));
1066 }
1067 }
1068#endif /* HAVE_X_WINDOWS */
1069
1070#if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1071 unsigned short *bits = fb->bits;
1072 int j;
1073 for (j = 0; j < fb->height; j++)
1074 {
1075 unsigned short b = *bits;
1076 *bits++ = ((b >> 8) & 0xff) | ((b & 0xff) << 8);
1077 }
1078#endif /* MAC_OS && WORDS_BIG_ENDIAN */
1079 }
1080
1081 if (!once_p)
1082 {
1083 Fdestroy_fringe_bitmap (make_number (which));
1084
1085 /* XXX Is SELECTED_FRAME OK here? */
1086 if (FRAME_RIF (SELECTED_FRAME ())->define_fringe_bitmap)
1087 FRAME_RIF (SELECTED_FRAME ())->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1088
1089 fringe_bitmaps[which] = fb;
1090 if (which >= max_used_fringe_bitmap)
1091 max_used_fringe_bitmap = which + 1;
1092 }
1093}
1094
1095
1096DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1097 1, 5, 0,
1098 doc: /* Define a fringe bitmap from BITS of height HEIGHT and width WIDTH.
1099BITS is either a string or a vector of integers.
1100HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1101WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1102Optional forth arg ALIGN may be one of `top', `center', or `bottom',
1103indicating the positioning of the bitmap relative to the rows where it
1104is used; the default is to center the bitmap. Fourth arg may also be a
1105list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1106should be repeated.
1107Optional fifth argument WHICH is bitmap number to redefine.
1108Return new bitmap number, or nil of no more free bitmap slots. */)
1109 (bits, height, width, align, which)
1110 Lisp_Object bits, height, width, align, which;
1111{
1112 Lisp_Object len;
1113 int n, h, i, j;
1114 unsigned short *b;
1115 struct fringe_bitmap fb, *xfb;
1116 int fill1 = 0, fill2 = 0;
1117
1118 if (!STRINGP (bits) && !VECTORP (bits))
1119 bits = wrong_type_argument (Qstringp, bits);
1120
1121 len = Flength (bits);
1122
1123 if (NILP (height))
1124 h = fb.height = XINT (len);
1125 else
1126 {
1127 CHECK_NUMBER (height);
1128 fb.height = min (XINT (height), 255);
1129 if (fb.height > XINT (len))
1130 {
1131 h = XINT (len);
1132 fill1 = (fb.height - h) / 2;
1133 fill2 = fb.height - h - fill1;
1134 }
1135 }
1136
1137 if (NILP (width))
1138 fb.width = 8;
1139 else
1140 {
1141 CHECK_NUMBER (width);
1142 fb.width = min (XINT (width), 255);
1143 }
1144
1145 fb.period = 0;
1146 fb.align = ALIGN_BITMAP_CENTER;
1147
1148 if (CONSP (align))
1149 {
1150 Lisp_Object period = XCDR (align);
1151 if (CONSP (period))
1152 {
1153 period = XCAR (period);
1154 if (!NILP (period))
1155 {
1156 fb.period = fb.height;
1157 fb.height = 255;
1158 }
1159 }
1160 align = XCAR (align);
1161 }
1162 if (EQ (align, Qtop))
1163 fb.align = ALIGN_BITMAP_TOP;
1164 else if (EQ (align, Qbottom))
1165 fb.align = ALIGN_BITMAP_BOTTOM;
1166 else if (!NILP (align) && !EQ (align, Qcenter))
1167 error ("Bad align argument");
1168
1169 if (NILP (which))
1170 {
1171 if (max_used_fringe_bitmap < MAX_FRINGE_BITMAPS)
1172 n = max_used_fringe_bitmap++;
1173 else
1174 {
1175 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1176 n < MAX_FRINGE_BITMAPS;
1177 n++)
1178 if (fringe_bitmaps[n] == NULL)
1179 break;
1180 if (n == MAX_FRINGE_BITMAPS)
1181 return Qnil;
1182 }
1183 which = make_number (n);
1184 }
1185 else
1186 {
1187 CHECK_NUMBER (which);
1188 n = XINT (which);
1189 if (n <= NO_FRINGE_BITMAP || n >= MAX_FRINGE_BITMAPS)
1190 error ("Invalid fringe bitmap number");
1191 }
1192
1193 fb.dynamic = 1;
1194
1195 xfb = (struct fringe_bitmap *)xmalloc (sizeof fb
1196 + fb.height * BYTES_PER_BITMAP_ROW);
1197 fb.bits = b = (unsigned short *)(xfb+1);
1198 bzero (b, fb.height);
1199
1200 j = 0;
1201 while (j < fb.height)
1202 {
1203 for (i = 0; i < fill1 && j < fb.height; i++)
1204 b[j++] = 0;
1205 for (i = 0; i < h && j < fb.height; i++)
1206 {
1207 Lisp_Object elt = Faref (bits, make_number (i));
1208 b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1209 }
1210 for (i = 0; i < fill2 && j < fb.height; i++)
1211 b[j++] = 0;
1212 }
1213
1214 *xfb = fb;
1215
1216 init_fringe_bitmap (n, xfb, 0);
1217
1218 return which;
1219}
1220
1221DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1222 1, 2, 0,
1223 doc: /* Set face for fringe bitmap FRINGE-ID to FACE.
1224If FACE is nil, reset face to default fringe face. */)
1225 (fringe_id, face)
1226 Lisp_Object fringe_id, face;
1227{
1228 int face_id;
1229
1230 CHECK_NUMBER (fringe_id);
1231 if (!valid_fringe_bitmap_id_p (XINT (fringe_id)))
1232 error ("Invalid fringe id");
1233
1234 if (!NILP (face))
1235 {
1236 face_id = lookup_named_face (SELECTED_FRAME (), face, 'A');
1237 if (face_id < 0)
1238 error ("No such face");
1239 }
1240 else
1241 face_id = FRINGE_FACE_ID;
1242
1243 fringe_faces [XINT (fringe_id)] = face_id;
1244
1245 return Qnil;
1246}
1247
1248DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1249 0, 2, 0,
1250 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1251If WINDOW is nil, use selected window. If POS is nil, use value of point
1252in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT
1253are the fringe bitmap numbers for the bitmaps in the left and right fringe,
1254resp. Return nil if POS is not visible in WINDOW. */)
1255 (pos, window)
1256 Lisp_Object pos, window;
1257{
1258 struct window *w;
1259 struct buffer *old_buffer = NULL;
1260 struct glyph_row *row;
1261 int textpos;
1262
1263 if (NILP (window))
1264 window = selected_window;
1265 CHECK_WINDOW (window);
1266 w = XWINDOW (window);
1267
1268 if (!NILP (pos))
1269 {
1270 CHECK_NUMBER_COERCE_MARKER (pos);
1271 textpos = XINT (pos);
1272 }
1273 else if (w == XWINDOW (selected_window))
1274 textpos = PT;
1275 else
1276 textpos = XMARKER (w->pointm)->charpos;
1277
1278 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1279 row = row_containing_pos (w, textpos, row, NULL, 0);
1280 if (row)
1281 return Fcons (make_number (row->left_fringe_bitmap),
1282 make_number (row->right_fringe_bitmap));
1283 else
1284 return Qnil;
1285}
1286
1287
1288/***********************************************************************
1289 Initialization
1290 ***********************************************************************/
1291
1292void
1293syms_of_fringe ()
1294{
1295
1296 defsubr (&Sdestroy_fringe_bitmap);
1297 defsubr (&Sdefine_fringe_bitmap);
1298 defsubr (&Sfringe_bitmaps_at_pos);
1299 defsubr (&Sset_fringe_bitmap_face);
1300
1301 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1302 doc: /* *Non-nil means that newline may flow into the right fringe.
1303This means that display lines which are exactly as wide as the window
1304(not counting the final newline) will only occupy one screen line, by
1305showing (or hiding) the final newline in the right fringe; when point
1306is at the final newline, the cursor is shown in the right fringe.
1307If nil, also continue lines which are exactly as wide as the window. */);
1308 Voverflow_newline_into_fringe = Qt;
1309
1310}
1311
1312/* Initialize this module when Emacs starts. */
1313
1314void
1315init_fringe_once ()
1316{
1317 enum fringe_bitmap_type bt;
1318
1319 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1320 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1321}
1322
1323void
1324init_fringe ()
1325{
1326 int i;
1327
1328 bzero (fringe_bitmaps, sizeof fringe_bitmaps);
1329 for (i = 0; i < MAX_FRINGE_BITMAPS; i++)
1330 fringe_faces[i] = FRINGE_FACE_ID;
1331}
1332
1333#ifdef HAVE_NTGUI
1334
1335void
1336w32_init_fringe ()
1337{
1338 enum fringe_bitmap_type bt;
1339
1340 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1341 {
1342 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1343 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1344 }
1345}
1346
1347void
1348w32_reset_fringes ()
1349{
1350 /* Destroy row bitmaps. */
1351 int bt;
1352
1353 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1354 rif->destroy_fringe_bitmap (bt);
1355}
1356
1357#endif /* HAVE_NTGUI */
1358
1359#endif /* HAVE_WINDOW_SYSTEM */
1360
1361/* arch-tag: 04596920-43eb-473d-b319-82712338162d
1362 (do not change this comment) */
diff --git a/src/keyboard.c b/src/keyboard.c
index 11e1d18c7d5..8223049d79d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1322,6 +1322,7 @@ cancel_hourglass_unwind (arg)
1322 Lisp_Object arg; 1322 Lisp_Object arg;
1323{ 1323{
1324 cancel_hourglass (); 1324 cancel_hourglass ();
1325 return Qnil;
1325} 1326}
1326#endif 1327#endif
1327 1328
diff --git a/src/keymap.c b/src/keymap.c
index d03c84aa69d..4cea62c10fb 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1,5 +1,5 @@
1/* Manipulation of keymaps 1/* Manipulation of keymaps
2 Copyright (C) 1985, 86,87,88,93,94,95,98,99, 2000, 2001 2 Copyright (C) 1985, 86,87,88,93,94,95,98,99, 2000, 01, 2004
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -2321,7 +2321,7 @@ shadow_lookup (shadow, key, flag)
2321 return Qnil; 2321 return Qnil;
2322} 2322}
2323 2323
2324static Lisp_Object Vmenu_events; 2324static Lisp_Object Vmouse_events;
2325 2325
2326/* This function can GC if Flookup_key autoloads any keymaps. */ 2326/* This function can GC if Flookup_key autoloads any keymaps. */
2327 2327
@@ -2378,7 +2378,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
2378 /* if (nomenus && !ascii_sequence_p (this)) */ 2378 /* if (nomenus && !ascii_sequence_p (this)) */
2379 if (nomenus && XINT (last) >= 0 2379 if (nomenus && XINT (last) >= 0
2380 && SYMBOLP (tem = Faref (this, make_number (0))) 2380 && SYMBOLP (tem = Faref (this, make_number (0)))
2381 && !NILP (Fmemq (XCAR (parse_modifiers (tem)), Vmenu_events))) 2381 && !NILP (Fmemq (XCAR (parse_modifiers (tem)), Vmouse_events)))
2382 /* If no menu entries should be returned, skip over the 2382 /* If no menu entries should be returned, skip over the
2383 keymaps bound to `menu-bar' and `tool-bar' and other 2383 keymaps bound to `menu-bar' and `tool-bar' and other
2384 non-ascii prefixes like `C-down-mouse-2'. */ 2384 non-ascii prefixes like `C-down-mouse-2'. */
@@ -3710,13 +3710,17 @@ This keymap works like `function-key-map', but comes after that,
3710and applies even for keys that have ordinary bindings. */); 3710and applies even for keys that have ordinary bindings. */);
3711 Vkey_translation_map = Qnil; 3711 Vkey_translation_map = Qnil;
3712 3712
3713 staticpro (&Vmenu_events); 3713 staticpro (&Vmouse_events);
3714 Vmenu_events = Fcons (intern ("menu-bar"), 3714 Vmouse_events = Fcons (intern ("menu-bar"),
3715 Fcons (intern ("tool-bar"), 3715 Fcons (intern ("tool-bar"),
3716 Fcons (intern ("mouse-1"), 3716 Fcons (intern ("header-line"),
3717 Fcons (intern ("mouse-2"), 3717 Fcons (intern ("mode-line"),
3718 Fcons (intern ("mouse-3"), 3718 Fcons (intern ("mouse-1"),
3719 Qnil))))); 3719 Fcons (intern ("mouse-2"),
3720 Fcons (intern ("mouse-3"),
3721 Fcons (intern ("mouse-4"),
3722 Fcons (intern ("mouse-5"),
3723 Qnil)))))))));
3720 3724
3721 3725
3722 Qsingle_key_description = intern ("single-key-description"); 3726 Qsingle_key_description = intern ("single-key-description");
diff --git a/src/lisp.h b/src/lisp.h
index 570d5ff9757..a0bc2af24bb 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2301,6 +2301,11 @@ EXFUN (Ftruncate, 2);
2301extern void init_floatfns P_ ((void)); 2301extern void init_floatfns P_ ((void));
2302extern void syms_of_floatfns P_ ((void)); 2302extern void syms_of_floatfns P_ ((void));
2303 2303
2304/* Defined in fringe.c */
2305extern void syms_of_fringe P_ ((void));
2306extern void init_fringe P_ ((void));
2307extern void init_fringe_once P_ ((void));
2308
2304/* Defined in insdel.c */ 2309/* Defined in insdel.c */
2305extern Lisp_Object Qinhibit_modification_hooks; 2310extern Lisp_Object Qinhibit_modification_hooks;
2306extern void move_gap P_ ((int)); 2311extern void move_gap P_ ((int));
diff --git a/src/macfns.c b/src/macfns.c
index 0f87556fb1e..a01811048fe 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -7792,12 +7792,25 @@ x_kill_gs_process (pixmap, f)
7792 ***********************************************************************/ 7792 ***********************************************************************/
7793 7793
7794DEFUN ("x-change-window-property", Fx_change_window_property, 7794DEFUN ("x-change-window-property", Fx_change_window_property,
7795 Sx_change_window_property, 2, 3, 0, 7795 Sx_change_window_property, 2, 6, 0,
7796 doc: /* Change window property PROP to VALUE on the X window of FRAME. 7796 doc: /* Change window property PROP to VALUE on the X window of FRAME.
7797PROP and VALUE must be strings. FRAME nil or omitted means use the 7797VALUE may be a string or a list of conses, numbers and/or strings.
7798selected frame. Value is VALUE. */) 7798If an element in the list is a string, it is converted to
7799 (prop, value, frame) 7799an Atom and the value of the Atom is used. If an element is a cons,
7800 Lisp_Object frame, prop, value; 7800it is converted to a 32 bit number where the car is the 16 top bits and the
7801cdr is the lower 16 bits.
7802FRAME nil or omitted means use the selected frame.
7803If TYPE is given and non-nil, it is the name of the type of VALUE.
7804If TYPE is not given or nil, the type is STRING.
7805FORMAT gives the size in bits of each element if VALUE is a list.
7806It must be one of 8, 16 or 32.
7807If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
7808If OUTER_P is non-nil, the property is changed for the outer X window of
7809FRAME. Default is to change on the edit X window.
7810
7811Value is VALUE. */)
7812 (prop, value, frame, type, format, outer_p)
7813 Lisp_Object prop, value, frame, type, format, outer_p;
7801{ 7814{
7802#if 0 /* MAC_TODO : port window properties to Mac */ 7815#if 0 /* MAC_TODO : port window properties to Mac */
7803 struct frame *f = check_x_frame (frame); 7816 struct frame *f = check_x_frame (frame);
diff --git a/src/macterm.c b/src/macterm.c
index 9c7c497c00b..8bcee4a86c3 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -467,15 +467,21 @@ XClearWindow (display, w)
467/* Mac replacement for XCopyArea. */ 467/* Mac replacement for XCopyArea. */
468 468
469static void 469static void
470mac_draw_bitmap (display, w, gc, x, y, bitmap) 470mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
471 Display *display; 471 Display *display;
472 WindowPtr w; 472 WindowPtr w;
473 GC gc; 473 GC gc;
474 int x, y; 474 int x, y, width, height;
475 BitMap *bitmap; 475 unsigned short *bits;
476 int overlay_p;
476{ 477{
478 BitMap bitmap;
477 Rect r; 479 Rect r;
478 480
481 bitmap.rowBytes = sizeof(unsigned short);
482 bitmap.baseAddr = bits;
483 SetRect (&(bitmap.bounds), 0, 0, width, height);
484
479#if TARGET_API_MAC_CARBON 485#if TARGET_API_MAC_CARBON
480 SetPort (GetWindowPort (w)); 486 SetPort (GetWindowPort (w));
481#else 487#else
@@ -483,7 +489,7 @@ mac_draw_bitmap (display, w, gc, x, y, bitmap)
483#endif 489#endif
484 490
485 mac_set_colors (gc); 491 mac_set_colors (gc);
486 SetRect (&r, x, y, x + bitmap->bounds.right, y + bitmap->bounds.bottom); 492 SetRect (&r, x, y, x + bitmap.bounds.right, y + bitmap.bounds.bottom);
487 493
488#if TARGET_API_MAC_CARBON 494#if TARGET_API_MAC_CARBON
489 { 495 {
@@ -491,11 +497,13 @@ mac_draw_bitmap (display, w, gc, x, y, bitmap)
491 497
492 LockPortBits (GetWindowPort (w)); 498 LockPortBits (GetWindowPort (w));
493 pmh = GetPortPixMap (GetWindowPort (w)); 499 pmh = GetPortPixMap (GetWindowPort (w));
494 CopyBits (bitmap, (BitMap *) *pmh, &(bitmap->bounds), &r, srcCopy, 0); 500 CopyBits (&bitmap, (BitMap *) *pmh, &(bitmap.bounds), &r,
501 overlay_p ? srcOr : srcCopy, 0);
495 UnlockPortBits (GetWindowPort (w)); 502 UnlockPortBits (GetWindowPort (w));
496 } 503 }
497#else /* not TARGET_API_MAC_CARBON */ 504#else /* not TARGET_API_MAC_CARBON */
498 CopyBits (bitmap, &(w->portBits), &(bitmap->bounds), &r, srcCopy, 0); 505 CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
506 overlay_p ? srcOr : srcCopy, 0);
499#endif /* not TARGET_API_MAC_CARBON */ 507#endif /* not TARGET_API_MAC_CARBON */
500} 508}
501 509
@@ -1313,7 +1321,7 @@ x_draw_fringe_bitmap (w, row, p)
1313 else 1321 else
1314 x_clip_to_row (w, row, gc); 1322 x_clip_to_row (w, row, gc);
1315 1323
1316 if (p->bx >= 0) 1324 if (p->bx >= 0 && !p->overlay_p)
1317 { 1325 {
1318 XGCValues gcv; 1326 XGCValues gcv;
1319 gcv.foreground = face->background; 1327 gcv.foreground = face->background;
@@ -1339,18 +1347,18 @@ x_draw_fringe_bitmap (w, row, p)
1339#endif 1347#endif
1340 } 1348 }
1341 1349
1342 if (p->which != NO_FRINGE_BITMAP) 1350 if (p->which)
1343 { 1351 {
1344 unsigned char *bits = fringe_bitmaps[p->which].bits + p->dh; 1352 unsigned short *bits = p->bits + p->dh;
1345 BitMap bitmap;
1346 1353
1347 mac_create_bitmap_from_bitmap_data (&bitmap, bits, p->wd, p->h); 1354 gcv.foreground = (p->cursor_p
1348 gcv.foreground = face->foreground; 1355 ? (p->overlay_p ? face->background
1356 : f->output_data.mac->cursor_pixel)
1357 : face->foreground);
1349 gcv.background = face->background; 1358 gcv.background = face->background;
1350 1359
1351 mac_draw_bitmap (display, window, &gcv, p->x, p->y, &bitmap); 1360 mac_draw_bitmap (display, window, &gcv, p->x, p->y,
1352 1361 p->wd, p->h, bits, p->overlay_p);
1353 mac_free_bitmap (&bitmap);
1354 } 1362 }
1355 1363
1356 mac_reset_clipping (display, window); 1364 mac_reset_clipping (display, window);
@@ -6455,12 +6463,19 @@ static long app_sleep_time = WNE_SLEEP_AT_RESUME;
6455 6463
6456Boolean terminate_flag = false; 6464Boolean terminate_flag = false;
6457 6465
6466/* Contains the string "reverse", which is a constant for mouse button emu.*/
6467Lisp_Object Qreverse;
6468
6458/* True if using command key as meta key. */ 6469/* True if using command key as meta key. */
6459Lisp_Object Vmac_command_key_is_meta; 6470Lisp_Object Vmac_command_key_is_meta;
6460 6471
6461/* True if the ctrl and meta keys should be reversed. */ 6472/* True if the ctrl and meta keys should be reversed. */
6462Lisp_Object Vmac_reverse_ctrl_meta; 6473Lisp_Object Vmac_reverse_ctrl_meta;
6463 6474
6475/* True if the option and command modifiers should be used to emulate
6476 a three button mouse */
6477Lisp_Object Vmac_emulate_three_button_mouse;
6478
6464#if USE_CARBON_EVENTS 6479#if USE_CARBON_EVENTS
6465/* True if the mouse wheel button (i.e. button 4) should map to 6480/* True if the mouse wheel button (i.e. button 4) should map to
6466 mouse-2, instead of mouse-3. */ 6481 mouse-2, instead of mouse-3. */
@@ -6533,6 +6548,20 @@ mac_to_emacs_modifiers (EventModifiers mods)
6533 return result; 6548 return result;
6534} 6549}
6535 6550
6551static int
6552mac_get_emulated_btn ( UInt32 modifiers )
6553{
6554 int result = 0;
6555 if (Vmac_emulate_three_button_mouse != Qnil) {
6556 int cmdIs3 = (Vmac_emulate_three_button_mouse != Qreverse);
6557 if (modifiers & controlKey)
6558 result = cmdIs3 ? 2 : 1;
6559 else if (modifiers & optionKey)
6560 result = cmdIs3 ? 1 : 2;
6561 }
6562 return result;
6563}
6564
6536#if USE_CARBON_EVENTS 6565#if USE_CARBON_EVENTS
6537/* Obtains the event modifiers from the event ref and then calls 6566/* Obtains the event modifiers from the event ref and then calls
6538 mac_to_emacs_modifiers. */ 6567 mac_to_emacs_modifiers. */
@@ -6542,6 +6571,11 @@ mac_event_to_emacs_modifiers (EventRef eventRef)
6542 UInt32 mods = 0; 6571 UInt32 mods = 0;
6543 GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL, 6572 GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
6544 sizeof (UInt32), NULL, &mods); 6573 sizeof (UInt32), NULL, &mods);
6574 if (Vmac_emulate_three_button_mouse != Qnil &&
6575 GetEventClass(eventRef) == kEventClassMouse)
6576 {
6577 mods &= ~(optionKey & cmdKey);
6578 }
6545 return mac_to_emacs_modifiers (mods); 6579 return mac_to_emacs_modifiers (mods);
6546} 6580}
6547 6581
@@ -6556,7 +6590,14 @@ mac_get_mouse_btn (EventRef ref)
6556 switch (result) 6590 switch (result)
6557 { 6591 {
6558 case kEventMouseButtonPrimary: 6592 case kEventMouseButtonPrimary:
6559 return 0; 6593 if (Vmac_emulate_three_button_mouse == Qnil)
6594 return 0;
6595 else {
6596 UInt32 mods = 0;
6597 GetEventParameter (ref, kEventParamKeyModifiers, typeUInt32, NULL,
6598 sizeof (UInt32), NULL, &mods);
6599 return mac_get_emulated_btn(mods);
6600 }
6560 case kEventMouseButtonSecondary: 6601 case kEventMouseButtonSecondary:
6561 return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2; 6602 return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2;
6562 case kEventMouseButtonTertiary: 6603 case kEventMouseButtonTertiary:
@@ -7692,7 +7733,7 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
7692#if USE_CARBON_EVENTS 7733#if USE_CARBON_EVENTS
7693 bufp->code = mac_get_mouse_btn (eventRef); 7734 bufp->code = mac_get_mouse_btn (eventRef);
7694#else 7735#else
7695 bufp->code = 0; /* only one mouse button */ 7736 bufp_.code = mac_get_emulate_btn (er.modifiers);
7696#endif 7737#endif
7697 bufp->kind = SCROLL_BAR_CLICK_EVENT; 7738 bufp->kind = SCROLL_BAR_CLICK_EVENT;
7698 bufp->frame_or_window = tracked_scroll_bar->window; 7739 bufp->frame_or_window = tracked_scroll_bar->window;
@@ -7760,7 +7801,7 @@ XTread_socket (struct input_event *bufp, int numchars, int expected)
7760#if USE_CARBON_EVENTS 7801#if USE_CARBON_EVENTS
7761 bufp->code = mac_get_mouse_btn (eventRef); 7802 bufp->code = mac_get_mouse_btn (eventRef);
7762#else 7803#else
7763 bufp->code = 0; /* only one mouse button */ 7804 bufp_.code = mac_get_emulate_btn (er.modifiers);
7764#endif 7805#endif
7765 XSETINT (bufp->x, mouse_loc.h); 7806 XSETINT (bufp->x, mouse_loc.h);
7766 XSETINT (bufp->y, mouse_loc.v); 7807 XSETINT (bufp->y, mouse_loc.v);
@@ -8517,6 +8558,8 @@ static struct redisplay_interface x_redisplay_interface =
8517 x_get_glyph_overhangs, 8558 x_get_glyph_overhangs,
8518 x_fix_overlapping_area, 8559 x_fix_overlapping_area,
8519 x_draw_fringe_bitmap, 8560 x_draw_fringe_bitmap,
8561 0, /* define_fringe_bitmap */
8562 0, /* destroy_fringe_bitmap */
8520 mac_per_char_metric, 8563 mac_per_char_metric,
8521 mac_encode_char, 8564 mac_encode_char,
8522 NULL, /* mac_compute_glyph_string_overhangs */ 8565 NULL, /* mac_compute_glyph_string_overhangs */
@@ -8636,6 +8679,9 @@ syms_of_macterm ()
8636 8679
8637 Fprovide (intern ("mac-carbon"), Qnil); 8680 Fprovide (intern ("mac-carbon"), Qnil);
8638 8681
8682 staticpro (&Qreverse);
8683 Qreverse = intern ("reverse");
8684
8639 staticpro (&x_display_name_list); 8685 staticpro (&x_display_name_list);
8640 x_display_name_list = Qnil; 8686 x_display_name_list = Qnil;
8641 8687
@@ -8680,6 +8726,17 @@ Otherwise the option key is used. */);
8680 useful for non-standard keyboard layouts. */); 8726 useful for non-standard keyboard layouts. */);
8681 Vmac_reverse_ctrl_meta = Qnil; 8727 Vmac_reverse_ctrl_meta = Qnil;
8682 8728
8729 DEFVAR_LISP ("mac-emulate-three-button-mouse",
8730 &Vmac_emulate_three_button_mouse,
8731 doc: /* t means that when the option-key is held down while pressing the
8732 mouse button, the click will register as mouse-2 and while the
8733 command-key is held down, the click will register as mouse-3.
8734 'reverse means that the the option-key will register for mouse-3
8735 and the command-key will register for mouse-2. nil means that
8736 not emulation should be done and the modifiers should be placed
8737 on the mouse-1 event. */);
8738 Vmac_emulate_three_button_mouse = Qnil;
8739
8683#if USE_CARBON_EVENTS 8740#if USE_CARBON_EVENTS
8684 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2, 8741 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2,
8685 doc: /* Non-nil means that the wheel button will be treated as mouse-2 and 8742 doc: /* Non-nil means that the wheel button will be treated as mouse-2 and
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index bd5ad98571c..1007e3940b0 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -118,7 +118,8 @@ OBJ1 = $(BLD)/abbrev.$(O) \
118 $(BLD)/coding.$(O) \ 118 $(BLD)/coding.$(O) \
119 $(BLD)/category.$(O) \ 119 $(BLD)/category.$(O) \
120 $(BLD)/ccl.$(O) \ 120 $(BLD)/ccl.$(O) \
121 $(BLD)/fontset.$(O) 121 $(BLD)/fontset.$(O) \
122 $(BLD)/fringe.$(O)
122 123
123WIN32OBJ = $(BLD)/w32term.$(O) \ 124WIN32OBJ = $(BLD)/w32term.$(O) \
124 $(BLD)/w32xfns.$(O) \ 125 $(BLD)/w32xfns.$(O) \
diff --git a/src/minibuf.c b/src/minibuf.c
index 6124054f3c0..1f5a114540d 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -132,6 +132,8 @@ Lisp_Object Qminibuffer_default;
132 132
133Lisp_Object Qcurrent_input_method, Qactivate_input_method; 133Lisp_Object Qcurrent_input_method, Qactivate_input_method;
134 134
135Lisp_Object Qcase_fold_search;
136
135extern Lisp_Object Qmouse_face; 137extern Lisp_Object Qmouse_face;
136 138
137extern Lisp_Object Qfield; 139extern Lisp_Object Qfield;
@@ -322,7 +324,8 @@ read_minibuf_noninteractive (map, initial, prompt, backup_n, expflag,
322DEFUN ("minibufferp", Fminibufferp, 324DEFUN ("minibufferp", Fminibufferp,
323 Sminibufferp, 0, 1, 0, 325 Sminibufferp, 0, 1, 0,
324 doc: /* Return t if BUFFER is a minibuffer. 326 doc: /* Return t if BUFFER is a minibuffer.
325No argument or nil as argument means use current buffer as BUFFER.*/) 327No argument or nil as argument means use current buffer as BUFFER.
328BUFFER can be a buffer or a buffer name. */)
326 (buffer) 329 (buffer)
327 Lisp_Object buffer; 330 Lisp_Object buffer;
328{ 331{
@@ -411,9 +414,9 @@ minibuffer_completion_contents ()
411 with initial position HISTPOS. INITIAL should be a string or a 414 with initial position HISTPOS. INITIAL should be a string or a
412 cons of a string and an integer. BACKUP_N should be <= 0, or 415 cons of a string and an integer. BACKUP_N should be <= 0, or
413 Qnil, which is equivalent to 0. If INITIAL is a cons, BACKUP_N is 416 Qnil, which is equivalent to 0. If INITIAL is a cons, BACKUP_N is
414 ignored and replaced with an integer that puts point N characters 417 ignored and replaced with an integer that puts point at one-indexed
415 from the beginning of INITIAL, where N is the CDR of INITIAL, or at 418 position N in INITIAL, where N is the CDR of INITIAL, or at the
416 the beginning of INITIAL if N <= 0. 419 beginning of INITIAL if N <= 0.
417 420
418 Normally return the result as a string (the text that was read), 421 Normally return the result as a string (the text that was read),
419 but if EXPFLAG is nonzero, read it and return the object read. 422 but if EXPFLAG is nonzero, read it and return the object read.
@@ -898,23 +901,22 @@ read_minibuf_unwind (data)
898 901
899DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 7, 0, 902DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 7, 0,
900 doc: /* Read a string from the minibuffer, prompting with string PROMPT. 903 doc: /* Read a string from the minibuffer, prompting with string PROMPT.
901If optional second arg INITIAL-CONTENTS is non-nil, it is a string 904The optional second arg INITIAL-CONTENTS is an obsolete alternative to
902 to be inserted into the minibuffer before reading input. 905 DEFAULT-VALUE. It normally should be nil in new code, except when
903 If INITIAL-CONTENTS is (STRING . POSITION), the initial input 906 HIST is a cons. It is discussed in more detail below.
904 is STRING, but point is placed at position POSITION in the minibuffer.
905Third arg KEYMAP is a keymap to use whilst reading; 907Third arg KEYMAP is a keymap to use whilst reading;
906 if omitted or nil, the default is `minibuffer-local-map'. 908 if omitted or nil, the default is `minibuffer-local-map'.
907If fourth arg READ is non-nil, then interpret the result as a Lisp object 909If fourth arg READ is non-nil, then interpret the result as a Lisp object
908 and return that object: 910 and return that object:
909 in other words, do `(car (read-from-string INPUT-STRING))' 911 in other words, do `(car (read-from-string INPUT-STRING))'
910Fifth arg HIST, if non-nil, specifies a history list 912Fifth arg HIST, if non-nil, specifies a history list and optionally
911 and optionally the initial position in the list. 913 the initial position in the list. It can be a symbol, which is the
912 It can be a symbol, which is the history list variable to use, 914 history list variable to use, or it can be a cons cell
913 or it can be a cons cell (HISTVAR . HISTPOS). 915 (HISTVAR . HISTPOS). In that case, HISTVAR is the history list variable
914 In that case, HISTVAR is the history list variable to use, 916 to use, and HISTPOS is the initial position for use by the minibuffer
915 and HISTPOS is the initial position (the position in the list 917 history commands. For consistency, you should also specify that
916 which INITIAL-CONTENTS corresponds to). 918 element of the history as the value of INITIAL-CONTENTS. Positions
917 Positions are counted starting from 1 at the beginning of the list. 919 are counted starting from 1 at the beginning of the list.
918Sixth arg DEFAULT-VALUE is the default value. If non-nil, it is available 920Sixth arg DEFAULT-VALUE is the default value. If non-nil, it is available
919 for history commands; but, unless READ is non-nil, `read-from-minibuffer' 921 for history commands; but, unless READ is non-nil, `read-from-minibuffer'
920 does NOT return DEFAULT-VALUE if the user enters empty input! It returns 922 does NOT return DEFAULT-VALUE if the user enters empty input! It returns
@@ -923,7 +925,19 @@ Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
923 the current input method and the setting of `enable-multibyte-characters'. 925 the current input method and the setting of `enable-multibyte-characters'.
924If the variable `minibuffer-allow-text-properties' is non-nil, 926If the variable `minibuffer-allow-text-properties' is non-nil,
925 then the string which is returned includes whatever text properties 927 then the string which is returned includes whatever text properties
926 were present in the minibuffer. Otherwise the value has no text properties. */) 928 were present in the minibuffer. Otherwise the value has no text properties.
929
930The remainder of this documentation string describes the
931INITIAL-CONTENTS argument in more detail. It is only relevant when
932studying existing code, or when HIST is a cons. If non-nil,
933INITIAL-CONTENTS is a string to be inserted into the minibuffer before
934reading input. Normally, point is put at the end of that string.
935However, if INITIAL-CONTENTS is \(STRING . POSITION), the initial
936input is STRING, but point is placed at _one-indexed_ position
937POSITION in the minibuffer. Any integer value less than or equal to
938one puts point at the beginning of the string. *Note* that this
939behavior differs from the way such arguments are used in `completing-read'
940and some related functions, which use zero-indexing for POSITION. */)
927 (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method) 941 (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
928 Lisp_Object prompt, initial_contents, keymap, read, hist, default_value; 942 Lisp_Object prompt, initial_contents, keymap, read, hist, default_value;
929 Lisp_Object inherit_input_method; 943 Lisp_Object inherit_input_method;
@@ -963,9 +977,11 @@ If the variable `minibuffer-allow-text-properties' is non-nil,
963} 977}
964 978
965DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0, 979DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0,
966 doc: /* Return a Lisp object read using the minibuffer. 980 doc: /* Return a Lisp object read using the minibuffer, unevaluated.
967Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS 981Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
968is a string to insert in the minibuffer before reading. */) 982is a string to insert in the minibuffer before reading.
983\(INITIAL-CONTENTS can also be a cons of a string and an integer. Such
984arguments are used as in `read-from-minibuffer') */)
969 (prompt, initial_contents) 985 (prompt, initial_contents)
970 Lisp_Object prompt, initial_contents; 986 Lisp_Object prompt, initial_contents;
971{ 987{
@@ -978,7 +994,9 @@ is a string to insert in the minibuffer before reading. */)
978DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0, 994DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0,
979 doc: /* Return value of Lisp expression read using the minibuffer. 995 doc: /* Return value of Lisp expression read using the minibuffer.
980Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS 996Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
981is a string to insert in the minibuffer before reading. */) 997is a string to insert in the minibuffer before reading.
998\(INITIAL-CONTENTS can also be a cons of a string and an integer. Such
999arguments are used as in `read-from-minibuffer') */)
982 (prompt, initial_contents) 1000 (prompt, initial_contents)
983 Lisp_Object prompt, initial_contents; 1001 Lisp_Object prompt, initial_contents;
984{ 1002{
@@ -990,6 +1008,9 @@ is a string to insert in the minibuffer before reading. */)
990DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0, 1008DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0,
991 doc: /* Read a string from the minibuffer, prompting with string PROMPT. 1009 doc: /* Read a string from the minibuffer, prompting with string PROMPT.
992If non-nil, second arg INITIAL-INPUT is a string to insert before reading. 1010If non-nil, second arg INITIAL-INPUT is a string to insert before reading.
1011 This argument has been superseded by DEFAULT-VALUE and should normally
1012 be nil in new code. It behaves as in `read-from-minibuffer'. See the
1013 documentation string of that function for details.
993The third arg HISTORY, if non-nil, specifies a history list 1014The third arg HISTORY, if non-nil, specifies a history list
994 and optionally the initial position in the list. 1015 and optionally the initial position in the list.
995See `read-from-minibuffer' for details of HISTORY argument. 1016See `read-from-minibuffer' for details of HISTORY argument.
@@ -1013,9 +1034,14 @@ Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
1013 1034
1014DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 3, 0, 1035DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 3, 0,
1015 doc: /* Read a string from the terminal, not allowing blanks. 1036 doc: /* Read a string from the terminal, not allowing blanks.
1016Prompt with PROMPT, and provide INITIAL as an initial value of the input string. 1037Prompt with PROMPT. Whitespace terminates the input. If INITIAL is
1038non-nil, it should be a string, which is used as initial input, with
1039point positioned at the end, so that SPACE will accept the input.
1040\(Actually, INITIAL can also be a cons of a string and an integer.
1041Such values are treated as in `read-from-minibuffer', but are normally
1042not useful in this function.)
1017Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits 1043Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
1018the current input method and the setting of `enable-multibyte-characters'. */) 1044the current input method and the setting of`enable-multibyte-characters'. */)
1019 (prompt, initial, inherit_input_method) 1045 (prompt, initial, inherit_input_method)
1020 Lisp_Object prompt, initial, inherit_input_method; 1046 Lisp_Object prompt, initial, inherit_input_method;
1021{ 1047{
@@ -1243,7 +1269,7 @@ is used to further constrain the set of candidates. */)
1243 && (tem = Fcompare_strings (eltstring, make_number (0), 1269 && (tem = Fcompare_strings (eltstring, make_number (0),
1244 make_number (SCHARS (string)), 1270 make_number (SCHARS (string)),
1245 string, make_number (0), Qnil, 1271 string, make_number (0), Qnil,
1246 completion_ignore_case ?Qt : Qnil), 1272 completion_ignore_case ? Qt : Qnil),
1247 EQ (Qt, tem))) 1273 EQ (Qt, tem)))
1248 { 1274 {
1249 /* Yes. */ 1275 /* Yes. */
@@ -1252,15 +1278,20 @@ is used to further constrain the set of candidates. */)
1252 XSETFASTINT (zero, 0); 1278 XSETFASTINT (zero, 0);
1253 1279
1254 /* Ignore this element if it fails to match all the regexps. */ 1280 /* Ignore this element if it fails to match all the regexps. */
1255 for (regexps = Vcompletion_regexp_list; CONSP (regexps); 1281 {
1256 regexps = XCDR (regexps)) 1282 int count = SPECPDL_INDEX ();
1257 { 1283 specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
1258 tem = Fstring_match (XCAR (regexps), eltstring, zero); 1284 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
1259 if (NILP (tem)) 1285 regexps = XCDR (regexps))
1260 break; 1286 {
1261 } 1287 tem = Fstring_match (XCAR (regexps), eltstring, zero);
1262 if (CONSP (regexps)) 1288 if (NILP (tem))
1263 continue; 1289 break;
1290 }
1291 unbind_to (count, Qnil);
1292 if (CONSP (regexps))
1293 continue;
1294 }
1264 1295
1265 /* Ignore this element if there is a predicate 1296 /* Ignore this element if there is a predicate
1266 and the predicate doesn't like it. */ 1297 and the predicate doesn't like it. */
@@ -1498,15 +1529,20 @@ are ignored unless STRING itself starts with a space. */)
1498 XSETFASTINT (zero, 0); 1529 XSETFASTINT (zero, 0);
1499 1530
1500 /* Ignore this element if it fails to match all the regexps. */ 1531 /* Ignore this element if it fails to match all the regexps. */
1501 for (regexps = Vcompletion_regexp_list; CONSP (regexps); 1532 {
1502 regexps = XCDR (regexps)) 1533 int count = SPECPDL_INDEX ();
1503 { 1534 specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
1504 tem = Fstring_match (XCAR (regexps), eltstring, zero); 1535 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
1505 if (NILP (tem)) 1536 regexps = XCDR (regexps))
1506 break; 1537 {
1507 } 1538 tem = Fstring_match (XCAR (regexps), eltstring, zero);
1508 if (CONSP (regexps)) 1539 if (NILP (tem))
1509 continue; 1540 break;
1541 }
1542 unbind_to (count, Qnil);
1543 if (CONSP (regexps))
1544 continue;
1545 }
1510 1546
1511 /* Ignore this element if there is a predicate 1547 /* Ignore this element if there is a predicate
1512 and the predicate doesn't like it. */ 1548 and the predicate doesn't like it. */
@@ -1542,7 +1578,7 @@ Lisp_Object Vminibuffer_completing_file_name;
1542DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0, 1578DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0,
1543 doc: /* Read a string in the minibuffer, with completion. 1579 doc: /* Read a string in the minibuffer, with completion.
1544PROMPT is a string to prompt with; normally it ends in a colon and a space. 1580PROMPT is a string to prompt with; normally it ends in a colon and a space.
1545TABLE is an alist whose elements' cars are strings, or an obarray. 1581TABLE can be an list of strings, an alist, an obarray or a hash table.
1546TABLE can also be a function to do the completion itself. 1582TABLE can also be a function to do the completion itself.
1547PREDICATE limits completion to a subset of TABLE. 1583PREDICATE limits completion to a subset of TABLE.
1548See `try-completion' and `all-completions' for more details 1584See `try-completion' and `all-completions' for more details
@@ -1551,26 +1587,30 @@ See `try-completion' and `all-completions' for more details
1551If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless 1587If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless
1552 the input is (or completes to) an element of TABLE or is null. 1588 the input is (or completes to) an element of TABLE or is null.
1553 If it is also not t, typing RET does not exit if it does non-null completion. 1589 If it is also not t, typing RET does not exit if it does non-null completion.
1554If the input is null, `completing-read' returns an empty string, 1590If the input is null, `completing-read' returns DEF, or an empty string
1555 regardless of the value of REQUIRE-MATCH. 1591 if DEF is nil, regardless of the value of REQUIRE-MATCH.
1556 1592
1557If INITIAL-INPUT is non-nil, insert it in the minibuffer initially. 1593If INITIAL-INPUT is non-nil, insert it in the minibuffer initially,
1558 If it is (STRING . POSITION), the initial input 1594 with point positioned at the end.
1559 is STRING, but point is placed POSITION characters into the string. 1595 If it is (STRING . POSITION), the initial input is STRING, but point
1560 This feature is deprecated--it is best to pass nil for INITIAL-INPUT 1596 is placed at _zero-indexed_ position POSITION in STRING. (*Note*
1561 and supply the default value DEF instead. The user can yank the 1597 that this is different from `read-from-minibuffer' and related
1562 default value into the minibuffer easily using \\[next-history-element]. 1598 functions, which use one-indexing for POSITION.) This feature is
1563 1599 deprecated--it is best to pass nil for INITIAL-INPUT and supply the
1564HIST, if non-nil, specifies a history list 1600 default value DEF instead. The user can yank the default value into
1565 and optionally the initial position in the list. 1601 the minibuffer easily using \\[next-history-element].
1566 It can be a symbol, which is the history list variable to use, 1602
1567 or it can be a cons cell (HISTVAR . HISTPOS). 1603HIST, if non-nil, specifies a history list and optionally the initial
1568 In that case, HISTVAR is the history list variable to use, 1604 position in the list. It can be a symbol, which is the history list
1569 and HISTPOS is the initial position (the position in the list 1605 variable to use, or it can be a cons cell (HISTVAR . HISTPOS). In
1570 which INITIAL-INPUT corresponds to). 1606 that case, HISTVAR is the history list variable to use, and HISTPOS
1571 Positions are counted starting from 1 at the beginning of the list. 1607 is the initial position (the position in the list used by the
1572 The variable `history-length' controls the maximum length of a 1608 minibuffer history commands). For consistency, you should also
1573 history list. 1609 specify that element of the history as the value of
1610 INITIAL-CONTENTS. (This is the only case in which you should use
1611 INITIAL-INPUT instead of DEF.) Positions are counted starting from
1612 1 at the beginning of the list. The variable `history-length'
1613 controls the maximum length of a history list.
1574 1614
1575DEF, if non-nil, is the default value. 1615DEF, if non-nil, is the default value.
1576 1616
@@ -1737,20 +1777,27 @@ the values STRING, PREDICATE and `lambda'. */)
1737 return call3 (alist, string, predicate, Qlambda); 1777 return call3 (alist, string, predicate, Qlambda);
1738 1778
1739 /* Reject this element if it fails to match all the regexps. */ 1779 /* Reject this element if it fails to match all the regexps. */
1740 for (regexps = Vcompletion_regexp_list; CONSP (regexps); 1780 {
1741 regexps = XCDR (regexps)) 1781 int count = SPECPDL_INDEX ();
1742 { 1782 specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
1743 if (NILP (Fstring_match (XCAR (regexps), 1783 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
1744 SYMBOLP (tem) ? string : tem, 1784 regexps = XCDR (regexps))
1745 Qnil))) 1785 {
1746 return Qnil; 1786 if (NILP (Fstring_match (XCAR (regexps),
1747 } 1787 SYMBOLP (tem) ? string : tem,
1788 Qnil)))
1789 return unbind_to (count, Qnil);
1790 }
1791 unbind_to (count, Qnil);
1792 }
1748 1793
1749 /* Finally, check the predicate. */ 1794 /* Finally, check the predicate. */
1750 if (!NILP (predicate)) 1795 if (!NILP (predicate))
1751 return HASH_TABLE_P (alist) 1796 {
1752 ? call2 (predicate, tem, HASH_VALUE (XHASH_TABLE (alist), i)) 1797 return HASH_TABLE_P (alist)
1753 : call1 (predicate, tem); 1798 ? call2 (predicate, tem, HASH_VALUE (XHASH_TABLE (alist), i))
1799 : call1 (predicate, tem);
1800 }
1754 else 1801 else
1755 return Qt; 1802 return Qt;
1756} 1803}
@@ -2212,6 +2259,8 @@ DEFUN ("display-completion-list", Fdisplay_completion_list, Sdisplay_completion_
2212 doc: /* Display the list of completions, COMPLETIONS, using `standard-output'. 2259 doc: /* Display the list of completions, COMPLETIONS, using `standard-output'.
2213Each element may be just a symbol or string 2260Each element may be just a symbol or string
2214or may be a list of two strings to be printed as if concatenated. 2261or may be a list of two strings to be printed as if concatenated.
2262If it is a list of two strings, the first is the actual completion
2263alternative, the second serves as annotation.
2215`standard-output' must be a buffer. 2264`standard-output' must be a buffer.
2216The actual completion alternatives, as inserted, are given `mouse-face' 2265The actual completion alternatives, as inserted, are given `mouse-face'
2217properties of `highlight'. 2266properties of `highlight'.
@@ -2252,6 +2301,8 @@ It can find the completion buffer in `standard-output'. */)
2252 startpos = Qnil; 2301 startpos = Qnil;
2253 2302
2254 elt = Fcar (tail); 2303 elt = Fcar (tail);
2304 if (SYMBOLP (elt))
2305 elt = SYMBOL_NAME (elt);
2255 /* Compute the length of this element. */ 2306 /* Compute the length of this element. */
2256 if (CONSP (elt)) 2307 if (CONSP (elt))
2257 { 2308 {
@@ -2563,6 +2614,9 @@ syms_of_minibuf ()
2563 Qactivate_input_method = intern ("activate-input-method"); 2614 Qactivate_input_method = intern ("activate-input-method");
2564 staticpro (&Qactivate_input_method); 2615 staticpro (&Qactivate_input_method);
2565 2616
2617 Qcase_fold_search = intern ("case-fold-search");
2618 staticpro (&Qcase_fold_search);
2619
2566 DEFVAR_LISP ("read-buffer-function", &Vread_buffer_function, 2620 DEFVAR_LISP ("read-buffer-function", &Vread_buffer_function,
2567 doc: /* If this is non-nil, `read-buffer' does its work by calling this function. */); 2621 doc: /* If this is non-nil, `read-buffer' does its work by calling this function. */);
2568 Vread_buffer_function = Qnil; 2622 Vread_buffer_function = Qnil;
@@ -2597,7 +2651,8 @@ This variable makes a difference whenever the minibuffer window is active. */);
2597 2651
2598 DEFVAR_LISP ("minibuffer-completion-table", &Vminibuffer_completion_table, 2652 DEFVAR_LISP ("minibuffer-completion-table", &Vminibuffer_completion_table,
2599 doc: /* Alist or obarray used for completion in the minibuffer. 2653 doc: /* Alist or obarray used for completion in the minibuffer.
2600This becomes the ALIST argument to `try-completion' and `all-completion'. 2654This becomes the ALIST argument to `try-completion' and `all-completions'.
2655The value can also be a list of strings or a hash table.
2601 2656
2602The value may alternatively be a function, which is given three arguments: 2657The value may alternatively be a function, which is given three arguments:
2603 STRING, the current buffer contents; 2658 STRING, the current buffer contents;
@@ -2644,7 +2699,12 @@ Some uses of the echo area also raise that frame (since they use it too). */);
2644 minibuffer_auto_raise = 0; 2699 minibuffer_auto_raise = 0;
2645 2700
2646 DEFVAR_LISP ("completion-regexp-list", &Vcompletion_regexp_list, 2701 DEFVAR_LISP ("completion-regexp-list", &Vcompletion_regexp_list,
2647 doc: /* List of regexps that should restrict possible completions. */); 2702 doc: /* List of regexps that should restrict possible completions.
2703The basic completion functions only consider a completion acceptable
2704if it matches all regular expressions in this list, with
2705`case-fold-search' bound to the value of `completion-ignore-case'.
2706See Info node `(elisp)Basic Completion', for a description of these
2707functions. */);
2648 Vcompletion_regexp_list = Qnil; 2708 Vcompletion_regexp_list = Qnil;
2649 2709
2650 DEFVAR_BOOL ("minibuffer-allow-text-properties", 2710 DEFVAR_BOOL ("minibuffer-allow-text-properties",
diff --git a/src/process.c b/src/process.c
index be6094438e9..3e4b5dbc673 100644
--- a/src/process.c
+++ b/src/process.c
@@ -4262,7 +4262,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
4262 else 4262 else
4263 Available = input_wait_mask; 4263 Available = input_wait_mask;
4264 check_connect = (num_pending_connects > 0); 4264 check_connect = (num_pending_connects > 0);
4265 check_delay = process_output_delay_count; 4265 check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
4266 } 4266 }
4267 4267
4268 /* If frame size has changed or the window is newly mapped, 4268 /* If frame size has changed or the window is newly mapped,
diff --git a/src/region-cache.c b/src/region-cache.c
index fc9d3f98de0..251382a5a0e 100644
--- a/src/region-cache.c
+++ b/src/region-cache.c
@@ -21,12 +21,12 @@ Boston, MA 02111-1307, USA. */
21 21
22 22
23#include <config.h> 23#include <config.h>
24#include <stdio.h>
25
24#include "lisp.h" 26#include "lisp.h"
25#include "buffer.h" 27#include "buffer.h"
26#include "region-cache.h" 28#include "region-cache.h"
27 29
28#include <stdio.h>
29
30 30
31/* Data structures. */ 31/* Data structures. */
32 32
diff --git a/src/sysdep.c b/src/sysdep.c
index 73b7fb70a99..febf59253e1 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA. */
24#endif 24#endif
25 25
26#include <signal.h> 26#include <signal.h>
27#include <stdio.h>
27#include <setjmp.h> 28#include <setjmp.h>
28#ifdef HAVE_UNISTD_H 29#ifdef HAVE_UNISTD_H
29#include <unistd.h> 30#include <unistd.h>
@@ -82,7 +83,6 @@ static int delete_exited_processes;
82#undef fwrite 83#undef fwrite
83#endif 84#endif
84 85
85#include <stdio.h>
86#include <sys/types.h> 86#include <sys/types.h>
87#include <sys/stat.h> 87#include <sys/stat.h>
88#include <errno.h> 88#include <errno.h>
diff --git a/src/w32fns.c b/src/w32fns.c
index 1854c3908bd..3b53bade2ad 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -5558,6 +5558,11 @@ x_to_w32_font (lpxstr, lplogfont)
5558 (Fcheck_coding_system (Vlocale_coding_system), &coding); 5558 (Fcheck_coding_system (Vlocale_coding_system), &coding);
5559 coding.src_multibyte = 1; 5559 coding.src_multibyte = 1;
5560 coding.dst_multibyte = 1; 5560 coding.dst_multibyte = 1;
5561 /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
5562 encode_coding_iso2022 trying to dereference a null pointer. */
5563 coding.composing = COMPOSITION_DISABLED;
5564 if (coding.type == coding_type_iso2022)
5565 coding.flags |= CODING_FLAG_ISO_SAFE;
5561 bufsize = encoding_buffer_size (&coding, strlen (name)); 5566 bufsize = encoding_buffer_size (&coding, strlen (name));
5562 buf = (unsigned char *) alloca (bufsize); 5567 buf = (unsigned char *) alloca (bufsize);
5563 coding.mode |= CODING_MODE_LAST_BLOCK; 5568 coding.mode |= CODING_MODE_LAST_BLOCK;
@@ -12400,12 +12405,25 @@ x_kill_gs_process (pixmap, f)
12400 ***********************************************************************/ 12405 ***********************************************************************/
12401 12406
12402DEFUN ("x-change-window-property", Fx_change_window_property, 12407DEFUN ("x-change-window-property", Fx_change_window_property,
12403 Sx_change_window_property, 2, 3, 0, 12408 Sx_change_window_property, 2, 6, 0,
12404 doc: /* Change window property PROP to VALUE on the X window of FRAME. 12409 doc: /* Change window property PROP to VALUE on the X window of FRAME.
12405PROP and VALUE must be strings. FRAME nil or omitted means use the 12410VALUE may be a string or a list of conses, numbers and/or strings.
12406selected frame. Value is VALUE. */) 12411If an element in the list is a string, it is converted to
12407 (prop, value, frame) 12412an Atom and the value of the Atom is used. If an element is a cons,
12408 Lisp_Object frame, prop, value; 12413it is converted to a 32 bit number where the car is the 16 top bits and the
12414cdr is the lower 16 bits.
12415FRAME nil or omitted means use the selected frame.
12416If TYPE is given and non-nil, it is the name of the type of VALUE.
12417If TYPE is not given or nil, the type is STRING.
12418FORMAT gives the size in bits of each element if VALUE is a list.
12419It must be one of 8, 16 or 32.
12420If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
12421If OUTER_P is non-nil, the property is changed for the outer X window of
12422FRAME. Default is to change on the edit X window.
12423
12424Value is VALUE. */)
12425 (prop, value, frame, type, format, outer_p)
12426 Lisp_Object prop, value, frame, type, format, outer_p;
12409{ 12427{
12410#if 0 /* TODO : port window properties to W32 */ 12428#if 0 /* TODO : port window properties to W32 */
12411 struct frame *f = check_x_frame (frame); 12429 struct frame *f = check_x_frame (frame);
diff --git a/src/w32select.c b/src/w32select.c
index 6533f4b660d..940cce35772 100644
--- a/src/w32select.c
+++ b/src/w32select.c
@@ -212,6 +212,11 @@ DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
212 } 212 }
213 coding.src_multibyte = 1; 213 coding.src_multibyte = 1;
214 coding.dst_multibyte = 0; 214 coding.dst_multibyte = 0;
215 /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
216 encode_coding_iso2022 trying to dereference a null pointer. */
217 coding.composing = COMPOSITION_DISABLED;
218 if (coding.type == coding_type_iso2022)
219 coding.flags |= CODING_FLAG_ISO_SAFE;
215 Vnext_selection_coding_system = Qnil; 220 Vnext_selection_coding_system = Qnil;
216 coding.mode |= CODING_MODE_LAST_BLOCK; 221 coding.mode |= CODING_MODE_LAST_BLOCK;
217 bufsize = encoding_buffer_size (&coding, nbytes); 222 bufsize = encoding_buffer_size (&coding, nbytes);
diff --git a/src/w32term.c b/src/w32term.c
index 834df6ef88f..82db82826e8 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -698,28 +698,46 @@ w32_draw_fringe_bitmap (w, row, p)
698 else 698 else
699 w32_clip_to_row (w, row, hdc); 699 w32_clip_to_row (w, row, hdc);
700 700
701 if (p->bx >= 0) 701 if (p->bx >= 0 && !p->overlay_p)
702 { 702 {
703 w32_fill_area (f, hdc, face->background, 703 w32_fill_area (f, hdc, face->background,
704 p->bx, p->by, p->nx, p->ny); 704 p->bx, p->by, p->nx, p->ny);
705 } 705 }
706 706
707 if (p->which != NO_FRINGE_BITMAP) 707 if (p->which)
708 { 708 {
709 HBITMAP pixmap = fringe_bmp[p->which]; 709 HBITMAP pixmap = fringe_bmp[p->which];
710 HDC compat_hdc; 710 HDC compat_hdc;
711 HANDLE horig_obj; 711 HANDLE horig_obj;
712 712
713 compat_hdc = CreateCompatibleDC (hdc); 713 compat_hdc = CreateCompatibleDC (hdc);
714
714 SaveDC (hdc); 715 SaveDC (hdc);
715 716
716 horig_obj = SelectObject (compat_hdc, pixmap); 717 horig_obj = SelectObject (compat_hdc, pixmap);
717 SetTextColor (hdc, face->background); 718 SetTextColor (hdc, face->background);
718 SetBkColor (hdc, face->foreground); 719 SetBkColor (hdc, p->cursor_p
720 ? (p->overlay_p ? face->background
721 : f->output_data.w32->cursor_pixel)
722 : face->foreground);
719 723
720 BitBlt (hdc, p->x, p->y, p->wd, p->h, 724 /* Paint overlays transparently. */
721 compat_hdc, 0, p->dh, 725 if (p->overlay_p)
722 SRCCOPY); 726 {
727 BitBlt (hdc, p->x, p->y, p->wd, p->h,
728 compat_hdc, 0, p->dh,
729 DSTINVERT);
730 BitBlt (hdc, p->x, p->y, p->wd, p->h,
731 compat_hdc, 0, p->dh,
732 MERGEPAINT);
733 BitBlt (hdc, p->x, p->y, p->wd, p->h,
734 compat_hdc, 0, p->dh,
735 DSTINVERT);
736 }
737 else
738 BitBlt (hdc, p->x, p->y, p->wd, p->h,
739 compat_hdc, 0, p->dh,
740 SRCCOPY);
723 741
724 SelectObject (compat_hdc, horig_obj); 742 SelectObject (compat_hdc, horig_obj);
725 DeleteDC (compat_hdc); 743 DeleteDC (compat_hdc);
@@ -731,6 +749,25 @@ w32_draw_fringe_bitmap (w, row, p)
731 release_frame_dc (f, hdc); 749 release_frame_dc (f, hdc);
732} 750}
733 751
752static void
753w32_define_fringe_bitmap (which, bits, h, wd)
754 int which;
755 unsigned short *bits;
756 int h, wd;
757{
758 fringe_bmp[which] = CreateBitmap (wd, h, 1, 1, bits);
759}
760
761static void
762w32_destroy_fringe_bitmap (which)
763 int which;
764{
765 if (fringe_bmp[which])
766 DeleteObject (fringe_bmp[which]);
767 fringe_bmp[which] = 0;
768}
769
770
734 771
735/* This is called when starting Emacs and when restarting after 772/* This is called when starting Emacs and when restarting after
736 suspend. When starting Emacs, no window is mapped. And nothing 773 suspend. When starting Emacs, no window is mapped. And nothing
@@ -6220,32 +6257,7 @@ w32_term_init (display_name, xrm_option, resource_name)
6220 horizontally reflected compared to how they appear on X, so we 6257 horizontally reflected compared to how they appear on X, so we
6221 need to bitswap and convert to unsigned shorts before creating 6258 need to bitswap and convert to unsigned shorts before creating
6222 the bitmaps. */ 6259 the bitmaps. */
6223 { 6260 w32_init_fringe ();
6224 int i, j;
6225
6226 for (i = NO_FRINGE_BITMAP + 1; i < MAX_FRINGE_BITMAPS; i++)
6227 {
6228 int h = fringe_bitmaps[i].height;
6229 int wd = fringe_bitmaps[i].width;
6230 unsigned short *w32bits
6231 = (unsigned short *)alloca (h * sizeof (unsigned short));
6232 unsigned short *wb = w32bits;
6233 unsigned char *bits = fringe_bitmaps[i].bits;
6234 for (j = 0; j < h; j++)
6235 {
6236 static unsigned char swap_nibble[16]
6237 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
6238 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
6239 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
6240 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
6241
6242 unsigned char b = *bits++;
6243 *wb++ = (unsigned short)((swap_nibble[b & 0xf]<<4)
6244 | (swap_nibble[(b>>4) & 0xf]));
6245 }
6246 fringe_bmp[i] = CreateBitmap (wd, h, 1, 1, w32bits);
6247 }
6248 }
6249 6261
6250#ifndef F_SETOWN_BUG 6262#ifndef F_SETOWN_BUG
6251#ifdef F_SETOWN 6263#ifdef F_SETOWN
@@ -6313,13 +6325,7 @@ x_delete_display (dpyinfo)
6313 xfree (dpyinfo->font_table); 6325 xfree (dpyinfo->font_table);
6314 xfree (dpyinfo->w32_id_name); 6326 xfree (dpyinfo->w32_id_name);
6315 6327
6316 /* Destroy row bitmaps. */ 6328 w32_reset_fringes ();
6317 {
6318 int i;
6319
6320 for (i = NO_FRINGE_BITMAP + 1; i < MAX_FRINGE_BITMAPS; i++)
6321 DeleteObject (fringe_bmp[i]);
6322 }
6323} 6329}
6324 6330
6325/* Set up use of W32. */ 6331/* Set up use of W32. */
@@ -6350,6 +6356,8 @@ static struct redisplay_interface w32_redisplay_interface =
6350 w32_get_glyph_overhangs, 6356 w32_get_glyph_overhangs,
6351 x_fix_overlapping_area, 6357 x_fix_overlapping_area,
6352 w32_draw_fringe_bitmap, 6358 w32_draw_fringe_bitmap,
6359 w32_define_fringe_bitmap,
6360 w32_destroy_fringe_bitmap,
6353 w32_per_char_metric, 6361 w32_per_char_metric,
6354 w32_encode_char, 6362 w32_encode_char,
6355 NULL, /* w32_compute_glyph_string_overhangs */ 6363 NULL, /* w32_compute_glyph_string_overhangs */
diff --git a/src/window.c b/src/window.c
index 363c8d0eaff..8f971ab0260 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6018,9 +6018,7 @@ DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
6018 0, 1, 0, 6018 0, 1, 0,
6019 doc: /* Get width of fringes of window WINDOW. 6019 doc: /* Get width of fringes of window WINDOW.
6020If WINDOW is omitted or nil, use the currently selected window. 6020If WINDOW is omitted or nil, use the currently selected window.
6021Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). 6021Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6022If a window specific fringe width is not set, its width will be returned
6023as nil. */)
6024 (window) 6022 (window)
6025 Lisp_Object window; 6023 Lisp_Object window;
6026{ 6024{
diff --git a/src/xdisp.c b/src/xdisp.c
index 0e678b34897..edd7cc62e61 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -311,10 +311,7 @@ extern Lisp_Object Qscroll_bar;
311Lisp_Object Vshow_trailing_whitespace; 311Lisp_Object Vshow_trailing_whitespace;
312 312
313#ifdef HAVE_WINDOW_SYSTEM 313#ifdef HAVE_WINDOW_SYSTEM
314/* Non-nil means that newline may flow into the right fringe. */ 314extern Lisp_Object Voverflow_newline_into_fringe;
315
316Lisp_Object Voverflow_newline_into_fringe;
317#endif /* HAVE_WINDOW_SYSTEM */
318 315
319/* Test if overflow newline into fringe. Called with iterator IT 316/* Test if overflow newline into fringe. Called with iterator IT
320 at or past right window margin, and with IT->current_x set. */ 317 at or past right window margin, and with IT->current_x set. */
@@ -325,6 +322,8 @@ Lisp_Object Voverflow_newline_into_fringe;
325 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \ 322 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
326 && it->current_x == it->last_visible_x) 323 && it->current_x == it->last_visible_x)
327 324
325#endif /* HAVE_WINDOW_SYSTEM */
326
328/* Non-nil means show the text cursor in void text areas 327/* Non-nil means show the text cursor in void text areas
329 i.e. in blank areas after eol and eob. This used to be 328 i.e. in blank areas after eol and eob. This used to be
330 the default in 21.3. */ 329 the default in 21.3. */
@@ -3275,6 +3274,8 @@ handle_display_prop (it)
3275 && !EQ (XCAR (prop), Qraise) 3274 && !EQ (XCAR (prop), Qraise)
3276 /* Marginal area specifications. */ 3275 /* Marginal area specifications. */
3277 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin)) 3276 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3277 && !EQ (XCAR (prop), Qleft_fringe)
3278 && !EQ (XCAR (prop), Qright_fringe)
3278 && !NILP (XCAR (prop))) 3279 && !NILP (XCAR (prop)))
3279 { 3280 {
3280 for (; CONSP (prop); prop = XCDR (prop)) 3281 for (; CONSP (prop); prop = XCDR (prop))
@@ -3481,6 +3482,43 @@ handle_single_display_prop (it, prop, object, position,
3481 } 3482 }
3482#endif /* HAVE_WINDOW_SYSTEM */ 3483#endif /* HAVE_WINDOW_SYSTEM */
3483 } 3484 }
3485 else if (CONSP (prop)
3486 && (EQ (XCAR (prop), Qleft_fringe)
3487 || EQ (XCAR (prop), Qright_fringe))
3488 && CONSP (XCDR (prop)))
3489 {
3490 unsigned face_id = DEFAULT_FACE_ID;
3491
3492 /* `(left-fringe BITMAP FACE)'. */
3493 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3494 return 0;
3495
3496#ifdef HAVE_WINDOW_SYSTEM
3497 value = XCAR (XCDR (prop));
3498 if (!NUMBERP (value)
3499 || !valid_fringe_bitmap_id_p (XINT (value)))
3500 return 0;
3501
3502 if (CONSP (XCDR (XCDR (prop))))
3503 {
3504 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3505 face_id = lookup_named_face (it->f, face_name, 'A');
3506 if (face_id < 0)
3507 return 0;
3508 }
3509
3510 if (EQ (XCAR (prop), Qleft_fringe))
3511 {
3512 it->left_user_fringe_bitmap = XINT (value);
3513 it->left_user_fringe_face_id = face_id;
3514 }
3515 else
3516 {
3517 it->right_user_fringe_bitmap = XINT (value);
3518 it->right_user_fringe_face_id = face_id;
3519 }
3520#endif /* HAVE_WINDOW_SYSTEM */
3521 }
3484 else if (!it->string_from_display_prop_p) 3522 else if (!it->string_from_display_prop_p)
3485 { 3523 {
3486 /* `((margin left-margin) VALUE)' or `((margin right-margin) 3524 /* `((margin left-margin) VALUE)' or `((margin right-margin)
@@ -5610,7 +5648,11 @@ move_it_in_display_line_to (it, to_charpos, to_x, op)
5610#ifdef HAVE_WINDOW_SYSTEM 5648#ifdef HAVE_WINDOW_SYSTEM
5611 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 5649 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5612 { 5650 {
5613 get_next_display_element (it); 5651 if (!get_next_display_element (it))
5652 {
5653 result = MOVE_POS_MATCH_OR_ZV;
5654 break;
5655 }
5614 if (ITERATOR_AT_END_OF_LINE_P (it)) 5656 if (ITERATOR_AT_END_OF_LINE_P (it))
5615 { 5657 {
5616 result = MOVE_NEWLINE_OR_CR; 5658 result = MOVE_NEWLINE_OR_CR;
@@ -5678,7 +5720,11 @@ move_it_in_display_line_to (it, to_charpos, to_x, op)
5678#ifdef HAVE_WINDOW_SYSTEM 5720#ifdef HAVE_WINDOW_SYSTEM
5679 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 5721 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5680 { 5722 {
5681 get_next_display_element (it); 5723 if (!get_next_display_element (it))
5724 {
5725 result = MOVE_POS_MATCH_OR_ZV;
5726 break;
5727 }
5682 if (ITERATOR_AT_END_OF_LINE_P (it)) 5728 if (ITERATOR_AT_END_OF_LINE_P (it))
5683 { 5729 {
5684 result = MOVE_NEWLINE_OR_CR; 5730 result = MOVE_NEWLINE_OR_CR;
@@ -7614,7 +7660,10 @@ clear_garbaged_frames ()
7614 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f)) 7660 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7615 { 7661 {
7616 if (f->resized_p) 7662 if (f->resized_p)
7617 Fredraw_frame (frame); 7663 {
7664 Fredraw_frame (frame);
7665 f->force_flush_display_p = 1;
7666 }
7618 clear_current_matrices (f); 7667 clear_current_matrices (f);
7619 changed_count++; 7668 changed_count++;
7620 f->garbaged = 0; 7669 f->garbaged = 0;
@@ -8928,536 +8977,6 @@ note_tool_bar_highlight (f, x, y)
8928 8977
8929 8978
8930 8979
8931/***********************************************************************
8932 Fringes
8933 ***********************************************************************/
8934
8935#ifdef HAVE_WINDOW_SYSTEM
8936
8937/* Notice that all bitmaps bits are "mirrored". */
8938
8939/* An arrow like this: `<-'. */
8940/*
8941 ...xx...
8942 ....xx..
8943 .....xx.
8944 ..xxxxxx
8945 ..xxxxxx
8946 .....xx.
8947 ....xx..
8948 ...xx...
8949*/
8950static unsigned char left_bits[] = {
8951 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
8952
8953
8954/* Right truncation arrow bitmap `->'. */
8955/*
8956 ...xx...
8957 ..xx....
8958 .xx.....
8959 xxxxxx..
8960 xxxxxx..
8961 .xx.....
8962 ..xx....
8963 ...xx...
8964*/
8965static unsigned char right_bits[] = {
8966 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
8967
8968
8969/* Up arrow bitmap. */
8970/*
8971 ...xx...
8972 ..xxxx..
8973 .xxxxxx.
8974 xxxxxxxx
8975 ...xx...
8976 ...xx...
8977 ...xx...
8978 ...xx...
8979*/
8980static unsigned char up_arrow_bits[] = {
8981 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
8982
8983
8984/* Down arrow bitmap. */
8985/*
8986 ...xx...
8987 ...xx...
8988 ...xx...
8989 ...xx...
8990 xxxxxxxx
8991 .xxxxxx.
8992 ..xxxx..
8993 ...xx...
8994*/
8995static unsigned char down_arrow_bits[] = {
8996 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
8997
8998/* Marker for continued lines. */
8999/*
9000 ..xxxx..
9001 .xxxxx..
9002 xx......
9003 xxx..x..
9004 xxxxxx..
9005 .xxxxx..
9006 ..xxxx..
9007 .xxxxx..
9008*/
9009static unsigned char continued_bits[] = {
9010 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
9011
9012/* Marker for continuation lines. */
9013/*
9014 ..xxxx..
9015 ..xxxxx.
9016 ......xx
9017 ..x..xxx
9018 ..xxxxxx
9019 ..xxxxx.
9020 ..xxxx..
9021 ..xxxxx.
9022*/
9023static unsigned char continuation_bits[] = {
9024 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
9025
9026/* Overlay arrow bitmap. A triangular arrow. */
9027/*
9028 ......xx
9029 ....xxxx
9030 ...xxxxx
9031 ..xxxxxx
9032 ..xxxxxx
9033 ...xxxxx
9034 ....xxxx
9035 ......xx
9036*/
9037static unsigned char ov_bits[] = {
9038 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
9039
9040
9041/* First line bitmap. An left-up angle. */
9042/*
9043 ..xxxxxx
9044 ..xxxxxx
9045 ......xx
9046 ......xx
9047 ......xx
9048 ......xx
9049 ......xx
9050 ........
9051*/
9052static unsigned char first_line_bits[] = {
9053 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
9054
9055
9056/* Last line bitmap. An left-down angle. */
9057/*
9058 ........
9059 xx......
9060 xx......
9061 xx......
9062 xx......
9063 xx......
9064 xxxxxx..
9065 xxxxxx..
9066*/
9067static unsigned char last_line_bits[] = {
9068 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
9069
9070/* Filled box cursor bitmap. A filled box; max 13 pixels high. */
9071/*
9072 .xxxxxxx
9073 .xxxxxxx
9074 .xxxxxxx
9075 .xxxxxxx
9076 .xxxxxxx
9077 .xxxxxxx
9078 .xxxxxxx
9079 .xxxxxxx
9080 .xxxxxxx
9081 .xxxxxxx
9082 .xxxxxxx
9083 .xxxxxxx
9084 .xxxxxxx
9085*/
9086static unsigned char filled_box_cursor_bits[] = {
9087 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f};
9088
9089/* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
9090/*
9091 .xxxxxxx
9092 .x.....x
9093 .x.....x
9094 .x.....x
9095 .x.....x
9096 .x.....x
9097 .x.....x
9098 .x.....x
9099 .x.....x
9100 .x.....x
9101 .x.....x
9102 .x.....x
9103 .xxxxxxx
9104*/
9105static unsigned char hollow_box_cursor_bits[] = {
9106 0x7f, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7f};
9107
9108/* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
9109/*
9110 ......xx
9111 ......xx
9112 ......xx
9113 ......xx
9114 ......xx
9115 ......xx
9116 ......xx
9117 ......xx
9118 ......xx
9119 ......xx
9120 ......xx
9121 ......xx
9122 ......xx
9123*/
9124static unsigned char bar_cursor_bits[] = {
9125 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
9126
9127/* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
9128/*
9129 .xxxxxxx
9130 .xxxxxxx
9131*/
9132static unsigned char hbar_cursor_bits[] = {
9133 0x7f, 0x7f};
9134
9135
9136/* Bitmap drawn to indicate lines not displaying text if
9137 `indicate-empty-lines' is non-nil. */
9138static unsigned char zv_bits[] = {
9139 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9140 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9141 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9142 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9143 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9144 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9145 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9146 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
9147
9148/* Hollow square bitmap. */
9149/*
9150 .xxxxxx.
9151 .x....x.
9152 .x....x.
9153 .x....x.
9154 .x....x.
9155 .xxxxxx.
9156*/
9157static unsigned char hollow_square_bits[] = {
9158 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
9159
9160
9161struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS] =
9162{
9163 { 0, 0, 0, NULL /* NO_FRINGE_BITMAP */ },
9164 { 8, sizeof (left_bits), 0, left_bits },
9165 { 8, sizeof (right_bits), 0, right_bits },
9166 { 8, sizeof (up_arrow_bits), -1, up_arrow_bits },
9167 { 8, sizeof (down_arrow_bits), -2, down_arrow_bits },
9168 { 8, sizeof (continued_bits), 0, continued_bits },
9169 { 8, sizeof (continuation_bits), 0, continuation_bits },
9170 { 8, sizeof (ov_bits), 0, ov_bits },
9171 { 8, sizeof (first_line_bits), -1, first_line_bits },
9172 { 8, sizeof (last_line_bits), -2, last_line_bits },
9173 { 8, sizeof (filled_box_cursor_bits), 0, filled_box_cursor_bits },
9174 { 8, sizeof (hollow_box_cursor_bits), 0, hollow_box_cursor_bits },
9175 { 8, sizeof (bar_cursor_bits), 0, bar_cursor_bits },
9176 { 8, sizeof (hbar_cursor_bits), -2, hbar_cursor_bits },
9177 { 8, sizeof (zv_bits), 3, zv_bits },
9178 { 8, sizeof (hollow_square_bits), 0, hollow_square_bits },
9179};
9180
9181
9182/* Draw the bitmap WHICH in one of the left or right fringes of
9183 window W. ROW is the glyph row for which to display the bitmap; it
9184 determines the vertical position at which the bitmap has to be
9185 drawn.
9186 LEFT_P is 1 for left fringe, 0 for right fringe.
9187*/
9188
9189void
9190draw_fringe_bitmap (w, row, left_p)
9191 struct window *w;
9192 struct glyph_row *row;
9193 int left_p;
9194{
9195 struct frame *f = XFRAME (WINDOW_FRAME (w));
9196 struct draw_fringe_bitmap_params p;
9197 enum fringe_bitmap_type which;
9198 int period;
9199
9200 if (left_p)
9201 which = row->left_fringe_bitmap;
9202 else if (!row->cursor_in_fringe_p)
9203 which = row->right_fringe_bitmap;
9204 else
9205 switch (w->phys_cursor_type)
9206 {
9207 case HOLLOW_BOX_CURSOR:
9208 if (row->visible_height >= sizeof(hollow_box_cursor_bits))
9209 which = HOLLOW_BOX_CURSOR_BITMAP;
9210 else
9211 which = HOLLOW_SQUARE_BITMAP;
9212 break;
9213 case FILLED_BOX_CURSOR:
9214 which = FILLED_BOX_CURSOR_BITMAP;
9215 break;
9216 case BAR_CURSOR:
9217 which = BAR_CURSOR_BITMAP;
9218 break;
9219 case HBAR_CURSOR:
9220 which = HBAR_CURSOR_BITMAP;
9221 break;
9222 case NO_CURSOR:
9223 default:
9224 w->phys_cursor_on_p = 0;
9225 row->cursor_in_fringe_p = 0;
9226 which = row->right_fringe_bitmap;
9227 break;
9228 }
9229
9230 period = fringe_bitmaps[which].period;
9231
9232 /* Convert row to frame coordinates. */
9233 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
9234
9235 p.which = which;
9236 p.wd = fringe_bitmaps[which].width;
9237
9238 p.h = fringe_bitmaps[which].height;
9239 p.dh = (period > 0 ? (p.y % period) : 0);
9240 p.h -= p.dh;
9241 /* Clip bitmap if too high. */
9242 if (p.h > row->height)
9243 p.h = row->height;
9244
9245 p.face = FACE_FROM_ID (f, FRINGE_FACE_ID);
9246 PREPARE_FACE_FOR_DISPLAY (f, p.face);
9247
9248 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
9249 the fringe. */
9250 p.bx = -1;
9251 if (left_p)
9252 {
9253 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
9254 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
9255 ? LEFT_MARGIN_AREA
9256 : TEXT_AREA));
9257 if (p.wd > wd)
9258 p.wd = wd;
9259 p.x = x - p.wd - (wd - p.wd) / 2;
9260
9261 if (p.wd < wd || row->height > p.h)
9262 {
9263 /* If W has a vertical border to its left, don't draw over it. */
9264 wd -= ((!WINDOW_LEFTMOST_P (w)
9265 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
9266 ? 1 : 0);
9267 p.bx = x - wd;
9268 p.nx = wd;
9269 }
9270 }
9271 else
9272 {
9273 int x = window_box_right (w,
9274 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
9275 ? RIGHT_MARGIN_AREA
9276 : TEXT_AREA));
9277 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
9278 if (p.wd > wd)
9279 p.wd = wd;
9280 p.x = x + (wd - p.wd) / 2;
9281 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
9282 the fringe. */
9283 if (p.wd < wd || row->height > p.h)
9284 {
9285 p.bx = x;
9286 p.nx = wd;
9287 }
9288 }
9289
9290 if (p.bx >= 0)
9291 {
9292 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
9293
9294 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
9295 p.ny = row->visible_height;
9296 }
9297
9298 /* Adjust y to the offset in the row to start drawing the bitmap. */
9299 if (period == 0)
9300 p.y += (row->height - p.h) / 2;
9301 else if (period == -2)
9302 {
9303 p.h = fringe_bitmaps[which].height;
9304 p.y += (row->visible_height - p.h);
9305 }
9306
9307 FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
9308}
9309
9310/* Draw fringe bitmaps for glyph row ROW on window W. Call this
9311 function with input blocked. */
9312
9313void
9314draw_row_fringe_bitmaps (w, row)
9315 struct window *w;
9316 struct glyph_row *row;
9317{
9318 xassert (interrupt_input_blocked);
9319
9320 /* If row is completely invisible, because of vscrolling, we
9321 don't have to draw anything. */
9322 if (row->visible_height <= 0)
9323 return;
9324
9325 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
9326 draw_fringe_bitmap (w, row, 1);
9327
9328 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
9329 draw_fringe_bitmap (w, row, 0);
9330}
9331
9332/* Draw the fringes of window W. Only fringes for rows marked for
9333 update in redraw_fringe_bitmaps_p are drawn. */
9334
9335void
9336draw_window_fringes (w)
9337 struct window *w;
9338{
9339 struct glyph_row *row;
9340 int yb = window_text_bottom_y (w);
9341 int nrows = w->current_matrix->nrows;
9342 int y = 0, rn;
9343
9344 if (w->pseudo_window_p)
9345 return;
9346
9347 for (y = 0, rn = 0, row = w->current_matrix->rows;
9348 y < yb && rn < nrows;
9349 y += row->height, ++row, ++rn)
9350 {
9351 if (!row->redraw_fringe_bitmaps_p)
9352 continue;
9353 draw_row_fringe_bitmaps (w, row);
9354 row->redraw_fringe_bitmaps_p = 0;
9355 }
9356}
9357
9358
9359/* Compute actual fringe widths for frame F.
9360
9361 If REDRAW is 1, redraw F if the fringe settings was actually
9362 modified and F is visible.
9363
9364 Since the combined left and right fringe must occupy an integral
9365 number of columns, we may need to add some pixels to each fringe.
9366 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
9367 but a negative width value is taken literally (after negating it).
9368
9369 We never make the fringes narrower than specified. It is planned
9370 to make fringe bitmaps customizable and expandable, and at that
9371 time, the user will typically specify the minimum number of pixels
9372 needed for his bitmaps, so we shouldn't select anything less than
9373 what is specified.
9374*/
9375
9376void
9377compute_fringe_widths (f, redraw)
9378 struct frame *f;
9379 int redraw;
9380{
9381 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
9382 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
9383 int o_cols = FRAME_FRINGE_COLS (f);
9384
9385 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
9386 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
9387 int left_fringe_width, right_fringe_width;
9388
9389 if (!NILP (left_fringe))
9390 left_fringe = Fcdr (left_fringe);
9391 if (!NILP (right_fringe))
9392 right_fringe = Fcdr (right_fringe);
9393
9394 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
9395 XINT (left_fringe));
9396 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
9397 XINT (right_fringe));
9398
9399 if (left_fringe_width || right_fringe_width)
9400 {
9401 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
9402 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
9403 int conf_wid = left_wid + right_wid;
9404 int font_wid = FRAME_COLUMN_WIDTH (f);
9405 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
9406 int real_wid = cols * font_wid;
9407 if (left_wid && right_wid)
9408 {
9409 if (left_fringe_width < 0)
9410 {
9411 /* Left fringe width is fixed, adjust right fringe if necessary */
9412 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
9413 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
9414 }
9415 else if (right_fringe_width < 0)
9416 {
9417 /* Right fringe width is fixed, adjust left fringe if necessary */
9418 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
9419 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
9420 }
9421 else
9422 {
9423 /* Adjust both fringes with an equal amount.
9424 Note that we are doing integer arithmetic here, so don't
9425 lose a pixel if the total width is an odd number. */
9426 int fill = real_wid - conf_wid;
9427 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
9428 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
9429 }
9430 }
9431 else if (left_fringe_width)
9432 {
9433 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
9434 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9435 }
9436 else
9437 {
9438 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9439 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
9440 }
9441 FRAME_FRINGE_COLS (f) = cols;
9442 }
9443 else
9444 {
9445 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9446 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9447 FRAME_FRINGE_COLS (f) = 0;
9448 }
9449
9450 if (redraw && FRAME_VISIBLE_P (f))
9451 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
9452 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
9453 o_cols != FRAME_FRINGE_COLS (f))
9454 redraw_frame (f);
9455}
9456
9457#endif /* HAVE_WINDOW_SYSTEM */
9458
9459
9460
9461/************************************************************************ 8980/************************************************************************
9462 Horizontal scrolling 8981 Horizontal scrolling
9463 ************************************************************************/ 8982 ************************************************************************/
@@ -9558,7 +9077,10 @@ hscroll_window_tree (window)
9558 9077
9559 /* Position cursor in window. */ 9078 /* Position cursor in window. */
9560 if (!hscroll_relative_p && hscroll_step_abs == 0) 9079 if (!hscroll_relative_p && hscroll_step_abs == 0)
9561 hscroll = max (0, it.current_x - text_area_width / 2) 9080 hscroll = max (0, (it.current_x
9081 - (ITERATOR_AT_END_OF_LINE_P (&it)
9082 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9083 : (text_area_width / 2))))
9562 / FRAME_COLUMN_WIDTH (it.f); 9084 / FRAME_COLUMN_WIDTH (it.f);
9563 else if (w->cursor.x >= text_area_width - h_margin) 9085 else if (w->cursor.x >= text_area_width - h_margin)
9564 { 9086 {
@@ -11674,136 +11196,6 @@ set_vertical_scroll_bar (w)
11674 (w, end - start, whole, start); 11196 (w, end - start, whole, start);
11675} 11197}
11676 11198
11677#ifdef HAVE_WINDOW_SYSTEM
11678
11679/* Recalculate the bitmaps to show in the fringes of window W.
11680 If FORCE_P is 0, only mark rows with modified bitmaps for update in
11681 redraw_fringe_bitmaps_p; else mark all rows for update. */
11682
11683int
11684update_window_fringes (w, force_p)
11685 struct window *w;
11686 int force_p;
11687{
11688 struct glyph_row *row, *cur = 0;
11689 int yb = window_text_bottom_y (w);
11690 int rn, nrows = w->current_matrix->nrows;
11691 int y;
11692 int redraw_p = 0;
11693 Lisp_Object ind;
11694
11695 if (w->pseudo_window_p)
11696 return 0;
11697
11698 if (!MINI_WINDOW_P (w)
11699 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
11700 {
11701 int do_eob = 1, do_bob = 1;
11702
11703 for (y = 0, rn = 0;
11704 y < yb && rn < nrows;
11705 y += row->height, ++rn)
11706 {
11707 unsigned indicate_bob_p, indicate_top_line_p;
11708 unsigned indicate_eob_p, indicate_bottom_line_p;
11709
11710 row = w->desired_matrix->rows + rn;
11711 if (!row->enabled_p)
11712 row = w->current_matrix->rows + rn;
11713
11714 indicate_bob_p = row->indicate_bob_p;
11715 indicate_top_line_p = row->indicate_top_line_p;
11716 indicate_eob_p = row->indicate_eob_p;
11717 indicate_bottom_line_p = row->indicate_bottom_line_p;
11718
11719 row->indicate_bob_p = row->indicate_top_line_p = 0;
11720 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
11721
11722 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)))
11723 row->indicate_bob_p = do_bob, do_bob = 0;
11724 else if (EQ (ind, Qt)
11725 && (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) == rn)
11726 row->indicate_top_line_p = 1;
11727
11728 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)))
11729 row->indicate_eob_p = do_eob, do_eob = 0;
11730 else if (EQ (ind, Qt)
11731 && y + row->height >= yb)
11732 row->indicate_bottom_line_p = 1;
11733
11734 if (indicate_bob_p != row->indicate_bob_p
11735 || indicate_top_line_p != row->indicate_top_line_p
11736 || indicate_eob_p != row->indicate_eob_p
11737 || indicate_bottom_line_p != row->indicate_bottom_line_p)
11738 row->redraw_fringe_bitmaps_p = 1;
11739 }
11740 }
11741
11742 for (y = 0, rn = 0;
11743 y < yb && rn < nrows;
11744 y += row->height, rn++)
11745 {
11746 enum fringe_bitmap_type left, right;
11747
11748 row = w->desired_matrix->rows + rn;
11749 cur = w->current_matrix->rows + rn;
11750 if (!row->enabled_p)
11751 row = cur;
11752
11753 /* Decide which bitmap to draw in the left fringe. */
11754 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
11755 left = NO_FRINGE_BITMAP;
11756 else if (row->overlay_arrow_p)
11757 left = OVERLAY_ARROW_BITMAP;
11758 else if (row->truncated_on_left_p)
11759 left = LEFT_TRUNCATION_BITMAP;
11760 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
11761 left = CONTINUATION_LINE_BITMAP;
11762 else if (row->indicate_empty_line_p)
11763 left = ZV_LINE_BITMAP;
11764 else if (row->indicate_bob_p)
11765 left = FIRST_LINE_BITMAP;
11766 else
11767 left = NO_FRINGE_BITMAP;
11768
11769 /* Decide which bitmap to draw in the right fringe. */
11770 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
11771 right = NO_FRINGE_BITMAP;
11772 else if (row->truncated_on_right_p)
11773 right = RIGHT_TRUNCATION_BITMAP;
11774 else if (row->continued_p)
11775 right = CONTINUED_LINE_BITMAP;
11776 else if (row->indicate_eob_p)
11777 right = LAST_LINE_BITMAP;
11778 else if (row->indicate_top_line_p)
11779 right = UP_ARROW_BITMAP;
11780 else if (row->indicate_bottom_line_p)
11781 right = DOWN_ARROW_BITMAP;
11782 else if (row->indicate_empty_line_p && WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
11783 right = ZV_LINE_BITMAP;
11784 else
11785 right = NO_FRINGE_BITMAP;
11786
11787 if (force_p
11788 || row->y != cur->y
11789 || row->visible_height != cur->visible_height
11790 || left != cur->left_fringe_bitmap
11791 || right != cur->right_fringe_bitmap
11792 || cur->redraw_fringe_bitmaps_p)
11793 {
11794 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
11795 cur->left_fringe_bitmap = left;
11796 cur->right_fringe_bitmap = right;
11797 }
11798
11799 row->left_fringe_bitmap = left;
11800 row->right_fringe_bitmap = right;
11801 }
11802
11803 return redraw_p;
11804}
11805
11806#endif /* HAVE_WINDOW_SYSTEM */
11807 11199
11808/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only 11200/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11809 selected_window is redisplayed. 11201 selected_window is redisplayed.
@@ -12494,6 +11886,7 @@ redisplay_window (window, just_this_one_p)
12494 11886
12495#ifdef HAVE_WINDOW_SYSTEM 11887#ifdef HAVE_WINDOW_SYSTEM
12496 if (update_window_fringes (w, 0) 11888 if (update_window_fringes (w, 0)
11889 && !just_this_one_p
12497 && (used_current_matrix_p || overlay_arrow_seen) 11890 && (used_current_matrix_p || overlay_arrow_seen)
12498 && !w->pseudo_window_p) 11891 && !w->pseudo_window_p)
12499 { 11892 {
@@ -14835,6 +14228,11 @@ display_line (it)
14835 display the cursor there under X. Set the charpos of the 14228 display the cursor there under X. Set the charpos of the
14836 first glyph of blank lines not corresponding to any text 14229 first glyph of blank lines not corresponding to any text
14837 to -1. */ 14230 to -1. */
14231#ifdef HAVE_WINDOW_SYSTEM
14232 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14233 row->exact_window_width_line_p = 1;
14234 else
14235#endif /* HAVE_WINDOW_SYSTEM */
14838 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1) 14236 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14839 || row->used[TEXT_AREA] == 0) 14237 || row->used[TEXT_AREA] == 0)
14840 { 14238 {
@@ -14947,8 +14345,14 @@ display_line (it)
14947#ifdef HAVE_WINDOW_SYSTEM 14345#ifdef HAVE_WINDOW_SYSTEM
14948 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 14346 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14949 { 14347 {
14950 get_next_display_element (it); 14348 if (!get_next_display_element (it))
14951 if (ITERATOR_AT_END_OF_LINE_P (it)) 14349 {
14350 row->exact_window_width_line_p = 1;
14351 it->continuation_lines_width = 0;
14352 row->continued_p = 0;
14353 row->ends_at_zv_p = 1;
14354 }
14355 else if (ITERATOR_AT_END_OF_LINE_P (it))
14952 { 14356 {
14953 row->continued_p = 0; 14357 row->continued_p = 0;
14954 row->exact_window_width_line_p = 1; 14358 row->exact_window_width_line_p = 1;
@@ -15053,7 +14457,7 @@ display_line (it)
15053 it->max_phys_ascent + it->max_phys_descent); 14457 it->max_phys_ascent + it->max_phys_descent);
15054 14458
15055 /* End of this display line if row is continued. */ 14459 /* End of this display line if row is continued. */
15056 if (row->continued_p) 14460 if (row->continued_p || row->ends_at_zv_p)
15057 break; 14461 break;
15058 } 14462 }
15059 14463
@@ -15119,7 +14523,15 @@ display_line (it)
15119 /* Don't truncate if we can overflow newline into fringe. */ 14523 /* Don't truncate if we can overflow newline into fringe. */
15120 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 14524 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15121 { 14525 {
15122 get_next_display_element (it); 14526 if (!get_next_display_element (it))
14527 {
14528#ifdef HAVE_WINDOW_SYSTEM
14529 it->continuation_lines_width = 0;
14530 row->ends_at_zv_p = 1;
14531 row->exact_window_width_line_p = 1;
14532 break;
14533#endif /* HAVE_WINDOW_SYSTEM */
14534 }
15123 if (ITERATOR_AT_END_OF_LINE_P (it)) 14535 if (ITERATOR_AT_END_OF_LINE_P (it))
15124 { 14536 {
15125 row->exact_window_width_line_p = 1; 14537 row->exact_window_width_line_p = 1;
@@ -15196,6 +14608,17 @@ display_line (it)
15196 /* Remember the position at which this line ends. */ 14608 /* Remember the position at which this line ends. */
15197 row->end = it->current; 14609 row->end = it->current;
15198 14610
14611 /* Save fringe bitmaps in this row. */
14612 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14613 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14614 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14615 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14616
14617 it->left_user_fringe_bitmap = 0;
14618 it->left_user_fringe_face_id = 0;
14619 it->right_user_fringe_bitmap = 0;
14620 it->right_user_fringe_face_id = 0;
14621
15199 /* Maybe set the cursor. */ 14622 /* Maybe set the cursor. */
15200 if (it->w->cursor.vpos < 0 14623 if (it->w->cursor.vpos < 0
15201 && PT >= MATRIX_ROW_START_CHARPOS (row) 14624 && PT >= MATRIX_ROW_START_CHARPOS (row)
@@ -20555,8 +19978,7 @@ on_hot_spot_p (hot_spot, x, y)
20555 return inside; 19978 return inside;
20556 } 19979 }
20557 } 19980 }
20558 else 19981 return 0;
20559 return 0;
20560} 19982}
20561 19983
20562Lisp_Object 19984Lisp_Object
@@ -20595,10 +20017,8 @@ Returns the alist element for the first matching AREA in MAP. */)
20595 if (NILP (map)) 20017 if (NILP (map))
20596 return Qnil; 20018 return Qnil;
20597 20019
20598 if (!INTEGERP (x)) 20020 CHECK_NUMBER (x);
20599 wrong_type_argument (Qintegerp, x); 20021 CHECK_NUMBER (y);
20600 if (!INTEGERP (y))
20601 wrong_type_argument (Qintegerp, y);
20602 20022
20603 return find_hot_spot (map, XINT (x), XINT (y)); 20023 return find_hot_spot (map, XINT (x), XINT (y));
20604} 20024}
@@ -22016,17 +21436,6 @@ wide as that tab on the display. */);
22016The face used for trailing whitespace is `trailing-whitespace'. */); 21436The face used for trailing whitespace is `trailing-whitespace'. */);
22017 Vshow_trailing_whitespace = Qnil; 21437 Vshow_trailing_whitespace = Qnil;
22018 21438
22019#ifdef HAVE_WINDOW_SYSTEM
22020 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
22021 doc: /* *Non-nil means that newline may flow into the right fringe.
22022This means that display lines which are exactly as wide as the window
22023(not counting the final newline) will only occupy one screen line, by
22024showing (or hiding) the final newline in the right fringe; when point
22025is at the final newline, the cursor is shown in the right fringe.
22026If nil, also continue lines which are exactly as wide as the window. */);
22027 Voverflow_newline_into_fringe = Qt;
22028#endif
22029
22030 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer, 21439 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22031 doc: /* *The pointer shape to show in void text areas. 21440 doc: /* *The pointer shape to show in void text areas.
22032Nil means to show the text pointer. Other options are `arrow', `text', 21441Nil means to show the text pointer. Other options are `arrow', `text',
diff --git a/src/xfaces.c b/src/xfaces.c
index fc23b3e2b24..7761282f9eb 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -192,6 +192,7 @@ Boston, MA 02111-1307, USA. */
192 used to fill in unspecified attributes of the default face. */ 192 used to fill in unspecified attributes of the default face. */
193 193
194#include <config.h> 194#include <config.h>
195#include <stdio.h>
195#include <sys/types.h> 196#include <sys/types.h>
196#include <sys/stat.h> 197#include <sys/stat.h>
197#include <stdio.h> /* This needs to be before termchar.h */ 198#include <stdio.h> /* This needs to be before termchar.h */
diff --git a/src/xfns.c b/src/xfns.c
index 6e51965c248..a649ddd1068 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -775,7 +775,6 @@ x_create_bitmap_mask (f, id)
775 unsigned long x, y, xp, xm, yp, ym; 775 unsigned long x, y, xp, xm, yp, ym;
776 GC gc; 776 GC gc;
777 777
778 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
779 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 778 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
780 779
781 if (!(id > 0)) 780 if (!(id > 0))
@@ -1597,7 +1596,7 @@ x_set_menu_bar_lines (f, value, oldval)
1597 Lisp_Object value, oldval; 1596 Lisp_Object value, oldval;
1598{ 1597{
1599 int nlines; 1598 int nlines;
1600#ifndef USE_X_TOOLKIT 1599#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
1601 int olines = FRAME_MENU_BAR_LINES (f); 1600 int olines = FRAME_MENU_BAR_LINES (f);
1602#endif 1601#endif
1603 1602
@@ -4292,125 +4291,6 @@ x_sync (f)
4292 4291
4293 4292
4294/*********************************************************************** 4293/***********************************************************************
4295 General X functions exposed to Elisp.
4296 ***********************************************************************/
4297
4298DEFUN ("x-send-client-message", Fx_send_client_event,
4299 Sx_send_client_message, 6, 6, 0,
4300 doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
4301
4302For DISPLAY, specify either a frame or a display name (a string).
4303If DISPLAY is nil, that stands for the selected frame's display.
4304DEST may be an integer, in which case it is a Window id. The value 0 may
4305be used to send to the root window of the DISPLAY.
4306If DEST is a frame the event is sent to the outer window of that frame.
4307Nil means the currently selected frame.
4308If DEST is the string "PointerWindow" the event is sent to the window that
4309contains the pointer. If DEST is the string "InputFocus" the event is
4310sent to the window that has the input focus.
4311FROM is the frame sending the event. Use nil for currently selected frame.
4312MESSAGE-TYPE is the name of an Atom as a string.
4313FORMAT must be one of 8, 16 or 32 and determines the size of the values in
4314bits. VALUES is a list of integer and/or strings containing the values to
4315send. If a value is a string, it is converted to an Atom and the value of
4316the Atom is sent. If more values than fits into the event is given,
4317the excessive values are ignored. */)
4318 (display, dest, from, message_type, format, values)
4319 Lisp_Object display, dest, from, message_type, format, values;
4320{
4321 struct x_display_info *dpyinfo = check_x_display_info (display);
4322 Window wdest;
4323 XEvent event;
4324 Lisp_Object cons;
4325 int i;
4326 int max_nr_values = (int) sizeof (event.xclient.data.b);
4327 struct frame *f = check_x_frame (from);
4328
4329 CHECK_STRING (message_type);
4330 CHECK_NUMBER (format);
4331 CHECK_CONS (values);
4332
4333 for (cons = values; CONSP (cons); cons = XCDR (cons))
4334 {
4335 Lisp_Object o = XCAR (cons);
4336
4337 if (! INTEGERP (o) && ! STRINGP (o))
4338 error ("Bad data in VALUES, must be integer or string");
4339 }
4340
4341 event.xclient.type = ClientMessage;
4342 event.xclient.format = XFASTINT (format);
4343
4344 if (event.xclient.format != 8 && event.xclient.format != 16
4345 && event.xclient.format != 32)
4346 error ("FORMAT must be one of 8, 16 or 32");
4347 if (event.xclient.format == 16) max_nr_values /= 2;
4348 if (event.xclient.format == 32) max_nr_values /= 4;
4349
4350 if (FRAMEP (dest) || NILP (dest))
4351 {
4352 struct frame *fdest = check_x_frame (dest);
4353 wdest = FRAME_OUTER_WINDOW (fdest);
4354 }
4355 else if (STRINGP (dest))
4356 {
4357 if (strcmp (SDATA (dest), "PointerWindow") == 0)
4358 wdest = PointerWindow;
4359 else if (strcmp (SDATA (dest), "InputFocus") == 0)
4360 wdest = InputFocus;
4361 else
4362 error ("DEST as a string must be one of PointerWindow or InputFocus");
4363 }
4364 else
4365 {
4366 CHECK_NUMBER (dest);
4367 wdest = (Window) XFASTINT (dest);
4368 if (wdest == 0) wdest = dpyinfo->root_window;
4369 }
4370
4371 BLOCK_INPUT;
4372 for (cons = values, i = 0;
4373 CONSP (cons) && i < max_nr_values;
4374 cons = XCDR (cons), ++i)
4375 {
4376 Lisp_Object o = XCAR (cons);
4377 long val;
4378
4379 if (INTEGERP (o))
4380 val = XINT (o);
4381 else if (STRINGP (o))
4382 val = XInternAtom (dpyinfo->display, SDATA (o), False);
4383
4384 if (event.xclient.format == 8)
4385 event.xclient.data.b[i] = (char) val;
4386 else if (event.xclient.format == 16)
4387 event.xclient.data.s[i] = (short) val;
4388 else
4389 event.xclient.data.l[i] = val;
4390 }
4391
4392 for ( ; i < max_nr_values; ++i)
4393 if (event.xclient.format == 8)
4394 event.xclient.data.b[i] = 0;
4395 else if (event.xclient.format == 16)
4396 event.xclient.data.s[i] = 0;
4397 else
4398 event.xclient.data.l[i] = 0;
4399
4400 event.xclient.message_type
4401 = XInternAtom (dpyinfo->display, SDATA (message_type), False);
4402 event.xclient.display = dpyinfo->display;
4403 event.xclient.window = FRAME_OUTER_WINDOW (f);
4404
4405 XSendEvent (dpyinfo->display, wdest, False, 0xffff, &event);
4406
4407 XFlush (dpyinfo->display);
4408 UNBLOCK_INPUT;
4409
4410 return Qnil;
4411}
4412
4413/***********************************************************************
4414 Image types 4294 Image types
4415 ***********************************************************************/ 4295 ***********************************************************************/
4416 4296
@@ -9601,24 +9481,85 @@ x_kill_gs_process (pixmap, f)
9601 ***********************************************************************/ 9481 ***********************************************************************/
9602 9482
9603DEFUN ("x-change-window-property", Fx_change_window_property, 9483DEFUN ("x-change-window-property", Fx_change_window_property,
9604 Sx_change_window_property, 2, 3, 0, 9484 Sx_change_window_property, 2, 6, 0,
9605 doc: /* Change window property PROP to VALUE on the X window of FRAME. 9485 doc: /* Change window property PROP to VALUE on the X window of FRAME.
9606PROP and VALUE must be strings. FRAME nil or omitted means use the 9486PROP must be a string.
9607selected frame. Value is VALUE. */) 9487VALUE may be a string or a list of conses, numbers and/or strings.
9608 (prop, value, frame) 9488If an element in the list is a string, it is converted to
9609 Lisp_Object frame, prop, value; 9489an Atom and the value of the Atom is used. If an element is a cons,
9490it is converted to a 32 bit number where the car is the 16 top bits and the
9491cdr is the lower 16 bits.
9492FRAME nil or omitted means use the selected frame.
9493If TYPE is given and non-nil, it is the name of the type of VALUE.
9494If TYPE is not given or nil, the type is STRING.
9495FORMAT gives the size in bits of each element if VALUE is a list.
9496It must be one of 8, 16 or 32.
9497If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
9498If OUTER_P is non-nil, the property is changed for the outer X window of
9499FRAME. Default is to change on the edit X window.
9500
9501Value is VALUE. */)
9502 (prop, value, frame, type, format, outer_p)
9503 Lisp_Object prop, value, frame, type, format, outer_p;
9610{ 9504{
9611 struct frame *f = check_x_frame (frame); 9505 struct frame *f = check_x_frame (frame);
9612 Atom prop_atom; 9506 Atom prop_atom;
9507 Atom target_type = XA_STRING;
9508 int element_format = 8;
9509 unsigned char *data;
9510 int nelements;
9511 Window w;
9613 9512
9614 CHECK_STRING (prop); 9513 CHECK_STRING (prop);
9615 CHECK_STRING (value); 9514
9515 if (! NILP (format))
9516 {
9517 CHECK_NUMBER (format);
9518 element_format = XFASTINT (format);
9519
9520 if (element_format != 8 && element_format != 16
9521 && element_format != 32)
9522 error ("FORMAT must be one of 8, 16 or 32");
9523 }
9524
9525 if (CONSP (value))
9526 {
9527 nelements = x_check_property_data (value);
9528 if (nelements == -1)
9529 error ("Bad data in VALUE, must be number, string or cons");
9530
9531 if (element_format == 8)
9532 data = (unsigned char *) xmalloc (nelements);
9533 else if (element_format == 16)
9534 data = (unsigned char *) xmalloc (nelements*2);
9535 else
9536 data = (unsigned char *) xmalloc (nelements*4);
9537
9538 x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
9539 }
9540 else
9541 {
9542 CHECK_STRING (value);
9543 data = SDATA (value);
9544 nelements = SCHARS (value);
9545 }
9616 9546
9617 BLOCK_INPUT; 9547 BLOCK_INPUT;
9618 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False); 9548 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
9619 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 9549 if (! NILP (type))
9620 prop_atom, XA_STRING, 8, PropModeReplace, 9550 {
9621 SDATA (value), SCHARS (value)); 9551 CHECK_STRING (type);
9552 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
9553 }
9554
9555 if (! NILP (outer_p)) w = FRAME_OUTER_WINDOW (f);
9556 else w = FRAME_X_WINDOW (f);
9557
9558 XChangeProperty (FRAME_X_DISPLAY (f), w,
9559 prop_atom, target_type, element_format, PropModeReplace,
9560 data, nelements);
9561
9562 if (CONSP (value)) xfree (data);
9622 9563
9623 /* Make sure the property is set when we return. */ 9564 /* Make sure the property is set when we return. */
9624 XFlush (FRAME_X_DISPLAY (f)); 9565 XFlush (FRAME_X_DISPLAY (f));
@@ -9652,13 +9593,20 @@ FRAME nil or omitted means use the selected frame. Value is PROP. */)
9652 9593
9653 9594
9654DEFUN ("x-window-property", Fx_window_property, Sx_window_property, 9595DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
9655 1, 2, 0, 9596 1, 6, 0,
9656 doc: /* Value is the value of window property PROP on FRAME. 9597 doc: /* Value is the value of window property PROP on FRAME.
9657If FRAME is nil or omitted, use the selected frame. Value is nil 9598If FRAME is nil or omitted, use the selected frame.
9658if FRAME hasn't a property with name PROP or if PROP has no string 9599If TYPE is nil or omitted, get the property as a string. Otherwise TYPE
9659value. */) 9600is the name of the Atom that denotes the type expected.
9660 (prop, frame) 9601If SOURCE is non-nil, get the property on that window instead of from
9661 Lisp_Object prop, frame; 9602FRAME. The number 0 denotes the root window.
9603If DELETE_P is non-nil, delete the property after retreiving it.
9604If VECTOR_RET_P is non-nil, don't return a string but a vector of values.
9605
9606Value is nil if FRAME hasn't a property with name PROP or if PROP has
9607no value of TYPE. */)
9608 (prop, frame, type, source, delete_p, vector_ret_p)
9609 Lisp_Object prop, frame, type, source, delete_p, vector_ret_p;
9662{ 9610{
9663 struct frame *f = check_x_frame (frame); 9611 struct frame *f = check_x_frame (frame);
9664 Atom prop_atom; 9612 Atom prop_atom;
@@ -9666,14 +9614,43 @@ value. */)
9666 Lisp_Object prop_value = Qnil; 9614 Lisp_Object prop_value = Qnil;
9667 char *tmp_data = NULL; 9615 char *tmp_data = NULL;
9668 Atom actual_type; 9616 Atom actual_type;
9617 Atom target_type = XA_STRING;
9669 int actual_format; 9618 int actual_format;
9670 unsigned long actual_size, bytes_remaining; 9619 unsigned long actual_size, bytes_remaining;
9620 Window target_window = FRAME_X_WINDOW (f);
9621 struct gcpro gcpro1;
9671 9622
9623 GCPRO1 (prop_value);
9672 CHECK_STRING (prop); 9624 CHECK_STRING (prop);
9625
9626 if (! NILP (source))
9627 {
9628 if (NUMBERP (source))
9629 {
9630 if (FLOATP (source))
9631 target_window = (Window) XFLOAT (source);
9632 else
9633 target_window = XFASTINT (source);
9634
9635 if (target_window == 0)
9636 target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
9637 }
9638 else if (CONSP (source))
9639 target_window = cons_to_long (source);
9640 }
9641
9673 BLOCK_INPUT; 9642 BLOCK_INPUT;
9643 if (STRINGP (type))
9644 {
9645 if (strcmp ("AnyPropertyType", SDATA (type)) == 0)
9646 target_type = AnyPropertyType;
9647 else
9648 target_type = XInternAtom (FRAME_X_DISPLAY (f), SDATA (type), False);
9649 }
9650
9674 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False); 9651 prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SDATA (prop), False);
9675 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 9652 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
9676 prop_atom, 0, 0, False, XA_STRING, 9653 prop_atom, 0, 0, False, target_type,
9677 &actual_type, &actual_format, &actual_size, 9654 &actual_type, &actual_format, &actual_size,
9678 &bytes_remaining, (unsigned char **) &tmp_data); 9655 &bytes_remaining, (unsigned char **) &tmp_data);
9679 if (rc == Success) 9656 if (rc == Success)
@@ -9683,19 +9660,29 @@ value. */)
9683 XFree (tmp_data); 9660 XFree (tmp_data);
9684 tmp_data = NULL; 9661 tmp_data = NULL;
9685 9662
9686 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 9663 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
9687 prop_atom, 0, bytes_remaining, 9664 prop_atom, 0, bytes_remaining,
9688 False, XA_STRING, 9665 ! NILP (delete_p), target_type,
9689 &actual_type, &actual_format, 9666 &actual_type, &actual_format,
9690 &actual_size, &bytes_remaining, 9667 &actual_size, &bytes_remaining,
9691 (unsigned char **) &tmp_data); 9668 (unsigned char **) &tmp_data);
9692 if (rc == Success && tmp_data) 9669 if (rc == Success && tmp_data)
9693 prop_value = make_string (tmp_data, size); 9670 {
9671 if (NILP (vector_ret_p))
9672 prop_value = make_string (tmp_data, size);
9673 else
9674 prop_value = x_property_data_to_lisp (f,
9675 (unsigned char *) tmp_data,
9676 actual_type,
9677 actual_format,
9678 actual_size);
9679 }
9694 9680
9695 XFree (tmp_data); 9681 if (tmp_data) XFree (tmp_data);
9696 } 9682 }
9697 9683
9698 UNBLOCK_INPUT; 9684 UNBLOCK_INPUT;
9685 UNGCPRO;
9699 return prop_value; 9686 return prop_value;
9700} 9687}
9701 9688
@@ -10752,7 +10739,6 @@ selection dialog's entry field, if MUSTMATCH is non-nil.")
10752 int count = specpdl_ptr - specpdl; 10739 int count = specpdl_ptr - specpdl;
10753 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 10740 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
10754 char *cdef_file; 10741 char *cdef_file;
10755 char *cprompt;
10756 10742
10757 GCPRO5 (prompt, dir, default_filename, mustmatch, file); 10743 GCPRO5 (prompt, dir, default_filename, mustmatch, file);
10758 CHECK_STRING (prompt); 10744 CHECK_STRING (prompt);
@@ -11110,7 +11096,6 @@ meaning don't clear the cache. */);
11110 defsubr (&Sx_close_connection); 11096 defsubr (&Sx_close_connection);
11111 defsubr (&Sx_display_list); 11097 defsubr (&Sx_display_list);
11112 defsubr (&Sx_synchronize); 11098 defsubr (&Sx_synchronize);
11113 defsubr (&Sx_send_client_message);
11114 defsubr (&Sx_focus_frame); 11099 defsubr (&Sx_focus_frame);
11115 defsubr (&Sx_backspace_delete_keys_p); 11100 defsubr (&Sx_backspace_delete_keys_p);
11116 11101
diff --git a/src/xselect.c b/src/xselect.c
index e1dbb4601dc..637b39272b7 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
23/* Rewritten by jwz */ 23/* Rewritten by jwz */
24 24
25#include <config.h> 25#include <config.h>
26#include <stdio.h> /* termhooks.h needs this */
26#include "lisp.h" 27#include "lisp.h"
27#include "xterm.h" /* for all of the X includes */ 28#include "xterm.h" /* for all of the X includes */
28#include "dispextern.h" /* frame.h seems to want this */ 29#include "dispextern.h" /* frame.h seems to want this */
@@ -30,6 +31,9 @@ Boston, MA 02111-1307, USA. */
30#include "blockinput.h" 31#include "blockinput.h"
31#include "buffer.h" 32#include "buffer.h"
32#include "process.h" 33#include "process.h"
34#include "termhooks.h"
35
36#include <X11/Xproto.h>
33 37
34struct prop_location; 38struct prop_location;
35 39
@@ -50,7 +54,9 @@ static struct prop_location *expect_property_change P_ ((Display *, Window,
50static void unexpect_property_change P_ ((struct prop_location *)); 54static void unexpect_property_change P_ ((struct prop_location *));
51static Lisp_Object wait_for_property_change_unwind P_ ((Lisp_Object)); 55static Lisp_Object wait_for_property_change_unwind P_ ((Lisp_Object));
52static void wait_for_property_change P_ ((struct prop_location *)); 56static void wait_for_property_change P_ ((struct prop_location *));
53static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object, Lisp_Object)); 57static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object,
58 Lisp_Object,
59 Lisp_Object));
54static void x_get_window_property P_ ((Display *, Window, Atom, 60static void x_get_window_property P_ ((Display *, Window, Atom,
55 unsigned char **, int *, 61 unsigned char **, int *,
56 Atom *, int *, unsigned long *, int)); 62 Atom *, int *, unsigned long *, int));
@@ -1223,8 +1229,8 @@ static Window reading_selection_window;
1223 Converts this to Lisp data and returns it. */ 1229 Converts this to Lisp data and returns it. */
1224 1230
1225static Lisp_Object 1231static Lisp_Object
1226x_get_foreign_selection (selection_symbol, target_type) 1232x_get_foreign_selection (selection_symbol, target_type, time_stamp)
1227 Lisp_Object selection_symbol, target_type; 1233 Lisp_Object selection_symbol, target_type, time_stamp;
1228{ 1234{
1229 struct frame *sf = SELECTED_FRAME (); 1235 struct frame *sf = SELECTED_FRAME ();
1230 Window requestor_window; 1236 Window requestor_window;
@@ -1252,6 +1258,18 @@ x_get_foreign_selection (selection_symbol, target_type)
1252 else 1258 else
1253 type_atom = symbol_to_x_atom (dpyinfo, display, target_type); 1259 type_atom = symbol_to_x_atom (dpyinfo, display, target_type);
1254 1260
1261 if (! NILP (time_stamp))
1262 {
1263 if (CONSP (time_stamp))
1264 requestor_time = (Time) cons_to_long (time_stamp);
1265 else if (INTEGERP (time_stamp))
1266 requestor_time = (Time) XUINT (time_stamp);
1267 else if (FLOATP (time_stamp))
1268 requestor_time = (Time) XFLOAT (time_stamp);
1269 else
1270 error ("TIME_STAMP must be cons or number");
1271 }
1272
1255 BLOCK_INPUT; 1273 BLOCK_INPUT;
1256 1274
1257 count = x_catch_errors (display); 1275 count = x_catch_errors (display);
@@ -1943,13 +1961,15 @@ anything that the functions on `selection-converter-alist' know about. */)
1943 will block until all of the data has arrived. */ 1961 will block until all of the data has arrived. */
1944 1962
1945DEFUN ("x-get-selection-internal", Fx_get_selection_internal, 1963DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
1946 Sx_get_selection_internal, 2, 2, 0, 1964 Sx_get_selection_internal, 2, 3, 0,
1947 doc: /* Return text selected from some X window. 1965 doc: /* Return text selected from some X window.
1948SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. 1966SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
1949\(Those are literal upper-case symbol names, since that's what X expects.) 1967\(Those are literal upper-case symbol names, since that's what X expects.)
1950TYPE is the type of data desired, typically `STRING'. */) 1968TYPE is the type of data desired, typically `STRING'.
1951 (selection_symbol, target_type) 1969TIME_STAMP is the time to use in the XConvertSelection call for foreign
1952 Lisp_Object selection_symbol, target_type; 1970selections. If omitted, defaults to the time for the last event. */)
1971 (selection_symbol, target_type, time_stamp)
1972 Lisp_Object selection_symbol, target_type, time_stamp;
1953{ 1973{
1954 Lisp_Object val = Qnil; 1974 Lisp_Object val = Qnil;
1955 struct gcpro gcpro1, gcpro2; 1975 struct gcpro gcpro1, gcpro2;
@@ -1973,7 +1993,7 @@ TYPE is the type of data desired, typically `STRING'. */)
1973 1993
1974 if (NILP (val)) 1994 if (NILP (val))
1975 { 1995 {
1976 val = x_get_foreign_selection (selection_symbol, target_type); 1996 val = x_get_foreign_selection (selection_symbol, target_type, time_stamp);
1977 goto DONE; 1997 goto DONE;
1978 } 1998 }
1979 1999
@@ -2310,6 +2330,351 @@ Positive means shift the values forward, negative means backward. */)
2310 2330
2311#endif 2331#endif
2312 2332
2333/***********************************************************************
2334 Drag and drop support
2335***********************************************************************/
2336/* Check that lisp values are of correct type for x_fill_property_data.
2337 That is, number, string or a cons with two numbers (low and high 16
2338 bit parts of a 32 bit number). */
2339
2340int
2341x_check_property_data (data)
2342 Lisp_Object data;
2343{
2344 Lisp_Object iter;
2345 int size = 0;
2346
2347 for (iter = data; CONSP (iter) && size != -1; iter = XCDR (iter), ++size)
2348 {
2349 Lisp_Object o = XCAR (iter);
2350
2351 if (! NUMBERP (o) && ! STRINGP (o) && ! CONSP (o))
2352 size = -1;
2353 else if (CONSP (o) &&
2354 (! NUMBERP (XCAR (o)) || ! NUMBERP (XCDR (o))))
2355 size = -1;
2356 }
2357
2358 return size;
2359}
2360
2361/* Convert lisp values to a C array. Values may be a number, a string
2362 which is taken as an X atom name and converted to the atom value, or
2363 a cons containing the two 16 bit parts of a 32 bit number.
2364
2365 DPY is the display use to look up X atoms.
2366 DATA is a Lisp list of values to be converted.
2367 RET is the C array that contains the converted values. It is assumed
2368 it is big enough to hol all values.
2369 FORMAT is 8, 16 or 32 and gives the size in bits for each C value to
2370 be stored in RET. */
2371
2372void
2373x_fill_property_data (dpy, data, ret, format)
2374 Display *dpy;
2375 Lisp_Object data;
2376 void *ret;
2377 int format;
2378{
2379 CARD32 val;
2380 CARD32 *d32 = (CARD32 *) ret;
2381 CARD16 *d16 = (CARD16 *) ret;
2382 CARD8 *d08 = (CARD8 *) ret;
2383 Lisp_Object iter;
2384
2385 for (iter = data; CONSP (iter); iter = XCDR (iter))
2386 {
2387 Lisp_Object o = XCAR (iter);
2388
2389 if (INTEGERP (o))
2390 val = (CARD32) XFASTINT (o);
2391 else if (FLOATP (o))
2392 val = (CARD32) XFLOAT (o);
2393 else if (CONSP (o))
2394 val = (CARD32) cons_to_long (o);
2395 else if (STRINGP (o))
2396 {
2397 BLOCK_INPUT;
2398 val = XInternAtom (dpy, (char *) SDATA (o), False);
2399 UNBLOCK_INPUT;
2400 }
2401 else
2402 error ("Wrong type, must be string, number or cons");
2403
2404 if (format == 8)
2405 *d08++ = (CARD8) val;
2406 else if (format == 16)
2407 *d16++ = (CARD16) val;
2408 else
2409 *d32++ = val;
2410 }
2411}
2412
2413/* Convert an array of C values to a Lisp list.
2414 F is the frame to be used to look up X atoms if the TYPE is XA_ATOM.
2415 DATA is a C array of values to be converted.
2416 TYPE is the type of the data. Only XA_ATOM is special, it converts
2417 each number in DATA to its corresponfing X atom as a symbol.
2418 FORMAT is 8, 16 or 32 and gives the size in bits for each C value to
2419 be stored in RET.
2420 SIZE is the number of elements in DATA.
2421
2422 Also see comment for selection_data_to_lisp_data above. */
2423
2424Lisp_Object
2425x_property_data_to_lisp (f, data, type, format, size)
2426 struct frame *f;
2427 unsigned char *data;
2428 Atom type;
2429 int format;
2430 unsigned long size;
2431{
2432 return selection_data_to_lisp_data (FRAME_X_DISPLAY (f),
2433 data, size*format/8, type, format);
2434}
2435
2436/* Get the mouse position frame relative coordinates. */
2437
2438static void
2439mouse_position_for_drop (f, x, y)
2440 FRAME_PTR f;
2441 int *x;
2442 int *y;
2443{
2444 Window root, dummy_window;
2445 int dummy;
2446
2447 BLOCK_INPUT;
2448
2449 XQueryPointer (FRAME_X_DISPLAY (f),
2450 DefaultRootWindow (FRAME_X_DISPLAY (f)),
2451
2452 /* The root window which contains the pointer. */
2453 &root,
2454
2455 /* Window pointer is on, not used */
2456 &dummy_window,
2457
2458 /* The position on that root window. */
2459 x, y,
2460
2461 /* x/y in dummy_window coordinates, not used. */
2462 &dummy, &dummy,
2463
2464 /* Modifier keys and pointer buttons, about which
2465 we don't care. */
2466 (unsigned int *) &dummy);
2467
2468
2469 /* Absolute to relative. */
2470 *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
2471 *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
2472
2473 UNBLOCK_INPUT;
2474}
2475
2476DEFUN ("x-get-atom-name", Fx_get_atom_name,
2477 Sx_get_atom_name, 1, 2, 0,
2478 doc: /* Return the X atom name for VALUE as a string.
2479VALUE may be a number or a cons where the car is the upper 16 bits and
2480the cdr is the lower 16 bits of a 32 bit value.
2481Use the display for FRAME or the current frame if FRAME is not given or nil.
2482
2483If the value is 0 or the atom is not known, return the empty string. */)
2484 (value, frame)
2485 Lisp_Object value, frame;
2486{
2487 struct frame *f = check_x_frame (frame);
2488 char *name = 0;
2489 Lisp_Object ret = Qnil;
2490 int count;
2491 Display *dpy = FRAME_X_DISPLAY (f);
2492 Atom atom;
2493
2494 if (INTEGERP (value))
2495 atom = (Atom) XUINT (value);
2496 else if (FLOATP (value))
2497 atom = (Atom) XFLOAT (value);
2498 else if (CONSP (value))
2499 atom = (Atom) cons_to_long (value);
2500 else
2501 error ("Wrong type, value must be number or cons");
2502
2503 BLOCK_INPUT;
2504 count = x_catch_errors (dpy);
2505
2506 name = atom ? XGetAtomName (dpy, atom) : "";
2507
2508 if (! x_had_errors_p (dpy))
2509 ret = make_string (name, strlen (name));
2510
2511 x_uncatch_errors (dpy, count);
2512
2513 if (atom && name) XFree (name);
2514 if (NILP (ret)) ret = make_string ("", 0);
2515
2516 UNBLOCK_INPUT;
2517
2518 return ret;
2519}
2520
2521/* Convert an XClientMessageEvent to a Lisp event of type DRAG_N_DROP_EVENT.
2522 TODO: Check if this client event really is a DND event? */
2523
2524int
2525x_handle_dnd_message (f, event, dpyinfo, bufp)
2526 struct frame *f;
2527 XClientMessageEvent *event;
2528 struct x_display_info *dpyinfo;
2529 struct input_event *bufp;
2530{
2531 Lisp_Object vec;
2532 Lisp_Object frame;
2533 unsigned long size = (8*sizeof (event->data))/event->format;
2534 int x, y;
2535
2536 XSETFRAME (frame, f);
2537
2538 vec = Fmake_vector (make_number (4), Qnil);
2539 AREF (vec, 0) = SYMBOL_NAME (x_atom_to_symbol (FRAME_X_DISPLAY (f),
2540 event->message_type));
2541 AREF (vec, 1) = frame;
2542 AREF (vec, 2) = make_number (event->format);
2543 AREF (vec, 3) = x_property_data_to_lisp (f,
2544 event->data.b,
2545 event->message_type,
2546 event->format,
2547 size);
2548
2549 mouse_position_for_drop (f, &x, &y);
2550 bufp->kind = DRAG_N_DROP_EVENT;
2551 bufp->frame_or_window = Fcons (frame, vec);
2552 bufp->timestamp = CurrentTime;
2553 bufp->x = make_number (x);
2554 bufp->y = make_number (y);
2555 bufp->arg = Qnil;
2556 bufp->modifiers = 0;
2557
2558 return 1;
2559}
2560
2561DEFUN ("x-send-client-message", Fx_send_client_event,
2562 Sx_send_client_message, 6, 6, 0,
2563 doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
2564
2565For DISPLAY, specify either a frame or a display name (a string).
2566If DISPLAY is nil, that stands for the selected frame's display.
2567DEST may be a number, in which case it is a Window id. The value 0 may
2568be used to send to the root window of the DISPLAY.
2569If DEST is a cons, it is converted to a 32 bit number
2570with the high 16 bits from the car and the lower 16 bit from the cdr. That
2571number is then used as a window id.
2572If DEST is a frame the event is sent to the outer window of that frame.
2573Nil means the currently selected frame.
2574If DEST is the string "PointerWindow" the event is sent to the window that
2575contains the pointer. If DEST is the string "InputFocus" the event is
2576sent to the window that has the input focus.
2577FROM is the frame sending the event. Use nil for currently selected frame.
2578MESSAGE-TYPE is the name of an Atom as a string.
2579FORMAT must be one of 8, 16 or 32 and determines the size of the values in
2580bits. VALUES is a list of numbers, cons and/or strings containing the values
2581to send. If a value is a string, it is converted to an Atom and the value of
2582the Atom is sent. If a value is a cons, it is converted to a 32 bit number
2583with the high 16 bits from the car and the lower 16 bit from the cdr.
2584If more values than fits into the event is given, the excessive values
2585are ignored. */)
2586 (display, dest, from, message_type, format, values)
2587 Lisp_Object display, dest, from, message_type, format, values;
2588{
2589 struct x_display_info *dpyinfo = check_x_display_info (display);
2590 Window wdest;
2591 XEvent event;
2592 Lisp_Object cons;
2593 int size;
2594 struct frame *f = check_x_frame (from);
2595 int count;
2596 int to_root;
2597
2598 CHECK_STRING (message_type);
2599 CHECK_NUMBER (format);
2600 CHECK_CONS (values);
2601
2602 if (x_check_property_data (values) == -1)
2603 error ("Bad data in VALUES, must be number, cons or string");
2604
2605 event.xclient.type = ClientMessage;
2606 event.xclient.format = XFASTINT (format);
2607
2608 if (event.xclient.format != 8 && event.xclient.format != 16
2609 && event.xclient.format != 32)
2610 error ("FORMAT must be one of 8, 16 or 32");
2611
2612 if (FRAMEP (dest) || NILP (dest))
2613 {
2614 struct frame *fdest = check_x_frame (dest);
2615 wdest = FRAME_OUTER_WINDOW (fdest);
2616 }
2617 else if (STRINGP (dest))
2618 {
2619 if (strcmp (SDATA (dest), "PointerWindow") == 0)
2620 wdest = PointerWindow;
2621 else if (strcmp (SDATA (dest), "InputFocus") == 0)
2622 wdest = InputFocus;
2623 else
2624 error ("DEST as a string must be one of PointerWindow or InputFocus");
2625 }
2626 else if (INTEGERP (dest))
2627 wdest = (Window) XFASTINT (dest);
2628 else if (FLOATP (dest))
2629 wdest = (Window) XFLOAT (dest);
2630 else if (CONSP (dest))
2631 {
2632 if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest)))
2633 error ("Both car and cdr for DEST must be numbers");
2634 else
2635 wdest = (Window) cons_to_long (dest);
2636 }
2637 else
2638 error ("DEST must be a frame, nil, string, number or cons");
2639
2640 if (wdest == 0) wdest = dpyinfo->root_window;
2641 to_root = wdest == dpyinfo->root_window;
2642
2643 for (cons = values, size = 0; CONSP (cons); cons = XCDR (cons), ++size)
2644 ;
2645
2646 BLOCK_INPUT;
2647
2648 event.xclient.message_type
2649 = XInternAtom (dpyinfo->display, SDATA (message_type), False);
2650 event.xclient.display = dpyinfo->display;
2651
2652 /* Some clients (metacity for example) expects sending window to be here
2653 when sending to the root window. */
2654 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
2655
2656 memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b));
2657 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
2658 event.xclient.format);
2659
2660 /* If event mask is 0 the event is sent to the client that created
2661 the destination window. But if we are sending to the root window,
2662 there is no such client. Then we set the event mask to 0xffff. The
2663 event then goes to clients selecting for events on the root window. */
2664 count = x_catch_errors (dpyinfo->display);
2665 {
2666 int propagate = to_root ? False : True;
2667 unsigned mask = to_root ? 0xffff : 0;
2668 XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
2669 XFlush (dpyinfo->display);
2670 }
2671 x_uncatch_errors (dpyinfo->display, count);
2672 UNBLOCK_INPUT;
2673
2674 return Qnil;
2675}
2676
2677
2313void 2678void
2314syms_of_xselect () 2679syms_of_xselect ()
2315{ 2680{
@@ -2325,6 +2690,9 @@ syms_of_xselect ()
2325 defsubr (&Sx_rotate_cut_buffers_internal); 2690 defsubr (&Sx_rotate_cut_buffers_internal);
2326#endif 2691#endif
2327 2692
2693 defsubr (&Sx_get_atom_name);
2694 defsubr (&Sx_send_client_message);
2695
2328 reading_selection_reply = Fcons (Qnil, Qnil); 2696 reading_selection_reply = Fcons (Qnil, Qnil);
2329 staticpro (&reading_selection_reply); 2697 staticpro (&reading_selection_reply);
2330 reading_selection_window = 0; 2698 reading_selection_window = 0;
diff --git a/src/xterm.c b/src/xterm.c
index 2d60a534a42..321e9fa3f2f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -716,7 +716,7 @@ x_draw_fringe_bitmap (w, row, p)
716 else 716 else
717 x_clip_to_row (w, row, gc); 717 x_clip_to_row (w, row, gc);
718 718
719 if (p->bx >= 0) 719 if (p->bx >= 0 && !p->overlay_p)
720 { 720 {
721 /* In case the same realized face is used for fringes and 721 /* In case the same realized face is used for fringes and
722 for something displayed in the text (e.g. face `region' on 722 for something displayed in the text (e.g. face `region' on
@@ -734,20 +734,49 @@ x_draw_fringe_bitmap (w, row, p)
734 XSetForeground (display, face->gc, face->foreground); 734 XSetForeground (display, face->gc, face->foreground);
735 } 735 }
736 736
737 if (p->which != NO_FRINGE_BITMAP) 737 if (p->which)
738 { 738 {
739 unsigned char *bits = fringe_bitmaps[p->which].bits + p->dh; 739 unsigned char *bits;
740 Pixmap pixmap; 740 Pixmap pixmap, clipmask = (Pixmap) 0;
741 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f)); 741 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
742 XGCValues gcv;
743
744 if (p->wd > 8)
745 bits = (unsigned char *)(p->bits + p->dh);
746 else
747 bits = (unsigned char *)p->bits + p->dh;
742 748
743 /* Draw the bitmap. I believe these small pixmaps can be cached 749 /* Draw the bitmap. I believe these small pixmaps can be cached
744 by the server. */ 750 by the server. */
745 pixmap = XCreatePixmapFromBitmapData (display, window, bits, p->wd, p->h, 751 pixmap = XCreatePixmapFromBitmapData (display, window, bits, p->wd, p->h,
746 face->foreground, 752 (p->cursor_p
753 ? (p->overlay_p ? face->background
754 : f->output_data.x->cursor_pixel)
755 : face->foreground),
747 face->background, depth); 756 face->background, depth);
757
758 if (p->overlay_p)
759 {
760 clipmask = XCreatePixmapFromBitmapData (display,
761 FRAME_X_DISPLAY_INFO (f)->root_window,
762 bits, p->wd, p->h,
763 1, 0, 1);
764 gcv.clip_mask = clipmask;
765 gcv.clip_x_origin = p->x;
766 gcv.clip_y_origin = p->y;
767 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
768 }
769
748 XCopyArea (display, pixmap, window, gc, 0, 0, 770 XCopyArea (display, pixmap, window, gc, 0, 0,
749 p->wd, p->h, p->x, p->y); 771 p->wd, p->h, p->x, p->y);
750 XFreePixmap (display, pixmap); 772 XFreePixmap (display, pixmap);
773
774 if (p->overlay_p)
775 {
776 gcv.clip_mask = (Pixmap) 0;
777 XChangeGC (display, gc, GCClipMask, &gcv);
778 XFreePixmap (display, clipmask);
779 }
751 } 780 }
752 781
753 XSetClipMask (display, gc, None); 782 XSetClipMask (display, gc, None);
@@ -5943,7 +5972,25 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
5943 } 5972 }
5944#endif /* USE_TOOLKIT_SCROLL_BARS */ 5973#endif /* USE_TOOLKIT_SCROLL_BARS */
5945 else 5974 else
5946 goto OTHER; 5975 {
5976 struct frame *f
5977 = x_any_window_to_frame (dpyinfo, event.xclient.window);
5978
5979 if (f)
5980 {
5981 int ret = x_handle_dnd_message (f, &event.xclient,
5982 dpyinfo, bufp);
5983 if (ret > 0)
5984 {
5985 ++bufp, ++count, --numchars;
5986 }
5987
5988 if (ret != 0)
5989 *finish = X_EVENT_DROP;
5990 }
5991 else
5992 goto OTHER;
5993 }
5947 } 5994 }
5948 break; 5995 break;
5949 5996
@@ -10877,6 +10924,8 @@ static struct redisplay_interface x_redisplay_interface =
10877 x_get_glyph_overhangs, 10924 x_get_glyph_overhangs,
10878 x_fix_overlapping_area, 10925 x_fix_overlapping_area,
10879 x_draw_fringe_bitmap, 10926 x_draw_fringe_bitmap,
10927 0, /* define_fringe_bitmap */
10928 0, /* destroy_fringe_bitmap */
10880 x_per_char_metric, 10929 x_per_char_metric,
10881 x_encode_char, 10930 x_encode_char,
10882 x_compute_glyph_string_overhangs, 10931 x_compute_glyph_string_overhangs,
diff --git a/src/xterm.h b/src/xterm.h
index 8eb8604ae75..45de640f165 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1009,8 +1009,24 @@ extern void x_handle_selection_request P_ ((struct input_event *));
1009extern void x_handle_selection_clear P_ ((struct input_event *)); 1009extern void x_handle_selection_clear P_ ((struct input_event *));
1010extern void x_clear_frame_selections P_ ((struct frame *)); 1010extern void x_clear_frame_selections P_ ((struct frame *));
1011 1011
1012extern int x_handle_dnd_message P_ ((struct frame *,
1013 XClientMessageEvent *,
1014 struct x_display_info *,
1015 struct input_event *bufp));
1016extern int x_check_property_data P_ ((Lisp_Object));
1017extern void x_fill_property_data P_ ((Display *,
1018 Lisp_Object,
1019 void *,
1020 int));
1021extern Lisp_Object x_property_data_to_lisp P_ ((struct frame *,
1022 unsigned char *,
1023 Atom,
1024 int,
1025 unsigned long));
1026
1012/* Defined in xfns.c */ 1027/* Defined in xfns.c */
1013 1028
1029extern struct x_display_info * check_x_display_info P_ ((Lisp_Object frame));
1014extern int have_menus_p P_ ((void)); 1030extern int have_menus_p P_ ((void));
1015extern int x_bitmap_height P_ ((struct frame *, int)); 1031extern int x_bitmap_height P_ ((struct frame *, int));
1016extern int x_bitmap_width P_ ((struct frame *, int)); 1032extern int x_bitmap_width P_ ((struct frame *, int));
@@ -1062,6 +1078,7 @@ extern void x_free_dpy_colors P_ ((Display *, Screen *, Colormap,
1062extern void x_activate_menubar P_ ((struct frame *)); 1078extern void x_activate_menubar P_ ((struct frame *));
1063extern int popup_activated P_ ((void)); 1079extern int popup_activated P_ ((void));
1064extern void initialize_frame_menubar P_ ((struct frame *)); 1080extern void initialize_frame_menubar P_ ((struct frame *));
1081extern void free_frame_menubar P_ ((struct frame *));
1065 1082
1066/* Defined in widget.c */ 1083/* Defined in widget.c */
1067 1084