I'm writing something to try and help us cut down on the system
resources used by emacsen, calling it 'load-manager-unload-feature',
intending to eventually make a nice gui for it (but, for now, it's
basically just a different interactive interface on `unload-feature')
It would make it a heck of a lot easier to do this, if we added
something like this to loadhist.el, where `unload-feature' is defined:
(define-error 'cannot-unload-feature
"error to signal when a feature cannot be unloaded")
.. and modify `unload-feature', to make it signal that error, when a
feature cannot be unloaded because some loaded libraries are depending
on it.
but i didn't think that was the best name for the error. any
suggestions?
--
sean champ
here's a snapshot of the load-manager code so far:
;; load-manager.el
(defvar load-manager-feature-history nil
"history used by `load-manager-unload-feature")
;; haven't integrated this error type yet, but here it is:
(define-error 'cannot-unload-feature
"error to signal when a feature cannot be unloaded")
(defun load-manager-unload-feature (feature)
"attempt to unload FEATURE
If the feature is required by any other loaded code, a warning will be
signaled [was implemented, but presently isn't].
also see: `unload-feature'
"
(interactive
(list (intern-soft
(completing-read "unload feature: " obarray
#'(lambda (obj) (and (featurep obj) (feature-file obj)))
t nil 'load-manager-feature-history))))
;; i need to use a `condition-case' here, instead,
;; but this hopefully makes the point of what i'm trying to do:
;; i'm trying to change what happens when a feature cannot be unloaded.
(catch 'unable-to-unload
(if (feature-file feature)
(condition-case err
(unload-feature feature)
;; the error-handler makes up the most of this
(error
(let ((errmsg (car (cdr err))))
; DEBUG:
(print errmsg (current-buffer))
;; check to make sure it's the error that we're looking for ...
(if (and errmsg
(string-match
(format "^Loaded libraries (\\(.*\\)) depend on %s" feature)
errmsg))
(let ((dependents
(split-string
;; we get "\"foo"\" for each thing that we want from
;; the the string-match. this isn't the best way to
;; get rid of those quotes, but it works.
(replace-in-string (match-string 1 errmsg) "\"" "")
" "))
dependv)
;; hope that the library name of the dependent library is the same as
;; that of a feature provided it; if it is, ask user if that
;; dependent feature should be unloaded.
; DEBUG:
(print dependents (current-buffer))
(while (progn (setq dependv (intern-soft (car dependents))
dependents (cdr dependents))
(featurep dependv))
(if (yes-or-no-p
(format
"feature %s depends on %s ; unload %1$s?"
dependv feature))
(load-manager-unload-feature dependv)
(throw 'unable-to-unload "dependents still loaded"))))
;; else, it was a different error, so tell user about it:
(apply #'error err)))))
;; this happens when the (feature-file feature) => nil
(throw 'unable-to-unload
(format "load-file of feature %s is not known" feature)))))
;(print features (current-buffer))
;; test-case:
; (require 'bookmark) ;; requires pp , also
; (call-interactively #'load-manager-unload-feature)
;
;; now, try to make it unload pp
;;
;; it should work, but it's some ugly code that gets it to do so.
;; and it doesn't tell the user, yet, when a feature cannot be unloaded.
;; load-manager.el ends here