+1998-09-29 SL Baur <steve@altair.xemacs.org>
+
+ * XEmacs 21.2-beta2 is released.
+
+1998-09-08 Raymond Toy <toy@rtp.ericsson.se>
+
+ * 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 <steve@altair.xemacs.org>
* XEmacs 21.2-beta1 is released.
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 "<drive>:"
+ to "//<drive>/". */
+ 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);
; /* 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
+1998-09-29 SL Baur <steve@altair.xemacs.org>
+
+ * XEmacs 21.2-beta2 is released.
+
+1998-08-14 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * files.el (auto-mode-alist): Enhanced regexp for perl-mode
+
+1998-09-22 Karl M. Hegbloom <karlheg@bittersweet.inetarena.com>
+
+ * 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 <karlheg@bittersweet.inetarena.com>
+
+ * 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 <colin@xemacs.org>
+
+ * 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 <vroonhof@math.ethz.ch>
+
+ * 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 <hniksic@srce.hr>
+
+ * 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 <hniksic@srce.hr>
+
+ * 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 <martin@xemacs.org>
+
+ * 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 <jhar@tardis.ed.ac.uk>
+
+ * 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 <torkel@hpc2n.umu.se>
+
+ * package-get.el (package-get-remote): Fix the path where to find
+ the packages on xemacs.org.
+
+1998-09-08 Hrvoje Niksic <hniksic@srce.hr>
+
+ * about.el (about-maintainer-info): Update Ben's entry.
+
+1998-09-24 Martin Buchholz <martin@xemacs.org>
+
+ * 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 <darrylo@sr.hp.com>
+
+ * 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.<package> 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 <hniksic@srce.hr>
+
+ * files.el (find-file-noselect): Handle all signals, kill the
+ buffer and resignal.
+
+1998-09-23 SL Baur <steve@altair.xemacs.org>
+
+ * cl-macs.el (glyph-image): Add setf method.
+
+1998-09-06 Darryl Okahata <darrylo@sr.hp.com>
+
+ * 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 <vroonhof@math.ethz.ch>
+
+ * x-font-menu.el (font-menu-set-font): Add "pt" units to size
+ argument.
+
+1998-09-03 Darryl Okahata <darrylo@sr.hp.com>
+
+ * 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 <hniksic@srce.hr>
+
+ * startup.el (load-init-file): spelling fix.
+
+1998-09-02 Michael Sperber [Mr. Preprocessor] <sperber@informatik.uni-tuebingen.de>
+
+ * startup.el (normal-top-level): Load auto-autoload files
+ covariantly with their precedence.
+
+1998-08-26 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * 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 <vroonhof@math.ethz.ch>
+
+ (custom-face-value-create): Show the customized settings if set
+ but not saved.
+
+1998-08-31 Hrvoje Niksic <hniksic@srce.hr>
+
+ * keydefs.el (global-map): Add FSF 20.3 binding of
+ query-replace-regexp.
+
+1998-08-21 Greg Klanderman <greg@alphatech.com>
+
+ * minibuf.el (read-file-name-internal-1): use
+ user-name-completion-1 instead of user-name-completion.
+
+1998-08-19 Michael Sperber [Mr. Preprocessor] <sperber@informatik.uni-tuebingen.de>
+
+ * 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 <leo@arioch.oche.de>
+
+ * about.el (about-hackers): new email
+
+1998-08-16 SL Baur <steve@altair.xemacs.org>
+
+ * lisp-mode.el (with-string-as-buffer-contents): Set indentation.
+
+1998-07-17 Didier Verna <verna@inf.enst.fr>
+
+ * 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] <sperber@informatik.uni-tuebingen.de>
+
+ * 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] <sperber@informatik.uni-tuebingen.de>
+
+ * packages.el (packages-data-path-depth): Added and used.
+
+1998-08-05 Charles G. Waldman <cgw@pgt.com>
+
+ * 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 <martin@xemacs.org>
+
+ * x-init.el (x-initialize-compose): Add support for
+ dead-circumflex as YET ANOTHER NAME for that dead key.
+
+1998-08-05 Colin Rafferty <colin@xemacs.org>
+
+ * 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 <khaberz@synnet.de>
+
+ * startup.el(startup-splash-frame-body):
+ Update Copyright notice in splash screen
+
+1998-07-20 Greg Klanderman <greg@alphatech.com>
+
+ * minibuf.el (read-file-name-internal-1): do ~user completion.
+
+1998-07-22 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * font-lock.el (font-lock-fontify-glumped-region): Add guard
+ aginst destroyed extents
+
+1998-07-24 Greg Klanderman <greg@alphatech.com>
+
+ * package-get.el (package-get): add `install-dir' argument.
+
+1998-07-20 John Jones <jj@asu.edu>
+
+ * package-get.el: calls to package-get-update-all will only
+ update packages which are already installed.
+
+1998-07-23 SL Baur <steve@altair.xemacs.org>
+
+ * autoload.el (update-file-autoloads): Ensure autoloads buffer is
+ writable.
+
+1998-07-20 Colin Rafferty <colin@xemacs.org>
+
+ * about.el (about-hackers): Correct my email.
+
+1998-07-20 Kai Haberzettl <khaberz@synnet.de>
+
+ * about.el (about-hackers): new email-address.
+
+1998-07-25 SL Baur <steve@altair.xemacs.org>
+
+ * minibuf.el (read-number): Don't let `input-error' condition
+ escape.
+
+1998-07-20 Greg Klanderman <greg@alphatech.com>
+
+ * about.el (about-hackers): use my `email-for-life' address.
+
1998-07-19 SL Baur <steve@altair.xemacs.org>
* XEmacs 21.2-beta1 is released.
;; 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'.
'((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")
(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"))
(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/")
(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"
(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
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,
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
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.
(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"))
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.
(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)
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)
(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")
(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")
(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")
(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")
(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")
(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")
(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")
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.
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
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
;;;***
\f
+;;;### (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)
+
+;;;***
+\f
;;;### (autoloads (picture-mode) "picture" "lisp/picture.el")
(autoload 'picture-mode "picture" "\
(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)
(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))))
;; 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)
(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
: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)
: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.")
(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
(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
(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
(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"))
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.
(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
(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
(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'.
;;; (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)))
\f
;; FSF has `insert-file-literally' and `find-file-literally' here.
("\\.[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)
(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)
'()
(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
"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."
(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))))
"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)))
;; 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
;;; 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
(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
(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)))))
\f
(defvar Info-mode-map nil
"Keymap containing Info commands.")
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'.
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")
;; 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,
(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)
;; 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))
(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)
(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))
-
-
-
(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)
(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)
:user-data
:reference-buffer
(:help-string completion-default-help-string)
+ (:completion-string "Possible completions are:")
:window-width)
()
(let ((old-buffer (current-buffer))
(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
;; 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 "^[^-.]"
(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-
;; 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")
["Set..." customize-customized]
["Apropos..." customize-apropos]
["Browse..." customize-browse]
+ ["List Packages" pui-list-packages]
["Update Packages" package-get-custom])
("Editing Options"
["Overstrike"
(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]
)
(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))
(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_)
(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)))
'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_]*\\|{[^}]*\\)\\'"
;; 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
;; 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)
;;; 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)
"^[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.
; 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)
(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)
(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)
; 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)
(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.
;; 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.<package> 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.<pkgname>
+
+ ;; 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)
"*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)
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
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)
`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)))
(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.
(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
(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.")
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"
(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)
;; 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'."
(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
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
(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."
(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
;; 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.
;; Thanks to Francesco Potorti` <pot@cnuce.cnr.it> for suggestions,
;; rewritings & speedups.
+;; 1998-08-15 Martin Buchholz: Speed up using hashtables instead of lists.
+
;;; Code:
\f
(defun find-emacs-lisp-shadows (&optional path)
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"
;; 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))
: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
(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)
(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
" 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
(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)))
(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)
(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))))
(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)
)
newstring = XmStringLtoRCreate (newchars, XmFONTLIST_DEFAULT_TAG);
XmStringExtent (mw->menu.font_list, newstring, &width, &height);
XmStringFree (newstring);
+ XtFree (chars);
return width;
#else
# ifdef USE_XFONTSET
}
}
x += string_draw_range (mw, window, x, y, gc, chars, s, i);
+#ifdef NEED_MOTIF
+ XtFree (chars);
+#endif
}
static void
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);
}
/*-------------------------- 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)
{
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);
}
+1998-09-29 SL Baur <steve@altair.xemacs.org>
+
+ * XEmacs 21.2-beta2 is released.
+
+1998-09-20 Hrvoje Niksic <hniksic@srce.hr>
+
+ * lispref/customize.texi: New file.
+
+1998-09-09 Hrvoje Niksic <hniksic@srce.hr>
+
+ * internals/internals.texi (Coding for Mule): New node and
+ section.
+
+1998-09-03 Darryl Okahata <darrylo@sr.hp.com>
+
+ * xemacs/packages.texi: Document manually installing binary packages.
+
+1998-09-02 Jeff Miller <jmiller@smart.net>
+
+ * Synch calendar.texi with Emacs 20.3
+
+1998-09-03 Darryl Okahata <darrylo@sr.hp.com>
+
+ * 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 <hniksic@srce.hr>
+
+ * lispref/buffers.texi (Indirect Buffers): Update with XEmacs
+ specifics.
+
+1998-08-21 Greg Klanderman <greg@alphatech.com>
+
+ * lispref/files.texi (User Name Completion): new section.
+
+1998-07-23 Adrian Aichner <aichner@ecf.teradyne.com>
+
+ * 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] <sperber@informatik.uni-tuebingen.de>
+
+ * xemacs/startup.texi: Small fixes, suggested by Hrvoje.
+
+ * xemacs/xemacs.texi:
+ * xemacs/packages.texi: More packages documentation.
+
1998-07-19 SL Baur <steve@altair.xemacs.org>
* XEmacs 21.2-beta1 is released.
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
* General Coding Rules::
* Writing Lisp Primitives::
* Adding Global Lisp Variables::
+* Coding for Mule::
* Techniques for XEmacs Developers::
@end menu
@{
val = Feval (XCAR (args));
if (!NILP (val))
- break;
+ break;
args = XCDR (args);
@}
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
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
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{} #<buffer "indirect">
+@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{} #<buffer "*scratch*">
+@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{} (#<buffer "indirect">)
+@end group
+@end example
+@end defun
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.
@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{} #<buttonup-event meta-button1up>
@end group
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
@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.
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.
@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.
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
@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
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
@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.
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
@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
@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"}@*
* 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
@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
* 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.
@include variables.texi
@include functions.texi
@include macros.texi
+@include customize.texi
@include loading.texi
@include compile.texi
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.
@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
@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.
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.
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.
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
@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 *?
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{\|}
@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.
@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
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:
@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
(@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}).
@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.
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)}
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
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.
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:
@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
@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
@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
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
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{<package-name>-<version>-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 <return>
+@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),
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.
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
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.)
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{<root>}, it means that XEmacs searches for it under all
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
Moreover, XEmacs expects late hierarchies in the subdirectories
@file{site-packages}, @file{mule-packages}, and @file{xemacs-packages}
(in that order) of the @file{<root>/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{<root>/lib/xemacs-<VERSION>}
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.
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{<root>/lib/xemacs-<VERSION>}.
@item site-specific
+@cindex site-specific directories
directories are independent of the version of XEmacs they belong to and
typically reside under @file{<root>/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{<root>/lib/xemacs-<VERSION>/<ARCHITECTURE>}.
directories of the environment variables @code{PATH}
@vindex PATH
and @code{EMACSPATH}.
-@vindex EMCSPATH
+@vindex EMACSPATH
@item doc-directory
@vindex doc-directory
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
* 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
+1998-09-29 SL Baur <steve@altair.xemacs.org>
+
+ * XEmacs 21.2-beta2 is released.
+
+1998-09-19 Adrian Aichner <aichner@ecf.teradyne.com>
+
+ * tiff.mak: New file provided by Charles Wilson
+ <cwilson@ee.gatech.edu>
+
+ * README: Update provided by Charles Wilson
+ <cwilson@ee.gatech.edu>. Documenting use of the newly
+ introduced tiff.mak. Renumbering subsequent build instruction
+ items.
+
+1998-09-20 Jonathan Harris <jhar@tardis.ed.ac.uk>
+
+ * PROBLEMS: New file.
+
+ * xemacs.mak: Install the PROBLEMS file in the root directory of
+ the XEmacs installation.
+
+1998-08-31 Jonathan Harris <jhar@tardis.ed.ac.uk>
+
+ * xemacs.mak: Detect failure to supply PNG_DIR or XLIB_DIR
+ when building with PNG support.
+
+1998-08-31 Jonathan Harris <jhar@tardis.ed.ac.uk>
+
+ * README: Document the PNG, ZLIB, JPEG, TIFF and GIF build
+ options.
+
+1998-08-12 Jeff Sparkes <jsparkes@internetivity.com>
+
+ * xemacs.mak: Link in GIF, fix HAVE_JPEG default.
+
+1998-08-09 Jonathan Harris <jhar@tardis.ed.ac.uk>
+
+ * 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 <cgw@pgt.com>
+
+ * xemacs.mak: change "copy" to "xcopy" in install target
+
+1998-08-04 Jeff Sparkes <jsparkes@internetivity.com>
+
+ * xemacs.mak: Link in PNG, TIFF and JPEG in native build.
+
+1998-08-04 Jonathan Harris <jhar@tardis.ed.ac.uk>
+
+ * 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 <steve@altair.xemacs.org>
* XEmacs 21.2-beta1 is released.
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
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
!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
!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
!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
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
$(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)
$(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 \
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