How do I check if emacs has a library installed? - emacs

I want to check whether pymacs has been installed.

M-x locate-library will tell you if emacs can find the library in its load-path. If it does not return anything you might need to edit your load-path first.

There are many ways to do it.
type apropos, then pymacs. If it finds the symbols, it was loaded.
(require 'pymacs) -- if it does not return error, it was loaded
if you already loaded it, it called (provide 'pymacs), and the variable load-history keeps the symbols
There are still other ways to ckeck it.

Not sure if you're talking about ELPA packages, but I have the following definitions in my .emacs:
(defun sh-elpa-ensure-package (name)
"Make sure that a particular package is installed; if not then
automatically download, compile and install it.
This is primarily used by sh-elpa-require to allow deployment of
the configuration to a new machine - packages will therefore be
downloaded on that fresh machine (following installation they are
automatically kept up to date by the package manager).
Use this as follows:
(sh-elpa-ensure-package 'org)"
(if (not (package-installed-p name))
(package-install name)))
(defun sh-elpa-require (name)
"A replacement for the standard Emacs 'require'
function. This uses sh-elpa-require to download and install a
package if necessary prior to using the standard 'require'
function to import it. This is useful to allow the configuration
to just 'sh-elpa-require' a package and not have to bother
checking whether it has been installed yet."
(sh-elpa-ensure-package name)
(require name))
I can then include code such as the following in my .emacs to activate the package - if it's not already installed then this will download it from ELPA and byte-compile it before it is "required":
(sh-elpa-require 'pymacs)
If you're just talking about checking whether a package is installed from elisp, then you can also pick the bones of that out of the above snippet - see the (if (not (package-installed-p name)) bit.

Related

I can't load an .el package on emacs

So I downloaded an .el file, I put it on the ~/.emacs.d/elpa/ folder, but it won't appear on the M-x list-packages. How do I make it appear there or how can I install this file/package?
There are two ways of installing an Emacs package: either type M-x list-packages and install it from the list, letting Emacs download it for you, or download the package yourself and install it with M-x package-install-file.
Installing from a package archive
In the first case, note that there are several different package archives. The default value for the variable package-archives only contains GNU ELPA, but most people want to add MELPA to that list since it has more packages. To do that, you need to add the following to your .emacs file (copied from the MELPA web page):
(require 'package) ;; You might already have this line
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/"))
(when (< emacs-major-version 24)
;; For important compatibility libraries like cl-lib
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
(package-initialize) ;; You might already have this line
After that, typing M-x list-packages should list more packages than you'll ever need :)
Installing from a downloaded file
There are two types of packages: single-file packages and multi-file packages. The former can be downloaded as a single .el file, while the latter are distributed as tarballs (.tar). Both types can be installed with M-x package-install-file.
Note that not every .el file can be installed as a package. The comments at the beginning of the file need to follow a certain convention, documented in the Simple packages node of the Emacs Lisp reference manual.
That leaves the possibility that the .el file you've downloaded is not installable as a package. In that case, you should put it in some other directory (~/.emacs.d/elpa is meant for installed packages only), add that directory to the load-path variable, and require the package. If you have foo.el and put it in ~/path/to/foo, it would look something like this:
(add-to-list 'load-path "~/path/to/foo")
(require 'foo)
An .el file is not a package. Installing it via ELPA is probably vastly preferrable to manually downloading a static .el file; perhaps the maintainer has a home page with ELPA (or Marmalade, etc) instructions.
In particular, a package will receive updates as they are made available, so you will not be forever stuck on an increasingly obsolete, unmanaged version (though quiet, fully automatic updates are not yet available or feasible, AFAICT).
But if you have to get by with just the file you already downloaded, you can put it pretty much anywhere you like, as long as that directory is included in the load-path. Manually mucking with the elpa directory is a bad idea, though; put it somewhere else.
Look for comments near the top of the file for any additional instructions; any autoloads, for example, will probably have to be configured separately, and usually completely manually.
This used to be how you always did things in older versions of Emacs, so you should find that the Internet is still practically bulging with guides and tutorials which explain the finer details of this mechanism, if this answer alone isn't sufficient.

emacs elpa version of auctex has no "auctex.el"

To set up auctex in Emacs you are told to include
(load "auctex.el" nil t t)
...etc. in your init/.emacs file. But if you installed auctex with elpa (which puts files in ~/.emacs.d/elpa/auctex-11.86/), you have no auctex.el and the (load ...) fails. What should I do?
Instead of loading nonexistent auctex.el do
(require 'tex)
which initializes AUCTeX for me (Windows Emacs 24.3 and pdflatex from Cygwin). If you have MiKTeX, you would also need
(require 'tex-mik)
Another potential problem with the package from elpa is the tex-site.el which is supposed to be generated during installation and contain system-specific data but gets installed from elpa instead. You may want to examine the file and make corrections if needed (and copy it to some other location which is listed earlier in your load-path). For instance it has some unix paths which make no sense in Windows environment.
Your problem is most likely due to the package initialization problem discussed here: Emacs 24 Package System Initialization Problems
You need to call (package-initialize) before calling load to not get an error.

How do I automatically (re)compile ELPA packages?

I'm now installing as much as I can through MELPA and Marmalade, and I manage my ~/.emacs.d using git. However, I have git ignore *.elc files.
This means that when I install a package on one system and then start using another system, git pull only gives me the *.el files. Using these files is often slower than using *.elc.
I tried adding the following to ~/.emacs.d/init.el:
;; load the packages we've installed. Note that package-install
;; byte-compiles the packages, but .elc is ignored by git so we force recompilation here
(byte-recompile-directory (expand-file-name "~/.emacs.d/elpa") 0)
(package-initialize)
Unfortunately, this isn't equivalent to the compilation done by package.el. For example, if I install emacs-eclim, package.el doesn't compile emacs-eclim/company-emacs-eclim.el, and I get the following error:
Leaving directory `/home/wilfred/.emacs.d/elpa'
Compiling file /home/wilfred/.emacs.d/elpa/emacs-eclim-20130310.1237/company-emacs-eclim.el at Mon Mar 11 15:40:01 2013
Entering directory `/home/wilfred/.emacs.d/elpa/emacs-eclim-20130310.1237/'
company-emacs-eclim.el:35:1:Error: Cannot open load file: eclim
Warning: reference to free variable `multiple-cursors-mode'
Warning: reference to free variable `mc--read-char'
Warning: assignment to free variable `mc--read-char'
Warning: reference to free variable `multiple-cursors-mode'
Warning: reference to free variable `mc--read-quoted-char'
Warning: assignment to free variable `mc--read-quoted-char'
Warning: reference to free variable `rectangular-region-mode'
Warning: reference to free variable `rectangular-region-mode'
How do I make Emacs byte-compile only the same files as package.el would?
package.el actually uses exactly the same method, it's just recompiling on startup makes the errors more noticable.
The function used is package--make-autoloads-and-compile, which calls:
(byte-recompile-directory pkg-dir 0 t)
So the original code in the question is correct. However, to recompile a directory that isn't yet compiled, you can do the following:
(require 'dash)
(require 'f)
(defun was-compiled-p (path)
"Does the directory at PATH contain any .elc files?"
(--any-p (f-ext? it "elc") (f-files path)))
(defun ensure-packages-compiled ()
"If any packages installed with package.el aren't compiled yet, compile them."
(--each (f-directories package-user-dir)
(unless (was-compiled-p it)
(byte-recompile-directory it 0))))
(ensure-packages-compiled)
I recommend not keeping the packages in version control (you wouldn't put .o files under revision control, would you?). Here is the code I use to keep my packages in sync:
(setq jpk-packages
'(
ac-dabbrev
...
yasnippet
))
(package-initialize)
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/"))
(add-to-list 'package-archives
'("org" . "http://orgmode.org/elpa/"))
(when (not package-archive-contents)
(package-refresh-contents))
(dolist (pkg jpk-packages)
(when (and (not (package-installed-p pkg))
(assoc pkg package-archive-contents))
(package-install pkg)))
(defun package-list-unaccounted-packages ()
"Like `package-list-packages', but shows only the packages that
are installed and are not in `jpk-packages'. Useful for
cleaning out unwanted packages."
(interactive)
(package-show-package-list
(remove-if-not (lambda (x) (and (not (memq x jpk-packages))
(not (package-built-in-p x))
(package-installed-p x)))
(mapcar 'car package-archive-contents))))
I put the above in init.el (which of course is under version control), and it installs any packages that don't exist yet when emacs starts up. Updating is done from the buffer package-list-packages creates. package-list-unaccounted-packages shows all the packages that are installed but not in my jpk-packages list, and makes it easy to remove the ones that I took out of the list.
To answer your specific question, I'd just delete the elpa directory and reinstall everything (using the above code).
The solution I like to the more general question of "How do I automatically re-compile any outdated .elc file" is to use https://github.com/tarsius/auto-compile
I used to have a handful of custom solutions which covered most situations I ran into, but this library covers everything I was doing and more besides. Just initialise it before loading anything else, and you're sorted.
As to the original question of not compiling files which were not originally compiled, that's what the 0 argument to byte-recompile-directory does, so you're explicitly asking for that behaviour. The default behaviour is to only recompile existing outdated .elc files, so you should simply remove that 0.
I do not know the answer to your specific issue about byte-compiling packages exactly the same way package.el would.
However, for your more general problem about maintaining your emacs configuration directory in git while installing extensions through Melpa or marmalade, I suggest you give a look to pallet, which has been designed to solve this very problem.
(byte-compile-file) worked for me when I need to manually recompile packages I have previously installed using elpa.
Particularly for this situation: https://github.com/yjwen/org-reveal/issues/76t
The problem you have is simply that you byte-compile files before initializing your packages. If you switch the two lines, your problem should disappear. The error you get (Cannot open load file: eclim) is because ~/.emacs.d/elpa/emacs-eclim-20130310.1237/ is not yet in your load-path, and package-initialize will add it to your load-path (along with a few other things).

Customize the list of packages that emacs-prelude provides

I see at this link how emacs prelude ensures that a set of packages is installed when emacs starts. I was wondering if I could somehow extend the variable prelude-packages to add some other packages, without changing the prelude-packages.el file?
Barring that I was wondering how I could define a list of packages that are installed at start-up if they aren't currently installed.
You can place a .el file in personal/ directory in Prelude. Prelude loads any .el file it finds there in an alphabetical order. Below is the content of my personal/00-packages.el file.:
(require 'package)
(add-to-list 'package-archives
'("marmalade" .
"http://marmalade-repo.org/packages/"))
(package-initialize)
;; My packages
(setq prelude-packages (append '(
drupal-mode
nginx-mode
) prelude-packages))
;; Install my packages
(prelude-install-packages)
"00" is added to the file name to ensure that the file is loaded before all personal customizations. Add any new package you need to the list being appended to prelude-packages.
Also, if you want to use any mode that is not available in MELPA or Marmalade, you can simply drop the mode's file in personal folder and Prelude will pick it up while loading. If there are any customizations to that mode, simply create another .el file and add the Emacs Lisp code there.
Prelude recommends to use
(prelude-require-packages '(some-package some-other-package))
if you have several package. Or in case you want to add just one package:
(prelude-require-package 'some-package)
If you want you can still maintain your package list in a variable:
(setq my-packages '(drupal-mode nginx-mode toto-mode)
(prelude-require-package my-packages)
In your .emacs file you could add code like this (very similar to the code in the link you sent) to check if each package is installed and install it if is not:
(dolist (package '(eredis anything erlang elnode))
(unless (package-installed-p package)
(package-install package)))
In answer to your question there's no reason you can't do this after the prelude code has run.

How to evaluate a piece of elisp code after all install packages are loaded?

I have installed several Emacs packages by M-x install-package. The starter-kit package hide the tool-bar and menu bar of emacs but I want them show back.
I added
(tool-bar-mode t)
in my ~/.emacs file but it seems get evaluated before starter-kit package get loaded.
Where should I put those code if I want evaluate them when all installed packages finished loading ?
Assuming that the starter kit package is in library called "starter-kit", this should work:
(eval-after-load "starter-kit"
'(tool-bar-mode t))
Have a look at the package.el file, in particular:
(defcustom package-enable-at-startup t
"Whether to activate installed packages when Emacs starts.
If non-nil, packages are activated after reading the init file
and before `after-init-hook'. Activation is not done if
`user-init-file' is nil (e.g. Emacs was started with \"-q\").
Even if the value is nil, you can type \\[package-initialize] to
activate the package system at any time."
:type 'boolean
:group 'package
:version "24.1")
So you can call package-initialize early in your .emacs and then overwrite what you need such as tool-bar-mode.
You could also put your overwrites in the after-init-hook.