From: tomo Date: Mon, 17 May 1999 09:41:33 +0000 (+0000) Subject: XEmacs 21.2-b2 X-Git-Tag: r21-2b2~2 X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72a705551741d6f85a40eea486c222bac482d8dc;p=chise%2Fxemacs-chise.git- XEmacs 21.2-b2 --- diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 738fa34..4cfe60b 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,13 @@ +1998-09-29 SL Baur + + * XEmacs 21.2-beta2 is released. + +1998-09-08 Raymond Toy + + * gnuclient.c (filename_expand): Added better recognition of + absolute pathnames for CYGWIN. Convert absolute pathnames with + drive letters to something xemacs can handle. + 1998-07-19 SL Baur * XEmacs 21.2-beta1 is released. diff --git a/lib-src/gnuclient.c b/lib-src/gnuclient.c index a89641f..e8797c1 100644 --- a/lib-src/gnuclient.c +++ b/lib-src/gnuclient.c @@ -179,8 +179,37 @@ filename_expand (char *fullpath, char *filename) fullpath[0] = '\0'; - if (filename[0] && filename[0] != '/') - { /* relative filename */ + if (filename[0] && filename[0] == '/') + { + /* Absolute (unix-style) pathname. Do nothing */ + strcat (fullpath, filename); + } +#ifdef __CYGWIN32__ + else if (filename[0] && filename[0] == '\\' && + filename[1] && filename[1] == '\\') + { + /* This path includes the server name (something like + "\\server\path"), so we assume it's absolute. Do nothing to + it. */ + strcat (fullpath, filename); + } + else if (filename[0] && + filename[1] && filename[1] == ':' && + filename[2] && filename[2] == '\\') + { + /* Absolute pathname with drive letter. Convert ":" + to "///". */ + strcat (fullpath, "//"); + strncat (fullpath, filename, 1); + strcat (fullpath, &filename[2]); + } +#endif + else + { + /* Assume relative Unix style path. Get the current directory + and prepend it. FIXME: need to fix the case of DOS paths like + "\foo", where we need to get the current drive. */ + strcat (fullpath, get_current_working_directory ()); len = strlen (fullpath); @@ -188,10 +217,7 @@ filename_expand (char *fullpath, char *filename) ; /* yep */ else strcat (fullpath, "/"); /* nope, append trailing slash */ - } /* if */ - - strcat (fullpath,filename); - + } } /* filename_expand */ /* Encase the string in quotes, escape all the backslashes and quotes diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c2f1b30..6cca999 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,317 @@ +1998-09-29 SL Baur + + * XEmacs 21.2-beta2 is released. + +1998-08-14 Jan Vroonhof + + * files.el (auto-mode-alist): Enhanced regexp for perl-mode + +1998-09-22 Karl M. Hegbloom + + * info.el (Info-mode): Document page turning by double clicks in + docstring so `M-x describe-mode' will display it. + +1998-09-20 Karl M. Hegbloom + + * info.el (Info-mouse-track-double-click-hook): Use character + widths to calculate a border region where double clicking does + page turning, and return `nil' by default so other hooks, such as + region highlighting, will be run. + +1998-09-29 Colin Rafferty + + * sound.el (default-sound-directory-list): Initialize with all the + "sounds" directories in `data-directory-list'. It used to just be + the first one. + + * packages.el (locate-data-directory-list): Created. This gives + the list of matching directories, unlike `locate-data-directory', + which just gives the first one. + +1998-09-26 Jan Vroonhof + + * minibuf.el (read-from-minibuffer): No longer bind help-form but + make a binding in the local keymap until help-char handling is + improved. + + * help.el (help-keymap-with-help-key): Provide keymap with help + binding. + (help-print-help-form): New helper function. + +1998-09-23 Hrvoje Niksic + + * isearch-mode.el (isearch-highlight): set-extent-endpoints can + move extent to another buffer; no need to create a new extent. + (isearch-fix-case): New function. + (isearch-search-and-update): Use it. + +1998-09-22 Hrvoje Niksic + + * isearch-mode.el (isearch-mode): Use overriding-local-map to set + the keymap, not minor-mode-map-alist. + (isearch-done): Restore overriding-local-map. + +1998-09-21 Martin Buchholz + + * bytecomp.el (byte-compile-buffer-substring): + Fix for: (byte-compile (defun f () (buffer-substring))) + ==> ** buffer-substring called with 3 args, but requires 0-3 + - new code not only works, but is more readable, too. + +1998-09-20 Jonathan Harris + + * msw-faces.el (mswindows-init-device-faces): Don't try to + specify a default font at this late stage. Do try to force + creation of the default face font so that if it fails we get + an error now instead of a crash at frame creation. + + mswindows-font-canonicalize-name, mswindows-make-font-unbold, + mswindows-make-font-unitalic: Canonical default weight + changed from "Normal" to "Regular". + + mswindows-make-font-bold / -bold-italic: Supplied device was + not being passed into call to mswindows-find-smaller-font. + +1998-09-10 Björn Torkelsson + + * package-get.el (package-get-remote): Fix the path where to find + the packages on xemacs.org. + +1998-09-08 Hrvoje Niksic + + * about.el (about-maintainer-info): Update Ben's entry. + +1998-09-24 Martin Buchholz + + * lisp/shadow.el (find-emacs-lisp-shadows): + - `member' was being called on lists of length 2000! + - Replace with hashtables. + - Replace hand-coded loops with (dolist) + - Fix comment typo + +1998-09-20 Darryl Okahata + + * packages.el: Added new function, `package-delete-name', to + delete existing packages from the installed package database + (`packages-package-list'). Also added the "pkginfo" directory + to `packages-special-base-regexp', so that the pkginfo directory + would not get added to `late-packages'. + + * package-admin.el: Added ability to delete an installed package + (added low-level function, `package-admin-delete-package'). + Understands how to use the pkginfo/MANIFEST. file to + delete the package. When installing a package, will also + create a MANIFEST.* file if one is not provided by the + package. If the MANIFEST.* doesn't exist when deleting a + package, the functions will fall back to attempting to delete + any package-specific lisp directory. + + * package-get.el: Moved some functions to package-admin.el. + Added interactive function `package-get-delete-package', for + use by users for deleting a package. + + Also modified to not require the prescence of efs. + +1998-09-22 Hrvoje Niksic + + * files.el (find-file-noselect): Handle all signals, kill the + buffer and resignal. + +1998-09-23 SL Baur + + * cl-macs.el (glyph-image): Add setf method. + +1998-09-06 Darryl Okahata + + * package-get.el: Fixed broken EFS downloading. Also, look for + .tar.gz files first, in preference over .tgz files. + + * package-ui.el: Fix display of package version numbers. + +1998-08-27 Jan Vroonhof + + * x-font-menu.el (font-menu-set-font): Add "pt" units to size + argument. + +1998-09-03 Darryl Okahata + + * list-mode.el: `display-completion-list': added new/optional + keyword `:completion-string', which allows the programmer to + change the "Possible completions are:" prompt. + + * menubar-items.el: Added new pulldown menu-pick to start up the + visual package browser/installer: + + Options->Customize->List Packages + + * package-admin.el: Added hooks for installing under both Unix + and MS Windows. Does additional error checking. No longer + calls "add-big-package.sh" to install packages under Unix; now + calls gunzip & tar directly. + + * package-get.el: Added ability to install packages from files + on a local disk/CDROM. Now deletes any existing package lisp + directory. Does completion on available packages when + querying for package names. Will also search for .tgz files + in addition for .tar.gz files. Tries to reload + auto-autoloads, as a convenience when loading new packages, + and also tries to add any new package paths to `load-path'. + Changed all occurences of `concat' to use `expand-file-name'. + + * package-ui.el: New file which implements the main visual + package browser/installer, which is started via a menu pick or + M-x pui-list packages. + +1998-09-03 Hrvoje Niksic + + * startup.el (load-init-file): spelling fix. + +1998-09-02 Michael Sperber [Mr. Preprocessor] + + * startup.el (normal-top-level): Load auto-autoload files + covariantly with their precedence. + +1998-08-26 Jan Vroonhof + + * menubar-items.el (default-menubar): Remove "Font Weight" + option, there is currently no custom equivalent.. Customize-faces + is "Edit faces". + + * x-font-menu.el (font-menu-set-font): Use customize to set + default face. + + * faces.el (face-spec-update-all-matching): New function. + + * cus-face.el (custom-set-face-update-spec): New function. + Interface to customize faces from elisp. + + (custom-face-value-create): Show the customized settings if set + but not saved. + +1998-08-26 Jan Vroonhof + + (custom-face-value-create): Show the customized settings if set + but not saved. + +1998-08-31 Hrvoje Niksic + + * keydefs.el (global-map): Add FSF 20.3 binding of + query-replace-regexp. + +1998-08-21 Greg Klanderman + + * minibuf.el (read-file-name-internal-1): use + user-name-completion-1 instead of user-name-completion. + +1998-08-19 Michael Sperber [Mr. Preprocessor] + + * loadup.el: + * make-docfile.el: + * update-elc.el: Don't set `source-directory' (now defunct as a + global variable) no more. + + * packages.el (packages-list-autoloads): Made `source-directory' + (now defunct as a global variable) a parameter. + +1998-08-13 Carsten Leonhardt + + * about.el (about-hackers): new email + +1998-08-16 SL Baur + + * lisp-mode.el (with-string-as-buffer-contents): Set indentation. + +1998-07-17 Didier Verna + + * faces.el (set-face-property): + (set-face-dim-p): + (face-dim-p): updated the doc strings now that the dim property isn't + tty-specific. + (face-equal): the dim property is now a common one. + + * cus-face.el (custom-face-attributes): New face attribute: `dim' + Renamed the `stipple' attribute to `background-pixmap'. + (custom-face-background-pixmap): make custom-face-stipple an + obsolete alias for this. + +1998-08-11 Michael Sperber [Mr. Preprocessor] + + * find-paths.el (paths-file-readable-directory-p): Created and + used. + + * loadup.el: Don't set inhibit-... flags from run-temacs. + +1998-08-06 Michael Sperber [Mr. Preprocessor] + + * packages.el (packages-data-path-depth): Added and used. + +1998-08-05 Charles G. Waldman + + * about.el: + - Change .xpm to .png, delete "zcat" section. + - cosmetic fix in the 'marcpa' entry. + + * etc/photos + - convert all .xpm.Z to .png + - rename mrb to martin + - rename mcook-m to mcookm + +1998-07-31 Martin Buchholz + + * x-init.el (x-initialize-compose): Add support for + dead-circumflex as YET ANOTHER NAME for that dead key. + +1998-08-05 Colin Rafferty + + * setup-paths.el (paths-construct-exec-path): Made the + last-packages really be last. + (paths-construct-data-directory-list): Ditto. + +1998-08-01 Kai Haberzettl + + * startup.el(startup-splash-frame-body): + Update Copyright notice in splash screen + +1998-07-20 Greg Klanderman + + * minibuf.el (read-file-name-internal-1): do ~user completion. + +1998-07-22 Jan Vroonhof + + * font-lock.el (font-lock-fontify-glumped-region): Add guard + aginst destroyed extents + +1998-07-24 Greg Klanderman + + * package-get.el (package-get): add `install-dir' argument. + +1998-07-20 John Jones + + * package-get.el: calls to package-get-update-all will only + update packages which are already installed. + +1998-07-23 SL Baur + + * autoload.el (update-file-autoloads): Ensure autoloads buffer is + writable. + +1998-07-20 Colin Rafferty + + * about.el (about-hackers): Correct my email. + +1998-07-20 Kai Haberzettl + + * about.el (about-hackers): new email-address. + +1998-07-25 SL Baur + + * minibuf.el (read-number): Don't let `input-error' condition + escape. + +1998-07-20 Greg Klanderman + + * about.el (about-hackers): use my `email-for-life' address. + 1998-07-19 SL Baur * XEmacs 21.2-beta1 is released. diff --git a/lisp/about.el b/lisp/about.el index e2f0176..1bb1241 100644 --- a/lisp/about.el +++ b/lisp/about.el @@ -50,7 +50,7 @@ ;; People in this list have their individual links from the main page, ;; or from the `Legion' page. If they have an image, it should be -;; named after the CAR of the list element (baw -> baw.xpm). +;; named after the CAR of the list element (baw -> baw.png). ;; ;; If you add to this list, you'll want to update ;; `about-maintainer-info' (and maybe `about-hackers'. @@ -58,13 +58,14 @@ '((ajc "Andrew Cosgriff" "ajc@bing.wattle.id.au") (baw "Barry Warsaw" "bwarsaw@python.org") (bw "Bob Weiner" "weiner@altrasoft.com") + (chr "Christian Nybø" "chr@mediascience.no") (cthomp "Chuck Thompson" "cthomp@xemacs.org") (dmoore "David Moore" "dmoore@ucsd.edu") (dkindred "Darrell Kindred" "dkindred@cmu.edu") (dv "Didier Verna" "verna@inf.enst.fr") (hniksic "Hrvoje Niksic" "hniksic@srce.hr") (jareth "Jareth Hein" "jareth@camelot.co.jp") - (jason "Jason Mastaler" "jason@mastaler.com") + (jason "Jason Mastaler" "jason@xemacs.org") (jens "Jens Lautenbacher" "jens@lemcbed.lem.uni-karlsruhe.de") (jmiller "Jeff Miller" "jmiller@smart.net") (juhp "Jens-Ulrik Holger Petersen" "petersen@kurims.kyoto-u.ac.jp") @@ -87,7 +88,7 @@ (slb "SL Baur" "steve@xemacs.org") (stig "Jonathan Stigelman" "stig@hackvan.com") (stigb "Stig Bjorlykke" "stigb@tihlde.hist.no") - (thiessel "Marcus Thiessel" "thiessel@rhrk.uni-kl.de") + (thiessel "Marcus Thiessel" "marcus_thiessel@hp.com") (vladimir "Vladimir Ivanovic" "vladimir@mri.com") (wing "Ben Wing" "ben@xemacs.org") (wmperry "William Perry" "wmperry@aventail.com")) @@ -99,8 +100,11 @@ (defvar about-url-alist '((ajc . "http://www-personal.monash.edu.au/~ajc/") (altrasoft . "http://www.altrasoft.com/") + (ben . "http://www.666.com/ben/") + (ben-xemacs . "http://www.666.com/xemacs/") (baw . "http://www.python.org/~bwarsaw/") (cc-mode . "http://www.python.org/ftp/emacs/") + (chr . "http://www.xemacs.org/faq/") (dkindred . "http://www.cs.cmu.edu/People/dkindred/me.html") (dmoore . "http://oj.egbt.org/dmoore/") (jason . "http://www.mastaler.com/") @@ -209,7 +213,7 @@ (let* ((emacs-short-version (format "%d.%d" emacs-major-version emacs-minor-version)) - (emacs-about-version (format "version %s; Apr 1998" + (emacs-about-version (format "version %s; Aug 1998" emacs-short-version))) (widget-insert (about-center emacs-about-version)) (widget-create 'link :help-echo "The latest NEWS of XEmacs" @@ -529,45 +533,22 @@ contributed to the XEmacs development from late 1994 to early (if (memq (device-class) '(color grayscale)) "" "m") - ".xpm") + ".png") (locate-data-directory "photos"))) (data nil)) - (unless (file-exists-p file) - ;; Maybe the file is compressed? - (setq file (concat file ".Z")) - (if (file-exists-p file) - ;; Decompress it. - (condition-case nil - (let ((buffer (get-buffer-create " *image*"))) - (unwind-protect - (save-excursion - (message "Uncompressing image...") - (set-buffer buffer) - (erase-buffer) - (let ((coding-system-for-read 'binary) - (coding-system-for-write 'binary)) - (insert-file-contents-literally file) - (call-process-region (point-min) (point-max) - "zcat" t t nil) - (setq data - (buffer-substring (point-min) (point-max)))) - (message "Uncompressing image... done")) - (kill-buffer buffer))) - (error (setq data 'error))) - (setq file nil))) (setq glyph (cond ((stringp data) (make-glyph - (if (featurep 'xpm) - `([xpm :data ,data] + (if (featurep 'png) + `([png :data ,data] [string :data "[Image]"]) `([string :data "[Image]"])))) ((eq data 'error) (make-glyph [string :data "[Error]"])) (file (make-glyph - (if (featurep 'xpm) - `([xpm :file ,file] + (if (featurep 'png) + `([png :file ,file] [string :data "[Image]"]) `([string :data "[Image]"])))) (t @@ -607,26 +588,21 @@ Martin is no longer doing XEmacs for a living, and is Just Another Volunteer.\n")) (hniksic (widget-insert "\ -Hrvoje is currently a student at the Faculty of Electrical -Engineering and Computing in Zagreb, Croatia. He works part-time -at SRCE, where he helps run the network machines. In his free time he -is helping develop free software (especially XEmacs, as well as GNU -software) and is writing his own -- he has written a small network -mirroring utility Wget, see ") - (about-url-link 'wget "Download Wget") - (widget-insert ".\n")) +Hrvoje is a student at the Faculty of Electrical Engineering and +Computing in Zagreb, Croatia, working part-time at system administration +at SRCE. His hobby is hacking free software, particularly XEmacs and +GNU Wget, the latter being his very own creation. + +His contribution to XEmacs consists of a multitude of hours spent +adding new features and bugs, and fixing old ones. He dreams of +writing a home page.\n")) (wing (widget-insert "\ -I'm not a thug -- I just play one on video. -My roommate says I'm a San Francisco \"Mission Critter\".\n\n" - (about-with-face "Gory stuff follows:" 'italic) - "\n -In 1992 I left a stuffy East-Coast university, set out into the real -world, and ended up a co-founder of Pearl Software. As part of this -company, I became the principal architect of Win-Emacs, a port of -Lucid Emacs to Microsoft Windows and Windows NT (for more info, e-mail -to info@pearlsoft.com). +I began my Emacs life in 1992 as the co-founder of the now defunct +Pearl Software. As part of this company, I became the principal +architect of Win-Emacs, an early port of Lucid Emacs to Microsoft +Windows and Windows NT. Since April 1993, I've worked on XEmacs as a contractor for various companies, changing hats faster than Ronald Reagan's hair color (oops, @@ -637,8 +613,19 @@ widget, improving the documentation (especially the Emacs Lisp manual), and being a general nuisance ... er, brainstormer for many of the new features of XEmacs. -Recently I took a job at Dimension X, where I'm working on a -Java-based toolkit for developing VRML applications.\n")) +Alas, life has not been good to me recently. This former San Francisco +\"Mission Critter\" was exiled to \"Stroller Valley\" and, after a brief +stint developing a Java-based VRML toolkit for the now also defunct +Dimension X, I developed insidious hand and neck problems, and I was +forced to quit working. Since then, I have been learning how to interact +with the computer by using foot pedals and by dictating text to other +people. Recently I completed Architecting XEmacs, a web site about the +future of XEmacs.\n\n") + (widget-insert "Architecting XEmacs: ") + (about-url-link 'ben-xemacs "Find the miracles in store for XEmacs") + (widget-insert "\nBen's home page: ") + (about-url-link 'ben "Visit Ben's page") + (widget-insert "\n")) (cthomp (widget-insert "\ Chuck, through being in the wrong place at the right time, has gotten @@ -781,7 +768,7 @@ I'm part of the team producing POWER 911, a 911 emergency response system written in Modula3:\n") (about-url-link 'marcpa "Visit POWER 911") (widget-insert "\ -Previously, I worked at Softimage Inc., now a Microsoft company +\n\nPreviously, I worked at Softimage Inc., now a Microsoft company \(eeekkk!), as a UNIX system administrator. This is where I've been converted to NT. @@ -830,13 +817,12 @@ He has a page at ") (widget-insert ".\n")) (thiessel (widget-insert "\ -On May 1, 1996 he started working at University of Kaiserslautern in -the field of computer aided analog circuit design. His -responsibilities include the development and design of a CAD-Tool for -analog integrated circuits with special emphasis on distributed -software concepts. +Worked at University of Kaiserslautern where he took part in the +development and design of a CAD framework for analog integrated +circuits with special emphasis on distributed software concepts. He +has now joined HP as technical consultant. -When all the daily hacking is done he tries to take care of XEmacs +For XEmacs he does beta testing and tries to take care of XEmacs website at ") (about-url-link 'xemacs "Visit XEmacs web site") (widget-insert ".\n")) @@ -997,6 +983,16 @@ skiing, puzzles, and sci-fi. Jeff is also really interested in classical Roman history and enjoys making trips to Italy, where he was born, and seeing the sights") (widget-insert ".\n")) + (chr + (widget-insert "\ +Maintainer of the XEmacs FAQ and proud author of `zap-up-to-char'. + +Christian is a student at the Norwegian School of Economics and +Business Administration in Bergen, Norway. He used to work for an +internet startup called New Media Science, doing scripting and +violation of HTML DTD's. After graduation, spring 1999, he'll be +looking for a job involving lisp programming, French and Russian.") + (widget-insert ".\n")) )) ;; Setup the buffer for a maintainer. @@ -1041,7 +1037,7 @@ seeing the sights") (format "<%s>\n%s\n" address shortinfo)))) (defun about-hackers (&rest ignore) - (unless (about-get-buffer "*About Hackers*") + (unless (about-get-buffer "*About Contributors*") (let ((title "Other Contributors to XEmacs")) (widget-insert (about-center title) @@ -1206,6 +1202,8 @@ Beta tester and manager of the various XEmacs mailing lists. Originator and maintainer of the gnus.org domain.\n") (about-show-linked-info 'jmiller "\ Beta tester and last hacker of calendar.\n") + (about-show-linked-info 'chr "\ +Maintainer of the XEmacs FAQ and proud author of `zap-up-to-char'.\n") (flet ((print-short (name addr &optional shortinfo) (concat (about-with-face name 'italic) (about-tabs name) @@ -1349,7 +1347,7 @@ above. We couldn't have done it without them.\n\n" (print-short "Michael Guenther" "michaelg@igor.stuttgart.netsurf.de") (print-short "Dipankar Gupta" "dg@hplb.hpl.hp.com") (print-short "Markus Gutschke" "gutschk@GOEDEL.UNI-MUENSTER.DE") - (print-short "Kai Haberzettl" "khaberz@privat.circular.de") + (print-short "Kai Haberzettl" "khaberz@synnet.de") (print-short "Adam Hammer" "hammer@cs.purdue.edu") (print-short "Magnus Hammerin" "magnush@epact.se") (print-short "ChangGil Han" "cghan@phys401.phys.pusan.ac.kr") @@ -1384,7 +1382,7 @@ above. We couldn't have done it without them.\n\n" (print-short "Gregor Kennedy" "gregork@dadd.ti.com") (print-short "Michael Kifer" "kifer@cs.sunysb.edu") (print-short "Yasuhiko Kiuchi" "kiuchi@dsp.ksp.fujixerox.co.jp") - (print-short "Greg Klanderman" "greg@alphatech.com") + (print-short "Greg Klanderman" "greg.klanderman@alum.mit.edu") (print-short "Valdis Kletnieks" "Valdis.Kletnieks@vt.edu") (print-short "Rob Kooper" "kooper@cc.gatech.edu") (print-short "Peter Skov Knudsen" "knu@dde.dk") @@ -1392,7 +1390,7 @@ above. We couldn't have done it without them.\n\n" (print-short "Maximilien Lincourt" "max@toonboom.com") (print-short "Mats Larsson" "Mats.Larsson@uab.ericsson.se") (print-short "Simon Leinen" "simon@instrumatic.ch") - (print-short "Carsten Leonhardt" "leo@arioch.tng.oche.de") + (print-short "Carsten Leonhardt" "leo@arioch.oche.de") (print-short "James LewisMoss" "moss@cs.sc.edu") (print-short "Mats Lidell" "mats.lidell@contactor.se") (print-short "Matt Liggett" "mliggett@seven.ucs.indiana.edu") @@ -1430,7 +1428,6 @@ above. We couldn't have done it without them.\n\n" (print-short "Andy Norman" "ange@hplb.hpl.hp.com") (print-short "Joe Nuspl" "nuspl@sequent.com") (print-short "Kim Nyberg" "kny@tekla.fi") - (print-short "Christian Nybø" "chr@mediascience.no") (print-short "Kevin Oberman" "oberman@es.net") (print-short "David Ofelt" "ofelt@getalife.Stanford.EDU") (print-short "Alexandre Oliva" "oliva@dcc.unicamp.br") @@ -1446,7 +1443,7 @@ above. We couldn't have done it without them.\n\n" (print-short "Frederic Poncin" "fp@info.ucl.ac.be") (print-short "E. Rehmi Post" "rehmi@asylum.sf.ca.us") (print-short "Martin Pottendorfer" "Martin.Pottendorfer@aut.alcatel.at") - (print-short "Colin Rafferty" "craffert@ml.com") + (print-short "Colin Rafferty" "colin@xemacs.org") (print-short "Rick Rankin" "Rick_Rankin-P15254@email.mot.com") (print-short "Paul M Reilly" "pmr@pajato.com") (print-short "Jack Repenning" "jackr@sgi.com") @@ -1469,6 +1466,7 @@ above. We couldn't have done it without them.\n\n" (print-short "Cotton Seed" "cottons@cybercom.net") (print-short "Axel Seibert" "seiberta@informatik.tu-muenchen.de") (print-short "Odd-Magne Sekkingstad" "oddms@ii.uib.no") + (print-short "Gregory Neil Shapiro" "gshapiro@sendmail.org") (print-short "Justin Sheehy" "justin@linus.mitre.org") (print-short "John Shen" "zfs60@cas.org") (print-short "Murata Shuuichirou" "mrt@mickey.ai.kyutech.ac.jp") @@ -1504,6 +1502,7 @@ above. We couldn't have done it without them.\n\n" (print-short "Peter B. West" "p.west@uq.net.au") (print-short "Rod Whitby" "rwhitby@asc.corp.mot.com") (print-short "Rich Williams" "rdw@hplb.hpl.hp.com") + (print-short "Raymond Wiker" "raymond@orion.no") (print-short "Peter Windle" "peterw@SDL.UG.EDS.COM") (print-short "David C Worenklein" "dcw@gcm.com") (print-short "Takeshi Yamada" "yamada@sylvie.kecl.ntt.jp") diff --git a/lisp/auto-autoloads.el b/lisp/auto-autoloads.el index 55a4534..59692fc 100644 --- a/lisp/auto-autoloads.el +++ b/lisp/auto-autoloads.el @@ -1214,7 +1214,9 @@ Fetch PACKAGE with VERSION and all other required packages. Uses `package-get-base' to determine just what is required and what package provides that functionality. If VERSION is nil, retrieves latest version. Optional argument FETCHED-PACKAGES is used to keep -track of packages already fetched." t nil) +track of packages already fetched. + +Returns nil upon error." t nil) (autoload 'package-get "package-get" "\ Fetch PACKAGE from remote site. @@ -1223,6 +1225,8 @@ means most recent version. CONFLICT indicates what happens if the package is already installed. Valid values for CONFLICT are: 'always always retrieve the package even if it is already installed 'never do not retrieve the package if it is installed. +INSTALL-DIR, if non-nil, specifies the package directory where +fetched packages should be installed. The value of `package-get-base' is used to determine what files should be retrieved. The value of `package-get-remote' is used to determine @@ -1231,7 +1235,11 @@ order so one is better off listing easily reached sites first. Once the package is retrieved, its md5 checksum is computed. If that sum does not match that stored in `package-get-base' for this version -of the package, an error is signalled." t nil) +of the package, an error is signalled. + +Returns `t' upon success, the symbol `error' if the package was +successfully installed but errors occurred during initialization, or +`nil' upon error." t nil) (autoload 'package-get-package-provider "package-get" "\ Search for a package that provides SYM and return the name and @@ -1244,6 +1252,23 @@ Fetch and install the latest versions of all customized packages." t nil) ;;;*** +;;;### (autoloads (pui-list-packages pui-add-install-directory) "package-ui" "lisp/package-ui.el") + +(autoload 'pui-add-install-directory "package-ui" "\ +Add a new package binary directory to the head of `package-get-remote'. +Note that no provision is made for saving any changes made by this function. +It exists mainly as a convenience for one-time package installations from +disk." t nil) + +(autoload 'pui-list-packages "package-ui" "\ +List all packages and package information. +The package name, version, and description are displayed. From the displayed +buffer, the user can see which packages are installed, which are not, and +which are out-of-date (a newer version is available). The user can then +select packages for installation via the keyboard or mouse." t nil) + +;;;*** + ;;;### (autoloads (picture-mode) "picture" "lisp/picture.el") (autoload 'picture-mode "picture" "\ diff --git a/lisp/autoload.el b/lisp/autoload.el index a4b68da..ec70873 100644 --- a/lisp/autoload.el +++ b/lisp/autoload.el @@ -375,6 +375,8 @@ This functions refuses to update autoloads files." (let ((find-file-hooks nil)) (set-buffer (or (get-file-buffer generated-autoload-file) (find-file-noselect generated-autoload-file)))) + ;; Make sure we can scribble in it. + (setq buffer-read-only nil) ;; First delete all sections for this file. (goto-char (point-min)) (while (search-forward generate-autoload-section-header nil t) diff --git a/lisp/bytecomp.el b/lisp/bytecomp.el index 95bce46..4e0bd04 100644 --- a/lisp/bytecomp.el +++ b/lisp/bytecomp.el @@ -3125,15 +3125,15 @@ If FORM is a lambda or a macro, byte-compile it as a function." (t (byte-compile-normal-call form))))) (defun byte-compile-buffer-substring (form) - (let ((len (length form))) - ;; buffer-substring used to take exactly two args, but now takes 0-3. - ;; convert 0-2 to two args and use special bytecode operand. - ;; convert 3 args to a normal call. - (cond ((= len 1) (setq form (append form '(nil nil))) - (= len 2) (setq form (append form '(nil))))) - (cond ((= len 3) (byte-compile-two-args form)) - ((= len 4) (byte-compile-normal-call form)) - (t (byte-compile-subr-wrong-args form "0-3"))))) + ;; buffer-substring used to take exactly two args, but now takes 0-3. + ;; convert 0-2 to two args and use special bytecode operand. + ;; convert 3 args to a normal call. + (case (length (cdr form)) + (0 (byte-compile-two-args (append form '(nil nil)))) + (1 (byte-compile-two-args (append form '(nil)))) + (2 (byte-compile-two-args form)) + (3 (byte-compile-normal-call form)) + (t (byte-compile-subr-wrong-args form "0-3")))) (defun byte-compile-list (form) (let ((count (length (cdr form)))) diff --git a/lisp/cl-macs.el b/lisp/cl-macs.el index e08a165..93971ff 100644 --- a/lisp/cl-macs.el +++ b/lisp/cl-macs.el @@ -1731,6 +1731,8 @@ Example: (defsetf nth (n x) (v) (list 'setcar (list 'nthcdr n x) v))." ;; Avoid adding various face and glyph functions. (defsetf frame-selected-window (&optional f) (v) `(set-frame-selected-window ,f ,v)) +(defsetf glyph-image (glyph &optional domain) (i) + (list 'set-glyph-image glyph i domain)) (defsetf itimer-function set-itimer-function) (defsetf itimer-function-arguments set-itimer-function-arguments) (defsetf itimer-is-idle set-itimer-is-idle) diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index 630c5dc..7a573fe 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -2288,7 +2288,8 @@ Match frames with dark backgrounds") (unless (widget-get widget :custom-form) (widget-put widget :custom-form custom-face-default-form)) (let* ((symbol (widget-value widget)) - (spec (or (get symbol 'saved-face) + (spec (or (get symbol 'customized-face) + (get symbol 'saved-face) (get symbol 'face-defface-spec) ;; Attempt to construct it. (list (list t (face-custom-attributes-get diff --git a/lisp/cus-face.el b/lisp/cus-face.el index 09e7771..1660a7a 100644 --- a/lisp/cus-face.el +++ b/lisp/cus-face.el @@ -67,13 +67,17 @@ :help-echo "\ Text size (e.g. 9pt or 2mm).") custom-set-face-font-size custom-face-font-size) - (:stipple (editable-field :format "Stipple: %v" - :help-echo "Name of background bitmap file.") - set-face-stipple custom-face-stipple) (:family (editable-field :format "Font Family: %v" :help-echo "\ Name of font family to use (e.g. times).") custom-set-face-font-family custom-face-font-family) + (:background-pixmap (editable-field :format "Background pixmap: %v" + :help-echo "\ +Name of background pixmap file.") + set-face-background-pixmap custom-face-background-pixmap) + (:dim (toggle :format "%[Dim%]: %v\n" + :help-echo "Control whether the text should be dimmed.") + set-face-dim-p face-dim-p) (:bold (toggle :format "%[Bold%]: %v\n" :help-echo "Control whether a bold font should be used.") custom-set-face-bold custom-face-bold) @@ -85,7 +89,6 @@ Control whether an italic font should be used.") :help-echo "\ Control whether the text should be underlined.") set-face-underline-p face-underline-p) - ;; #### Should make it work on X (:strikethru (toggle :format "%[Strikethru%]: %v\n" :help-echo "\ Control whether the text should be strikethru.") @@ -146,6 +149,14 @@ If FRAME is nil, use the default face." (error nil))) result)) +(defsubst custom-face-get-spec (symbol) + (or (get symbol 'customized-face) + (get symbol 'saved-face) + (get symbol 'face-defface-spec) + ;; Attempt to construct it. + (list (list t (face-custom-attributes-get + symbol (selected-frame)))))) + (defun custom-set-face-bold (face value &optional frame) "Set the bold property of FACE to VALUE." (if value @@ -178,8 +189,8 @@ If FRAME is nil, use the default face." (fontobj (font-create-object font))) (font-italic-p fontobj))) -(defun custom-face-stipple (face &rest args) - "Return the name of the stipple file used for FACE." +(defun custom-face-background-pixmap (face &rest args) + "Return the name of the background pixmap file used for FACE." (let ((image (apply 'specifier-instance (face-background-pixmap face) args))) (and image @@ -215,6 +226,14 @@ If FRAME is nil, use the default face." (fontobj (font-create-object font))) (font-family fontobj))) +(defun custom-set-face-update-spec (face display plist) + "Customize the FACE for display types matching DISPLAY, merging + in the new items from PLIST" + (let ((spec (face-spec-update-all-matching (custom-face-get-spec face) + display plist))) + (put face 'customized-face spec) + (face-spec-set face spec))) + ;;; Initializing. ;;;###autoload diff --git a/lisp/custom-load.el b/lisp/custom-load.el index d4da910..6e38ac8 100644 --- a/lisp/custom-load.el +++ b/lisp/custom-load.el @@ -72,7 +72,8 @@ (custom-add-loads 'isearch '("isearch-mode")) (custom-add-loads 'font-lock-faces '("font-lock")) (custom-add-loads 'modeline '("modeline")) -(custom-add-loads 'editing '("simple" "abbrev" "fill" "mouse" "dragdrop" "cus-edit")) +(custom-add-loads 'packages '("package-get-custom")) +(custom-add-loads 'editing '("simple" "abbrev" "fill" "mouse" "cus-edit" "dragdrop")) (custom-add-loads 'matching '("simple" "isearch-mode" "hyper-apropos")) (custom-add-loads 'i18n '("cus-edit")) (custom-add-loads 'info '("toolbar-items" "info")) diff --git a/lisp/faces.el b/lisp/faces.el index 09a3e79..c847f37 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -318,7 +318,6 @@ The following symbols have predefined meanings: For valid instantiators, see `face-boolean-specifier-p'. dim Dim all text covered by this face. - Only used by faces on TTY devices. For valid instantiators, see `face-boolean-specifier-p'. blinking Blink all text covered by this face. @@ -690,12 +689,12 @@ See `set-face-property' for the semantics of the LOCALE, TAG-SET, and (set-face-property face 'highlight highlight-p locale tag-set how-to-add)) (defun face-dim-p (face &optional domain default no-fallback) - "Return t if FACE is dimmed in DOMAIN (TTY domains only). + "Return t if FACE is dimmed in DOMAIN. See `face-property-instance' for the semantics of the DOMAIN argument." (face-property-instance face 'dim domain default no-fallback)) (defun set-face-dim-p (face dim-p &optional locale tag-set how-to-add) - "Change whether FACE is dimmed in LOCALE (TTY locales only). + "Change whether FACE is dimmed in LOCALE. DIM-P is normally a face-boolean instantiator; see `face-boolean-specifier-p'. See `set-face-property' for the semantics of the LOCALE, TAG-SET, and @@ -750,9 +749,10 @@ See `face-property-instance' for the semantics of the DOMAIN argument." (if (not (valid-specifier-domain-p domain)) (error "Invalid specifier domain")) (let ((device (dfw-device domain)) - (common-props '(foreground background font display-table underline)) + (common-props '(foreground background font display-table underline + dim)) (win-props '(background-pixmap strikethru)) - (tty-props '(highlight dim blinking reverse))) + (tty-props '(highlight blinking reverse))) ;; First check the properties which are used in common between the ;; x and tty devices. Then, check those properties specific to @@ -1256,6 +1256,39 @@ If FRAME is nil, return the default frame properties." (setq default-custom-frame-properties (extract-custom-frame-properties (selected-frame)))))) +(defun face-spec-update-all-matching (spec display plist) + "Update all entries in the face spec that could match display to +have the entries from the new plist and return the new spec" + (mapcar + (lambda (e) + (let ((entries (car e)) + (options (cadr e)) + (match t) + dplist + (new-options plist) + ) + (unless (eq display t) + (mapc (lambda (arg) + (setq dplist (plist-put dplist (car arg) (cadr arg)))) + display)) + (unless (eq entries t) + (mapc (lambda (arg) + (setq match (and match (eq (cadr arg) + (plist-get + dplist (car arg) + (cadr arg)))))) + entries)) + (if (not match) + e + (while new-options + (setq options + (plist-put options (car new-options) (cadr new-options))) + (setq new-options (cddr new-options))) + (list entries options)))) + (copy-sequence spec))) + + + (defun face-spec-set-match-display (display &optional frame) "Return non-nil if DISPLAY matches FRAME. DISPLAY is part of a spec such as can be used in `defface'. diff --git a/lisp/files.el b/lisp/files.el index 591648d..2c288c3 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -976,65 +976,69 @@ If RAWFILE is non-nil, the file is read literally." ;;; (message "Symbolic link to file in buffer %s" ;;; (buffer-name linked-buf)))) (setq buf (create-file-buffer filename)) - (set-buffer-major-mode buf) - (set-buffer buf) - (erase-buffer) - (if rawfile - (condition-case () - (insert-file-contents-literally filename t) - (file-error - (when (and (file-exists-p filename) - (not (file-readable-p filename))) - (kill-buffer buf) - (signal 'file-error (list "File is not readable" filename))) - ;; Unconditionally set error - (setq error t))) - (condition-case () - (insert-file-contents filename t) - (file-error - (when (and (file-exists-p filename) - (not (file-readable-p filename))) - (kill-buffer buf) - (signal 'file-error (list "File is not readable" filename))) - ;; Run find-file-not-found-hooks until one returns non-nil. - (or (run-hook-with-args-until-success 'find-file-not-found-hooks) - ;; If they fail too, set error. - (setq error t))))) - ;; Find the file's truename, and maybe use that as visited name. - ;; automatically computed in XEmacs, unless jka-compr was used! - (unless buffer-file-truename - (setq buffer-file-truename truename)) - (setq buffer-file-number number) - ;; On VMS, we may want to remember which directory in a search list - ;; the file was found in. - (and (eq system-type 'vax-vms) - (let (logical) - (if (string-match ":" (file-name-directory filename)) - (setq logical (substring (file-name-directory filename) - 0 (match-beginning 0)))) - (not (member logical find-file-not-true-dirname-list))) - (setq buffer-file-name buffer-file-truename)) - (and find-file-use-truenames - ;; This should be in C. Put pathname abbreviations that have - ;; been explicitly requested back into the pathname. Most - ;; importantly, strip out automounter /tmp_mnt directories so - ;; that auto-save will work - (setq buffer-file-name (abbreviate-file-name buffer-file-name))) - ;; Set buffer's default directory to that of the file. - (setq default-directory (file-name-directory buffer-file-name)) - ;; Turn off backup files for certain file names. Since - ;; this is a permanent local, the major mode won't eliminate it. - (and (not (funcall backup-enable-predicate buffer-file-name)) - (progn - (make-local-variable 'backup-inhibited) - (setq backup-inhibited t))) - (if rawfile - ;; #### FSF 20.3 sets buffer-file-coding-system to - ;; `no-conversion' here. Should we copy? It also makes - ;; `find-file-literally' a local variable and sets it to t. - nil - (after-find-file error (not nowarn)) - (setq buf (current-buffer))))) + ;; Catch various signals, such as QUIT, and kill the buffer + ;; in that case. + (condition-case data + (progn + (set-buffer-major-mode buf) + (set-buffer buf) + (erase-buffer) + (condition-case () + (if rawfile + (insert-file-contents-literally filename t) + (insert-file-contents filename t)) + (file-error + (when (and (file-exists-p filename) + (not (file-readable-p filename))) + (signal 'file-error (list "File is not readable" filename))) + (if rawfile + ;; Unconditionally set error + (setq error t) + (or + ;; Run find-file-not-found-hooks until one returns non-nil. + (run-hook-with-args-until-success 'find-file-not-found-hooks) + ;; If they fail too, set error. + (setq error t))))) + ;; Find the file's truename, and maybe use that as visited name. + ;; automatically computed in XEmacs, unless jka-compr was used! + (unless buffer-file-truename + (setq buffer-file-truename truename)) + (setq buffer-file-number number) + ;; On VMS, we may want to remember which directory in + ;; a search list the file was found in. + (and (eq system-type 'vax-vms) + (let (logical) + (if (string-match ":" (file-name-directory filename)) + (setq logical (substring (file-name-directory filename) + 0 (match-beginning 0)))) + (not (member logical find-file-not-true-dirname-list))) + (setq buffer-file-name buffer-file-truename)) + (and find-file-use-truenames + ;; This should be in C. Put pathname + ;; abbreviations that have been explicitly + ;; requested back into the pathname. Most + ;; importantly, strip out automounter /tmp_mnt + ;; directories so that auto-save will work + (setq buffer-file-name (abbreviate-file-name buffer-file-name))) + ;; Set buffer's default directory to that of the file. + (setq default-directory (file-name-directory buffer-file-name)) + ;; Turn off backup files for certain file names. Since + ;; this is a permanent local, the major mode won't eliminate it. + (and (not (funcall backup-enable-predicate buffer-file-name)) + (progn + (make-local-variable 'backup-inhibited) + (setq backup-inhibited t))) + (if rawfile + ;; #### FSF 20.3 sets buffer-file-coding-system to + ;; `no-conversion' here. Should we copy? It also + ;; makes `find-file-literally' a local variable + ;; and sets it to t. + nil + (after-find-file error (not nowarn)) + (setq buf (current-buffer)))) + (t + (kill-buffer buf) + (signal (car data) (cdr data)))))) buf))) ;; FSF has `insert-file-literally' and `find-file-literally' here. @@ -1154,7 +1158,7 @@ run `normal-mode' explicitly." ("\\.[fF]90\\'" . f90-mode) ;;; Less common extensions come here ;;; so more common ones above are found faster. - ("\\.p[lm]\\'" . perl-mode) + ("\\.\\([pP][Llm]\\|al\\)\\'" . perl-mode) ("\\.py\\'" . python-mode) ("\\.texi\\(nfo\\)?\\'" . texinfo-mode) ("\\.ad[abs]\\'" . ada-mode) diff --git a/lisp/find-paths.el b/lisp/find-paths.el index 9685d6e..8ecbcc1 100644 --- a/lisp/find-paths.el +++ b/lisp/find-paths.el @@ -62,7 +62,7 @@ from the search." (let ((directory (file-name-as-directory (expand-file-name (car directories))))) - (if (file-directory-p directory) + (if (paths-file-readable-directory-p directory) (let ((raw-entries (if (equal 0 max-depth) '() @@ -88,6 +88,11 @@ from the search." (setq directories (cdr directories))) path)) +(defun paths-file-readable-directory-p (filename) + "Check if filename is a readable directory." + (and (file-directory-p filename) + (file-readable-p filename))) + (defun paths-find-recursive-load-path (directories &optional max-depth) "Construct a recursive load path underneath DIRECTORIES." (paths-find-recursive-path directories @@ -97,13 +102,13 @@ from the search." "Check if DIRECTORY is a plausible installation root for XEmacs." (or ;; installed - (file-directory-p (paths-construct-path (list directory - "lib" - emacs-program-name))) + (paths-file-readable-directory-p (paths-construct-path (list directory + "lib" + emacs-program-name))) ;; in-place or windows-nt (and - (file-directory-p (paths-construct-path (list directory "lisp"))) - (file-directory-p (paths-construct-path (list directory "etc")))))) + (paths-file-readable-directory-p (paths-construct-path (list directory "lisp"))) + (paths-file-readable-directory-p (paths-construct-path (list directory "etc")))))) (defun paths-chase-symlink (file-name) "Chase a symlink until the bitter end." @@ -168,19 +173,19 @@ the directory." (let ((preferred-value (or (and envvar (getenv envvar)) default))) (if (and preferred-value - (file-directory-p preferred-value)) + (paths-file-readable-directory-p preferred-value)) (file-name-as-directory preferred-value) (catch 'gotcha (while roots (let* ((root (car roots)) ;; installed (path (paths-construct-emacs-directory root suffix base))) - (if (file-directory-p path) + (if (paths-file-readable-directory-p path) (throw 'gotcha path) ;; in-place (if (null keep-suffix) (let ((path (paths-construct-emacs-directory root "" base))) - (if (file-directory-p path) + (if (paths-file-readable-directory-p path) (throw 'gotcha path)))))) (setq roots (cdr roots))) nil)))) @@ -230,7 +235,7 @@ If ENFORCE-VERSION is non-nil, the directory must contain the XEmacs version." "Return the directories among DIRECTORIES." (let ((reverse-directories '())) (while directories - (if (file-directory-p (car directories)) + (if (paths-file-readable-directory-p (car directories)) (setq reverse-directories (cons (car directories) reverse-directories))) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 91446fd..b587a78 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1073,8 +1073,9 @@ This can take a while for large buffers." ;; region as fontified; otherwise, the same error might get signaled ;; after every command. (unwind-protect - ;; buffer may be deleted. - (if (buffer-live-p (extent-object font-lock-old-extent)) + ;; buffer/extent may be deleted. + (if (and (extent-live-p font-lock-old-extent) + (buffer-live-p (extent-object font-lock-old-extent))) (save-excursion (set-buffer (extent-object font-lock-old-extent)) (font-lock-after-change-function-1 diff --git a/lisp/font.el b/lisp/font.el index eed2710..ecaf1c9 100644 --- a/lisp/font.el +++ b/lisp/font.el @@ -776,7 +776,7 @@ for use in the 'weight' field of an X font string.") ;;; A maximal mswindows font spec looks like: ;;; Courier New:Bold Italic:10:underline strikeout:western ;;; Missing parts of the font spec should be filled in with these values: -;;; Courier New:Normal:10::western +;;; Courier New:Regular:10::western ;; "^[a-zA-Z ]+:[a-zA-Z ]*:[0-9]+:[a-zA-Z ]*:[a-zA-Z 0-9]*$" (defvar font-mswindows-font-regexp (let diff --git a/lisp/help.el b/lisp/help.el index 5f43c0c..8590638 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -1416,4 +1416,25 @@ after the listing is made.)" (if cmd (princ " "))))) (terpri)))))) +;; Stop gap for 21.0 untill we do help-char etc properly. +(defun help-keymap-with-help-key (keymap form) + "Return a copy of KEYMAP with an help-key binding according to help-char + invoking FORM like help-form. An existing binding is not overridden. + If FORM is nil then no binding is made." + (let ((map (copy-keymap keymap)) + (key (if (characterp help-char) + (vector (character-to-event help-char)) + help-char))) + (when (and form key (not (lookup-key map key))) + (define-key map key + `(lambda () (interactive) (help-print-help-form ,form)))) + map)) + +(defun help-print-help-form (form) + (let ((string (eval form))) + (if (stringp string) + (with-displaying-help-buffer + (insert string))))) + + ;;; help.el ends here diff --git a/lisp/info.el b/lisp/info.el index def6f7b..eb62c6f 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -2614,39 +2614,20 @@ At end of the node's text, moves to the next node." (if (/= click-count 2) ;; Return nil so any other hooks are performed. nil - (let* ((x (event-x-pixel event)) - (y (event-y-pixel event)) - (w (window-pixel-width (event-window event))) - (h (window-pixel-height (event-window event))) - (w/3 (/ w 3)) - (w/2 (/ w 2)) - (h/4 (/ h 4))) + (let* ((fw (face-width 'default)) + (fh (face-height 'default)) + (x (/ (event-x-pixel event) fw)) + (y (/ (event-y-pixel event) fw)) + (w (/ (window-pixel-width (event-window event)) fw)) + (h (/ (window-pixel-height (event-window event)) fh)) + (bx 3) + (by 2)) (cond - ;; In the top 1/4 and inside the middle 1/3 - ((and (<= y h/4) - (and (>= x w/3) (<= x (+ w/3 w/3)))) - (Info-up) - t) - ;; In the bottom 1/4 and inside the middle 1/3 - ((and (>= y (+ h/4 h/4 h/4)) - (and (>= x w/3) (<= x (+ w/3 w/3)))) - (Info-nth-menu-item 1) - t) - ;; In the lower 3/4 and the right 1/2 - ;; OR in the upper 1/4 and the right 1/3 - ((or (and (>= y h/4) (>= x w/2)) - (and (< y h/4) (>= x (+ w/3 w/3)))) - (Info-next) - t) - ;; In the lower 3/4 and the left 1/2 - ;; OR in the upper 1/4 and the left 1/3 - ((or (and (>= y h/4) (< x w/2)) - (and (< y h/4) (<= x w/3))) - (Info-prev) - t) - ;; This shouldn't happen. - (t - (error "event out of bounds: %s %s" x y)))))) + ((<= y by) (Info-up) t) + ((>= y (- h by)) (Info-nth-menu-item 1) t) + ((<= x bx) (Info-prev) t) + ((>= x (- w bx)) (Info-next) t) + (t nil))))) (defvar Info-mode-map nil "Keymap containing Info commands.") @@ -2742,10 +2723,16 @@ b Go to beginning of node. Meta-> Go to end of node. TAB Go to next cross-reference. Meta-TAB Go to previous ref. Mouse commands: -Left Button Set point. +Left Button Set point (usual text-mode functionality) Middle Button Click on a highlighted node reference to go to it. Right Button Pop up a menu of applicable Info commands. +Left Button Double Click in window edges: + Top edge: Go up to the parent node, like `u'. + Left edge: Go to the previous node, like `p'. + Right edge: Go to the next node, like `n'. + Bottom edge: Follow first menu item, like `1'. + Advanced commands: g Move to node, file, or annotation tag specified by name. Examples: `g Rectangles' `g (Emacs)Rectangles' `g Emacs'. diff --git a/lisp/isearch-mode.el b/lisp/isearch-mode.el index 1abd4e0..c1f7ef5 100644 --- a/lisp/isearch-mode.el +++ b/lisp/isearch-mode.el @@ -459,10 +459,9 @@ is treated as a regexp. See \\[isearch-forward] for more info." isearch-opoint (point) isearch-window-configuration (current-window-configuration) - ;; #### - don't do this statically: isearch-mode must be FIRST in - ;; the minor-mode-map-alist -- Stig - minor-mode-map-alist (cons (cons 'isearch-mode isearch-mode-map) - minor-mode-map-alist) + ;; #### Should we remember the old value of + ;; overriding-local-map? + overriding-local-map isearch-mode-map isearch-selected-frame (selected-frame) isearch-mode (gettext " Isearch") @@ -541,8 +540,9 @@ is treated as a regexp. See \\[isearch-forward] for more info." ;; in the buffer we frobbed them in. But only if the buffer ;; is still alive. (set-buffer isearch-buffer) - (setq minor-mode-map-alist (delq (assoc 'isearch-mode minor-mode-map-alist) - minor-mode-map-alist)) + ;; #### Should we restore the old value of + ;; overriding-local-map? + (setq overriding-local-map nil) ;; Use remove-hook instead of just setting it to our saved value ;; in case some process filter has created a buffer and modified ;; the pre-command-hook in that buffer... yeah, this is obscure, @@ -936,6 +936,20 @@ backwards." (interactive) (isearch-yank (x-get-clipboard))) +(defun isearch-fix-case () + (if (and isearch-case-fold-search search-caps-disable-folding) + (setq isearch-case-fold-search (isearch-no-upper-case-p isearch-string))) + (setq isearch-mode (if case-fold-search + (if isearch-case-fold-search + " Isearch" ;As God Intended Mode + " ISeARch") ;Warn about evil case via StuDLYcAps. + "Isearch" +; (if isearch-case-fold-search +; " isearch" ;Presumably case-sensitive losers +; ;will notice this 1-char difference. +; " Isearch") ;Weenie mode. + ))) + (defun isearch-search-and-update () ;; Do the search and update the display. (if (and (not isearch-success) @@ -951,12 +965,15 @@ backwards." ;; long as the match does not extend past search origin. (if (and (not isearch-forward) (not isearch-adjusted) (condition-case () - (looking-at (if isearch-regexp isearch-string - (regexp-quote isearch-string))) + (progn + (isearch-fix-case) + (let ((case-fold-search isearch-case-fold-search)) + (looking-at (if isearch-regexp isearch-string + (regexp-quote isearch-string))))) (error nil)) - (or isearch-yank-flag - (<= (match-end 0) - (min isearch-opoint isearch-barrier)))) + (or isearch-yank-flag + (<= (match-end 0) + (min isearch-opoint isearch-barrier)))) (setq isearch-success t isearch-invalid-regexp nil isearch-other-end (match-end 0)) @@ -1460,12 +1477,9 @@ currently matches the search-string.") (if (null isearch-highlight) nil ;; make sure isearch-extent is in the current buffer - (cond ((not (extentp isearch-extent)) - (isearch-make-extent begin end)) - ((not (eq (extent-object isearch-extent) (current-buffer))) - (delete-extent isearch-extent) - (isearch-make-extent begin end))) - (set-extent-endpoints isearch-extent begin end))) + (or (extentp isearch-extent) + (isearch-make-extent begin end)) + (set-extent-endpoints isearch-extent begin end (current-buffer)))) (defun isearch-dehighlight (totally) (if (and isearch-highlight isearch-extent) @@ -1485,19 +1499,7 @@ currently matches the search-string.") (defun isearch-search () ;; Do the search with the current search string. (isearch-message nil t) - (if (and isearch-case-fold-search search-caps-disable-folding) - (setq isearch-case-fold-search (isearch-no-upper-case-p isearch-string))) - - (setq isearch-mode (if case-fold-search - (if isearch-case-fold-search - " Isearch" ;As God Intended Mode - " ISeARch") ;Warn about evil case via StuDLYcAps. - "Isearch" -; (if isearch-case-fold-search -; " isearch" ;Presumably case-sensitive losers -; ;will notice this 1-char difference. -; " Isearch") ;Weenie mode. - )) + (isearch-fix-case) (condition-case lossage (let ((inhibit-quit nil) (case-fold-search isearch-case-fold-search)) diff --git a/lisp/keydefs.el b/lisp/keydefs.el index 63b6c2d..947ce34 100644 --- a/lisp/keydefs.el +++ b/lisp/keydefs.el @@ -452,11 +452,11 @@ Keymap for characters following C-c.") - - - (define-key global-map "\M-%" 'query-replace) +;; FSF v20 binding +(define-key global-map [(control meta %)] 'query-replace-regexp) + ; autoloaded ;(define-key global-map "\C-x4a" 'add-change-log-entry-other-window) diff --git a/lisp/lisp-mode.el b/lisp/lisp-mode.el index d193288..e5e97ec 100644 --- a/lisp/lisp-mode.el +++ b/lisp/lisp-mode.el @@ -766,6 +766,7 @@ of the start of the containing expression." (put 'unwind-protect 'lisp-indent-function 1) (put 'save-current-buffer 'lisp-indent-function 0) (put 'with-current-buffer 'lisp-indent-function 1) +(put 'with-string-as-buffer-contents 'lisp-indent-function 1) (put 'with-temp-file 'lisp-indent-function 1) (put 'with-temp-buffer 'lisp-indent-function 0) (put 'with-output-to-string 'lisp-indent-function 0) diff --git a/lisp/list-mode.el b/lisp/list-mode.el index 8789a14..b3603e5 100644 --- a/lisp/list-mode.el +++ b/lisp/list-mode.el @@ -284,6 +284,7 @@ If `completion-highlight-first-word-only' is non-nil, then only the start :user-data :reference-buffer (:help-string completion-default-help-string) + (:completion-string "Possible completions are:") :window-width) () (let ((old-buffer (current-buffer)) @@ -341,7 +342,8 @@ If `completion-highlight-first-word-only' is non-nil, then only the start (if (/= (% count cols) 0) ; want ceiling... (1+ (/ count cols)) (/ count cols))))))) - (princ (gettext "Possible completions are:")) + (if (stringp cl-completion-string) + (princ (gettext cl-completion-string))) (let ((tail completions) (r 0) (regexp-string diff --git a/lisp/loadup.el b/lisp/loadup.el index 68063a8..35cc183 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -64,7 +64,6 @@ ;; the package path. ;; #### This code is duplicated in two other places. (let ((temp-path (expand-file-name "." (car load-path)))) - (setq source-directory temp-path) (setq load-path (nconc (mapcar #'(lambda (i) (concat i "/")) (directory-files temp-path t "^[^-.]" @@ -183,19 +182,16 @@ (dump-emacs (if (featurep 'infodock) "infodock" "xemacs") "temacs") (kill-emacs)) +;; Avoid error if user loads some more libraries now. +(setq purify-flag nil) + (when (member "run-temacs" command-line-args) (message "\nBootstrapping from temacs...") - (setq purify-flag nil) - (setq inhibit-early-packages t) - (setq inhibit-autoloads t) ;; Remove all args up to and including "run-temacs" (apply #'run-emacs-from-temacs (cdr (member "run-temacs" command-line-args))) ;; run-emacs-from-temacs doesn't actually return anyway. (kill-emacs)) -;; Avoid error if user loads some more libraries now. -(setq purify-flag nil) - ;; XEmacs change ;; If you are using 'recompile', then you should have used -l loadup-el.el ;; so that the .el files always get loaded (the .elc files may be out-of- diff --git a/lisp/make-docfile.el b/lisp/make-docfile.el index 1f56feb..9157467 100644 --- a/lisp/make-docfile.el +++ b/lisp/make-docfile.el @@ -81,8 +81,6 @@ ;; Then process the autoloads (setq autoload-file-name "auto-autoloads.elc") -(setq source-directory (concat default-directory "../lisp")) -;; (print (concat "Source directory: " source-directory)) (load "find-paths.el") (load "packages.el") (load "setup-paths.el") diff --git a/lisp/menubar-items.el b/lisp/menubar-items.el index a096e9d..a281501 100644 --- a/lisp/menubar-items.el +++ b/lisp/menubar-items.el @@ -232,6 +232,7 @@ ["Set..." customize-customized] ["Apropos..." customize-apropos] ["Browse..." customize-browse] + ["List Packages" pui-list-packages] ["Update Packages" package-get-custom]) ("Editing Options" ["Overstrike" @@ -800,10 +801,10 @@ (fboundp 'browse-url-grail))] ) "-----" - ["Browse Faces..." (customize-face nil)] + ["Edit Faces..." (customize-face nil)] ("Font" :filter font-menu-family-constructor) ("Size" :filter font-menu-size-constructor) - ("Weight" :filter font-menu-weight-constructor) +; ("Weight" :filter font-menu-weight-constructor) "-----" ["Save Options" customize-save-customized] ) diff --git a/lisp/minibuf.el b/lisp/minibuf.el index b7b90e0..1217fe6 100644 --- a/lisp/minibuf.el +++ b/lisp/minibuf.el @@ -243,6 +243,7 @@ in `substitute-in-file-name'." (delete-region (point-min) (point))) (insert ?~)) + (defvar read-file-name-map (let ((map (make-sparse-keymap 'read-file-name-map))) (set-keymap-parents map (list minibuffer-local-completion-map)) @@ -447,12 +448,14 @@ See also the variable completion-highlight-first-word-only for control over (insert initial-contents) (setq current-minibuffer-contents initial-contents current-minibuffer-point (point)))) - (use-local-map (or keymap minibuffer-local-map)) + (use-local-map (help-keymap-with-help-key + (or keymap minibuffer-local-map) + minibuffer-help-form)) (let ((mouse-grabbed-buffer (and minibuffer-smart-completion-tracking-behavior (current-buffer))) (current-prefix-arg current-prefix-arg) - (help-form minibuffer-help-form) +;; (help-form minibuffer-help-form) (minibuffer-history-variable (cond ((not _history_) 'minibuffer-history) ((consp _history_) @@ -1452,6 +1455,7 @@ only existing buffer names are allowed." (read-from-minibuffer prompt (if num (prin1-to-string num)) nil t t)) ;no history + (input-error nil) (invalid-read-syntax nil) (end-of-file nil))) (or (funcall pred num) (beep))) @@ -1669,7 +1673,7 @@ DIR defaults to current buffer's directory default." 'read-directory-name-internal)) -;; Environment-variable completion hack +;; Environment-variable and ~username completion hack (defun read-file-name-internal-1 (string dir action completer) (if (not (string-match "\\([^$]\\|\\`\\)\\(\\$\\$\\)*\\$\\([A-Za-z0-9_]*\\|{[^}]*\\)\\'" @@ -1677,14 +1681,38 @@ DIR defaults to current buffer's directory default." ;; Not doing environment-variable completion hack (let* ((orig (if (equal string "") nil string)) (sstring (if orig (substitute-in-file-name string) string)) - (specdir (if orig (file-name-directory sstring) nil))) - (funcall completer - action - orig - sstring - specdir - (if specdir (expand-file-name specdir dir) dir) - (if orig (file-name-nondirectory sstring) string))) + (specdir (if orig (file-name-directory sstring) nil)) + (name (if orig (file-name-nondirectory sstring) string)) + (direct (if specdir (expand-file-name specdir dir) dir))) + ;; ~username completion + (if (and (fboundp 'user-name-completion-1) + (string-match "^[~]" name)) + (let ((user (substring name 1))) + (cond ((eq action 'lambda) + (file-directory-p name)) + ((eq action 't) + ;; all completions + (mapcar #'(lambda (p) (concat "~" p)) + (user-name-all-completions user))) + (t;; 'nil + ;; complete + (let* ((val+uniq (user-name-completion-1 user)) + (val (car val+uniq)) + (uniq (cdr val+uniq))) + (cond ((stringp val) + (if uniq + (file-name-as-directory (concat "~" val)) + (concat "~" val))) + ((eq val t) + (file-name-as-directory name)) + (t nil)))))) + (funcall completer + action + orig + sstring + specdir + direct + name))) ;; An odd number of trailing $'s (let* ((start (match-beginning 3)) (env (substring string diff --git a/lisp/msw-faces.el b/lisp/msw-faces.el index c393bdf..b2e52f4 100644 --- a/lisp/msw-faces.el +++ b/lisp/msw-faces.el @@ -26,15 +26,14 @@ ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. -;; This file does the magic to parse mswindows font names, and make sure that the -;; default and modeline attributes of new frames are specified enough. +;; This file does the magic to parse mswindows font names, and make sure that +;; the default and modeline attributes of new frames are specified enough. -;;; ensure that the default face has some reasonable fallbacks if nothing -;;; else is specified. +;;; Force creation of the default face font so that if it fails we get an +;;; error now instead of a crash at frame creation. (defun mswindows-init-device-faces (device) - (set-face-font 'default - '((mswindows default) . "Courier New:Regular:10") 'global) - ) + (unless (face-font-instance 'default device) + (error "Can't find a suitable default font"))) (defun mswindows-init-frame-faces (frame) @@ -48,12 +47,12 @@ ;;; A minimal mswindows font spec looks like: ;;; Courier New ;;; A maximal mswindows font spec looks like: -;;; Courier New:Bold Italic:10:underline strikeout:western +;;; Courier New:Bold Italic:10:underline strikeout:Western ;;; Missing parts of the font spec should be filled in with these values: -;;; Courier New:Normal:10::western +;;; Courier New:Regular:10::Western (defun mswindows-font-canonicalize-name (font) - "Given a mswindows font or font specification, this returns its -specification in canonical form." + "Given a mswindows font or font name, this returns its name in +canonical form." (if (or (font-instance-p font) (stringp font)) (let ((name (if (font-instance-p font) @@ -63,14 +62,14 @@ specification in canonical form." "^[a-zA-Z ]+:[a-zA-Z ]*:[0-9]+:[a-zA-Z ]*:[a-zA-Z 0-9]*$" name) name) ((string-match "^[a-zA-Z ]+:[a-zA-Z ]*:[0-9]+:[a-zA-Z ]*$" - name) (concat name ":western")) + name) (concat name ":Western")) ((string-match "^[a-zA-Z ]+:[a-zA-Z ]*:[0-9]+$" name) - (concat name "::western")) + (concat name "::Western")) ((string-match "^[a-zA-Z ]+:[a-zA-Z ]*$" name) - (concat name ":10::western")) + (concat name ":10::Western")) ((string-match "^[a-zA-Z ]+$" name) - (concat name ":Normal:10::western")) - (t "Courier New:Normal:10::western"))))) + (concat name ":Regular:10::Western")) + (t "Courier New:Regular:10::Western"))))) (defun mswindows-make-font-bold (font &optional device) "Given a mswindows font specification, this attempts to make a bold font. @@ -88,7 +87,7 @@ If it fails, it returns nil." ; makes it the same width (maybe at the expense of making it one pixel shorter) (if (font-instance-p newfont) (if (> (font-instance-width newfont) oldwidth) - (mswindows-find-smaller-font newfont) + (mswindows-find-smaller-font newfont device) newfont)))))) (defun mswindows-make-font-unbold (font &optional device) @@ -99,7 +98,7 @@ If it fails, it returns nil." (string-match "^[a-zA-Z ]+:\\([a-zA-Z ]*\\):" name) (make-font-instance (concat (substring name 0 (match-beginning 1)) - "Normal" (substring name (match-end 1))) + "Regular" (substring name (match-end 1))) device t)))) (defun mswindows-make-font-italic (font &optional device) @@ -121,7 +120,7 @@ font. If it fails, it returns nil." (string-match "^[a-zA-Z ]+:\\([a-zA-Z ]*\\):" name) (make-font-instance (concat (substring name 0 (match-beginning 1)) - "Normal" (substring name (match-end 1))) + "Regular" (substring name (match-end 1))) device t)))) (defun mswindows-make-font-bold-italic (font &optional device) @@ -140,7 +139,7 @@ font. If it fails, it returns nil." ; makes it the same width (maybe at the expense of making it one pixel shorter) (if (font-instance-p newfont) (if (> (font-instance-width newfont) oldwidth) - (mswindows-find-smaller-font newfont) + (mswindows-find-smaller-font newfont device) newfont)))))) (defun mswindows-find-smaller-font (font &optional device) diff --git a/lisp/package-admin.el b/lisp/package-admin.el index 8a9d4c1..7099173 100644 --- a/lisp/package-admin.el +++ b/lisp/package-admin.el @@ -38,6 +38,70 @@ (defvar package-admin-temp-buffer "*Package Output*" "Temporary buffer where output of backend commands is saved.") +(defvar package-admin-install-function 'package-admin-default-install-function + "The function to call to install a package. +Three args are passed: FILENAME PKG-DIR BUF +Install package FILENAME into directory PKG-DIR, with any messages output +to buffer BUF.") + +(defvar package-admin-error-messages '( + "No space left on device" + "No such file or directory" + "Filename too long" + "Read-only file system" + "File too large" + "Too many open files" + "Not enough space" + "Permission denied" + "Input/output error" + "Out of memory" + "Unable to create directory" + "Directory checksum error" + "Cannot exclusively open file" + "corrupted file" + "incomplete .* tree" + "Bad table" + "corrupt input" + "invalid compressed data" + "too many leaves in Huffman tree" + "not a valid zip file" + "first entry not deflated or stored" + "encrypted file --" + "unexpected end of file" + ) + "Regular expressions of possible error messages. +After each package extraction, the `package-admin-temp-buffer' buffer is +scanned for these messages. An error code is returned if one of these are +found. + +This is awful, but it exists because error return codes aren't reliable +under MS Windows.") + +(defvar package-admin-tar-filename-regexps + '( + ;; GNU tar: + ;; drwxrwxr-x john/doe 123 1997-02-18 15:48 pathname + "\\S-+\\s-+[-a-z0-9_/]+\\s-+[0-9]+\\s-+[-0-9]+\\s-+[0-9:]+\\s-+\\(\\S-.*\\)" + ;; HP-UX & SunOS tar: + ;; rwxrwxr-x 501/501 123 Feb 18 15:46 1997 pathname + ;; Solaris tar (phooey!): + ;; rwxrwxr-x501/501 123 Feb 18 15:46 1997 pathname + ;; AIX tar: + ;; -rw-r--r-- 147 1019 32919 Mar 26 12:00:09 1992 pathname + "\\S-+\\s-*[-a-z0-9_]+[/ ][-a-z0-9_]+\\s-+[0-9]+\\s-+[a-z][a-z][a-z]\\s-+[0-9]+\\s-+[0-9:]+\\s-+[0-9]+\\s-+\\(\\S-.*\\)" + + ;; djtar: + ;; drwx Aug 31 02:01:41 1998 123 pathname + "\\S-+\\s-+[a-z][a-z][a-z]\\s-+[0-9]+\\s-+[0-9:]+\\s-+[0-9]+\\s-+[0-9]+\\s-+\\(\\S-.*\\)" + + ) + "List of regexps to use to search for tar filenames. +Note that \"\\(\" and \"\\)\" must be used to delimit the pathname (as +match #1). Don't put \"^\" to match the beginning of the line; this +is already implicit, as `looking-at' is used. Filenames can, +unfortunately, contain spaces, so be careful in constructing any +regexps.") + ;;;###autoload (defun package-admin-add-single-file-package (file destdir &optional pkg-dir) "Install a single file Lisp package into XEmacs package hierarchy. @@ -57,23 +121,356 @@ The optional `pkg-dir' can be used to override the default package hierarchy ;; rest of command line follows package-admin-xemacs file destination))) -;;;###autoload -(defun package-admin-add-binary-package (file &optional pkg-dir) - "Install a pre-bytecompiled XEmacs package into package hierarchy." - (interactive "fPackage tarball: ") +(defun package-admin-install-function-mswindows (file pkg-dir buf) + "Install function for mswindows" + (let ( (default-directory pkg-dir) ) + (call-process "djtar" nil buf t "-x" file) + )) + +(defun package-admin-default-install-function (file pkg-dir buf) + "Default function to install a package. +Install package FILENAME into directory PKG-DIR, with any messages output +to buffer BUF." + (let (filename) + (setq filename (expand-file-name file pkg-dir)) + ;; Don't assume GNU tar. + (if (shell-command (concat "gunzip -c " filename " | tar xvf -") buf) + 0 + 1) + )) + +; (call-process "add-big-package.sh" +; nil +; buf +; t +; ;; rest of command line follows +; package-admin-xemacs file pkg-dir)) + +(defun package-admin-get-install-dir (pkg-dir) (when (null pkg-dir) (when (or (not (listp late-packages)) (not late-packages)) (error "No package path")) (setq pkg-dir (car (last late-packages)))) + pkg-dir + ) - (let ((buf (get-buffer-create package-admin-temp-buffer))) - (call-process "add-big-package.sh" - nil - buf - t - ;; rest of command line follows - package-admin-xemacs file pkg-dir))) +(defun package-admin-get-manifest-file (pkg-topdir package) + "Return the name of the MANIFEST file for package PACKAGE. +Note that PACKAGE is a symbol, and not a string." + (let (dir) + (setq dir (expand-file-name "pkginfo" pkg-topdir)) + (expand-file-name (concat "MANIFEST." (symbol-name package)) dir) + )) + +(defun package-admin-check-manifest (pkg-outbuf pkg-topdir) + "Check for a MANIFEST. file in the package distribution. +If it doesn't exist, create and write one. +PKG-OUTBUF is the buffer that holds the output from `tar', and PKG-TOPDIR +is the top-level directory under which the package was installed." + (let ( (manifest-buf " *pkg-manifest*") + old-case-fold-search regexp package-name pathname regexps) + ;; Save and restore the case-fold-search status. + ;; We do this in case we have to screw with it (as it the case of + ;; case-insensitive filesystems such as MS Windows). + (setq old-case-fold-search case-fold-search) + (unwind-protect + (save-excursion ;; Probably redundant. + (set-buffer (get-buffer pkg-outbuf)) ;; Probably already the + ;; current buffer. + (goto-char (point-min)) + + ;; Make filenames case-insensitive, if necessary + (if (eq system-type 'windows-nt) + (setq case-fold-search t)) + + ;; We really should compute the regexp. + ;; However, directory-sep-char is currently broken, but we need + ;; functional code *NOW*. + (setq regexp "\\bpkginfo[\\/]MANIFEST\\...*") + + ;; Look for the manifest. + (if (not (re-search-forward regexp nil t)) + (progn + ;; We didn't find a manifest. Make one. + + ;; Yuk. We weren't passed the package name, and so we have + ;; to dig for it. Look for it as the subdirectory name below + ;; "lisp", "man", "info", or "etc". + ;; Here, we don't use a single regexp because we want to search + ;; the directories for a package name in a particular order. + ;; The problem is that packages could have directories like + ;; "etc/sounds/" or "etc/photos/" and we don't want to get + ;; these confused with the actual package name (although, in + ;; the case of "etc/sounds/", it's probably correct). + (if (catch 'done + (let ( (dirs '("lisp" "info" "man" "etc")) rexp) + (while dirs + (setq rexp (concat "\\b" (car dirs) + "[\\/]\\([^\\/]+\\)[\//]")) + (if (re-search-forward rexp nil t) + (throw 'done t)) + (setq dirs (cdr dirs)) + ))) + (progn + (setq package-name (buffer-substring (match-beginning 1) + (match-end 1))) + + ;; Get and erase the manifest buffer + (setq manifest-buf (get-buffer-create manifest-buf)) + (buffer-disable-undo manifest-buf) + (erase-buffer manifest-buf) + + ;; Now, scan through the output buffer, looking for + ;; file and directory names. + (goto-char (point-min)) + ;; for each line ... + (while (< (point) (point-max)) + (beginning-of-line) + (setq pathname nil) + + ;; scan through the regexps, looking for a pathname + (if (catch 'found-path + (setq regexps package-admin-tar-filename-regexps) + (while regexps + (if (looking-at (car regexps)) + (progn + (setq pathname + (buffer-substring + (match-beginning 1) + (match-end 1))) + (throw 'found-path t) + )) + (setq regexps (cdr regexps)) + ) + ) + (progn + ;; found a pathname -- add it to the manifest + ;; buffer + (save-excursion + (set-buffer manifest-buf) + (goto-char (point-max)) + (insert pathname "\n") + ) + )) + (forward-line 1) + ) + + ;; Processed all lines. + ;; Now, create the file, pkginfo/MANIFEST. + + ;; We use `expand-file-name' instead of `concat', + ;; for portability. + (setq pathname (expand-file-name "pkginfo" + pkg-topdir)) + ;; Create pkginfo, if necessary + (if (not (file-directory-p pathname)) + (make-directory pathname)) + (setq pathname (expand-file-name + (concat "MANIFEST." package-name) + pathname)) + (save-excursion + (set-buffer manifest-buf) + ;; Put the files in sorted order + (sort-lines nil (point-min) (point-max)) + ;; Write the file. + ;; Note that using `write-region' *BYPASSES* any check + ;; to see if XEmacs is currently editing/visiting the + ;; file. + (write-region (point-min) (point-max) pathname) + ) + (kill-buffer manifest-buf) + ) + (progn + ;; We can't determine the package name from an extracted + ;; file in the tar output buffer. + )) + )) + ) + ;; Restore old case-fold-search status + (setq case-fold-search old-case-fold-search)) + )) + +;;;###autoload +(defun package-admin-add-binary-package (file &optional pkg-dir) + "Install a pre-bytecompiled XEmacs package into package hierarchy." + (interactive "fPackage tarball: ") + (let ((buf (get-buffer-create package-admin-temp-buffer)) + (status 1) + start err-list + ) + (setq pkg-dir (package-admin-get-install-dir pkg-dir)) + ;; Insure that the current directory doesn't change + (save-excursion + (set-buffer buf) + (setq default-directory pkg-dir) + (setq case-fold-search t) + (buffer-disable-undo) + (goto-char (setq start (point-max))) + (if (= 0 (setq status (funcall package-admin-install-function + file pkg-dir buf))) + (progn + ;; First, check for errors. + ;; We can't necessarily rely upon process error codes. + (catch 'done + (goto-char start) + (setq err-list package-admin-error-messages) + (while err-list + (if (re-search-forward (car err-list) nil t) + (progn + (setq status 1) + (throw 'done nil) + )) + (setq err-list (cdr err-list)) + ) + ) + ;; Make sure that the MANIFEST file exists + (package-admin-check-manifest buf pkg-dir) + )) + ) + status + )) + +(defun package-admin-rmtree (directory) + "Delete a directory and all of its contents, recursively. +This is a feeble attempt at making a portable rmdir." + (let ( (orig-default-directory default-directory) files dirs dir) + (unwind-protect + (progn + (setq directory (file-name-as-directory directory)) + (setq files (directory-files directory nil nil nil t)) + (setq dirs (directory-files directory nil nil nil 'dirs)) + (while dirs + (setq dir (car dirs)) + (if (file-symlink-p dir) ;; just in case, handle symlinks + (delete-file dir) + (if (not (or (string-equal dir ".") (string-equal dir ".."))) + (package-admin-rmtree (expand-file-name dir directory)))) + (setq dirs (cdr dirs)) + ) + (setq default-directory directory) + (condition-case err + (progn + (while files + (delete-file (car files)) + (setq files (cdr files)) + ) + (delete-directory directory) + ) + (file-error + (message "%s: %s: \"%s\"" (nth 1 err) (nth 2 err) (nth 3 err))) + ) + ) + (progn + (setq default-directory orig-default-directory) + )) + )) + +(defun package-admin-get-lispdir (pkg-topdir package) + (let (package-lispdir) + (if (and (setq package-lispdir (expand-file-name "lisp" pkg-topdir)) + (setq package-lispdir (expand-file-name (symbol-name package) + package-lispdir)) + (file-accessible-directory-p package-lispdir)) + package-lispdir) + )) + +(defun package-admin-delete-binary-package (package pkg-topdir) + "Delete a binary installation of PACKAGE below directory PKG-TOPDIR. +PACKAGE is a symbol, not a string." + (let ( (tmpbuf " *pkg-manifest*") manifest-file package-lispdir dirs file) + (if (not pkg-topdir) + (setq pkg-topdir (package-admin-get-install-dir nil))) + (setq manifest-file (package-admin-get-manifest-file pkg-topdir package)) + (if (file-exists-p manifest-file) + (progn + ;; The manifest file exists! Use it to delete the old distribution. + (message "Removing old files for package \"%s\" ..." package) + (sit-for 0) + (setq tmpbuf (get-buffer-create tmpbuf)) + (save-excursion + (set-buffer tmpbuf) + (buffer-disable-undo tmpbuf) + (erase-buffer tmpbuf) + (insert-file-contents manifest-file) + (goto-char (point-min)) + ;; For each entry in the MANIFEST ... + (while (< (point) (point-max)) + (beginning-of-line) + (setq file (expand-file-name (buffer-substring + (point) + (save-excursion (end-of-line) + (point))) + pkg-topdir)) + (if (file-directory-p file) + ;; Keep a record of each directory + (setq dirs (cons file dirs)) + (progn + ;; Delete each file. + ;; Make sure that the file is writable. + ;; (This is important under MS Windows.) + (set-file-modes file 438) ;; 438 -> #o666 + (delete-file file) + )) + (forward-line 1) + ) + ;; Delete empty directories. + (if dirs + (let ( (orig-default-directory default-directory) + directory files file ) + ;; Make sure we preserve the existing `default-directory'. + (unwind-protect + (progn + ;; Warning: destructive sort! + (setq dirs (nreverse (sort dirs 'string<))) + ;; For each directory ... + (while dirs + (setq directory (file-name-as-directory (car dirs))) + (setq files (directory-files directory)) + ;; Delete the directory if it's empty. + (if (catch 'done + (while files + (setq file (car files)) + (if (and (not (string= file ".")) + (not (string= file ".."))) + (throw 'done nil)) + (setq files (cdr files)) + ) + t) + (delete-directory directory)) + (setq dirs (cdr dirs)) + ) + ) + (setq default-directory orig-default-directory) + ))) + ) + (kill-buffer tmpbuf) + ;; Delete the MANIFEST file + (set-file-modes manifest-file 438) ;; 438 -> #o666 + (delete-file manifest-file) + (message "Removing old files for package \"%s\" ... done" package) + ) + (progn + ;; The manifest file doesn't exist. Fallback to just deleting the + ;; package-specific lisp directory, if it exists. + ;; + ;; Delete old lisp directory, if any + ;; Gads, this is ugly. However, we're not supposed to use `concat' + ;; in the name of portability. + (if (setq package-lispdir (package-admin-get-lispdir pkg-topdir + package)) + (progn + (message "Removing old lisp directory \"%s\" ..." + package-lispdir) + (sit-for 0) + (package-admin-rmtree package-lispdir) + (message "Removing old lisp directory \"%s\" ... done" + package-lispdir) + )) + )) + ;; Delete the package from the database of installed packages. + (package-delete-name package) + )) (provide 'package-admin) diff --git a/lisp/package-get.el b/lisp/package-get.el index ba0f0ed..4675572 100644 --- a/lisp/package-get.el +++ b/lisp/package-get.el @@ -149,27 +149,70 @@ one version of a package available.") "*Where to store temporary files for staging.") (defvar package-get-remote - '( - ("ftp.xemacs.org" "/pub/xemacs/beta/xemacs-21.0/packages/binary-packages") - ("ftp.xemacs.org" "/pub/xemacs/beta/xemacs-21.0/packages/single-file-packages") - ("ftp.xemacs.org" "/pub/xemacs/package")) + '(("ftp.xemacs.org" "/pub/xemacs/packages")) "*List of remote sites to contact for downloading packages. List format is '(site-name directory-on-site). Each site is tried in -order until the package is found.") +order until the package is found. As a special case, `site-name' can be +`nil', in which case `directory-on-site' is treated as a local directory.") (defvar package-get-remove-copy nil "*After copying and installing a package, if this is T, then remove the copy. Otherwise, keep it around.") +(defun package-get-interactive-package-query (get-version package-symbol) + "Perform interactive querying for package and optional version. +Query for a version if GET-VERSION is non-nil. Return package name as +a symbol instead of a string if PACKAGE-SYMBOL is non-nil. +The return value is suitable for direct passing to `interactive'." + (let ( (table (mapcar '(lambda (item) + (let ( (name (symbol-name (car item))) ) + (cons name name) + )) + package-get-base)) + package package-symbol default-version version) + (save-window-excursion + (setq package (completing-read "Package: " table nil t)) + (setq package-symbol (intern package)) + (if get-version + (progn + (setq default-version + (package-get-info-prop + (package-get-info-version + (package-get-info-find-package package-get-base + package-symbol) nil) + 'version)) + (while (string= + (setq version (read-string "Version: " default-version)) + "") + ) + (if package-symbol + (list package-symbol version) + (list package version)) + ) + (if package-symbol + (list package-symbol) + (list package))) + ))) + +;;;###autoload +(defun package-get-delete-package (package &optional pkg-topdir) + "Delete an installation of PACKAGE below directory PKG-TOPDIR. +PACKAGE is a symbol, not a string. +This is just an interactive wrapper for `package-admin-delete-binary-package'." + (interactive (package-get-interactive-package-query nil t)) + (package-admin-delete-binary-package package pkg-topdir)) + ;;;###autoload (defun package-get-update-all () "Fetch and install the latest versions of all currently installed packages." (interactive) ;; Load a fresh copy - (mapcar (lambda (pkg) - (package-get-all - (car pkg) nil)) - packages-package-list)) + (catch 'exit + (mapcar (lambda (pkg) + (if (not (package-get (car pkg) nil 'never)) + (throw 'exit nil) ;; Bail out if error detected + )) + packages-package-list))) ;;;###autoload (defun package-get-all (package version &optional fetched-packages) @@ -177,48 +220,100 @@ copy. Otherwise, keep it around.") Uses `package-get-base' to determine just what is required and what package provides that functionality. If VERSION is nil, retrieves latest version. Optional argument FETCHED-PACKAGES is used to keep -track of packages already fetched." - (interactive "sPackage: \nsVersion: ") +track of packages already fetched. + +Returns nil upon error." + (interactive (package-get-interactive-package-query t nil)) (let* ((the-package (package-get-info-find-package package-get-base package)) (this-package (package-get-info-version the-package version)) (this-requires (package-get-info-prop this-package 'requires)) ) - (setq version (package-get-info-prop this-package 'version)) - (unless (package-get-installedp package version) - (package-get package version)) - (setq fetched-packages - (append (list package) - (package-get-info-prop this-package 'provides) - fetched-packages)) - ;; grab everything that this package requires plus recursively - ;; grab everything that the requires require. Keep track - ;; in `fetched-packages' the list of things provided -- this - ;; keeps us from going into a loop - (while this-requires - (if (not (member (car this-requires) fetched-packages)) - (let* ((reqd-package (package-get-package-provider - (car this-requires))) - (reqd-version (cadr reqd-package)) - (reqd-name (car reqd-package))) - (if (null reqd-name) - (error "Unable to find a provider for %s" (car this-requires))) - (setq fetched-packages - (package-get-all reqd-name reqd-version fetched-packages))) - ) - (setq this-requires (cdr this-requires))) + (catch 'exit + (setq version (package-get-info-prop this-package 'version)) + (unless (package-get-installedp package version) + (if (not (package-get package version)) + (progn + (setq fetched-packages nil) + (throw 'exit nil)))) + (setq fetched-packages + (append (list package) + (package-get-info-prop this-package 'provides) + fetched-packages)) + ;; grab everything that this package requires plus recursively + ;; grab everything that the requires require. Keep track + ;; in `fetched-packages' the list of things provided -- this + ;; keeps us from going into a loop + (while this-requires + (if (not (member (car this-requires) fetched-packages)) + (let* ((reqd-package (package-get-package-provider + (car this-requires))) + (reqd-version (cadr reqd-package)) + (reqd-name (car reqd-package))) + (if (null reqd-name) + (error "Unable to find a provider for %s" + (car this-requires))) + (if (not (setq fetched-packages + (package-get-all reqd-name reqd-version + fetched-packages))) + (throw 'exit nil))) + ) + (setq this-requires (cdr this-requires))) + ) fetched-packages )) +(defun package-get-load-package-file (lispdir file) + (let (pathname) + (setq pathname (expand-file-name file lispdir)) + (condition-case err + (progn + (load pathname t) + t) + (t + (message "Error loading package file \"%s\" %s!" pathname err) + nil)) + )) + +(defun package-get-init-package (lispdir) + "Initialize the package. +This really assumes that the package has never been loaded. Updating +a newer package can cause problems, due to old, obsolete functions in +the old package. + +Return `t' upon complete success, `nil' if any errors occurred." + (progn + (if (and lispdir + (file-accessible-directory-p lispdir)) + (progn + ;; Add lispdir to load-path if it doesn't already exist. + ;; NOTE: this does not take symlinks, etc., into account. + (if (let ( (dirs load-path) ) + (catch 'done + (while dirs + (if (string-equal (car dirs) lispdir) + (throw 'done nil)) + (setq dirs (cdr dirs)) + ) + t)) + (setq load-path (cons lispdir load-path))) + (if (not (package-get-load-package-file lispdir "auto-autoloads")) + (package-get-load-package-file lispdir "_pkg")) + t) + nil) + )) + ;;;###autoload -(defun package-get (package &optional version conflict) +(defun package-get (package &optional version conflict install-dir) "Fetch PACKAGE from remote site. Optional arguments VERSION indicates which version to retrieve, nil means most recent version. CONFLICT indicates what happens if the package is already installed. Valid values for CONFLICT are: 'always always retrieve the package even if it is already installed 'never do not retrieve the package if it is installed. +INSTALL-DIR, if non-nil, specifies the package directory where +fetched packages should be installed. The value of `package-get-base' is used to determine what files should be retrieved. The value of `package-get-remote' is used to determine @@ -227,59 +322,158 @@ order so one is better off listing easily reached sites first. Once the package is retrieved, its md5 checksum is computed. If that sum does not match that stored in `package-get-base' for this version -of the package, an error is signalled." - (interactive "xPackage List: ") +of the package, an error is signalled. + +Returns `t' upon success, the symbol `error' if the package was +successfully installed but errors occurred during initialization, or +`nil' upon error." + (interactive (package-get-interactive-package-query nil t)) (let* ((this-package (package-get-info-version (package-get-info-find-package package-get-base package) version)) (found nil) (search-dirs package-get-remote) - (filename (package-get-info-prop this-package 'filename))) + (base-filename (package-get-info-prop this-package 'filename)) + (package-status t) + filenames full-package-filename) (if (null this-package) (error "Couldn't find package %s with version %s" package version)) - (if (null filename) + (if (null base-filename) (error "No filename associated with package %s, version %s" package version)) + (if (null install-dir) + (setq install-dir (package-admin-get-install-dir nil))) + + ;; Contrive a list of possible package filenames. + ;; Ugly. Is there a better way to do this? + (setq filenames (cons base-filename nil)) + (if (string-match "^\\(..*\\)\.tar\.gz$" base-filename) + (setq filenames (append filenames + (list (concat (match-string 1 base-filename) + ".tgz"))))) + (setq version (package-get-info-prop this-package 'version)) (unless (and (eq conflict 'never) (package-get-installedp package version)) - ;; Find the package from search list in package-get-remote + ;; Find the package from the search list in package-get-remote ;; and copy it into the staging directory. Then validate ;; the checksum. Finally, install the package. - (while (and search-dirs - (not (file-exists-p (package-get-staging-dir filename)))) - (if (file-exists-p (package-get-remote-filename - (car search-dirs) filename)) - (copy-file (package-get-remote-filename (car search-dirs) filename) - (package-get-staging-dir filename)) - (setq search-dirs (cdr search-dirs)) + (catch 'done + (let (search-filenames current-dir-entry host dir current-filename + dest-filename) + ;; In each search directory ... + (while search-dirs + (setq current-dir-entry (car search-dirs) + host (car current-dir-entry) + dir (car (cdr current-dir-entry)) + search-filenames filenames + ) + + ;; Look for one of the possible package filenames ... + (while search-filenames + (setq current-filename (car search-filenames) + dest-filename (package-get-staging-dir current-filename)) + (cond + ;; No host means look on the current system. + ( (null host) + (setq full-package-filename + (substitute-in-file-name + (expand-file-name current-filename + (file-name-as-directory dir)))) + ) + + ;; If it's already on the disk locally, and the size is + ;; greater than zero ... + ( (and (file-exists-p dest-filename) + (let (attrs) + ;; file-attributes could return -1 for LARGE files, + ;; but, hopefully, packages won't be that large. + (and (setq attrs (file-attributes dest-filename)) + (> (nth 7 attrs) 0)))) + (setq full-package-filename dest-filename) + ) + + ;; If the file exists on the remote system ... + ( (file-exists-p (package-get-remote-filename + current-dir-entry current-filename)) + ;; Get it + (setq full-package-filename dest-filename) + (message "Retrieving package `%s' ..." + current-filename) + (sit-for 0) + (copy-file (package-get-remote-filename current-dir-entry + current-filename) + full-package-filename t) + ) + ) + + ;; If we found it, we're done. + (if (and full-package-filename + (file-exists-p full-package-filename)) + (throw 'done nil)) + ;; Didn't find it. Try the next possible filename. + (setq search-filenames (cdr search-filenames)) + ) + ;; Try looking in the next possible directory ... + (setq search-dirs (cdr search-dirs)) + ) )) - (if (not (file-exists-p (package-get-staging-dir filename))) - (error "Unable to find file %s" filename)) + + (if (or (not full-package-filename) + (not (file-exists-p full-package-filename))) + (error "Unable to find file %s" base-filename)) ;; Validate the md5 checksum ;; Doing it with XEmacs removes the need for an external md5 program + (message "Validating checksum for `%s'..." package) (sit-for 0) (with-temp-buffer ;; What ever happened to i-f-c-literally (let (file-name-handler-alist) - (insert-file-contents-internal (package-get-staging-dir filename))) + (insert-file-contents-internal full-package-filename)) (if (not (string= (md5 (current-buffer)) (package-get-info-prop this-package 'md5sum))) - (error "Package %s does not match md5 checksum" filename))) - (message "Retrieved package %s" filename) (sit-for 0) + (error "Package %s does not match md5 checksum" base-filename))) + + (package-admin-delete-binary-package package install-dir) + + (message "Installing package `%s' ..." package) (sit-for 0) (let ((status - (package-admin-add-binary-package - (package-get-staging-dir filename)))) - (when (not (= status 0)) - (message "Package failed.") - (switch-to-buffer package-admin-temp-buffer))) - (sit-for 0) - (message "Added package") (sit-for 0) + (package-admin-add-binary-package full-package-filename + install-dir))) + (if (= status 0) + (progn + ;; clear messages so that only messages from + ;; package-get-init-package are seen, below. + (clear-message) + (if (package-get-init-package (package-admin-get-lispdir + install-dir package)) + (progn + (message "Added package `%s'" package) + (sit-for 0) + ) + (progn + ;; display message only if there isn't already one. + (if (not (current-message)) + (progn + (message "Added package `%s' (errors occurred)" + package) + (sit-for 0) + )) + (if package-status + (setq package-status 'errors)) + )) + ) + (message "Installation of package %s failed." base-filename) + (sit-for 0) + (switch-to-buffer package-admin-temp-buffer) + (setq package-status nil) + )) (setq found t)) (if (and found package-get-remove-copy) - (delete-file (package-get-staging-dir filename))) + (delete-file full-package-filename)) + package-status )) (defun package-get-info-find-package (which name) @@ -304,7 +498,7 @@ from a version returned by `package-get-info-version'." `package-get-info-find-package'. If VERSION is nil, then return the first (aka most recent) version. Use `package-get-info-find-prop' to retrieve a particular property from the value returned by this." - (interactive "xPackage Info: \nsVersion: ") + (interactive (package-get-interactive-package-query t t)) (while (and version package (not (string= (plist-get (car package) 'version) version))) (setq package (cdr package))) (if package (car package))) @@ -345,10 +539,11 @@ Creates `package-get-dir' it it doesn't exist." (interactive "FPackage filename: ") (if (not (file-exists-p package-get-dir)) (make-directory package-get-dir)) - (concat - (file-name-as-directory package-get-dir) - (file-name-nondirectory (or (nth 2 (efs-ftp-path filename)) filename)))) - + (expand-file-name + (file-name-nondirectory (or (and (fboundp 'efs-ftp-path) + (nth 2 (efs-ftp-path filename))) + filename)) + (file-name-as-directory package-get-dir))) (defun package-get-remote-filename (search filename) "Return FILENAME as a remote filename. @@ -458,10 +653,12 @@ Entries in the customization file are retrieved from package-get-base.el." (let ((custom-buffer (find-file-noselect (or (package-get-file-installed-p "package-get-custom.el") - (concat (file-name-directory - (package-get-file-installed-p - "package-get-base.el")) - "package-get-custom.el")))) + (expand-file-name + "package-get-custom.el" + (file-name-directory + (package-get-file-installed-p + "package-get-base.el")) + )))) (pkg-groups nil)) ;; clear existing stuff diff --git a/lisp/packages.el b/lisp/packages.el index 974bdd3..49f4fd4 100644 --- a/lisp/packages.el +++ b/lisp/packages.el @@ -63,6 +63,9 @@ (defvar packages-load-path-depth 1 "Depth of load-path search in package hierarchies.") +(defvar packages-data-path-depth 1 + "Depth of data-path search in package hierarchies.") + (defvar early-packages nil "Packages early in the load path.") @@ -133,6 +136,18 @@ the directory to be ignored.") version name (cdr pkg))) (t t)))) +(defun package-delete-name (name) + (let (pkg) + ;; Delete ALL versions of package. + ;; This is pretty memory-intensive, as we use copy-alist when deleting + ;; package entries, to prevent side-effects in functions that call this + ;; one. + (while (setq pkg (assq name packages-package-list)) + (setq packages-package-list (delete pkg (copy-alist + packages-package-list))) + ) + )) + ;;; Build time stuff (defvar autoload-file-name "auto-autoloads.el" @@ -220,14 +235,10 @@ is used instead of `load-path'." (setq path (cdr path))) autoloads)) -(defun packages-list-autoloads () +(defun packages-list-autoloads (source-directory) "List autoload files in (what will be) the normal lisp search path. This function is used during build to find where the global symbol files so they can be perused for their useful information." - ;; Source directory may not be initialized yet. - ;; (print (prin1-to-string load-path)) - (if (null source-directory) - (setq source-directory (car load-path))) (let ((files (directory-files (file-name-as-directory source-directory) t ".*")) file autolist) @@ -294,6 +305,23 @@ is run. Don't call it or you'll be sorry." ;; Data-directory is really a list now. Provide something to search it for ;; directories. +(defun locate-data-directory-list (name &optional dir-list) + "Locate the matching list of directories in a search path DIR-LIST. +If no DIR-LIST is supplied, it defaults to `data-directory-list'." + (unless dir-list + (setq dir-list data-directory-list)) + (let (found found-dir found-dir-list) + (while dir-list + (setq found (file-name-as-directory (concat (car dir-list) name)) + found-dir (file-directory-p found)) + (and found-dir + (setq found-dir-list (cons found found-dir-list))) + (setq dir-list (cdr dir-list))) + (nreverse found-dir-list))) + +;; Data-directory is really a list now. Provide something to search it for +;; a directory. + (defun locate-data-directory (name &optional dir-list) "Locate a directory in a search path DIR-LIST (a list of directories). If no DIR-LIST is supplied, it defaults to `data-directory-list'." @@ -331,7 +359,7 @@ This function is basically a wrapper over `locate-file'." (and version-directory (list version-directory)) (and site-directory (list site-directory))))) -(defvar packages-special-base-regexp "^\\(etc\\|info\\|lisp\\|lib-src\\|bin\\)$" +(defvar packages-special-base-regexp "^\\(etc\\|info\\|lisp\\|lib-src\\|bin\\|pkginfo\\)$" "Special subdirectories of packages.") (defvar packages-no-package-hierarchy-regexp @@ -445,16 +473,25 @@ PACKAGES is a list of package directories." packages-load-path-depth)) (defun packages-find-package-exec-path (packages) + "Construct the exec-path component for packages. +PACKAGES is a list of package directories." (packages-find-package-library-path packages (list (paths-construct-path (list "bin" system-configuration)) "lib-src"))) (defun packages-find-package-info-path (packages) + "Construct the info-path component for packages. +PACKAGES is a list of package directories." (packages-find-package-library-path packages '("info"))) (defun packages-find-package-data-path (packages) - (packages-find-package-library-path packages '("etc"))) + "Construct the data-path component for packages. +PACKAGES is a list of package directories." + (paths-find-recursive-load-path + (packages-find-package-library-path packages + '("etc")) + packages-data-path-depth)) ;; Loading package initialization files diff --git a/lisp/setup-paths.el b/lisp/setup-paths.el index 3d07560..b64dc0b 100644 --- a/lisp/setup-paths.el +++ b/lisp/setup-paths.el @@ -137,12 +137,12 @@ (paths-decode-directory-path path-envval 'drop-empties))) (packages-find-package-exec-path early-packages) (packages-find-package-exec-path late-packages) - (packages-find-package-exec-path last-packages) (let ((emacspath-envval (getenv "EMACSPATH"))) (and emacspath-envval (split-path emacspath-envval))) (and exec-directory - (list exec-directory)))) + (list exec-directory)) + (packages-find-package-exec-path last-packages))) (defun paths-find-data-directory (roots) "Find the data directory." @@ -154,7 +154,7 @@ (append (packages-find-package-data-path early-packages) (packages-find-package-data-path late-packages) - (packages-find-package-data-path last-packages) - (list data-directory))) + (list data-directory) + (packages-find-package-data-path last-packages))) ;;; setup-paths.el ends here diff --git a/lisp/shadow.el b/lisp/shadow.el index 46d3a58..f841f40 100644 --- a/lisp/shadow.el +++ b/lisp/shadow.el @@ -6,9 +6,9 @@ ;; Keywords: lisp ;; Created: 15 December 1995 -;; This file is part of GNU Emacs. +;; This file is part of XEmacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; XEmacs is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. @@ -51,6 +51,8 @@ ;; Thanks to Francesco Potorti` for suggestions, ;; rewritings & speedups. +;; 1998-08-15 Martin Buchholz: Speed up using hashtables instead of lists. + ;;; Code: (defun find-emacs-lisp-shadows (&optional path) @@ -64,50 +66,49 @@ are stripped from the file names in the list. See the documentation for `list-load-path-shadows' for further information." - (or path (setq path load-path)) - - (let (true-names ; List of dirs considered. - shadows ; List of shadowings, to be returned. - files ; File names ever seen, with dirs. + (let (shadows ; List of shadowings, to be returned. dir ; The dir being currently scanned. curr-files ; This dir's Emacs Lisp files. orig-dir ; Where the file was first seen. - files-seen-this-dir ; Files seen so far in this dir. - file) ; The current file. - + (file-dirs + (make-hashtable 2000 'equal)) ; File names ever seen, with dirs. + (true-names + (make-hashtable 50 'equal)) ; Dirs ever considered. + (files-seen-this-dir + (make-hashtable 100 'equal)) ; Files seen so far in this dir. + ) - (while path + (dolist (path-elt (or path load-path)) - (setq dir (file-truename (or (car path) "."))) - (if (member dir true-names) + (setq dir (file-truename (or path-elt "."))) + (if (gethash dir true-names) ;; We have already considered this PATH redundant directory. - ;; Show the redundancy if we are interactiver, unless the PATH + ;; Show the redundancy if we are interactive, unless the PATH ;; dir is nil or "." (these redundant directories are just a ;; result of the current working directory, and are therefore ;; not always redundant). (or noninteractive - (and (car path) - (not (string= (car path) ".")) - (message "Ignoring redundant directory %s" (car path)))) - - (setq true-names (append true-names (list dir))) - (setq dir (or (car path) ".")) + (and path-elt + (not (string= path-elt ".")) + (message "Ignoring redundant directory %s" path-elt))) + + (puthash dir t true-names) + (setq dir (or path-elt ".")) (setq curr-files (if (file-accessible-directory-p dir) (directory-files dir nil ".\\.elc?$" t))) (and curr-files (not noninteractive) (message "Checking %d files in %s..." (length curr-files) dir)) - (setq files-seen-this-dir nil) + (clrhash files-seen-this-dir) - (while curr-files + (dolist (file curr-files) - (setq file (car curr-files)) (setq file (substring file 0 (if (string= (substring file -1) "c") -4 -3))) ;; FILE now contains the current file name, with no suffix. - (unless (or (member file files-seen-this-dir) + (unless (or (gethash file files-seen-this-dir) ;; Ignore these files. (member file '("subdirs" @@ -119,22 +120,19 @@ See the documentation for `list-load-path-shadows' for further information." ;; File has not been seen yet in this directory. ;; This test prevents us declaring that XXX.el shadows ;; XXX.elc (or vice-versa) when they are in the same directory. - (setq files-seen-this-dir (cons file files-seen-this-dir)) + (puthash file t files-seen-this-dir) - (if (setq orig-dir (assoc file files)) + (if (setq orig-dir (gethash file file-dirs)) ;; This file was seen before, we have a shadowing. (setq shadows - (append shadows - (list (concat (file-name-as-directory (cdr orig-dir)) - file) - (concat (file-name-as-directory dir) - file)))) + (nconc shadows + (list (concat (file-name-as-directory orig-dir) + file) + (concat (file-name-as-directory dir) + file)))) ;; Not seen before, add it to the list of seen files. - (setq files (cons (cons file dir) files)))) - - (setq curr-files (cdr curr-files)))) - (setq path (cdr path))) + (puthash file dir file-dirs)))))) ;; Return the list of shadowings. shadows)) diff --git a/lisp/sound.el b/lisp/sound.el index 62b2706..be24062 100644 --- a/lisp/sound.el +++ b/lisp/sound.el @@ -113,7 +113,7 @@ :group 'sound :type 'string) -(defcustom default-sound-directory-list ( list default-sound-directory ) +(defcustom default-sound-directory-list (locate-data-directory-list "sounds") "List of directories which to search for sound files" :group 'sound diff --git a/lisp/startup.el b/lisp/startup.el index 19cbcc3..c601f84 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -402,10 +402,10 @@ Type ^H^H^H (Control-h Control-h Control-h) to get more help options.\n") (if (not inhibit-autoloads) (progn - (packages-load-package-auto-autoloads last-package-load-path) - (packages-load-package-auto-autoloads late-package-load-path) (if (not inhibit-early-packages) - (packages-load-package-auto-autoloads early-package-load-path)))) + (packages-load-package-auto-autoloads early-package-load-path)) + (packages-load-package-auto-autoloads late-package-load-path) + (packages-load-package-auto-autoloads last-package-load-path))) (unwind-protect (command-line) @@ -680,7 +680,7 @@ If this is nil, no message will be displayed.") (message "Error in init file: %s" (error-message-string error)) (display-warning 'initialization (format "\ -An error has occured while loading %s: +An error has occurred while loading %s: %s @@ -935,7 +935,7 @@ a new format, when variables have changed, etc." " to see what this means.\n"))) `( "\n")) (face bold-italic "\ -Copyright (C) 1985-1997 Free Software Foundation, Inc. +Copyright (C) 1985-1998 Free Software Foundation, Inc. Copyright (C) 1990-1994 Lucid, Inc. Copyright (C) 1993-1997 Sun Microsystems, Inc. All Rights Reserved. Copyright (C) 1994-1996 Board of Trustees, University of Illinois diff --git a/lisp/update-elc.el b/lisp/update-elc.el index 45b5e1d..bddaf12 100644 --- a/lisp/update-elc.el +++ b/lisp/update-elc.el @@ -71,7 +71,7 @@ (load "setup-paths.el") (load "dump-paths.el") -(let ((autol (packages-list-autoloads))) +(let ((autol (packages-list-autoloads (concat default-directory "../lisp")))) ;; (print (prin1-to-string autol)) (while autol (let ((src (car autol))) diff --git a/lisp/x-font-menu.el b/lisp/x-font-menu.el index 40d4c11..3e902e1 100644 --- a/lisp/x-font-menu.el +++ b/lisp/x-font-menu.el @@ -466,15 +466,18 @@ or if you change your font path, you can call this to re-initialize the menus." (from-size (aref font-data 2)) (from-weight (aref font-data 3)) (from-slant (aref font-data 4)) - new-default-face-font) + new-default-face-font + new-props) (unless from-family (signal 'error '("couldn't parse font name for default face"))) - (setq new-default-face-font - (font-menu-load-font (or family from-family) - (or weight from-weight) - (or size from-size) - from-slant - font-menu-preferred-resolution)) + (when weight + (signal 'error '("Setting weight currently not supported"))) +; (setq new-default-face-font +; (font-menu-load-font (or family from-family) +; (or weight from-weight) +; (or size from-size) +; from-slant +; font-menu-preferred-resolution)) (dolist (face (delq 'default (face-list))) (when (face-font-instance face) (message "Changing font of `%s'..." face) @@ -487,10 +490,16 @@ or if you change your font path, you can call this to re-initialize the menus." (sit-for 1))))) ;; Set the default face's font after hacking the other faces, so that ;; the frame size doesn't change until we are all done. - - ;;; WMP - we need to honor font-menu-this-frame-only-p here! - (set-face-font 'default new-default-face-font - (and font-menu-this-frame-only-p (selected-frame))) + + (when (and family (not (equal family from-family))) + (setq new-props (append (list :family family) new-props))) + (when (and size (not (equal size from-size))) + (setq new-props (append (list :size (concat (int-to-string + (/ size 10)) "pt")) new-props))) + (custom-set-face-update-spec 'default '((type x)) new-props) + ;;; WMP - we need to honor font-menu-this-frame-only-p here! +; (set-face-font 'default new-default-face-font +; (and font-menu-this-frame-only-p (selected-frame))) (message "Font %s" (face-font-name 'default)))) diff --git a/lisp/x-init.el b/lisp/x-init.el index b71799e..e9a344f 100644 --- a/lisp/x-init.el +++ b/lisp/x-init.el @@ -208,6 +208,7 @@ (x-define-dead-key dead-cedilla compose-cedilla-map) (x-define-dead-key dead-diaeresis compose-diaeresis-map) (x-define-dead-key dead-circum compose-circumflex-map) + (x-define-dead-key dead-circumflex compose-circumflex-map) (x-define-dead-key dead-tilde compose-tilde-map) ) diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index 87f7543..12dca51 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -444,6 +444,7 @@ string_width_u (XlwMenuWidget mw, newstring = XmStringLtoRCreate (newchars, XmFONTLIST_DEFAULT_TAG); XmStringExtent (mw->menu.font_list, newstring, &width, &height); XmStringFree (newstring); + XtFree (chars); return width; #else # ifdef USE_XFONTSET @@ -891,6 +892,9 @@ char *chars; } } x += string_draw_range (mw, window, x, y, gc, chars, s, i); +#ifdef NEED_MOTIF + XtFree (chars); +#endif } static void @@ -2803,13 +2807,31 @@ make_shadow_gcs (XlwMenuWidget mw) xgcv.fill_style = FillOpaqueStippled; xgcv.foreground = mw->menu.top_shadow_color; xgcv.background = mw->core.background_pixel; +/* xgcv.stipple = mw->menu.top_shadow_pixmap; gtb */ +#ifdef NEED_MOTIF + if (mw->menu.top_shadow_pixmap && + mw->menu.top_shadow_pixmap != XmUNSPECIFIED_PIXMAP) + xgcv.stipple = mw->menu.top_shadow_pixmap; + else + xgcv.stipple = 0; +#else xgcv.stipple = mw->menu.top_shadow_pixmap; +#endif /* NEED_MOTIF */ pm = (xgcv.stipple ? GCStipple|GCFillStyle : 0); mw->menu.shadow_top_gc = XtGetGC((Widget)mw, GCForeground|GCBackground|pm, &xgcv); xgcv.foreground = mw->menu.bottom_shadow_color; +/* xgcv.stipple = mw->menu.bottom_shadow_pixmap; gtb */ +#ifdef NEED_MOTIF + if (mw->menu.top_shadow_pixmap && + mw->menu.top_shadow_pixmap != XmUNSPECIFIED_PIXMAP) + xgcv.stipple = mw->menu.bottom_shadow_pixmap; + else + xgcv.stipple = 0; +#else xgcv.stipple = mw->menu.bottom_shadow_pixmap; +#endif /* NEED_MOTIF */ pm = (xgcv.stipple ? GCStipple|GCFillStyle : 0); mw->menu.shadow_bottom_gc = XtGetGC ((Widget)mw, GCForeground|GCBackground|pm, &xgcv); diff --git a/lwlib/xlwscrollbar.c b/lwlib/xlwscrollbar.c index e8ded5a..81f8cdb 100644 --- a/lwlib/xlwscrollbar.c +++ b/lwlib/xlwscrollbar.c @@ -485,6 +485,12 @@ arrow_same_end (XlwScrollBarWidget w) } /*-------------------------- GC and Pixel allocation --------------------*/ +#ifdef NEED_MOTIF +#ifndef XmUNSPECIFIED_PIXMAP +#define XmUNSPECIFIED_PIXMAP 2 +#endif +#endif /* NEED_MOTIF */ + static GC get_gc (XlwScrollBarWidget w, Pixel fg, Pixel bg, Pixmap pm) { @@ -506,8 +512,19 @@ get_gc (XlwScrollBarWidget w, Pixel fg, Pixel bg, Pixmap pm) values.background = bg; values.fill_style = FillOpaqueStippled; values.stipple = pm; +/* mask = GCForeground | GCBackground | + (pm == None ? 0 : GCStipple | GCFillStyle); gtb */ +#ifdef NEED_MOTIF + if (pm != None && pm != 0 && pm != XmUNSPECIFIED_PIXMAP) + values.stipple = pm; + else + values.stipple = None; +#else + values.stipple = pm; +#endif /* NEED_MOTIF */ mask = GCForeground | GCBackground | - (pm == None ? 0 : GCStipple | GCFillStyle); + (values.stipple == None ? 0 : GCStipple | GCFillStyle); + return XtGetGC((Widget) w, mask, &values); } diff --git a/man/ChangeLog b/man/ChangeLog index 963d144..a3814fa 100644 --- a/man/ChangeLog +++ b/man/ChangeLog @@ -1,3 +1,52 @@ +1998-09-29 SL Baur + + * XEmacs 21.2-beta2 is released. + +1998-09-20 Hrvoje Niksic + + * lispref/customize.texi: New file. + +1998-09-09 Hrvoje Niksic + + * internals/internals.texi (Coding for Mule): New node and + section. + +1998-09-03 Darryl Okahata + + * xemacs/packages.texi: Document manually installing binary packages. + +1998-09-02 Jeff Miller + + * Synch calendar.texi with Emacs 20.3 + +1998-09-03 Darryl Okahata + + * xemacs/packages.texi: Correct and update package documentation. + Updated the package installation section to mention the visual + package browser/installer. + +1998-08-31 Hrvoje Niksic + + * lispref/buffers.texi (Indirect Buffers): Update with XEmacs + specifics. + +1998-08-21 Greg Klanderman + + * lispref/files.texi (User Name Completion): new section. + +1998-07-23 Adrian Aichner + + * xemacs/packages.texi (Packages): Changing @itemize @emph to + @itemize @bullet (this is what all other files included in + xemacs.texi use) to fix error in texi2dvi (GNU Texinfo 3.12) 0.8. + +1998-07-20 Michael Sperber [Mr. Preprocessor] + + * xemacs/startup.texi: Small fixes, suggested by Hrvoje. + + * xemacs/xemacs.texi: + * xemacs/packages.texi: More packages documentation. + 1998-07-19 SL Baur * XEmacs 21.2-beta1 is released. diff --git a/man/internals/internals.texi b/man/internals/internals.texi index 0575315..7b8e67e 100644 --- a/man/internals/internals.texi +++ b/man/internals/internals.texi @@ -598,6 +598,8 @@ A timeline for Emacs 20 is version 20.1 released September 17, 1997. @item version 20.2 released September 20, 1997. +@item +version 20.3 released August 19, 1998. @end itemize @node XEmacs @@ -1654,6 +1656,7 @@ often in code far away from where the actual breakage is. * General Coding Rules:: * Writing Lisp Primitives:: * Adding Global Lisp Variables:: +* Coding for Mule:: * Techniques for XEmacs Developers:: @end menu @@ -1754,7 +1757,7 @@ If all args return nil, return nil. @{ val = Feval (XCAR (args)); if (!NILP (val)) - break; + break; args = XCDR (args); @} @@ -2024,6 +2027,352 @@ is in use, and will happily collect it and reuse its storage for another Lisp object, and you will be the one who's unhappy when you can't figure out how your variable got overwritten. +@node Coding for Mule +@section Coding for Mule +@cindex Coding for Mule + +Although Mule support is not compiled by default in XEmacs, many people +are using it, and we consider it crucial that new code works correctly +with multibyte characters. This is not hard; it is only a matter of +following several simple user-interface guidelines. Even if you never +compile with Mule, with a little practice you will find it quite easy +to code Mule-correctly. + +Note that these guidelines are not necessarily tied to the current Mule +implementation; they are also a good idea to follow on the grounds of +code generalization for future I18N work. + +@menu +* Character-Related Data Types:: +* Working With Character and Byte Positions:: +* Conversion of External Data:: +* General Guidelines for Writing Mule-Aware Code:: +* An Example of Mule-Aware Code:: +@end menu + +@node Character-Related Data Types +@subsection Character-Related Data Types + +First, we will list the basic character-related datatypes used by +XEmacs. Note that the separate @code{typedef}s are not required for the +code to work (all of them boil down to @code{unsigned char} or +@code{int}), but they improve clarity of code a great deal, because one +glance at the declaration can tell the intended use of the variable. + +@table @code +@item Emchar +@cindex Emchar +An @code{Emchar} holds a single Emacs character. + +Obviously, the equality between characters and bytes is lost in the Mule +world. Characters can be represented by one or more bytes in the +buffer, and @code{Emchar} is the C type large enough to hold any +character. + +Without Mule support, an @code{Emchar} is equivalent to an +@code{unsigned char}. + +@item Bufbyte +@cindex Bufbyte +The data representing the text in a buffer or string is logically a set +of @code{Bufbyte}s. + +XEmacs does not work with character formats all the time; when reading +characters from the outside, it decodes them to an internal format, and +likewise encodes them when writing. @code{Bufbyte} (in fact +@code{unsigned char}) is the basic unit of XEmacs internal buffers and +strings format. + +One character can correspond to one or more @code{Bufbyte}s. In the +current implementation, an ASCII character is represented by the same +@code{Bufbyte}, and extended characters are represented by a sequence of +@code{Bufbyte}s. + +Without Mule support, a @code{Bufbyte} is equivalent to an +@code{Emchar}. + +@item Bufpos +@itemx Charcount +A @code{Bufpos} represents a character position in a buffer or string. +A @code{Charcount} represents a number (count) of characters. +Logically, subtracting two @code{Bufpos} values yields a +@code{Charcount} value. Although all of these are @code{typedef}ed to +@code{int}, we use them in preference to @code{int} to make it clear +what sort of position is being used. + +@code{Bufpos} and @code{Charcount} values are the only ones that are +ever visible to Lisp. + +@item Bytind +@itemx Bytecount +A @code{Bytind} represents a byte position in a buffer or string. A +@code{Bytecount} represents the distance between two positions in bytes. +The relationship between @code{Bytind} and @code{Bytecount} is the same +as the relationship between @code{Bufpos} and @code{Charcount}. + +@item Extbyte +@itemx Extcount +When dealing with the outside world, XEmacs works with @code{Extbyte}s, +which are equivalent to @code{unsigned char}. Obviously, an +@code{Extcount} is the distance between two @code{Extbyte}s. Extbytes +and Extcounts are not all that frequent in XEmacs code. +@end table + +@node Working With Character and Byte Positions +@subsection Working With Character and Byte Positions + +Now that we have defined the basic character-related types, we can look +at the macros and functions designed for work with them and for +conversion between them. Most of these macros are defined in +@file{buffer.h}, and we don't discuss all of them here, but only the +most important ones. Examining the existing code is the best way to +learn about them. + +@table @code +@item MAX_EMCHAR_LEN +This preprocessor constant is the maximum number of buffer bytes per +Emacs character, i.e. the byte length of an @code{Emchar}. It is useful +when allocating temporary strings to keep a known number of characters. +For instance: + +@example +@group +@{ + Charcount cclen; + ... + @{ + /* Allocate place for @var{cclen} characters. */ + Bufbyte *tmp_buf = (Bufbyte *)alloca (cclen * MAX_EMCHAR_LEN); +... +@end group +@end example + +If you followed the previous section, you can guess that, logically, +multiplying a @code{Charcount} value with @code{MAX_EMCHAR_LEN} produces +a @code{Bytecount} value. + +In the current Mule implementation, @code{MAX_EMCHAR_LEN} equals 4. +Without Mule, it is 1. + +@item charptr_emchar +@item set_charptr_emchar +@code{charptr_emchar} macro takes a @code{Bufbyte} pointer and returns +the underlying @code{Emchar}. If it were a function, its prototype +would be: + +@example +Emchar charptr_emchar (Bufbyte *p); +@end example + +@code{set_charptr_emchar} stores an @code{Emchar} to the specified byte +position. It returns the number of bytes stored: + +@example +Bytecount set_charptr_emchar (Bufbyte *p, Emchar c); +@end example + +It is important to note that @code{set_charptr_emchar} is safe only for +appending a character at the end of a buffer, not for overwriting a +character in the middle. This is because the width of characters +varies, and @code{set_charptr_emchar} cannot resize the string if it +writes, say, a two-byte character where a single-byte character used to +reside. + +A typical use of @code{set_charptr_emchar} can be demonstrated by this +example, which copies characters from buffer @var{buf} to a temporary +string of Bufbytes. + +@example +@group +@{ + Bufpos pos; + for (pos = beg; pos < end; pos++) + @{ + Emchar c = BUF_FETCH_CHAR (buf, pos); + p += set_charptr_emchar (buf, c); + @} +@} +@end group +@end example + +Note how @code{set_charptr_emchar} is used to store the @code{Emchar} +and increment the counter, at the same time. + +@item INC_CHARPTR +@itemx DEC_CHARPTR +These two macros increment and decrement a @code{Bufbyte} pointer, +respectively. The pointer needs to be correctly positioned at the +beginning of a valid character position. + +Without Mule support, @code{INC_CHARPTR (p)} and @code{DEC_CHARPTR (p)} +simply expand to @code{p++} and @code{p--}, respectively. + +@item bytecount_to_charcount +Given a pointer to a text string and a length in bytes, return the +equivalent length in characters. + +@example +Charcount bytecount_to_charcount (Bufbyte *p, Bytecount bc); +@end example + +@item charcount_to_bytecount +Given a pointer to a text string and a length in characters, return the +equivalent length in bytes. + +@example +Bytecount charcount_to_bytecount (Bufbyte *p, Charcount cc); +@end example + +@item charptr_n_addr +Return a pointer to the beginning of the character offset @var{cc} (in +characters) from @var{p}. + +@example +Bufbyte *charptr_n_addr (Bufbyte *p, Charcount cc); +@end example +@end table + +@node Conversion of External Data +@subsection Conversion of External Data + +When an external function, such as a C library function, returns a +@code{char} pointer, you should never treat it as @code{Bufbyte}. This +is because these returned strings may contain 8bit characters which can +be misinterpreted by XEmacs, and cause a crash. Instead, you should use +a conversion macro. Many different conversion macros are defined in +@file{buffer.h}, so I will try to order them logically, by direction and +by format. + +Thus the basic conversion macros are @code{GET_CHARPTR_INT_DATA_ALLOCA} +and @code{GET_CHARPTR_EXT_DATA_ALLOCA}. The former is used to convert +external data to internal format, and the latter is used to convert the +other way around. The arguments each of these receives are @var{ptr} +(pointer to the text in external format), @var{len} (length of texts in +bytes), @var{fmt} (format of the external text), @var{ptr_out} (lvalue +to which new text should be copied), and @var{len_out} (lvalue which +will be assigned the length of the internal text in bytes). The +resulting text is stored to a stack-allocated buffer. If the text +doesn't need changing, these macros will do nothing, except for setting +@var{len_out}. + +Currently meaningful formats are @code{FORMAT_BINARY}, +@code{FORMAT_FILENAME}, @code{FORMAT_OS}, and @code{FORMAT_CTEXT}. + +The two macros above take many arguments which makes them unwieldy. For +this reason, several convenience macros are defined with obvious +functionality, but accepting less arguments: + +@table @code +@item GET_C_CHARPTR_EXT_DATA_ALLOCA +@itemx GET_C_CHARPTR_INT_DATA_ALLOCA +These two macros work on ``C char pointers'', which are zero-terminated, +and thus do not need @var{len} or @var{len_out} parameters. + +@item GET_STRING_EXT_DATA_ALLOCA +@itemx GET_C_STRING_EXT_DATA_ALLOCA +These two macros work on Lisp strings, thus also not needing a @var{len} +parameter. However, @code{GET_STRING_EXT_DATA_ALLOCA} still provides a +@var{len_out} parameter. Note that for Lisp strings only one conversion +direction makes sense. + +@item GET_C_CHARPTR_EXT_BINARY_DATA_ALLOCA +@itemx GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA +@itemx GET_C_CHARPTR_EXT_CTEXT_DATA_ALLOCA +@itemx ... +These macros are a combination of the above, but with the @var{fmt} +argument encoded into the name of the macro. +@end table + +@node General Guidelines for Writing Mule-Aware Code +@subsection General Guidelines for Writing Mule-Aware Code + +This section contains some general guidance on how to write Mule-aware +code, as well as some pitfalls you should avoid. + +@table @emph +@item Never use @code{char} and @code{char *}. +In XEmacs, the use of @code{char} and @code{char *} is almost always a +mistake. If you want to manipulate an Emacs character from ``C'', use +@code{Emchar}. If you want to examine a specific octet in the internal +format, use @code{Bufbyte}. If you want a Lisp-visible character, use a +@code{Lisp_Object} and @code{make_char}. If you want a pointer to move +through the internal text, use @code{Bufbyte *}. Also note that you +almost certainly do not need @code{Emchar *}. + +@item Be careful not to confuse @code{Charcount}, @code{Bytecount}, and @code{Bufpos}. +The whole point of using different types is to avoid confusion about the +use of certain variables. Lest this effect be nullified, you need to be +careful about using the right types. + +@item Always convert external data +It is extremely important to always convert external data, because +XEmacs can crash if unexpected 8bit sequences are copied to its internal +buffers literally. + +This means that when a system function, such as @code{readdir}, returns +a string, you need to convert it using one of the conversion macros +described in the previous chapter, before passing it further to Lisp. +In the case of @code{readdir}, you would use the +@code{GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA} macro. + +Also note that many internal functions, such as @code{make_string}, +accept Bufbytes, which removes the need for them to convert the data +they receive. This increases efficiency because that way external data +needs to be decoded only once, when it is read. After that, it is +passed around in internal format. +@end table + +@node An Example of Mule-Aware Code +@subsection An Example of Mule-Aware Code + +As an example of Mule-aware code, we shall will analyze the +@code{string} function, which conses up a Lisp string from the character +arguments it receives. Here is the definition, pasted from +@code{alloc.c}: + +@example +@group +DEFUN ("string", Fstring, 0, MANY, 0, /* +Concatenate all the argument characters and make the result a string. +*/ + (int nargs, Lisp_Object *args)) +@{ + Bufbyte *storage = alloca_array (Bufbyte, nargs * MAX_EMCHAR_LEN); + Bufbyte *p = storage; + + for (; nargs; nargs--, args++) + @{ + Lisp_Object lisp_char = *args; + CHECK_CHAR_COERCE_INT (lisp_char); + p += set_charptr_emchar (p, XCHAR (lisp_char)); + @} + return make_string (storage, p - storage); +@} +@end group +@end example + +Now we can analyze the source line by line. + +Obviously, string will be as long as there are arguments to the +function. This is why we allocate @code{MAX_EMCHAR_LEN} * @var{nargs} +bytes on the stack, i.e. the worst-case number of bytes for @var{nargs} +@code{Emchar}s to fit in the string. + +Then, the loop checks that each element is a character, converting +integers in the process. Like many other functions in XEmacs, this +function silently accepts integers where characters are expected, for +historical and compatibility reasons. Unless you know what you are +doing, @code{CHECK_CHAR} will also suffice. @code{XCHAR (lisp_char)} +extracts the @code{Emchar} from the @code{Lisp_Object}, and +@code{set_charptr_emchar} stores it to storage, increasing @code{p} in +the process. + +Other instructing examples of correct coding under Mule can be found all +over XEmacs code. For starters, I recommend +@code{Fnormalize_menu_item_name} in @file{menubar.c}. After you have +understood this section of the manual and studied the examples, you can +proceed writing new Mule-aware code. + @node Techniques for XEmacs Developers @section Techniques for XEmacs Developers diff --git a/man/lispref/buffers.texi b/man/lispref/buffers.texi index e6b05d9..24008a5 100644 --- a/man/lispref/buffers.texi +++ b/man/lispref/buffers.texi @@ -890,27 +890,28 @@ when set for any reason. @xref{Buffer-Local Variables}. An @dfn{indirect buffer} shares the text of some other buffer, which is called the @dfn{base buffer} of the indirect buffer. In some ways it is the analogue, for buffers, of a symbolic link among files. The base -buffer may not itself be an indirect buffer. +buffer may not itself be an indirect buffer. One base buffer may have +several @dfn{indirect children}. The text of the indirect buffer is always identical to the text of its base buffer; changes made by editing either one are visible immediately -in the other. This includes the text properties as well as the characters -themselves. +in the other. But in all other respects, the indirect buffer and its base buffer are completely separate. They have different names, different values of -point, different narrowing, different markers and overlays (though -inserting or deleting text in either buffer relocates the markers and -overlays for both), different major modes, and different local -variables. +point and mark, different narrowing, different markers and extents +(though inserting or deleting text in either buffer relocates the +markers and extents for both), different major modes, and different +local variables. Unlike in FSF Emacs, XEmacs indirect buffers do not +automatically share text properties among themselves and their base +buffer. An indirect buffer cannot visit a file, but its base buffer can. If you try to save the indirect buffer, that actually works by saving the base buffer. Killing an indirect buffer has no effect on its base buffer. Killing -the base buffer effectively kills the indirect buffer in that it cannot -ever again be the current buffer. +the base buffer kills all its indirect children. @deffn Command make-indirect-buffer base-buffer name This creates an indirect buffer named @var{name} whose base buffer @@ -919,11 +920,39 @@ or a string. If @var{base-buffer} is an indirect buffer, its base buffer is used as the base for the new buffer. + +@example +@group +(make-indirect-buffer "*scratch*" "indirect") + @result{} # +@end group +@end example @end deffn -@defun buffer-base-buffer buffer +@defun buffer-base-buffer &optional buffer This function returns the base buffer of @var{buffer}. If @var{buffer} is not indirect, the value is @code{nil}. Otherwise, the value is -another buffer, which is never an indirect buffer. +another buffer, which is never an indirect buffer. If @var{buffer} is +not supplied, it defaults to the current buffer. + +@example +@group +(buffer-base-buffer (get-buffer "indirect")) + @result{} # +@end group +@end example @end defun +@defun buffer-indirect-children &optional buffer +This function returns a list of all indirect buffers whose base buffer +is @var{buffer}. If @var{buffer} is indirect, the return value will +always be nil; see @code{make-indirect-buffer}. If @var{buffer} is not +supplied, it defaults to the current buffer. + +@example +@group +(buffer-indirect-children (get-buffer "*scratch*")) + @result{} (#) +@end group +@end example +@end defun diff --git a/man/lispref/commands.texi b/man/lispref/commands.texi index 5056764..49b599c 100644 --- a/man/lispref/commands.texi +++ b/man/lispref/commands.texi @@ -834,7 +834,7 @@ at the time and the position of the pointer at the time. also specify the modifier keys that were held down at the time. @item misc-user event - A menu item was selected, the scrollbar was used, or a drag or a drop occured. + A menu item was selected, the scrollbar was used, or a drag or a drop occurred. @item process event Input is available on a process. @@ -1388,7 +1388,7 @@ Here are some basic examples of usage: @end group @group -;; @r{Create a simmilar button-release event.} +;; @r{Create a similar button-release event.} (make-event 'button-release `(button 1 modifiers (meta) x ,x y ,x)) @result{} # @end group diff --git a/man/lispref/display.texi b/man/lispref/display.texi index a663e14..3d1e992 100644 --- a/man/lispref/display.texi +++ b/man/lispref/display.texi @@ -359,7 +359,7 @@ in a separate buffer, and include an explanatory message that may span across several lines. Here is an example of how a warning is displayed: @example -(1) (initialization/error) An error has occured while loading ~/.emacs: +(1) (initialization/error) An error has occurred while loading ~/.emacs: Symbol's value as variable is void: bogus-variable @@ -499,11 +499,11 @@ applies to it. The list can have two kinds of elements: @table @code @item @var{atom} -A character is invisible if its @code{invisible} propery value +A character is invisible if its @code{invisible} property value is @var{atom} or if it is a list with @var{atom} as a member. @item (@var{atom} . t) -A character is invisible if its @code{invisible} propery value +A character is invisible if its @code{invisible} property value is @var{atom} or if it is a list with @var{atom} as a member. Moreover, if this character is at the end of a line and is followed by a visible newline, it displays an ellipsis. diff --git a/man/lispref/dragndrop.texi b/man/lispref/dragndrop.texi index 1757b61..ceab662 100644 --- a/man/lispref/dragndrop.texi +++ b/man/lispref/dragndrop.texi @@ -12,7 +12,7 @@ interface may change! The current implementation is considered experimental. Drag'n'drop is a way to transfer information between multiple applications. -To do this serveral GUIs define their own protocols. Examples are OffiX, CDE, +To do this several GUIs define their own protocols. Examples are OffiX, CDE, Motif, KDE, MSWindows, GNOME, and many more. To catch all these protocols, XEmacs provides a generic API. @@ -32,7 +32,7 @@ powerful interfaces to support these types of data (tm and w3). @section Supported Protocols The current release of XEmacs only support a small set of Drag'n'drop -protocols. Some of these only support limited options avaiable in the API. +protocols. Some of these only support limited options available in the API. @menu * OffiX DND:: A generic X based protocol. @@ -63,7 +63,7 @@ is dragged from XEmacs (well, not yet...). XEmacs supports both MIME and URL drags and drops using this API. No application interaction is possible while dragging is in progress. -For infomation about the OffiX project have a look at http://leb.net/~offix/ +For information about the OffiX project have a look at http://leb.net/~offix/ @node CDE dt @subsection CDE dt @@ -110,7 +110,7 @@ This misc-user-event has its function argument set to @code{experimental-dragdrop-drop-functions} for a function that can handle the dropped data. -To modify the drop behaviour, the user can modify the variable +To modify the drop behavior, the user can modify the variable @code{experimental-dragdrop-drop-functions}. Each element of this list specifies a possible handler for dropped data. The first one that can handle the data will return @code{t} and exit. Another possibility is to set a diff --git a/man/lispref/edebug-inc.texi b/man/lispref/edebug-inc.texi index 3245127..bce6dbc 100644 --- a/man/lispref/edebug-inc.texi +++ b/man/lispref/edebug-inc.texi @@ -355,7 +355,7 @@ Step into the function or macro after point after first ensuring that it is instrumented. It does this by calling @code{edebug-on-entry} and then switching to @code{go} mode. -Although the automatic instrumentating is convenient, it is not +Although the automatic instrumentation is convenient, it is not later automatically uninstrumented. @item h @@ -1411,7 +1411,7 @@ no higher alternatives may apply. @cindex backquote (Edebug) Backquote (@kbd{`}) is a macro that results in an expression that may or may not be evaluated. It is often used to simplify the definition of a -macro to return an expression that is evaluted, but Edebug does not know +macro to return an expression that is evaluated, but Edebug does not know when this is the case. However, the forms inside unquotes (@code{,} and @code{,@@}) are evaluated and Edebug instruments them. diff --git a/man/lispref/edebug.texi b/man/lispref/edebug.texi index 204bf7f..37f5ad4 100644 --- a/man/lispref/edebug.texi +++ b/man/lispref/edebug.texi @@ -147,7 +147,7 @@ much as it can of the bottom of the buffer, but I think it scrolls off sometimes. There is a bug in window updating when there is both a trace buffer -and an evaluation list - the source buffer doesnt get displayed. +and an evaluation list - the source buffer doesn't get displayed. @item Killing and reinserting an instrumented definition or parts of diff --git a/man/lispref/errors.texi b/man/lispref/errors.texi index 42be1cd..109b9c8 100644 --- a/man/lispref/errors.texi +++ b/man/lispref/errors.texi @@ -125,8 +125,6 @@ This is a @code{file-error}.@* @item setting-constant @code{"Attempt to set a constant symbol"}@* -The values of the symbols @code{nil} and @code{t} -may not be changed.@* @xref{Constant Variables, , Variables that Never Change}. @c XEmacs feature @@ -142,10 +140,6 @@ may not be changed.@* @item undefined-keystroke-sequence @code{"Undefined keystroke sequence"}@* -@c XEmacs feature -@item underflow-error -@code{"Arithmetic underflow error"}@* - @ignore FSF Emacs only @item undefined-color @code{"Undefined color"}@* diff --git a/man/lispref/files.texi b/man/lispref/files.texi index 8f1542b..7608b4a 100644 --- a/man/lispref/files.texi +++ b/man/lispref/files.texi @@ -1240,6 +1240,7 @@ as well as Unix syntax. * File Name Expansion:: Converting relative file names to absolute ones. * Unique File Names:: Generating names for temporary files. * File Name Completion:: Finding the completions for a given file name. +* User Name Completion:: Finding the completions for a given user name. @end menu @node File Name Components @@ -1763,6 +1764,41 @@ completion-ignored-extensions @end example @end defopt +@node User Name Completion +@subsection User Name Completion +@cindex user name completion subroutines +@cindex completion, user name + + This section describes low-level subroutines for completing a user +name. For other completion functions, see @ref{Completion}. + +@defun user-name-all-completions partial-username +This function returns a list of all possible completions for a user +whose name starts with @var{partial-username}. The order of the +completions is unpredictable and conveys no useful information. + +The argument @var{partial-username} must be a partial user name +containing no tilde character and no slash. +@end defun + +@defun user-name-completion username +This function completes the user name @var{username}. It returns the +longest prefix common to all user names that start with @var{username}. + +If only one match exists and @var{username} matches it exactly, the +function returns @code{t}. The function returns @code{nil} if no user +name starting with @var{username} exists. +@end defun + +@defun user-name-completion-1 username +This function completes the user name @var{username}, like +@code{user-name-completion}, differing only in the return value. +This function returns the cons of the completion returned by +@code{user-name-completion}, and a boolean indicating whether that +completion was unique. +@end defun + + @node Contents of Directories @section Contents of Directories @cindex directory-oriented functions diff --git a/man/lispref/lispref.texi b/man/lispref/lispref.texi index d50887e..ff9f0d9 100644 --- a/man/lispref/lispref.texi +++ b/man/lispref/lispref.texi @@ -140,6 +140,7 @@ Reference Manual, corresponding to XEmacs version 21.0. * Functions:: A function is a Lisp program that can be invoked from other functions. * Macros:: Macros are a way to extend the Lisp language. +* Customization:: Writing customization declarations. * Loading:: Reading files of Lisp code into Lisp. * Byte Compilation:: Compilation makes programs run faster. @@ -1144,6 +1145,7 @@ Building XEmacs and Object Allocation @include variables.texi @include functions.texi @include macros.texi +@include customize.texi @include loading.texi @include compile.texi diff --git a/man/lispref/menus.texi b/man/lispref/menus.texi index 3b98c08..713aef1 100644 --- a/man/lispref/menus.texi +++ b/man/lispref/menus.texi @@ -644,7 +644,7 @@ keys, the return key and the escape key are defined to traverse the menus in a way that should be familiar to users of any of a certain family of popular PC operating systems. -This behaviour can be changed by modifying the bindings in +This behavior can be changed by modifying the bindings in menu-accelerator-map. At this point, the online help is your best bet for more information about how to modify the menu traversal keys. @@ -685,7 +685,7 @@ occurring while the menubar is active. @xref{Keyboard Menu Traversal}. @defvar menu-accelerator-modifiers A list of modifier keys which must be pressed in addition to a valid menu accelerator in order for the top level menu to be activated in response to -a keystroke. The default value of @code{(meta)} mirrors the useage of the alt key +a keystroke. The default value of @code{(meta)} mirrors the usage of the alt key as a menu accelerator in popular PC operating systems. The modifier keys in @var{menu-accelerator-modifiers} must match exactly the diff --git a/man/lispref/modes.texi b/man/lispref/modes.texi index dc6ebb9..0a05e5f 100644 --- a/man/lispref/modes.texi +++ b/man/lispref/modes.texi @@ -634,7 +634,7 @@ Here is an example of how to prepend several pattern pairs to @end defvar @defvar interpreter-mode-alist -This variable specifes major modes to use for scripts that specify a +This variable specifies major modes to use for scripts that specify a command interpreter in an @samp{#!} line. Its value is a list of elements of the form @code{(@var{interpreter} . @var{mode})}; for example, @code{("perl" . perl-mode)} is one element present by default. diff --git a/man/lispref/objects.texi b/man/lispref/objects.texi index e74584f..97ab831 100644 --- a/man/lispref/objects.texi +++ b/man/lispref/objects.texi @@ -2202,7 +2202,7 @@ the same name are not @code{eq}. @xref{Creating Symbols}.) NOTE: Under XEmacs 19, characters are really just integers, and thus characters and integers are @code{eq}. Under XEmacs 20, it was -necessary to preserve remants of this in function such as @code{old-eq} +necessary to preserve remnants of this in function such as @code{old-eq} in order to maintain byte-code compatibility. Byte code compiled under any Emacs 19 will automatically have calls to @code{eq} mapped to @code{old-eq} when executed under XEmacs 20. diff --git a/man/lispref/os.texi b/man/lispref/os.texi index 0e6bce6..b79830b 100644 --- a/man/lispref/os.texi +++ b/man/lispref/os.texi @@ -1540,7 +1540,7 @@ computer): This function is used to open a @dfn{termscript file} that will record all the characters sent by XEmacs to the terminal. (If there are multiple tty or stream devices, all characters sent to all such devices -are recorded.) The funcion returns @code{nil}. Termscript files are +are recorded.) The function returns @code{nil}. Termscript files are useful for investigating problems where XEmacs garbles the screen, problems that are due to incorrect Termcap entries or to undesirable settings of terminal options more often than to actual XEmacs bugs. diff --git a/man/lispref/positions.texi b/man/lispref/positions.texi index e52319d..0030e51 100644 --- a/man/lispref/positions.texi +++ b/man/lispref/positions.texi @@ -901,7 +901,7 @@ before you try it. If @var{body} changes the current buffer, @code{save-restriction} still restores the restrictions on the original buffer (the buffer whose -restructions it saved from), but it does not restore the identity of the +restrictions it saved from), but it does not restore the identity of the current buffer. @code{save-restriction} does @emph{not} restore point and the mark; use diff --git a/man/lispref/searching.texi b/man/lispref/searching.texi index 95b1fa9..db7eadc 100644 --- a/man/lispref/searching.texi +++ b/man/lispref/searching.texi @@ -263,7 +263,7 @@ all three strings. @cindex @samp{?} in regexp is a quantifying suffix operator similar to @samp{*}, except that the preceding expression can match either once or not at all. For example, -@samp{ca?r} matches @samp{car} or @samp{cr}, but does not match anyhing +@samp{ca?r} matches @samp{car} or @samp{cr}, but does not match anything else. @item *? @@ -1096,7 +1096,7 @@ last regular expression searched for, or a subexpression of it. If @var{count} is zero, then the value is the position of the start of the entire match. Otherwise, @var{count} specifies a subexpression in -the regular expresion, and the value of the function is the starting +the regular expression, and the value of the function is the starting position of the match for that subexpression. The value is @code{nil} for a subexpression inside a @samp{\|} diff --git a/man/lispref/tooltalk.texi b/man/lispref/tooltalk.texi index 01f176c..d309307 100644 --- a/man/lispref/tooltalk.texi +++ b/man/lispref/tooltalk.texi @@ -225,7 +225,7 @@ nulls (use @code{arg_bval}). @defun create-tooltalk-message Create a new ToolTalk message. The message's session attribute is -initialized to the default session. Other attributes can be intialized +initialized to the default session. Other attributes can be initialized with @code{set-tooltalk-message-attribute}. @code{make-tooltalk-message} is the preferred way to create and initialize a message. diff --git a/man/lispref/variables.texi b/man/lispref/variables.texi index 5af0fe5..d5d5ab5 100644 --- a/man/lispref/variables.texi +++ b/man/lispref/variables.texi @@ -95,10 +95,12 @@ x @vindex t @kindex setting-constant - XEmacs Lisp has two special symbols, @code{nil} and @code{t}, that -always evaluate to themselves. These symbols cannot be rebound, nor can -their value cells be changed. An attempt to change the value of -@code{nil} or @code{t} signals a @code{setting-constant} error. +In XEmacs Lisp, some symbols always evaluate to themselves: the two +special symbols @code{nil} and @code{t}, as well as @dfn{keyword +symbols}, that is, symbols whose name begins with the character +@samp{@code{:}}. These symbols cannot be rebound, nor can their value +cells be changed. An attempt to change the value of @code{nil} or +@code{t} signals a @code{setting-constant} error. @example @group @@ -433,7 +435,7 @@ XEmacs help functions (@pxref{Documentation}) look for this property. If the first character of @var{doc-string} is @samp{*}, it means that this variable is considered a user option. This lets users set the -variable conventiently using the commands @code{set-variable} and +variable conveniently using the commands @code{set-variable} and @code{edit-options}. For example, this form defines @code{foo} but does not set its value: diff --git a/man/xemacs/calendar.texi b/man/xemacs/calendar.texi index 1344fdc..d935a1d 100644 --- a/man/xemacs/calendar.texi +++ b/man/xemacs/calendar.texi @@ -194,7 +194,7 @@ then centers the three-month calendar around that month. @kindex . @r{(Calendar mode)} @findex calendar-goto-today - You can return to today's date with @kbd{.} + You can return to today's date with @kbd{.}@: (@code{calendar-goto-today}). @node Scroll Calendar, Mark and Region, Calendar Motion, Calendar/Diary @@ -393,7 +393,7 @@ Generate a calendar for one year (@code{cal-tex-cursor-year}). @item t Y Generate a sideways-printing calendar for one year -(@code{cal-tex-cursor-landscape-year}). +(@code{cal-tex-cursor-year-landscape}). @item t f y Generate a Filofax-style calendar for one year (@code{cal-tex-cursor-filofax-year}). @@ -480,7 +480,7 @@ equinoxes. @findex list-holidays The command @kbd{M-x list-holidays} displays the list of holidays for a range of years. This function asks you for the starting and stopping -years, and allows you to chose all the holidays or one of several +years, and allows you to choose all the holidays or one of several categories of holidays. You can use this command even if you don't have a calendar window. @@ -998,6 +998,8 @@ Unmark the calendar window (@code{calendar-unmark}). Print hard copy of the diary display as it appears. @item M-x diary Display all diary entries for today's date. +@item M-x diary-mail-entries +Mail yourself email reminders about upcoming diary entries. @end table @kindex d @r{(Calendar mode)} @@ -1054,6 +1056,14 @@ automatically displays a window with the day's diary entries, when you enter Emacs. The mode line of the displayed window shows the date and any holidays that fall on that date. +@findex diary-mail-entries +@vindex diary-mail-days + Many users like to receive notice of events in their diary as email. +To send such mail to yourself, use the command @kbd{M-x +diary-mail-entries}. A prefix argument specifies how many days +(starting with today) to check; otherwise, the variable +@code{diary-mail-days} says how many days. + @node Format of Diary File, Date Formats, Diary Commands, Diary @subsection The Diary File @cindex diary file @@ -1216,10 +1226,6 @@ diary entry with the @kbd{i y} command. All of the above commands make marking diary entries by default. To make a nonmarking diary entry, give a numeric argument to the command. For example, @kbd{C-u i w} makes a nonmarking weekly diary entry. - - All of the above commands make marking diary entries. If you want the diary -entry to be nonmarking, give a prefix argument to the command. For example, -@kbd{C-u i w} makes a nonmarking, weekly diary entry. When you modify the diary file, be sure to save the file before exiting Emacs. @@ -1760,9 +1766,9 @@ ends, in the form of a list @code{(@var{month} @var{day} @var{year})}. The values should be @code{nil} if your area does not use daylight savings time. - Emacs uses these expressions to determine the start and end dates of -daylight savings time as holidays and for correcting times of day in the -solar and lunar calculations. + Emacs uses these expressions to determine the starting date of +daylight savings time for the holiday list and for correcting times of +day in the solar and lunar calculations. The values for Cambridge, Massachusetts are as follows: @@ -1774,7 +1780,7 @@ solar and lunar calculations. @end example @noindent -i.e., the first 0th day (Sunday) of the fourth month (April) in +That is, the first 0th day (Sunday) of the fourth month (April) in the year specified by @code{year}, and the last Sunday of the tenth month (October) of that year. If daylight savings time were changed to start on October 1, you would set @@ -1809,10 +1815,10 @@ minutes. The value for Cambridge, Massachusetts is 60. @c @vindex calendar-daylight-savings-starts-time too long! @vindex calendar-daylight-savings-ends-time - The variable @code{calendar-daylight-savings-starts-time} and the -variable @code{calendar-daylight-savings-ends-time} specify the number -of minutes after midnight local time when the transition to and from -daylight savings time should occur. For Cambridge, both variables' + The two variables @code{calendar-daylight-savings-starts-time} and +@code{calendar-daylight-savings-ends-time} specify the number of minutes +after midnight local time when the transition to and from daylight +savings time should occur. For Cambridge, Massachusetts both variables' values are 120. @node Diary Customizing diff --git a/man/xemacs/packages.texi b/man/xemacs/packages.texi index 66166b8..3066210 100644 --- a/man/xemacs/packages.texi +++ b/man/xemacs/packages.texi @@ -1,7 +1,7 @@ @node Packages, Abbrevs, Running, Top @comment node-name, next, previous, up -@section Introduction to XEmacs Packages +@section Packages @cindex packages The XEmacs 21 distribution comes only with a very basic set of @@ -12,16 +12,27 @@ packages to install; the actual installation process is easy. This gives an installer the ability to tailor an XEmacs installation for local needs with safe removal of unnecessary code. +@menu +* Package Terminology:: Understanding different kinds of packages. +* Using Packages:: How to install and use packages. +* Building Packages:: Building packages from sources. +@end menu + +@node Package Terminology, Using Packages, , Packages +@comment node-name, next, previous, up + @subsection Package Flavors There are two main flavors of packages. -@itemize @emph +@itemize @bullet @item Regular Packages +@cindex regular packages A regular package is one in which multiple files are involved and one may not in general safely remove any of them. @item Single-File Packages +@cindex single-file packages A single-file package is an aggregate collection of thematically related but otherwise independent lisp files. These files are bundled together for download convenience and individual files may deleted at @@ -37,17 +48,272 @@ are for developers and include all files necessary for rebuilding bytecompiled lisp and creating tarballs for distribution. @subsection Binary Packages +@cindex binary packages Binary packages may be installed directly into an XEmacs package hierarchy. @subsection Source Packages - +@cindex source packages Source packages contain all of the Package author's (where appropriate in regular packages) source code plus all of the files necessary to build distribution tarballs (Unix Tar format files and gzipped for space savings). -@subsection Prerequisites for building Source Packages +@node Using Packages, Building Packages, Package Terminology, Packages +@comment node-name, next, previous, up + +@subsection Getting Started + +When you first download XEmacs 21, you will usually first grab the +@dfn{core distribution}, +@cindex core distribution +a file called +@file{xemacs-21.0.tar.gz}. (Replace the @t{21.0} by the current version +number.) The core distribution contains the sources of XEmacs and a +minimal set of Emacs Lisp files, which are in the subdirectory named +@file{lisp}. This subdirectory used to contain all Emacs Lisp files +distributed with XEmacs. Now, to conserve disk space, most +non-essential packages were made optional. + +@subsection Choosing the Packages You Need + +The available packages can currently be found in the same ftp directory +where you grabbed the core distribition from, and are located in the +subdirectory @file{packages/binary-packages}. Package file names follow +the naming convention @file{--pkg.tar.gz}. + +If you have EFS @ref{(EFS)}, packages can be installed over the network. +Alternatively, if you have copies of the packages locally, you can +install packages from a local disk or CDROM. + +The file @file{etc/PACKAGES} in the core distribution contains a list of +the packages available at the time of the XEmacs release. Packages are +also listed on the @code{Options} menu under: + +@example + Options->Customize->Emacs->Packages +@end example + +However, don't select any of these menu picks unless you actually want +to install the given package (and have properly configured your system +to do so). + +You can also get a list of available packages, and whether or not they +are installed, using the visual package browser and installer. You can +access it via the menus: + +@example + Options->Customize->List Packages +@end example + +Or, you can get to it via the keyboard: + +@example +M-x pui-list-packages +@end example + +Hint to system administrators of multi-user systems: it might be a good +idea to install all packages and not interfere with the wishes of your +users. + +@subsection XEmacs and Installing Packages + +Normally, packages are installed over the network, using EFS +@ref{(EFS)}. However, you may not have network access, or you may +already have some or all of the packages on a local disk, such as a +CDROM. If you want to install from a local disk, you must first tell +XEmacs where to find the package binaries. This is done by adding a line +like the following to your @file{.emacs} file: + +@example +(setq package-get-remote (cons (list nil "/my/path/to/package/binaries") + package-get-remote)) +@end example + +Here, you'd change @file{/my/path/to/package/binaries} to be the path +to your local package binaries. Next, restart XEmacs, and you're ready +to go (advanced users can just re-evaluate the sexp). + +If you are installing from a temporary, one-time directory, you can also +add these directory names to @code{package-get-remote} using: + +@example + M-x pui-add-install-directory +@end example + +Note, however, that any directories added using this function are not +saved; this information will be lost when you quit XEmacs. + +If you're going to install over the network, you only have to insure +that EFS @ref{(EFS)} works, and that it can get outside a firewall, if +you happen to be behind one. You shouldn't have to do anything else; +XEmacs already knows where to go. + +The easiest way to install a package is to use the visual package +browser and installer, using the menu pick: + +@example + Options->Customize->List Packages +@end example + +You can also access it using the keyboard: + +@example +M-x pui-list-packages +@end example + +The visual package browser will then display a list of all packages. +Help information will be displayed at the very bottom of the buffer; you +may have to scroll down to see it. You can also press @kbd{?} to get +the same help. From this buffer, you can tell the package status by the +character in the first column: + +@table @kbd +@item - +The package has not been installed. +@item * +The package has been installed, but a newer version is available. The +current version is out-of-date. +@item + +The package has been marked for installation/update. +@end table + +If there is no character in the first column, the package has been +installed and is up-to-date. + +From here, you can select or unselect packages for installation using +the @key{RET} key, or using the @kbd{Mouse-2} or @kbd{Mouse-3} buttons. +Once you've finished selecting the packages, you can press the @kbd{x} +key to actually install the packages. Note that you will have to +restart XEmacs for XEmacs to recognize any new packages. + +Key summary: + +@table @kbd +@item ? +Display simple help. +@item @key{RET} +@itemx @key{Mouse-2} +@itemx @key{Mouse-3} +Toggle between selecting and unselecting a package for installation. +@item x +Install selected packages. +@item @key{SPC} +View, in the minibuffer, additional information about the package, such +as the package date (not the build date) and the package author. Moving +the mouse over a package name will also do the same thing. +@item v +Toggle between verbose and non-verbose package display. +@item g +Refresh the package display. +@item q +Kill the package buffer. +@end table + +Moving the mouse over a package will also cause additional information +about the package to be displayed in the minibuffer. + +@subsection Other package installation interfaces + +For an alternative package interface, you can select packages from the +customize menus, under: + +@example + Options->Customize->Emacs->Packages-> ... +@end example + +Set their state to on, and then do: + +@example + Options->Customize->Update Packages +@end example + +This will automatically retrieve the packages you have selected from the +XEmacs ftp site or your local disk, and install them into +XEmacs. Additionally it will update any packages you already have +installed to the newest version. Note that if a package is newly +installed you will have to restart XEmacs for the change to take effect. + +You can also install packages using a semi-manual interface: + +@example +M-x package-get-all +@end example + +Enter the name of the package (e.g., @code{prog-modes}), and XEmacs +will search for the latest version (as listed in the lisp file +@file{lisp/package-get-base.el}), and install it and any packages that +it depends upon. + +@subsection Manual Binary Package Installation + +Pre-compiled, binary packages can be installed in either a system +package directory (this is determined when XEmacs is compiled), or in a +subdirectory off your @file{$HOME} directory: + +@example +~/.xemacs/packages +@end example + +XEmacs does not have to be running to install binary packages, although +XEmacs will not know about any newly-installed packages until you +restart XEmacs. Note, however, that installing a newer version of a +package while XEmacs is running could cause strange errors in XEmacs; +it's best to exit XEmacs before upgrading an existing package. + +To install binary packages manually: + +@enumerate +@item +Download the package(s) that you want to install. Each binary package +will typically be a gzip'd tarball. + +@item +Decide where to install the packages: in the system package directory, +or in @file{~/.xemacs/packages}. If you want to install the +packages in the system package directory, make sure you can write into +that directory. If you want to install in your @file{$HOME} directory, +create the directory, @file{~/.xemacs/packages}. + +@item +Next, @code{cd} to the directory under which you want to install the +package(s). + +@item +From this directory, uncompress and extract each of the gzip'd tarballs +that you downloaded in step 1. Unix and Cygnus cygwin users will +typically do this using the commands: + +@example + gunzip < package.tar.gz | tar xvf - +@end example + +Above, replace @file{package.tar.gz} with the filename of the +package that you downloaded in step 1. + +Of course, if you use GNU @code{tar}, you could also use: + +@example + tar xvzf package.tar.gz +@end example + +@comment What about native MS Windows users??? + +@item +That's it. Quit and restart XEmacs to get it to recognize any new or +changed packages. + +@end enumerate + +@node Building Packages, , Using Packages, Packages +@comment node-name, next, previous, up + +Source packages are available from the @file{packages/source-packages} +subdirectory of your favorite XEmacs distribution site. Alternatively, +they are available via CVS from @file{cvs.xemacs.org}. Look at +@file{http://cvs.xemacs.org} for instructions. + +@subsection Prerequisites for Building Source Packages You must have GNU @code{cp}, GNU @code{install} (or a BSD compatible @code{install} program) GNU @code{make} (3.75 or later preferred), @@ -58,7 +324,7 @@ correct directory structure. At the top level you must have available from the XEmacs FTP site from the same place you obtained your source package distributions. -@subsection What you can do with Source Packages +@subsection What You Can Do With Source Packages NB: A global build operation doesn't exist yet as of 13 January 1998. @@ -66,7 +332,7 @@ Source packages are most useful for creating XEmacs package tarballs for installation into your own XEmacs installations or for distributing to others. -Supported operations from Make are: +Supported operations from @file{make} are: @table @code @item clean diff --git a/man/xemacs/startup.texi b/man/xemacs/startup.texi index 72e1260..a3d488e 100644 --- a/man/xemacs/startup.texi +++ b/man/xemacs/startup.texi @@ -8,7 +8,7 @@ XEmacs deals with a multitude of files during operation. These files are spread over many directories, and XEmacs determines the location of most of these directories at startup and organizes them into various -paths. (A @emph{path}, +paths. (A @dfn{path}, @cindex path for the purposes of this section, is simply a list of directories which XEmacs searches successively in order to locate a file.) @@ -30,12 +30,12 @@ matter where they may be hidden. XEmacs will always respect directory options passed to @code{configure}. However, if it cannot locate a directory at the configured place, it will initiate a search for the directory in any of a number of -@emph{hierachies} rooted under a directory which XEmacs assumes contain +@dfn{hierachies} rooted under a directory which XEmacs assumes contain parts of the XEmacs installation; it may locate several such hierarchies and search across them. (Typically, there are just one or two hierarchies: the hierarchy where XEmacs was or will be installed, and the one where it is being built.) Such a directory containing a -hierarchy is called a @emph{root}. +hierarchy is called a @dfn{root}. @cindex root of a hierarchy Whenever this section refers to a directory using the shorthand @code{}, it means that XEmacs searches for it under all @@ -53,8 +53,8 @@ usually installed on top of an XEmacs installation. (@xref{Packages}.) Hence, they play a prominent role in the various paths XEmacs sets up. XEmacs locates packages in any of a number of package hierarchies. -Package hierarchies fall into three groups: @emph{early}, @emph{late}, -and @emph{last}, +Package hierarchies fall into three groups: @dfn{early}, @dfn{late}, +and @dfn{last}, @cindex early package hierarchies @cindex late package hierarchies @cindex last package hierarchies @@ -69,16 +69,16 @@ subdirectory @file{.xemacs} of the user's home directory. Moreover, XEmacs expects late hierarchies in the subdirectories @file{site-packages}, @file{mule-packages}, and @file{xemacs-packages} (in that order) of the @file{/lib/xemacs} subdirectory of one of -the installation hierarchies. (If you run in-place, these are directr +the installation hierarchies. (If you run in-place, these are direct subdirectories of the build directory.) Furthermore, XEmacs will also search these subdirectories in the @file{/lib/xemacs-} subdirectory and prefer directories found there. By default, XEmacs does not have a pre-configured last package -hierarchy. Last hierarchies are primarily for using package -hierarchies of outdated versions of XEmacs as a fallback option. For -example, it is possible to run XEmacs with the 20.4 package hierarchy -as a last hierarchy. +hierarchy. Last hierarchies are primarily for using package hierarchies +of outdated versions of XEmacs as a fallback option. For example, it is +possible to run XEmacs 21.0 with the 20.4 package hierarchy as a last +hierarchy. It is possible to specify at configure-time the location of the various package hierarchies with the @code{--package-path} option to configure. @@ -103,17 +103,20 @@ There may be any number of package hierarchy directories. Here is a list of the various directories and paths XEmacs tries to locate during startup. XEmacs distinguishes between directories and -paths specific to @emph{version}, @emph{site}, and @emph{architecture} +paths specific to @dfn{version}, @dfn{site}, and @dfn{architecture} when looking for them. @table @code @item version-specific +@cindex version-specific directories directories are specific to the version of XEmacs they belong to and typically reside under @file{/lib/xemacs-}. @item site-specific +@cindex site-specific directories directories are independent of the version of XEmacs they belong to and typically reside under @file{/lib/xemacs} @item architecture-specific +@cindex architecture-specific directories directories are specific both to the version of XEmacs and the architecture it runs on and typically reside under @file{/lib/xemacs-/}. @@ -177,7 +180,7 @@ the package executable paths as well as @code{exec-directory}, and the directories of the environment variables @code{PATH} @vindex PATH and @code{EMACSPATH}. -@vindex EMCSPATH +@vindex EMACSPATH @item doc-directory @vindex doc-directory diff --git a/man/xemacs/xemacs.texi b/man/xemacs/xemacs.texi index 607ffee..82ccfb2 100644 --- a/man/xemacs/xemacs.texi +++ b/man/xemacs/xemacs.texi @@ -93,7 +93,7 @@ The XEmacs Editor XEmacs is the extensible, customizable, self-documenting real-time display editor. This Info file describes how to edit with Emacs and some of how to customize it, but not how to extend it. It -corresponds to XEmacs version 20.0. +corresponds to XEmacs version 21.0. This manual is intended as a detailed reference to XEmacs. If you are looking for an introductory manual, see the New User's @@ -497,7 +497,11 @@ Lisp Libraries * Mocklisp:: Converting Mocklisp to Lisp so XEmacs can run it. Packages + * Packages:: Introduction to XEmacs Packages. +* Package Terminology:: Understanding different kinds of packages. +* Using Packages:: How to install and use packages. +* Building Packages:: Building packages from sources. Abbrevs diff --git a/nt/ChangeLog b/nt/ChangeLog index 3acbeb7..6374d51 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog @@ -1,3 +1,59 @@ +1998-09-29 SL Baur + + * XEmacs 21.2-beta2 is released. + +1998-09-19 Adrian Aichner + + * tiff.mak: New file provided by Charles Wilson + + + * README: Update provided by Charles Wilson + . Documenting use of the newly + introduced tiff.mak. Renumbering subsequent build instruction + items. + +1998-09-20 Jonathan Harris + + * PROBLEMS: New file. + + * xemacs.mak: Install the PROBLEMS file in the root directory of + the XEmacs installation. + +1998-08-31 Jonathan Harris + + * xemacs.mak: Detect failure to supply PNG_DIR or XLIB_DIR + when building with PNG support. + +1998-08-31 Jonathan Harris + + * README: Document the PNG, ZLIB, JPEG, TIFF and GIF build + options. + +1998-08-12 Jeff Sparkes + + * xemacs.mak: Link in GIF, fix HAVE_JPEG default. + +1998-08-09 Jonathan Harris + + * xemacs.mak (install): Win95 fixes: + DOS mkdir doesn't create intermediate directories. xcopy does + so use it to create the install and lock directories. + Removed trailing backslashes from copy commands since DOS + copy doesn't like them. + +1998-08-05 Charles G. Waldman + + * xemacs.mak: change "copy" to "xcopy" in install target + +1998-08-04 Jeff Sparkes + + * xemacs.mak: Link in PNG, TIFF and JPEG in native build. + +1998-08-04 Jonathan Harris + + * README: XEmacs has been successfully built with MSVC 4.0. + Mention the vcvars32.bat file installed with the MSVC tools. + 1998-07-19 SL Baur * XEmacs 21.2-beta1 is released. diff --git a/nt/README b/nt/README index 9dfe3f5..6906c1a 100644 --- a/nt/README +++ b/nt/README @@ -10,11 +10,15 @@ from http://www.cs.washington.edu/homes/voelker/ntemacs.html To get it working you will need: -1. You will need Visual C++ V4.2 or later to compile everything. Personally we - have tested V4.2 and V5.0. +1. You will need Visual C++ V4.0 or later to compile everything. Personally we + have tested V4.0, V4.2 and V5.0. Note that Visual C++ assumes a couple of environment variables INCLUDE and LIB to be set which specify the location of the includes and libraries. - At this point you can select X or Win32 native support. + Your PATH environment variable also needs to include the DevStudio vc\bin + and sharedide\bin directories. + Visual C++ V5.0 installs a batch file called vcvars32.bat in + c:\Program Files\DevStudio\VC\bin\ (or wherever you installed it) that you + can run before building to set up all of these environment variables. 2. Grab the latest XEmacs source from ftp.xemacs.org if necessary. All Win32 support is in the nt\ subdirectory. You'll also need the xemacs-base @@ -22,41 +26,72 @@ To get it working you will need: want at least the edit-utils, text-utils, cc-mode and prog-utils packages. Unpack the packages into, say, "c:\Program Files\XEmacs\packages". +3. At this point you can select X or Win32 native GUI support. If you want to build for native GUI: -1. If you want XPM and toolbar support grab the latest version of the xpm - sources (xpm-3.4k.tar.gz at time of writing) and unpack them somewhere. +1. If you want XPM image and toolbar support grab the latest version of the + xpm sources (xpm-3.4k.tar.gz at time of writing) and unpack them somewhere. Copy nt\xpm.mak from the xemacs sources to the lib subdirectory of the - xpm sources, cd to that directory and build xpm with `nmake -f xpm.mak`. + xpm sources, cd to that directory and build xpm with 'nmake -f xpm.mak'. -2. cd to the nt subdirectory of the xemacs distribution and build xemacs: +2. You probably also want PNG image support. Grab the latest versions of zlib + and libpng (zlib-1.1.3 and libpng-1.0.2 at time of writing), unpack them + somewhere and read the respective READMEs for details on how to build them. + The following build procedure works for zlib-1.1.3 and libpng-1.0.2: + + cd to the zlib directory, type 'copy msdos\makefile.w32 Makefile' and + then type 'nmake'. + + cd to the libpng directory, rename or move the zlib directory to ..\zlib + and type 'nmake -f scripts\makefile.w32'. + +3. If you want TIFF support, grap the latest version of libtiff (tiff-v3.4 + at time of writing) and unpack it somewhere. Copy nt\tiff.mak from the + xemacs sources to the contrib\winnt subdirectory of the tiff sources, + cd to that directory and build libtiff with 'nmake -f tiff.mak'. Note: + tiff.mak has only been verified to work under WinNT, not Win95 or 98. + However, the lastest distribution of libtiff includes a + contrib\win95\makefile.w95; that might work. + +4. If you want JPEG support grab the latest version of jpegsrc (jpeg-6b at + time of writing) and read the README for details on how to build it. + +5. cd to the nt subdirectory of the xemacs distribution and build xemacs: `nmake install -f xemacs.mak`, but read on before hitting Enter. -3. If you're building with XPM support, add this to the nmake command line: - HAVE_XPM=1 XPM_DIR="x:\location\of\your\xpm\source\tree" +6. If you're building with XPM support, add this to the nmake command line: + HAVE_XPM=1 XPM_DIR="x:\location\of\your\xpm\sources" + and similarly for JPEG and TIFF support. + + If you're building with PNG support, add this to the nmake command line: + HAVE_PNG=1 PNG_DIR="x:\location\of\your\png\sources" + ZLIB_DIR="x:\location\of\your\zlib\sources" + + If you want to build with GIF support, add this to the nmake command line: + HAVE_GIF=1 -4. By default, XEmacs will look for packages in +7. By default, XEmacs will look for packages in "c:\Program Files\XEmacs\packages". If you want it to look elsewhere, add this to the nmake command line: PACKAGEPATH="x:\\location\\of\\your\\packages" Note the doubled-up backslashes in that path. If you want to change the package path after you've already built XEmacs, delete the file - .\obj\emacs.obj and rebuild with the new value of PACKAGEPATH. + .\obj\emacs.obj before rebuilding with the new value of PACKAGEPATH. -5. By default, XEmacs will be installed in directories under the directory +8. By default, XEmacs will be installed in directories under the directory "c:\Program Files\XEmacs\XEmacs-21.0". If you want to install it elsewhere, add this to the nmake command line: INSTALL_DIR="x:\your\installation\directory" -6. Now you can press Enter. nmake will build temacs, the DOC file, update the +9. Now you can press Enter. nmake will build temacs, the DOC file, update the elc's, dump xemacs and install the relevant files in the directories under - the installation directory. Unless you set INSTALL_DIR in step 5 above, the - file that you should run to start XEmacs will be installed as + the installation directory. Unless you set INSTALL_DIR above, the file that + you should run to start XEmacs will be installed as "c:\Program Files\XEmacs\XEmacs-21.0\i386-pc-win32\runemacs.exe". You may want to create a shortcut to that file from your Desktop or Start Menu. -7. The build process always creates debugging and "Source Browser" information +10. The build process always creates debugging and "Source Browser" information in the source tree for use with MS DevStudio. If you actually want to debug XEmacs you should run XEmacs from the source directory instead of from the installation directory. You should probably also build a debug version of diff --git a/nt/xemacs.mak b/nt/xemacs.mak index ee3b96a..1a45c4f 100644 --- a/nt/xemacs.mak +++ b/nt/xemacs.mak @@ -82,6 +82,18 @@ HAVE_MULE=0 !if !defined(HAVE_XPM) HAVE_XPM=0 !endif +!if !defined(HAVE_PNG) +HAVE_PNG=0 +!endif +!if !defined(HAVE_TIFF) +HAVE_TIFF=0 +!endif +!if !defined(HAVE_JPEG) +HAVE_JPEG=0 +!endif +!if !defined(HAVE_GIF) +HAVE_GIF=1 +!endif !if !defined(HAVE_TOOLBARS) HAVE_TOOLBARS=$(HAVE_XPM) !endif @@ -152,6 +164,38 @@ CONFIG_ERROR=1 !message Specified XPM directory does not contain "$(XPM_DIR)\lib\Xpm.lib" CONFIG_ERROR=1 !endif +!if $(HAVE_MSW) && $(HAVE_PNG) && !defined(PNG_DIR) +!message Please specify root directory for your PNG installation: PNG_DIR=path +CONFIG_ERROR=1 +!endif +!if $(HAVE_MSW) && $(HAVE_PNG) && defined(PNG_DIR) && !exist("$(PNG_DIR)\libpng.lib") +!message Specified PNG directory does not contain "$(PNG_DIR)\libpng.lib" +CONFIG_ERROR=1 +!endif +!if $(HAVE_MSW) && $(HAVE_PNG) && !defined(ZLIB_DIR) +!message Please specify root directory for your ZLIB installation: ZLIB_DIR=path +CONFIG_ERROR=1 +!endif +!if $(HAVE_MSW) && $(HAVE_PNG) && defined(ZLIB_DIR) && !exist("$(ZLIB_DIR)\zlib.lib") +!message Specified ZLIB directory does not contain "$(ZLIB_DIR)\zlib.lib" +CONFIG_ERROR=1 +!endif +!if $(HAVE_MSW) && $(HAVE_TIFF) && !defined(TIFF_DIR) +!message Please specify root directory for your TIFF installation: TIFF_DIR=path +CONFIG_ERROR=1 +!endif +!if $(HAVE_MSW) && $(HAVE_TIFF) && !exist("$(TIFF_DIR)\libtiff\libtiff.lib") +!message Specified TIFF directory does not contain "$(TIFF_DIR)\libtiff\libtiff.lib" +CONFIG_ERROR=1 +!endif +!if $(HAVE_MSW) && $(HAVE_JPEG) && !defined(JPEG_DIR) +!message Please specify root directory for your JPEG installation: JPEG_DIR=path +CONFIG_ERROR=1 +!endif +!if $(HAVE_MSW) && $(HAVE_JPEG) && !exist("$(JPEG_DIR)\libjpeg.lib") +!message Specified JPEG directory does not contain "$(JPEG_DIR)\libjpeg.lib" +CONFIG_ERROR=1 +!endif !if $(HAVE_MSW) && $(HAVE_TOOLBARS) && !$(HAVE_XPM) !error Toolbars require XPM support CONFIG_ERROR=1 @@ -195,6 +239,18 @@ USE_INDEXED_LRECORD_IMPLEMENTATION=$(GUNG_HO) !if $(HAVE_XPM) !message Compiling in support for XPM images. !endif +!if $(HAVE_GIF) +!message Compiling in support for GIF images. +!endif +!if $(HAVE_PNG) +!message Compiling in support for PNG images. +!endif +!if $(HAVE_TIFF) +!message Compiling in support for TIFF images. +!endif +!if $(HAVE_JPEG) +!message Compiling in support for JPEG images. +!endif !if $(HAVE_TOOLBARS) !message Compiling in support for toolbars. !endif @@ -266,6 +322,26 @@ MSW_DEFINES=$(MSW_DEFINES) -DHAVE_XPM -DFOR_MSW MSW_INCLUDES=$(MSW_INCLUDES) -I"$(XPM_DIR)" -I"$(XPM_DIR)\lib" MSW_LIBS=$(MSW_LIBS) "$(XPM_DIR)\lib\Xpm.lib" !endif +!if $(HAVE_GIF) +MSW_DEFINES=$(MSW_DEFINES) -DHAVE_GIF +MSW_GIF_SRC=$(XEMACS)\src\dgif_lib.c $(XEMACS)\src\gif_io.c +MSW_GIF_OBJ=$(OUTDIR)\dgif_lib.obj $(OUTDIR)\gif_io.obj +!endif +!if $(HAVE_PNG) +MSW_DEFINES=$(MSW_DEFINES) -DHAVE_PNG +MSW_INCLUDES=$(MSW_INCLUDES) -I"$(PNG_DIR)" -I"$(ZLIB_DIR)" +MSW_LIBS=$(MSW_LIBS) "$(PNG_DIR)\libpng.lib" "$(ZLIB_DIR)\zlib.lib" +!endif +!if $(HAVE_TIFF) +MSW_DEFINES=$(MSW_DEFINES) -DHAVE_TIFF +MSW_INCLUDES=$(MSW_INCLUDES) -I"$(TIFF_DIR)\libtiff" +MSW_LIBS=$(MSW_LIBS) "$(TIFF_DIR)\libtiff\libtiff.lib" +!endif +!if $(HAVE_JPEG) +MSW_DEFINES=$(MSW_DEFINES) -DHAVE_JPEG +MSW_INCLUDES=$(MSW_INCLUDES) -I"$(JPEG_DIR)" +MSW_LIBS=$(MSW_LIBS) "$(JPEG_DIR)\libjpeg.lib" +!endif !if $(HAVE_TOOLBARS) MSW_DEFINES=$(MSW_DEFINES) -DHAVE_TOOLBARS MSW_TOOLBAR_SRC=$(XEMACS)\src\toolbar.c $(XEMACS)\src\toolbar-msw.c @@ -584,7 +660,8 @@ DOC_SRC7=\ $(XEMACS)\src\select-msw.c \ $(MSW_C_DIRED_SRC) \ $(MSW_TOOLBAR_SRC) \ - $(MSW_DIALOG_SRC) + $(MSW_DIALOG_SRC) \ + $(MSW_GIF_SRC) !endif !if $(HAVE_MULE) @@ -670,10 +747,10 @@ TEMACS_MSW_OBJS=\ $(OUTDIR)\select-msw.obj \ $(MSW_C_DIRED_OBJ) \ $(MSW_TOOLBAR_OBJ) \ - $(MSW_DIALOG_OBJ) + $(MSW_DIALOG_OBJ) \ + $(MSW_GIF_OBJ) !endif - !if $(HAVE_MULE) TEMACS_MULE_OBJS=\ $(OUTDIR)\input-method-xlib.obj \ @@ -867,21 +944,19 @@ all: $(OUTDIR)\nul $(LASTFILE) $(LWLIB) $(LIB_SRC_TOOLS) $(RUNEMACS) \ temacs: $(TEMACS) # use this rule to install the system -install: all "$(INSTALL_DIR)\nul" "$(INSTALL_DIR)\lock\nul" +install: all + @echo Installing in $(INSTALL_DIR) ... + @xcopy /q PROBLEMS "$(INSTALL_DIR)\" + @xcopy /q README "$(INSTALL_DIR)\lock\" + @del "$(INSTALL_DIR)\lock\README" @xcopy /q $(LIB_SRC)\*.exe "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)\" - @copy $(LIB_SRC)\DOC "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)\" - @copy $(XEMACS)\src\xemacs.exe "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)\" - @copy $(RUNEMACS) "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)\" + @copy $(LIB_SRC)\DOC "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)" + @copy $(XEMACS)\src\xemacs.exe "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)" + @copy $(RUNEMACS) "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)" @xcopy /e /q $(XEMACS)\etc "$(INSTALL_DIR)\etc\" @xcopy /e /q $(XEMACS)\info "$(INSTALL_DIR)\info\" @xcopy /e /q $(XEMACS)\lisp "$(INSTALL_DIR)\lisp\" -"$(INSTALL_DIR)\nul": - -@mkdir "$(INSTALL_DIR)" - -"$(INSTALL_DIR)\lock\nul": "$(INSTALL_DIR)\nul" - -@mkdir "$(INSTALL_DIR)\lock" - distclean: del *.bak del *.orig