I'm using the elisp snippet below(courtesy of Stas Boukarev with some modifications) to reload a .asd file. Is asdf::load-sysdef the best way to trigger a reload(but not recompilation) ?
Use case: I want to work on a system that isn't in the ASDF path, it being one of the many development trees I have around(e.g. CFFI), so I want to be able to say that "this cffi.asd is the CFFI to use during this session". Any ideas ?
(defvar slime-custom-file-loaders '(("asd" . slime-load-asdf) ("lisp" . slime-load-file)))
(defun slime-load-asdf (filename) (slime-eval-with-transcript `(asdf::load-sysdef ,(file-name-sans-extension filename) ,(slime-to-lisp-filename (expand-file-name filename)))))
(defun slime-custom-load-file () (interactive) (unless buffer-file-name (error "Buffer %s is not associated with a file." (buffer-name))) (check-parens) (when (and (buffer-modified-p) (y-or-n-p (format "Save file %s? " (buffer-file-name)))) (save-buffer)) (let* ((type (file-name-extension buffer-file-name)) (loader (cdr (assoc-string type slime-custom-file-loaders t)))) (funcall (or loader 'slime-load-file) buffer-file-name)))
(define-key slime-mode-map (kbd "C-c C-l") 'slime-custom-load-file)
On Sun, May 6, 2012 at 3:27 PM, Stelian Ionescu sionescu@cddr.org wrote:
I'm using the elisp snippet below(courtesy of Stas Boukarev with some modifications) to reload a .asd file. Is asdf::load-sysdef the best way to trigger a reload(but not recompilation) ?
Yes, with a catch: IF there's a system in your central-registry, source-registry, quicklisp registry, or wherever locate-system will find it, then that OTHER system will be found by the next find-system, as called whenever you try to compile it.
So load-sysdef will only help you define a system that CANNOT be found by locate-system.
What if you want to override what locate-system finds? Well, then override your source-registry, by exporting CL_SOURCE_REGISTRY, or giving an explicit parameter to asdf:initialize-source-registry. And the system is located by some other hook that has precedence over the source-registry (e.g. *central-registry*), then it's your responsibility to properly configure that hook.
Use case: I want to work on a system that isn't in the ASDF path, it being one of the many development trees I have around(e.g. CFFI), so I want to be able to say that "this cffi.asd is the CFFI to use during this session". Any ideas ?
If the session is well-defined enough to have some initial incantation or configuration file, I would use something like this to set it up:
(asdf:initialize-source-registry '(:source-registry (:tree "/path/to/overriding/cffi") (:tree "/path/to/other/overriding/library") :inherit-configuration))
Or, a bit more brutal and old-fashioned: (pushnew #p"/path/to/overriding/cffi/" asdf:*central-registry*) (pushnew #p"/path/to/overriding/cffi/uffi-compat/" asdf:*central-registry*)
If you want a 100% answer for a dynamically defined SLIME-directed session, where whichever .asd file you load incrementally modifies current session, I'd add another hook in front of asdf:*system-definition-search-functions*, that remembers whichever .asd you load that way, then calls load-sysdef. That would be a nice addition to slime's asdf support.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org To do evil a human being must first of all believe that what he's doing is good. — Alexander Solzhenitsyn
On Sun, 2012-05-06 at 16:05 -0400, Faré wrote:
On Sun, May 6, 2012 at 3:27 PM, Stelian Ionescu sionescu@cddr.org wrote:
I'm using the elisp snippet below(courtesy of Stas Boukarev with some modifications) to reload a .asd file. Is asdf::load-sysdef the best way to trigger a reload(but not recompilation) ?
Yes, with a catch: IF there's a system in your central-registry, source-registry, quicklisp registry, or wherever locate-system will find it, then that OTHER system will be found by the next find-system, as called whenever you try to compile it.
So load-sysdef will only help you define a system that CANNOT be found by locate-system.
I only want to put a system into "manual" mode, and make sure that find-system never overrides that no matter what. How about adding an optional third parameter to load-sysdef that sets a "definitivep" flag in the system, which makes find-system to never search it on the file-system any more ?
I only want to put a system into "manual" mode, and make sure that find-system never overrides that no matter what. How about adding an optional third parameter to load-sysdef that sets a "definitivep" flag in the system, which makes find-system to never search it on the file-system any more ?
As I explained in my previous mail, it would more be something like what follows (wholly untested), where in your code you'd (1) call the register function initially (2) use load-slime-override-sysdef instead of load-sysdef in your code.
(in-package :asdf)
(defvar *slime-override-systems* (make-hash-table :test 'equal))
(defun sysdef-slime-override (name) (values (gethash (coerce-name system) *slime-override-systems*)))
(defun register-slime-override () (setf asdf:*system-definition-search-functions* (cons 'sysdef-slime-override (remove 'sysdef-slime-override *system-definition-search-functions*))))
(defun load-slime-override-sysdef (name pathname) (let ((name (coerce-name name))) (setf (gethash name *slime-override-systems*) pathname) (load-sysdef name pathname)))
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org "I believe that sex is one of the most beautiful, natural, wholesome things that money can buy." — Steve Martin
On Sun, 2012-05-06 at 17:08 -0400, Faré wrote:
I only want to put a system into "manual" mode, and make sure that find-system never overrides that no matter what. How about adding an optional third parameter to load-sysdef that sets a "definitivep" flag in the system, which makes find-system to never search it on the file-system any more ?
As I explained in my previous mail, it would more be something like what follows (wholly untested), where in your code you'd (1) call the register function initially (2) use load-slime-override-sysdef instead of load-sysdef in your code.
(in-package :asdf)
(defvar *slime-override-systems* (make-hash-table :test 'equal))
(defun sysdef-slime-override (name) (values (gethash (coerce-name system) *slime-override-systems*)))
(defun register-slime-override () (setf asdf:*system-definition-search-functions* (cons 'sysdef-slime-override (remove 'sysdef-slime-override *system-definition-search-functions*))))
(defun load-slime-override-sysdef (name pathname) (let ((name (coerce-name name))) (setf (gethash name *slime-override-systems*) pathname) (load-sysdef name pathname)))
Yes, but I'd like to push this as Slime contrib and there's no guarantee that this will work in any case
On Sun, May 6, 2012 at 5:24 PM, Stelian Ionescu sionescu@cddr.org wrote:
Yes, but I'd like to push this as Slime contrib and there's no guarantee that this will work in any case
No guarantee that my code will work? You can test and debug it; the underlying API is not going to change.
No guarantee that the notoriously picky SLIME maintainers will accept a contribution? I can't help you there.
There, I fixed two obvious bugs. Looks like it works:
(in-package :asdf)
(defvar *slime-override-systems* (make-hash-table :test 'equal))
(defun sysdef-slime-override (name) (values (gethash (coerce-name name) *slime-override-systems*)))
(defun register-slime-override () (setf asdf:*system-definition-search-functions* (cons 'sysdef-slime-override (remove 'sysdef-slime-override *system-definition-search-functions*))))
(defun load-slime-override-sysdef (name pathname) (let ((name (coerce-name name)) (pathname (pathname pathname))) (setf (gethash name *slime-override-systems*) pathname) (load-sysdef name pathname)))
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Natural laws have no pity. — Robert Heinlein, "Time Enough For Love"
On Sun, 2012-05-06 at 18:09 -0400, Faré wrote:
On Sun, May 6, 2012 at 5:24 PM, Stelian Ionescu sionescu@cddr.org wrote:
Yes, but I'd like to push this as Slime contrib and there's no guarantee that this will work in any case
No guarantee that my code will work? You can test and debug it; the underlying API is not going to change.
No guarantee in the sense that, after loading the ASDF contrib, the user might push another function to *system-definition-search-functions* and it will break. There's no way to guarantee that load-slime-override-sysdef will always be the first element of *system-definition-search-functions*
FWIW, Faré's example, where he has to push /both/ the CFFI path and the CFFI-UFFI path into the asdf registry shows the risks of this kind of behavior.
Mightn't it be better to provide an easy SLIME command to modify the search behavior on the fly, than try to mess around with single-file patching? That seems very likely to fail for systems that have nested or related subsystems (UFFI example, related -test system, etc.).
Cheers, r
On Sun, May 6, 2012 at 6:15 PM, Stelian Ionescu sionescu@cddr.org wrote:
On Sun, 2012-05-06 at 18:09 -0400, Faré wrote:
On Sun, May 6, 2012 at 5:24 PM, Stelian Ionescu sionescu@cddr.org wrote:
Yes, but I'd like to push this as Slime contrib and there's no guarantee that this will work in any case
No guarantee that my code will work? You can test and debug it; the underlying API is not going to change.
No guarantee in the sense that, after loading the ASDF contrib, the user might push another function to *system-definition-search-functions* and it will break. There's no way to guarantee that load-slime-override-sysdef will always be the first element of *system-definition-search-functions*
Oh, well, if you want more robustness, you could redefine or advise search-for-system-definition that already has such a trick to introduce a function at the beginning of the list (put there to avoid infinite loops, as used to happen in some edge cases with quicklisp and other systems). And if you want the redefinition or advice to be preserved when ASDF is reloaded, you could redefine or advise upgrade-asdf.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org The worst thing about totalitarian regimes is not that they make people poor, miserable and unfree — it's that they corrupt people's souls, and turning everyone into a double-thinking, double-speaking liar for the sake of survival.