syl20bnr / spacemacs

A community-driven Emacs distribution - The best editor is neither Emacs nor Vim, it's Emacs *and* Vim!

Home Page:http://spacemacs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't find information on using a local version of a package

dalaing opened this issue · comments

I'm trying to add something to flycheck, which in my setup is used by the syntax-checking and +lang/haskell layers.

It is unclear how to get spacemacs to use flycheck from a local checkout of the code.
I've tried modifying the relevant packages.el files to contain (flycheck :location local), with flycheck in <layer>/local/flycheck, but it's not picking up on any of the changes.

I've also tried adding it in via dotspacemacs-additional-packages, both with local and paths to the package as the location.

This seems similar to these two issues, and all I can find in gitter is other people unable to do the same kind of thing.

I don't think I can just copy the code into a private layer, since it's coming from two different existing layers.

Am I missing something obvious?

I'm curious about this also and the recommended ways to load packages locally.

I have a custom layer and it works fine when I pull everything down from melpa. But, when I put the same packages I want to work on in private//local to try work on them, those packages never get loaded.

I found two ways that work. Either explicitly requireing the packages I want to load locally or setting the use-package :commands property to the same function that is loaded from the mode hook.

So, basically I'm curious I guess what is it that is different between local packages and melpa packages that causes this loading behavior.

One thing that could go wrong if you have a local checkout of the repository as opposed to the elpa directory generated by package.el is that the autoloads aren't properly configured. In package.el these are generated from ;;;### autoload cookies in the source code, but if you check out the package locally you have to do this yourself.

Use update-file-autoloads or update-directory-autoloads to do this, by the way.

Ah, that makes sense now, I was unaware of how the autoload cookies actually worked. Thanks!

commented

Would love to see a correct doc on this point.

The README at ~/.emacs.d/private/local seems to imply that everything would work out of the box (somehow the local package would take precedence) but instead it looks like a hard game of try and guess.

For instance in dotspacemacs-additional-packages using the location key does not seem to have any effect:

   dotspacemacs-additional-packages '((ox-asciidoc :location local))

So if you just want to take an elpa package, make some local changes to it (without renaming it), what's the best way to do so ?

You should be able to override a location with dotspacemacs-additional-packages, I use it to use my own forks on github. Maybe there is a bug with the local value, have you tried a string with an absolute path to the package as a work-around ?

To see the value of location you can try the new function configuration-layer/describe-package (should be bound to a key).

The documentation needs improvement in this area, I believe that a tutorial is the best format to grok the layer advanced stuff.

commented

@syl20bnr I have investigated a bit more. local actually works as much as an absolute path. What I need is to manually require the local package in dotspacemacs/user-config if I want it to be available.
Is this an autoload problem or is this expected ?

This is indeed expected, dotspacemacs-additional-packages only installs the package and make its feature (Emacs sense of the term) available in load-path variable so you can require it (either via require or use-package).

A configuration layer does this require for you but at the dotfile level there is no such thing so you have to either move your package to a layer and require it in the <layer>/init-<package> function or simply put it in user-config.

