On Fri, Feb 29, 2008 at 05:35:56PM +0100, Agustin Martin wrote:
> On Sun, Nov 11, 2001 at 01:52:22AM -0600, Manoj Srivastava wrote:
> > Hi,
> > >>"Rob" == Rob Browning <[EMAIL PROTECTED]> writes:
> > 
> >  Rob> Manoj Srivastava <[EMAIL PROTECTED]> writes:
> > 
> >  Rob> This isn't emacs21's problem as far as I can tell.  If you run emacs
> >  Rob> with -q --no-site-file, load-path has the policy-specified
> >  Rob> directories.  It looks like all the other packages are just putting
> >  Rob> their dirs onto the front of load-path in their site-start.d files.
> > 
> >  Rob> I'm not sure why, though.  Emacs adds these dirs to the load path
> >  Rob> after it starts up (recursively).
> > 
> >  Rob> Seems like a bug in a bunch of other packages to me, though it may be
> >  Rob> that previous emacs versions didn't do the recursive load-path
> >  Rob> additions.  However, even if that's true, it seems like to the end of
> >  Rob> load-path might make more sense.
> > 
> >     Fair enough. I'll investigate and file bugs appropriately.
> >  Could this  be an addition to the emacsen policy, now that emacs does
> >  load-path additions by itself? 
>
> I finally noticed *where the bug really is*, in
> debian-startup.el->(debian-run-directories) function, after reading the
> /etc/emacs/site-start.d stuff, rearranges the load path and puts
> site-lisp stuff first in the load-path, what is plain wrong.
> 
> Will try to look better into this bug.

Tried a bit harder and wrote a proof of concept, also including other
changes. Note that this is written for xemacs21 or emacs21 or higher (I
think this will work with all xemacs21 versions, but I might be wrong). It
will not work for ancient emacs19 or emacs20. If is important to have
emacsen-common support for them, I can try to use the old (while..) instead
of dolist and define a better add-to-list (emacs20 definition is
incompatible). Otherwise conflicts are needed.

Find attached the modified debian-startup.el.

-- 
Agustin
;;; debian-startup.el --- Debian specific emacsen startup code.

;; Copyright (C) 1998 Rob Browning

;; Maintainer: Rob Browning <[EMAIL PROTECTED]>
;; Keywords: debian

;; This file is part of the debian release of GNU Emacs, and will
;; be contributed to the FSF after testing. It is released under the same
;; terms, namely the GPL v2 or later.

;; GNU Emacs 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.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; This file contains startup code needed by all the various flavors
;; of Emacs for a Debian system.


(defun debian-sanitized-emacs-load-path ( &optional exclude )
  "Make sure ``load-path'' has the right ordering, returning it.
If optional list EXCLUDE is given, will take its elements out
of ``load-path''"
  (let (etc-load-path
        local-load-path
        site-load-path
        system-load-path)
    (dolist (path load-path)
      (unless (member path exclude)
        (if (string-match "^/usr/local" path)
            (add-to-list 'local-load-path path t)
          (if (string-match "^/etc" path)
              (add-to-list 'etc-load-path path t)
            (if (string-match "/site-lisp" path)
                (add-to-list 'site-load-path path t)
              (add-to-list 'system-load-path path t))))))
    (unless local-load-path
      (error "No /usr/local/ prefixed paths in load-path"))
    (append etc-load-path
            local-load-path
            site-load-path
            system-load-path)))

(defun debian-pkg-add-load-path-item (item)
  "Takes a path item (a string) and adds it to load path in the
correct position for an add-on package, before the emacs system
directories, but after the /usr/local/ directories.  After modifying
load-path, returns the new load-path."
  (add-to-list 'load-path item)
  (setq load-path (debian-sanitized-emacs-load-path))
  load-path)

;; Rewritten to less elegant -- non recursive version because elisp
;; doesn't seem to handle tail recursion :<
(defun debian-unique-strings (strings)
  "Takes a list of strings and returns the list with *adjacent*
duplicates removed."
  (let ((result '()))
    (while (consp strings)
      (if (not (string= (car strings) (car (cdr strings))))
          (setq result (cons (car strings) result)))
      (setq strings (cdr strings)))
    (nreverse result)))

(defun debian-run-directories (&rest dirs)
  "Load each file of the form XXfilename.el or XXfilename.elc in any
of the dirs, where XX must be a number.  The files will be run in
alphabetical order.  If a file appears in more than one of the dirs,
then the earlier dir takes precedence, and a .elc file always
supercedes a .el file of the same name."
  (let* ((paths dirs)
         ;; Get a list of all the files in all the specified
         ;; directories that match the pattern.
         (files
          (apply 'append
                 (mapcar
                  (lambda (dir)
                    (directory-files dir nil "^[0-9][0-9].*\\.\\(el\\|elc\\)$" 
t))
                  paths)))

         ;; Now strip the directory portion, remove any .el or .elc
         ;; extension.
         (stripped-names
          (mapcar (lambda (file)
                    (if (string-match "\\.el$" file)
                        (substring file 0 -3)
                      (if (string-match "\\.elc$" file)
                          (substring file 0 -4)
                        file)))
                  (mapcar
                   (lambda (file) (file-name-nondirectory file))
                   files)))

         ;; Finally sort them, and delete duplicates
         (base-names (debian-unique-strings (sort stripped-names 'string<))))

    ;; Actually load site files. First make sure they are in the load-path
    (setq load-path (append paths load-path))
    (dolist (file base-names)
      (condition-case ()
          (load file nil)
        (error (message "Error while loading %s" file))))

    ;; Sanitize load-path. Re-order if needed and remove temporal additions
    (setq load-path (debian-sanitized-emacs-load-path paths))))

(defun debian-startup (flavor)
  ;; Our handling of debian-emacs-flavor here is truly weird, but we
  ;; have to do it like this because some of the emacsen flavors
  ;; didn't DWIM in their startup sequence.  I wasn't as clear as I
  ;; should have been in debian-policy, but they were also
  ;; technically violating policy.

  ;; It's even weirder now.  I've changed policy back to the old way,
  ;; but I'm also doing some sanity checking here and making sure that
  ;; even debian-emacs-flavor gets set no matter what.  I'm in a rush
  ;; right now, but I'll come back later and make all this cleaner and
  ;; better documented.  Sorry.

  (if (not (boundp 'debian-emacs-flavor))
      (defconst debian-emacs-flavor flavor
        "A symbol representing the particular debian flavor of emacs that's
running.  Something like 'emacs20, 'xemacs20, etc.")

    (let ((common-dir "/etc/emacs/site-start.d")
          (flavor-dir (concat "/etc/" (symbol-name flavor) "/site-start.d")))
      (debian-run-directories flavor-dir common-dir))))

Reply via email to