11

This is similar to this question but the answer there seems to be deprecated.

Let's say I'm using a layer and want hack the code of a particular package that layer is using. How do I go about it?


To better illustrate what I want to accomplish in general, I present a specific example.

I try to get the spotify layer to work, but the current master branch in the helm-spotify package uses a deprecated web API. There is a pull request to fix this and I want to try it and maybe contribute something. My problem is, that I can not get the local copy of helm-spotify to load.

What I tried was to switch to the develop branch of spacemacs:

git branch --track develop origin/develop
git checkout develop

In ~/.emacs.d/layers/spotify/packages.el

I changed from

(setq spotify-packages '(spotify helm-spotify))

To

(setq spotify-packages
          '(    
                spotify
                (helm-spotify :location local)
           ))

And pulled the helm-spotify repository to ~/.emacs.d/layers/spotify/local/helm-spotify

When I restart spacemacs I get

File error: Cannot open load file, no such file or directory, multi

In when I look into helm-spotify.el there is:

(require 'multi)

So my guess is, that when installing helm-spotify from melpa the dependency on multi gets resolved prior to loading helm-spotify but of course not anymore when I use a local copy of helm-spotify.

So my questions are:

  • How do resolve dependencies when using a local package?
  • Or should I do this completely differently from what I described?

I also tried, without success, to add multi to dotspacemacs-additional-packages and to spotify-packages:

(setq spotify-packages '(
                         multi ;; I added this
                         spotify
                         (helm-spotify :location local) ;; I modified here
                         ))

;; I added this
(defun spotify/init-multi ()
  (use-package multi))

;; the rest is as it was

(defun spotify/init-spotify ()
  (use-package spotify
    :config (spacemacs/set-leader-keys
              "amsp" 'spotify-playpause
              "amsn" 'spotify-next
              "amsN" 'spotify-previous
              "amsQ" 'spotify-quit)))

(when (configuration-layer/layer-usedp 'spacemacs-helm)
  (defun spotify/init-helm-spotify ()
    (use-package helm-spotify
      :config (spacemacs/set-leader-keys
                "amsg" 'helm-spotify))))

in packages.el. Also tried without adding multi to dotspacemacs-additional-packages.

4
  • AFAIK there isn't a way to automatically resolve dependencies when using local packages, since package.el (the built-in Emacs module) doesn't really see local/helm-spotify as a package. The way to resolve it is manually, and you are in the right direction. Can you add more detail how you tried to add multi? It's not clear if you added it to additional-packages and spotify-packages at the same time, or tried them separately. Having multi in spotify-packages and a spotify/init-multi function in packages.el (without using additional-packages) should be enough
    – bmag
    Feb 20, 2016 at 20:48
  • Also, if you want to test a pull request without editing its code locally, you can use recipe instead of local. e.g. (helm-spotify :location (recipe <recipe specs>))
    – bmag
    Feb 20, 2016 at 20:51
  • I just tried it without adding multi to dotspacemacs-additional-packages with no success. The error is the same. I updated my question to reflect the packages.el I'm using. Thanks for your effort! Feb 20, 2016 at 21:04
  • I think you found a bug, because I tried what I thought should work and I got the same error. It's late here so I can't dig deeper right now, but in the meantime you can either try using recipe instead of local (it should take care of the multi dependency for you), or move the multi configuration to a separate layer and make sure that layer is listed before spotify in dotspacemacs-configuration-layers (the layer list)
    – bmag
    Feb 20, 2016 at 21:40

1 Answer 1

14

First, you should never modify the code in master branch, Spacemacs is designed to be hackable while keeping the master branch read-only, also not that force pushes to master branch may happen!. If you really want to modify the code you should use the develop branch and keep it up to date manually. Develop branch is never forced push.

EDIT: actually you were using the develop branch, my apologies, I let the paragraph for reference.

Now the answer :-) The correct way to do what you want is to overwrite the location in dotspacemacs-additional-packages. I just tried it by forking helm-spotify in my namespace and then added:

   dotspacemacs-additional-packages
     '((helm-spotify :location (recipe :fetcher github :repo "syl20bnr/helm-spotify")))

Then upon restart Spacemacs fetched the package from my fork correctly instead of reaching MELPA. Spacemacs uses quelpa to fetch repositories from GitHub based on MELPA recipes, package.el is used to install the packages so dependencies are correctly resolved.

Note that:

  • you may have to manually delete the helm-spotify folder in ˜/.emacs.d/elpa directory and restart Emacs.
  • You still have to add the spotify layer to your dotspacemacs-configuration-layers variable.
5
  • 3
    You can also add a branch to the recipe: :branch "my-branch"
    – syl20bnr
    Feb 23, 2016 at 3:13
  • This worked perfectly! Thank you a lot! Feb 23, 2016 at 14:33
  • Sorry if I'm slow to grasp, but could somebody please explain this is a stupid-form? So I'm using package XYZ, currently installed automatically by Spacemacs from Melpa. What exactly are the steps that need to be taken to switch this package to a local version? (Or one on a Github repo of mine, if that's necessary; but frankly it would be a quite annoying for the debugging of any changes.) What Spacemacs configuration files need to be tweaked, and in which way? Jun 20, 2019 at 15:43
  • 1
    Alternatively create a directory with the name of the package in the .emacs.d/private/local directory, and add that directory to the load-path variable by adding (some-package :location local) to the list dotspacemacs-additional-packages within the dotspacemacs/layers function of your dotspacemacs file. After placing your package file into this package-directory the file can be loaded, without requiring the full path, by placing a (require 'package-name) within the body of the dotspacemacs/user-config function of your dotspacemacs file. - from spacemacs doc
    – Didier A.
    Apr 14, 2020 at 2:24
  • 1
    Thank you for mentioning that you need to remove package from elpa directory. That was not obvious for me.
    – Astery
    Mar 3, 2021 at 8:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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