I ran into the exact same issue as @dalaing. Using (location: local) in either dotspacemacs-additional-packages or in the syntax-checking layer did not have any effect. Neither did using (recipe :fetcher git :url "file:///home/me/package).

The only way I managed to load my package was to add the following to dotspacemacs/user-config:

(load-file "path/to/package.el")
(require 'package)

My setup:

  • OS: gnu/linux
  • Emacs: 25.1.1
  • Spacemacs: 0.200.5
  • Spacemacs branch: master (rev. 664ba6a)

Additionally, the first thing I tried was to add the package on my load-path in dotspacemacs/user-config:

(add-to-load-path "path/to/package")
(require 'package)

But note that does not work, because the package has already been required by a layer previously, so further require calls do not load the feature.

Hence, you have to use (load-file) to force Emacs to load the package you want.

Finally, as noted by @deb0ch on Gitter, the require in my solution above is redundant, since it (load-file) will already provide the feature.

I am not sure how (pkg-name :location local) should work if it's placed in .spacemacs file under additional packages (I mean, what's local?). But using :location local works as expected when it's in layer. Following conditions must meet:

  • that layer has local/pkg-name/pkg-name.el
  • pkg-name.el has (provide 'pgk-name) at the end of file
  • that layer has properly configured layer-name/[post-|pre-]init-pkg-name function

In the core-configuration-layer.el there is a line that avoid package loading if it's marked as local in .spacemacs file.

(cond
         ((eq 'dotfile (car (oref pkg :owners)))
          (spacemacs-buffer/message
           (format "%S is configured in the dotfile." pkg-name)))
         (t
          (configuration-layer//configure-package pkg)))

It even prints a message that you can observer in messages buffer.


But if you wish to overload package location to local in .spacemacs file, then use file fetcher recipe. Like this: (flycheck :location (recipe :fetcher file :path "/Users/d12frosted/.environment/emacs/local/flycheck/flycheck.el")). Note that this must be real package with proper header and stuff.

@d12frosted Correct me if I'm wrong, but setting

(setq dotspacemacs-additional-packages (some-package :location "/some/path/to/package"))

used to work, right ? Because it doesn't work now.

At some point I didn't have to use the file fetcher recipe (and I haven't seen it documented either).

Never used :location path-string. As per file fetcher recipe - it's a quelpa thing.

I have tried according to the docs, but still no success.

   dotspacemacs-additional-packages
   '(dtrt-indent
     (spaceline :location (recipe :fetcher file
                                  :repo "/home/chauvo_t/.emacs.d/private/local/spaceline/")))

does not install Spaceline correctly:

  • If I don't manually remove Spaceline from ~/.emacs.d/elpa/24.5/, the new location is ignored and the elpa version is used
  • when I do remove it and restart Spacemacs, it fails miserably to install and Spacemacs doesn't even start (I checked that the path to the cloned package is correct):

screenshot from 2016-12-18 13-27-40

EDIT: In the code I pasted it is my second try, using the keyword :repo. My first try was using the keyword :path and got me the same result.

@d12frosted I mentionned that I tried to set (pkg-name :location local) in the syntax-checking layer itself, and added the package under local/ as indicated, but Spacemacs still loads the version under .emacs.d/elpa.

I just tried :fetcher file, and it does not work either. Maybe it works in develop?

@d12frosted should we open a separate issue ?

So, is there any solution a year and a half later?

I haven't had to use a local only package yet, but for repos you can fork or for using a specific branch of a package, edit .spacemacs like so:

dotspacemacs-additional-packages '((some-package :fetcher github :repo "git-username/some-package" :branch "some-branch"))

(defun dotspacemacs/user-config ()
(require 'some-package)

Well, as a maintainer of zephir-mode I have managed to enable this as follows:

$ mkdir -p $HOME/.emacs.d/private/local/zephir-mode
$ ln -s <PROJECT_HOME>/zephir-mode.el $HOME/.emacs.d/private/local/zephir-mode/zephir-mode.el

Then added zephir-mode to my $HOME/.spacemacs file as follows:

;; ...
dotspacemacs-additional-packages
'((zephir-mode :location
               (recipe :fetcher file
                       :path "~/.emacs.d/private/local/zephir-mode/zephir-mode.el")))

Note: After each file change I have to:

  • quelpa-upgrade
  • restart Spacemacs

A bit weird for me or at least terribly uncomfortable

what about using it from a layer? layers can have local packages and hopefully the layer packages should not get cached like it would for an additional-package.

Seems like the :location keyword is working but you have to update the packages to clean up the cache... That works for me.

  ;; To use local repo, update the packages to cleanup the cache
    (doom-themes :location "~/Developer/Github/emacs-doom-themes")

I have a similar issue, but related to cc-mode, that comes with emacs itself. It looks like there's no way to make it work, while other packages (coming from MELPA, or new ones) seem to work. I opened #9929, so it's a bit more specific.

commented

@fmdkdd , I think it is better to use (load "file-name-without-extension")
instead of (load-file "file-name"). This will load the compiled version of the file if available.

This should be closed since #9861 has been merged 👀

Thank you for the heads up ! 👍