1

I am using use-package in my .emacs and it is great. However occasionally I want to use a 3-rd party code which is not in [M]ELPA. Of course, I can download it but then I will need to maintain a copy of it on all the machines I use. Now I can just copy .emacs to a new machine, start emacs and it will download and install all packages. I wonder if there is anything similar for non-packaged libraries? Something which will fetch them via HTTP or git, compile and add to load path.

Here is an example of a package I want to use:

https://github.com/emacsmirror/emacswiki.org/blob/master/zoom-frm.el

I suspect that maybe el-get can do this but I am unsure. Maybe somebody can show me an example for this zoom-ftm.el?

  • Did you perhaps mean zoom-frm.el? – Drew Nov 29 '19 at 6:11
  • 1
    Dunno whether this is what you're asking, but I think this example, for downloading and compiling the Bookmark+ files from Emacs Wiki, might be relevant (i.e., might help): emacswiki.org/emacs/BookmarkPlus#BulkDownloadCompileLoad – Drew Nov 29 '19 at 7:01
  • @Drew, yes that zoom-frm. Thanks for the download snippet. It looks like what I want. I was hoping somebody automated this as a library. For example, a function where I can pass a URL, list of files and the package name. It could be generalized further by supporting git checkouts in addition to HTTP downloads. – krokodil Nov 29 '19 at 17:26
  • Found this related question: emacs.stackexchange.com/questions/50815/… – krokodil Nov 29 '19 at 22:02
  • Please add the link in your last comment to your answer too, for future reference. (Comments can be deleted at any time.) Thx. – Drew Nov 30 '19 at 6:28
0

I have not found any existing solution to do that and come up with my own:

;; Inspired by https://www.emacswiki.org/emacs/BookmarkPlus#BulkDownloadCompileLoad 
(defun fetch-and-load-elisp (pkg-name pkg-files base-url base-dir)
  (let ((pkg-dir (concat (file-name-as-directory base-dir) (symbol-name pkg-name))))
    (require 'url)
    (add-to-list 'load-path pkg-dir)
    (make-directory pkg-dir t)
    (mapcar (lambda (arg)
              (let ((local-file (concat (file-name-as-directory pkg-dir) arg)))
                (unless (file-exists-p local-file)
                  (url-copy-file (concat base-url arg) local-file t))))
            pkg-files)
    (byte-recompile-directory pkg-dir 0)
    (require pkg-name)))

(when (fetch-and-load-elisp 'zoom-frm '("frame-cmds.el" "frame-fns.el" "zoom-frm.el") "https://www.emacswiki.org/emacs/download/" "~/lisp/")
      (define-key ctl-x-map [(control ?+)] 'zoom-in/out)
      (define-key ctl-x-map [(control ?-)] 'zoom-in/out)
      (define-key ctl-x-map [(control ?=)] 'zoom-in/out)
      (define-key ctl-x-map [(control ?0)] 'zoom-in/out))

I am not proficient in ELISP, and perhaps it could be improved. Error handling comes to mind. Also, the byte compilation is now run every time, even when files were unchanged.

| improve this answer | |
  • 2
    I think you meant when rather than if in the last expression. Or else you need a progn around the define-key calls. – npostavs Nov 30 '19 at 3:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.